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