worker: implement `MessagePort` and `MessageChannel` · nodejs/node@337be58
1+# Worker
2+3+<!--introduced_in=REPLACEME-->
4+5+> Stability: 1 - Experimental
6+7+## Class: MessageChannel
8+<!-- YAML
9+added: REPLACEME
10+-->
11+12+Instances of the `worker.MessageChannel` class represent an asynchronous,
13+two-way communications channel.
14+The `MessageChannel` has no methods of its own. `new MessageChannel()`
15+yields an object with `port1` and `port2` properties, which refer to linked
16+[`MessagePort`][] instances.
17+18+```js
19+const { MessageChannel } = require('worker');
20+21+const { port1, port2 } = new MessageChannel();
22+port1.on('message', (message) => console.log('received', message));
23+port2.postMessage({ foo: 'bar' });
24+// prints: received { foo: 'bar' }
25+```
26+27+## Class: MessagePort
28+<!-- YAML
29+added: REPLACEME
30+-->
31+32+* Extends: {EventEmitter}
33+34+Instances of the `worker.MessagePort` class represent one end of an
35+asynchronous, two-way communications channel. It can be used to transfer
36+structured data, memory regions and other `MessagePort`s between different
37+[`Worker`][]s.
38+39+With the exception of `MessagePort`s being [`EventEmitter`][]s rather
40+than `EventTarget`s, this implementation matches [browser `MessagePort`][]s.
41+42+### Event: 'close'
43+<!-- YAML
44+added: REPLACEME
45+-->
46+47+The `'close'` event is emitted once either side of the channel has been
48+disconnected.
49+50+### Event: 'message'
51+<!-- YAML
52+added: REPLACEME
53+-->
54+55+* `value` {any} The transmitted value
56+57+The `'message'` event is emitted for any incoming message, containing the cloned
58+input of [`port.postMessage()`][].
59+60+Listeners on this event will receive a clone of the `value` parameter as passed
61+to `postMessage()` and no further arguments.
62+63+### port.close()
64+<!-- YAML
65+added: REPLACEME
66+-->
67+68+Disables further sending of messages on either side of the connection.
69+This method can be called once you know that no further communication
70+will happen over this `MessagePort`.
71+72+### port.postMessage(value[, transferList])
73+<!-- YAML
74+added: REPLACEME
75+-->
76+77+* `value` {any}
78+* `transferList` {Object[]}
79+80+Sends a JavaScript value to the receiving side of this channel.
81+`value` will be transferred in a way which is compatible with
82+the [HTML structured clone algorithm][]. In particular, it may contain circular
83+references and objects like typed arrays that the `JSON` API is not able
84+to stringify.
85+86+`transferList` may be a list of `ArrayBuffer` objects.
87+After transferring, they will not be usable on the sending side of the channel
88+anymore (even if they are not contained in `value`).
89+90+`value` may still contain `ArrayBuffer` instances that are not in
91+`transferList`; in that case, the underlying memory is copied rather than moved.
92+93+For more information on the serialization and deserialization mechanisms
94+behind this API, see the [serialization API of the `v8` module][v8.serdes].
95+96+Because the object cloning uses the structured clone algorithm,
97+non-enumerable properties, property accessors, and object prototypes are
98+not preserved. In particular, [`Buffer`][] objects will be read as
99+plain [`Uint8Array`][]s on the receiving side.
100+101+The message object will be cloned immediately, and can be modified after
102+posting without having side effects.
103+104+### port.ref()
105+<!-- YAML
106+added: REPLACEME
107+-->
108+109+Opposite of `unref()`. Calling `ref()` on a previously `unref()`ed port will
110+*not* let the program exit if it's the only active handle left (the default
111+behavior). If the port is `ref()`ed, calling `ref()` again will have no effect.
112+113+If listeners are attached or removed using `.on('message')`, the port will
114+be `ref()`ed and `unref()`ed automatically depending on whether
115+listeners for the event exist.
116+117+### port.start()
118+<!-- YAML
119+added: REPLACEME
120+-->
121+122+Starts receiving messages on this `MessagePort`. When using this port
123+as an event emitter, this will be called automatically once `'message'`
124+listeners are attached.
125+126+### port.unref()
127+<!-- YAML
128+added: REPLACEME
129+-->
130+131+Calling `unref()` on a port will allow the thread to exit if this is the only
132+active handle in the event system. If the port is already `unref()`ed calling
133+`unref()` again will have no effect.
134+135+If listeners are attached or removed using `.on('message')`, the port will
136+be `ref()`ed and `unref()`ed automatically depending on whether
137+listeners for the event exist.
138+139+[`Buffer`]: buffer.html
140+[`EventEmitter`]: events.html
141+[`MessagePort`]: #worker_class_messageport
142+[`port.postMessage()`]: #worker_port_postmessage_value_transferlist
143+[v8.serdes]: v8.html#v8_serialization_api
144+[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
145+[browser `MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
146+[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm