/** * The rows one run keeps for the answers delivered to its durable waits. * * A retained answer is a row rather than a journal event, because delivery and * execution are different operations. The value arrives while nothing is * running; it becomes history only when an execution reaches the wait it * answers and publishes it. Until then the row is what the run holds and the * only thing a later resume consults. * * Each row carries the identity of the wait it answers three ways over: the * suspension id it was delivered against, the exact journal event the request * was published as, and a fingerprint of the request and its response schema. * The fingerprint is what a resume compares — a run whose retained request at * that position is not the one the value was judged against is a run this * answer was never for. */ import type { DatabaseSync } from "node:sqlite"; import type { Json } from "@executablemd/durable-streams"; /** Whether a retained answer is still waiting to be published, or already was. */ export type RetainedAnswerState = "pending" | "consumed"; /** One delivered answer, as this run retains it. */ export interface RetainedAnswer { readonly suspensionId: string; readonly requestEventId: string; readonly requestFingerprint: string; readonly answer: Json; readonly state: RetainedAnswerState; readonly createdAt: string; readonly consumedAt: string | undefined; } /** What one delivery retains. */ export interface PendingAnswerInsertion { readonly suspensionId: string; readonly requestEventId: string; readonly requestFingerprint: string; readonly answer: Json; readonly createdAt: string; } /** The answer retained for this wait, whatever state it is in. */ export declare function readRetainedAnswer(database: DatabaseSync, suspensionId: string): RetainedAnswer | undefined; /** * Every answer this run retains, in one deterministic order. * * What an export seals. Ordered by the wait each one answers rather than by * insertion, so the same retained state reads the same however SQLite would * have returned the rows. */ export declare function readAllRetainedAnswers(database: DatabaseSync): RetainedAnswer[]; /** * Retain one pending answer. * * The primary key is what refuses a second delivery for the same wait, so * duplicate and already-consumed deliveries are refused by the database rather * than by a check the caller could race. */ export declare function insertPendingAnswer(database: DatabaseSync, insertion: PendingAnswerInsertion): void; /** * Mark this wait's retained answer consumed, and say whether it was this call * that did it. * * The state is part of the statement rather than something read first: a second * consumption changes no rows and is told so, which is how the publication that * commits with it stays the only one. */ export declare function consumeRetainedAnswer(database: DatabaseSync, suspensionId: string, consumedAt: string): boolean;