import { Behavior } from "./behavior.js"; import { Resource } from "./resource.js"; import { DateProvider, GraphEvent } from "./common.js"; /** * Owns the event loop. Usually there is one per application. Every {@link Extent} belongs to a * graph, and every change to the graph's resources happens inside an event that an action opens. * * See AGENT_GUIDE.md in this package for the mental model, patterns and errors. */ export declare class Graph { /** Supplies the timestamp of each new event. Replace it to control time in tests. */ dateProvider: DateProvider; /** The event in progress, or null between events. */ currentEvent: GraphEvent | null; /** The last completed event. Sequence 0 before the first action. */ lastEvent: GraphEvent; /** The behavior whose `runs` block is executing, or null (including during side effects). */ currentBehavior: Behavior | null; /** * When true (the default), a behavior may statically demand or supply another extent's * resources only if that extent has the same lifetime ({@link Extent.unifyLifetime}) or is an * ancestor ({@link Extent.addChildLifetime}). Reach other extents through dynamicDemands. */ validateLifetimes: boolean; /** * When true, a behavior may read `state.traceValue` or `state.traceEvent` only if it supplies * or demands the state, or declares `state.trace` in its demands. On by default since 2.0; * set it to false to run 1.x code that reads traceValue without declaring it while migrating. */ validateTraceDemands: boolean; constructor(); /** * Opens an event, runs `block`, then runs every activated behavior and side effect. Returns * when the event, and any events its side effects started, have completed. Inside `block`, * update resources that no behavior supplies. Throws if called inside a behavior or another * action; start actions from side effects or outside code. */ action(block: () => void, debugName?: string): void; /** * Like {@link Graph.action}, but returns a promise that resolves when the action's event has * completed. Called during an event (from a side effect), the action is queued and runs after * the current event rather than nested. Prefer `action` unless you need this. */ actionAsync(block: () => void, debugName?: string): Promise; private eventLoop; private validateAddedExtents; private validateRemovedExtents; private clearTransients; private activateBehavior; private runNextBehavior; /** * Runs `callback` as a side effect at the end of any event in which one of `resources` * updated. Reading resource values inside it is allowed. Returns an unsubscribe function. */ subscribeToJustUpdated(resources: Resource[], callback: () => void): () => void; private turnSubscriptionsIntoSideEffects; /** * Queues `block` to run after every activated behavior in the current event has run. Side * effects run in the order queued and are the place to touch the outside world. Only valid * inside a behavior or action. Prefer {@link Extent.sideEffect}, which passes the extent. */ sideEffect(block: () => void, debugName?: string): void; /** Text describing the current event: its sequence, the resources its action updated, and the current behavior. */ debugHere(): string; private addUntrackedBehaviors; private addUntrackedSupplies; private addUntrackedDemands; private orderBehaviors; private sortDFS; /** The resources on a dependency cycle through `behavior`, or an empty array if there is none. */ debugCycleForBehavior(behavior: Behavior): Resource[]; private cycleDFS; }