The return-value pattern
The return-value pattern over the legacy
postMessage transport. The call shape is identical to the BroadcastChannel demo — what differs is that the child shares the parent's event loop. Pick this transport when you want the simplest setup; pick BroadcastChannel when the child runs alongside a busy parent.Last result
Whatever the child popup most recently returned.
// no result yet
Code
Both sides of the pattern. The parent awaits a typed value; the child turns user interaction into a procedure return.
parent.tsx
// Parent: open the popup and await a typed value.
// The postMessage transport keeps `window.opener` wired up, so the
// parent and child share an event loop. Same call shape as the
// BroadcastChannel demo — only the option differs.
const child = await iwpc.open(`./child?kind=color`, {
width: 520,
height: 540
});
const hex = await child.invoke<void, string | null>(
'PICK_COLOR',
undefined,
{ timeout: 5 * 60 * 1000 } // generous, the user is in the loop
);
if (hex === null) {
// user cancelled
} else {
setColor(hex);
}child.tsx
// Child: register BEFORE initialize() so the parent's invoke
// (which fires the moment open() resolves) finds the handler.
const instance = new IwpcWindow(window);
instance.register('PICK_COLOR', () =>
new Promise<string | null>((resolve) => {
// Resolve from a button click handler in the UI.
setPending({ kind: 'color', resolve });
})
);
instance.initialize();