| 102 | type MaybePromise<T> = T | Promise<T>; |
| 103 | |
| 104 | export class MessageReceiver { |
| 105 | private emitter: EventTarget; |
| 106 | private senderPort: MessagePort = null as any; |
| 107 | |
| 108 | constructor() { |
| 109 | this.emitter = new EventTarget(); |
| 110 | this.waitForHandshake(); |
| 111 | } |
| 112 | |
| 113 | private waitForHandshake() { |
| 114 | const handshakePromise = new DeferredPromise(); |
| 115 | |
| 116 | const handshakeListener = (message: MessageEvent) => { |
| 117 | const { data } = message; |
| 118 | |
| 119 | debug('[message-receiver]: incoming', message); |
| 120 | |
| 121 | if (data.type === 'internal/handshake') { |
| 122 | invariant( |
| 123 | message.ports.length > 0, |
| 124 | 'Failed to confirm a MessageReceiver handshake: received event has no ports' |
| 125 | ); |
| 126 | |
| 127 | this.senderPort = message.ports[0]; |
| 128 | this.addMessageListener(); |
| 129 | |
| 130 | debug('[message-receiver]: handshake received!', this.senderPort); |
| 131 | |
| 132 | this.send('internal/handshake/done'); |
| 133 | debug('[message-receiver]: finish handshake'); |
| 134 | } |
| 135 | }; |
| 136 | |
| 137 | window.addEventListener('message', handshakeListener); |
| 138 | handshakePromise.then(() => { |
| 139 | window.removeEventListener('message', handshakeListener); |
| 140 | }); |
| 141 | |
| 142 | window.parent.postMessage({ type: 'internal/ready' }, '*'); |
| 143 | |
| 144 | return handshakePromise; |
| 145 | } |
| 146 | |
| 147 | private addMessageListener(): void { |
| 148 | invariant( |
| 149 | this.senderPort, |
| 150 | '[MessageReceiver] Failed to add a message listener: sender port is not defined. Did you forget to await a handshake?' |
| 151 | ); |
| 152 | |
| 153 | this.senderPort.onmessage = (evt) => { |
| 154 | const data = evt.data; |
| 155 | if (data.type == null) { |
| 156 | return; |
| 157 | } |
| 158 | |
| 159 | this.emitter.dispatchEvent( |
| 160 | new MessageEvent(data.type, { |
| 161 | data: data.payload, |
nothing calls this directly
no outgoing calls
no test coverage detected