/** * Bounded per-`(name, revision)` load-state diagnostics for dynamic * workflow sources (WFT-15/16): the `idle -> loading -> ready|failed` * state machine, waiter-count bookkeeping, and the `loading -> cancelled` * transition. The `record*`/`begin*`/`end*` functions are pure state * mutation, individually unit-testable; the `*AndDispatch` wrappers pair * each with the matching `workflow-source:load-*` event, gated on the pure * function's boolean return so a late, orphaned settle never re-dispatches * `ready`/`failed` after the key already moved to `cancelled`, and a fresh * attempt for the same key resets cleanly back to `loading` first. * `source-resolution.ts` calls only the `*AndDispatch` wrappers. * * @module core/engine/source-diagnostics */ import type { WorkflowSourceKind } from '../source/index.ts'; import type { Engine } from './index.ts'; import type { EngineInternals } from './internals.ts'; import { type SourceLoadDiagnostics } from './source-runtime-state.ts'; /** Bounded diagnostics for one `(name, revision)`, or `undefined` when no load was ever attempted. */ export declare function readSourceLoadDiagnostics(internals: EngineInternals, name: string, revision: string): SourceLoadDiagnostics | undefined; /** Record that a fresh shared load for `(name, revision)` just started. */ export declare function recordSourceLoadStarted(internals: EngineInternals, name: string, revision: string, kind: WorkflowSourceKind, now: number): void; /** * Record a successful load, UNLESS the key already moved on (a `cancelled` * transition from the last waiter releasing, or a fresh attempt already * reset it back to `loading` for a NEW load this settle does not belong * to). Returns whether the caller should dispatch `WorkflowSourceLoadReadyEvent`. */ export declare function recordSourceLoadReady(internals: EngineInternals, name: string, revision: string, now: number): boolean; /** The failed-load counterpart of {@link recordSourceLoadReady}. */ export declare function recordSourceLoadFailed(internals: EngineInternals, name: string, revision: string, now: number, error: unknown): boolean; /** Increment the outstanding-waiter count for `(name, revision)`. Call once per `resolveWorkflowSource()` call, before any await. */ export declare function beginSourceWaiter(internals: EngineInternals, name: string, revision: string): void; /** * Decrement the outstanding-waiter count for `(name, revision)`; call in * every `resolveWorkflowSource()` call's own `finally`. Returns whether * this was the LAST outstanding waiter releasing while the shared load is * still `loading` — the caller should transition diagnostics to * `cancelled` and dispatch `WorkflowSourceLoadCancelledEvent`. */ export declare function endSourceWaiterAndCheckCancellation(internals: EngineInternals, name: string, revision: string): boolean; /** * When a new caller joins a still-in-flight shared load whose diagnostics * were marked `cancelled` (the last waiter released while the shared * promise was still unsettled, and a later caller then joined that SAME * orphaned promise instead of starting a fresh one — single-flight never * aborts the shared load itself, only per-caller waiter interest), restore * the state to `loading` so the eventual settle reaches its normal * `ready`/`failed` transition instead of being silently suppressed by * `recordSourceLoadReady`/`recordSourceLoadFailed`'s own `state !== * 'loading'` guard. Never dispatches a fresh `WorkflowSourceLoadStartedEvent` * — the load itself did not restart, only diagnostics visibility into it * did. A no-op for any state other than `cancelled` (in particular, * `getOrCreateSharedSourceLoad`'s cache-miss branch already sets `loading` * itself via {@link recordSourceLoadStartedAndDispatch} for a genuinely new * load, so this never fires there). */ export declare function reviveOrphanedSourceLoadDiagnostics(internals: EngineInternals, name: string, revision: string): void; /** Current outstanding-waiter count for `(name, revision)`. */ export declare function readSourceWaiterCount(internals: EngineInternals, name: string, revision: string): number; /** Bundles the identity a `source-resolution.ts` call site already has in scope, so the `*AndDispatch` wrappers below take one argument instead of five. */ export type SourceEventContext = { engine: Engine; internals: EngineInternals; name: string; revision: string; kind: WorkflowSourceKind; }; /** {@link recordSourceLoadStarted} plus dispatching `WorkflowSourceLoadStartedEvent`. */ export declare function recordSourceLoadStartedAndDispatch(ctx: SourceEventContext, now: number): void; /** {@link recordSourceLoadReady} plus dispatching `WorkflowSourceLoadReadyEvent` when it returns `true`. */ export declare function recordSourceLoadReadyAndDispatch(ctx: SourceEventContext, now: number): void; /** {@link recordSourceLoadFailed} plus dispatching `WorkflowSourceLoadFailedEvent` when it returns `true`. */ export declare function recordSourceLoadFailedAndDispatch(ctx: SourceEventContext, now: number, error: unknown): void; /** {@link endSourceWaiterAndCheckCancellation} plus dispatching `WorkflowSourceLoadCancelledEvent` when it returns `true`. */ export declare function endSourceWaiterAndDispatchCancellation(engine: Engine, internals: EngineInternals, name: string, revision: string): void;