statewire 0.18.1 → 0.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"socket.js","names":["encodeDocument","DEFAULT_PROTOCOL","WIRE_VERSION","negotiateProtocols","StatewireProtocol","applyDocumentOps","mainDocument","StatewireDocuments","useEffect","useState","createTapRoot","flushTapSync","useResource","ResourceElement","getCommandsHost","getStateHost","CommandsHost","CommandsOutcome","StatewireSendError","Statewire","StatewireHost","StatewireHostInternal","reviveValue","COMMAND_CAPACITY_RETRY_MS","MAX_COMMANDS_PER_FRAME","MAX_CONTEXT_VALUE_BYTES","MAX_FRAME_BODY_BYTES","MAX_INFLIGHT_COMMANDS_PER_CLIENT","MAX_INFLIGHT_COMMANDS_PER_HOST","createMacrotaskPoster","StatewireDocument","StatewirePath","StatewireCmd","StatewireEnvelope","frames","serveFrames","stream","serveStream","CLIENT_ID_RE","PRINCIPAL_MISMATCH_MESSAGE","authEquals","a","b","Object","is","Date","getTime","Array","isArray","length","every","v","i","getPrototypeOf","prototype","keysA","keys","keysB","key","Record","RESULT_TTL_MS","RESULT_LIMIT","CLIENT_RECORD_LIMIT","MAX_SUBSCRIBERS","SUBSCRIBER_LIMIT_MESSAGE","STREAM_QUEUE_SIZE","WireOp","op","path","value","meta","MetaEntry","Admission","seq","method","applied","appliedSent","settled","ClientRec","id","lastSeq","ctxSeq","touched","context","contextDocuments","State","results","Map","ts","cmd","inflight","principal","Conn","selection","Selection","clientId","socket","Socket","open","sawFrame","lastSentAt","lease","auth","PendingConn","authorizing","queued","timer","ReturnType","setTimeout","connection","SocketConnection","violation","reason","assign","Error","name","violationReason","error","message","CtxStatement","ops","CmdStatement","protocol","params","ParsedFrame","ctx","isPlainObject","parseLane","statements","prev","statement","Number","isInteger","push","frameEncoder","TextEncoder","parseFrameValue","frame","unknown","filter","sort","undefined","lane","encode","JSON","stringify","byteLength","parseFrame","raw","parse","frameIsOversized","encodePayload","payload","cmdOf","adm","outcome","type","failure","fate","code","String","parseInitialFrame","headers","lanes","Response","status","values","some","SocketHostState","Definition","wireVersion","Range","heartbeatMs","wsInitTimeoutMs","maxSubscribers","maxInflightCommands","streamQueueSize","clientRecordLimit","finOnIdle","pushback","authorize","SocketHostOptions","clients","conns","Set","pendingConns","pendingOps","pendingApplied","pendingCmds","idleWire","finished","Fin","disposed","flushScheduled","heartbeatTimer","setInterval","stateHost","StateHost","commandsHost","current","persistence","SocketHostPersistence","post","connect","options","SocketConnectOptions","finish","fin","request","Request","Promise","scheduleFlush","h","recordOp","attach","next","nextState","state","nextCommands","commands","submit","setOnOp","closeConn","conn","delete","close","size","clearInterval","sendTo","data","now","send","atSubscriberLimit","ensureHeartbeat","unref","setHeartbeatMs","ms","idleLevel","work","isIdle","rec","flush","takeChanged","queueApplied","level","edge","cmds","appliedEntries","get","map","packet","protocols","p","idle","verdicts","dur","list","set","queueCmd","notifyClientRecords","onClientRecordsChange","admittedThrough","documents","entry","retain","newest","Math","max","min","reemit","cached","settleCmd","settleWire","callerOf","Caller","isConnected","rejectStatement","admitCmd","rejectUnknown","names","methods","caller","onApplied","onSettle","catch","FrameAdmission","syn","retry","admitFrame","version","through","ctxNew","s","cmdNew","hostCommandLoad","client","isSafeInteger","TypeError","at","first","admission","closePending","pending","clearTimeout","sendPending","refuseSubscriberLimit","rejectPendingAuthorization","response","unauthorized","statusText","normalizedHeaders","seen","toLowerCase","has","add","fromEntries","Headers","connectAuthorized","authorized","registration","register","refuse","test","initial","resolve","then","onAuthorized","splice","gcClients","excess","changed","live","oldest","Registration","known","created","mode","snapshot","hello","main","abort","resume","suspend","restoreClientRecords","records","ClientRecord","record","useSocketHost","transport","Pick","SocketHost","host","clientRecords","connectOptions","heartbeatIntervalMs","StatewireSocketHost","SocketHostRoot","root","getValue","dispose","unmount"],"sources":["../../src/host/socket.ts"],"sourcesContent":["import { encodeDocument } from \"../document\";\nimport {\n DEFAULT_PROTOCOL,\n WIRE_VERSION,\n negotiateProtocols,\n} from \"../wire/protocol\";\nimport type { StatewireProtocol } from \"../wire/protocol\";\nimport { applyDocumentOps, mainDocument } from \"../wire/documents\";\nimport type { StatewireDocuments } from \"../wire/documents\";\nimport { useEffect, useState } from \"react\";\nimport { createTapRoot, flushTapSync, useResource } from \"@assistant-ui/tap\";\nimport type { ResourceElement } from \"@assistant-ui/tap\";\nimport { getCommandsHost, getStateHost } from \"./host\";\nimport type { CommandsHost, CommandsOutcome } from \"./host\";\nimport { StatewireSendError } from \"../types\";\nimport type { Statewire } from \"../types\";\nimport type { StatewireHost } from \"../host\";\nimport type { StatewireHostInternal } from \"../host-internal\";\nimport { reviveValue } from \"../wire/meta\";\nimport {\n COMMAND_CAPACITY_RETRY_MS,\n MAX_COMMANDS_PER_FRAME,\n MAX_CONTEXT_VALUE_BYTES,\n MAX_FRAME_BODY_BYTES,\n MAX_INFLIGHT_COMMANDS_PER_CLIENT,\n MAX_INFLIGHT_COMMANDS_PER_HOST,\n} from \"../wire/limits\";\nimport { createMacrotaskPoster } from \"../util/macrotask\";\nimport type { StatewireDocument } from \"../document\";\nimport type { StatewirePath } from \"../wire/ops\";\nimport type { StatewireCmd, StatewireEnvelope } from \"../client/connection\";\nimport { frames as serveFrames, stream as serveStream } from \"./http\";\n\nexport const CLIENT_ID_RE = /^[A-Za-z0-9._~-]{1,256}$/;\nexport const PRINCIPAL_MISMATCH_MESSAGE =\n \"client id is bound to another principal\";\n\n/** Structural equality over auth values: primitives, Dates, arrays, and plain\n * objects compare by value; anything else by identity. */\nexport const authEquals = (a: unknown, b: unknown): boolean => {\n if (Object.is(a, b)) return true;\n if (a instanceof Date && b instanceof Date)\n return a.getTime() === b.getTime();\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((v, i) => authEquals(v, b[i]));\n }\n if (\n typeof a === \"object\" &&\n typeof b === \"object\" &&\n a !== null &&\n b !== null &&\n Object.getPrototypeOf(a) === Object.prototype &&\n Object.getPrototypeOf(b) === Object.prototype\n ) {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n return (\n keysA.length === keysB.length &&\n keysA.every(\n (key) =>\n key in b &&\n authEquals(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key],\n ),\n )\n );\n }\n return false;\n};\n\nconst RESULT_TTL_MS = 30_000;\nconst RESULT_LIMIT = 256;\nconst CLIENT_RECORD_LIMIT = 1024;\nconst MAX_SUBSCRIBERS = 1024;\nexport const SUBSCRIBER_LIMIT_MESSAGE = \"stream subscriber limit reached\";\nconst STREAM_QUEUE_SIZE = 256;\n\ntype WireOp = {\n op: string;\n path?: StatewirePath;\n value?: unknown;\n meta?: StatewireDocument.MetaEntry[];\n};\n\ntype Admission = {\n seq: number;\n method: string;\n applied: boolean;\n appliedSent: boolean;\n settled: boolean;\n};\n\nexport type ClientRec = {\n id: string;\n lastSeq: number;\n ctxSeq: number;\n touched: number;\n context: Record<string, unknown> | null;\n contextDocuments: StatewireDocuments.State;\n results: Map<number, { ts: number; cmd: StatewireCmd }>;\n inflight: Map<number, Admission>;\n /** The auth captured at the record's first attach; later attaches must match. */\n principal: unknown;\n};\n\nexport type Conn = {\n selection: StatewireProtocol.Selection;\n clientId: string;\n socket: StatewireHostInternal.Socket;\n open: boolean;\n sawFrame: boolean;\n lastSentAt: number;\n lease: string | null;\n /** The awaited `authorize` return captured at this attach's authorization. */\n auth: unknown;\n};\n\ntype PendingConn = {\n socket: StatewireHostInternal.Socket;\n open: boolean;\n authorizing: boolean;\n queued: string[];\n timer: ReturnType<typeof setTimeout> | null;\n connection: StatewireHostInternal.SocketConnection | null;\n};\n\n// ─── frame parsing ──────────────────────────────────────\n\nconst violation = (reason: string): never => {\n throw Object.assign(new Error(reason), { name: \"StatewireViolation\" });\n};\n\nconst violationReason = (error: unknown): string | null =>\n error instanceof Error && error.name === \"StatewireViolation\"\n ? error.message\n : null;\n\ntype CtxStatement = { seq: number; ops: unknown[] };\ntype CmdStatement = {\n protocol: string;\n seq: number;\n method: string;\n params: unknown;\n meta?: unknown;\n};\n\nexport type ParsedFrame = {\n ctx: CtxStatement[];\n cmd: CmdStatement[];\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst parseLane = (value: unknown): Record<string, unknown>[] => {\n if (!Array.isArray(value)) return violation(\"malformed frame\");\n if (value.length === 0) return violation(\"empty lane\");\n const statements: Record<string, unknown>[] = [];\n let prev: number | null = null;\n for (const statement of value) {\n if (!isPlainObject(statement)) return violation(\"malformed statement\");\n const seq = statement[\"seq\"];\n if (typeof seq !== \"number\" || !Number.isInteger(seq) || seq < 1) {\n return violation(\"malformed statement\");\n }\n if (prev !== null && seq !== prev + 1) return violation(\"malformed frame\");\n prev = seq;\n statements.push(statement);\n }\n return statements;\n};\n\nconst frameEncoder = new TextEncoder();\n\nexport const parseFrameValue = (frame: unknown): ParsedFrame => {\n if (!isPlainObject(frame)) return violation(\"malformed frame\");\n const keys = Object.keys(frame);\n if (keys.length === 0) return violation(\"malformed frame\");\n const unknown = keys.filter((key) => key !== \"ctx\" && key !== \"cmd\").sort();\n if (unknown.length > 0)\n return violation(`unknown frame key: '${unknown[0]}'`);\n const ctx: CtxStatement[] = [];\n if (frame[\"ctx\"] !== undefined) {\n const lane = frame[\"ctx\"];\n if (Array.isArray(lane) && lane.length > MAX_COMMANDS_PER_FRAME) {\n return violation(\"too many context statements\");\n }\n for (const statement of parseLane(lane)) {\n const ops = statement[\"ops\"];\n if (!Array.isArray(ops) || !ops.length)\n return violation(\"invalid-context\");\n if (\n frameEncoder.encode(JSON.stringify(ops)).byteLength >\n MAX_CONTEXT_VALUE_BYTES\n )\n return violation(\"oversized-context\");\n ctx.push({ seq: statement[\"seq\"] as number, ops });\n }\n }\n const cmd: CmdStatement[] = [];\n if (frame[\"cmd\"] !== undefined) {\n const lane = frame[\"cmd\"];\n if (Array.isArray(lane) && lane.length > MAX_COMMANDS_PER_FRAME) {\n return violation(\"too many commands\");\n }\n for (const statement of parseLane(lane)) {\n const method = statement[\"method\"];\n if (\n typeof method !== \"string\" ||\n typeof statement[\"protocol\"] !== \"string\" ||\n !(\"params\" in statement)\n ) {\n return violation(\"malformed statement\");\n }\n cmd.push({\n protocol: statement[\"protocol\"] as string,\n seq: statement[\"seq\"] as number,\n method,\n params: statement[\"params\"],\n ...(statement[\"meta\"] !== undefined && { meta: statement[\"meta\"] }),\n });\n }\n }\n return { ctx, cmd };\n};\n\nexport const parseFrame = (raw: string): ParsedFrame => {\n let frame: unknown;\n try {\n frame = JSON.parse(raw);\n } catch {\n return violation(\"malformed frame\");\n }\n return parseFrameValue(frame);\n};\n\nconst frameIsOversized = (raw: string): boolean =>\n raw.length > MAX_FRAME_BODY_BYTES ||\n frameEncoder.encode(raw).byteLength > MAX_FRAME_BODY_BYTES;\n\n// ─── verdict encoding ───────────────────────────────────\n\nconst encodePayload = (\n payload: unknown,\n): { payload?: unknown; meta?: StatewireDocument.MetaEntry[] } => {\n if (payload === undefined) return {};\n const { value, meta } = encodeDocument(payload);\n return { payload: value, ...(meta !== undefined && { meta }) };\n};\n\nconst cmdOf = (adm: Admission, outcome: CommandsOutcome): StatewireCmd => {\n if (outcome.type === \"accepted\") {\n return { seq: adm.seq, type: \"result\", ...encodePayload(outcome.payload) };\n }\n const failure =\n outcome.error instanceof StatewireSendError ? outcome.error.failure : null;\n switch (failure?.fate) {\n case \"crashed\":\n return { seq: adm.seq, type: \"crashed\" };\n case \"failed\":\n return {\n seq: adm.seq,\n type: \"failed\",\n ...(failure.message !== undefined && { message: failure.message }),\n };\n case \"rejected\": {\n if (failure.code !== undefined) {\n const message =\n failure.code === \"unknown-command\"\n ? `unknown method: '${adm.method}'`\n : failure.message;\n return {\n seq: adm.seq,\n type: \"rejected\",\n code: failure.code,\n ...(message !== undefined && { message }),\n };\n }\n return {\n seq: adm.seq,\n type: \"rejected\",\n ...(failure.message !== undefined && { message: failure.message }),\n ...encodePayload(failure.payload),\n };\n }\n default:\n return {\n seq: adm.seq,\n type: \"failed\",\n message:\n outcome.error instanceof Error\n ? outcome.error.message\n : String(outcome.error),\n };\n }\n};\n\nconst parseInitialFrame = (raw: string) => {\n let value: unknown;\n try {\n value = JSON.parse(raw);\n } catch {\n return violation(\"malformed frame\");\n }\n if (!isPlainObject(value)) return violation(\"malformed frame\");\n const { headers, ...lanes } = value;\n if (headers === undefined) throw new Response(null, { status: 401 });\n if (\n !isPlainObject(headers) ||\n Object.values(headers).some((v) => typeof v !== \"string\")\n ) {\n return violation(\"malformed headers\");\n }\n return {\n headers: headers as Record<string, string>,\n frame: Object.keys(lanes).length\n ? parseFrameValue(lanes)\n : { ctx: [], cmd: [] },\n };\n};\n\n// ─── host ───────────────────────────────────────────────\n\nexport type SocketHostState = {\n protocol: StatewireProtocol.Definition;\n wireVersion: StatewireProtocol.Range;\n heartbeatMs: number;\n wsInitTimeoutMs: number;\n maxSubscribers: number;\n maxInflightCommands: number;\n streamQueueSize: number;\n clientRecordLimit: number;\n finOnIdle: boolean;\n pushback: (() => number | null) | undefined;\n authorize: StatewireHostInternal.SocketHostOptions[\"authorize\"];\n clients: Map<string, ClientRec>;\n conns: Set<Conn>;\n pendingConns: Set<PendingConn>;\n pendingOps: WireOp[];\n pendingApplied: Map<string, number[]>;\n pendingCmds: Map<string, StatewireCmd[]>;\n idleWire: boolean;\n finished: StatewireHost.Fin | null;\n disposed: boolean;\n flushScheduled: boolean;\n heartbeatTimer: ReturnType<typeof setInterval> | null;\n stateHost: StatewireHost.StateHost | null;\n commandsHost: CommandsHost | null;\n current: Statewire<unknown> | null;\n persistence: StatewireHostInternal.SocketHostPersistence | undefined;\n post: () => void;\n connect: (\n clientId: string,\n socket: StatewireHostInternal.Socket,\n options?: StatewireHostInternal.SocketConnectOptions,\n ) => StatewireHostInternal.SocketConnection | null;\n finish: (fin: StatewireHost.Fin) => void;\n stream: (request: Request) => Promise<Response>;\n frames: (request: Request) => Promise<Response>;\n};\n\nconst scheduleFlush = (h: SocketHostState) => {\n if (h.flushScheduled || h.disposed) return;\n h.flushScheduled = true;\n h.post();\n};\n\nconst recordOp = (\n h: SocketHostState,\n op: {\n op: string;\n path?: StatewirePath;\n value?: unknown;\n },\n) => {\n if (op.op === \"replace\" || op.op === \"add\") {\n const { value, meta } = encodeDocument(op.value);\n h.pendingOps.push({ ...op, value, ...(meta !== undefined && { meta }) });\n } else {\n h.pendingOps.push(op);\n }\n scheduleFlush(h);\n};\n\nconst attach = (h: SocketHostState, next: Statewire<unknown>) => {\n if (next === h.current) return;\n h.current = next;\n const nextState =\n typeof next.state === \"object\" && next.state !== null\n ? getStateHost(next.state)\n : undefined;\n const nextCommands = getCommandsHost(next.commands);\n if (!nextState || !nextCommands?.submit) {\n throw new Error(\n \"StatewireSocketHost requires a statewire/host transport (useStatewireState with object state, useStatewireCommands)\",\n );\n }\n if (nextState !== h.stateHost) {\n h.stateHost?.setOnOp(null);\n h.stateHost = nextState;\n h.stateHost.setOnOp((op) => recordOp(h, op));\n }\n h.commandsHost = nextCommands;\n};\n\nexport const closeConn = (\n h: SocketHostState,\n conn: Conn,\n code?: number,\n reason?: string,\n) => {\n if (!conn.open) return;\n conn.open = false;\n h.conns.delete(conn);\n try {\n conn.socket.close(code, reason);\n } catch {\n /* peer already gone */\n }\n if (h.conns.size === 0 && h.heartbeatTimer !== null) {\n clearInterval(h.heartbeatTimer);\n h.heartbeatTimer = null;\n }\n};\n\nexport const sendTo = (h: SocketHostState, conn: Conn, data: string) => {\n if (!conn.open) return;\n conn.lastSentAt = Date.now();\n try {\n conn.socket.send(data);\n } catch {\n closeConn(h, conn);\n }\n};\n\nexport const atSubscriberLimit = (h: SocketHostState): boolean =>\n h.conns.size +\n [...h.pendingConns].filter((conn) => conn.authorizing).length >=\n h.maxSubscribers;\n\nconst ensureHeartbeat = (h: SocketHostState) => {\n if (h.heartbeatTimer !== null || h.heartbeatMs <= 0) return;\n h.heartbeatTimer = setInterval(() => {\n const now = Date.now();\n for (const conn of [...h.conns]) {\n if (now - conn.lastSentAt >= h.heartbeatMs) sendTo(h, conn, \"{}\");\n }\n }, h.heartbeatMs);\n (h.heartbeatTimer as unknown as { unref?: () => void }).unref?.();\n};\n\nconst setHeartbeatMs = (h: SocketHostState, ms: number) => {\n if (ms === h.heartbeatMs) return;\n h.heartbeatMs = ms;\n if (h.heartbeatTimer !== null) {\n clearInterval(h.heartbeatTimer);\n h.heartbeatTimer = null;\n ensureHeartbeat(h);\n }\n};\n\nconst idleLevel = (h: SocketHostState): boolean => {\n if (h.current?.work?.isIdle === false) return false;\n for (const rec of h.clients.values()) {\n if (rec.inflight.size > 0) return false;\n }\n return true;\n};\n\nexport const flush = (h: SocketHostState, fin?: StatewireHost.Fin) => {\n flushTapSync(() => {});\n h.stateHost?.takeChanged();\n for (const rec of h.clients.values()) {\n for (const adm of rec.inflight.values()) {\n if (adm.applied && !adm.settled && !adm.appliedSent) {\n adm.appliedSent = true;\n queueApplied(h, rec.id, adm.seq);\n }\n }\n }\n const level = idleLevel(h);\n const edge = level !== h.idleWire;\n if (\n h.pendingOps.length === 0 &&\n h.pendingApplied.size === 0 &&\n h.pendingCmds.size === 0 &&\n fin === undefined &&\n !edge\n ) {\n return;\n }\n h.idleWire = level;\n if (fin === undefined && edge && level && h.finOnIdle) {\n fin = { reason: \"idle\" };\n }\n const ops = h.pendingOps;\n const applied = h.pendingApplied;\n const cmds = h.pendingCmds;\n h.pendingOps = [];\n h.pendingApplied = new Map();\n h.pendingCmds = new Map();\n // Applied entries anchor to their effects: piggybacked on the ops packet\n // when one is flushing, standalone otherwise. Terminal verdicts ride their\n // own packet.\n for (const conn of [...h.conns]) {\n const appliedEntries: StatewireCmd[] = (\n applied.get(conn.clientId) ?? []\n ).map((seq) => ({ seq, type: \"applied\" }));\n if (ops.length > 0) {\n const packet: StatewireEnvelope = {\n ops: conn.selection.protocols.some((p) => p.name === h.protocol.name)\n ? ops\n : [],\n ...(appliedEntries.length > 0 && { cmd: appliedEntries }),\n ...(edge && { idle: level }),\n };\n sendTo(h, conn, JSON.stringify(packet));\n } else if (appliedEntries.length > 0) {\n sendTo(h, conn, JSON.stringify({ cmd: appliedEntries }));\n }\n const verdicts = (cmds.get(conn.clientId) ?? []).map((cmd) =>\n conn.selection.protocols.some((p) => p.name === h.protocol.name)\n ? cmd\n : { seq: cmd.seq, ...(cmd.dur === undefined ? {} : { dur: cmd.dur }) },\n );\n if (verdicts.length > 0) {\n sendTo(h, conn, JSON.stringify({ cmd: verdicts }));\n }\n if (edge && ops.length === 0) {\n sendTo(h, conn, JSON.stringify({ idle: level }));\n }\n if (fin !== undefined) {\n sendTo(h, conn, JSON.stringify({ fin }));\n closeConn(h, conn);\n }\n }\n};\n\nconst queueApplied = (h: SocketHostState, clientId: string, seq: number) => {\n const list = h.pendingApplied.get(clientId);\n if (list) list.push(seq);\n else h.pendingApplied.set(clientId, [seq]);\n scheduleFlush(h);\n};\n\nconst queueCmd = (h: SocketHostState, clientId: string, cmd: StatewireCmd) => {\n const list = h.pendingCmds.get(clientId);\n if (list) list.push(cmd);\n else h.pendingCmds.set(clientId, [cmd]);\n scheduleFlush(h);\n};\n\nconst notifyClientRecords = (h: SocketHostState) => {\n h.persistence?.onClientRecordsChange?.(\n [...h.clients.values()].map((rec) => ({\n id: rec.id,\n lastSeq: admittedThrough(rec),\n ctxSeq: rec.ctxSeq,\n touched: rec.touched,\n context: rec.context,\n contextDocuments: [...rec.contextDocuments.documents],\n results: [...rec.results].map(([seq, entry]) => ({\n seq,\n ts: entry.ts,\n cmd: entry.cmd,\n })),\n principal: rec.principal,\n })),\n );\n};\n\nconst retain = (rec: ClientRec, cmd: StatewireCmd) => {\n const now = Date.now();\n rec.results.set(cmd.seq, { ts: now, cmd });\n const newest = Math.max(...rec.results.keys());\n for (const [seq, entry] of rec.results) {\n if (seq !== newest && now - entry.ts > RESULT_TTL_MS) {\n rec.results.delete(seq);\n }\n }\n while (rec.results.size > RESULT_LIMIT) {\n rec.results.delete(Math.min(...rec.results.keys()));\n }\n};\n\n/** Cmd-lane watermark: the last statement admitted, settled or not. */\nconst admittedThrough = (rec: ClientRec): number =>\n Math.max(rec.lastSeq, ...rec.inflight.keys());\n\n// A re-asked seq never re-runs: the stored verdict re-emits, an applied\n// inflight run re-answers applied; one not yet applied answers nothing (its\n// answers ride the stream when ready), an evicted verdict answers expired.\nconst reemit = (h: SocketHostState, rec: ClientRec, seq: number) => {\n const cached = rec.results.get(seq);\n if (cached) {\n const newest = Math.max(...rec.results.keys());\n if (seq === newest || Date.now() - cached.ts <= RESULT_TTL_MS) {\n queueCmd(h, rec.id, cached.cmd);\n return;\n }\n rec.results.delete(seq);\n notifyClientRecords(h);\n }\n const adm = rec.inflight.get(seq);\n if (adm) {\n if (adm.applied) queueApplied(h, rec.id, seq);\n return;\n }\n queueCmd(h, rec.id, { seq, type: \"expired\" });\n};\n\nconst settleCmd = (\n h: SocketHostState,\n rec: ClientRec,\n adm: Admission,\n cmd: StatewireCmd,\n) => {\n if (adm.settled) return;\n adm.settled = true;\n rec.inflight.delete(adm.seq);\n retain(rec, cmd);\n rec.lastSeq = Math.max(rec.lastSeq, adm.seq);\n adm.applied = true;\n queueCmd(h, rec.id, cmd);\n notifyClientRecords(h);\n};\n\nconst settleWire = (\n h: SocketHostState,\n rec: ClientRec,\n adm: Admission,\n outcome: CommandsOutcome,\n) => settleCmd(h, rec, adm, cmdOf(adm, outcome));\n\nconst callerOf = (\n h: SocketHostState,\n rec: ClientRec,\n auth: unknown,\n): StatewireHost.Caller => ({\n clientId: rec.id,\n auth,\n get context() {\n return rec.context;\n },\n get isConnected() {\n if (h.clients.get(rec.id) !== rec) return false;\n for (const conn of h.conns) {\n if (conn.clientId === rec.id && conn.open) return true;\n }\n return false;\n },\n});\n\nconst rejectStatement = (\n h: SocketHostState,\n rec: ClientRec,\n adm: Admission,\n message: string,\n) =>\n settleCmd(h, rec, adm, {\n seq: adm.seq,\n type: \"rejected\",\n code: \"invalid-params\",\n message,\n });\n\nconst admitCmd = (\n h: SocketHostState,\n rec: ClientRec,\n statement: CmdStatement,\n auth: unknown,\n selection: StatewireProtocol.Selection,\n) => {\n const adm: Admission = {\n seq: statement.seq,\n method: statement.method,\n applied: false,\n appliedSent: false,\n settled: false,\n };\n rec.inflight.set(statement.seq, adm);\n notifyClientRecords(h);\n if (\n statement.protocol !== h.protocol.name ||\n !selection.protocols.some((p) => p.name === statement.protocol)\n ) {\n settleCmd(h, rec, adm, {\n seq: adm.seq,\n type: \"rejected\",\n code: \"unsupported-protocol\",\n message: \"command protocol was not negotiated\",\n });\n return;\n }\n if (!Array.isArray(statement.params)) {\n rejectStatement(h, rec, adm, \"params must be an array\");\n return;\n }\n let params = statement.params;\n if (statement.meta !== undefined) {\n try {\n params = reviveValue(params, statement.meta, {\n rejectUnknown: true,\n }) as unknown[];\n } catch (error) {\n rejectStatement(\n h,\n rec,\n adm,\n `invalid params: ${(error as Error).message}`,\n );\n return;\n }\n }\n if (statement.method === \"statewire/commands\") {\n if (params.length > 0) {\n rejectStatement(h, rec, adm, \"statewire/commands takes no params\");\n return;\n }\n const names = [\n ...(h.commandsHost?.methods?.() ?? []),\n \"statewire/commands\",\n ].sort();\n settleCmd(h, rec, adm, { seq: adm.seq, type: \"result\", payload: names });\n return;\n }\n h.commandsHost!.submit!({\n method: statement.method,\n params,\n clientId: rec.id,\n caller: callerOf(h, rec, auth),\n onApplied: () => {\n if (adm.settled || adm.applied) return;\n adm.applied = true;\n rec.lastSeq = Math.max(rec.lastSeq, adm.seq);\n notifyClientRecords(h);\n scheduleFlush(h);\n },\n onSettle: (outcome) => settleWire(h, rec, adm, outcome),\n }).catch((error: unknown) => {\n if (!adm.settled) settleWire(h, rec, adm, { type: \"rejected\", error });\n });\n};\n\n// One admission law, both lanes: absorbed statements answer from the record,\n// then the new suffix is admitted whole or the frame is refused whole via a\n// {syn} stating both watermarks, nothing consumed. A gap is never a close.\nexport type FrameAdmission =\n | { type: \"ok\" }\n | {\n type: \"refused\";\n syn: {\n syn: { seq: number; ctxSeq: number; retry?: number };\n };\n };\n\nexport const admitFrame = (\n h: SocketHostState,\n rec: ClientRec,\n frame: ParsedFrame,\n auth: unknown,\n selection: StatewireProtocol.Selection = {\n version: h.wireVersion.version,\n protocols: [{ name: h.protocol.name, version: h.protocol.version }],\n },\n): FrameAdmission => {\n rec.touched = Date.now();\n const through = admittedThrough(rec);\n for (const statement of frame.cmd) {\n if (statement.seq <= through) reemit(h, rec, statement.seq);\n }\n const ctxNew = frame.ctx.filter((s) => s.seq > rec.ctxSeq);\n const cmdNew = frame.cmd.filter((s) => s.seq > through);\n if (\n (ctxNew.length > 0 && ctxNew[0]!.seq !== rec.ctxSeq + 1) ||\n (cmdNew.length > 0 && cmdNew[0]!.seq !== through + 1)\n ) {\n notifyClientRecords(h);\n return {\n type: \"refused\",\n syn: { syn: { seq: through, ctxSeq: rec.ctxSeq } },\n };\n }\n if (cmdNew.length > 0) {\n let hostCommandLoad = 0;\n for (const client of h.clients.values()) {\n hostCommandLoad += client.inflight.size;\n }\n if (\n rec.inflight.size + cmdNew.length > MAX_INFLIGHT_COMMANDS_PER_CLIENT ||\n hostCommandLoad + cmdNew.length > h.maxInflightCommands\n ) {\n return {\n type: \"refused\",\n syn: {\n syn: {\n seq: through,\n ctxSeq: rec.ctxSeq,\n retry: COMMAND_CAPACITY_RETRY_MS,\n },\n },\n };\n }\n }\n if ((ctxNew.length || cmdNew.length) && h.pushback) {\n const retry = h.pushback();\n if (retry !== null) {\n if (!Number.isSafeInteger(retry) || retry < 0)\n throw new TypeError(\n \"pushback must return a nonnegative safe integer or null\",\n );\n return {\n type: \"refused\",\n syn: { syn: { seq: through, ctxSeq: rec.ctxSeq, retry } },\n };\n }\n }\n let contextDocuments = rec.contextDocuments;\n try {\n for (const statement of ctxNew)\n contextDocuments = applyDocumentOps(\n contextDocuments,\n statement.ops,\n selection.protocols,\n true,\n );\n if (\n frameEncoder.encode(JSON.stringify([...contextDocuments.documents]))\n .byteLength > MAX_CONTEXT_VALUE_BYTES\n )\n return violation(\"oversized-context\");\n } catch {\n return violation(\"invalid-context\");\n }\n rec.contextDocuments = contextDocuments;\n rec.context = (mainDocument(contextDocuments, h.protocol.name)?.value ??\n null) as Record<string, unknown> | null;\n if (ctxNew.length) rec.ctxSeq = ctxNew.at(-1)!.seq;\n for (const statement of cmdNew) admitCmd(h, rec, statement, auth, selection);\n if (cmdNew.length > 0) {\n // Memory host: admitted means retained — dur rides the admitting flush.\n queueCmd(h, rec.id, { seq: cmdNew.at(-1)!.seq, dur: true });\n }\n notifyClientRecords(h);\n scheduleFlush(h);\n return { type: \"ok\" };\n};\n\nconst message = (h: SocketHostState, conn: Conn, data: string) => {\n if (!conn.open || h.disposed || h.finished !== null) return;\n if (frameIsOversized(data)) {\n sendTo(\n h,\n conn,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: \"frame too large\",\n },\n }),\n );\n closeConn(h, conn, 1009, \"frame too large\");\n return;\n }\n const first = !conn.sawFrame;\n conn.sawFrame = true;\n let frame: ParsedFrame;\n try {\n frame = first ? parseInitialFrame(data).frame : parseFrame(data);\n } catch (error) {\n const reason = violationReason(error);\n if (reason === null) throw error;\n sendTo(\n h,\n conn,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: reason,\n },\n }),\n );\n closeConn(h, conn, 1008, reason);\n return;\n }\n if (frame.ctx.length === 0 && frame.cmd.length === 0) return;\n const rec = h.clients.get(conn.clientId)!;\n let admission: ReturnType<typeof admitFrame>;\n try {\n admission = admitFrame(h, rec, frame, conn.auth, conn.selection);\n } catch (error) {\n const reason = violationReason(error);\n if (reason === null) throw error;\n sendTo(\n h,\n conn,\n JSON.stringify({ fin: { reason: \"protocol-error\", message: reason } }),\n );\n closeConn(h, conn, 1008, reason);\n return;\n }\n if (admission.type === \"refused\") {\n sendTo(h, conn, JSON.stringify(admission.syn));\n }\n};\n\nconst closePending = (\n h: SocketHostState,\n pending: PendingConn,\n code?: number,\n reason?: string,\n) => {\n if (!pending.open) return;\n pending.open = false;\n h.pendingConns.delete(pending);\n if (pending.timer !== null) clearTimeout(pending.timer);\n try {\n pending.socket.close(code, reason);\n } catch {\n /* peer already gone */\n }\n};\n\nconst sendPending = (pending: PendingConn, data: string): boolean => {\n if (!pending.open) return false;\n try {\n pending.socket.send(data);\n return true;\n } catch {\n return false;\n }\n};\n\nconst refuseSubscriberLimit = (socket: StatewireHostInternal.Socket): null => {\n try {\n socket.send(\n JSON.stringify({\n fin: {\n reason: \"reconnect\",\n code: \"overloaded\",\n message: SUBSCRIBER_LIMIT_MESSAGE,\n },\n }),\n );\n } catch {\n /* peer already gone */\n }\n try {\n socket.close(1013, SUBSCRIBER_LIMIT_MESSAGE);\n } catch {\n /* peer already gone */\n }\n return null;\n};\n\nconst rejectPendingAuthorization = (\n h: SocketHostState,\n pending: PendingConn,\n error: unknown,\n) => {\n const response = error instanceof Response ? error : null;\n const unauthorized = response?.status === 401 || response?.status === 403;\n const status = response?.status;\n const message = unauthorized\n ? \"unauthorized\"\n : response?.statusText ||\n (status === undefined ? \"authorization failed\" : `HTTP ${status}`);\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason:\n status === 403\n ? \"forbidden\"\n : unauthorized\n ? \"unauthorized\"\n : \"error\",\n message,\n ...(status !== undefined && { status }),\n },\n }),\n );\n closePending(h, pending, unauthorized ? 1008 : 1011, message);\n};\n\nconst normalizedHeaders = (\n headers: Record<string, string>,\n): Record<string, string> => {\n const seen = new Set<string>();\n for (const name of Object.keys(headers)) {\n const key = name.toLowerCase();\n if (seen.has(key)) throw new TypeError(\"duplicate header name\");\n seen.add(key);\n }\n return Object.fromEntries(new Headers(headers));\n};\n\nconst connectAuthorized = (\n h: SocketHostState,\n clientId: string,\n socket: StatewireHostInternal.Socket,\n options: StatewireHostInternal.SocketConnectOptions,\n): StatewireHostInternal.SocketConnection | null => {\n const authorize = h.authorize;\n if (options.authorized === true) {\n const registration = register(\n h,\n clientId,\n socket,\n options.authorized === true,\n options.auth,\n options.selection,\n );\n return registration?.connection ?? null;\n }\n const refuse = (code: number, reason: string) => {\n try {\n socket.close(code, reason);\n } catch {\n /* peer already gone */\n }\n return null;\n };\n if (h.disposed) return refuse(1001, \"disposed\");\n if (!CLIENT_ID_RE.test(clientId)) return refuse(1008, \"invalid client id\");\n flush(h);\n if (h.finished !== null) {\n try {\n socket.send(JSON.stringify({ fin: h.finished }));\n } catch {\n /* peer already gone */\n }\n return refuse(1000, \"finished\");\n }\n const pending: PendingConn = {\n socket,\n open: true,\n authorizing: false,\n queued: [],\n timer: null,\n connection: null,\n };\n h.pendingConns.add(pending);\n pending.timer = setTimeout(\n () =>\n rejectPendingAuthorization(\n h,\n pending,\n new Response(null, { status: 401 }),\n ),\n h.wsInitTimeoutMs,\n );\n (pending.timer as unknown as { unref?: () => void }).unref?.();\n return {\n clientId,\n message: (data) => {\n if (pending.connection !== null) {\n pending.connection.message(data);\n return;\n }\n if (!pending.open || h.disposed || h.finished !== null) return;\n if (frameIsOversized(data)) {\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: \"frame too large\",\n },\n }),\n );\n closePending(h, pending, 1009, \"frame too large\");\n return;\n }\n if (pending.authorizing) {\n pending.queued.push(data);\n return;\n }\n let initial: ReturnType<typeof parseInitialFrame>;\n try {\n initial = parseInitialFrame(data);\n } catch (error) {\n if (error instanceof Response) {\n rejectPendingAuthorization(h, pending, error);\n return;\n }\n const reason = violationReason(error);\n if (reason === null) throw error;\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: reason,\n },\n }),\n );\n closePending(h, pending, 1008, reason);\n return;\n }\n const frame = initial.frame;\n let headers: Record<string, string>;\n try {\n headers = {\n ...normalizedHeaders(initial.headers),\n ...normalizedHeaders(options.headers ?? {}),\n };\n } catch {\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: \"malformed headers\",\n },\n }),\n );\n closePending(h, pending, 1008, \"malformed headers\");\n return;\n }\n if (atSubscriberLimit(h)) {\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason: \"reconnect\",\n code: \"overloaded\",\n message: SUBSCRIBER_LIMIT_MESSAGE,\n },\n }),\n );\n closePending(h, pending, 1013, SUBSCRIBER_LIMIT_MESSAGE);\n return;\n }\n pending.authorizing = true;\n Promise.resolve()\n .then(() => authorize?.({ headers }))\n .then((auth) => {\n if (!pending.open || h.disposed || h.finished !== null) return;\n const selection = negotiateProtocols(\n new Headers(headers),\n h.wireVersion,\n [h.protocol],\n );\n if (\"fin\" in selection) {\n sendPending(pending, JSON.stringify(selection));\n closePending(h, pending, 1008, selection.fin.message);\n return;\n }\n options.onAuthorized?.(auth, selection);\n pending.open = false;\n h.pendingConns.delete(pending);\n if (pending.timer !== null) clearTimeout(pending.timer);\n const registration = register(\n h,\n clientId,\n socket,\n true,\n auth,\n selection,\n );\n if (registration === null) return;\n pending.connection = registration.connection;\n if (frame.ctx.length || frame.cmd.length) {\n message(\n h,\n registration.conn,\n JSON.stringify({\n ...(frame.ctx.length ? { ctx: frame.ctx } : {}),\n ...(frame.cmd.length ? { cmd: frame.cmd } : {}),\n }),\n );\n }\n for (const data of pending.queued.splice(0))\n registration.connection.message(data);\n })\n .catch((error: unknown) => {\n if (pending.open) rejectPendingAuthorization(h, pending, error);\n });\n },\n close: () => {\n if (pending.connection !== null) pending.connection.close();\n else closePending(h, pending);\n },\n };\n};\n\nconst gcClients = (h: SocketHostState) => {\n let excess = h.clients.size - h.clientRecordLimit;\n if (excess <= 0) return;\n let changed = false;\n const live = new Set([...h.conns].map((conn) => conn.clientId));\n const oldest = [...h.clients.values()].sort((a, b) => a.touched - b.touched);\n for (const rec of oldest) {\n if (excess <= 0) break;\n if (live.has(rec.id) || rec.inflight.size > 0) continue;\n h.clients.delete(rec.id);\n changed = true;\n excess -= 1;\n }\n if (changed) notifyClientRecords(h);\n};\n\nexport type Registration = {\n rec: ClientRec;\n conn: Conn;\n connection: StatewireHostInternal.SocketConnection;\n};\n\nexport const register = (\n h: SocketHostState,\n clientId: string,\n socket: StatewireHostInternal.Socket,\n sawFrame = false,\n auth: unknown = undefined,\n selection: StatewireProtocol.Selection = {\n version: h.wireVersion.version,\n protocols: [{ name: h.protocol.name, version: h.protocol.version }],\n },\n): Registration | null => {\n const refuse = (code: number, reason: string) => {\n try {\n socket.close(code, reason);\n } catch {\n /* peer already gone */\n }\n return null;\n };\n if (h.disposed) return refuse(1001, \"disposed\");\n if (!CLIENT_ID_RE.test(clientId)) return refuse(1008, \"invalid client id\");\n flush(h);\n if (h.finished !== null) {\n try {\n socket.send(JSON.stringify({ fin: h.finished }));\n } catch {\n /* peer already gone */\n }\n refuse(1000, \"finished\");\n return null;\n }\n if (atSubscriberLimit(h)) {\n return refuseSubscriberLimit(socket);\n }\n const known = h.clients.get(clientId);\n if (known !== undefined && !authEquals(known.principal, auth)) {\n try {\n socket.send(\n JSON.stringify({\n fin: {\n reason: \"forbidden\",\n message: PRINCIPAL_MISMATCH_MESSAGE,\n status: 403,\n },\n }),\n );\n } catch {\n /* peer already gone */\n }\n return refuse(1008, PRINCIPAL_MISMATCH_MESSAGE);\n }\n const rec =\n known ??\n (() => {\n const created: ClientRec = {\n id: clientId,\n lastSeq: 0,\n ctxSeq: 0,\n touched: Date.now(),\n context: null,\n contextDocuments: { mode: \"mounted\", documents: new Map() },\n results: new Map(),\n inflight: new Map(),\n principal: auth,\n };\n h.clients.set(clientId, created);\n return created;\n })();\n rec.touched = Date.now();\n const conn: Conn = {\n selection,\n clientId,\n socket,\n open: true,\n sawFrame,\n lastSentAt: 0,\n lease: null,\n auth,\n };\n h.conns.add(conn);\n gcClients(h);\n notifyClientRecords(h);\n ensureHeartbeat(h);\n const { value, meta } = encodeDocument(h.stateHost!.snapshot());\n const hello: StatewireEnvelope = {\n ops: [\n {\n op: \"mount\",\n protocol: h.protocol.name,\n main: true,\n value,\n ...(meta !== undefined && { meta }),\n },\n ],\n syn: {\n ...selection,\n seq: admittedThrough(rec),\n ctxSeq: rec.ctxSeq,\n ...(h.idleWire && { idle: true }),\n },\n };\n if (!selection.protocols.some((p) => p.name === h.protocol.name))\n hello.ops = [];\n sendTo(h, conn, JSON.stringify(hello));\n const connection: StatewireHostInternal.SocketConnection = {\n clientId,\n message: (data) => message(h, conn, data),\n close: () => closeConn(h, conn),\n };\n return { rec, conn, connection };\n};\n\nconst connect = (\n h: SocketHostState,\n clientId: string,\n socket: StatewireHostInternal.Socket,\n options: StatewireHostInternal.SocketConnectOptions = {},\n): StatewireHostInternal.SocketConnection | null => {\n return connectAuthorized(h, clientId, socket, options);\n};\n\nconst finish = (h: SocketHostState, fin: StatewireHost.Fin) => {\n if (\n fin.retry !== undefined &&\n (!Number.isSafeInteger(fin.retry) || fin.retry < 0)\n ) {\n throw new Error(\"statewire: retry must be a nonnegative safe integer\");\n }\n if (h.finished !== null || h.disposed) return;\n h.commandsHost?.abort?.();\n h.finished = fin;\n for (const pending of [...h.pendingConns]) {\n sendPending(pending, JSON.stringify({ fin }));\n closePending(h, pending, 1000, fin.reason);\n }\n flush(h, fin);\n};\n\nconst resume = (h: SocketHostState) => {\n h.disposed = false;\n h.stateHost?.setOnOp((op) => recordOp(h, op));\n};\n\nconst suspend = (h: SocketHostState) => {\n h.disposed = true;\n if (h.heartbeatTimer !== null) {\n clearInterval(h.heartbeatTimer);\n h.heartbeatTimer = null;\n }\n h.stateHost?.setOnOp(null);\n};\n\nconst restoreClientRecords = (\n records: readonly StatewireHostInternal.ClientRecord[] = [],\n): Map<string, ClientRec> =>\n new Map(\n records.map((record) => [\n record.id,\n {\n ...record,\n contextDocuments: {\n mode: \"mounted\",\n documents: new Map(record.contextDocuments ?? []),\n },\n results: new Map(\n record.results.map(({ seq, ts, cmd }) => [seq, { ts, cmd }]),\n ),\n inflight: new Map(),\n },\n ]),\n );\n\nconst useSocketHost = (\n transport: ResourceElement<Statewire>,\n options?: StatewireHostInternal.SocketHostOptions,\n persistence?: StatewireHostInternal.SocketHostPersistence,\n): Pick<\n StatewireHostInternal.SocketHost,\n \"connect\" | \"finish\" | \"stream\" | \"frames\"\n> => {\n const [h] = useState((): SocketHostState => {\n const host: SocketHostState = {\n protocol: { name: DEFAULT_PROTOCOL, version: WIRE_VERSION },\n wireVersion: { version: WIRE_VERSION },\n heartbeatMs: 15_000,\n wsInitTimeoutMs: 5_000,\n maxSubscribers: MAX_SUBSCRIBERS,\n maxInflightCommands: MAX_INFLIGHT_COMMANDS_PER_HOST,\n streamQueueSize: STREAM_QUEUE_SIZE,\n clientRecordLimit: CLIENT_RECORD_LIMIT,\n finOnIdle: false,\n pushback: undefined,\n authorize: undefined,\n clients: restoreClientRecords(persistence?.clientRecords),\n conns: new Set(),\n pendingConns: new Set(),\n pendingOps: [],\n pendingApplied: new Map(),\n pendingCmds: new Map(),\n idleWire: true,\n finished: null,\n disposed: false,\n flushScheduled: false,\n heartbeatTimer: null,\n stateHost: null,\n commandsHost: null,\n current: null,\n persistence,\n post: createMacrotaskPoster(() => {\n host.flushScheduled = false;\n flush(host);\n }),\n connect: (clientId, socket, connectOptions) =>\n connect(host, clientId, socket, connectOptions),\n finish: (fin) => finish(host, fin),\n stream: (request) => serveStream(host, request),\n frames: (request) => serveFrames(host, request),\n };\n return host;\n });\n h.protocol = options?.protocol ?? {\n name: DEFAULT_PROTOCOL,\n version: WIRE_VERSION,\n };\n h.wireVersion = options?.wireVersion ?? { version: WIRE_VERSION };\n setHeartbeatMs(h, options?.heartbeatIntervalMs ?? 15_000);\n h.pushback = options?.pushback;\n h.wsInitTimeoutMs = options?.wsInitTimeoutMs ?? 5_000;\n const maxSubscribers =\n options?.maxSubscribers === undefined\n ? MAX_SUBSCRIBERS\n : options.maxSubscribers;\n if (!Number.isInteger(maxSubscribers) || maxSubscribers < 1) {\n throw new TypeError(\"maxSubscribers must be a positive integer\");\n }\n h.maxSubscribers = maxSubscribers;\n const maxInflightCommands =\n options?.maxInflightCommands === undefined\n ? MAX_INFLIGHT_COMMANDS_PER_HOST\n : options.maxInflightCommands;\n if (!Number.isInteger(maxInflightCommands) || maxInflightCommands < 1) {\n throw new TypeError(\"maxInflightCommands must be a positive integer\");\n }\n h.maxInflightCommands = maxInflightCommands;\n const streamQueueSize =\n options?.streamQueueSize === undefined\n ? STREAM_QUEUE_SIZE\n : options.streamQueueSize;\n if (!Number.isInteger(streamQueueSize) || streamQueueSize < 1) {\n throw new TypeError(\"streamQueueSize must be a positive integer\");\n }\n h.streamQueueSize = streamQueueSize;\n h.clientRecordLimit = options?.clientRecordLimit ?? CLIENT_RECORD_LIMIT;\n h.finOnIdle = options?.finOnIdle ?? false;\n h.authorize = options?.authorize;\n const value = useResource(transport) as Statewire<unknown>;\n attach(h, value);\n useEffect(() => {\n attach(h, value);\n scheduleFlush(h);\n });\n useEffect(() => {\n resume(h);\n return () => suspend(h);\n }, [h]);\n return h;\n};\n\n/**\n * Transport-agnostic WS binding over a statewire/host transport:\n * feed it sockets (anything with `send`/`close`) and raw text frames, and it\n * speaks the Statewire packet protocol — snapshot-first hello with `syn`,\n * statement-lane client frames under one admission law, `{cmd}` answer\n * arrays fanned out to every attach of a client id, idle edges, and `fin` on\n * finish.\n */\nexport const StatewireSocketHost = (\n transport: ResourceElement<Statewire>,\n options?: StatewireHostInternal.SocketHostOptions,\n persistence?: StatewireHostInternal.SocketHostPersistence,\n): StatewireHostInternal.SocketHost => {\n const SocketHostRoot = () => useSocketHost(transport, options, persistence);\n const root = createTapRoot(SocketHostRoot);\n let disposed = false;\n return {\n connect: (clientId, socket, connectOptions) =>\n flushTapSync(() =>\n root.getValue().connect(clientId, socket, connectOptions),\n ),\n stream: (request) => flushTapSync(() => root.getValue().stream(request)),\n frames: (request) => flushTapSync(() => root.getValue().frames(request)),\n finish: (fin) => flushTapSync(() => root.getValue().finish(fin)),\n dispose: () => {\n if (disposed) return;\n disposed = true;\n flushTapSync(() =>\n root.getValue().finish({ reason: \"reconnect\", code: \"evicted\" }),\n );\n root.unmount();\n },\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"socket.js","names":["encodeDocument","DEFAULT_PROTOCOL","WIRE_VERSION","negotiateProtocols","StatewireProtocol","applyDocumentOps","mainDocument","StatewireDocuments","useEffect","useState","createTapRoot","flushTapSync","useResource","ResourceElement","getCommandsHost","getStateHost","CommandsHost","CommandsOutcome","StatewireSendError","Statewire","StatewireHost","StatewireHostInternal","reviveValue","COMMAND_CAPACITY_RETRY_MS","MAX_COMMANDS_PER_FRAME","MAX_CONTEXT_VALUE_BYTES","MAX_FRAME_BODY_BYTES","MAX_INFLIGHT_COMMANDS_PER_CLIENT","MAX_INFLIGHT_COMMANDS_PER_HOST","createMacrotaskPoster","StatewireDocument","StatewirePath","StatewireCmd","StatewireEnvelope","frames","serveFrames","stream","serveStream","CLIENT_ID_RE","PRINCIPAL_MISMATCH_MESSAGE","authEquals","a","b","Object","is","Date","getTime","Array","isArray","length","every","v","i","getPrototypeOf","prototype","keysA","keys","keysB","key","Record","RESULT_TTL_MS","RESULT_LIMIT","CLIENT_RECORD_LIMIT","MAX_SUBSCRIBERS","SUBSCRIBER_LIMIT_MESSAGE","STREAM_QUEUE_SIZE","WireOp","op","path","value","meta","MetaEntry","Admission","seq","method","applied","appliedSent","settled","ClientRec","id","lastSeq","touched","results","Map","ts","cmd","inflight","principal","Conn","selection","Selection","clientId","socket","Socket","open","sawFrame","lastSentAt","lease","auth","ctxSeq","context","contextDocuments","State","PendingConn","authorizing","queued","timer","ReturnType","setTimeout","connection","SocketConnection","violation","reason","assign","Error","name","violationReason","error","message","CtxStatement","ops","CmdStatement","protocol","params","ParsedFrame","ctx","isPlainObject","parseLane","statements","prev","statement","Number","isInteger","push","frameEncoder","TextEncoder","parseFrameValue","frame","unknown","filter","sort","undefined","lane","encode","JSON","stringify","byteLength","parseFrame","raw","parse","frameIsOversized","encodePayload","payload","cmdOf","adm","outcome","type","failure","fate","code","String","parseInitialFrame","headers","lanes","Response","status","values","some","SocketHostState","Definition","wireVersion","Range","heartbeatMs","wsInitTimeoutMs","maxSubscribers","maxInflightCommands","streamQueueSize","clientRecordLimit","finOnIdle","pushback","authorize","SocketHostOptions","clients","conns","Set","pendingConns","pendingOps","pendingApplied","pendingCmds","idleWire","finished","Fin","disposed","flushScheduled","heartbeatTimer","setInterval","stateHost","StateHost","commandsHost","current","persistence","SocketHostPersistence","post","connect","options","SocketConnectOptions","finish","fin","request","Request","Promise","scheduleFlush","h","recordOp","attach","next","nextState","state","nextCommands","commands","submit","setOnOp","closeConn","conn","delete","close","size","clearInterval","sendTo","data","now","send","atSubscriberLimit","ensureHeartbeat","unref","setHeartbeatMs","ms","idleLevel","work","isIdle","rec","flush","takeChanged","queueApplied","level","edge","cmds","appliedEntries","get","map","packet","protocols","p","idle","verdicts","dur","list","set","queueCmd","notifyClientRecords","onClientRecordsChange","admittedThrough","entry","retain","newest","Math","max","min","reemit","cached","settleCmd","settleWire","callerOf","Caller","isConnected","rejectStatement","admitCmd","rejectUnknown","names","methods","caller","onApplied","onSettle","catch","FrameAdmission","syn","retry","admitFrame","through","ctxNew","s","cmdNew","hostCommandLoad","client","isSafeInteger","TypeError","documents","at","first","admission","closePending","pending","clearTimeout","sendPending","refuseSubscriberLimit","rejectPendingAuthorization","response","unauthorized","statusText","normalizedHeaders","seen","toLowerCase","has","add","fromEntries","Headers","connectAuthorized","authorized","registration","register","refuse","test","initial","resolve","then","onAuthorized","splice","gcClients","excess","changed","live","oldest","Registration","version","known","created","mode","snapshot","hello","main","abort","resume","suspend","restoreClientRecords","records","ClientRecord","record","useSocketHost","transport","Pick","SocketHost","host","clientRecords","connectOptions","heartbeatIntervalMs","StatewireSocketHost","SocketHostRoot","root","getValue","dispose","unmount"],"sources":["../../src/host/socket.ts"],"sourcesContent":["import { encodeDocument } from \"../document\";\nimport {\n DEFAULT_PROTOCOL,\n WIRE_VERSION,\n negotiateProtocols,\n} from \"../wire/protocol\";\nimport type { StatewireProtocol } from \"../wire/protocol\";\nimport { applyDocumentOps, mainDocument } from \"../wire/documents\";\nimport type { StatewireDocuments } from \"../wire/documents\";\nimport { useEffect, useState } from \"react\";\nimport { createTapRoot, flushTapSync, useResource } from \"@assistant-ui/tap\";\nimport type { ResourceElement } from \"@assistant-ui/tap\";\nimport { getCommandsHost, getStateHost } from \"./host\";\nimport type { CommandsHost, CommandsOutcome } from \"./host\";\nimport { StatewireSendError } from \"../types\";\nimport type { Statewire } from \"../types\";\nimport type { StatewireHost } from \"../host\";\nimport type { StatewireHostInternal } from \"../host-internal\";\nimport { reviveValue } from \"../wire/meta\";\nimport {\n COMMAND_CAPACITY_RETRY_MS,\n MAX_COMMANDS_PER_FRAME,\n MAX_CONTEXT_VALUE_BYTES,\n MAX_FRAME_BODY_BYTES,\n MAX_INFLIGHT_COMMANDS_PER_CLIENT,\n MAX_INFLIGHT_COMMANDS_PER_HOST,\n} from \"../wire/limits\";\nimport { createMacrotaskPoster } from \"../util/macrotask\";\nimport type { StatewireDocument } from \"../document\";\nimport type { StatewirePath } from \"../wire/ops\";\nimport type { StatewireCmd, StatewireEnvelope } from \"../client/connection\";\nimport { frames as serveFrames, stream as serveStream } from \"./http\";\n\nexport const CLIENT_ID_RE = /^[A-Za-z0-9._~-]{1,256}$/;\nexport const PRINCIPAL_MISMATCH_MESSAGE =\n \"client id is bound to another principal\";\n\n/** Structural equality over auth values: primitives, Dates, arrays, and plain\n * objects compare by value; anything else by identity. */\nexport const authEquals = (a: unknown, b: unknown): boolean => {\n if (Object.is(a, b)) return true;\n if (a instanceof Date && b instanceof Date)\n return a.getTime() === b.getTime();\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((v, i) => authEquals(v, b[i]));\n }\n if (\n typeof a === \"object\" &&\n typeof b === \"object\" &&\n a !== null &&\n b !== null &&\n Object.getPrototypeOf(a) === Object.prototype &&\n Object.getPrototypeOf(b) === Object.prototype\n ) {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n return (\n keysA.length === keysB.length &&\n keysA.every(\n (key) =>\n key in b &&\n authEquals(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key],\n ),\n )\n );\n }\n return false;\n};\n\nconst RESULT_TTL_MS = 30_000;\nconst RESULT_LIMIT = 256;\nconst CLIENT_RECORD_LIMIT = 1024;\nconst MAX_SUBSCRIBERS = 1024;\nexport const SUBSCRIBER_LIMIT_MESSAGE = \"stream subscriber limit reached\";\nconst STREAM_QUEUE_SIZE = 256;\n\ntype WireOp = {\n op: string;\n path?: StatewirePath;\n value?: unknown;\n meta?: StatewireDocument.MetaEntry[];\n};\n\ntype Admission = {\n seq: number;\n method: string;\n applied: boolean;\n appliedSent: boolean;\n settled: boolean;\n};\n\nexport type ClientRec = {\n id: string;\n lastSeq: number;\n touched: number;\n results: Map<number, { ts: number; cmd: StatewireCmd }>;\n inflight: Map<number, Admission>;\n /** The auth captured at the record's first attach; later attaches must match. */\n principal: unknown;\n};\n\n// The ctx lane is attach scoped: a Conn is born with an empty context table\n// and outlives its socket so an admitted command keeps reading its last value.\nexport type Conn = {\n selection: StatewireProtocol.Selection;\n clientId: string;\n socket: StatewireHostInternal.Socket;\n open: boolean;\n sawFrame: boolean;\n lastSentAt: number;\n lease: string | null;\n /** The awaited `authorize` return captured at this attach's authorization. */\n auth: unknown;\n ctxSeq: number;\n context: Record<string, unknown> | null;\n contextDocuments: StatewireDocuments.State;\n};\n\ntype PendingConn = {\n socket: StatewireHostInternal.Socket;\n open: boolean;\n authorizing: boolean;\n queued: string[];\n timer: ReturnType<typeof setTimeout> | null;\n connection: StatewireHostInternal.SocketConnection | null;\n};\n\n// ─── frame parsing ──────────────────────────────────────\n\nconst violation = (reason: string): never => {\n throw Object.assign(new Error(reason), { name: \"StatewireViolation\" });\n};\n\nconst violationReason = (error: unknown): string | null =>\n error instanceof Error && error.name === \"StatewireViolation\"\n ? error.message\n : null;\n\ntype CtxStatement = { seq: number; ops: unknown[] };\ntype CmdStatement = {\n protocol: string;\n seq: number;\n method: string;\n params: unknown;\n meta?: unknown;\n};\n\nexport type ParsedFrame = {\n ctx: CtxStatement[];\n cmd: CmdStatement[];\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst parseLane = (value: unknown): Record<string, unknown>[] => {\n if (!Array.isArray(value)) return violation(\"malformed frame\");\n if (value.length === 0) return violation(\"empty lane\");\n const statements: Record<string, unknown>[] = [];\n let prev: number | null = null;\n for (const statement of value) {\n if (!isPlainObject(statement)) return violation(\"malformed statement\");\n const seq = statement[\"seq\"];\n if (typeof seq !== \"number\" || !Number.isInteger(seq) || seq < 1) {\n return violation(\"malformed statement\");\n }\n if (prev !== null && seq !== prev + 1) return violation(\"malformed frame\");\n prev = seq;\n statements.push(statement);\n }\n return statements;\n};\n\nconst frameEncoder = new TextEncoder();\n\nexport const parseFrameValue = (frame: unknown): ParsedFrame => {\n if (!isPlainObject(frame)) return violation(\"malformed frame\");\n const keys = Object.keys(frame);\n if (keys.length === 0) return violation(\"malformed frame\");\n const unknown = keys.filter((key) => key !== \"ctx\" && key !== \"cmd\").sort();\n if (unknown.length > 0)\n return violation(`unknown frame key: '${unknown[0]}'`);\n const ctx: CtxStatement[] = [];\n if (frame[\"ctx\"] !== undefined) {\n const lane = frame[\"ctx\"];\n if (Array.isArray(lane) && lane.length > MAX_COMMANDS_PER_FRAME) {\n return violation(\"too many context statements\");\n }\n for (const statement of parseLane(lane)) {\n const ops = statement[\"ops\"];\n if (!Array.isArray(ops) || !ops.length)\n return violation(\"invalid-context\");\n if (\n frameEncoder.encode(JSON.stringify(ops)).byteLength >\n MAX_CONTEXT_VALUE_BYTES\n )\n return violation(\"oversized-context\");\n ctx.push({ seq: statement[\"seq\"] as number, ops });\n }\n }\n const cmd: CmdStatement[] = [];\n if (frame[\"cmd\"] !== undefined) {\n const lane = frame[\"cmd\"];\n if (Array.isArray(lane) && lane.length > MAX_COMMANDS_PER_FRAME) {\n return violation(\"too many commands\");\n }\n for (const statement of parseLane(lane)) {\n const method = statement[\"method\"];\n if (\n typeof method !== \"string\" ||\n typeof statement[\"protocol\"] !== \"string\" ||\n !(\"params\" in statement)\n ) {\n return violation(\"malformed statement\");\n }\n cmd.push({\n protocol: statement[\"protocol\"] as string,\n seq: statement[\"seq\"] as number,\n method,\n params: statement[\"params\"],\n ...(statement[\"meta\"] !== undefined && { meta: statement[\"meta\"] }),\n });\n }\n }\n return { ctx, cmd };\n};\n\nexport const parseFrame = (raw: string): ParsedFrame => {\n let frame: unknown;\n try {\n frame = JSON.parse(raw);\n } catch {\n return violation(\"malformed frame\");\n }\n return parseFrameValue(frame);\n};\n\nconst frameIsOversized = (raw: string): boolean =>\n raw.length > MAX_FRAME_BODY_BYTES ||\n frameEncoder.encode(raw).byteLength > MAX_FRAME_BODY_BYTES;\n\n// ─── verdict encoding ───────────────────────────────────\n\nconst encodePayload = (\n payload: unknown,\n): { payload?: unknown; meta?: StatewireDocument.MetaEntry[] } => {\n if (payload === undefined) return {};\n const { value, meta } = encodeDocument(payload);\n return { payload: value, ...(meta !== undefined && { meta }) };\n};\n\nconst cmdOf = (adm: Admission, outcome: CommandsOutcome): StatewireCmd => {\n if (outcome.type === \"accepted\") {\n return { seq: adm.seq, type: \"result\", ...encodePayload(outcome.payload) };\n }\n const failure =\n outcome.error instanceof StatewireSendError ? outcome.error.failure : null;\n switch (failure?.fate) {\n case \"crashed\":\n return { seq: adm.seq, type: \"crashed\" };\n case \"failed\":\n return {\n seq: adm.seq,\n type: \"failed\",\n ...(failure.message !== undefined && { message: failure.message }),\n };\n case \"rejected\": {\n if (failure.code !== undefined) {\n const message =\n failure.code === \"unknown-command\"\n ? `unknown method: '${adm.method}'`\n : failure.message;\n return {\n seq: adm.seq,\n type: \"rejected\",\n code: failure.code,\n ...(message !== undefined && { message }),\n };\n }\n return {\n seq: adm.seq,\n type: \"rejected\",\n ...(failure.message !== undefined && { message: failure.message }),\n ...encodePayload(failure.payload),\n };\n }\n default:\n return {\n seq: adm.seq,\n type: \"failed\",\n message:\n outcome.error instanceof Error\n ? outcome.error.message\n : String(outcome.error),\n };\n }\n};\n\nconst parseInitialFrame = (raw: string) => {\n let value: unknown;\n try {\n value = JSON.parse(raw);\n } catch {\n return violation(\"malformed frame\");\n }\n if (!isPlainObject(value)) return violation(\"malformed frame\");\n const { headers, ...lanes } = value;\n if (headers === undefined) throw new Response(null, { status: 401 });\n if (\n !isPlainObject(headers) ||\n Object.values(headers).some((v) => typeof v !== \"string\")\n ) {\n return violation(\"malformed headers\");\n }\n return {\n headers: headers as Record<string, string>,\n frame: Object.keys(lanes).length\n ? parseFrameValue(lanes)\n : { ctx: [], cmd: [] },\n };\n};\n\n// ─── host ───────────────────────────────────────────────\n\nexport type SocketHostState = {\n protocol: StatewireProtocol.Definition;\n wireVersion: StatewireProtocol.Range;\n heartbeatMs: number;\n wsInitTimeoutMs: number;\n maxSubscribers: number;\n maxInflightCommands: number;\n streamQueueSize: number;\n clientRecordLimit: number;\n finOnIdle: boolean;\n pushback: (() => number | null) | undefined;\n authorize: StatewireHostInternal.SocketHostOptions[\"authorize\"];\n clients: Map<string, ClientRec>;\n conns: Set<Conn>;\n pendingConns: Set<PendingConn>;\n pendingOps: WireOp[];\n pendingApplied: Map<string, number[]>;\n pendingCmds: Map<string, StatewireCmd[]>;\n idleWire: boolean;\n finished: StatewireHost.Fin | null;\n disposed: boolean;\n flushScheduled: boolean;\n heartbeatTimer: ReturnType<typeof setInterval> | null;\n stateHost: StatewireHost.StateHost | null;\n commandsHost: CommandsHost | null;\n current: Statewire<unknown> | null;\n persistence: StatewireHostInternal.SocketHostPersistence | undefined;\n post: () => void;\n connect: (\n clientId: string,\n socket: StatewireHostInternal.Socket,\n options?: StatewireHostInternal.SocketConnectOptions,\n ) => StatewireHostInternal.SocketConnection | null;\n finish: (fin: StatewireHost.Fin) => void;\n stream: (request: Request) => Promise<Response>;\n frames: (request: Request) => Promise<Response>;\n};\n\nconst scheduleFlush = (h: SocketHostState) => {\n if (h.flushScheduled || h.disposed) return;\n h.flushScheduled = true;\n h.post();\n};\n\nconst recordOp = (\n h: SocketHostState,\n op: {\n op: string;\n path?: StatewirePath;\n value?: unknown;\n },\n) => {\n if (op.op === \"replace\" || op.op === \"add\") {\n const { value, meta } = encodeDocument(op.value);\n h.pendingOps.push({ ...op, value, ...(meta !== undefined && { meta }) });\n } else {\n h.pendingOps.push(op);\n }\n scheduleFlush(h);\n};\n\nconst attach = (h: SocketHostState, next: Statewire<unknown>) => {\n if (next === h.current) return;\n h.current = next;\n const nextState =\n typeof next.state === \"object\" && next.state !== null\n ? getStateHost(next.state)\n : undefined;\n const nextCommands = getCommandsHost(next.commands);\n if (!nextState || !nextCommands?.submit) {\n throw new Error(\n \"StatewireSocketHost requires a statewire/host transport (useStatewireState with object state, useStatewireCommands)\",\n );\n }\n if (nextState !== h.stateHost) {\n h.stateHost?.setOnOp(null);\n h.stateHost = nextState;\n h.stateHost.setOnOp((op) => recordOp(h, op));\n }\n h.commandsHost = nextCommands;\n};\n\nexport const closeConn = (\n h: SocketHostState,\n conn: Conn,\n code?: number,\n reason?: string,\n) => {\n if (!conn.open) return;\n conn.open = false;\n h.conns.delete(conn);\n try {\n conn.socket.close(code, reason);\n } catch {\n /* peer already gone */\n }\n if (h.conns.size === 0 && h.heartbeatTimer !== null) {\n clearInterval(h.heartbeatTimer);\n h.heartbeatTimer = null;\n }\n};\n\nexport const sendTo = (h: SocketHostState, conn: Conn, data: string) => {\n if (!conn.open) return;\n conn.lastSentAt = Date.now();\n try {\n conn.socket.send(data);\n } catch {\n closeConn(h, conn);\n }\n};\n\nexport const atSubscriberLimit = (h: SocketHostState): boolean =>\n h.conns.size +\n [...h.pendingConns].filter((conn) => conn.authorizing).length >=\n h.maxSubscribers;\n\nconst ensureHeartbeat = (h: SocketHostState) => {\n if (h.heartbeatTimer !== null || h.heartbeatMs <= 0) return;\n h.heartbeatTimer = setInterval(() => {\n const now = Date.now();\n for (const conn of [...h.conns]) {\n if (now - conn.lastSentAt >= h.heartbeatMs) sendTo(h, conn, \"{}\");\n }\n }, h.heartbeatMs);\n (h.heartbeatTimer as unknown as { unref?: () => void }).unref?.();\n};\n\nconst setHeartbeatMs = (h: SocketHostState, ms: number) => {\n if (ms === h.heartbeatMs) return;\n h.heartbeatMs = ms;\n if (h.heartbeatTimer !== null) {\n clearInterval(h.heartbeatTimer);\n h.heartbeatTimer = null;\n ensureHeartbeat(h);\n }\n};\n\nconst idleLevel = (h: SocketHostState): boolean => {\n if (h.current?.work?.isIdle === false) return false;\n for (const rec of h.clients.values()) {\n if (rec.inflight.size > 0) return false;\n }\n return true;\n};\n\nexport const flush = (h: SocketHostState, fin?: StatewireHost.Fin) => {\n flushTapSync(() => {});\n h.stateHost?.takeChanged();\n for (const rec of h.clients.values()) {\n for (const adm of rec.inflight.values()) {\n if (adm.applied && !adm.settled && !adm.appliedSent) {\n adm.appliedSent = true;\n queueApplied(h, rec.id, adm.seq);\n }\n }\n }\n const level = idleLevel(h);\n const edge = level !== h.idleWire;\n if (\n h.pendingOps.length === 0 &&\n h.pendingApplied.size === 0 &&\n h.pendingCmds.size === 0 &&\n fin === undefined &&\n !edge\n ) {\n return;\n }\n h.idleWire = level;\n if (fin === undefined && edge && level && h.finOnIdle) {\n fin = { reason: \"idle\" };\n }\n const ops = h.pendingOps;\n const applied = h.pendingApplied;\n const cmds = h.pendingCmds;\n h.pendingOps = [];\n h.pendingApplied = new Map();\n h.pendingCmds = new Map();\n // Applied entries anchor to their effects: piggybacked on the ops packet\n // when one is flushing, standalone otherwise. Terminal verdicts ride their\n // own packet.\n for (const conn of [...h.conns]) {\n const appliedEntries: StatewireCmd[] = (\n applied.get(conn.clientId) ?? []\n ).map((seq) => ({ seq, type: \"applied\" }));\n if (ops.length > 0) {\n const packet: StatewireEnvelope = {\n ops: conn.selection.protocols.some((p) => p.name === h.protocol.name)\n ? ops\n : [],\n ...(appliedEntries.length > 0 && { cmd: appliedEntries }),\n ...(edge && { idle: level }),\n };\n sendTo(h, conn, JSON.stringify(packet));\n } else if (appliedEntries.length > 0) {\n sendTo(h, conn, JSON.stringify({ cmd: appliedEntries }));\n }\n const verdicts = (cmds.get(conn.clientId) ?? []).map((cmd) =>\n conn.selection.protocols.some((p) => p.name === h.protocol.name)\n ? cmd\n : { seq: cmd.seq, ...(cmd.dur === undefined ? {} : { dur: cmd.dur }) },\n );\n if (verdicts.length > 0) {\n sendTo(h, conn, JSON.stringify({ cmd: verdicts }));\n }\n if (edge && ops.length === 0) {\n sendTo(h, conn, JSON.stringify({ idle: level }));\n }\n if (fin !== undefined) {\n sendTo(h, conn, JSON.stringify({ fin }));\n closeConn(h, conn);\n }\n }\n};\n\nconst queueApplied = (h: SocketHostState, clientId: string, seq: number) => {\n const list = h.pendingApplied.get(clientId);\n if (list) list.push(seq);\n else h.pendingApplied.set(clientId, [seq]);\n scheduleFlush(h);\n};\n\nconst queueCmd = (h: SocketHostState, clientId: string, cmd: StatewireCmd) => {\n const list = h.pendingCmds.get(clientId);\n if (list) list.push(cmd);\n else h.pendingCmds.set(clientId, [cmd]);\n scheduleFlush(h);\n};\n\nconst notifyClientRecords = (h: SocketHostState) => {\n h.persistence?.onClientRecordsChange?.(\n [...h.clients.values()].map((rec) => ({\n id: rec.id,\n lastSeq: admittedThrough(rec),\n touched: rec.touched,\n results: [...rec.results].map(([seq, entry]) => ({\n seq,\n ts: entry.ts,\n cmd: entry.cmd,\n })),\n principal: rec.principal,\n })),\n );\n};\n\nconst retain = (rec: ClientRec, cmd: StatewireCmd) => {\n const now = Date.now();\n rec.results.set(cmd.seq, { ts: now, cmd });\n const newest = Math.max(...rec.results.keys());\n for (const [seq, entry] of rec.results) {\n if (seq !== newest && now - entry.ts > RESULT_TTL_MS) {\n rec.results.delete(seq);\n }\n }\n while (rec.results.size > RESULT_LIMIT) {\n rec.results.delete(Math.min(...rec.results.keys()));\n }\n};\n\n/** Cmd-lane watermark: the last statement admitted, settled or not. */\nconst admittedThrough = (rec: ClientRec): number =>\n Math.max(rec.lastSeq, ...rec.inflight.keys());\n\n// A re-asked seq never re-runs: the stored verdict re-emits, an applied\n// inflight run re-answers applied; one not yet applied answers nothing (its\n// answers ride the stream when ready), an evicted verdict answers expired.\nconst reemit = (h: SocketHostState, rec: ClientRec, seq: number) => {\n const cached = rec.results.get(seq);\n if (cached) {\n const newest = Math.max(...rec.results.keys());\n if (seq === newest || Date.now() - cached.ts <= RESULT_TTL_MS) {\n queueCmd(h, rec.id, cached.cmd);\n return;\n }\n rec.results.delete(seq);\n notifyClientRecords(h);\n }\n const adm = rec.inflight.get(seq);\n if (adm) {\n if (adm.applied) queueApplied(h, rec.id, seq);\n return;\n }\n queueCmd(h, rec.id, { seq, type: \"expired\" });\n};\n\nconst settleCmd = (\n h: SocketHostState,\n rec: ClientRec,\n adm: Admission,\n cmd: StatewireCmd,\n) => {\n if (adm.settled) return;\n adm.settled = true;\n rec.inflight.delete(adm.seq);\n retain(rec, cmd);\n rec.lastSeq = Math.max(rec.lastSeq, adm.seq);\n adm.applied = true;\n queueCmd(h, rec.id, cmd);\n notifyClientRecords(h);\n};\n\nconst settleWire = (\n h: SocketHostState,\n rec: ClientRec,\n adm: Admission,\n outcome: CommandsOutcome,\n) => settleCmd(h, rec, adm, cmdOf(adm, outcome));\n\nconst callerOf = (\n h: SocketHostState,\n rec: ClientRec,\n conn: Conn,\n): StatewireHost.Caller => ({\n clientId: rec.id,\n auth: conn.auth,\n get context() {\n return conn.context;\n },\n get isConnected() {\n if (h.clients.get(rec.id) !== rec) return false;\n for (const conn of h.conns) {\n if (conn.clientId === rec.id && conn.open) return true;\n }\n return false;\n },\n});\n\nconst rejectStatement = (\n h: SocketHostState,\n rec: ClientRec,\n adm: Admission,\n message: string,\n) =>\n settleCmd(h, rec, adm, {\n seq: adm.seq,\n type: \"rejected\",\n code: \"invalid-params\",\n message,\n });\n\nconst admitCmd = (\n h: SocketHostState,\n rec: ClientRec,\n conn: Conn,\n statement: CmdStatement,\n) => {\n const adm: Admission = {\n seq: statement.seq,\n method: statement.method,\n applied: false,\n appliedSent: false,\n settled: false,\n };\n rec.inflight.set(statement.seq, adm);\n notifyClientRecords(h);\n if (\n statement.protocol !== h.protocol.name ||\n !conn.selection.protocols.some((p) => p.name === statement.protocol)\n ) {\n settleCmd(h, rec, adm, {\n seq: adm.seq,\n type: \"rejected\",\n code: \"unsupported-protocol\",\n message: \"command protocol was not negotiated\",\n });\n return;\n }\n if (!Array.isArray(statement.params)) {\n rejectStatement(h, rec, adm, \"params must be an array\");\n return;\n }\n let params = statement.params;\n if (statement.meta !== undefined) {\n try {\n params = reviveValue(params, statement.meta, {\n rejectUnknown: true,\n }) as unknown[];\n } catch (error) {\n rejectStatement(\n h,\n rec,\n adm,\n `invalid params: ${(error as Error).message}`,\n );\n return;\n }\n }\n if (statement.method === \"statewire/commands\") {\n if (params.length > 0) {\n rejectStatement(h, rec, adm, \"statewire/commands takes no params\");\n return;\n }\n const names = [\n ...(h.commandsHost?.methods?.() ?? []),\n \"statewire/commands\",\n ].sort();\n settleCmd(h, rec, adm, { seq: adm.seq, type: \"result\", payload: names });\n return;\n }\n h.commandsHost!.submit!({\n method: statement.method,\n params,\n clientId: rec.id,\n caller: callerOf(h, rec, conn),\n onApplied: () => {\n if (adm.settled || adm.applied) return;\n adm.applied = true;\n rec.lastSeq = Math.max(rec.lastSeq, adm.seq);\n notifyClientRecords(h);\n scheduleFlush(h);\n },\n onSettle: (outcome) => settleWire(h, rec, adm, outcome),\n }).catch((error: unknown) => {\n if (!adm.settled) settleWire(h, rec, adm, { type: \"rejected\", error });\n });\n};\n\n// One admission law, both lanes: absorbed statements answer from the record\n// (cmd) or the attach (ctx), then the new suffix is admitted whole or the\n// frame is refused whole via a {syn} stating both watermarks, nothing\n// consumed. A gap is never a close.\nexport type FrameAdmission =\n | { type: \"ok\" }\n | {\n type: \"refused\";\n syn: {\n syn: { seq: number; ctxSeq: number; retry?: number };\n };\n };\n\nexport const admitFrame = (\n h: SocketHostState,\n conn: Conn,\n frame: ParsedFrame,\n): FrameAdmission => {\n const rec = h.clients.get(conn.clientId)!;\n rec.touched = Date.now();\n const through = admittedThrough(rec);\n for (const statement of frame.cmd) {\n if (statement.seq <= through) reemit(h, rec, statement.seq);\n }\n const ctxNew = frame.ctx.filter((s) => s.seq > conn.ctxSeq);\n const cmdNew = frame.cmd.filter((s) => s.seq > through);\n if (\n (ctxNew.length > 0 && ctxNew[0]!.seq !== conn.ctxSeq + 1) ||\n (cmdNew.length > 0 && cmdNew[0]!.seq !== through + 1)\n ) {\n notifyClientRecords(h);\n return {\n type: \"refused\",\n syn: { syn: { seq: through, ctxSeq: conn.ctxSeq } },\n };\n }\n if (cmdNew.length > 0) {\n let hostCommandLoad = 0;\n for (const client of h.clients.values()) {\n hostCommandLoad += client.inflight.size;\n }\n if (\n rec.inflight.size + cmdNew.length > MAX_INFLIGHT_COMMANDS_PER_CLIENT ||\n hostCommandLoad + cmdNew.length > h.maxInflightCommands\n ) {\n return {\n type: \"refused\",\n syn: {\n syn: {\n seq: through,\n ctxSeq: conn.ctxSeq,\n retry: COMMAND_CAPACITY_RETRY_MS,\n },\n },\n };\n }\n }\n if ((ctxNew.length || cmdNew.length) && h.pushback) {\n const retry = h.pushback();\n if (retry !== null) {\n if (!Number.isSafeInteger(retry) || retry < 0)\n throw new TypeError(\n \"pushback must return a nonnegative safe integer or null\",\n );\n return {\n type: \"refused\",\n syn: { syn: { seq: through, ctxSeq: conn.ctxSeq, retry } },\n };\n }\n }\n let contextDocuments = conn.contextDocuments;\n try {\n for (const statement of ctxNew)\n contextDocuments = applyDocumentOps(\n contextDocuments,\n statement.ops,\n conn.selection.protocols,\n true,\n );\n if (\n frameEncoder.encode(JSON.stringify([...contextDocuments.documents]))\n .byteLength > MAX_CONTEXT_VALUE_BYTES\n )\n return violation(\"oversized-context\");\n } catch {\n return violation(\"invalid-context\");\n }\n conn.contextDocuments = contextDocuments;\n conn.context = (mainDocument(contextDocuments, h.protocol.name)?.value ??\n null) as Record<string, unknown> | null;\n if (ctxNew.length) conn.ctxSeq = ctxNew.at(-1)!.seq;\n for (const statement of cmdNew) admitCmd(h, rec, conn, statement);\n if (cmdNew.length > 0) {\n // Memory host: admitted means retained — dur rides the admitting flush.\n queueCmd(h, rec.id, { seq: cmdNew.at(-1)!.seq, dur: true });\n }\n notifyClientRecords(h);\n scheduleFlush(h);\n return { type: \"ok\" };\n};\n\nconst message = (h: SocketHostState, conn: Conn, data: string) => {\n if (!conn.open || h.disposed || h.finished !== null) return;\n if (frameIsOversized(data)) {\n sendTo(\n h,\n conn,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: \"frame too large\",\n },\n }),\n );\n closeConn(h, conn, 1009, \"frame too large\");\n return;\n }\n const first = !conn.sawFrame;\n conn.sawFrame = true;\n let frame: ParsedFrame;\n try {\n frame = first ? parseInitialFrame(data).frame : parseFrame(data);\n } catch (error) {\n const reason = violationReason(error);\n if (reason === null) throw error;\n sendTo(\n h,\n conn,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: reason,\n },\n }),\n );\n closeConn(h, conn, 1008, reason);\n return;\n }\n if (frame.ctx.length === 0 && frame.cmd.length === 0) return;\n let admission: ReturnType<typeof admitFrame>;\n try {\n admission = admitFrame(h, conn, frame);\n } catch (error) {\n const reason = violationReason(error);\n if (reason === null) throw error;\n sendTo(\n h,\n conn,\n JSON.stringify({ fin: { reason: \"protocol-error\", message: reason } }),\n );\n closeConn(h, conn, 1008, reason);\n return;\n }\n if (admission.type === \"refused\") {\n sendTo(h, conn, JSON.stringify(admission.syn));\n }\n};\n\nconst closePending = (\n h: SocketHostState,\n pending: PendingConn,\n code?: number,\n reason?: string,\n) => {\n if (!pending.open) return;\n pending.open = false;\n h.pendingConns.delete(pending);\n if (pending.timer !== null) clearTimeout(pending.timer);\n try {\n pending.socket.close(code, reason);\n } catch {\n /* peer already gone */\n }\n};\n\nconst sendPending = (pending: PendingConn, data: string): boolean => {\n if (!pending.open) return false;\n try {\n pending.socket.send(data);\n return true;\n } catch {\n return false;\n }\n};\n\nconst refuseSubscriberLimit = (socket: StatewireHostInternal.Socket): null => {\n try {\n socket.send(\n JSON.stringify({\n fin: {\n reason: \"reconnect\",\n code: \"overloaded\",\n message: SUBSCRIBER_LIMIT_MESSAGE,\n },\n }),\n );\n } catch {\n /* peer already gone */\n }\n try {\n socket.close(1013, SUBSCRIBER_LIMIT_MESSAGE);\n } catch {\n /* peer already gone */\n }\n return null;\n};\n\nconst rejectPendingAuthorization = (\n h: SocketHostState,\n pending: PendingConn,\n error: unknown,\n) => {\n const response = error instanceof Response ? error : null;\n const unauthorized = response?.status === 401 || response?.status === 403;\n const status = response?.status;\n const message = unauthorized\n ? \"unauthorized\"\n : response?.statusText ||\n (status === undefined ? \"authorization failed\" : `HTTP ${status}`);\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason:\n status === 403\n ? \"forbidden\"\n : unauthorized\n ? \"unauthorized\"\n : \"error\",\n message,\n ...(status !== undefined && { status }),\n },\n }),\n );\n closePending(h, pending, unauthorized ? 1008 : 1011, message);\n};\n\nconst normalizedHeaders = (\n headers: Record<string, string>,\n): Record<string, string> => {\n const seen = new Set<string>();\n for (const name of Object.keys(headers)) {\n const key = name.toLowerCase();\n if (seen.has(key)) throw new TypeError(\"duplicate header name\");\n seen.add(key);\n }\n return Object.fromEntries(new Headers(headers));\n};\n\nconst connectAuthorized = (\n h: SocketHostState,\n clientId: string,\n socket: StatewireHostInternal.Socket,\n options: StatewireHostInternal.SocketConnectOptions,\n): StatewireHostInternal.SocketConnection | null => {\n const authorize = h.authorize;\n if (options.authorized === true) {\n const registration = register(\n h,\n clientId,\n socket,\n options.authorized === true,\n options.auth,\n options.selection,\n );\n return registration?.connection ?? null;\n }\n const refuse = (code: number, reason: string) => {\n try {\n socket.close(code, reason);\n } catch {\n /* peer already gone */\n }\n return null;\n };\n if (h.disposed) return refuse(1001, \"disposed\");\n if (!CLIENT_ID_RE.test(clientId)) return refuse(1008, \"invalid client id\");\n flush(h);\n if (h.finished !== null) {\n try {\n socket.send(JSON.stringify({ fin: h.finished }));\n } catch {\n /* peer already gone */\n }\n return refuse(1000, \"finished\");\n }\n const pending: PendingConn = {\n socket,\n open: true,\n authorizing: false,\n queued: [],\n timer: null,\n connection: null,\n };\n h.pendingConns.add(pending);\n pending.timer = setTimeout(\n () =>\n rejectPendingAuthorization(\n h,\n pending,\n new Response(null, { status: 401 }),\n ),\n h.wsInitTimeoutMs,\n );\n (pending.timer as unknown as { unref?: () => void }).unref?.();\n return {\n clientId,\n message: (data) => {\n if (pending.connection !== null) {\n pending.connection.message(data);\n return;\n }\n if (!pending.open || h.disposed || h.finished !== null) return;\n if (frameIsOversized(data)) {\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: \"frame too large\",\n },\n }),\n );\n closePending(h, pending, 1009, \"frame too large\");\n return;\n }\n if (pending.authorizing) {\n pending.queued.push(data);\n return;\n }\n let initial: ReturnType<typeof parseInitialFrame>;\n try {\n initial = parseInitialFrame(data);\n } catch (error) {\n if (error instanceof Response) {\n rejectPendingAuthorization(h, pending, error);\n return;\n }\n const reason = violationReason(error);\n if (reason === null) throw error;\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: reason,\n },\n }),\n );\n closePending(h, pending, 1008, reason);\n return;\n }\n const frame = initial.frame;\n let headers: Record<string, string>;\n try {\n headers = {\n ...normalizedHeaders(initial.headers),\n ...normalizedHeaders(options.headers ?? {}),\n };\n } catch {\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason: \"protocol-error\",\n message: \"malformed headers\",\n },\n }),\n );\n closePending(h, pending, 1008, \"malformed headers\");\n return;\n }\n if (atSubscriberLimit(h)) {\n sendPending(\n pending,\n JSON.stringify({\n fin: {\n reason: \"reconnect\",\n code: \"overloaded\",\n message: SUBSCRIBER_LIMIT_MESSAGE,\n },\n }),\n );\n closePending(h, pending, 1013, SUBSCRIBER_LIMIT_MESSAGE);\n return;\n }\n pending.authorizing = true;\n Promise.resolve()\n .then(() => authorize?.({ headers }))\n .then((auth) => {\n if (!pending.open || h.disposed || h.finished !== null) return;\n const selection = negotiateProtocols(\n new Headers(headers),\n h.wireVersion,\n [h.protocol],\n );\n if (\"fin\" in selection) {\n sendPending(pending, JSON.stringify(selection));\n closePending(h, pending, 1008, selection.fin.message);\n return;\n }\n options.onAuthorized?.(auth, selection);\n pending.open = false;\n h.pendingConns.delete(pending);\n if (pending.timer !== null) clearTimeout(pending.timer);\n const registration = register(\n h,\n clientId,\n socket,\n true,\n auth,\n selection,\n );\n if (registration === null) return;\n pending.connection = registration.connection;\n if (frame.ctx.length || frame.cmd.length) {\n message(\n h,\n registration.conn,\n JSON.stringify({\n ...(frame.ctx.length ? { ctx: frame.ctx } : {}),\n ...(frame.cmd.length ? { cmd: frame.cmd } : {}),\n }),\n );\n }\n for (const data of pending.queued.splice(0))\n registration.connection.message(data);\n })\n .catch((error: unknown) => {\n if (pending.open) rejectPendingAuthorization(h, pending, error);\n });\n },\n close: () => {\n if (pending.connection !== null) pending.connection.close();\n else closePending(h, pending);\n },\n };\n};\n\nconst gcClients = (h: SocketHostState) => {\n let excess = h.clients.size - h.clientRecordLimit;\n if (excess <= 0) return;\n let changed = false;\n const live = new Set([...h.conns].map((conn) => conn.clientId));\n const oldest = [...h.clients.values()].sort((a, b) => a.touched - b.touched);\n for (const rec of oldest) {\n if (excess <= 0) break;\n if (live.has(rec.id) || rec.inflight.size > 0) continue;\n h.clients.delete(rec.id);\n changed = true;\n excess -= 1;\n }\n if (changed) notifyClientRecords(h);\n};\n\nexport type Registration = {\n conn: Conn;\n connection: StatewireHostInternal.SocketConnection;\n};\n\nexport const register = (\n h: SocketHostState,\n clientId: string,\n socket: StatewireHostInternal.Socket,\n sawFrame = false,\n auth: unknown = undefined,\n selection: StatewireProtocol.Selection = {\n version: h.wireVersion.version,\n protocols: [{ name: h.protocol.name, version: h.protocol.version }],\n },\n): Registration | null => {\n const refuse = (code: number, reason: string) => {\n try {\n socket.close(code, reason);\n } catch {\n /* peer already gone */\n }\n return null;\n };\n if (h.disposed) return refuse(1001, \"disposed\");\n if (!CLIENT_ID_RE.test(clientId)) return refuse(1008, \"invalid client id\");\n flush(h);\n if (h.finished !== null) {\n try {\n socket.send(JSON.stringify({ fin: h.finished }));\n } catch {\n /* peer already gone */\n }\n refuse(1000, \"finished\");\n return null;\n }\n if (atSubscriberLimit(h)) {\n return refuseSubscriberLimit(socket);\n }\n const known = h.clients.get(clientId);\n if (known !== undefined && !authEquals(known.principal, auth)) {\n try {\n socket.send(\n JSON.stringify({\n fin: {\n reason: \"forbidden\",\n message: PRINCIPAL_MISMATCH_MESSAGE,\n status: 403,\n },\n }),\n );\n } catch {\n /* peer already gone */\n }\n return refuse(1008, PRINCIPAL_MISMATCH_MESSAGE);\n }\n const rec =\n known ??\n (() => {\n const created: ClientRec = {\n id: clientId,\n lastSeq: 0,\n touched: Date.now(),\n results: new Map(),\n inflight: new Map(),\n principal: auth,\n };\n h.clients.set(clientId, created);\n return created;\n })();\n rec.touched = Date.now();\n const conn: Conn = {\n selection,\n clientId,\n socket,\n open: true,\n sawFrame,\n lastSentAt: 0,\n lease: null,\n auth,\n ctxSeq: 0,\n context: null,\n contextDocuments: { mode: \"mounted\", documents: new Map() },\n };\n h.conns.add(conn);\n gcClients(h);\n notifyClientRecords(h);\n ensureHeartbeat(h);\n const { value, meta } = encodeDocument(h.stateHost!.snapshot());\n const hello: StatewireEnvelope = {\n ops: [\n {\n op: \"mount\",\n protocol: h.protocol.name,\n main: true,\n value,\n ...(meta !== undefined && { meta }),\n },\n ],\n syn: {\n ...selection,\n seq: admittedThrough(rec),\n ctxSeq: 0,\n ...(h.idleWire && { idle: true }),\n },\n };\n if (!selection.protocols.some((p) => p.name === h.protocol.name))\n hello.ops = [];\n sendTo(h, conn, JSON.stringify(hello));\n const connection: StatewireHostInternal.SocketConnection = {\n clientId,\n message: (data) => message(h, conn, data),\n close: () => closeConn(h, conn),\n };\n return { conn, connection };\n};\n\nconst connect = (\n h: SocketHostState,\n clientId: string,\n socket: StatewireHostInternal.Socket,\n options: StatewireHostInternal.SocketConnectOptions = {},\n): StatewireHostInternal.SocketConnection | null => {\n return connectAuthorized(h, clientId, socket, options);\n};\n\nconst finish = (h: SocketHostState, fin: StatewireHost.Fin) => {\n if (\n fin.retry !== undefined &&\n (!Number.isSafeInteger(fin.retry) || fin.retry < 0)\n ) {\n throw new Error(\"statewire: retry must be a nonnegative safe integer\");\n }\n if (h.finished !== null || h.disposed) return;\n h.commandsHost?.abort?.();\n h.finished = fin;\n for (const pending of [...h.pendingConns]) {\n sendPending(pending, JSON.stringify({ fin }));\n closePending(h, pending, 1000, fin.reason);\n }\n flush(h, fin);\n};\n\nconst resume = (h: SocketHostState) => {\n h.disposed = false;\n h.stateHost?.setOnOp((op) => recordOp(h, op));\n};\n\nconst suspend = (h: SocketHostState) => {\n h.disposed = true;\n if (h.heartbeatTimer !== null) {\n clearInterval(h.heartbeatTimer);\n h.heartbeatTimer = null;\n }\n h.stateHost?.setOnOp(null);\n};\n\nconst restoreClientRecords = (\n records: readonly StatewireHostInternal.ClientRecord[] = [],\n): Map<string, ClientRec> =>\n new Map(\n records.map((record) => [\n record.id,\n {\n id: record.id,\n lastSeq: record.lastSeq,\n touched: record.touched,\n results: new Map(\n record.results.map(({ seq, ts, cmd }) => [seq, { ts, cmd }]),\n ),\n inflight: new Map(),\n principal: record.principal,\n },\n ]),\n );\n\nconst useSocketHost = (\n transport: ResourceElement<Statewire>,\n options?: StatewireHostInternal.SocketHostOptions,\n persistence?: StatewireHostInternal.SocketHostPersistence,\n): Pick<\n StatewireHostInternal.SocketHost,\n \"connect\" | \"finish\" | \"stream\" | \"frames\"\n> => {\n const [h] = useState((): SocketHostState => {\n const host: SocketHostState = {\n protocol: { name: DEFAULT_PROTOCOL, version: WIRE_VERSION },\n wireVersion: { version: WIRE_VERSION },\n heartbeatMs: 15_000,\n wsInitTimeoutMs: 5_000,\n maxSubscribers: MAX_SUBSCRIBERS,\n maxInflightCommands: MAX_INFLIGHT_COMMANDS_PER_HOST,\n streamQueueSize: STREAM_QUEUE_SIZE,\n clientRecordLimit: CLIENT_RECORD_LIMIT,\n finOnIdle: false,\n pushback: undefined,\n authorize: undefined,\n clients: restoreClientRecords(persistence?.clientRecords),\n conns: new Set(),\n pendingConns: new Set(),\n pendingOps: [],\n pendingApplied: new Map(),\n pendingCmds: new Map(),\n idleWire: true,\n finished: null,\n disposed: false,\n flushScheduled: false,\n heartbeatTimer: null,\n stateHost: null,\n commandsHost: null,\n current: null,\n persistence,\n post: createMacrotaskPoster(() => {\n host.flushScheduled = false;\n flush(host);\n }),\n connect: (clientId, socket, connectOptions) =>\n connect(host, clientId, socket, connectOptions),\n finish: (fin) => finish(host, fin),\n stream: (request) => serveStream(host, request),\n frames: (request) => serveFrames(host, request),\n };\n return host;\n });\n h.protocol = options?.protocol ?? {\n name: DEFAULT_PROTOCOL,\n version: WIRE_VERSION,\n };\n h.wireVersion = options?.wireVersion ?? { version: WIRE_VERSION };\n setHeartbeatMs(h, options?.heartbeatIntervalMs ?? 15_000);\n h.pushback = options?.pushback;\n h.wsInitTimeoutMs = options?.wsInitTimeoutMs ?? 5_000;\n const maxSubscribers =\n options?.maxSubscribers === undefined\n ? MAX_SUBSCRIBERS\n : options.maxSubscribers;\n if (!Number.isInteger(maxSubscribers) || maxSubscribers < 1) {\n throw new TypeError(\"maxSubscribers must be a positive integer\");\n }\n h.maxSubscribers = maxSubscribers;\n const maxInflightCommands =\n options?.maxInflightCommands === undefined\n ? MAX_INFLIGHT_COMMANDS_PER_HOST\n : options.maxInflightCommands;\n if (!Number.isInteger(maxInflightCommands) || maxInflightCommands < 1) {\n throw new TypeError(\"maxInflightCommands must be a positive integer\");\n }\n h.maxInflightCommands = maxInflightCommands;\n const streamQueueSize =\n options?.streamQueueSize === undefined\n ? STREAM_QUEUE_SIZE\n : options.streamQueueSize;\n if (!Number.isInteger(streamQueueSize) || streamQueueSize < 1) {\n throw new TypeError(\"streamQueueSize must be a positive integer\");\n }\n h.streamQueueSize = streamQueueSize;\n h.clientRecordLimit = options?.clientRecordLimit ?? CLIENT_RECORD_LIMIT;\n h.finOnIdle = options?.finOnIdle ?? false;\n h.authorize = options?.authorize;\n const value = useResource(transport) as Statewire<unknown>;\n attach(h, value);\n useEffect(() => {\n attach(h, value);\n scheduleFlush(h);\n });\n useEffect(() => {\n resume(h);\n return () => suspend(h);\n }, [h]);\n return h;\n};\n\n/**\n * Transport-agnostic WS binding over a statewire/host transport:\n * feed it sockets (anything with `send`/`close`) and raw text frames, and it\n * speaks the Statewire packet protocol — snapshot-first hello with `syn`,\n * statement-lane client frames under one admission law, `{cmd}` answer\n * arrays fanned out to every attach of a client id, idle edges, and `fin` on\n * finish.\n */\nexport const StatewireSocketHost = (\n transport: ResourceElement<Statewire>,\n options?: StatewireHostInternal.SocketHostOptions,\n persistence?: StatewireHostInternal.SocketHostPersistence,\n): StatewireHostInternal.SocketHost => {\n const SocketHostRoot = () => useSocketHost(transport, options, persistence);\n const root = createTapRoot(SocketHostRoot);\n let disposed = false;\n return {\n connect: (clientId, socket, connectOptions) =>\n flushTapSync(() =>\n root.getValue().connect(clientId, socket, connectOptions),\n ),\n stream: (request) => flushTapSync(() => root.getValue().stream(request)),\n frames: (request) => flushTapSync(() => root.getValue().frames(request)),\n finish: (fin) => flushTapSync(() => root.getValue().finish(fin)),\n dispose: () => {\n if (disposed) return;\n disposed = true;\n flushTapSync(() =>\n root.getValue().finish({ reason: \"reconnect\", code: \"evicted\" }),\n );\n root.unmount();\n },\n };\n};\n"],"mappings":";;;;;;;;;;;AAiCA,MAAasC,eAAe;AAC5B,MAAaC,6BACX;;;AAIF,MAAaC,cAAcC,GAAYC,MAAwB;CAC7D,IAAIC,OAAOC,GAAGH,GAAGC,CAAC,GAAG,OAAO;CAC5B,IAAID,aAAaI,QAAQH,aAAaG,MACpC,OAAOJ,EAAEK,QAAQ,MAAMJ,EAAEI,QAAQ;CACnC,IAAIC,MAAMC,QAAQP,CAAC,KAAKM,MAAMC,QAAQN,CAAC,GACrC,OAAOD,EAAEQ,WAAWP,EAAEO,UAAUR,EAAES,OAAOC,GAAGC,MAAMZ,WAAWW,GAAGT,EAAEU,EAAE,CAAC;CAEvE,IACE,OAAOX,MAAM,YACb,OAAOC,MAAM,YACbD,MAAM,QACNC,MAAM,QACNC,OAAOU,eAAeZ,CAAC,MAAME,OAAOW,aACpCX,OAAOU,eAAeX,CAAC,MAAMC,OAAOW,WACpC;EACA,MAAMC,QAAQZ,OAAOa,KAAKf,CAAC;EAC3B,MAAMgB,QAAQd,OAAOa,KAAKd,CAAC;EAC3B,OACEa,MAAMN,WAAWQ,MAAMR,UACvBM,MAAML,OACHQ,QACCA,OAAOhB,KACPF,WACGC,EAA8BiB,MAC9BhB,EAA8BgB,IACjC,CACJ;CAEJ;CACA,OAAO;AACT;AAEA,MAAME,gBAAgB;AACtB,MAAMC,eAAe;AACrB,MAAMC,sBAAsB;AAC5B,MAAMC,kBAAkB;AACxB,MAAaC,2BAA2B;AACxC,MAAMC,oBAAoB;AAuD1B,MAAM8C,aAAaC,WAA0B;CAC3C,MAAMrE,OAAOsE,OAAO,IAAIC,MAAMF,MAAM,GAAG,EAAEG,MAAM,qBAAqB,CAAC;AACvE;AAEA,MAAMC,mBAAmBC,UACvBA,iBAAiBH,SAASG,MAAMF,SAAS,uBACrCE,MAAMC,UACN;AAgBN,MAAMQ,iBAAiBzD,UACrB,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACtB,MAAMC,QAAQqB,KAAK;AAErE,MAAM0D,aAAa1D,UAA8C;CAC/D,IAAI,CAACtB,MAAMC,QAAQqB,KAAK,GAAG,OAAO0C,UAAU,iBAAiB;CAC7D,IAAI1C,MAAMpB,WAAW,GAAG,OAAO8D,UAAU,YAAY;CACrD,MAAMiB,aAAwC,CAAA;CAC9C,IAAIC,OAAsB;CAC1B,KAAK,MAAMC,aAAa7D,OAAO;EAC7B,IAAI,CAACyD,cAAcI,SAAS,GAAG,OAAOnB,UAAU,qBAAqB;EACrE,MAAMtC,MAAMyD,UAAU;EACtB,IAAI,OAAOzD,QAAQ,YAAY,CAAC0D,OAAOC,UAAU3D,GAAG,KAAKA,MAAM,GAC7D,OAAOsC,UAAU,qBAAqB;EAExC,IAAIkB,SAAS,QAAQxD,QAAQwD,OAAO,GAAG,OAAOlB,UAAU,iBAAiB;EACzEkB,OAAOxD;EACPuD,WAAWK,KAAKH,SAAS;CAC3B;CACA,OAAOF;AACT;AAEA,MAAMM,eAAe,IAAIC,YAAY;AAErC,MAAaC,mBAAmBC,UAAgC;CAC9D,IAAI,CAACX,cAAcW,KAAK,GAAG,OAAO1B,UAAU,iBAAiB;CAC7D,MAAMvD,OAAOb,OAAOa,KAAKiF,KAAK;CAC9B,IAAIjF,KAAKP,WAAW,GAAG,OAAO8D,UAAU,iBAAiB;CACzD,MAAM2B,UAAUlF,KAAKmF,QAAQjF,QAAQA,QAAQ,SAASA,QAAQ,KAAK,CAAC,CAACkF,KAAK;CAC1E,IAAIF,QAAQzF,SAAS,GACnB,OAAO8D,UAAU,uBAAuB2B,QAAQ,GAAE,EAAG;CACvD,MAAMb,MAAsB,CAAA;CAC5B,IAAIY,MAAM,WAAWI,KAAAA,GAAW;EAC9B,MAAMC,OAAOL,MAAM;EACnB,IAAI1F,MAAMC,QAAQ8F,IAAI,KAAKA,KAAK7F,SAAAA,KAC9B,OAAO8D,UAAU,6BAA6B;EAEhD,KAAK,MAAMmB,aAAaH,UAAUe,IAAI,GAAG;GACvC,MAAMtB,MAAMU,UAAU;GACtB,IAAI,CAACnF,MAAMC,QAAQwE,GAAG,KAAK,CAACA,IAAIvE,QAC9B,OAAO8D,UAAU,iBAAiB;GACpC,IACEuB,aAAaS,OAAOC,KAAKC,UAAUzB,GAAG,CAAC,CAAC,CAAC0B,aAAAA,OAGzC,OAAOnC,UAAU,mBAAmB;GACtCc,IAAIQ,KAAK;IAAE5D,KAAKyD,UAAU;IAAkBV;GAAI,CAAC;EACnD;CACF;CACA,MAAMnC,MAAsB,CAAA;CAC5B,IAAIoD,MAAM,WAAWI,KAAAA,GAAW;EAC9B,MAAMC,OAAOL,MAAM;EACnB,IAAI1F,MAAMC,QAAQ8F,IAAI,KAAKA,KAAK7F,SAAAA,KAC9B,OAAO8D,UAAU,mBAAmB;EAEtC,KAAK,MAAMmB,aAAaH,UAAUe,IAAI,GAAG;GACvC,MAAMpE,SAASwD,UAAU;GACzB,IACE,OAAOxD,WAAW,YAClB,OAAOwD,UAAU,gBAAgB,YACjC,EAAE,YAAYA,YAEd,OAAOnB,UAAU,qBAAqB;GAExC1B,IAAIgD,KAAK;IACPX,UAAUQ,UAAU;IACpBzD,KAAKyD,UAAU;IACfxD;IACAiD,QAAQO,UAAU;IAClB,GAAIA,UAAU,YAAYW,KAAAA,KAAa,EAAEvE,MAAM4D,UAAU,QAAQ;GACnE,CAAC;EACH;CACF;CACA,OAAO;EAAEL;EAAKxC;CAAI;AACpB;AAEA,MAAa8D,cAAcC,QAA6B;CACtD,IAAIX;CACJ,IAAI;EACFA,QAAQO,KAAKK,MAAMD,GAAG;CACxB,QAAQ;EACN,OAAOrC,UAAU,iBAAiB;CACpC;CACA,OAAOyB,gBAAgBC,KAAK;AAC9B;AAEA,MAAMa,oBAAoBF,QACxBA,IAAInG,SAAAA,WACJqF,aAAaS,OAAOK,GAAG,CAAC,CAACF,aAAAA;AAI3B,MAAMK,iBACJC,YACgE;CAChE,IAAIA,YAAYX,KAAAA,GAAW,OAAO,CAAC;CACnC,MAAM,EAAExE,OAAOC,SAAStE,eAAewJ,OAAO;CAC9C,OAAO;EAAEA,SAASnF;EAAO,GAAIC,SAASuE,KAAAA,KAAa,EAAEvE,KAAK;CAAG;AAC/D;AAEA,MAAMmF,SAASC,KAAgBC,YAA2C;CACxE,IAAIA,QAAQC,SAAS,YACnB,OAAO;EAAEnF,KAAKiF,IAAIjF;EAAKmF,MAAM;EAAU,GAAGL,cAAcI,QAAQH,OAAO;CAAE;CAE3E,MAAMK,UACJF,QAAQtC,iBAAiBnG,qBAAqByI,QAAQtC,MAAMwC,UAAU;CACxE,QAAQA,SAASC,MAAjB;EACE,KAAK,WACH,OAAO;GAAErF,KAAKiF,IAAIjF;GAAKmF,MAAM;EAAU;EACzC,KAAK,UACH,OAAO;GACLnF,KAAKiF,IAAIjF;GACTmF,MAAM;GACN,GAAIC,QAAQvC,YAAYuB,KAAAA,KAAa,EAAEvB,SAASuC,QAAQvC,QAAQ;EAClE;EACF,KAAK;GACH,IAAIuC,QAAQE,SAASlB,KAAAA,GAAW;IAC9B,MAAMvB,UACJuC,QAAQE,SAAS,oBACb,oBAAoBL,IAAIhF,OAAM,KAC9BmF,QAAQvC;IACd,OAAO;KACL7C,KAAKiF,IAAIjF;KACTmF,MAAM;KACNG,MAAMF,QAAQE;KACd,GAAIzC,YAAYuB,KAAAA,KAAa,EAAEvB,QAAQ;IACzC;GACF;GACA,OAAO;IACL7C,KAAKiF,IAAIjF;IACTmF,MAAM;IACN,GAAIC,QAAQvC,YAAYuB,KAAAA,KAAa,EAAEvB,SAASuC,QAAQvC,QAAQ;IAChE,GAAGiC,cAAcM,QAAQL,OAAO;GAClC;EAEF,SACE,OAAO;GACL/E,KAAKiF,IAAIjF;GACTmF,MAAM;GACNtC,SACEqC,QAAQtC,iBAAiBH,QACrByC,QAAQtC,MAAMC,UACd0C,OAAOL,QAAQtC,KAAK;EAC5B;CACJ;AACF;AAEA,MAAM4C,qBAAqBb,QAAgB;CACzC,IAAI/E;CACJ,IAAI;EACFA,QAAQ2E,KAAKK,MAAMD,GAAG;CACxB,QAAQ;EACN,OAAOrC,UAAU,iBAAiB;CACpC;CACA,IAAI,CAACe,cAAczD,KAAK,GAAG,OAAO0C,UAAU,iBAAiB;CAC7D,MAAM,EAAEmD,SAAS,GAAGC,UAAU9F;CAC9B,IAAI6F,YAAYrB,KAAAA,GAAW,MAAM,IAAIuB,SAAS,MAAM,EAAEC,QAAQ,IAAI,CAAC;CACnE,IACE,CAACvC,cAAcoC,OAAO,KACtBvH,OAAO2H,OAAOJ,OAAO,CAAC,CAACK,MAAMpH,MAAM,OAAOA,MAAM,QAAQ,GAExD,OAAO4D,UAAU,mBAAmB;CAEtC,OAAO;EACImD;EACTzB,OAAO9F,OAAOa,KAAK2G,KAAK,CAAC,CAAClH,SACtBuF,gBAAgB2B,KAAK,IACrB;GAAEtC,KAAK,CAAA;GAAIxC,KAAK,CAAA;EAAG;CACzB;AACF;AA0CA,MAAM8H,iBAAiBC,MAAuB;CAC5C,IAAIA,EAAEnB,kBAAkBmB,EAAEpB,UAAU;CACpCoB,EAAEnB,iBAAiB;CACnBmB,EAAEV,KAAK;AACT;AAEA,MAAMW,YACJD,GACAjJ,OAKG;CACH,IAAIA,GAAGA,OAAO,aAAaA,GAAGA,OAAO,OAAO;EAC1C,MAAM,EAAEE,OAAOC,SAAStE,eAAemE,GAAGE,KAAK;EAC/C+I,EAAE1B,WAAWrD,KAAK;GAAE,GAAGlE;GAAIE;GAAO,GAAIC,SAASuE,KAAAA,KAAa,EAAEvE,KAAK;EAAG,CAAC;CACzE,OACE8I,EAAE1B,WAAWrD,KAAKlE,EAAE;CAEtBgJ,cAAcC,CAAC;AACjB;AAEA,MAAME,UAAUF,GAAoBG,SAA6B;CAC/D,IAAIA,SAASH,EAAEb,SAAS;CACxBa,EAAEb,UAAUgB;CACZ,MAAMC,YACJ,OAAOD,KAAKE,UAAU,YAAYF,KAAKE,UAAU,OAC7C1M,aAAawM,KAAKE,KAAK,IACvB5E,KAAAA;CACN,MAAM6E,eAAe5M,gBAAgByM,KAAKI,QAAQ;CAClD,IAAI,CAACH,aAAa,CAACE,cAAcE,QAC/B,MAAM,IAAI1G,MACR,qHACF;CAEF,IAAIsG,cAAcJ,EAAEhB,WAAW;EAC7BgB,EAAEhB,WAAWyB,QAAQ,IAAI;EACzBT,EAAEhB,YAAYoB;EACdJ,EAAEhB,UAAUyB,SAAS1J,OAAOkJ,SAASD,GAAGjJ,EAAE,CAAC;CAC7C;CACAiJ,EAAEd,eAAeoB;AACnB;AAEA,MAAaI,aACXV,GACAW,MACAhE,MACA/C,WACG;CACH,IAAI,CAAC+G,KAAKjI,MAAM;CAChBiI,KAAKjI,OAAO;CACZsH,EAAE7B,MAAMyC,OAAOD,IAAI;CACnB,IAAI;EACFA,KAAKnI,OAAOqI,MAAMlE,MAAM/C,MAAM;CAChC,QAAQ,CACN;CAEF,IAAIoG,EAAE7B,MAAM2C,SAAS,KAAKd,EAAElB,mBAAmB,MAAM;EACnDiC,cAAcf,EAAElB,cAAc;EAC9BkB,EAAElB,iBAAiB;CACrB;AACF;AAEA,MAAakC,UAAUhB,GAAoBW,MAAYM,SAAiB;CACtE,IAAI,CAACN,KAAKjI,MAAM;CAChBiI,KAAK/H,aAAanD,KAAKyL,IAAI;CAC3B,IAAI;EACFP,KAAKnI,OAAO2I,KAAKF,IAAI;CACvB,QAAQ;EACNP,UAAUV,GAAGW,IAAI;CACnB;AACF;AAEA,MAAaS,qBAAqBpB,MAChCA,EAAE7B,MAAM2C,OACN,CAAC,GAAGd,EAAE3B,YAAY,CAAC,CAAC9C,QAAQoF,SAASA,KAAKvH,WAAW,CAAC,CAACvD,UACzDmK,EAAEtC;AAEJ,MAAM2D,mBAAmBrB,MAAuB;CAC9C,IAAIA,EAAElB,mBAAmB,QAAQkB,EAAExC,eAAe,GAAG;CACrDwC,EAAElB,iBAAiBC,kBAAkB;EACnC,MAAMmC,MAAMzL,KAAKyL,IAAI;EACrB,KAAK,MAAMP,QAAQ,CAAC,GAAGX,EAAE7B,KAAK,GAC5B,IAAI+C,MAAMP,KAAK/H,cAAcoH,EAAExC,aAAawD,OAAOhB,GAAGW,MAAM,IAAI;CAEpE,GAAGX,EAAExC,WAAW;CAChB,EAAGsB,eAAqDwC,QAAQ;AAClE;AAEA,MAAMC,kBAAkBvB,GAAoBwB,OAAe;CACzD,IAAIA,OAAOxB,EAAExC,aAAa;CAC1BwC,EAAExC,cAAcgE;CAChB,IAAIxB,EAAElB,mBAAmB,MAAM;EAC7BiC,cAAcf,EAAElB,cAAc;EAC9BkB,EAAElB,iBAAiB;EACnBuC,gBAAgBrB,CAAC;CACnB;AACF;AAEA,MAAMyB,aAAazB,MAAgC;CACjD,IAAIA,EAAEb,SAASuC,MAAMC,WAAW,OAAO,OAAO;CAC9C,KAAK,MAAMC,OAAO5B,EAAE9B,QAAQhB,OAAO,GACjC,IAAI0E,IAAI1J,SAAS4I,OAAO,GAAG,OAAO;CAEpC,OAAO;AACT;AAEA,MAAae,SAAS7B,GAAoBL,QAA4B;CACpEpM,mBAAmB,CAAC,CAAC;CACrByM,EAAEhB,WAAW8C,YAAY;CACzB,KAAK,MAAMF,OAAO5B,EAAE9B,QAAQhB,OAAO,GACjC,KAAK,MAAMZ,OAAOsF,IAAI1J,SAASgF,OAAO,GACpC,IAAIZ,IAAI/E,WAAW,CAAC+E,IAAI7E,WAAW,CAAC6E,IAAI9E,aAAa;EACnD8E,IAAI9E,cAAc;EAClBuK,aAAa/B,GAAG4B,IAAIjK,IAAI2E,IAAIjF,GAAG;CACjC;CAGJ,MAAM2K,QAAQP,UAAUzB,CAAC;CACzB,MAAMiC,OAAOD,UAAUhC,EAAEvB;CACzB,IACEuB,EAAE1B,WAAWzI,WAAW,KACxBmK,EAAEzB,eAAeuC,SAAS,KAC1Bd,EAAExB,YAAYsC,SAAS,KACvBnB,QAAQlE,KAAAA,KACR,CAACwG,MAED;CAEFjC,EAAEvB,WAAWuD;CACb,IAAIrC,QAAQlE,KAAAA,KAAawG,QAAQD,SAAShC,EAAElC,WAC1C6B,MAAM,EAAE/F,QAAQ,OAAO;CAEzB,MAAMQ,MAAM4F,EAAE1B;CACd,MAAM/G,UAAUyI,EAAEzB;CAClB,MAAM2D,OAAOlC,EAAExB;CACfwB,EAAE1B,aAAa,CAAA;CACf0B,EAAEzB,iCAAiB,IAAIxG,IAAI;CAC3BiI,EAAExB,8BAAc,IAAIzG,IAAI;CAIxB,KAAK,MAAM4I,QAAQ,CAAC,GAAGX,EAAE7B,KAAK,GAAG;EAC/B,MAAMgE,kBACJ5K,QAAQ6K,IAAIzB,KAAKpI,QAAQ,KAAK,CAAA,EAAA,CAC9B8J,KAAKhL,SAAS;GAAEA;GAAKmF,MAAM;EAAU,EAAE;EACzC,IAAIpC,IAAIvE,SAAS,GAAG;GAClB,MAAMyM,SAA4B;IAChClI,KAAKuG,KAAKtI,UAAUkK,UAAUpF,MAAMqF,MAAMA,EAAEzI,SAASiG,EAAE1F,SAASP,IAAI,IAChEK,MACA,CAAA;IACJ,GAAI+H,eAAetM,SAAS,KAAK,EAAEoC,KAAKkK,eAAe;IACvD,GAAIF,QAAQ,EAAEQ,MAAMT,MAAM;GAC5B;GACAhB,OAAOhB,GAAGW,MAAM/E,KAAKC,UAAUyG,MAAM,CAAC;EACxC,OAAO,IAAIH,eAAetM,SAAS,GACjCmL,OAAOhB,GAAGW,MAAM/E,KAAKC,UAAU,EAAE5D,KAAKkK,eAAe,CAAC,CAAC;EAEzD,MAAMO,YAAYR,KAAKE,IAAIzB,KAAKpI,QAAQ,KAAK,CAAA,EAAA,CAAI8J,KAAKpK,QACpD0I,KAAKtI,UAAUkK,UAAUpF,MAAMqF,MAAMA,EAAEzI,SAASiG,EAAE1F,SAASP,IAAI,IAC3D9B,MACA;GAAEZ,KAAKY,IAAIZ;GAAK,GAAIY,IAAI0K,QAAQlH,KAAAA,IAAY,CAAC,IAAI,EAAEkH,KAAK1K,IAAI0K,IAAI;EAAG,CACzE;EACA,IAAID,SAAS7M,SAAS,GACpBmL,OAAOhB,GAAGW,MAAM/E,KAAKC,UAAU,EAAE5D,KAAKyK,SAAS,CAAC,CAAC;EAEnD,IAAIT,QAAQ7H,IAAIvE,WAAW,GACzBmL,OAAOhB,GAAGW,MAAM/E,KAAKC,UAAU,EAAE4G,MAAMT,MAAM,CAAC,CAAC;EAEjD,IAAIrC,QAAQlE,KAAAA,GAAW;GACrBuF,OAAOhB,GAAGW,MAAM/E,KAAKC,UAAU,EAAE8D,IAAI,CAAC,CAAC;GACvCe,UAAUV,GAAGW,IAAI;EACnB;CACF;AACF;AAEA,MAAMoB,gBAAgB/B,GAAoBzH,UAAkBlB,QAAgB;CAC1E,MAAMuL,OAAO5C,EAAEzB,eAAe6D,IAAI7J,QAAQ;CAC1C,IAAIqK,MAAMA,KAAK3H,KAAK5D,GAAG;MAClB2I,EAAEzB,eAAesE,IAAItK,UAAU,CAAClB,GAAG,CAAC;CACzC0I,cAAcC,CAAC;AACjB;AAEA,MAAM8C,YAAY9C,GAAoBzH,UAAkBN,QAAsB;CAC5E,MAAM2K,OAAO5C,EAAExB,YAAY4D,IAAI7J,QAAQ;CACvC,IAAIqK,MAAMA,KAAK3H,KAAKhD,GAAG;MAClB+H,EAAExB,YAAYqE,IAAItK,UAAU,CAACN,GAAG,CAAC;CACtC8H,cAAcC,CAAC;AACjB;AAEA,MAAM+C,uBAAuB/C,MAAuB;CAClDA,EAAEZ,aAAa4D,wBACb,CAAC,GAAGhD,EAAE9B,QAAQhB,OAAO,CAAC,CAAC,CAACmF,KAAKT,SAAS;EACpCjK,IAAIiK,IAAIjK;EACRC,SAASqL,gBAAgBrB,GAAG;EAC5B/J,SAAS+J,IAAI/J;EACbC,SAAS,CAAC,GAAG8J,IAAI9J,OAAO,CAAC,CAACuK,KAAK,CAAChL,KAAK6L,YAAY;GAC/C7L;GACAW,IAAIkL,MAAMlL;GACVC,KAAKiL,MAAMjL;EACb,EAAE;EACFE,WAAWyJ,IAAIzJ;CACjB,EAAE,CACJ;AACF;AAEA,MAAMgL,UAAUvB,KAAgB3J,QAAsB;CACpD,MAAMiJ,MAAMzL,KAAKyL,IAAI;CACrBU,IAAI9J,QAAQ+K,IAAI5K,IAAIZ,KAAK;EAAEW,IAAIkJ;EAAKjJ;CAAI,CAAC;CACzC,MAAMmL,SAASC,KAAKC,IAAI,GAAG1B,IAAI9J,QAAQ1B,KAAK,CAAC;CAC7C,KAAK,MAAM,CAACiB,KAAK6L,UAAUtB,IAAI9J,SAC7B,IAAIT,QAAQ+L,UAAUlC,MAAMgC,MAAMlL,KAAKxB,eACrCoL,IAAI9J,QAAQ8I,OAAOvJ,GAAG;CAG1B,OAAOuK,IAAI9J,QAAQgJ,OAAOrK,cACxBmL,IAAI9J,QAAQ8I,OAAOyC,KAAKE,IAAI,GAAG3B,IAAI9J,QAAQ1B,KAAK,CAAC,CAAC;AAEtD;;AAGA,MAAM6M,mBAAmBrB,QACvByB,KAAKC,IAAI1B,IAAIhK,SAAS,GAAGgK,IAAI1J,SAAS9B,KAAK,CAAC;AAK9C,MAAMoN,UAAUxD,GAAoB4B,KAAgBvK,QAAgB;CAClE,MAAMoM,SAAS7B,IAAI9J,QAAQsK,IAAI/K,GAAG;CAClC,IAAIoM,QAAQ;EAEV,IAAIpM,QADWgM,KAAKC,IAAI,GAAG1B,IAAI9J,QAAQ1B,KAAK,CAChCgN,KAAU3N,KAAKyL,IAAI,IAAIuC,OAAOzL,MAAMxB,eAAe;GAC7DsM,SAAS9C,GAAG4B,IAAIjK,IAAI8L,OAAOxL,GAAG;GAC9B;EACF;EACA2J,IAAI9J,QAAQ8I,OAAOvJ,GAAG;EACtB0L,oBAAoB/C,CAAC;CACvB;CACA,MAAM1D,MAAMsF,IAAI1J,SAASkK,IAAI/K,GAAG;CAChC,IAAIiF,KAAK;EACP,IAAIA,IAAI/E,SAASwK,aAAa/B,GAAG4B,IAAIjK,IAAIN,GAAG;EAC5C;CACF;CACAyL,SAAS9C,GAAG4B,IAAIjK,IAAI;EAAEN;EAAKmF,MAAM;CAAU,CAAC;AAC9C;AAEA,MAAMkH,aACJ1D,GACA4B,KACAtF,KACArE,QACG;CACH,IAAIqE,IAAI7E,SAAS;CACjB6E,IAAI7E,UAAU;CACdmK,IAAI1J,SAAS0I,OAAOtE,IAAIjF,GAAG;CAC3B8L,OAAOvB,KAAK3J,GAAG;CACf2J,IAAIhK,UAAUyL,KAAKC,IAAI1B,IAAIhK,SAAS0E,IAAIjF,GAAG;CAC3CiF,IAAI/E,UAAU;CACduL,SAAS9C,GAAG4B,IAAIjK,IAAIM,GAAG;CACvB8K,oBAAoB/C,CAAC;AACvB;AAEA,MAAM2D,cACJ3D,GACA4B,KACAtF,KACAC,YACGmH,UAAU1D,GAAG4B,KAAKtF,KAAKD,MAAMC,KAAKC,OAAO,CAAC;AAE/C,MAAMqH,YACJ5D,GACA4B,KACAjB,UAC0B;CAC1BpI,UAAUqJ,IAAIjK;CACdmB,MAAM6H,KAAK7H;CACX,IAAIE,UAAU;EACZ,OAAO2H,KAAK3H;CACd;CACA,IAAI8K,cAAc;EAChB,IAAI9D,EAAE9B,QAAQkE,IAAIR,IAAIjK,EAAE,MAAMiK,KAAK,OAAO;EAC1C,KAAK,MAAMjB,QAAQX,EAAE7B,OACnB,IAAIwC,KAAKpI,aAAaqJ,IAAIjK,MAAMgJ,KAAKjI,MAAM,OAAO;EAEpD,OAAO;CACT;AACF;AAEA,MAAMqL,mBACJ/D,GACA4B,KACAtF,KACApC,YAEAwJ,UAAU1D,GAAG4B,KAAKtF,KAAK;CACrBjF,KAAKiF,IAAIjF;CACTmF,MAAM;CACNG,MAAM;CACNzC;AACF,CAAC;AAEH,MAAM8J,YACJhE,GACA4B,KACAjB,MACA7F,cACG;CACH,MAAMwB,MAAiB;EACrBjF,KAAKyD,UAAUzD;EACfC,QAAQwD,UAAUxD;EAClBC,SAAS;EACTC,aAAa;EACbC,SAAS;CACX;CACAmK,IAAI1J,SAAS2K,IAAI/H,UAAUzD,KAAKiF,GAAG;CACnCyG,oBAAoB/C,CAAC;CACrB,IACElF,UAAUR,aAAa0F,EAAE1F,SAASP,QAClC,CAAC4G,KAAKtI,UAAUkK,UAAUpF,MAAMqF,MAAMA,EAAEzI,SAASe,UAAUR,QAAQ,GACnE;EACAoJ,UAAU1D,GAAG4B,KAAKtF,KAAK;GACrBjF,KAAKiF,IAAIjF;GACTmF,MAAM;GACNG,MAAM;GACNzC,SAAS;EACX,CAAC;EACD;CACF;CACA,IAAI,CAACvE,MAAMC,QAAQkF,UAAUP,MAAM,GAAG;EACpCwJ,gBAAgB/D,GAAG4B,KAAKtF,KAAK,yBAAyB;EACtD;CACF;CACA,IAAI/B,SAASO,UAAUP;CACvB,IAAIO,UAAU5D,SAASuE,KAAAA,GACrB,IAAI;EACFlB,SAASrG,oBAAYqG,QAAQO,UAAU5D,MAAM,EAC3C+M,eAAe,KACjB,CAAC;CACH,SAAShK,OAAO;EACd8J,gBACE/D,GACA4B,KACAtF,KACA,mBAAoBrC,MAAgBC,SACtC;EACA;CACF;CAEF,IAAIY,UAAUxD,WAAW,sBAAsB;EAC7C,IAAIiD,OAAO1E,SAAS,GAAG;GACrBkO,gBAAgB/D,GAAG4B,KAAKtF,KAAK,oCAAoC;GACjE;EACF;EACA,MAAM4H,QAAQ,CACZ,GAAIlE,EAAEd,cAAciF,UAAU,KAAK,CAAA,GACnC,oBAAoB,CACrB,CAAC3I,KAAK;EACPkI,UAAU1D,GAAG4B,KAAKtF,KAAK;GAAEjF,KAAKiF,IAAIjF;GAAKmF,MAAM;GAAUJ,SAAS8H;EAAM,CAAC;EACvE;CACF;CACAlE,EAAEd,aAAcsB,OAAQ;EACtBlJ,QAAQwD,UAAUxD;EAClBiD;EACAhC,UAAUqJ,IAAIjK;EACdyM,QAAQR,SAAS5D,GAAG4B,KAAKjB,IAAI;EAC7B0D,iBAAiB;GACf,IAAI/H,IAAI7E,WAAW6E,IAAI/E,SAAS;GAChC+E,IAAI/E,UAAU;GACdqK,IAAIhK,UAAUyL,KAAKC,IAAI1B,IAAIhK,SAAS0E,IAAIjF,GAAG;GAC3C0L,oBAAoB/C,CAAC;GACrBD,cAAcC,CAAC;EACjB;EACAsE,WAAW/H,YAAYoH,WAAW3D,GAAG4B,KAAKtF,KAAKC,OAAO;CACxD,CAAC,CAAC,CAACgI,OAAOtK,UAAmB;EAC3B,IAAI,CAACqC,IAAI7E,SAASkM,WAAW3D,GAAG4B,KAAKtF,KAAK;GAAEE,MAAM;GAAYvC;EAAM,CAAC;CACvE,CAAC;AACH;AAeA,MAAa0K,cACX3E,GACAW,MACAtF,UACmB;CACnB,MAAMuG,MAAM5B,EAAE9B,QAAQkE,IAAIzB,KAAKpI,QAAQ;CACvCqJ,IAAI/J,UAAUpC,KAAKyL,IAAI;CACvB,MAAM0D,UAAU3B,gBAAgBrB,GAAG;CACnC,KAAK,MAAM9G,aAAaO,MAAMpD,KAC5B,IAAI6C,UAAUzD,OAAOuN,SAASpB,OAAOxD,GAAG4B,KAAK9G,UAAUzD,GAAG;CAE5D,MAAMwN,SAASxJ,MAAMZ,IAAIc,QAAQuJ,MAAMA,EAAEzN,MAAMsJ,KAAK5H,MAAM;CAC1D,MAAMgM,SAAS1J,MAAMpD,IAAIsD,QAAQuJ,MAAMA,EAAEzN,MAAMuN,OAAO;CACtD,IACGC,OAAOhP,SAAS,KAAKgP,OAAO,EAAE,CAAExN,QAAQsJ,KAAK5H,SAAS,KACtDgM,OAAOlP,SAAS,KAAKkP,OAAO,EAAE,CAAE1N,QAAQuN,UAAU,GACnD;EACA7B,oBAAoB/C,CAAC;EACrB,OAAO;GACLxD,MAAM;GACNiI,KAAK,EAAEA,KAAK;IAAEpN,KAAKuN;IAAS7L,QAAQ4H,KAAK5H;GAAO,EAAE;EACpD;CACF;CACA,IAAIgM,OAAOlP,SAAS,GAAG;EACrB,IAAImP,kBAAkB;EACtB,KAAK,MAAMC,UAAUjF,EAAE9B,QAAQhB,OAAO,GACpC8H,mBAAmBC,OAAO/M,SAAS4I;EAErC,IACEc,IAAI1J,SAAS4I,OAAOiE,OAAOlP,SAAAA,OAC3BmP,kBAAkBD,OAAOlP,SAASmK,EAAErC,qBAEpC,OAAO;GACLnB,MAAM;GACNiI,KAAK,EACHA,KAAK;IACHpN,KAAKuN;IACL7L,QAAQ4H,KAAK5H;IACb2L,OAAOvQ;GACT,EACF;EACF;CAEJ;CACA,KAAK0Q,OAAOhP,UAAUkP,OAAOlP,WAAWmK,EAAEjC,UAAU;EAClD,MAAM2G,QAAQ1E,EAAEjC,SAAS;EACzB,IAAI2G,UAAU,MAAM;GAClB,IAAI,CAAC3J,OAAOmK,cAAcR,KAAK,KAAKA,QAAQ,GAC1C,MAAM,IAAIS,UACR,yDACF;GACF,OAAO;IACL3I,MAAM;IACNiI,KAAK,EAAEA,KAAK;KAAEpN,KAAKuN;KAAS7L,QAAQ4H,KAAK5H;KAAQ2L;IAAM,EAAE;GAC3D;EACF;CACF;CACA,IAAIzL,mBAAmB0H,KAAK1H;CAC5B,IAAI;EACF,KAAK,MAAM6B,aAAa+J,QACtB5L,mBAAmBhG,iBACjBgG,kBACA6B,UAAUV,KACVuG,KAAKtI,UAAUkK,WACf,IACF;EACF,IACErH,aAAaS,OAAOC,KAAKC,UAAU,CAAC,GAAG5C,iBAAiBmM,SAAS,CAAC,CAAC,CAAC,CACjEtJ,aAAAA,OAEH,OAAOnC,UAAU,mBAAmB;CACxC,QAAQ;EACN,OAAOA,UAAU,iBAAiB;CACpC;CACAgH,KAAK1H,mBAAmBA;CACxB0H,KAAK3H,UAAW9F,aAAa+F,kBAAkB+G,EAAE1F,SAASP,IAAI,CAAC,EAAE9C,SAC/D;CACF,IAAI4N,OAAOhP,QAAQ8K,KAAK5H,SAAS8L,OAAOQ,GAAG,EAAE,CAAC,CAAEhO;CAChD,KAAK,MAAMyD,aAAaiK,QAAQf,SAAShE,GAAG4B,KAAKjB,MAAM7F,SAAS;CAChE,IAAIiK,OAAOlP,SAAS,GAElBiN,SAAS9C,GAAG4B,IAAIjK,IAAI;EAAEN,KAAK0N,OAAOM,GAAG,EAAE,CAAC,CAAEhO;EAAKsL,KAAK;CAAK,CAAC;CAE5DI,oBAAoB/C,CAAC;CACrBD,cAAcC,CAAC;CACf,OAAO,EAAExD,MAAM,KAAK;AACtB;AAEA,MAAMtC,WAAW8F,GAAoBW,MAAYM,SAAiB;CAChE,IAAI,CAACN,KAAKjI,QAAQsH,EAAEpB,YAAYoB,EAAEtB,aAAa,MAAM;CACrD,IAAIxC,iBAAiB+E,IAAI,GAAG;EAC1BD,OACEhB,GACAW,MACA/E,KAAKC,UAAU,EACb8D,KAAK;GACH/F,QAAQ;GACRM,SAAS;EACX,EACF,CAAC,CACH;EACAwG,UAAUV,GAAGW,MAAM,MAAM,iBAAiB;EAC1C;CACF;CACA,MAAM2E,QAAQ,CAAC3E,KAAKhI;CACpBgI,KAAKhI,WAAW;CAChB,IAAI0C;CACJ,IAAI;EACFA,QAAQiK,QAAQzI,kBAAkBoE,IAAI,CAAC,CAAC5F,QAAQU,WAAWkF,IAAI;CACjE,SAAShH,OAAO;EACd,MAAML,SAASI,gBAAgBC,KAAK;EACpC,IAAIL,WAAW,MAAM,MAAMK;EAC3B+G,OACEhB,GACAW,MACA/E,KAAKC,UAAU,EACb8D,KAAK;GACH/F,QAAQ;GACRM,SAASN;EACX,EACF,CAAC,CACH;EACA8G,UAAUV,GAAGW,MAAM,MAAM/G,MAAM;EAC/B;CACF;CACA,IAAIyB,MAAMZ,IAAI5E,WAAW,KAAKwF,MAAMpD,IAAIpC,WAAW,GAAG;CACtD,IAAI0P;CACJ,IAAI;EACFA,YAAYZ,WAAW3E,GAAGW,MAAMtF,KAAK;CACvC,SAASpB,OAAO;EACd,MAAML,SAASI,gBAAgBC,KAAK;EACpC,IAAIL,WAAW,MAAM,MAAMK;EAC3B+G,OACEhB,GACAW,MACA/E,KAAKC,UAAU,EAAE8D,KAAK;GAAE/F,QAAQ;GAAkBM,SAASN;EAAO,EAAE,CAAC,CACvE;EACA8G,UAAUV,GAAGW,MAAM,MAAM/G,MAAM;EAC/B;CACF;CACA,IAAI2L,UAAU/I,SAAS,WACrBwE,OAAOhB,GAAGW,MAAM/E,KAAKC,UAAU0J,UAAUd,GAAG,CAAC;AAEjD;AAEA,MAAMe,gBACJxF,GACAyF,SACA9I,MACA/C,WACG;CACH,IAAI,CAAC6L,QAAQ/M,MAAM;CACnB+M,QAAQ/M,OAAO;CACfsH,EAAE3B,aAAauC,OAAO6E,OAAO;CAC7B,IAAIA,QAAQnM,UAAU,MAAMoM,aAAaD,QAAQnM,KAAK;CACtD,IAAI;EACFmM,QAAQjN,OAAOqI,MAAMlE,MAAM/C,MAAM;CACnC,QAAQ,CACN;AAEJ;AAEA,MAAM+L,eAAeF,SAAsBxE,SAA0B;CACnE,IAAI,CAACwE,QAAQ/M,MAAM,OAAO;CAC1B,IAAI;EACF+M,QAAQjN,OAAO2I,KAAKF,IAAI;EACxB,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;AAEA,MAAM2E,yBAAyBpN,WAA+C;CAC5E,IAAI;EACFA,OAAO2I,KACLvF,KAAKC,UAAU,EACb8D,KAAK;GACH/F,QAAQ;GACR+C,MAAM;GACNzC,SAAStD;EACX,EACF,CAAC,CACH;CACF,QAAQ,CACN;CAEF,IAAI;EACF4B,OAAOqI,MAAM,MAAMjK,wBAAwB;CAC7C,QAAQ,CACN;CAEF,OAAO;AACT;AAEA,MAAMiP,8BACJ7F,GACAyF,SACAxL,UACG;CACH,MAAM6L,WAAW7L,iBAAiB+C,WAAW/C,QAAQ;CACrD,MAAM8L,eAAeD,UAAU7I,WAAW,OAAO6I,UAAU7I,WAAW;CACtE,MAAMA,SAAS6I,UAAU7I;CACzB,MAAM/C,UAAU6L,eACZ,iBACAD,UAAUE,eACT/I,WAAWxB,KAAAA,IAAY,yBAAyB,QAAQwB;CAC7D0I,YACEF,SACA7J,KAAKC,UAAU,EACb8D,KAAK;EACH/F,QACEqD,WAAW,MACP,cACA8I,eACE,iBACA;EACR7L;EACA,GAAI+C,WAAWxB,KAAAA,KAAa,EAAEwB,OAAO;CACvC,EACF,CAAC,CACH;CACAuI,aAAaxF,GAAGyF,SAASM,eAAe,OAAO,MAAM7L,OAAO;AAC9D;AAEA,MAAM+L,qBACJnJ,YAC2B;CAC3B,MAAMoJ,uBAAO,IAAI9H,IAAY;CAC7B,KAAK,MAAMrE,QAAQxE,OAAOa,KAAK0G,OAAO,GAAG;EACvC,MAAMxG,MAAMyD,KAAKoM,YAAY;EAC7B,IAAID,KAAKE,IAAI9P,GAAG,GAAG,MAAM,IAAI6O,UAAU,uBAAuB;EAC9De,KAAKG,IAAI/P,GAAG;CACd;CACA,OAAOf,OAAO+Q,YAAY,IAAIC,QAAQzJ,OAAO,CAAC;AAChD;AAEA,MAAM0J,qBACJxG,GACAzH,UACAC,QACAgH,YACkD;CAClD,MAAMxB,YAAYgC,EAAEhC;CACpB,IAAIwB,QAAQiH,eAAe,MASzB,OARqBE,SACnB3G,GACAzH,UACAC,QACAgH,QAAQiH,eAAe,MACvBjH,QAAQ1G,MACR0G,QAAQnH,SAEHqO,CAAY,EAAEjN,cAAc;CAErC,MAAMmN,UAAUjK,MAAc/C,WAAmB;EAC/C,IAAI;GACFpB,OAAOqI,MAAMlE,MAAM/C,MAAM;EAC3B,QAAQ,CACN;EAEF,OAAO;CACT;CACA,IAAIoG,EAAEpB,UAAU,OAAOgI,OAAO,MAAM,UAAU;CAC9C,IAAI,CAAC1R,aAAa2R,KAAKtO,QAAQ,GAAG,OAAOqO,OAAO,MAAM,mBAAmB;CACzE/E,MAAM7B,CAAC;CACP,IAAIA,EAAEtB,aAAa,MAAM;EACvB,IAAI;GACFlG,OAAO2I,KAAKvF,KAAKC,UAAU,EAAE8D,KAAKK,EAAEtB,SAAS,CAAC,CAAC;EACjD,QAAQ,CACN;EAEF,OAAOkI,OAAO,KAAM,UAAU;CAChC;CACA,MAAMnB,UAAuB;EAC3BjN;EACAE,MAAM;EACNU,aAAa;EACbC,QAAQ,CAAA;EACRC,OAAO;EACPG,YAAY;CACd;CACAuG,EAAE3B,aAAagI,IAAIZ,OAAO;CAC1BA,QAAQnM,QAAQE,iBAEZqM,2BACE7F,GACAyF,SACA,IAAIzI,SAAS,MAAM,EAAEC,QAAQ,IAAI,CAAC,CACpC,GACF+C,EAAEvC,eACJ;CACA,QAASnE,MAA4CgI,QAAQ;CAC7D,OAAO;EACL/I;EACA2B,UAAU+G,SAAS;GACjB,IAAIwE,QAAQhM,eAAe,MAAM;IAC/BgM,QAAQhM,WAAWS,QAAQ+G,IAAI;IAC/B;GACF;GACA,IAAI,CAACwE,QAAQ/M,QAAQsH,EAAEpB,YAAYoB,EAAEtB,aAAa,MAAM;GACxD,IAAIxC,iBAAiB+E,IAAI,GAAG;IAC1B0E,YACEF,SACA7J,KAAKC,UAAU,EACb8D,KAAK;KACH/F,QAAQ;KACRM,SAAS;IACX,EACF,CAAC,CACH;IACAsL,aAAaxF,GAAGyF,SAAS,MAAM,iBAAiB;IAChD;GACF;GACA,IAAIA,QAAQrM,aAAa;IACvBqM,QAAQpM,OAAO4B,KAAKgG,IAAI;IACxB;GACF;GACA,IAAI6F;GACJ,IAAI;IACFA,UAAUjK,kBAAkBoE,IAAI;GAClC,SAAShH,OAAO;IACd,IAAIA,iBAAiB+C,UAAU;KAC7B6I,2BAA2B7F,GAAGyF,SAASxL,KAAK;KAC5C;IACF;IACA,MAAML,SAASI,gBAAgBC,KAAK;IACpC,IAAIL,WAAW,MAAM,MAAMK;IAC3B0L,YACEF,SACA7J,KAAKC,UAAU,EACb8D,KAAK;KACH/F,QAAQ;KACRM,SAASN;IACX,EACF,CAAC,CACH;IACA4L,aAAaxF,GAAGyF,SAAS,MAAM7L,MAAM;IACrC;GACF;GACA,MAAMyB,QAAQyL,QAAQzL;GACtB,IAAIyB;GACJ,IAAI;IACFA,UAAU;KACR,GAAGmJ,kBAAkBa,QAAQhK,OAAO;KACpC,GAAGmJ,kBAAkBzG,QAAQ1C,WAAW,CAAC,CAAC;IAC5C;GACF,QAAQ;IACN6I,YACEF,SACA7J,KAAKC,UAAU,EACb8D,KAAK;KACH/F,QAAQ;KACRM,SAAS;IACX,EACF,CAAC,CACH;IACAsL,aAAaxF,GAAGyF,SAAS,MAAM,mBAAmB;IAClD;GACF;GACA,IAAIrE,kBAAkBpB,CAAC,GAAG;IACxB2F,YACEF,SACA7J,KAAKC,UAAU,EACb8D,KAAK;KACH/F,QAAQ;KACR+C,MAAM;KACNzC,SAAStD;IACX,EACF,CAAC,CACH;IACA4O,aAAaxF,GAAGyF,SAAS,MAAM7O,wBAAwB;IACvD;GACF;GACA6O,QAAQrM,cAAc;GACtB0G,QAAQiH,QAAQ,CAAC,CACdC,WAAWhJ,YAAY,EAAElB,QAAQ,CAAC,CAAC,CAAC,CACpCkK,MAAMlO,SAAS;IACd,IAAI,CAAC2M,QAAQ/M,QAAQsH,EAAEpB,YAAYoB,EAAEtB,aAAa,MAAM;IACxD,MAAMrG,YAAYtF,mBAChB,IAAIwT,QAAQzJ,OAAO,GACnBkD,EAAE1C,aACF,CAAC0C,EAAE1F,QAAQ,CACb;IACA,IAAI,SAASjC,WAAW;KACtBsN,YAAYF,SAAS7J,KAAKC,UAAUxD,SAAS,CAAC;KAC9CmN,aAAaxF,GAAGyF,SAAS,MAAMpN,UAAUsH,IAAIzF,OAAO;KACpD;IACF;IACAsF,QAAQyH,eAAenO,MAAMT,SAAS;IACtCoN,QAAQ/M,OAAO;IACfsH,EAAE3B,aAAauC,OAAO6E,OAAO;IAC7B,IAAIA,QAAQnM,UAAU,MAAMoM,aAAaD,QAAQnM,KAAK;IACtD,MAAMoN,eAAeC,SACnB3G,GACAzH,UACAC,QACA,MACAM,MACAT,SACF;IACA,IAAIqO,iBAAiB,MAAM;IAC3BjB,QAAQhM,aAAaiN,aAAajN;IAClC,IAAI4B,MAAMZ,IAAI5E,UAAUwF,MAAMpD,IAAIpC,QAChCqE,QACE8F,GACA0G,aAAa/F,MACb/E,KAAKC,UAAU;KACb,GAAIR,MAAMZ,IAAI5E,SAAS,EAAE4E,KAAKY,MAAMZ,IAAI,IAAI,CAAC;KAC7C,GAAIY,MAAMpD,IAAIpC,SAAS,EAAEoC,KAAKoD,MAAMpD,IAAI,IAAI,CAAC;IAC/C,CAAC,CACH;IAEF,KAAK,MAAMgJ,QAAQwE,QAAQpM,OAAO6N,OAAO,CAAC,GACxCR,aAAajN,WAAWS,QAAQ+G,IAAI;GACxC,CAAC,CAAC,CACDsD,OAAOtK,UAAmB;IACzB,IAAIwL,QAAQ/M,MAAMmN,2BAA2B7F,GAAGyF,SAASxL,KAAK;GAChE,CAAC;EACL;EACA4G,aAAa;GACX,IAAI4E,QAAQhM,eAAe,MAAMgM,QAAQhM,WAAWoH,MAAM;QACrD2E,aAAaxF,GAAGyF,OAAO;EAC9B;CACF;AACF;AAEA,MAAM0B,aAAanH,MAAuB;CACxC,IAAIoH,SAASpH,EAAE9B,QAAQ4C,OAAOd,EAAEnC;CAChC,IAAIuJ,UAAU,GAAG;CACjB,IAAIC,UAAU;CACd,MAAMC,OAAO,IAAIlJ,IAAI,CAAC,GAAG4B,EAAE7B,KAAK,CAAC,CAACkE,KAAK1B,SAASA,KAAKpI,QAAQ,CAAC;CAC9D,MAAMgP,SAAS,CAAC,GAAGvH,EAAE9B,QAAQhB,OAAO,CAAC,CAAC,CAAC1B,MAAMnG,GAAGC,MAAMD,EAAEwC,UAAUvC,EAAEuC,OAAO;CAC3E,KAAK,MAAM+J,OAAO2F,QAAQ;EACxB,IAAIH,UAAU,GAAG;EACjB,IAAIE,KAAKlB,IAAIxE,IAAIjK,EAAE,KAAKiK,IAAI1J,SAAS4I,OAAO,GAAG;EAC/Cd,EAAE9B,QAAQ0C,OAAOgB,IAAIjK,EAAE;EACvB0P,UAAU;EACVD,UAAU;CACZ;CACA,IAAIC,SAAStE,oBAAoB/C,CAAC;AACpC;AAOA,MAAa2G,YACX3G,GACAzH,UACAC,QACAG,WAAW,OACXG,OAAgB2C,KAAAA,GAChBpD,YAAyC;CACvCoP,SAASzH,EAAE1C,YAAYmK;CACvBlF,WAAW,CAAC;EAAExI,MAAMiG,EAAE1F,SAASP;EAAM0N,SAASzH,EAAE1F,SAASmN;CAAQ,CAAC;AACpE,MACwB;CACxB,MAAMb,UAAUjK,MAAc/C,WAAmB;EAC/C,IAAI;GACFpB,OAAOqI,MAAMlE,MAAM/C,MAAM;EAC3B,QAAQ,CACN;EAEF,OAAO;CACT;CACA,IAAIoG,EAAEpB,UAAU,OAAOgI,OAAO,MAAM,UAAU;CAC9C,IAAI,CAAC1R,aAAa2R,KAAKtO,QAAQ,GAAG,OAAOqO,OAAO,MAAM,mBAAmB;CACzE/E,MAAM7B,CAAC;CACP,IAAIA,EAAEtB,aAAa,MAAM;EACvB,IAAI;GACFlG,OAAO2I,KAAKvF,KAAKC,UAAU,EAAE8D,KAAKK,EAAEtB,SAAS,CAAC,CAAC;EACjD,QAAQ,CACN;EAEFkI,OAAO,KAAM,UAAU;EACvB,OAAO;CACT;CACA,IAAIxF,kBAAkBpB,CAAC,GACrB,OAAO4F,sBAAsBpN,MAAM;CAErC,MAAMkP,QAAQ1H,EAAE9B,QAAQkE,IAAI7J,QAAQ;CACpC,IAAImP,UAAUjM,KAAAA,KAAa,CAACrG,WAAWsS,MAAMvP,WAAWW,IAAI,GAAG;EAC7D,IAAI;GACFN,OAAO2I,KACLvF,KAAKC,UAAU,EACb8D,KAAK;IACH/F,QAAQ;IACRM,SAAS/E;IACT8H,QAAQ;GACV,EACF,CAAC,CACH;EACF,QAAQ,CACN;EAEF,OAAO2J,OAAO,MAAMzR,0BAA0B;CAChD;CACA,MAAMyM,MACJ8F,gBACO;EACL,MAAMC,UAAqB;GACzBhQ,IAAIY;GACJX,SAAS;GACTC,SAASpC,KAAKyL,IAAI;GAClBpJ,yBAAS,IAAIC,IAAI;GACjBG,0BAAU,IAAIH,IAAI;GAClBI,WAAWW;EACb;EACAkH,EAAE9B,QAAQ2E,IAAItK,UAAUoP,OAAO;EAC/B,OAAOA;CACT,EAAA,CAAG;CACL/F,IAAI/J,UAAUpC,KAAKyL,IAAI;CACvB,MAAMP,OAAa;EACjBtI;EACAE;EACAC;EACAE,MAAM;EACNC;EACAC,YAAY;EACZC,OAAO;EACPC;EACAC,QAAQ;EACRC,SAAS;EACTC,kBAAkB;GAAE2O,MAAM;GAAWxC,2BAAW,IAAIrN,IAAI;EAAE;CAC5D;CACAiI,EAAE7B,MAAMkI,IAAI1F,IAAI;CAChBwG,UAAUnH,CAAC;CACX+C,oBAAoB/C,CAAC;CACrBqB,gBAAgBrB,CAAC;CACjB,MAAM,EAAE/I,OAAOC,SAAStE,eAAeoN,EAAEhB,UAAW6I,SAAS,CAAC;CAC9D,MAAMC,QAA2B;EAC/B1N,KAAK,CACH;GACErD,IAAI;GACJuD,UAAU0F,EAAE1F,SAASP;GACrBgO,MAAM;GACN9Q;GACA,GAAIC,SAASuE,KAAAA,KAAa,EAAEvE,KAAK;EACnC,CAAC;EAEHuN,KAAK;GACH,GAAGpM;GACHhB,KAAK4L,gBAAgBrB,GAAG;GACxB7I,QAAQ;GACR,GAAIiH,EAAEvB,YAAY,EAAEgE,MAAM,KAAK;EACjC;CACF;CACA,IAAI,CAACpK,UAAUkK,UAAUpF,MAAMqF,MAAMA,EAAEzI,SAASiG,EAAE1F,SAASP,IAAI,GAC7D+N,MAAM1N,MAAM,CAAA;CACd4G,OAAOhB,GAAGW,MAAM/E,KAAKC,UAAUiM,KAAK,CAAC;CAMrC,OAAO;EAAEnH;EAAMlH,YAAAA;GAJblB;GACA2B,UAAU+G,SAAS/G,QAAQ8F,GAAGW,MAAMM,IAAI;GACxCJ,aAAaH,UAAUV,GAAGW,IAAI;EAEjBlH;CAAW;AAC5B;AAEA,MAAM8F,WACJS,GACAzH,UACAC,QACAgH,UAAsD,CAAC,MACL;CAClD,OAAOgH,kBAAkBxG,GAAGzH,UAAUC,QAAQgH,OAAO;AACvD;AAEA,MAAME,UAAUM,GAAoBL,QAA2B;CAC7D,IACEA,IAAI+E,UAAUjJ,KAAAA,MACb,CAACV,OAAOmK,cAAcvF,IAAI+E,KAAK,KAAK/E,IAAI+E,QAAQ,IAEjD,MAAM,IAAI5K,MAAM,qDAAqD;CAEvE,IAAIkG,EAAEtB,aAAa,QAAQsB,EAAEpB,UAAU;CACvCoB,EAAEd,cAAc8I,QAAQ;CACxBhI,EAAEtB,WAAWiB;CACb,KAAK,MAAM8F,WAAW,CAAC,GAAGzF,EAAE3B,YAAY,GAAG;EACzCsH,YAAYF,SAAS7J,KAAKC,UAAU,EAAE8D,IAAI,CAAC,CAAC;EAC5C6F,aAAaxF,GAAGyF,SAAS,KAAM9F,IAAI/F,MAAM;CAC3C;CACAiI,MAAM7B,GAAGL,GAAG;AACd;AAEA,MAAMsI,UAAUjI,MAAuB;CACrCA,EAAEpB,WAAW;CACboB,EAAEhB,WAAWyB,SAAS1J,OAAOkJ,SAASD,GAAGjJ,EAAE,CAAC;AAC9C;AAEA,MAAMmR,WAAWlI,MAAuB;CACtCA,EAAEpB,WAAW;CACb,IAAIoB,EAAElB,mBAAmB,MAAM;EAC7BiC,cAAcf,EAAElB,cAAc;EAC9BkB,EAAElB,iBAAiB;CACrB;CACAkB,EAAEhB,WAAWyB,QAAQ,IAAI;AAC3B;AAEA,MAAM0H,wBACJC,UAAyD,CAAA,MAEzD,IAAIrQ,IACFqQ,QAAQ/F,KAAKiG,WAAW,CACtBA,OAAO3Q,IACP;CACEA,IAAI2Q,OAAO3Q;CACXC,SAAS0Q,OAAO1Q;CAChBC,SAASyQ,OAAOzQ;CAChBC,SAAS,IAAIC,IACXuQ,OAAOxQ,QAAQuK,KAAK,EAAEhL,KAAKW,IAAIC,UAAU,CAACZ,KAAK;EAAEW;EAAIC;CAAI,CAAC,CAAC,CAC7D;CACAC,0BAAU,IAAIH,IAAI;CAClBI,WAAWmQ,OAAOnQ;AACpB,CAAC,CACF,CACH;AAEF,MAAMoQ,iBACJC,WACAhJ,SACAJ,gBAIG;CACH,MAAM,CAACY,KAAK3M,eAAgC;EAC1C,MAAMsV,OAAwB;GAC5BrO,UAAU;IAAEP,MAAMlH;IAAkB4U,SAAS3U;GAAa;GAC1DwK,aAAa,EAAEmK,SAAS3U,aAAa;GACrC0K,aAAa;GACbC,iBAAiB;GACjBC,gBAAgB/G;GAChBgH,qBAAqBnJ;GACrBoJ,iBAAiB/G;GACjBgH,mBAAmBnH;GACnBoH,WAAW;GACXC,UAAUtC,KAAAA;GACVuC,WAAWvC,KAAAA;GACXyC,SAASiK,qBAAqB/I,aAAawJ,aAAa;GACxDzK,uBAAO,IAAIC,IAAI;GACfC,8BAAc,IAAID,IAAI;GACtBE,YAAY,CAAA;GACZC,gCAAgB,IAAIxG,IAAI;GACxByG,6BAAa,IAAIzG,IAAI;GACrB0G,UAAU;GACVC,UAAU;GACVE,UAAU;GACVC,gBAAgB;GAChBC,gBAAgB;GAChBE,WAAW;GACXE,cAAc;GACdC,SAAS;GACTC;GACAE,MAAM7K,4BAA4B;IAChCkU,KAAK9J,iBAAiB;IACtBgD,MAAM8G,IAAI;GACZ,CAAC;GACDpJ,UAAUhH,UAAUC,QAAQqQ,mBAC1BtJ,QAAQoJ,MAAMpQ,UAAUC,QAAQqQ,cAAc;GAChDnJ,SAASC,QAAQD,OAAOiJ,MAAMhJ,GAAG;GACjC3K,SAAS4K,YAAY3K,OAAY0T,MAAM/I,OAAO;GAC9C9K,SAAS8K,cAAY7K,OAAY4T,MAAM/I,SAAO;EAChD;EACA,OAAO+I;CACT,CAAC;CACD3I,EAAE1F,WAAWkF,SAASlF,YAAY;EAChCP,MAAAA;EACA0N,SAAAA;CACF;CACAzH,EAAE1C,cAAckC,SAASlC,eAAe,EAAEmK,SAAAA,aAAsB;CAChElG,eAAevB,GAAGR,SAASsJ,uBAAuB,IAAM;CACxD9I,EAAEjC,WAAWyB,SAASzB;CACtBiC,EAAEvC,kBAAkB+B,SAAS/B,mBAAmB;CAChD,MAAMC,iBACJ8B,SAAS9B,mBAAmBjC,KAAAA,IACxB9E,kBACA6I,QAAQ9B;CACd,IAAI,CAAC3C,OAAOC,UAAU0C,cAAc,KAAKA,iBAAiB,GACxD,MAAM,IAAIyH,UAAU,2CAA2C;CAEjEnF,EAAEtC,iBAAiBA;CACnB,MAAMC,sBACJ6B,SAAS7B,wBAAwBlC,KAAAA,IAC7BjH,iCACAgL,QAAQ7B;CACd,IAAI,CAAC5C,OAAOC,UAAU2C,mBAAmB,KAAKA,sBAAsB,GAClE,MAAM,IAAIwH,UAAU,gDAAgD;CAEtEnF,EAAErC,sBAAsBA;CACxB,MAAMC,kBACJ4B,SAAS5B,oBAAoBnC,KAAAA,IACzB5E,oBACA2I,QAAQ5B;CACd,IAAI,CAAC7C,OAAOC,UAAU4C,eAAe,KAAKA,kBAAkB,GAC1D,MAAM,IAAIuH,UAAU,4CAA4C;CAElEnF,EAAEpC,kBAAkBA;CACpBoC,EAAEnC,oBAAoB2B,SAAS3B,qBAAqBnH;CACpDsJ,EAAElC,YAAY0B,SAAS1B,aAAa;CACpCkC,EAAEhC,YAAYwB,SAASxB;CACvB,MAAM/G,QAAQzD,YAAYgV,SAAS;CACnCtI,OAAOF,GAAG/I,KAAK;CACf7D,gBAAgB;EACd8M,OAAOF,GAAG/I,KAAK;EACf8I,cAAcC,CAAC;CACjB,CAAC;CACD5M,gBAAgB;EACd6U,OAAOjI,CAAC;EACR,aAAakI,QAAQlI,CAAC;CACxB,GAAG,CAACA,CAAC,CAAC;CACN,OAAOA;AACT;;;;;;;;;AAUA,MAAa+I,uBACXP,WACAhJ,SACAJ,gBACqC;CACrC,MAAM4J,uBAAiB;EAAA,OAAMT,cAAcC,WAAWhJ,SAASJ,WAAW;CAAC;CAC3E,MAAM6J,OAAO3V,cAAc0V,cAAc;CACzC,IAAIpK,WAAW;CACf,OAAO;EACLW,UAAUhH,UAAUC,QAAQqQ,mBAC1BtV,mBACE0V,KAAKC,SAAS,CAAC,CAAC3J,QAAQhH,UAAUC,QAAQqQ,cAAc,CAC1D;EACF7T,SAAS4K,YAAYrM,mBAAmB0V,KAAKC,SAAS,CAAC,CAAClU,OAAO4K,OAAO,CAAC;EACvE9K,SAAS8K,YAAYrM,mBAAmB0V,KAAKC,SAAS,CAAC,CAACpU,OAAO8K,OAAO,CAAC;EACvEF,SAASC,QAAQpM,mBAAmB0V,KAAKC,SAAS,CAAC,CAACxJ,OAAOC,GAAG,CAAC;EAC/DwJ,eAAe;GACb,IAAIvK,UAAU;GACdA,WAAW;GACXrL,mBACE0V,KAAKC,SAAS,CAAC,CAACxJ,OAAO;IAAE9F,QAAQ;IAAa+C,MAAM;GAAU,CAAC,CACjE;GACAsM,KAAKG,QAAQ;EACf;CACF;AACF"}
@@ -1,4 +1,3 @@
1
- import { StatewireDocuments } from "./wire/documents.js";
2
1
  import { StatewireProtocol } from "./wire/protocol.js";
