import type { Event as $Event, Fn, Fn0, IDeref, IID, IIDGen, INotify, Listener, Maybe, Nullable } from "@thi.ng/api";
import type { ILogger } from "@thi.ng/logger";
import { type FiberEventType, type FiberFactory, type FiberOpts, type MaybeFiber, type State } from "./api.js";
export declare const setDefaultIDGen: (gen: IIDGen<string>) => IIDGen<string>;
export declare class Fiber<T = any> implements IDeref<Maybe<T>>, IID<string>, INotify<FiberEventType> {
    /**
     * This fiber's user provided or generated ID.
     */
    readonly id: string;
    /**
     * This fiber's parent.
     */
    readonly parent?: Fiber;
    gen: Nullable<Generator<unknown, T>>;
    idgen?: IIDGen<string>;
    state: State;
    autoTerminate: boolean;
    children: Fiber[];
    value?: T;
    error?: Error;
    logger?: ILogger;
    user?: Partial<Pick<FiberOpts, "init" | "deinit" | "catch">>;
    _promise?: Promise<Maybe<T>>;
    constructor(gen?: Nullable<FiberFactory<T> | Generator<unknown, T>>, opts?: Partial<FiberOpts>);
    /**
     * Co-routine which blocks whilst this fiber (incl. its children) is active.
     * Then return this fiber's value.
     */
    [Symbol.iterator](): Generator<undefined, T | undefined, unknown>;
    /**
     * Returns a promise which only resolves when the fiber is not active
     * anymore. If there was an unhandled error during the fiber execution the
     * promise will reject, else if the fiber (incl. children) completed on its
     * own or was cancelled, the promise resolves with the fiber's final
     * (possibly `undefined`) value.
     *
     * @remarks
     * The promise assumes the fiber either already has been (or will be)
     * scheduled & executed via other means. This promise only repeatedly checks
     * for any state changes of this fiber (at a configurable
     * frequency/interval), but does *NOT* trigger fiber execution!
     *
     * @param delay
     */
    promise(delay?: number): Promise<Maybe<T>>;
    /**
     * Returns this fiber's result value (if any). Only available if the fiber
     * completed successfully and produced a value (either by returning a value
     * from the fiber's generator or externally via {@link Fiber.done}).
     */
    deref(): T | undefined;
    /**
     * Returns true if this fiber is still in new or active state (i.e. still
     * can be processed).
     */
    isActive(): boolean;
    /**
     * Returns child fiber for given `id`.
     *
     * @param id
     */
    childForID(id: string): Fiber<any> | undefined;
    /**
     * Adds given `body` as child process to this fiber. If not already a
     * {@link Fiber} instance, it will be wrapped as such incl. with given
     * options. `opts` are only used for this latter case and will inherit this
     * (parent) fiber's {@link FiberOpts.logger} and {@link FiberOpts.idgen} as
     * defaults. Returns child fiber.
     *
     * @remarks
     * Child fibers are only processed when the parent is processed (e.g. via
     * {@link Fiber.run} or via `yield* fiber`). Also see {@link Fiber.join} to
     * wait for all child processes to finish.
     *
     * Non-active child process (i.e. finished, cancelled or errored) are
     * automatically removed from the parent. If the child fiber is needed for
     * future inspection, the return value of `fork()` should be stored by the
     * user. Whilst still active, child fibers can also be looked up via
     * {@link Fiber.childForID}.
     *
     * @example
     * ```ts tangle:../export/fork.ts
     * import { fiber, wait } from "@thi.ng/fibers";
     *
     * fiber(function* (ctx) {
     *   console.log("main start")
     *   // create 2 child processes
     *   ctx.fork(function* () {
     *     console.log("child1 start");
     *     yield* wait(500);
     *     console.log("child1 end");
     *   });
     *   // second process will take longer than first
     *   ctx.fork(function* () {
     *     console.log("child2 start");
     *     yield* wait(1000);
     *     console.log("child2 end");
     *   });
     *   // wait for children to complete
     *   yield* ctx.join();
     *   console.log("main end")
     * }).run();
     *
     * // main start
     * // child1 start
     * // child2 start
     * // child1 end
     * // child2 end
     * // main end
     * ```
     *
     * @param body
     * @param opts
     */
    fork<F>(body?: Nullable<MaybeFiber<F>>, opts?: Partial<FiberOpts>): Fiber<any>;
    /**
     * Calls {@link Fiber.fork} for all given fibers and returns them as array.
     *
     * @remarks
     * Also see {@link Fiber.join} to wait for all child processes to complete.
     *
     * @param fibers
     */
    forkAll(...fibers: MaybeFiber[]): Fiber[];
    /**
     * Waits for all child processes to complete/terminate. Use as `yield*
     * fiber.join()`.
     *
     * @remarks
     * See {@link Fiber.fork}, {@link Fiber.forkAll}.
     *
     */
    join(): Generator<undefined, void, unknown>;
    /**
     * Processes a single iteration of this fiber and any of its children. Does
     * nothing if the fiber is not active anymore. Returns fiber's state.
     *
     * @remarks
     * New, ininitialized fibers are first initialized via {@link Fiber.init}.
     * Likewise, when fibers are terminated (for whatever reason), they will be
     * de-initialized via {@link Fiber.deinit}. For all of these cases
     * (init/deinit), hooks for user customization are provided via
     * {@link FiberOpts.init}, {@link FiberOpts.deinit} and
     * {@link FiberOpts.catch}.
     */
    next(): State;
    protected init(): void;
    protected deinit(): void;
    /**
     * Cancels further processing of this fiber and its children (if any). Calls
     * {@link Fiber.deinit} and emits {@link EVENT_FIBER_CANCELED} event.
     *
     * @remarks
     * Function is a no-op if the fiber is not active anymore.
     */
    cancel(): void;
    /**
     * Stops further processing of this fiber and its children (if any) and sets
     * this fiber's value to given `value`. Calls {@link Fiber.deinit} and emits
     * {@link EVENT_FIBER_DONE} event.
     *
     * @remarks
     * Function is a no-op if the fiber is not active anymore.
     *
     * @param value
     */
    done(value?: T): void;
    /**
     * Stops further processing of this fiber, cancels all child processes (if
     * any) and sets this fiber's {@link Fiber.error} value to given `error`.
     * Calls {@link Fiber.deinit} and emits {@link EVENT_FIBER_ERROR} event.
     *
     * @remarks
     * Function is a no-op if the fiber already is in an error state. See
     * {@link FiberOpts.catch} for details about user provided error handling
     * and interception logic.
     *
     * @param err
     */
    catch(err: Error): void;
    addListener(id: FiberEventType, fn: Listener<FiberEventType>, scope?: any): boolean;
    removeListener(id: FiberEventType, fn: Listener<FiberEventType>, scope?: any): boolean;
    notify(event: $Event<FiberEventType>): boolean;
    /**
     * Calls {@link Fiber.runWith} using default loop handlers.
     *
     * @remarks
     * Current default handlers:
     *
     * - `requestAnimationFrame()` in browsers
     * - `setImmediate()` in NodeJs
     * - `setTimeout(fn, 1)` otherwise
     */
    run(): this;
    /**
     * Starts fiber execution using the provided higher-order loop/interval
     * `handler` (e.g. see {@link Fiber.run}).
     *
     * @remarks
     * That given `handler` is used to repeatedly schedule the next execution of
     * {@link Fiber.next} (indirectly, via a zero-arg helper function passed to
     * the `handler`).
     *
     * Note: **Do not use `setInterval` instead of `setTimeout`**. The given
     * `handler` must only manage a single execution step, not multiple.
     *
     * @example
     * ```ts tangle:../export/run-with.ts
     * import { fiber } from "@thi.ng/fibers";
     *
     * // start with custom higher frequency handler
     * fiber(function*() {
     *   while(true) {
     *     console.log("hello");
     *     yield;
     *   }
     * }).runWith(setImmediate);
     * ```
     *
     * @param handler
     */
    runWith(handler: Fn<Fn0<void>, void>): this;
}
/**
 * Functional syntax sugar for {@link Fiber} constructor. The `opts` are only
 * used if given a generator or {@link FiberFactory}.
 *
 * @param fiber
 * @param opts
 */
export declare const fiber: <T>(fiber?: Nullable<MaybeFiber<T>>, opts?: Partial<FiberOpts>) => Fiber<T>;
//# sourceMappingURL=fiber.d.ts.map