Behavior of Structured Clone
Structured clone is JavaScript’s algorithm to create “deep copies” of values. It is used for postMessage()
and therefore is used extensively under the hood with Workercom. By default, every function parameter and function return value is structured cloned. Here is a table of how the structured clone algorithm handles different kinds of values. Or to phrase it differently: If you pass a value from the left side as a parameter into a proxy’d function, the actual function code will get what is listed on the right side.
Yellow : Can full copy if installTransfer Green : Can full copy by transfer installed default Warning : Can't copy if you don't have transfer installed
Input | Output | Notes |
---|---|---|
[1,2,3] |
[1,2,3] |
Full copy |
{a: 1, b: 2} |
{a: 1, b: 2} |
Full copy |
{a: 1, b() { return 2; } |
{a: 1, b: () => Promise<2>} |
Full copy |
new MyClass() |
{...} |
Just the properties |
Map |
Map |
Map is structured cloneable or full copy |
Set |
Set |
Set is structured cloneable or full copy |
ArrayBuffer |
ArrayBuffer |
ArrayBuffer full copy |
TypedArray |
TypedArray |
TypedArray full copy |
Function |
Function => Promise |
Function full copy |
Error |
Error |
Error full copy |
Event |
❌ | |
Any DOM element | ❌ | |
MessagePort |
MessagePort |
Only transferable, not structured cloneable |
Request |
❌ | |
Response |
❌ | |
ReadableStream |
❌ | Streams are planned to be transferable, but not structured cloneable |
import { installTransfer } from "workercom"
installTransfer<MessagePort, MessagePort>({
canHandle: (value) => value instanceof MessagePort,
serialize: (port) => [port, [port]],
deserialize: ({ raw: port }) => port,
})
import { installTransfer } from "workercom"
installTransfer<Event, {
target: {
id: string;
classList: string[]
}
}>("EVENT", {
canHandle: (obj) => obj instanceof Event,
serialize: (ev) => {
return [
{
target: {
id: ev.target.id,
classList: [...ev.target.classList],
},
},
[],
];
},
deserialize: (obj) => obj,
});