/** * JQHTML Component Lifecycle Queue * * One lock per component. Serializes boot with render(), load(), reload() and refresh(): * * - Boot is the first entry. Every entry - boot included - holds the lock from its start * through the end of its own on_ready(). A call made meanwhile, including one made * from inside on_ready(), waits and starts after it - unless it is awaited while that * on_ready() is still running: then promote() runs it at once, nested. * - A call made while the lock is held waits as a pending entry; pending entries run in * call order, one at a time. * - A new call merges only into the LAST pending entry (never the running one), and only * when it has the same key (same method, same arguments). The merged caller does not * run; it settles with the result of the entry it merged into. Different keys never * merge: reload, refresh, reload stays three entries. * - A caller is settled BEFORE the next pending entry starts. */ export interface Queue_Entry { /** Method plus arguments: 'render', 'load', 'reload' (reload(), reload(true)), 'refresh' (refresh(), reload(false)) */ key: string; executor: () => Promise; resolvers: Array<(value: T) => void>; rejecters: Array<(error: any) => void>; } export declare class Component_Queue { private _on_idle; /** * True while boot or an entry holds the lock - and through the macrotask gap between a * finished entry and the next pending one, so nothing can jump ahead of the queue. */ private _busy; /** True from begin_boot() until end_boot() */ private _booting; /** Entries waiting for the lock, in call order */ private _pending; /** Promoted entries still running (see promote()) */ private _promoted_running; /** The lock holder finished while promoted entries still ran; release when they end */ private _release_deferred; /** @param _on_idle - Called whenever the lock is released with nothing waiting */ constructor(_on_idle: () => void); /** True while calls are waiting for the lock. */ get has_pending(): boolean; /** True while a promoted entry is still running. */ get promoted_running(): boolean; /** Boot start: boot is the first entry and takes the lock. */ begin_boot(): void; /** * Boot ended: after its on_ready(), or early (stopped, threw, truncated lifecycle). * Releases the lock. Safe to call more than once. */ end_boot(): void; /** * Run `executor` now if the component is idle, otherwise queue it. * * @param key - Method plus arguments. Only an identical key merges. * @param executor - The async operation. It reads this.args when it STARTS, so a * merged caller gets the newest args. * @returns The promise that settles with the result of the entry that ran, and the * pending entry the call is waiting on (null when it started at once) - the * handle promote() takes. */ enqueue(key: string, executor: () => Promise): { promise: Promise; entry: Queue_Entry | null; }; /** * Run a pending entry NOW, nested inside the cycle that holds the lock: the cycle's * on_ready() is awaiting it, and would otherwise wait forever. The entry leaves the * queue (so no later call merges into it); the lock stays with the running cycle. The * lock is not released while a promoted entry still runs, even when the cycle that * holds it ends first, so nothing queued can start alongside it. * @returns false when the entry is no longer pending (already started or promoted) */ promote(entry: Queue_Entry): boolean; /** * Run one entry, settle its callers, then release the lock. * @private */ private _run; /** * Run an entry's executor and settle its callers. Touches no lock state. * @private */ private _execute; /** * Release the lock, or hand it to the next pending entry. * @private */ private _release; } /** * The promise render(), load(), reload() and refresh() return when they are called while * one of the component's own on_loaded() or on_ready() is running. * * `await` (and any chaining) calls .then() on a non-native promise, so .then() is where * awaiting is seen. The first .then() runs `on_then` once: during on_ready() it pulls the * queued call forward so it runs at once instead of deadlocking; during on_loaded() it * warns (development). * * Derived promises (.then()/.catch()/.finally() results) are plain Promises. */ export declare class Lifecycle_Call_Promise extends Promise { static get [Symbol.species](): PromiseConstructor; private _on_then; /** * @param promise - The queued call's promise * @param on_then - Run once, on the first .then() (await or chain) */ static wrap(promise: Promise, on_then: () => void): Lifecycle_Call_Promise; then(on_fulfilled?: ((value: T) => R1 | PromiseLike) | null, on_rejected?: ((reason: any) => R2 | PromiseLike) | null): Promise; } //# sourceMappingURL=component-queue.d.ts.map