Payloads
The transport supports the following payloads:
number(includingNaN,Infinity, and-Infinity)stringbooleanbigintundefinedandnull- plain JSON-like
ObjectandArray Envelope<H, B>whereHis JSON-like andBisArrayBuffer(default),SharedArrayBuffer,ProcessSharedBuffer, orBufferReferenceBuffer(Node.js),ArrayBufferUint8Array,Int32Array,Float64Array,BigInt64Array,BigUint64ArrayDataViewProcessSharedBufferfor zero-copy shared memory (see Shared memory)BufferReferencefromknitting/unsafefor zero-copy buffers to thread workers (see Buffer reference)Error(name, message, stack, and cause chain)DatesymbolfromSymbol.for(...)only- native
Promise<supported>values at the host call boundary
If you need multiple values, pass a tuple or object as the single argument. These types are not supported directly:
Map,Set,WeakMap, and custom class instances (exceptEnvelopeand subclasses)- non-global symbols
Blob- functions
Promise values are accepted at the call.*() boundary, but promises
themselves are runtime state and are not transferred through IPC as payloads.
Only resolved values are serialized and sent to workers.
If a promise input rejects, the host call rejects and the worker task is not
executed. Only native Promise is accepted; thenables are treated as regular
values.
See Promise inputs and awaited outputs for details.
type JSONValue = | string | number | boolean | null | JSONArray | JSONObject;
interface JSONObject { [key: string]: JSONValue;}
interface JSONArray extends Array<JSONValue> {}
type ValidInput = | bigint | void | JSONValue | symbol | Envelope<JSONValue | string, ArrayBuffer | SharedArrayBuffer> | Uint8Array | Int32Array | Float64Array | BigInt64Array | BigUint64Array | DataView | ArrayBuffer | Error | Date;
type Args = ValidInput | Serializable;
type TaskInput = NoBlob<Args> | Promise<NoBlob<Args>>;Picking the right payload type
Section titled “Picking the right payload type”Different types take different code paths and have very different costs. Use the cheapest type that fits your data.
Header-only (fastest): number, boolean, undefined, null, Date,
small string, small bigint. These fit in the call header with near-zero
overhead. Prefer these whenever possible.
Static payload (fast): Symbol.for(...), large bigint, typed arrays
(Uint8Array, Int32Array, etc.). Reuses a small buffer region alongside the
header.
Dynamic payload (allocator path): Object, Array (JSON-serialized),
Error, Date, and larger strings. These need allocation, serialization, and
copying. Still faster than postMessage, but measurably heavier in hot loops.
See the Performance guide for per-type benchmarks and batching guidance.
Envelope
Section titled “Envelope”Envelope<H, B> pairs a JSON-serializable header with a binary body. Use it
when a call needs both structured metadata and raw bytes — the transport carries
one special binary value per call, so an envelope is how you attach a header to one.
import { Envelope } from "knitting";
const message = new Envelope( { route: "/upload", contentType: "application/octet-stream" }, new Uint8Array([1, 2, 3]).buffer,);The second type parameter B sets the body type and defaults to ArrayBuffer.
The supported body types are:
| Body | Copy? | Works with | Notes |
|---|---|---|---|
ArrayBuffer | copied | thread + process | Default. Works everywhere. |
SharedArrayBuffer | zero-copy, shared | thread only | Shared by reference; process workers reject it. |
ProcessSharedBuffer | zero-copy, shared | thread + process | Cross-process shared memory. |
BufferReference | zero-copy, moved | thread only | From knitting/unsafe. Source is detached on construction. |
Envelope is disposable — [Symbol.dispose]() disposes a disposable body (a
BufferReference) and is a no-op for ArrayBuffer and SharedArrayBuffer.
Use using to dispose automatically when the envelope goes out of scope:
using result = await pool.call.processImage( new Envelope({ format: "png" }, buffer),);console.log(result.header);// result is disposed here when the `using` scope exitsFor BufferReference bodies, see Buffer reference.
For ProcessSharedBuffer bodies, see Shared memory.
Errors
Section titled “Errors”Error payloads preserve name, message, stack, and recursive cause
chains. Both sync throws and async rejections inside tasks propagate back to
the host as Error objects.
See also: knitting/utils for buffer serialization helpers and Buffer reference for zero-copy thread payloads.