forked from jlalmes/trpc-chrome
-
Notifications
You must be signed in to change notification settings - Fork 11
/
window.ts
50 lines (45 loc) · 1.42 KB
/
window.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import type { TRPCLink } from '@trpc/client';
import type { AnyRouter } from '@trpc/server';
import type { MinimalWindow, TRPCChromeMessage } from '../types';
import { createBaseLink } from './internal/base';
export type WindowLinkOptions = {
window: MinimalWindow;
postWindow?: MinimalWindow;
postOrigin?: string;
};
export const windowLink = <TRouter extends AnyRouter>(
opts: WindowLinkOptions,
): TRPCLink<TRouter> => {
const handlerMap = new Map<
(message: TRPCChromeMessage) => void,
(ev: MessageEvent<TRPCChromeMessage>) => void
>();
const listenWindow = opts.window;
const postWindow = opts.postWindow ?? listenWindow;
return createBaseLink({
postMessage(message) {
postWindow.postMessage(message, {
targetOrigin: opts.postOrigin,
});
},
addMessageListener(listener) {
const handler = (ev: MessageEvent<TRPCChromeMessage>) => {
listener(ev.data);
};
handlerMap.set(listener, handler);
listenWindow.addEventListener('message', handler);
},
removeMessageListener(listener) {
const handler = handlerMap.get(listener);
if (handler) {
listenWindow.removeEventListener('message', handler);
}
},
addCloseListener(listener) {
listenWindow.addEventListener('beforeunload', listener);
},
removeCloseListener(listener) {
listenWindow.removeEventListener('beforeunload', listener);
},
});
};