import { type RejectionDetails } from './rejection-details.js'; export type ScopeMap = Record; export interface ReqHeaderFrame { type: 'REQ_HEADER'; clientId: string; schemaVersion: number; /** Wire v2 partition log identity; absent requests epoch acquisition. */ logEpoch?: string; } export interface PushOperation { table: string; rowId: string; op: 'upsert' | 'delete'; /** Optimistic-concurrency token (§6.2); absent = last-write-wins. */ baseVersion?: number; /** Generated-row-codec bytes; present iff `op` is `upsert` (§6.1). */ payload?: Uint8Array; } export interface PushCommitFrame { type: 'PUSH_COMMIT'; clientCommitId: string; operations: PushOperation[]; } export interface PullHeaderFrame { type: 'PULL_HEADER'; limitCommits: number; limitSnapshotRows: number; maxSnapshotPages: number; /** Bitmask (§4.2): bit 0 inline rows, 1 external rows, 2 sqlite, 3 signed URLs. */ accept: number; } export interface SubscriptionFrame { type: 'SUBSCRIPTION'; id: string; table: string; scopes: ScopeMap; /** Host-opaque JSON document, preserved verbatim. */ params?: string; cursor: number; /** Opaque resume token JSON, round-tripped byte-for-byte (§4.7). */ bootstrapState?: string; } export interface UnknownFrame { type: 'UNKNOWN'; frameType: number; payload: Uint8Array; } export type RequestFrame = ReqHeaderFrame | PushCommitFrame | PullHeaderFrame | SubscriptionFrame | UnknownFrame; export interface RespHeaderFrame { type: 'RESP_HEADER'; requiredSchemaVersion?: number; latestSchemaVersion?: number; /** Required and non-empty on wire v2. */ logEpoch?: string; /** Required on wire v2. True produces a header-only reset response. */ resetRequired?: boolean; } /** §7.3.2: a server-issued auth lease delivered to the client (opaque). */ export interface LeaseFrame { type: 'LEASE'; leaseId: string; expiresAtMs: number; } export type PushOperationResult = { opIndex: number; status: 'applied'; } | { opIndex: number; status: 'conflict'; code: string; message: string; serverVersion: number; serverRow: Uint8Array; /** * §6.3 (wire version 3): presence-bitmap layout over the row's columns, * marking the present columns whose `column_version` exceeded the * operation's `baseVersion`. A `baseVersion = 0` lost-insert conflict * marks every present non-crdt column. */ conflictColumns: Uint8Array; } | { opIndex: number; status: 'error'; code: string; message: string; retryable: boolean; /** * Host-safe structured metadata. It is emitted on the wire through the * additive PUSH_RESULT_DETAILS companion frame, not the legacy record. */ details?: RejectionDetails; }; export interface PushResultFrame { type: 'PUSH_RESULT'; clientCommitId: string; status: 'applied' | 'cached' | 'rejected'; /** Present iff `status` is `applied` or `cached` (§6.3). */ commitSeq?: number; results: PushOperationResult[]; } /** * Additive companion metadata for host validation errors. Older clients see * this as an unknown frame and continue processing the normative PUSH_RESULT. */ export interface PushResultDetailsFrame { type: 'PUSH_RESULT_DETAILS'; clientCommitId: string; entries: Array<{ opIndex: number; details: RejectionDetails; }>; } export interface SubStartFrame { type: 'SUB_START'; id: string; status: 'active' | 'revoked' | 'reset'; reasonCode: string; effectiveScopes: ScopeMap; bootstrap: boolean; } export interface CommitChange { tableIndex: number; rowId: string; op: 'upsert' | 'delete'; /** Present iff `op` is `upsert` (§4.5). */ rowVersion?: number; scopes: Record; /** Generated-row-codec bytes; present iff `op` is `upsert` (§4.5). */ row?: Uint8Array; } export interface CommitFrame { type: 'COMMIT'; commitSeq: number; createdAtMs: number; actorId: string; tables: string[]; changes: CommitChange[]; } export interface SegmentRefFrame { type: 'SEGMENT_REF'; segmentId: string; mediaType: 'rows' | 'sqlite'; table: string; byteLength: number; rowCount: number; asOfCommitSeq: number; scopeDigest: string; rowCursor?: string; nextRowCursor?: string; url?: string; /** Present iff `url` is (§5.4). */ urlExpiresAtMs?: number; } export interface SegmentInlineFrame { type: 'SEGMENT_INLINE'; /** One complete SSG2 rows segment, including magic (§5.7). */ payload: Uint8Array; } export interface SubEndFrame { type: 'SUB_END'; nextCursor: number; /** Present iff the bootstrap is incomplete (§4.4). */ bootstrapState?: string; } export interface ErrorFrame { type: 'ERROR'; code: string; message: string; category: string; retryable: boolean; recommendedAction: string; details?: string; } export type ResponseFrame = RespHeaderFrame | LeaseFrame | PushResultFrame | PushResultDetailsFrame | SubStartFrame | CommitFrame | SegmentRefFrame | SegmentInlineFrame | SubEndFrame | ErrorFrame | UnknownFrame; export interface RequestMessage { wireVersion: number; msgKind: 'request'; frames: RequestFrame[]; } export interface ResponseMessage { wireVersion: number; msgKind: 'response'; frames: ResponseFrame[]; } export type SyncMessage = RequestMessage | ResponseMessage; export declare function validateFrameSequence(message: SyncMessage): void; export declare function encodeMessage(message: SyncMessage): Uint8Array; export declare function decodeMessage(bytes: Uint8Array): SyncMessage;