@thi.ng/fibers
Version:
Process hierarchies & operators for cooperative multitasking
248 lines • 8.05 kB
TypeScript
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