/** * `resolveWorkflowSource()` — the async, single-flight entry point that * loads, validates, and installs one dynamic workflow source revision * (WFT-13/14). * * Single-flight per `(name, revision)`: the underlying load+validate+install * work is shared by every concurrent caller for the same key via * `internals.sources.resolutionsInFlight`, but each caller races that work * against its OWN per-call cancellation interest — a cancelled waiter never * aborts a load another waiter still needs, and the shared load is never * tied to any individual caller's lifetime. Disposal aborts every * outstanding waiter (rejecting each pending `resolveWorkflowSource()` call) * without touching the shared load, which keeps running to its own settle. * * @module core/engine/source-resolution */ import { type WorkflowRevisionRecord } from '../catalog/index.ts'; import type { Engine } from './index.ts'; /** * Options accepted by {@link resolveWorkflowSource}. * * @example * ```ts * import { Engine } from '@lostgradient/weft'; * import type { ResolveWorkflowSourceOptions } from '@lostgradient/weft'; * * declare const engine: Engine; * const options: ResolveWorkflowSourceOptions = { signal: AbortSignal.timeout(5_000) }; * const record = await engine.resolveWorkflowSource('checkout', 'r1', options); * console.log(record.manifest.revision); * ``` */ export type ResolveWorkflowSourceOptions = { /** When aborted, this caller's own `resolveWorkflowSource()` call rejects; a load already in flight for other callers is unaffected. */ signal?: AbortSignal; }; /** * Load, validate, and install one dynamic workflow source revision * previously recorded via `engine.registerSource()`. Returns the installed * {@link WorkflowRevisionRecord} immediately, without invoking the loader * at all, when `(name, revision)` is already durably installed — including * a revision installed by a different process. When that is the case, * `internals.sources.resolved` is NOT populated for this key (there * is no locally-loaded `WorkflowDefinition` to stash — only the durable * manifest was ever read) even though the catalog itself considers the * revision installed; a caller reading `internals.sources.resolved` must * account for that gap rather than assuming every installed revision has a * live definition available in this process — see * {@link resolveWorkflowSourceForExecution} for the internal-only variant * that closes exactly this gap for callers that need a local definition. * This fast path still requires * `registerSource()` to have been called for this exact key first (see * {@link resolveCachedOrHandle}), and still validates a pinned * `workflowVersion`/`contractHash` against the cached manifest — the ONLY * thing it skips is re-invoking the loader and re-running * {@link import('../source/index.ts').validateResolvedWorkflowSource}. * * Single-flight per `(name, revision)` — see the module doc for the full * cancellation contract. Throws a plain `Error` when `registerSource()` was * never called for this exact key (a programmer error, not untrusted-input * rejection); throws {@link WorkflowSourceValidationError} when the loaded * module fails validation, OR when a cached manifest contradicts a pinned * `workflowVersion`/`contractHash`; throws {@link EngineDisposedError} when * the engine is disposed, either already or during the call; propagates * {@link import('../catalog/index.ts').WorkflowCatalogConflictError} * unwrapped on a genuine content conflict with an already-installed * revision. * * @example * ```ts * import { Engine, workflowSource } from '@lostgradient/weft'; * * declare const engine: Engine; * declare const loadCheckout: () => Promise<{ * checkout: import('@lostgradient/weft').WorkflowDefinition; * }>; * engine.registerSource( * workflowSource( * { name: 'checkout', location: './checkout.ts', exportName: 'checkout', revision: 'r1' }, * loadCheckout, * ), * ); * const record = await engine.resolveWorkflowSource('checkout', 'r1'); * console.log(record.manifest.revision); * ``` */ export declare function resolveWorkflowSource(engine: Engine, name: string, revision: string, options?: ResolveWorkflowSourceOptions): Promise; /** * Internal-only variant of {@link resolveWorkflowSource} used exclusively by * `resolveExecutableRegistration()` (`dynamic-source-execution.ts`, WFT-15). * Identical cancellation, disposal, and single-flight contract, with one * difference: a cache hit whose local resolved-definition cache * (`internals.sources.resolved`) is still empty for this exact key falls * through to a real load instead of returning the cached manifest — * closing the cross-process-restart gap {@link resolveWorkflowSource}'s own * doc calls out. `catalog.install()` is idempotent on byte-identical * content, so re-installing an already-installed manifest never throws. * Not exported from the package root — reached only via * `resolveExecutableRegistration`. */ export declare function resolveWorkflowSourceForExecution(engine: Engine, name: string, revision: string, options?: ResolveWorkflowSourceOptions): Promise;