/** * Typed, explicit main/worker transport with state, event, and RPC lanes. * * This module intentionally knows nothing about Three.js, the DOM, or the runtime * dispatcher. Applications map only the protocol fields they deliberately expose. * * @module three-blocks/worker */ export declare const WORKER_PROTOCOL_VERSION = 1; export type StructuredClonePrimitive = null | undefined | void | boolean | number | bigint | string; export type StructuredCloneBuiltin = ArrayBuffer | ArrayBufferView | Date | RegExp | SharedArrayBuffer; declare const TRANSFERABLE_VALUE: unique symbol; /** Explicitly marks an opaque host value that is sent once through a transfer list. */ export type TransferableValue = TValue & { readonly [TRANSFERABLE_VALUE]: true; }; /** Identity helper making transfer-only protocol fields visible to the type system. */ export declare function asTransferable(value: TValue): TransferableValue; /** Values accepted by the browser structured-clone algorithm or a transfer list. */ export type StructuredCloneable = StructuredClonePrimitive | StructuredCloneBuiltin | readonly StructuredCloneable[] | { readonly [key: string]: StructuredCloneable; }; /** Recursively preserves a contract shape while replacing non-cloneable members with never. */ export type StructuredCloneableShape = TValue extends TransferableValue ? TValue : TValue extends (...args: never[]) => unknown ? never : TValue extends StructuredClonePrimitive | StructuredCloneBuiltin ? TValue : TValue extends ReadonlyMap ? ReadonlyMap, StructuredCloneableShape> : TValue extends ReadonlySet ? ReadonlySet> : TValue extends readonly (infer TEntry)[] ? readonly StructuredCloneableShape[] : TValue extends object ? { readonly [TKey in keyof TValue]: StructuredCloneableShape; } : never; type CloneableContractArguments = TState extends StructuredCloneableShape ? TEvents extends StructuredCloneableShape ? TRequests extends StructuredCloneableShape ? [options?: TOptions] : [options: TOptions | undefined, structuredCloneContractError: never] : [options: TOptions | undefined, structuredCloneContractError: never] : [options: TOptions | undefined, structuredCloneContractError: never]; export type WorkerLifecyclePhase = 'connect' | 'state' | 'event' | 'request' | 'response' | 'transport' | 'dispose'; export interface SerializedWorkerError { readonly name: string; readonly message: string; readonly stack?: string; readonly source?: string; readonly lifecyclePhase: WorkerLifecyclePhase; readonly code?: string; } export interface SerializeWorkerErrorOptions { readonly source?: string; readonly lifecyclePhase: WorkerLifecyclePhase; readonly code?: string; } export type WorkerTransportErrorCode = 'clone-rejected' | 'disposed' | 'endpoint-replaced' | 'invalid-message' | 'missing-handler' | 'no-endpoint' | 'not-connected' | 'protocol-mismatch' | 'remote-error' | 'sequence-error' | 'transport-error'; export declare class WorkerTransportError extends Error { readonly code: WorkerTransportErrorCode; readonly serialized: SerializedWorkerError | undefined; constructor(code: WorkerTransportErrorCode, message: string, serialized?: SerializedWorkerError); } export declare class RemoteWorkerError extends Error { readonly remote: SerializedWorkerError; constructor(remote: SerializedWorkerError); } export interface MessageEventLike { readonly data: T; } export type MessageEndpointListener = (event: MessageEventLike) => void; /** The DOM-free subset shared by Worker, MessagePort, and Node MessagePort adapters. */ export interface MessageEndpoint { postMessage(message: unknown, transfer?: readonly object[]): void; addEventListener(type: 'message', listener: MessageEndpointListener): void; removeEventListener(type: 'message', listener: MessageEndpointListener): void; start?(): void; close?(): void; } /** * Structural browser endpoint accepted without application-side casts. * * The deliberately non-callable `never[]` signatures let the native overloads on * Worker, MessagePort, and DedicatedWorkerGlobalScope satisfy this contract while all * calls remain centralized in `messageEndpoint()` below. */ export interface BrowserMessageEndpoint { postMessage(...arguments_: never[]): unknown; addEventListener(...arguments_: never[]): unknown; removeEventListener(...arguments_: never[]): unknown; start?(...arguments_: never[]): unknown; close?(...arguments_: never[]): unknown; } export type MessageEndpointSource = MessageEndpoint | BrowserMessageEndpoint; /** Normalize a native Worker, MessagePort, worker global, or test adapter once. */ export declare function messageEndpoint(source: MessageEndpointSource): MessageEndpoint; export interface RequestDefinition { readonly parameters: TParameters; readonly result: TResult; } export type RequestParameters = TDefinition extends RequestDefinition ? TParameters : never; export type RequestResult = TDefinition extends RequestDefinition ? TResult : never; export interface SendOptions { readonly transfer?: readonly object[]; } export type CloneValue = (value: unknown) => unknown; export interface WorkerClientOptions { readonly protocolVersion?: number; readonly source?: string; readonly validateStructuredClone?: boolean; readonly cloneValue?: CloneValue; readonly closeEndpointOnReplace?: boolean; readonly closeEndpointOnDispose?: boolean; readonly onError?: (error: SerializedWorkerError) => void; } export interface WorkerServerOptions { readonly protocolVersion?: number; readonly source?: string; readonly validateStructuredClone?: boolean; readonly cloneValue?: CloneValue; readonly closeEndpointOnDispose?: boolean; readonly onError?: (error: SerializedWorkerError) => void; } export interface WorkerHandlerContext { readonly key: TName; readonly protocolVersion: number; readonly source: string; } export interface WorkerStateHandlerContext extends WorkerHandlerContext { readonly lane: 'state'; readonly sequence: number; } export interface WorkerEventHandlerContext extends WorkerHandlerContext { readonly lane: 'event'; readonly sequence: number; } export interface WorkerRequestHandlerContext extends WorkerHandlerContext { readonly lane: 'request'; readonly requestId: string; } type StringKey = Extract; type MaybePromise = TValue | PromiseLike; export declare class WorkerTransfer { readonly value: TResult; readonly transfer: readonly object[]; constructor(value: TResult, transfer: readonly object[]); } export declare function withTransfer(value: TResult, transfer: readonly object[]): WorkerTransfer; export type WorkerStateHandlers = { [TName in StringKey]?: (value: TState[TName], context: WorkerStateHandlerContext) => MaybePromise; }; export type WorkerEventHandlers = { [TName in StringKey]?: (value: TEvents[TName], context: WorkerEventHandlerContext) => MaybePromise; }; export type WorkerRequestHandlers = { [TName in StringKey]?: (parameters: RequestParameters, context: WorkerRequestHandlerContext) => MaybePromise | WorkerTransfer>>; }; export interface WorkerServerHandlers { readonly state?: WorkerStateHandlers; readonly events?: WorkerEventHandlers; readonly requests?: WorkerRequestHandlers; } export interface WorkerStateLane { /** Transfer-bearing state is sent once and cannot be retained for endpoint replay. */ set>(name: TName, value: TState[TName], options?: SendOptions): void; clear>(name: TName): void; } export interface WorkerEventLane { emit>(name: TName, value: TEvents[TName], options?: SendOptions): void; } export interface WorkerRpcLane { request>(name: TName, parameters: RequestParameters, options?: SendOptions): Promise>; } export declare function serializeWorkerError(error: unknown, options: SerializeWorkerErrorOptions): SerializedWorkerError; /** Main-side transport retaining only latest state across endpoint replacement. */ export declare class WorkerClient { #private; readonly state: WorkerStateLane; readonly events: WorkerEventLane; readonly rpc: WorkerRpcLane; constructor(...arguments_: CloneableContractArguments); get connected(): boolean; get disposed(): boolean; get lastError(): SerializedWorkerError | undefined; replaceEndpoint(source: MessageEndpointSource): Promise; dispose(): void; } /** Worker-side adapter invoking only the explicitly supplied state/event/RPC maps. */ export declare class WorkerServer { #private; constructor(source: MessageEndpointSource, handlers: WorkerServerHandlers, ...arguments_: CloneableContractArguments); get disposed(): boolean; whenIdle(): Promise; dispose(): void; } export declare function createWorkerClient(...arguments_: CloneableContractArguments): WorkerClient; export declare function createWorkerServer(endpoint: MessageEndpointSource, handlers: WorkerServerHandlers, ...arguments_: CloneableContractArguments): WorkerServer; export {};