# Messaging

> How Elide supports MessageChannel, MessagePort and MessageEvent: same-realm channels, which values structured clone copies, and DataCloneError cases.

`MessageChannel`, `MessagePort`, and `MessageEvent` are globals and follow the
[HTML Standard](https://html.spec.whatwg.org/multipage/web-messaging.html).

## Example

```js
// messaging.mjs
const { port1, port2 } = new MessageChannel();
port2.onmessage = (event) => {
  const { when, tags } = event.data;
  console.log(when instanceof Date, tags instanceof Set, [...tags].join());
  port1.close();
  port2.close();
};
port1.postMessage({ when: new Date(0), tags: new Set(["a", "b"]) });

try {
  port1.postMessage(() => {});
} catch (error) {
  console.log(error.name);
}
```

`elide run messaging.mjs` prints:

```text
DataCloneError
true true a,b
```

## Differences from browsers

- A channel connects ports in the same realm; it does not create a worker.
- Structured clone copies primitives, arrays, plain objects, cycles, `Date`, `RegExp`, `Map`, `Set`, and `ArrayBuffer`.
- Posting a function throws `DataCloneError`.

For workers, see [node:worker_threads](https://elide.help/docs/api-node-worker-threads).

<!-- api-reference:start 664c308fbb59 -->
## Reference

**Status:** Partial · Not measured

### Exports

| Export | Kind | Status | Notes |
| --- | --- | --- | --- |
| `MessageEvent` | class | Partial | missing WindowProxy and ServiceWorker as MessageEventSource (non-browser). `data`, `origin`, `lastEventId`, `source`, `ports`, `initMessageEvent()` |
| `MessageChannel` | class | Partial | missing WindowProxy and ServiceWorker as MessageEventSource (non-browser). `port1`, `port2` |
| `MessagePort` | class | Partial | missing WindowProxy and ServiceWorker as MessageEventSource (non-browser). `postMessage()`, `start()`, `close()`, `onclose`, `onmessage`, `onmessageerror` |
<!-- api-reference:end -->
