UNPKG

@xylabs/threads

Version:

Web workers & worker threads as simple as a function call

79 lines (74 loc) 3.54 kB
import { Observable } from 'observable-fns'; import { ObservablePromise } from './observable-promise.js'; declare const $errors: unique symbol; declare const $events: unique symbol; declare const $terminate: unique symbol; declare const $transferable: unique symbol; declare const $worker: unique symbol; interface TransferDescriptor<T = any> { [$transferable]: true; send: T; transferables: Transferable[]; } interface ObservableLikeSubscription { unsubscribe(): any; } interface ObservableLike<T> { subscribe(onNext: (value: T) => any, onError?: (error: any) => any, onComplete?: () => any): ObservableLikeSubscription; subscribe(listeners: { complete?(): any; error?(error: any): any; next?(value: T): any; }): ObservableLikeSubscription; } type StripAsync<Type> = Type extends Promise<infer PromiseBaseType> ? PromiseBaseType : Type extends ObservableLike<infer ObservableBaseType> ? ObservableBaseType : Type; type StripTransfer<Type> = Type extends TransferDescriptor<infer BaseType> ? BaseType : Type; type ModuleMethods = { [methodName: string]: (...args: any) => any; }; type ProxyableArgs<Args extends any[]> = Args extends [arg0: infer Arg0, ...rest: infer RestArgs] ? [Arg0 extends Transferable ? Arg0 | TransferDescriptor<Arg0> : Arg0, ...RestArgs] : Args; type ProxyableFunction<Args extends any[], ReturnType> = Args extends [] ? () => ObservablePromise<StripTransfer<StripAsync<ReturnType>>> : (...args: ProxyableArgs<Args>) => ObservablePromise<StripTransfer<StripAsync<ReturnType>>>; type ModuleProxy<Methods extends ModuleMethods> = { [method in keyof Methods]: ProxyableFunction<Parameters<Methods[method]>, ReturnType<Methods[method]>>; }; interface PrivateThreadProps { [$errors]: Observable<Error>; [$events]: Observable<WorkerEvent>; [$terminate]: () => Promise<void>; [$worker]: Worker; } type FunctionThread<Args extends any[] = any[], ReturnType = any> = ProxyableFunction<Args, ReturnType> & PrivateThreadProps; type ModuleThread<Methods extends ModuleMethods = any> = ModuleProxy<Methods> & PrivateThreadProps; interface AnyFunctionThread extends PrivateThreadProps { (...args: any[]): ObservablePromise<any>; } interface AnyModuleThread extends PrivateThreadProps { } /** Worker thread. Either a `FunctionThread` or a `ModuleThread`. */ type Thread = AnyFunctionThread | AnyModuleThread; type TransferList = Transferable[]; /** Worker instance. Either a web worker or a node.js Worker provided by `worker_threads` or `tiny-worker`. */ interface Worker extends EventTarget { postMessage(value: any, transferList?: TransferList): void; /** In nodejs 10+ return type is Promise while with tiny-worker and in browser return type is void */ terminate(callback?: (error?: Error, exitCode?: number) => void): void | Promise<number>; } /** Event as emitted by worker thread. Subscribe to using `Thread.events(thread)`. */ declare enum WorkerEventType { internalError = "internalError", message = "message", termination = "termination" } interface WorkerInternalErrorEvent { error: Error; type: WorkerEventType.internalError; } interface WorkerMessageEvent<Data> { data: Data; type: WorkerEventType.message; } interface WorkerTerminationEvent { type: WorkerEventType.termination; } type WorkerEvent = WorkerInternalErrorEvent | WorkerMessageEvent<any> | WorkerTerminationEvent; export type { FunctionThread as F, ModuleThread as M, StripAsync as S, Thread as T, WorkerEvent as W, Worker as a };