forked from clerk/javascript
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocalStorageBroadcastChannel.ts
57 lines (47 loc) · 1.43 KB
/
localStorageBroadcastChannel.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
51
52
53
54
55
56
57
type Listener<T> = (e: MessageEvent<T>) => void;
const KEY_PREFIX = '__lsbc__';
export class LocalStorageBroadcastChannel<E> {
private readonly eventTarget = window;
private readonly channelKey: string;
constructor(name: string) {
this.channelKey = KEY_PREFIX + name;
this.setupLocalStorageListener();
}
public postMessage = (data: E): void => {
if (typeof window === 'undefined') {
// Silently do nothing
return;
}
try {
window.localStorage.setItem(this.channelKey, JSON.stringify(data));
window.localStorage.removeItem(this.channelKey);
} catch (e) {
// Silently do nothing
}
};
public addEventListener = (eventName: 'message', listener: Listener<E>): void => {
this.eventTarget.addEventListener(this.prefixEventName(eventName), e => {
listener(e as MessageEvent);
});
};
private setupLocalStorageListener = () => {
const notifyListeners = (e: StorageEvent) => {
if (e.key !== this.channelKey || !e.newValue) {
return;
}
try {
const data = JSON.parse(e.newValue || '');
const event = new MessageEvent(this.prefixEventName('message'), {
data,
});
this.eventTarget.dispatchEvent(event);
} catch (e) {
//
}
};
window.addEventListener('storage', notifyListeners);
};
private prefixEventName(eventName: string): string {
return this.channelKey + eventName;
}
}