/** * Push apply (SPEC.md §6) with §3.4 write-path authorization. * * Security-critical rules implemented here: * - authorization runs against the STORED row when it exists, never the * pushed payload (§3.4 step 2); * - declared scope columns are stripped from every update path (§3.4 * rule 5) — updates keep the stored row's scope column values; * - a lost `baseVersion = 0` insert race re-authorizes the winner's row * before disclosing it in a conflict record (§6.2). * * Per-commit atomicity (§6.4): one storage transaction per commit; the * idempotency record persists in the same transaction as the writes. * * Optional per-table write validation (§6.7) runs after decode + the §3.4 * scope check, on the row that will persist (post scope-strip, post CRDT * merge); a validator throw rejects the whole commit atomically with a * host code. */ import { type PushCommitFrame, type PushOperation, type PushResultFrame } from '@syncular/core'; import type { SyncRequestContext } from './context.js'; import type { CompiledSchema } from './schema.js'; import type { ResolvedScopes } from './scopes.js'; import type { StorageTransaction, StoredCommit } from './storage.js'; export interface ProcessedPushCommit { readonly frame: PushResultFrame; /** True when this request observed an already-recorded idempotency outcome. */ readonly replayed: boolean; readonly recordedAtMs?: number; readonly cacheIdentity?: string; } export interface AppliedCommitEvent { readonly commit: StoredCommit; } /** * Process one `PUSH_COMMIT` frame: idempotency replay (§2.3), sequential * atomic apply (§6.4), realtime notification for applied commits. */ export declare function processPushCommit(ctx: SyncRequestContext, schema: CompiledSchema, resolved: ResolvedScopes, clientId: string, frame: PushCommitFrame): Promise; /** * Host-observable variant of `processPushCommit`. The SSP2 wire frame keeps * rejected replays as `status: rejected`; this companion result preserves the * cache provenance needed by structured events and server helpers. */ export declare function processPushCommitWithTrace(ctx: SyncRequestContext, schema: CompiledSchema, resolved: ResolvedScopes, clientId: string, frame: PushCommitFrame): Promise; /** * Shared serialized apply path for SSP2 commits and authoritative commands. * The builder runs after the partition lock and idempotency re-check, so its * reads and the returned operations share the transaction that is committed. */ export declare function processPushOperationsWithTrace(ctx: SyncRequestContext, schema: CompiledSchema, resolved: ResolvedScopes, clientId: string, clientCommitId: string, buildOperations: (tx: StorageTransaction) => Promise): Promise;