/** * The Deno workflow-run storage provider. * * This module is where the host stops being provider-neutral: it hashes run * ids, resolves paths beneath the authorized root, opens SQLite, and decides * what each of SQLite's refusals means. Nothing above it names any of those. * * ## Finding a run * * A run's file is the SHA-256 of its public run id beneath the root, so * discovery is arithmetic and there is no index that could disagree with the * files. Because a path can be derived by anyone, the run id is also stored * inside the database and checked: a file at the right path holding a different * run is a collision or tampering, and is refused rather than adopted. * * ## Creating is reusing * * `create()` answers with the stored run when the request describes it, and * refuses when any immutable field differs. That is what makes a * caller-selected id usable twice — as a retry, or as a second process * addressing the same work — without a separate idempotency concept. * * Two callers creating at once converge through SQLite's own write lock: the * first initializes the file, the second finds it already initialized and * compares instead of writing. */ import type { DatabaseSync } from "node:sqlite"; import { type Operation, type Result } from "effection"; import { type WorkflowRunConnections } from "./connections.js"; import type { PrivateWorkspaceOptions } from "./workspace/private.js"; export interface WorkflowRunStorageOptions { /** * The directory this host is authorized to keep runs in. * * Absolute. A relative root names a different directory from a different * working directory, and where a run lives is host arrangement that must not * depend on where a process happened to start. `~` is not expanded: a path * only a shell understands is not a path. */ readonly root: string; } export type WorkflowRunRecognitionProbe = (database: DatabaseSync) => void; /** Adapter-private observation seam for deterministic snapshot tests. */ export declare const WorkflowRunRecognition: import("effection").Context; /** * Install this host's run storage for the current scope and its descendants. * * `{ at: "min" }` is not decoration. Middleware installed at the default * position runs outermost, so an outer scope's provider would answer ahead of * one installed nearer the work — the opposite of what a provider is for. * * The turns taken at each database belong to this installation. They are * created here rather than at module scope, so coordination lasts exactly as * long as the scope that installed the provider and nothing accumulates * between runs. */ export declare function useWorkflowRunStorage(options: WorkflowRunStorageOptions): Operation; /** * The same installation, with what only this adapter's own suites supply. * * Kept apart from the published entrypoint on purpose: `internal` carries a * decorator for the authoritative Workspace filesystem, which is provider * ownership rather than host arrangement. It is captured in the provider's * closure here and never handed to a scope, a context or a descendant. */ export declare function installWorkflowRunStorage(options: WorkflowRunStorageOptions, internal: PrivateWorkspaceOptions, connections: WorkflowRunConnections): Operation; export declare function authorizedRoot(root: string): string; /** * The run id a caller named, whichever operation they called. * * `create` and `lookup` address the same runs by the same rule, so they check * it in the same place — and it is the same rule a retained `run_id` is read * back through, so an id no request could address cannot be stored and then * answered for. Nothing here assumes the argument is a string: a host built * without types, or one that read the id out of a file, can hand over anything * at all, and hashing that would fail somewhere far less legible. */ export declare function checkRunId(runId: unknown): Result;