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
TypeScript
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 {};