UNPKG

@thi.ng/fibers

Version:

Process hierarchies & operators for cooperative multitasking

248 lines 8.05 kB
import type { Fn, Fn0, Predicate } from "@thi.ng/api"; import type { IRandom } from "@thi.ng/random"; import { type FiberOpts, type MaybeFiber, type State } from "./api.js"; import { Fiber } from "./fiber.js"; /** * Returns co-routine which "blocks" for given number of milliseconds or * indefinitely. * * @param delay */ export declare const wait: (delay?: number) => Fiber<void>; /** * Returns ES6 generator which "blocks" for given number of frames. * * @param delay */ export declare function waitFrames(delay: number): Generator<undefined, void, unknown>; /** * Returns a fiber which executes given fibers in sequence until all are * complete or one of them errored or got canceled. * * @param fibers * @param opts */ export declare const sequence: (fibers: Iterable<MaybeFiber>, opts?: Partial<FiberOpts>) => Fiber<unknown>; /** * Returns a fiber which executes given fibers as child processes until **one** * of them is finished/terminated. That child fiber itself will be the result. * * @remarks * Also see {@link withTimeout}, {@link all}. * * @example * ```ts * import { first, untilEvent, wait } from "@thi.ng/fibers"; * * // wait until mouse click for max 5 seconds * const res = yield* first([ * untilEvent(window, "click", { id: "click" }), * wait(5000) * ]); * * // one way to check result * if (res.id === "click") { ... } * ``` * * @param fibers * @param opts */ export declare const first: (fibers: Iterable<MaybeFiber>, opts?: Partial<FiberOpts>) => Fiber<Fiber<any>>; /** * Returns a fiber which executes given fibers as child processes until **all** * of them are finished/terminated. * * @remarks * Also see {@link first}. * * @param fibers * @param opts */ export declare const all: (fibers: Iterable<MaybeFiber>, opts?: Partial<FiberOpts>) => Fiber<void>; /** * Syntax sugar common use cases of {@link first} where a child fiber should be * limited to a max. time period before giving up. * * @example * ```ts * import { untilPromise, withTimeout } from "@thi.ng/fibers"; * * // wait for fetch response max. 5 seconds * const res = yield* withTimeout(untilPromise(fetch("example.json")), 5000); * * if (res.deref() != null) { ... } * ``` * * @param body * @param timeout * @param opts */ export declare const withTimeout: (body: MaybeFiber, timeout: number, opts?: Partial<FiberOpts>) => Fiber<Fiber<any>>; /** * Higher-order fiber which repeatedly executes given `fiber` until its * completion, but does so in a time-sliced manner, such that the fiber never * consumes more than `maxTime` milliseconds per update cycle. * * @param fiber * @param maxTime * @param opts */ export declare const timeSlice: (body: MaybeFiber, maxTime: number, opts?: Partial<FiberOpts>) => Fiber<void>; /** * Similar to {@link timeSlice}, but for consuming the given iterable in a * time-sliced manner. With each fiber update consumes & buffers values from * `src` in chunks for `maxTime` milliseconds, then passes recorded chunk to * given `consume` function in order to process these values further. * * @example * ```ts tangle:../export/timeslice-iterable.ts * import { timeSliceIterable } from "@thi.ng/fibers"; * import { range } from "@thi.ng/transducers"; * * // consume & batch process iterable in 16ms time slices * timeSliceIterable( * range(1_000_000), * (chunk) => console.log("items:", chunk.length), * 16 * ).run(); * ``` * * @param src * @param consume * @param maxTime * @param opts */ export declare const timeSliceIterable: <T>(src: Iterable<T>, consume: Fn<T[], void>, maxTime: number, opts?: Partial<FiberOpts>) => Fiber<void>; /** * Returns a fiber which "blocks" until given predicate function returns true. * * @remarks * See {@link untilState} for stateful version. * * @param pred */ export declare function until(pred: Fn0<boolean>): Generator<undefined, void, unknown>; /** * Stateful version of {@link until}. Takes an arbitrary `state` * value/container and returns a fiber which "blocks" until given predicate * function returns true. The `state` is passed to the predicate in each * iteration. * * @param state * @param pred */ export declare function untilState<T>(state: T, pred: Predicate<T>): Generator<undefined, void, unknown>; /** * Returns a fiber which "blocks" until the given `promise` resolves or rejects. * In the latter case, the fiber will throw the received error. * * @remarks * If the fiber was added to a parent {@link Fiber}, the error will be logged * and the fiber removed from the parent. See {@link Fiber.next} for details. * * @param promise * @param opts */ export declare const untilPromise: <T>(promise: PromiseLike<T>, opts?: Partial<FiberOpts>) => Fiber<T>; /** * Returns fiber which attaches a one-off event handler for event `type` to * `target` and then "blocks" until the event occurred. * * @remarks * The event handler will be removed when the fiber terminates. Upon completion, * the event will be the fiber's {@link Fiber.value}. * * @param target * @param type * @param opts */ export declare const untilEvent: (target: EventTarget, type: string, opts?: Partial<FiberOpts>) => Fiber<unknown>; /** * Custom fiber implementation for {@link shuffle}. */ export declare class Shuffle extends Fiber { rnd: IRandom; constructor(fibers: Iterable<MaybeFiber>, opts?: Partial<FiberOpts & { rnd: IRandom; }>); next(): State; } /** * Higher-order fiber for creating a constantly randomized execution order of * given `fibers`, e.g. for distributing workloads. Creates and returns a new * fiber as parent of the given `fibers` which then shuffles their execution * order on each {@link Fiber.next} invocation/update. The fiber terminates when * all children are done. * * @remarks * The `rnd` option can be used to customize the * [`IRandom`](https://docs.thi.ng/umbrella/random/interfaces/IRandom.html) * implementation used for shuffling. Defaults to * [`SYSTEM`](https://docs.thi.ng/umbrella/random/variables/SYSTEM.html). * * @example * ```ts tangle:../export/shuffle.ts * import { shuffle } from "@thi.ng/fibers"; * import { repeatedly } from "@thi.ng/transducers"; * * // create & run fiber with 16 children, executing in random order * shuffle( * repeatedly( * (id) => function*() { while(true) { console.log(`worker #${id}`); yield; } }, * 16 * ) * ).run() * * // worker #0 * // worker #1 * // worker #3 * // worker #3 * // worker #2 * // worker #0 * // worker #2 * // ... * ``` * * @param fibers * @param opts */ export declare const shuffle: (fibers: Iterable<MaybeFiber>, opts?: Partial<FiberOpts & { rnd: IRandom; }>) => Shuffle; /** * Helper function to await fiber-based task completion from within an `async` * context. Wraps given `task` in a fiber with custom {@link FiberOpts.deinit} * and {@link FiberOpts.catch} handlers and executes it. Returns a promise which * resolves with that fiber's final value once its complete. If there is an * error during fiber execution the promise will be rejected with that original * error. * * @remarks * If `opts` are given, their {@link FiberOpts.deinit} and * {@link FiberOpts.catch} handlers will be augmented with resolving/rejecting * the promise. I.e. The promise will NOT be rejected if there's a user-provided * `catch` handler indicating the error has been dealt with. * * @example * ```ts tangle:../export/as-promise.ts * import { asPromise, wait } from "@thi.ng/fibers"; * * (async () => { * // create & spawn task/fiber * const task = asPromise(function*() { * for(let i = 0; i< 3; i++) { * console.log("working...", i); * yield* wait(1000); * } * return 42; * }); * // now wait for task to complete * const result = await task; * console.log("final result", result); * })() * ``` * * @param task */ export declare const asPromise: <T>(task: MaybeFiber<T>, opts?: Partial<FiberOpts>) => Promise<T>; //# sourceMappingURL=ops.d.ts.map