/** * The synchronous apply frame (T12344; journal spec §3.2 "withApplyFrame"). * * Every remote op is applied inside one apply frame: a single * `BEGIN IMMEDIATE … COMMIT` holding a `_sync_frame` row of kind `apply`, so * the capture triggers label the frame's captures and the sealer subtracts * the frame's apply intents from them (§3.3). The frame body is SYNCHRONOUS: * an `await` inside it would let another writer on the same handle interleave * its writes into the frame, and they would be subtracted as if the apply had * written them. * * - {@link runApplyFrame} awaits the async preparation first (unsealing, * loading), then queues the frame behind the handle's foreground * transactions and committed effects (`scheduleTaskBackground`), and only * then runs the synchronous body. * - {@link withApplyFrame} is the frame itself: * - it opens the only transaction, BEGIN IMMEDIATE, once: the handle's * `busy_timeout` does the waiting (30 s on dual-scope handles), so the * main thread blocks at most that long, and a BUSY after it is thrown, * never retried mid-frame; * - it inserts the frame row and calls the body with the API; * - **type guard:** the body's return type excludes `PromiseLike`; * - **runtime guard:** a thenable return rolls back and throws * `E_SYNC_APPLY_ASYNC`; * - any API call after the frame ended throws (`assertActive`). * * @module store/sync/apply/frame * @task T12344 */ import type { DatabaseSync } from 'node:sqlite'; import type { TableScope } from '@cleocode/contracts'; import { type ApplyWriteApi } from './write-api.js'; /** * A frame misuse (an async body, a nested call, a call after the frame * ended), or a deferred foreign key the frame's COMMIT refused, with the rows * named (`E_SYNC_APPLY_FK`, T13868). */ export declare class ApplyFrameError extends Error { readonly code: 'E_SYNC_APPLY_ASYNC' | 'E_SYNC_APPLY_NESTED' | 'E_SYNC_APPLY_ENDED' | 'E_SYNC_APPLY_FK'; constructor(code: 'E_SYNC_APPLY_ASYNC' | 'E_SYNC_APPLY_NESTED' | 'E_SYNC_APPLY_ENDED' | 'E_SYNC_APPLY_FK', message: string); } /** A synchronous result: never a thenable. */ export type SyncResult = T extends PromiseLike ? never : T; /** Everything a frame body may do. */ export interface ApplyApi extends ApplyWriteApi { /** The frame id, or null when capture is off on this connection. */ readonly frame: string | null; /** * Merge a remote HLC into this replica's clock (§1.3). Returns the new * clock, or `held` when the remote clock is beyond the skew limit. */ clockReceive(replica: string, remoteHlc: string, nowMs: number): { held: false; clock: string; } | { held: true; }; } /** * Run `fn` as one apply frame on `db`: the only transaction, with a * `_sync_frame` row of kind `apply`, committed when `fn` returns. * * @param db - The store; must not be inside a transaction. * @param scope - The store's scope. * @param actor - The frame's actor (JSON of the remote writer), or null. * @param fn - The synchronous body. * @returns What `fn` returned. * @throws {ApplyFrameError} On a nested call or a thenable result. * @throws SQLITE_BUSY when another writer holds the store past `busy_timeout`. */ export declare function withApplyFrame(db: DatabaseSync, scope: TableScope, actor: string | null, fn: (api: ApplyApi) => SyncResult): SyncResult; /** * Prepare asynchronously, then run one apply frame queued behind the * handle's foreground transactions (§3.2 steps 1–3). * * @param db - The store. * @param scope - The store's scope. * @param actor - The frame's actor, or null. * @param prepare - Async preparation (unsealing secrets, loading); its result is passed in. * @param fn - The synchronous body. * @returns What `fn` returned. */ export declare function runApplyFrame(db: DatabaseSync, scope: TableScope, actor: string | null, prepare: () => Promise

, fn: (api: ApplyApi, prepared: P) => SyncResult): Promise>; //# sourceMappingURL=frame.d.ts.map