| 133 | } |
| 134 | |
| 135 | export class WindowMessageConnect implements MessageConnect { |
| 136 | private readonly listenerId = `${uuidv4()}`; // 使用 uuidv4 确保唯一 |
| 137 | private target: PostMessage | null; |
| 138 | private isSelfDisconnected = false; |
| 139 | |
| 140 | constructor( |
| 141 | private messageId: string, |
| 142 | EE: EventEmitter<string, any>, |
| 143 | target: PostMessage |
| 144 | ) { |
| 145 | this.target = target; // 强引用 |
| 146 | const handler = (msg: TMessage) => { |
| 147 | listenerMgr.emit(`onMessage:${this.listenerId}`, msg); |
| 148 | }; |
| 149 | const cleanup = () => { |
| 150 | if (this.target) { |
| 151 | this.target = null; |
| 152 | listenerMgr.removeAllListeners(`cleanup:${this.listenerId}`); |
| 153 | EE.removeAllListeners("connectMessage:" + this.messageId); // 模拟 con.onMessage.removeListener |
| 154 | EE.removeAllListeners("disconnect:" + this.messageId); // 模拟 con.onDisconnect.removeListener |
| 155 | listenerMgr.emit(`onDisconnect:${this.listenerId}`, this.isSelfDisconnected); |
| 156 | listenerMgr.removeAllListeners(`onDisconnect:${this.listenerId}`); |
| 157 | listenerMgr.removeAllListeners(`onMessage:${this.listenerId}`); |
| 158 | } |
| 159 | }; |
| 160 | EE.addListener(`connectMessage:${this.messageId}`, handler); // 模拟 con.onMessage.addListener |
| 161 | EE.addListener(`disconnect:${this.messageId}`, cleanup); // 模拟 con.onDisconnect.addListener |
| 162 | listenerMgr.once(`cleanup:${this.listenerId}`, cleanup); |
| 163 | } |
| 164 | |
| 165 | sendMessage(data: TMessage) { |
| 166 | if (!this.target) { |
| 167 | console.error("Attempted to sendMessage on a disconnected Target."); |
| 168 | // 無法 sendMessage 不应该屏蔽错误 |
| 169 | throw new Error("Attempted to sendMessage on a disconnected Target."); |
| 170 | } |
| 171 | const body: WindowMessageBody<TMessage> = { |
| 172 | messageId: this.messageId, |
| 173 | type: "connectMessage", |
| 174 | data, |
| 175 | }; |
| 176 | this.target.postMessage(body); |
| 177 | } |
| 178 | |
| 179 | onMessage(callback: (data: TMessage) => void) { |
| 180 | if (!this.target) { |
| 181 | console.error("onMessage Invalid Target"); |
| 182 | // 無法監聽的話不应该屏蔽错误 |
| 183 | throw new Error("onMessage Invalid Target"); |
| 184 | } |
| 185 | listenerMgr.addListener(`onMessage:${this.listenerId}`, callback); |
| 186 | } |
| 187 | |
| 188 | disconnect(ignoreAlreadyDisconnected: boolean) { |
| 189 | if (!this.target) { |
| 190 | if (ignoreAlreadyDisconnected) return; |
| 191 | console.warn("Attempted to disconnect on a disconnected Target."); |
| 192 | // 重复 disconnect() 不应该屏蔽错误 |
nothing calls this directly
no outgoing calls
no test coverage detected