3
2
  import { StatewireHost } from "./host.js";
4
3
  import { StatewireCmd } from "./client/connection.js";
@@ -38,10 +37,7 @@ declare namespace StatewireHostInternal {
38
37
  type ClientRecord = {
39
38
  id: string;
40
39
  lastSeq: number;
41
- ctxSeq: number;
42
40
  touched: number;
43
- context: Record<string, unknown> | null;
44
- contextDocuments?: readonly [number, StatewireDocuments.Document][];
45
41
  results: readonly {
46
42
  seq: number;
47
43
  ts: number;
@@ -1 +1 @@
1
- {"version":3,"file":"host-internal.d.ts","names":[],"sources":["../src/host-internal.ts"],"mappings":";;;;;;;;kBAQiB;OACH;IACV,OAAO;IACP,QAAQ,eAAe;;OAGb;aACD;IACT,UAAU;IACV;;OAGU;;IAEV,UAAU;;IAEV;IACA,YAAY,kBAAkB;;IAE9B;;IAEA,gBACE,eACA,WAAW,kBAAkB;;OAIrB;;IAEV,UACE,kBACA,QAAQ,QACR,UAAU,yBACP;IACL,SAAS,SAAS,YAAY,QAAQ;IACtC,SAAS,SAAS,YAAY,QAAQ;IACtC,SAAS,KAAK,cAAc;IAC5B;;OAGU;IACV;IACA;IACA;IACA;IACA,SAAS;IACT,qCAAqC,mBAAmB;IACxD;MAAoB;MAAa;MAAY,KAAK;;IAClD;;OAGU;IACV,yBAAyB;IACzB,yBAAyB,kBAAkB;;OAGjC,kBAAkB;IAC5B,WAAW,kBAAkB;IAC7B,cAAc,kBAAkB;;IAEhC,aAAa;MACX,SAAS;UACL,QAAQ,QAAQ;;IAEtB;IACA;;IAEA;;IAEA;;IAEA;;IAEA;;IAEA;;IAEA;;OAGU,MAAM,cAAc"}
1
+ {"version":3,"file":"host-internal.d.ts","names":[],"sources":["../src/host-internal.ts"],"mappings":";;;;;;;kBAOiB;OACH;IACV,OAAO;IACP,QAAQ,eAAe;;OAGb;aACD;IACT,UAAU;IACV;;OAGU;;IAEV,UAAU;;IAEV;IACA,YAAY,kBAAkB;;IAE9B;;IAEA,gBACE,eACA,WAAW,kBAAkB;;OAIrB;;IAEV,UACE,kBACA,QAAQ,QACR,UAAU,yBACP;IACL,SAAS,SAAS,YAAY,QAAQ;IACtC,SAAS,SAAS,YAAY,QAAQ;IACtC,SAAS,KAAK,cAAc;IAC5B;;OAGU;IACV;IACA;IACA;IACA;MAAoB;MAAa;MAAY,KAAK;;IAClD;;OAGU;IACV,yBAAyB;IACzB,yBAAyB,kBAAkB;;OAGjC,kBAAkB;IAC5B,WAAW,kBAAkB;IAC7B,cAAc,kBAAkB;;IAEhC,aAAa;MACX,SAAS;UACL,QAAQ,QAAQ;;IAEtB;IACA;;IAEA;;IAEA;;IAEA;;IAEA;;IAEA;;IAEA;;OAGU,MAAM,cAAc"}
package/dist/host.d.ts CHANGED
@@ -38,7 +38,7 @@ declare namespace StatewireHost {
38
38
  * (in-process dispatch has none — reading it throws), `auth` is the value
39
39
  * `authorize` returned for the attach that admitted the command (undefined
40
40
  * for a void `authorize` and for in-process dispatch), `context` reads the
41
- * client's current ambient context live (null until the client sends one),
41
+ * admitting attach's context live (null until that attach sends one),
42
42
  * `isConnected` reports whether the client has an active stream attachment.
43
43
  */
44
44
  type Caller = {
@@ -191,20 +191,10 @@ declare namespace StatewireClient {
191
191
  params: unknown[];
192
192
  meta?: unknown;
193
193
  };
194
- /** The persisted session: the lane identity, the lane clocks, and the commands the server has not marked durable. */
194
+ /** The persisted session: the lane identity, the cmd clock, and the commands the server has not marked durable. */
195
195
  type SessionRecord = {
196
196
  clientId: string;
197
197
  nextSeq: number;
198
- ctxNextSeq: number;
199
- context?: {
200
- ops: unknown[];
201
- pending: {
202
- seq: number;
203
- ops: unknown[];
204
- }[];
205
- /** Recover the original wire's unpersisted single-document context after the next hello. */
206
- recover?: "version-1";
207
- };
208
198
  commands: readonly SessionCommand[];
209
199
  /** Terminal verdicts parked for the sharer that minted the seq (shared storage only). */
210
200
  verdicts?: readonly SessionVerdict[];
@@ -1 +1 @@
1
- {"version":3,"file":"statewire.d.ts","names":[],"sources":["../src/statewire.ts"],"mappings":"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"}
1
+ {"version":3,"file":"statewire.d.ts","names":[],"sources":["../src/statewire.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"statewire.js","names":["StatewireDocuments","StatewireProtocol","StatewireHost","useMemo","useRef","useState","useSyncExternalStore","createTapRoot","flushTapSync","resource","useContextProvider","useResource","useResources","withKey","ResourceElement","CONNECTED_CONNECTION","useStatewireCore","Statewire","TERMINAL","DocumentStorageContext","ProtocolContext","SessionStorageContext","useSessionTransport","transport","session","documents","protocol","StatewireClient","SessionStorage","Storage","Options","SessionTransport","useStatewire","Commands","options","TState","TCommands","Helpers","latest","current","storage","undefined","wireVersion","applicationProtocols","keyPrefixes","value","core","subscribe","listener","state","getState","isBusy","getBusy","failed","getFailed","connection","failures","NonNullable","Error","selection","invoke","method","params","updateContext","ops","commands","CommandsProxy","setContext","contextValue","Record","retryFailed","entry","FailedCommand","retry","discardFailed","discard","StatewireResource","root","disposed","constructor","ClientRoot","getValue","Connection","Source","Selection","Promise","dispose","unmount","Readonly","Range","Offer","initialState","optimistic","Optimistic","materialize","Materialize","onStateChange","ctx","changes","Changes","onCommandChange","update","CommandUpdate","onConnectionChange","onError","error","ConnectionError","failureCovered","ConnectionState","status","reason","degraded","attempt","cause","code","nextRetryAt","lastError","message","payload","reconnect","ConnectionStatus","draft","command","Command","OptimisticContext","ts","seq","clientId","SendFailure","fate","predecessorLost","OnSessionLost","pending","ReadonlyArray","produced","SessionCommand","meta","failure","wire","protocols","SessionRecord","nextSeq","ctxNextSeq","context","recover","verdicts","SessionVerdict","type","ready","flush","load","save","record","migrate","lock","fn","T","fin","Fin","HeadersOption","HeadersInit","staleAuth","HttpOptions","sessionStore","url","isNew","headers","fetch","globalThis","onSessionLost","onChange","onDone","WebsocketOptions","query","webSocket","WebSocket"],"sources":["../src/statewire.ts"],"sourcesContent":["import type { StatewireDocuments } from \"./wire/documents\";\nimport type { StatewireProtocol } from \"./wire/protocol\";\nimport type { StatewireHost } from \"./host\";\nimport { useMemo, useRef, useState, useSyncExternalStore } from \"react\";\nimport {\n createTapRoot,\n flushTapSync,\n resource,\n useContextProvider,\n useResource,\n useResources,\n withKey,\n} from \"@assistant-ui/tap\";\nimport type { ResourceElement } from \"@assistant-ui/tap\";\nimport { CONNECTED_CONNECTION, useStatewireCore } from \"./client/core\";\nimport type { Statewire } from \"./types\";\nimport type { TERMINAL } from \"./client/connection\";\nimport {\n DocumentStorageContext,\n ProtocolContext,\n SessionStorageContext,\n} from \"./client/sessionStore\";\n\nconst useSessionTransport = ({\n transport,\n session,\n documents,\n protocol,\n}: {\n transport: ResourceElement<Statewire<any, any>>;\n session: StatewireClient.SessionStorage | undefined;\n documents: StatewireDocuments.Storage | undefined;\n protocol: StatewireProtocol.Options;\n}): Statewire<unknown> =>\n useContextProvider(SessionStorageContext, session, () =>\n // oxlint-disable-next-line react-hooks/rules-of-hooks\n useContextProvider(DocumentStorageContext, documents, () =>\n // oxlint-disable-next-line react-hooks/rules-of-hooks\n useContextProvider(ProtocolContext, protocol, () =>\n // oxlint-disable-next-line react-hooks/rules-of-hooks\n useResource(transport),\n ),\n ),\n );\n\n// The transport owns the session; it reads the storage off the context this\n// wrapper's own fiber provides, so plain-React callers get a provider too.\nconst SessionTransport = resource(useSessionTransport);\n\nexport const useStatewire = <\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n>(\n options: StatewireClient.Options<TState, TCommands>,\n): StatewireClient.Helpers<TState, TCommands> => {\n const latest = useRef(options);\n latest.current = options;\n\n const session = useResources(\n options.storage?.session !== undefined\n ? [withKey(\"session\", options.storage.session)]\n : [],\n )[0];\n const documents = useResources(\n options.storage?.documents === undefined\n ? []\n : [withKey(\"documents\", options.storage.documents)],\n )[0];\n const protocol: StatewireProtocol.Options = {\n ...(options.protocol !== undefined && { protocol: options.protocol }),\n ...(options.wireVersion !== undefined && {\n wireVersion: options.wireVersion,\n }),\n ...(options.applicationProtocols !== undefined && {\n applicationProtocols: options.applicationProtocols,\n }),\n ...(options.keyPrefixes !== undefined && {\n keyPrefixes: options.keyPrefixes,\n }),\n };\n const value = useResource(\n SessionTransport({\n transport: options.transport,\n session,\n documents,\n protocol,\n }),\n );\n const core = useStatewireCore(() => latest.current, value);\n const [subscribe] = useState(\n () => (listener: () => void) =>\n core.subscribe(() => flushTapSync(listener)),\n );\n\n const state = useSyncExternalStore(\n subscribe,\n core.getState,\n core.getState,\n ) as TState;\n const isBusy = useSyncExternalStore(subscribe, core.getBusy, core.getBusy);\n const failed = useSyncExternalStore(\n subscribe,\n core.getFailed,\n core.getFailed,\n );\n const connection = value.connection ?? CONNECTED_CONNECTION;\n\n return useMemo(() => {\n const failures = (): NonNullable<typeof value.failures> => {\n if (!value.failures) {\n throw new Error(\"statewire: this transport has no failed-send lane\");\n }\n return value.failures;\n };\n return {\n state,\n documents: value.documents,\n selection: value.selection,\n invoke: (\n protocol: string,\n method: string,\n params: readonly unknown[],\n ) => {\n if (!value.invoke)\n throw new Error(\n \"statewire: transport does not support protocol commands\",\n );\n return value.invoke(protocol, method, params);\n },\n updateContext: (ops: readonly unknown[]) => {\n if (!value.updateContext)\n throw new Error(\n \"statewire: transport does not support context documents\",\n );\n value.updateContext(ops);\n },\n getState: core.getState as () => TState,\n connection,\n commands: core.commands as Statewire.CommandsProxy<TCommands>,\n isBusy,\n setContext: (contextValue: Record<string, unknown>) => {\n if (!value.setContext) {\n throw new Error(\n \"statewire: this transport has no client context channel\",\n );\n }\n value.setContext(contextValue);\n },\n failed,\n retryFailed: (entry: StatewireClient.FailedCommand) =>\n failures().retry(entry),\n discardFailed: (entry: StatewireClient.FailedCommand) =>\n failures().discard(entry),\n };\n }, [state, isBusy, failed, connection, core, value]);\n};\n\nexport const StatewireResource = <\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n>(\n options: StatewireClient.Options<TState, TCommands>,\n): ResourceElement<StatewireClient.Helpers<TState, TCommands>> =>\n resource(useStatewire<TState, TCommands>)(options);\n\nexport class StatewireClient<\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n> {\n private readonly root;\n private disposed = false;\n\n constructor(options: StatewireClient.Options<TState, TCommands>) {\n const ClientRoot = () => useStatewire<TState, TCommands>(options);\n this.root = createTapRoot(ClientRoot);\n }\n\n get state(): TState {\n return this.root.getValue().getState();\n }\n\n get connection(): StatewireClient.Connection {\n return this.root.getValue().connection;\n }\n\n get commands(): Statewire.CommandsProxy<TCommands> {\n return this.root.getValue().commands;\n }\n\n get documents(): StatewireDocuments.Source | undefined {\n return this.root.getValue().documents;\n }\n get selection(): StatewireProtocol.Selection | undefined {\n return this.root.getValue().selection;\n }\n invoke(\n protocol: string,\n method: string,\n params: readonly unknown[],\n ): Promise<unknown> {\n return this.root.getValue().invoke(protocol, method, params);\n }\n updateContext(ops: readonly unknown[]): void {\n this.root.getValue().updateContext(ops);\n }\n\n get isBusy(): boolean {\n return this.root.getValue().isBusy;\n }\n\n setContext(value: Record<string, unknown>): void {\n this.root.getValue().setContext(value);\n }\n\n get failed(): readonly StatewireClient.FailedCommand[] {\n return this.root.getValue().failed;\n }\n\n retryFailed(entry: StatewireClient.FailedCommand): Promise<unknown> {\n return this.root.getValue().retryFailed(entry);\n }\n\n discardFailed(entry: StatewireClient.FailedCommand): void {\n this.root.getValue().discardFailed(entry);\n }\n\n subscribe(listener: () => void): () => void {\n return this.root.subscribe(listener);\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.root.unmount();\n }\n}\n\nexport namespace StatewireClient {\n export type Options<\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n > = {\n protocol?: string;\n keyPrefixes?: Readonly<Record<string, readonly string[]>>;\n wireVersion?: StatewireProtocol.Range;\n applicationProtocols?: readonly StatewireProtocol.Offer[] | \"*\";\n transport: ResourceElement<Statewire<TState, TCommands>>;\n /** Durable session: the mounted storage holds this client's lane identity and its un-durable commands, which resend on the next attach. */\n storage?:\n | {\n session?: ResourceElement<SessionStorage> | undefined;\n documents?: ResourceElement<StatewireDocuments.Storage> | undefined;\n }\n | undefined;\n /** Served as the canonical state until the attach snapshot; own commands fold over it. */\n initialState?: TState;\n optimistic?: Optimistic<NonNullable<TState>, TCommands>;\n materialize?: Materialize<NonNullable<TState>>;\n onStateChange?: (\n state: NonNullable<TState>,\n ctx: { changes: Statewire.Changes },\n ) => void;\n onCommandChange?: (\n update: Statewire.CommandUpdate<TCommands>,\n ctx: { state: NonNullable<TState> },\n ) => void;\n onConnectionChange?: (connection: Connection) => void;\n onError?: (error: ConnectionError) => void;\n /** Drops a retained failed entry once a canonical snapshot shows its effect landed; checked against each new snapshot. */\n failureCovered?: (\n state: NonNullable<TState>,\n entry: FailedCommand,\n ) => boolean;\n };\n\n export type Helpers<\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n > = {\n /** The statewire's state type — remote statewires include `undefined` until the first attach snapshot applies. */\n state: TState;\n documents: StatewireDocuments.Source | undefined;\n selection: StatewireProtocol.Selection | undefined;\n invoke: (\n protocol: string,\n method: string,\n params: readonly unknown[],\n ) => Promise<unknown>;\n updateContext: (ops: readonly unknown[]) => void;\n /** Identity-stable across renders; reads the current canonical state without subscribing the caller. */\n getState: () => TState;\n connection: Connection;\n commands: Statewire.CommandsProxy<TCommands>;\n /** Negation of the server's broadcast idle level (a transport without idle is always busy). */\n isBusy: boolean;\n /** Replace this client's ambient context on the server; throws on transports without a client context channel. */\n setContext: (value: Record<string, unknown>) => void;\n /** Non-accepted sends retained in the session record; reload with it. */\n failed: readonly FailedCommand[];\n /** Re-enqueues the entry's command on fresh clocks and removes the entry. */\n retryFailed: (entry: FailedCommand) => Promise<unknown>;\n /** Removes the entry. */\n discardFailed: (entry: FailedCommand) => void;\n };\n\n /** Connection lifecycle and whether its current state warrants a problem indicator. */\n export type ConnectionState =\n | { status: \"standby\"; reason: \"deferred\" | \"idle\"; degraded: false }\n | { status: \"connecting\"; degraded: false }\n | { status: \"connected\"; degraded: false }\n | {\n status: \"retrying\";\n degraded: true;\n attempt: number;\n /** Backoff details are absent while the retry dial is in flight. */\n cause?: \"dropped\" | \"reconnect\" | \"error\" | \"unauthorized\";\n code?: string;\n nextRetryAt?: number;\n lastError?: string;\n message?: string;\n }\n | {\n status: \"stopped\";\n degraded: true;\n reason:\n | \"gone\"\n | \"forbidden\"\n | \"protocol-error\"\n | \"unauthorized\"\n | \"storage-error\";\n message?: string;\n payload?: unknown;\n };\n export type Connection = ConnectionState & {\n error?: ConnectionError;\n reconnect: () => void;\n };\n export type ConnectionStatus = Connection[\"status\"];\n\n /**\n * Mutate the draft in place; the client records the next state plus the exact\n * changed paths. Re-run against the new base on every rebase.\n */\n export type Optimistic<\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n > = (\n draft: TState,\n command: Statewire.Command<TCommands>,\n ctx: OptimisticContext,\n ) => void;\n\n export type OptimisticContext = {\n ts: number;\n seq: number;\n clientId?: string;\n };\n\n /**\n * Mutate the draft to make server-accepted, still-uncommitted intents in\n * the state concrete (e.g. dispatch records into messages). Runs after the\n * optimistic folds on every published state.\n */\n export type Materialize<TState> = (draft: TState) => void;\n\n /**\n * fate: \"aborted\" = never sent, \"rejected\" = the server refused it\n * (`code` \"unknown-command\" | \"invalid-params\" for the static rejects,\n * code-less for handler rejects), \"lost\" = sent but no verdict will ever\n * arrive — the record is gone (a proven seq gap) or the channel died: it\n * may or may not have run, \"failed\" = the handler ran and threw,\n * \"crashed\" = the handler died involuntarily, \"expired\" = settled —\n * result, rejected, failed, or crashed — but the verdict outlived the\n * server's retention.\n * cause is which channel settled it: \"server\" = the server's answer;\n * the rest are channel deaths the client settled locally.\n */\n export type SendFailure =\n | {\n fate: \"rejected\";\n cause: \"server\";\n code?: string;\n message?: string;\n payload?: unknown;\n }\n | { fate: \"failed\"; cause: \"server\"; message?: string }\n | { fate: \"crashed\"; cause: \"server\" }\n | { fate: \"expired\"; cause: \"server\" }\n | {\n fate: \"aborted\";\n cause: \"unmount\" | \"stream-gone\" | \"session-lost\";\n predecessorLost?: true;\n }\n | {\n fate: \"lost\";\n cause: \"unmount\" | \"stream-gone\" | \"session-lost\";\n };\n\n /** Held commands a proven record gap settled `{fate: \"lost\", cause: \"session-lost\"}`; return \"requeue\" to re-enqueue them on the reset clocks. */\n export type OnSessionLost = (\n pending: ReadonlyArray<{\n method: string;\n params: readonly unknown[];\n ts: number;\n seq: number;\n clientId?: string;\n }>,\n ) => \"requeue\" | \"drop\";\n\n /** A non-accepted send retained for the user: the wire statement, its failure, and its original clocks. */\n export type FailedCommand = {\n readonly protocol: string;\n readonly produced?: SessionCommand[\"produced\"];\n readonly command: string;\n readonly params: readonly unknown[];\n readonly meta?: unknown;\n readonly failure: SendFailure;\n readonly ts: number;\n readonly seq: number;\n };\n\n /** A command as persisted while un-durable: its lane seq plus the wire statement. */\n export type SessionCommand = {\n seq: number;\n protocol: string;\n produced?: {\n wire: StatewireProtocol.Range;\n protocols: readonly StatewireProtocol.Offer[] | \"*\";\n };\n method: string;\n params: unknown[];\n meta?: unknown;\n };\n\n /** The persisted session: the lane identity, the lane clocks, and the commands the server has not marked durable. */\n export type SessionRecord = {\n clientId: string;\n nextSeq: number;\n ctxNextSeq: number;\n context?: {\n ops: unknown[];\n pending: { seq: number; ops: unknown[] }[];\n /** Recover the original wire's unpersisted single-document context after the next hello. */\n recover?: \"version-1\";\n };\n commands: readonly SessionCommand[];\n /** Terminal verdicts parked for the sharer that minted the seq (shared storage only). */\n verdicts?: readonly SessionVerdict[];\n /** Non-accepted sends retained for the user; survive record rebases and resets. */\n failed?: readonly FailedCommand[];\n };\n\n /** A terminal verdict one sharer's connection carried, parked for the sharer awaiting the seq. */\n export type SessionVerdict = {\n seq: number;\n type: (typeof TERMINAL)[number];\n code?: string;\n message?: string;\n payload?: unknown;\n meta?: unknown;\n };\n\n /** Session storage seam with optional asynchronous hydration and persistence. */\n export type SessionStorage = {\n /** Resolves when a synchronous load can return the hydrated record. */\n ready?: Promise<void>;\n /** Resolves after all queued saves are persisted; awaited before sending statements. */\n flush?: () => void | Promise<void>;\n load: () => SessionRecord | null;\n save: (record: SessionRecord) => void;\n /** Upgrade incompatible stored commands; null discards the old record and starts a new client identity. */\n migrate?: (\n record: SessionRecord,\n current: NonNullable<SessionCommand[\"produced\"]>,\n ) => SessionRecord | null;\n /** Serializes record mutations across sharers; presence marks the storage shared. */\n lock?: <T>(fn: () => T | Promise<T>) => Promise<T>;\n /** Notifies of record saves by other sharers; returns unsubscribe. Required alongside `lock`. */\n subscribe?: (listener: () => void) => () => void;\n };\n\n /** Static headers, or a resolver invoked per request/attach; `staleAuth` is true right after an auth rejection. */\n export type ConnectionError = Error & { fin?: StatewireHost.Fin };\n\n export type HeadersOption =\n | HeadersInit\n | ((ctx: { staleAuth: boolean }) => HeadersInit | Promise<HeadersInit>);\n\n export type HttpOptions = StatewireProtocol.Options & {\n sessionStore?: SessionStorage | undefined;\n url: string;\n /** The session does not exist on the server yet: the first attach waits for the first command send (or an explicit `reconnect()`). */\n isNew?: boolean;\n headers?: HeadersOption;\n fetch?: typeof globalThis.fetch;\n onSessionLost?: OnSessionLost;\n onChange?: (connection: Connection) => void;\n onError?: (error: ConnectionError) => void;\n /** The broadcast idle flag's rising edge: the instance went quiet. */\n onDone?: () => void;\n };\n\n export type WebsocketOptions = StatewireProtocol.Options & {\n sessionStore?: SessionStorage | undefined;\n url: string;\n /** The session does not exist on the server yet: the first attach waits for the first command send (or an explicit `reconnect()`). */\n isNew?: boolean;\n headers?: HeadersOption;\n protocols?: string | string[];\n query?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n webSocket?: new (url: string, protocols?: string | string[]) => WebSocket;\n onSessionLost?: OnSessionLost;\n onChange?: (connection: Connection) => void;\n onError?: (error: ConnectionError) => void;\n /** The broadcast idle flag's rising edge: the instance went quiet. */\n onDone?: () => void;\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"statewire.js","names":["StatewireDocuments","StatewireProtocol","StatewireHost","useMemo","useRef","useState","useSyncExternalStore","createTapRoot","flushTapSync","resource","useContextProvider","useResource","useResources","withKey","ResourceElement","CONNECTED_CONNECTION","useStatewireCore","Statewire","TERMINAL","DocumentStorageContext","ProtocolContext","SessionStorageContext","useSessionTransport","transport","session","documents","protocol","StatewireClient","SessionStorage","Storage","Options","SessionTransport","useStatewire","Commands","options","TState","TCommands","Helpers","latest","current","storage","undefined","wireVersion","applicationProtocols","keyPrefixes","value","core","subscribe","listener","state","getState","isBusy","getBusy","failed","getFailed","connection","failures","NonNullable","Error","selection","invoke","method","params","updateContext","ops","commands","CommandsProxy","setContext","contextValue","Record","retryFailed","entry","FailedCommand","retry","discardFailed","discard","StatewireResource","root","disposed","constructor","ClientRoot","getValue","Connection","Source","Selection","Promise","dispose","unmount","Readonly","Range","Offer","initialState","optimistic","Optimistic","materialize","Materialize","onStateChange","ctx","changes","Changes","onCommandChange","update","CommandUpdate","onConnectionChange","onError","error","ConnectionError","failureCovered","ConnectionState","status","reason","degraded","attempt","cause","code","nextRetryAt","lastError","message","payload","reconnect","ConnectionStatus","draft","command","Command","OptimisticContext","ts","seq","clientId","SendFailure","fate","predecessorLost","OnSessionLost","pending","ReadonlyArray","produced","SessionCommand","meta","failure","wire","protocols","SessionRecord","nextSeq","verdicts","SessionVerdict","type","ready","flush","load","save","record","migrate","lock","fn","T","fin","Fin","HeadersOption","HeadersInit","staleAuth","HttpOptions","sessionStore","url","isNew","headers","fetch","globalThis","onSessionLost","onChange","onDone","WebsocketOptions","query","webSocket","WebSocket"],"sources":["../src/statewire.ts"],"sourcesContent":["import type { StatewireDocuments } from \"./wire/documents\";\nimport type { StatewireProtocol } from \"./wire/protocol\";\nimport type { StatewireHost } from \"./host\";\nimport { useMemo, useRef, useState, useSyncExternalStore } from \"react\";\nimport {\n createTapRoot,\n flushTapSync,\n resource,\n useContextProvider,\n useResource,\n useResources,\n withKey,\n} from \"@assistant-ui/tap\";\nimport type { ResourceElement } from \"@assistant-ui/tap\";\nimport { CONNECTED_CONNECTION, useStatewireCore } from \"./client/core\";\nimport type { Statewire } from \"./types\";\nimport type { TERMINAL } from \"./client/connection\";\nimport {\n DocumentStorageContext,\n ProtocolContext,\n SessionStorageContext,\n} from \"./client/sessionStore\";\n\nconst useSessionTransport = ({\n transport,\n session,\n documents,\n protocol,\n}: {\n transport: ResourceElement<Statewire<any, any>>;\n session: StatewireClient.SessionStorage | undefined;\n documents: StatewireDocuments.Storage | undefined;\n protocol: StatewireProtocol.Options;\n}): Statewire<unknown> =>\n useContextProvider(SessionStorageContext, session, () =>\n // oxlint-disable-next-line react-hooks/rules-of-hooks\n useContextProvider(DocumentStorageContext, documents, () =>\n // oxlint-disable-next-line react-hooks/rules-of-hooks\n useContextProvider(ProtocolContext, protocol, () =>\n // oxlint-disable-next-line react-hooks/rules-of-hooks\n useResource(transport),\n ),\n ),\n );\n\n// The transport owns the session; it reads the storage off the context this\n// wrapper's own fiber provides, so plain-React callers get a provider too.\nconst SessionTransport = resource(useSessionTransport);\n\nexport const useStatewire = <\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n>(\n options: StatewireClient.Options<TState, TCommands>,\n): StatewireClient.Helpers<TState, TCommands> => {\n const latest = useRef(options);\n latest.current = options;\n\n const session = useResources(\n options.storage?.session !== undefined\n ? [withKey(\"session\", options.storage.session)]\n : [],\n )[0];\n const documents = useResources(\n options.storage?.documents === undefined\n ? []\n : [withKey(\"documents\", options.storage.documents)],\n )[0];\n const protocol: StatewireProtocol.Options = {\n ...(options.protocol !== undefined && { protocol: options.protocol }),\n ...(options.wireVersion !== undefined && {\n wireVersion: options.wireVersion,\n }),\n ...(options.applicationProtocols !== undefined && {\n applicationProtocols: options.applicationProtocols,\n }),\n ...(options.keyPrefixes !== undefined && {\n keyPrefixes: options.keyPrefixes,\n }),\n };\n const value = useResource(\n SessionTransport({\n transport: options.transport,\n session,\n documents,\n protocol,\n }),\n );\n const core = useStatewireCore(() => latest.current, value);\n const [subscribe] = useState(\n () => (listener: () => void) =>\n core.subscribe(() => flushTapSync(listener)),\n );\n\n const state = useSyncExternalStore(\n subscribe,\n core.getState,\n core.getState,\n ) as TState;\n const isBusy = useSyncExternalStore(subscribe, core.getBusy, core.getBusy);\n const failed = useSyncExternalStore(\n subscribe,\n core.getFailed,\n core.getFailed,\n );\n const connection = value.connection ?? CONNECTED_CONNECTION;\n\n return useMemo(() => {\n const failures = (): NonNullable<typeof value.failures> => {\n if (!value.failures) {\n throw new Error(\"statewire: this transport has no failed-send lane\");\n }\n return value.failures;\n };\n return {\n state,\n documents: value.documents,\n selection: value.selection,\n invoke: (\n protocol: string,\n method: string,\n params: readonly unknown[],\n ) => {\n if (!value.invoke)\n throw new Error(\n \"statewire: transport does not support protocol commands\",\n );\n return value.invoke(protocol, method, params);\n },\n updateContext: (ops: readonly unknown[]) => {\n if (!value.updateContext)\n throw new Error(\n \"statewire: transport does not support context documents\",\n );\n value.updateContext(ops);\n },\n getState: core.getState as () => TState,\n connection,\n commands: core.commands as Statewire.CommandsProxy<TCommands>,\n isBusy,\n setContext: (contextValue: Record<string, unknown>) => {\n if (!value.setContext) {\n throw new Error(\n \"statewire: this transport has no client context channel\",\n );\n }\n value.setContext(contextValue);\n },\n failed,\n retryFailed: (entry: StatewireClient.FailedCommand) =>\n failures().retry(entry),\n discardFailed: (entry: StatewireClient.FailedCommand) =>\n failures().discard(entry),\n };\n }, [state, isBusy, failed, connection, core, value]);\n};\n\nexport const StatewireResource = <\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n>(\n options: StatewireClient.Options<TState, TCommands>,\n): ResourceElement<StatewireClient.Helpers<TState, TCommands>> =>\n resource(useStatewire<TState, TCommands>)(options);\n\nexport class StatewireClient<\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n> {\n private readonly root;\n private disposed = false;\n\n constructor(options: StatewireClient.Options<TState, TCommands>) {\n const ClientRoot = () => useStatewire<TState, TCommands>(options);\n this.root = createTapRoot(ClientRoot);\n }\n\n get state(): TState {\n return this.root.getValue().getState();\n }\n\n get connection(): StatewireClient.Connection {\n return this.root.getValue().connection;\n }\n\n get commands(): Statewire.CommandsProxy<TCommands> {\n return this.root.getValue().commands;\n }\n\n get documents(): StatewireDocuments.Source | undefined {\n return this.root.getValue().documents;\n }\n get selection(): StatewireProtocol.Selection | undefined {\n return this.root.getValue().selection;\n }\n invoke(\n protocol: string,\n method: string,\n params: readonly unknown[],\n ): Promise<unknown> {\n return this.root.getValue().invoke(protocol, method, params);\n }\n updateContext(ops: readonly unknown[]): void {\n this.root.getValue().updateContext(ops);\n }\n\n get isBusy(): boolean {\n return this.root.getValue().isBusy;\n }\n\n setContext(value: Record<string, unknown>): void {\n this.root.getValue().setContext(value);\n }\n\n get failed(): readonly StatewireClient.FailedCommand[] {\n return this.root.getValue().failed;\n }\n\n retryFailed(entry: StatewireClient.FailedCommand): Promise<unknown> {\n return this.root.getValue().retryFailed(entry);\n }\n\n discardFailed(entry: StatewireClient.FailedCommand): void {\n this.root.getValue().discardFailed(entry);\n }\n\n subscribe(listener: () => void): () => void {\n return this.root.subscribe(listener);\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.root.unmount();\n }\n}\n\nexport namespace StatewireClient {\n export type Options<\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n > = {\n protocol?: string;\n keyPrefixes?: Readonly<Record<string, readonly string[]>>;\n wireVersion?: StatewireProtocol.Range;\n applicationProtocols?: readonly StatewireProtocol.Offer[] | \"*\";\n transport: ResourceElement<Statewire<TState, TCommands>>;\n /** Durable session: the mounted storage holds this client's lane identity and its un-durable commands, which resend on the next attach. */\n storage?:\n | {\n session?: ResourceElement<SessionStorage> | undefined;\n documents?: ResourceElement<StatewireDocuments.Storage> | undefined;\n }\n | undefined;\n /** Served as the canonical state until the attach snapshot; own commands fold over it. */\n initialState?: TState;\n optimistic?: Optimistic<NonNullable<TState>, TCommands>;\n materialize?: Materialize<NonNullable<TState>>;\n onStateChange?: (\n state: NonNullable<TState>,\n ctx: { changes: Statewire.Changes },\n ) => void;\n onCommandChange?: (\n update: Statewire.CommandUpdate<TCommands>,\n ctx: { state: NonNullable<TState> },\n ) => void;\n onConnectionChange?: (connection: Connection) => void;\n onError?: (error: ConnectionError) => void;\n /** Drops a retained failed entry once a canonical snapshot shows its effect landed; checked against each new snapshot. */\n failureCovered?: (\n state: NonNullable<TState>,\n entry: FailedCommand,\n ) => boolean;\n };\n\n export type Helpers<\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n > = {\n /** The statewire's state type — remote statewires include `undefined` until the first attach snapshot applies. */\n state: TState;\n documents: StatewireDocuments.Source | undefined;\n selection: StatewireProtocol.Selection | undefined;\n invoke: (\n protocol: string,\n method: string,\n params: readonly unknown[],\n ) => Promise<unknown>;\n updateContext: (ops: readonly unknown[]) => void;\n /** Identity-stable across renders; reads the current canonical state without subscribing the caller. */\n getState: () => TState;\n connection: Connection;\n commands: Statewire.CommandsProxy<TCommands>;\n /** Negation of the server's broadcast idle level (a transport without idle is always busy). */\n isBusy: boolean;\n /** Replace this client's ambient context on the server; throws on transports without a client context channel. */\n setContext: (value: Record<string, unknown>) => void;\n /** Non-accepted sends retained in the session record; reload with it. */\n failed: readonly FailedCommand[];\n /** Re-enqueues the entry's command on fresh clocks and removes the entry. */\n retryFailed: (entry: FailedCommand) => Promise<unknown>;\n /** Removes the entry. */\n discardFailed: (entry: FailedCommand) => void;\n };\n\n /** Connection lifecycle and whether its current state warrants a problem indicator. */\n export type ConnectionState =\n | { status: \"standby\"; reason: \"deferred\" | \"idle\"; degraded: false }\n | { status: \"connecting\"; degraded: false }\n | { status: \"connected\"; degraded: false }\n | {\n status: \"retrying\";\n degraded: true;\n attempt: number;\n /** Backoff details are absent while the retry dial is in flight. */\n cause?: \"dropped\" | \"reconnect\" | \"error\" | \"unauthorized\";\n code?: string;\n nextRetryAt?: number;\n lastError?: string;\n message?: string;\n }\n | {\n status: \"stopped\";\n degraded: true;\n reason:\n | \"gone\"\n | \"forbidden\"\n | \"protocol-error\"\n | \"unauthorized\"\n | \"storage-error\";\n message?: string;\n payload?: unknown;\n };\n export type Connection = ConnectionState & {\n error?: ConnectionError;\n reconnect: () => void;\n };\n export type ConnectionStatus = Connection[\"status\"];\n\n /**\n * Mutate the draft in place; the client records the next state plus the exact\n * changed paths. Re-run against the new base on every rebase.\n */\n export type Optimistic<\n TState,\n TCommands extends Statewire.Commands = Statewire.Commands,\n > = (\n draft: TState,\n command: Statewire.Command<TCommands>,\n ctx: OptimisticContext,\n ) => void;\n\n export type OptimisticContext = {\n ts: number;\n seq: number;\n clientId?: string;\n };\n\n /**\n * Mutate the draft to make server-accepted, still-uncommitted intents in\n * the state concrete (e.g. dispatch records into messages). Runs after the\n * optimistic folds on every published state.\n */\n export type Materialize<TState> = (draft: TState) => void;\n\n /**\n * fate: \"aborted\" = never sent, \"rejected\" = the server refused it\n * (`code` \"unknown-command\" | \"invalid-params\" for the static rejects,\n * code-less for handler rejects), \"lost\" = sent but no verdict will ever\n * arrive — the record is gone (a proven seq gap) or the channel died: it\n * may or may not have run, \"failed\" = the handler ran and threw,\n * \"crashed\" = the handler died involuntarily, \"expired\" = settled —\n * result, rejected, failed, or crashed — but the verdict outlived the\n * server's retention.\n * cause is which channel settled it: \"server\" = the server's answer;\n * the rest are channel deaths the client settled locally.\n */\n export type SendFailure =\n | {\n fate: \"rejected\";\n cause: \"server\";\n code?: string;\n message?: string;\n payload?: unknown;\n }\n | { fate: \"failed\"; cause: \"server\"; message?: string }\n | { fate: \"crashed\"; cause: \"server\" }\n | { fate: \"expired\"; cause: \"server\" }\n | {\n fate: \"aborted\";\n cause: \"unmount\" | \"stream-gone\" | \"session-lost\";\n predecessorLost?: true;\n }\n | {\n fate: \"lost\";\n cause: \"unmount\" | \"stream-gone\" | \"session-lost\";\n };\n\n /** Held commands a proven record gap settled `{fate: \"lost\", cause: \"session-lost\"}`; return \"requeue\" to re-enqueue them on the reset clocks. */\n export type OnSessionLost = (\n pending: ReadonlyArray<{\n method: string;\n params: readonly unknown[];\n ts: number;\n seq: number;\n clientId?: string;\n }>,\n ) => \"requeue\" | \"drop\";\n\n /** A non-accepted send retained for the user: the wire statement, its failure, and its original clocks. */\n export type FailedCommand = {\n readonly protocol: string;\n readonly produced?: SessionCommand[\"produced\"];\n readonly command: string;\n readonly params: readonly unknown[];\n readonly meta?: unknown;\n readonly failure: SendFailure;\n readonly ts: number;\n readonly seq: number;\n };\n\n /** A command as persisted while un-durable: its lane seq plus the wire statement. */\n export type SessionCommand = {\n seq: number;\n protocol: string;\n produced?: {\n wire: StatewireProtocol.Range;\n protocols: readonly StatewireProtocol.Offer[] | \"*\";\n };\n method: string;\n params: unknown[];\n meta?: unknown;\n };\n\n /** The persisted session: the lane identity, the cmd clock, and the commands the server has not marked durable. */\n export type SessionRecord = {\n clientId: string;\n nextSeq: number;\n commands: readonly SessionCommand[];\n /** Terminal verdicts parked for the sharer that minted the seq (shared storage only). */\n verdicts?: readonly SessionVerdict[];\n /** Non-accepted sends retained for the user; survive record rebases and resets. */\n failed?: readonly FailedCommand[];\n };\n\n /** A terminal verdict one sharer's connection carried, parked for the sharer awaiting the seq. */\n export type SessionVerdict = {\n seq: number;\n type: (typeof TERMINAL)[number];\n code?: string;\n message?: string;\n payload?: unknown;\n meta?: unknown;\n };\n\n /** Session storage seam with optional asynchronous hydration and persistence. */\n export type SessionStorage = {\n /** Resolves when a synchronous load can return the hydrated record. */\n ready?: Promise<void>;\n /** Resolves after all queued saves are persisted; awaited before sending statements. */\n flush?: () => void | Promise<void>;\n load: () => SessionRecord | null;\n save: (record: SessionRecord) => void;\n /** Upgrade incompatible stored commands; null discards the old record and starts a new client identity. */\n migrate?: (\n record: SessionRecord,\n current: NonNullable<SessionCommand[\"produced\"]>,\n ) => SessionRecord | null;\n /** Serializes record mutations across sharers; presence marks the storage shared. */\n lock?: <T>(fn: () => T | Promise<T>) => Promise<T>;\n /** Notifies of record saves by other sharers; returns unsubscribe. Required alongside `lock`. */\n subscribe?: (listener: () => void) => () => void;\n };\n\n /** Static headers, or a resolver invoked per request/attach; `staleAuth` is true right after an auth rejection. */\n export type ConnectionError = Error & { fin?: StatewireHost.Fin };\n\n export type HeadersOption =\n | HeadersInit\n | ((ctx: { staleAuth: boolean }) => HeadersInit | Promise<HeadersInit>);\n\n export type HttpOptions = StatewireProtocol.Options & {\n sessionStore?: SessionStorage | undefined;\n url: string;\n /** The session does not exist on the server yet: the first attach waits for the first command send (or an explicit `reconnect()`). */\n isNew?: boolean;\n headers?: HeadersOption;\n fetch?: typeof globalThis.fetch;\n onSessionLost?: OnSessionLost;\n onChange?: (connection: Connection) => void;\n onError?: (error: ConnectionError) => void;\n /** The broadcast idle flag's rising edge: the instance went quiet. */\n onDone?: () => void;\n };\n\n export type WebsocketOptions = StatewireProtocol.Options & {\n sessionStore?: SessionStorage | undefined;\n url: string;\n /** The session does not exist on the server yet: the first attach waits for the first command send (or an explicit `reconnect()`). */\n isNew?: boolean;\n headers?: HeadersOption;\n protocols?: string | string[];\n query?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n webSocket?: new (url: string, protocols?: string | string[]) => WebSocket;\n onSessionLost?: OnSessionLost;\n onChange?: (connection: Connection) => void;\n onError?: (error: ConnectionError) => void;\n /** The broadcast idle flag's rising edge: the instance went quiet. */\n onDone?: () => void;\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","names":[],"sources":["../src/storage.ts"],"mappings":";;;cAmkBa,oDAAsB,SAAA,gBAAA,iBAAA,SAAA,uBAAA;kBAElB;OACH;IACV,UAAU,gCAAgC;IAC1C,UAAU,aAAa,yBAAyB;IAChD,aAAa,uBAAuB;IACpC,uCAAuC;;IAEvC,cAAc,aAAa,cAAc,kBAAkB;;OAEjD;IACV,SAAS;IACT;IACA;;IAEA;MAAmB;MAAc;;IACjC,UAAU,gBAAgB;IAC1B;MAAc;MAAmB;;IACjC,WAAW"}
1
+ {"version":3,"file":"storage.d.ts","names":[],"sources":["../src/storage.ts"],"mappings":";;;cA+ea,oDAAsB,SAAA,gBAAA,iBAAA,SAAA,uBAAA;kBAElB;OACH;IACV,UAAU,gCAAgC;IAC1C,UAAU,aAAa,yBAAyB;IAChD,aAAa,uBAAuB;IACpC,uCAAuC;;IAEvC,cAAc,aAAa,cAAc,kBAAkB;;OAEjD;IACV,SAAS;IACT;IACA;;IAEA;MAAmB;MAAc;;IACjC,UAAU,gBAAgB;IAC1B;MAAc;MAAmB;;IACjC,WAAW"}