Something went wrong. Try again.
Offload functions to worker threads with shared memory primitives for Node.js.
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859import type { Transferable } from 'node:worker_threads';import { MessagePort } from 'node:worker_threads';
const TRANSFER = Symbol.for('moroutine.transfer');
export interface Transferred<T> { readonly [TRANSFER]: true; readonly value: T;}
/** * Marks a value for zero-copy transfer via postMessage. The original becomes detached after sending. * @param value - The value to transfer (ArrayBuffer, TypedArray, MessagePort, or stream). * @returns The same value, typed unchanged for transparent use as a moroutine argument. */export function transfer<T>(value: T): T { return { [TRANSFER]: true as const, value } as unknown as T;}
export function extractTransferables(args: unknown[]): { args: unknown[]; transfer: Transferable[] } { const transferList: Transferable[] = []; const processedArgs = args.map((arg) => { if (typeof arg === 'object' && arg !== null && TRANSFER in arg) { const value = (arg as Transferred<unknown>).value; collectTransferables(value, transferList); return value; } return arg; }); return { args: processedArgs, transfer: transferList };}
export function collectTransferables(value: unknown, list: Transferable[]): void { if (!(typeof value === 'object' && value !== null)) return;
// Directly transferable if ( value instanceof ArrayBuffer || value instanceof MessagePort || value instanceof ReadableStream || value instanceof WritableStream ) { list.push(value); return; }
// TypedArray or DataView — extract .buffer if (ArrayBuffer.isView(value) && value.buffer instanceof ArrayBuffer) { list.push(value.buffer); return; }
// TransformStream — extract both streams if (value instanceof TransformStream) { list.push(value.readable, value.writable); return; }}