narraleaf-react
Version:
A React visual novel player framework
126 lines (125 loc) • 5.99 kB
TypeScript
import { Awaitable } from "../../util/data";
import { GameStateGuard } from "./guard";
type TimelineStatus = "pending" | "cancelled" | "resolved";
export declare class Timeline {
awaitable: Awaitable;
guard?: GameStateGuard | undefined;
static proxy<T>(onSettled: (resolved: Timeline[], canceled: Timeline[]) => void): [awaitable: Awaitable<T>, timeline: Timeline];
/**
* Creates a new awaitable that resolves when any of the given awaitables resolves.
* All input awaitables are attached to a timeline for global tracking and cancellation.
*
* Behavior:
* - The returned `awaitable` resolves with the value of the first resolved awaitable.
* - Cancellations of individual awaitables are ignored.
* - If the outer awaitable is aborted, the entire timeline and all child awaitables are aborted.
* - The `timeline` is returned for centralized management, but does not affect resolution logic.
*
* This is conceptually similar to `Promise.any`, but built for the Awaitable + Timeline system.
*
* @template T The resolved type of the input awaitables.
* @param {Awaitable<T>[]} awaitables An array of awaitables to monitor.
* @returns {[Awaitable<T>, Timeline]} A tuple containing:
* - an awaitable that resolves with the first resolved value
* - a timeline that includes all provided awaitables as children
*/
static any<T>(awaitables: Awaitable[]): [Awaitable<T>, Timeline];
/**
* Creates a new awaitable that resolves when all of the given awaitables resolve.
* All input awaitables are attached to a timeline for global tracking and cancellation.
*
* Behavior:
* - The returned `awaitable` resolves with an array of all resolved values in the same order as input.
* - If any awaitable is cancelled, the entire timeline is cancelled.
* - If the outer awaitable is aborted, the entire timeline and all child awaitables are aborted.
* - The `timeline` is returned for centralized management, but does not affect resolution logic.
*
* This is conceptually similar to `Promise.all`, but built for the Awaitable + Timeline system.
*
* @template T The resolved type of the input awaitables.
* @param {Awaitable<T>[]} awaitables An array of awaitables to monitor.
* @returns {[Awaitable<T[]>, Timeline]} A tuple containing:
* - an awaitable that resolves with an array of all resolved values
* - a timeline that includes all provided awaitables as children
*/
static all<T>(awaitables: Awaitable<T>[]): [Awaitable<T[]>, Timeline];
/**
* Executes a chain of asynchronous steps in sequence using the provided generator function.
*
* Each step receives the result of the previous step and returns an `Awaitable<T>`.
* The process continues until the generator returns `null`, at which point the last value is returned as the final result.
*
* This method ensures that:
* - Only one awaitable runs at a time (strict sequencing).
* - Cancellation propagates both ways:
* - If the outer awaitable is aborted, the currently running inner awaitable is also aborted.
* - If the inner awaitable triggers an abort, the sequence is cancelled and no further steps are executed.
*
* Designed for use cases such as chained animations, step-based workflows, task pipelining, or recursive async structures.
*
* @template T The type of the value passed and returned between steps.
*
* @param {function(prev: T): Awaitable<T> | null} generator
* A function that receives the result of the previous step and returns:
* - a new Awaitable<T> to continue the sequence
* - or `null` to terminate the sequence and return the last value.
*
* @param {T} initial
* The initial value passed to the generator for the first step.
*
* @returns {Awaitable<T>} A single awaitable that resolves with the last non-null result
* in the sequence, or aborts if interrupted.
*/
static sequence<T>(generator: (prev: T) => Awaitable<T> | null, initial: T): Awaitable<T>;
private children;
private _onResolved;
private _onCancelled;
private _onTimelineRegistered;
private _ableToAttach;
private _status;
get status(): TimelineStatus;
constructor(awaitable: Awaitable, guard?: GameStateGuard | undefined);
isSettled(): boolean;
isResolved(): boolean;
isCancelled(): boolean;
onResolved(callback: () => void): void;
onCancelled(callback: () => void): void;
onSettled(callback: () => void): void;
abort(): void;
attachChild(arg0: Awaitable | Timeline): this;
setGuard(guard: GameStateGuard): this;
protected catSettled(): [resolved: Timeline[], cancelled: Timeline[]];
protected onTimelineRegistered(callback: () => void): this;
private resolveStatus;
private emitEvents;
/**
* Set the status of the timeline
*
* if the status is already resolved or canceled, it'll silently ignore the status change
*/
private setStatus;
private preventAttach;
}
export declare class Timelines {
private guard?;
private timelines;
constructor(guard?: GameStateGuard | undefined);
/**
* Attaches a new timeline or an awaitable to the task pool.
* If an Awaitable is provided, it wraps it into a new Timeline.
* Automatically removes any settled timelines before pushing the new one.
*
* @param input - An Awaitable instance or an existing Timeline.
* @returns The attached Timeline instance.
*/
attachTimeline(input: Awaitable | Timeline): Timeline;
/**
* Aborts all active timelines and removes any that are already settled.
*/
abortAll(): void;
/**
* Removes timelines that have already been resolved or cancelled.
*/
private cleanupSettled;
}
export {};