@dapplets/dapplet-overlay-bridge
Version:
The bridge between dapplet and overlay
81 lines (80 loc) • 2.81 kB
JavaScript
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;