cross-document-messenger
Version:
post and subscribe messages between documents
79 lines (78 loc) • 2.14 kB
JavaScript
// lib/index.ts
var TargetFrameConnector = class {
_crossDocMessenger;
_port;
_listener;
static getInstance() {
return new TargetFrameConnector();
}
_connectToHost() {
let handlerFn;
const listenerFn = (event) => {
if (!this._port && event.ports.length > 0) {
this._port = event.ports[0];
this._port.onmessage = (event2) => handlerFn(event2.data);
}
};
this._listener = listenerFn;
window.addEventListener('message', this._listener);
return {
emit: (message) => this?._port?.postMessage(message),
subscribe: (_handlerFn) => {
if (!this._listener) {
this._listener = listenerFn;
}
handlerFn = _handlerFn;
},
unsubscribe: () => {
this._listener = void 0;
window.removeEventListener('message', this._listener);
},
};
}
messenger() {
if (!this._crossDocMessenger) {
this._crossDocMessenger = this._connectToHost();
}
return this._crossDocMessenger;
}
};
var connector = TargetFrameConnector.getInstance();
var TargetFrameMessenger = connector.messenger();
var HostConnector = class {
_hostPort;
_channel;
static getInstance() {
return new HostConnector();
}
_establishChannel(target, targetOrigin) {
if (targetOrigin === '*') {
throw new Error('Unsecured targetOrigin');
}
this._channel = new MessageChannel();
this._hostPort = this._channel.port1;
target?.contentWindow?.postMessage('connect', targetOrigin, [
this._channel?.port2,
]);
}
messenger(target, targetOrigin) {
this._establishChannel(target, targetOrigin);
return {
emit: (message) => this._hostPort?.postMessage(message),
subscribe: (handlerFn) => {
if (!this._hostPort) return;
if (this._hostPort) {
this._hostPort.onmessage = (event) => {
const message = event.data;
handlerFn(message);
};
}
},
unsubscribe: () => {
this._channel = void 0;
},
};
}
};
export { HostConnector, TargetFrameMessenger };
//# sourceMappingURL=index.js.map