| 93 | * https://caniuse.com/?search=broadcastchannel |
| 94 | */ |
| 95 | export function BroadcastChannel(name = 'linen.message') { |
| 96 | return { |
| 97 | /** Get notified by other tabs/windows. */ |
| 98 | receive(onReceive: (message: BroadcastMessage) => void) { |
| 99 | const handler = (event: StorageEvent) => { |
| 100 | if (event.key !== name) return; |
| 101 | const message: BroadcastMessage = JSON.parse(event.newValue || '{}'); |
| 102 | if (message?.event !== 'session' || !message?.data) return; |
| 103 | |
| 104 | onReceive(message); |
| 105 | }; |
| 106 | window.addEventListener('storage', handler); |
| 107 | return () => window.removeEventListener('storage', handler); |
| 108 | }, |
| 109 | /** Notify other tabs/windows. */ |
| 110 | post(message: Record<string, unknown>) { |
| 111 | if (typeof window === 'undefined') return; |
| 112 | try { |
| 113 | localStorage.setItem( |
| 114 | name, |
| 115 | JSON.stringify({ ...message, timestamp: now() }) |
| 116 | ); |
| 117 | } catch { |
| 118 | /** |
| 119 | * The localStorage API isn't always available. |
| 120 | * It won't work in private mode prior to Safari 11 for example. |
| 121 | * Notifications are simply dropped if an error is encountered. |
| 122 | */ |
| 123 | } |
| 124 | }, |
| 125 | }; |
| 126 | } |
| 127 | |
| 128 | export function cleanUpStorage() { |
| 129 | if (typeof window === 'undefined') return; |