/**
 * Low-level reactive DAG runtime for parameter propagation.
 *
 * `GraphRuntime` is the scheduling engine behind `ParamRuntime`. It owns:
 * 1. Writable source nodes (`base` and `selection`).
 * 2. Derived/computed nodes with explicit dependencies.
 * 3. Side-effect nodes that run after computed stabilization.
 * 4. Transaction-aware batching and deterministic topological flushing.
 *
 * Typical usage:
 * 1. Create writable refs using `createWritable(...)`.
 * 2. Build derived refs with `computed(...)` from existing refs.
 * 3. Attach side effects with `effect(...)` when external work is needed.
 * 4. Batch writes with `runInTransaction(...)` when multiple updates belong to
 *    one logical state transition.
 * 5. Await `whenPropagated(...)` when callers need a "graph is settled" barrier.
 *
 * Notes:
 * 1. This class is intended for runtime internals; most call sites should use
 *    `ParamRuntime` / `ViewParamRuntime`.
 * 2. Equality is referential (`!==`), so object writes must use new identities
 *    to trigger propagation.
 */
export default class GraphRuntime {
    /**
     * Creates a graph runtime.
     *
     * @param {object} [options]
     * @param {import("./lifecycleRegistry.js").default} [options.lifecycleRegistry]
     *      Optional lifecycle owner registry. When provided, all created nodes
     *      are bound to owners and disposed automatically on owner disposal.
     */
    constructor(options?: {
        lifecycleRegistry?: import("./lifecycleRegistry.js").default;
    });
    /**
     * Registers a writable source node and returns a writable param ref.
     *
     * Write semantics:
     * 1. A write triggers propagation only when `value !== currentValue`.
     * 2. If `options.notify` is `false`, local listeners are not notified and
     *    downstream scheduling is skipped for writes to this ref.
     * 3. Writing to a disposed ref throws.
     *
     * Lifecycle:
     * 1. The node is owner-bound via `ownerId`.
     * 2. Owner disposal marks the node disposed and clears listeners.
     *
     * @template T
     * @param {string} ownerId
     * @param {string} name
     * @param {"base" | "selection"} kind
     * @param {T} initialValue
     * @param {{ notify?: boolean }} [options]
     * @returns {import("./types.js").WritableParamRef<T>}
     */
    createWritable<T>(ownerId: string, name: string, kind: "base" | "selection", initialValue: T, options?: {
        notify?: boolean;
    }): import("./types.js").WritableParamRef<T>;
    /**
     * Registers a derived node whose value is computed from dependencies.
     *
     * Compute semantics:
     * 1. Initial value is computed eagerly at registration time.
     * 2. On dependency changes, recomputation is queued (deduplicated per flush).
     * 3. Downstream listeners are notified only if computed value identity changes.
     *
     * Lifecycle:
     * 1. Dependency subscriptions are created immediately.
     * 2. Owner disposal unsubscribes dependencies and detaches the node.
     *
     * @template T
     * @param {string} ownerId
     * @param {string} name
     * @param {import("./types.js").ParamRef<any>[]} deps
     * @param {() => T} fn
     * @returns {import("./types.js").ParamRef<T>}
     */
    computed<T>(ownerId: string, name: string, deps: import("./types.js").ParamRef<any>[], fn: () => T): import("./types.js").ParamRef<T>;
    /**
     * Registers an effect node that runs after computed propagation.
     *
     * Effect semantics:
     * 1. Effect callbacks are queued on dependency changes.
     * 2. Effects run after computed nodes for the same flush epoch.
     * 3. Multiple dependency changes before a flush coalesce to one queued run.
     *
     * @param {string} ownerId
     * @param {import("./types.js").ParamRef<any>[]} deps
     * @param {() => void} fn
     * @returns {() => void} explicit disposer for manual teardown
     */
    effect(ownerId: string, deps: import("./types.js").ParamRef<any>[], fn: () => void): () => void;
    /**
     * Runs `fn` as an atomic update transaction for this runtime graph.
     *
     * Transaction intent:
     * 1. Batch multiple source writes so downstream computeds/effects observe
     *    the final state for the batch, not each intermediate write.
     * 2. Defer scheduling/flush until the outermost transaction exits.
     * 3. Preserve deterministic propagation order by running one flush pass
     *    after the transaction boundary.
     *
     * Semantics:
     * 1. Nested transactions are supported via depth counting.
     * 2. Only the outermost transaction exit triggers scheduling.
     * 3. If `fn` throws, the error is rethrown after transaction depth is
     *    restored; pending propagation is still scheduled from `finally`.
     * 4. The scheduled flush runs in a microtask (`queueMicrotask`) after the
     *    outermost transaction exits.
     * 5. This method does not force immediate synchronous propagation. Use
     *    `flushNow()` when the caller explicitly requires immediate flushing.
     *
     * @template T
     * @param {() => T} fn
     * @returns {T}
     */
    runInTransaction<T>(fn: () => T): T;
    /**
     * Flushes currently queued computed/effect work immediately.
     *
     * Behavior:
     * 1. No-op if called while a transaction is open.
     * 2. No-op during re-entrant flush calls.
     * 3. Runs computeds first, then effects, until the graph reaches a fixed
     *    point for the current queued work.
     */
    flushNow(): void;
    /**
     * Returns a promise that resolves when currently pending graph propagation
     * has completed (computed queue and effect queue are settled).
     *
     * This is a synchronization barrier for reactive propagation only. It does
     * not include animation/time-based convergence semantics.
     *
     * @param {{ signal?: AbortSignal, timeoutMs?: number }} [options]
     *      Optional cancellation/timeout controls for waiting callers.
     * @returns {Promise<void>}
     */
    whenPropagated(options?: {
        signal?: AbortSignal;
        timeoutMs?: number;
    }): Promise<void>;
    #private;
}
export type SubscribeFn = (listener: () => void) => () => void;
export type RuntimeNodeBase = {
    id: string;
    rank: number;
    disposed: boolean;
    listeners: Set<() => void>;
    subscribe: SubscribeFn;
};
export type WritableNode<T> = RuntimeNodeBase & {
    value: T;
    kind: "base" | "selection";
    name: string;
};
export type ComputedNode<T> = RuntimeNodeBase & {
    value: T;
    kind: "derived";
    name: string;
    fn: () => T;
};
export type EffectNode = {
    id: string;
    rank: number;
    disposed: boolean;
    fn: () => void;
};
/**
 * @param {import("./types.js").ParamRef<any>} ref
 * @returns {RuntimeNodeBase}
 */
export function getNode(ref: import("./types.js").ParamRef<any>): RuntimeNodeBase;
//# sourceMappingURL=graphRuntime.d.ts.map