UNPKG

goroutines

Version:

Inspired by Go's Goroutines, this package adds an easy ability to trivially multithread (and potentially multiprocess) your code (supports NodeJS and Bun)

43 lines (42 loc) 2.54 kB
import { Worker } from 'worker_threads'; type Package = typeof import('../package.json'); type Library = (Package extends { dependencies: {}; } ? keyof Package['dependencies'] : (string & {})) | (Package extends { devDependencies: {}; } ? keyof Package['devDependencies'] : (string & {})) | (Package extends { peerDependencies: {}; } ? keyof Package['peerDependencies'] : (string & {})) | (string & {}); type ImportRecord = Partial<Record<Library, Array<`default as ${string}` | `* as ${string}` | (string & {}) | `${string} as ${string}`>>>; type Goroutine<T extends (...args: any) => any> = (...args: Parameters<T>) => ReturnType<T> extends Generator<infer U, infer R, infer N> | AsyncGenerator<infer U, infer R, infer N> ? AsyncGenerator<U, R, N> : Promise<Awaited<ReturnType<T>>>; interface GoroutineOptions { /** An abort signal to kill the process */ signal?: AbortSignal; /** * A callback called after the worker has been created * @warn Posting messages can lead to unexpected behavior * @warn Expensive/slow operations can lead to unexpected behavior. If necessary and able, make function async */ onStart?: (worker: Worker) => void | Promise<void>; /** A timeout that will kill the process if not completed within the time (resets on `.next()` for generators) */ timeoutMs?: number; } /** * Create a goroutine function that runs on another thread * @see https://github.com/exoRift/goroutines.js * @param fn The function * @note Both synchronous and asynchronous functions can be used. The return value will always be a promise. * @note Synchronous and asynchronous generators can also be used which will return async generator values. This is useful for data streaming * @param ctx Global variables to be defined for the subprocess * @param imports Packages/files to import. `{ [PACKAGE_NAME]: [...IMPORTS] }` * @example * { // Anything can be renamed using `as`. `*` collects all named exports. `default` is the default export * fs: ['default as fs'], * echarts: ['* as echarts'], // import echarts from 'echarts' * express: ['default as express', 'Router', 'json as parseJson'] // import express, { router, json as parseJson } from 'express' * } * @param options Additional goroutine options * @returns A callable goroutine function */ export declare function go<T extends (...args: any) => void>(fn: T, ctx?: Record<string, any> | null, imports?: ImportRecord | null, options?: GoroutineOptions | null): Goroutine<T>; export {};