A dedicated worker is already two entangled ports. Mint a pair only when you need a second pipe.
new Worker(url) sets up a MessagePort the page never sees.
worker.postMessage and self.postMessage are that port.
Its port message queue is enabled at creation, so Worker has no start(), and
addEventListener("message") on the worker already dispatches.
The hop has no targetOrigin: the second argument is a transfer list, the same way you moved a port into an iframe.
(HTML §10.1.3.2)
const worker = new Worker(url);
worker.onmessage = onMsg;
worker.postMessage({ job: "crunch" }); // implicit pipe — enough
const { port1, port2 } = new MessageChannel();
port1.onmessage = onExtra;
worker.postMessage("stream", [port2]); // second pipe — only if you need one
Mint when the implicit stream is the wrong shape: a second logical conversation, a port you can close() without killing the worker, or a capability you hand to a third context (another worker, an iframe, a library caller).
The spec’s crypto-library example is that pattern: keep port1, ship port2 with the command.
(HTML §10.1.2.6)
| You already have | Use |
|---|---|
| The same JS world (a React child, a function) | Call it. No channel. |
| A window handle, and origin is the question | window.postMessage + targetOrigin |
| A name, and every same-origin listener should hear | BroadcastChannel |
| A dedicated worker, one stream with its creator | The implicit port. Do not mint. |
| A second stream, or an end to hand off | new MessageChannel(), transfer one port |
A real dedicated worker. Ping the implicit pipe. Then mint a pair, move port2 in the worker’s transfer list, and talk on that extra port. Ping implicit again: it is still its own pipe.
The lab needs JavaScript in this page.
Read
HTML Living Standard §10.1.3.2
(implicit port, queue already enabled, transfer as the second argument).
Then the extra-pipe pattern in
§10.1.2.6
(source.postMessage(message, [messageChannel.port2])).
If “why isn’t the worker just a MessageChannel?” is still mushy — ask. Next: lesson 5 — both ends in two iframes, parent off the pipe. Pocket cards: entangled ports, port API, transfer, choose.