理解@metamask/post-message-stream包

@metamask/post-message-stream 是MetaMask提供的一个在window.postMessage实现的双工对象流(基于 Duplex 的objectMode)

该库起初仅支持 window.postMessage的环境, 后续该库扩展环境范围:

  • window.postMessage: window.postMessagewindow.addEventListener('message',...)
  • runtime: 浏览器插件中的 chrome.runtime.sendMessagechrome.runtime.onMessage.addListener
  • webWorker:
    • web端的WebWorkerParentPostMessageStream: worker.postMessageworker.onmessage
    • worker端的WebWorkerPostMessageStream: self.postMessage self.addEventListener('message', ...)
  • node-process:
    • 父进程ProcessParentMessageStream: process.sendprocess.on('message', ...)
    • 子进程ProcessMessageStream: globalThis.process.sendglobalThis.process.on('message', ...)
  • node-thread:
    • 父线程 ThreadParentMessageStream: worker.postMessageworker.on('message', ...)
    • 子线程ThreadMessageStream: parentPort.postMessageparentPort.on('message', ...)

对比

未使用该库之前

1
2
3
4
5
6
7
8
9
10
window.addEventListener('message', function (e){
if (e.data.target === 'nameA') {
console.log(e.data)
}
})

window.postMessage({
name: 'nameB',
target: 'nameA'
})

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { WindowPostMessageStream } from '@metamask/post-message-stream';

const streamA = new WindowPostMessageStream({
name: 'streamA',
target: 'streamB',
});

// postMessage
streamA.write('hello');

const streamB = new WindowPostMessageStream({
name: 'streamB',
target: 'streamA',
});

// on message
streamB.on('data', data => {
console.log(data)
})

源码

UML类图: - Private# Protected* Abstract(渲染出来是斜体)$ Static(渲染出来是下划线)

classDiagram
direction RL
class BasePostMessageStream{
  -Boolean _init
  -Boolean _haveSyn
  -Log _log
  #_handshake()
  #_onData()
  #_postMessage()*
  +_read()
  +_write()
  +_setLogger()
}
namespace window {
  class WindowPostMessageStream {
    #_postMessage()
    -_onMessage()
    _destroy()
  }
}
BasePostMessageStream <|-- WindowPostMessageStream: 继承

ProcessMessageStream,ProcessParentMessageStream
ThreadMessageStream, ThreadParentMessageStream
BrowserRuntimePostMessageStream
WebWorkerPostMessageStream, WebWorkerParentPostMessageStream
与WindowPostMessageStream成员类似

其中基类BasePostMessageStream继承于readable-stream[1]Duplex


  1. 1.readable-stream是Node.js官方出的库,旨在提供Streams模块的兼容性实现。允许开发者在不同的Node.js版本中使用一致的StreamsAPI,同时也为浏览器环境提供支持