UNPKG

@dapplets/dapplet-overlay-bridge

Version:
81 lines (80 loc) 2.81 kB
export class GeneralBridge { constructor() { this._subId = 0; this._callbacks = {}; window.addEventListener('message', async (e) => { try { const data = JSON.parse(e.data); if (!data || !data.topic) return; const callbacks = this._callbacks[data.topic] || []; for (const callback of callbacks) { const result = callback.apply({}, [data.message]); if (data.id) { const msg = JSON.stringify({ id: data.id, result: result }); window.parent.postMessage(msg, '*'); } } } catch (ex) { } }); const _call = (method, args) => { const callbackEventDone = method + '_done'; const callbackEventUndone = method + '_undone'; return new Promise((res, rej) => { this.publish(this._subId.toString(), { type: method, message: args, }); this.subscribe(callbackEventDone, (result) => { this.unsubscribe(callbackEventDone); this.unsubscribe(callbackEventUndone); res(result); }); this.subscribe(callbackEventUndone, (err) => { this.unsubscribe(callbackEventUndone); this.unsubscribe(callbackEventDone); rej(`Error in ${method}. ${err ? err : ''}`); }); }); }; return new Proxy(this, { get: (target, prop) => { if (prop in target) { return target[prop]; } else { return (...args) => _call(prop, args); } }, }); } on(event, callback) { this.subscribe(event, (data) => { this._subId = Math.trunc(Math.random() * 1000000000); callback(data); return this._subId.toString(); }); } off(event) { this.unsubscribe(event); return; } publish(topic, message) { const msg = JSON.stringify({ topic, message }); window.parent.postMessage(msg, '*'); } subscribe(topic, handler) { if (!this._callbacks[topic]) { this._callbacks[topic] = []; } this._callbacks[topic].push(handler); } unsubscribe(topic) { this._callbacks[topic] = []; } } export const Bridge = GeneralBridge;