import { Graph } from "./graph.js"; import { Behavior, BehaviorBuilder } from "./behavior.js"; import { Moment, Resource, State } from "./resource.js"; import { RelinkingOrder } from "./common.js"; /** How {@link Extent.removeFromGraph} treats extents whose lifetimes are tied to this one. */ export declare enum ExtentRemoveStrategy { extentOnly = 0, containedLifetimes = 1 } declare class ExtentLifetime { addedToGraphWhen: number | null; extents: Set; children: Set | null; parent: ExtentLifetime | null; constructor(extent: Extent); unify(extent: Extent): void; addChild(extent: Extent): void; addChildLifetime(lifetime: ExtentLifetime): void; hasCompatibleLifetime(lifetime: ExtentLifetime | null): boolean; getAllContainedExtents(): Extent[]; getAllContainingExtents(): Extent[]; } /** * A group of resources and behaviors with a shared lifetime. Subclass it, declare resources as * fields (`count = this.state(0)`), build behaviors in the constructor with * {@link Extent.behavior}, and add the instance to the graph with * {@link Extent.addToGraphWithAction}. Do not name a field after an Extent member (`state`, * `moment`, `action`, `graph`, ...); addToGraph throws if one is hidden. */ export declare class Extent { /** Internal: the subclass name, used in messages. Do not assign. */ debugConstructorName: string | undefined; /** An optional name for this extent in debugging output. */ debugName: string | undefined; /** The behaviors created on this extent. Do not assign. */ behaviors: Behavior[]; /** The resources created on this extent. Do not assign. */ resources: Resource[]; /** The graph this extent belongs to. Do not assign. */ graph: Graph; /** Sequence of the event that added this extent to the graph, or null when it is not in the graph. */ addedToGraphWhen: number | null; /** Internal: sequence of the event that removed this extent. Do not assign. */ removedFromGraphWhen: number | null; /** True while the extent is in the graph; justUpdated in the event that adds it. Demand it to run a behavior on add. */ addedToGraph: State; /** Internal: set by unifyLifetime and addChildLifetime. Do not assign. */ lifetime: ExtentLifetime | null; /** Internal: subscriptions to cancel on removal. Do not assign. */ unsubscribes: Set<() => void>; /** Shorthand for {@link ExtentRemoveStrategy.containedLifetimes}. */ static readonly removeContainedLifetimes = ExtentRemoveStrategy.containedLifetimes; /** Shorthand for {@link RelinkingOrder.relinkingOrderSubsequent}. */ static readonly relinkingOrderSubsequent = RelinkingOrder.relinkingOrderSubsequent; constructor(graph: Graph); /** Same as {@link Graph.debugHere}. */ debugHere(): string; /** * Gives `extent` the same lifetime as this one, so behaviors on either may statically demand * and supply the other's resources. Both must then be added to the graph in the same event. */ unifyLifetime(extent: T): void; /** * Makes `extent` a child of this one: the child's behaviors may statically demand this * extent's resources, and removing this extent with * {@link ExtentRemoveStrategy.containedLifetimes} removes the child too. Call it before the * child is added to the graph. This extent reaches the child's resources only through * dynamicDemands. */ addChildLifetime(extent: T): void; /** Adds this extent to the graph in a new action. Use it at setup, outside any event. */ addToGraphWithAction(debugName?: string): void; /** * Adds this extent's resources and behaviors to the graph. Only valid inside an event (an * action or a behavior); use {@link Extent.addToGraphWithAction} from outside one. */ addToGraph(): void; /** Removes this extent from the graph in a new action. */ removeFromGraphWithAction(strategy?: ExtentRemoveStrategy, debugName?: string): void; /** * Removes this extent from the graph; with {@link ExtentRemoveStrategy.containedLifetimes}, * also every extent whose lifetime it contains. Only valid inside an event. Behaviors of a * removed extent stop running and updates to its resources are ignored. In the same event, * update whatever switches other behaviors' dynamic demands on its resources. */ removeFromGraph(strategy?: ExtentRemoveStrategy): void; /** * Like {@link Graph.subscribeToJustUpdated}, passing this extent to `callback`. The * subscription ends when the extent is removed. Returns an unsubscribe function. */ subscribeToJustUpdated(resources: Resource[], callback: (ext: this) => void): () => void; /** * Starts a behavior: chain `.demands(...)`, `.supplies(...)` and optionally * `.dynamicDemands(...)` or `.dynamicSupplies(...)`, then finish with `.runs(block)`. */ behavior(): BehaviorBuilder; /** Creates a resource with no value, for ordering (`r.order`) or as a link anchor. */ resource(name?: string): Resource; /** Creates a {@link Moment}: something that happened in one event, with an optional payload. */ moment(name?: string): Moment; /** Creates a {@link State}: a value that persists across events. */ state(initialState: T, name?: string): State; /** * Queues `block` to run, with this extent as its argument, after every activated behavior in * the current event has run. Side effects run in the order queued and are the only place to * touch the outside world (render, log, fetch, timers) or start another action. Only valid * inside a behavior or action. */ sideEffect(block: (ext: this) => void, debugName?: string): void; /** Like {@link Graph.actionAsync}, passing this extent to the block. */ actionAsync(action: (ext: this) => void, debugName?: string): Promise; /** Like {@link Graph.action}, passing this extent to the block. */ action(action: (ext: this) => void, debugName?: string): void; } export {};