/** * Where a reconnecting consumer left off in a session log, and whether the * kernel can honour it. * * The shortfall is a VALUE here, not a sentence in a document. A consumer that * asks for everything after seq 400 and silently receives a splice from a * different generation of the log is wrong and has no way to find out; a * consumer handed `{ status: 'unavailable', reason: 'cursor_ahead' }` re-derives * from the log and is right. */ import type { SessionLogHead } from '../../store/session-log/index.js'; import type { FencingToken } from './durable.js'; import type { SessionRecord } from './records.js'; /** What a consumer holds when it comes back. */ export interface SessionLogCursor { /** The last record `seq` the consumer received. Zero means "from the beginning". */ readonly sinceSeq: number; /** * The lease fence (`gen`) of the records the consumer received, when it * tracked one. Compared for equality only. */ readonly generation?: FencingToken; } /** Why a cursor could not be honoured. */ export type SessionLogReplayRefusal = /** The consumer claims to have seen more than the log holds. */ 'cursor_ahead' /** The session has been taken over since; the consumer's position belongs to an older holding. */ | 'generation_changed' /** The first record returned is not the one right after the cursor. */ | 'gap'; /** What came of a cursor. */ export type SessionLogReplay = /** The cursor is already at the log's head. Nothing was missed. */ { readonly status: 'complete'; } /** Contiguous from `sinceSeq + 1`, oldest first. */ | { readonly status: 'replayed'; readonly records: readonly SessionRecord[]; } /** Nothing is delivered. The consumer re-derives from the log. */ | { readonly status: 'unavailable'; readonly reason: SessionLogReplayRefusal; }; /** * Decide what a cursor is owed, given the log's head and the records read * after `cursor.sinceSeq`. * * Pure. The generation check runs FIRST: a takeover invalidates the position, * so comparing sequences across generations would be arithmetic on two * different scales. A `null` head is an empty log. */ export declare function resolveSessionLogReplay(cursor: SessionLogCursor, head: SessionLogHead | null, records: readonly SessionRecord[]): SessionLogReplay; //# sourceMappingURL=log-cursor.d.ts.map