@wuchuheng/window-message
Version:
A modern TypeScript library for cross-window messaging
142 lines (141 loc) • 3.92 kB
JavaScript
// src/logger.ts
var logger = {
log: (...args) => {
console.log(...args);
},
error: (...args) => {
console.error(...args);
}
};
// src/index.ts
var createChannel = (channel) => {
const requestChannel = `request:/${channel}`;
const responseChannel = `response:/${channel}`;
let isSetup = false;
const processSetupMsg = () => new Promise((resolve) => {
const onMessage = (event) => {
if (event.origin !== window.location.origin) {
return;
}
const channelMsg = event.data;
if (channelMsg.channel !== requestChannel) {
return;
}
if (channelMsg.isSetup) {
isSetup = true;
window.removeEventListener("message", onMessage);
resolve();
logger.log(`[windows message: request side]: setup success`);
return;
}
};
window.addEventListener("message", onMessage);
});
processSetupMsg();
const waitChildWindowSetup = async () => {
if (isSetup) {
return;
}
await processSetupMsg();
};
return {
request: (message, windowObj = window) => request(
message,
windowObj,
responseChannel,
requestChannel,
waitChildWindowSetup
),
handle: (callback) => handle(callback, requestChannel, responseChannel)
};
};
var handle = (callback, requestChannel, responseChannel) => {
const setupMsg = {
channel: requestChannel,
success: true,
isSetup: true,
data: void 0
};
window.parent.postMessage(setupMsg);
logger.log(
`[windows message: handle side]: setup: ${JSON.stringify(setupMsg)}`
);
const messageHandler = (event) => {
if (event.origin !== window.location.origin) {
return;
}
const channelMsg = event.data;
if (channelMsg.channel !== requestChannel) {
return;
}
if (channelMsg.isSetup) {
return;
}
logger.log(
`[windows message: handle side]: Receive ${JSON.stringify(channelMsg)} `
);
callback(channelMsg.data).then((res) => {
const msg = {
channel: responseChannel,
success: true,
data: res
};
event.source?.postMessage(msg, { targetOrigin: event.origin });
logger.log(
`[windows message: handle side]: Post ${JSON.stringify(msg)} `
);
}).catch((err) => {
const errMsg = {
channel: responseChannel,
success: false,
data: void 0,
error: {
msg: err.message,
stack: err.stack || ""
}
};
event.source?.postMessage(errMsg, { targetOrigin: event.origin });
logger.error(
`[windows message: handle side]: Post ${JSON.stringify(errMsg)} `
);
});
};
window.addEventListener("message", messageHandler);
};
var request = async (message, windowObj = window, responseChannel, requestChannel, waitChildWindowSetup) => {
await waitChildWindowSetup();
return new Promise((resolve, reject) => {
const messageHandler = (event) => {
if (event.origin !== window.location.origin) {
return;
}
const channelMsg = event.data;
if (channelMsg.channel !== responseChannel) {
return;
}
logger.log(
`[windows message: request side]: Receive ${JSON.stringify(channelMsg)} `
);
if (channelMsg.success) {
resolve(channelMsg.data);
} else {
reject(channelMsg.error?.msg || "Unknown error");
console.error(channelMsg.error?.msg);
console.error(channelMsg.error?.stack);
}
window.removeEventListener("message", messageHandler);
};
window.addEventListener("message", messageHandler);
const msg = {
channel: requestChannel,
success: true,
data: message
};
logger.log(`[windows message: request side]: Post ${JSON.stringify(msg)} `);
windowObj.postMessage(msg, "*");
});
};
export {
createChannel
};
//# sourceMappingURL=index.mjs.map