statewire 0.23.0 → 0.24.1

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.
Files changed (43) hide show
  1. package/dist/client/core.d.ts +4 -3
  2. package/dist/client/core.d.ts.map +1 -1
  3. package/dist/client/core.js +56 -45
  4. package/dist/client/core.js.map +1 -1
  5. package/dist/client/session.d.ts +56 -12
  6. package/dist/client/session.d.ts.map +1 -1
  7. package/dist/client/session.js +632 -260
  8. package/dist/client/session.js.map +1 -1
  9. package/dist/client/sessionStore.d.ts +1 -0
  10. package/dist/client/sessionStore.d.ts.map +1 -1
  11. package/dist/client/sessionStore.js +1 -0
  12. package/dist/client/sessionStore.js.map +1 -1
  13. package/dist/host/host.d.ts +6 -5
  14. package/dist/host/host.d.ts.map +1 -1
  15. package/dist/host/host.js.map +1 -1
  16. package/dist/indexedDb.d.ts +15 -0
  17. package/dist/indexedDb.d.ts.map +1 -0
  18. package/dist/indexedDb.js +171 -0
  19. package/dist/indexedDb.js.map +1 -0
  20. package/dist/statewire.d.ts +117 -59
  21. package/dist/statewire.d.ts.map +1 -1
  22. package/dist/statewire.js +13 -25
  23. package/dist/statewire.js.map +1 -1
  24. package/dist/storage.d.ts +42 -0
  25. package/dist/storage.d.ts.map +1 -1
  26. package/dist/storage.js +387 -125
  27. package/dist/storage.js.map +1 -1
  28. package/dist/transports/remote.d.ts.map +1 -1
  29. package/dist/transports/remote.js +7 -9
  30. package/dist/transports/remote.js.map +1 -1
  31. package/dist/types.d.ts +6 -7
  32. package/dist/types.d.ts.map +1 -1
  33. package/dist/types.js.map +1 -1
  34. package/package.json +2 -1
  35. package/src/client/core.ts +81 -64
  36. package/src/client/session.ts +886 -424
  37. package/src/client/sessionStore.ts +2 -0
  38. package/src/host/host.ts +10 -3
  39. package/src/indexedDb.ts +167 -0
  40. package/src/statewire.ts +133 -86
  41. package/src/storage.ts +548 -112
  42. package/src/transports/remote.ts +13 -14
  43. package/src/types.ts +6 -7
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","names":["useEffect","useMemo","useRef","randomId","wrapStorageError","resource","StatewireClient","StatewireProtocol","DEFAULT_PROTOCOL","MIN_SERVED_WIRE_VERSION","WIRE_VERSION","negotiationHeaders","protocolToken","isRecord","value","Record","Array","isArray","isOptionalString","undefined","isPositiveSafeInteger","Number","isSafeInteger","isStatement","isProtocol","isProducer","isIdentified","isFinite","isLegacyCommand","isSessionCommand","SessionCommand","isOutboxCommand","OutboxCommand","isSessionVerdict","SessionVerdict","isSendFailure","SendFailure","isFailedCommand","FailedCommand","isLaneWith","isCommand","command","SessionLane","every","mark","isSessionLane","isClientId","length","isRecordWith","isLane","lane","SessionRecord","Object","keys","values","isSessionRecord","identify","record","lanes","fromEntries","entries","map","protocol","commands","produced","wire","version","id","ts","Date","now","test","wireVersion","Range","applicationProtocols","Offer","invalid","Error","liftLegacy","clientId","nextSeq","verdicts","failed","legacyCommands","filter","_protocol","entry","target","normalize","parsed","statewireStorageVersion","format","savedAt","_savedAt","ctxNextSeq","_ctxNextSeq","context","_context","legacy","decode","raw","JSON","parse","isEmpty","outbox","active","WeakMap","KeyValueSessionStorage","Backend","Map","sweep","options","Options","currentKey","quota","backend","retention","namespace","getAllKeys","key","candidate","startsWith","get","has","getItem","push","sort","a","b","retained","quotaStart","Math","floor","index","expired","maxAgeMs","overflow","maxEntries","remove","removeItem","withUnused","isQuotaError","error","name","useKeyValueSessionStorage","SessionStorage","migrate","suppliedRetention","onError","latestErrorHandler","current","reportError","retain","configured","storageKey","state","Promise","cause","ready","queue","resolve","pending","failure","asynchronous","hydrated","then","catch","set","count","delete","load","save","encoded","stringify","recoverQuota","setItem","write","result","finally","flush","action"],"sources":["../src/storage.ts"],"sourcesContent":["import { useEffect, useMemo, useRef } from \"react\";\nimport { randomId } from \"./util/randomId\";\nimport { wrapStorageError } from \"./client/storageError\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type { StatewireClient } from \"./statewire\";\nimport type { StatewireProtocol } from \"./wire/protocol\";\nimport {\n DEFAULT_PROTOCOL,\n MIN_SERVED_WIRE_VERSION,\n WIRE_VERSION,\n negotiationHeaders,\n protocolToken,\n} from \"./wire/protocol\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isOptionalString = (value: unknown): boolean =>\n value === undefined || typeof value === \"string\";\n\nconst isPositiveSafeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value > 0;\n\nconst isStatement = (value: unknown): value is Record<string, unknown> =>\n isRecord(value) &&\n isProtocol(value[\"protocol\"]) &&\n isProducer(value[\"produced\"]) &&\n typeof value[\"method\"] === \"string\" &&\n Array.isArray(value[\"params\"]);\n\nconst isIdentified = (value: Record<string, unknown>) =>\n typeof value[\"id\"] === \"string\" &&\n value[\"id\"] !== \"\" &&\n typeof value[\"ts\"] === \"number\" &&\n Number.isFinite(value[\"ts\"]);\n\nconst isLegacyCommand = (value: unknown) =>\n isStatement(value) && isPositiveSafeInteger(value[\"seq\"]);\n\nconst isSessionCommand = (\n value: unknown,\n): value is StatewireClient.SessionCommand =>\n isLegacyCommand(value) &&\n isIdentified(value as Record<string, unknown>) &&\n isOptionalString((value as Record<string, unknown>)[\"owner\"]);\n\nconst isOutboxCommand = (\n value: unknown,\n): value is StatewireClient.OutboxCommand =>\n isStatement(value) &&\n isIdentified(value) &&\n (value[\"hold\"] === undefined || isRecord(value[\"hold\"])) &&\n (value[\"released\"] === undefined || value[\"released\"] === true) &&\n isOptionalString(value[\"by\"]);\n\nconst isSessionVerdict = (\n value: unknown,\n): value is StatewireClient.SessionVerdict =>\n isRecord(value) &&\n isPositiveSafeInteger(value[\"seq\"]) &&\n isOptionalString(value[\"id\"]) &&\n (value[\"type\"] === \"result\" ||\n value[\"type\"] === \"rejected\" ||\n value[\"type\"] === \"failed\" ||\n value[\"type\"] === \"crashed\" ||\n value[\"type\"] === \"expired\") &&\n isOptionalString(value[\"code\"]) &&\n isOptionalString(value[\"message\"]);\n\nconst isSendFailure = (\n value: unknown,\n): value is StatewireClient.SendFailure => {\n if (!isRecord(value)) return false;\n switch (value[\"fate\"]) {\n case \"rejected\":\n return (\n value[\"cause\"] === \"server\" &&\n isOptionalString(value[\"code\"]) &&\n isOptionalString(value[\"message\"])\n );\n case \"failed\":\n return value[\"cause\"] === \"server\" && isOptionalString(value[\"message\"]);\n case \"crashed\":\n case \"expired\":\n return value[\"cause\"] === \"server\";\n case \"aborted\":\n return (\n (value[\"cause\"] === \"unmount\" ||\n value[\"cause\"] === \"stream-gone\" ||\n value[\"cause\"] === \"session-lost\" ||\n value[\"cause\"] === \"removed\") &&\n (value[\"predecessorLost\"] === undefined ||\n value[\"predecessorLost\"] === true)\n );\n case \"lost\":\n return (\n value[\"cause\"] === \"unmount\" ||\n value[\"cause\"] === \"stream-gone\" ||\n value[\"cause\"] === \"session-lost\"\n );\n default:\n return false;\n }\n};\n\nconst isFailedCommand = (\n value: unknown,\n): value is StatewireClient.FailedCommand =>\n isRecord(value) &&\n isProtocol(value[\"protocol\"]) &&\n isProducer(value[\"produced\"]) &&\n typeof value[\"command\"] === \"string\" &&\n Array.isArray(value[\"params\"]) &&\n isSendFailure(value[\"failure\"]) &&\n typeof value[\"ts\"] === \"number\" &&\n Number.isFinite(value[\"ts\"]) &&\n isPositiveSafeInteger(value[\"seq\"]);\n\nconst isLaneWith = (\n value: unknown,\n isCommand: (command: unknown) => boolean,\n): value is StatewireClient.SessionLane =>\n isRecord(value) &&\n isPositiveSafeInteger(value[\"nextSeq\"]) &&\n Array.isArray(value[\"commands\"]) &&\n value[\"commands\"].every(isCommand) &&\n (value[\"outbox\"] === undefined ||\n (Array.isArray(value[\"outbox\"]) &&\n value[\"outbox\"].every(isOutboxCommand))) &&\n (value[\"removed\"] === undefined ||\n (Array.isArray(value[\"removed\"]) &&\n value[\"removed\"].every(\n (mark) =>\n isRecord(mark) &&\n typeof mark[\"id\"] === \"string\" &&\n typeof mark[\"by\"] === \"string\",\n ))) &&\n (value[\"verdicts\"] === undefined ||\n (Array.isArray(value[\"verdicts\"]) &&\n value[\"verdicts\"].every(isSessionVerdict))) &&\n (value[\"failed\"] === undefined ||\n (Array.isArray(value[\"failed\"]) && value[\"failed\"].every(isFailedCommand)));\n\nconst isSessionLane = (value: unknown): value is StatewireClient.SessionLane =>\n isLaneWith(value, isSessionCommand);\n\nconst isClientId = (value: unknown): value is string =>\n typeof value === \"string\" && value.length > 0;\n\nconst isRecordWith = (\n value: unknown,\n isLane: (lane: unknown) => boolean,\n): value is StatewireClient.SessionRecord =>\n isRecord(value) &&\n isClientId(value[\"clientId\"]) &&\n isRecord(value[\"lanes\"]) &&\n Object.keys(value[\"lanes\"]).every(isProtocol) &&\n Object.values(value[\"lanes\"]).every(isLane);\n\nconst isSessionRecord = (\n value: unknown,\n): value is StatewireClient.SessionRecord => isRecordWith(value, isSessionLane);\n\n// Formats before 4 stamped commands without an id or an enqueue time.\nconst identify = (\n record: StatewireClient.SessionRecord,\n): StatewireClient.SessionRecord => ({\n ...record,\n lanes: Object.fromEntries(\n Object.entries(record.lanes).map(([protocol, lane]) => [\n protocol,\n {\n ...lane,\n commands: lane.commands.map((command) => ({\n ...command,\n // The statement shape is unchanged across the gap-fill contract.\n ...(command.produced?.wire.version === MIN_SERVED_WIRE_VERSION && {\n produced: { ...command.produced, wire: { version: WIRE_VERSION } },\n }),\n id: randomId(),\n ts: Date.now(),\n })),\n },\n ]),\n ),\n});\n\nconst isProtocol = (value: unknown) =>\n value === undefined ||\n (typeof value === \"string\" && value !== \"*\" && protocolToken.test(value));\n\nconst isProducer = (value: unknown) => {\n if (value === undefined) return true;\n if (!isRecord(value) || !isRecord(value[\"wire\"])) return false;\n try {\n negotiationHeaders({\n wireVersion: value[\"wire\"] as StatewireProtocol.Range,\n applicationProtocols: value[\"protocols\"] as\n | readonly StatewireProtocol.Offer[]\n | \"*\",\n });\n return value[\"protocols\"] !== undefined;\n } catch {\n return false;\n }\n};\n\nconst invalid = (): never => {\n throw new Error(\"statewire: invalid stored session record\");\n};\n\n// Formats 1 and 2 held one lane: it lifts under the primary protocol, failed\n// entries under their own.\nconst liftLegacy = (\n value: Record<string, unknown>,\n protocol: string,\n): StatewireClient.SessionRecord => {\n const { clientId, nextSeq, commands, verdicts, failed } = value;\n const lane = {\n nextSeq,\n commands: [],\n ...(verdicts !== undefined && { verdicts }),\n };\n if (!isClientId(clientId) || !isSessionLane(lane) || !Array.isArray(commands))\n return invalid();\n const legacyCommands = commands as (StatewireClient.SessionCommand & {\n protocol?: string;\n })[];\n if (!legacyCommands.every(isLegacyCommand)) return invalid();\n if (\n failed !== undefined &&\n (!Array.isArray(failed) || !failed.every(isFailedCommand))\n )\n return invalid();\n const lanes: Record<string, StatewireClient.SessionLane> = {\n [protocol]: {\n ...lane,\n commands: legacyCommands\n .filter((command) => (command.protocol ?? protocol) === protocol)\n .map(({ protocol: _protocol, ...command }) => command),\n },\n };\n for (const entry of failed ?? []) {\n const target = lanes[entry.protocol] ?? { nextSeq: 1, commands: [] };\n lanes[entry.protocol] = {\n ...target,\n failed: [...(target.failed ?? []), entry],\n };\n }\n return identify({ clientId, lanes });\n};\n\nconst normalize = (\n parsed: unknown,\n protocol: string,\n): StatewireClient.SessionRecord => {\n if (!isRecord(parsed)) return invalid();\n const {\n statewireStorageVersion: format,\n savedAt: _savedAt,\n ...value\n } = parsed;\n if (format === 4) return isSessionRecord(value) ? value : invalid();\n if (format === 3)\n return isRecordWith(value, (lane) => isLaneWith(lane, isLegacyCommand))\n ? identify(value)\n : invalid();\n if (format !== undefined && format !== 1 && format !== 2)\n throw new Error(\"statewire: unsupported session storage version\");\n const { ctxNextSeq: _ctxNextSeq, context: _context, ...legacy } = value;\n return liftLegacy(legacy, protocol);\n};\n\nconst decode = (\n raw: string | null,\n protocol: string,\n): StatewireClient.SessionRecord | null =>\n raw === null ? null : normalize(JSON.parse(raw), protocol);\n\nconst isEmpty = (record: StatewireClient.SessionRecord) =>\n Object.values(record.lanes).every(\n (lane) =>\n lane.commands.length === 0 &&\n !lane.outbox?.length &&\n !lane.failed?.length,\n );\n\nconst active = new WeakMap<\n KeyValueSessionStorage.Backend,\n Map<string, number>\n>();\n\nconst sweep = async (\n options: KeyValueSessionStorage.Options,\n currentKey: string,\n quota = false,\n) => {\n const { backend, retention, namespace = \"\" } = options;\n if (!retention || !backend.getAllKeys) return;\n const entries: { key: string; savedAt: number }[] = [];\n const candidate = (raw: string | null) => {\n if (raw === null) return undefined;\n let value: unknown;\n try {\n value = JSON.parse(raw);\n } catch {\n return undefined;\n }\n try {\n if (!isEmpty(normalize(value, DEFAULT_PROTOCOL))) return undefined;\n } catch {\n return undefined;\n }\n const savedAt =\n (value as Record<string, unknown>)[\"savedAt\"] ??\n (value as Record<string, unknown>)[\"updatedAt\"];\n return typeof savedAt === \"number\" && Number.isFinite(savedAt)\n ? savedAt\n : undefined;\n };\n for (const key of await backend.getAllKeys()) {\n if (\n !key.startsWith(namespace) ||\n key === currentKey ||\n active.get(backend)?.has(key)\n )\n continue;\n const savedAt = candidate(await backend.getItem(key));\n if (savedAt !== undefined) entries.push({ key, savedAt });\n }\n entries.sort((a, b) => b.savedAt - a.savedAt);\n const now = Date.now();\n let retained = 1;\n const quotaStart = Math.floor(entries.length / 2);\n for (const [index, entry] of entries.entries()) {\n const expired =\n retention.maxAgeMs !== undefined &&\n now - entry.savedAt > retention.maxAgeMs;\n const overflow =\n retention.maxEntries !== undefined && retained >= retention.maxEntries;\n if (expired || overflow || (quota && index >= quotaStart)) {\n const remove = async () => {\n if (active.get(backend)?.has(entry.key)) return;\n if (candidate(await backend.getItem(entry.key)) !== entry.savedAt)\n return;\n if (active.get(backend)?.has(entry.key)) return;\n await backend.removeItem(entry.key);\n };\n if (backend.withUnused) await backend.withUnused(entry.key, remove);\n else await remove();\n } else retained++;\n }\n};\n\nconst isQuotaError = (error: unknown) =>\n error instanceof Error && error.name === \"QuotaExceededError\";\n\nconst useKeyValueSessionStorage = (\n options: KeyValueSessionStorage.Options,\n): StatewireClient.SessionStorage => {\n const {\n backend,\n key,\n namespace = \"\",\n protocol = DEFAULT_PROTOCOL,\n migrate,\n retention: suppliedRetention,\n onError,\n } = options;\n const latestErrorHandler = useRef(onError);\n latestErrorHandler.current = onError;\n const reportError = useMemo(\n () => (error: unknown) => latestErrorHandler.current?.(error),\n [],\n );\n const retain = suppliedRetention !== undefined;\n const maxAgeMs = suppliedRetention?.maxAgeMs;\n const maxEntries = suppliedRetention?.maxEntries;\n const retention = useMemo(\n () =>\n retain\n ? {\n ...(maxAgeMs === undefined ? {} : { maxAgeMs }),\n ...(maxEntries === undefined ? {} : { maxEntries }),\n }\n : undefined,\n [retain, maxAgeMs, maxEntries],\n );\n const configured = useMemo(\n () => ({\n backend,\n key,\n namespace,\n ...(retention === undefined ? {} : { retention }),\n }),\n [backend, key, namespace, retention],\n );\n const storageKey = namespace + key;\n if (retention !== undefined) {\n if (!namespace)\n throw new Error(\"statewire: session retention requires a namespace\");\n if (!backend.getAllKeys)\n throw new Error(\"statewire: session retention requires getAllKeys\");\n if (\n retention.maxAgeMs !== undefined &&\n (!Number.isFinite(retention.maxAgeMs) || retention.maxAgeMs < 0)\n )\n throw new Error(\"statewire: invalid session retention maxAgeMs\");\n if (\n retention.maxEntries !== undefined &&\n (!Number.isSafeInteger(retention.maxEntries) || retention.maxEntries < 1)\n )\n throw new Error(\"statewire: invalid session retention maxEntries\");\n }\n const state = useMemo(() => {\n let raw: string | null | Promise<string | null>;\n try {\n raw = backend.getItem(storageKey);\n } catch (cause) {\n const error = wrapStorageError(cause);\n reportError(error);\n throw error;\n }\n const state = {\n record: null as StatewireClient.SessionRecord | null,\n ready: undefined as Promise<void> | undefined,\n queue: Promise.resolve(),\n pending: 0,\n failure: undefined as unknown,\n asynchronous: typeof raw !== \"string\" && raw !== null,\n hydrated: typeof raw === \"string\" || raw === null,\n };\n if (state.asynchronous) {\n state.ready = Promise.resolve(raw)\n .then((value) => {\n state.record = decode(value, protocol);\n state.hydrated = true;\n })\n .catch((cause: unknown) => {\n const error = wrapStorageError(cause);\n if (state.failure !== error) reportError(error);\n state.failure = error;\n throw error;\n });\n state.ready.catch(() => {});\n } else {\n try {\n state.record = decode(raw as string | null, protocol);\n } catch (cause) {\n const error = wrapStorageError(cause);\n reportError(error);\n throw error;\n }\n }\n return state;\n }, [backend, storageKey, protocol, reportError]);\n\n useEffect(() => {\n const entries = active.get(backend) ?? new Map<string, number>();\n active.set(backend, entries);\n entries.set(storageKey, (entries.get(storageKey) ?? 0) + 1);\n return () => {\n const count = entries.get(storageKey)! - 1;\n if (count === 0) entries.delete(storageKey);\n else entries.set(storageKey, count);\n };\n }, [backend, storageKey]);\n\n useEffect(() => {\n if (retention !== undefined)\n void sweep(configured, storageKey).catch((cause: unknown) => {\n const error = wrapStorageError(cause);\n state.failure = error;\n reportError(error);\n });\n }, [state, configured, storageKey, retention, reportError]);\n\n return useMemo(\n () => ({\n ...(state.ready === undefined ? {} : { ready: state.ready }),\n load: () => {\n if (state.failure !== undefined) throw state.failure;\n if (!state.hydrated)\n throw new Error(\n \"statewire: await session storage readiness before loading\",\n );\n if (state.asynchronous || state.pending > 0) return state.record;\n let raw: string | null | Promise<string | null>;\n try {\n raw = backend.getItem(storageKey);\n } catch (cause) {\n const error = wrapStorageError(cause);\n reportError(error);\n throw error;\n }\n if (typeof raw !== \"string\" && raw !== null)\n throw new Error(\n \"statewire: storage backend changed from synchronous to asynchronous\",\n );\n try {\n return decode(raw, protocol);\n } catch (cause) {\n const error = wrapStorageError(cause);\n reportError(error);\n throw error;\n }\n },\n save: (record: StatewireClient.SessionRecord) => {\n if (state.failure !== undefined) throw state.failure;\n if (!state.hydrated)\n throw new Error(\n \"statewire: await session storage readiness before saving\",\n );\n if (!isSessionRecord(record))\n throw new Error(\"statewire: invalid session record\");\n const encoded = JSON.stringify({\n ...record,\n statewireStorageVersion: 4,\n savedAt: Date.now(),\n });\n state.record = record;\n const recoverQuota = async (error: unknown) => {\n if (!isQuotaError(error) || retention === undefined) throw error;\n await sweep(configured, storageKey, true);\n await backend.setItem(storageKey, encoded);\n };\n const write = async () => {\n try {\n await backend.setItem(storageKey, encoded);\n } catch (error) {\n await recoverQuota(error);\n }\n };\n if (!state.asynchronous && state.pending === 0) {\n let result: void | Promise<void>;\n try {\n result = backend.setItem(storageKey, encoded);\n } catch (error) {\n if (!isQuotaError(error) || retention === undefined) {\n state.failure = wrapStorageError(error);\n reportError(state.failure);\n throw state.failure;\n }\n result = recoverQuota(error);\n }\n if (result === undefined) return;\n state.pending++;\n state.queue = result;\n } else {\n state.pending++;\n state.queue = state.queue.then(() => state.ready).then(write);\n }\n state.queue = state.queue\n .catch((cause: unknown) => {\n const error = wrapStorageError(cause);\n if (state.failure !== error) reportError(error);\n state.failure = error;\n throw error;\n })\n .finally(() => {\n state.pending--;\n });\n state.queue.catch(() => {});\n },\n flush: () => {\n if (state.failure !== undefined) throw state.failure;\n if (!state.asynchronous && state.pending === 0) return;\n return (async () => {\n await state.ready;\n for (;;) {\n const queue = state.queue;\n await queue;\n if (queue === state.queue) return;\n }\n })();\n },\n ...(migrate === undefined ? {} : { migrate }),\n }),\n [\n state,\n backend,\n storageKey,\n protocol,\n migrate,\n retention,\n configured,\n reportError,\n ],\n );\n};\n\n/** Persist sessions through a synchronous or asynchronous string storage backend. */\nexport const KeyValueSessionStorage = resource(useKeyValueSessionStorage);\n\nexport namespace KeyValueSessionStorage {\n export type Backend = {\n getItem: (key: string) => string | null | Promise<string | null>;\n setItem: (key: string, value: string) => void | Promise<void>;\n removeItem: (key: string) => void | Promise<void>;\n getAllKeys?: () => readonly string[] | Promise<readonly string[]>;\n /** Runs cleanup under exclusive access, skipping keys in use by another runtime. */\n withUnused?: (key: string, action: () => Promise<void>) => Promise<void>;\n };\n export type Options = {\n backend: Backend;\n key: string;\n namespace?: string;\n /** The lane that sessions saved in a single-lane format lift into; defaults to the client's default protocol. */\n protocol?: string;\n migrate?: StatewireClient.SessionStorage[\"migrate\"];\n retention?: { maxAgeMs?: number; maxEntries?: number };\n onError?: (error: unknown) => void;\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","names":["useEffect","useMemo","useRef","randomId","wrapStorageError","reviveValue","resource","StatewireClient","Statewire","StatewireProtocol","DEFAULT_PROTOCOL","MIN_SERVED_WIRE_VERSION","WIRE_VERSION","negotiationHeaders","protocolToken","isRecord","value","Record","Array","isArray","isOptionalString","undefined","isPositiveSafeInteger","Number","isSafeInteger","isStatement","isProtocol","isProducer","isIdentified","isFinite","isLegacyCommand","isSessionCommand","SessionCommand","isOutboxCommand","OutboxCommand","isLegacyOutboxCommand","isStoredSettled","StoredSettled","isSendFailure","isSessionVerdict","SessionVerdict","SendFailure","FailedCommand","protocol","produced","command","params","meta","failure","ts","seq","isFailedCommand","isArrayOf","is","item","every","isMark","mark","isLaneWith","isCommand","legacy","SessionLane","isSessionLane","isClientId","length","isRecordWith","isLane","lane","SessionRecord","Object","keys","values","isSessionRecord","identify","record","lanes","fromEntries","entries","map","commands","wire","version","id","Date","now","test","wireVersion","Range","applicationProtocols","Offer","invalid","Error","LegacyLane","outbox","Omit","hold","failed","LegacyRecord","clientId","liftLegacy","nextSeq","verdicts","legacyCommands","filter","_protocol","entry","target","upgrade","inbox","sort","a","b","f","method","held","const","localMeta","isLegacyLane","normalize","parsed","statewireStorageVersion","format","savedAt","_savedAt","ctxNextSeq","_ctxNextSeq","context","_context","STORAGE_FORMAT","parse","raw","codec","KeyValueSessionStorage","Codec","Promise","JSON","decode","isUnsent","entryCount","reduce","sum","noticesOf","CommandUpdate","flatMap","n","status","active","WeakMap","Backend","Map","savers","Set","key","announce","backend","listener","get","Candidate","sweeping","sweep","options","Options","currentKey","quota","run","resolve","catch","then","sweepOnce","set","retention","namespace","onEvict","getAllKeys","candidate","some","empty","noticed","startsWith","has","found","getItem","push","remove","reason","EvictEvent","again","removeItem","dropped","withUnused","expired","maxAgeMs","retained","quotaStart","Math","floor","index","overflow","maxEntries","isQuotaError","error","name","quotaError","limit","otherBytes","total","other","validLimit","useKeyValueSessionStorage","SessionStorage","migrate","suppliedRetention","limits","suppliedLimits","onError","latest","current","reportError","reportEvict","event","retain","outboxEntries","recordBytes","totalBytes","configured","storageKey","state","cause","bytes","others","ready","queue","pending","asynchronous","hydrated","hydrate","count","delete","checkLimits","persist","encoded","stored","encode","setItem","durable","read","load","save","stringify","finally","flush","action","subscribe","plain","pages","useMemorySessionStorage","t0","$","_c","scope","t1","MemorySessionStorage","entriesOf","OutboxEntry","view","c","OutboxState","structuredClone","readOutboxes","ReadOutboxes","Outbox","result","subscribeOutboxes","outboxes","closed","reading","refresh","onKey","local","add","remote","IndexedDbSession","indexedDbBackend","_c","reviveValue"],"sources":["../src/storage.ts"],"sourcesContent":["import { useEffect, useMemo, useRef } from \"react\";\nimport { randomId } from \"./util/randomId\";\nimport { wrapStorageError } from \"./client/storageError\";\nimport { reviveValue } from \"./wire/meta\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type { StatewireClient } from \"./statewire\";\nimport type { Statewire } from \"./types\";\nimport type { StatewireProtocol } from \"./wire/protocol\";\nimport {\n DEFAULT_PROTOCOL,\n MIN_SERVED_WIRE_VERSION,\n WIRE_VERSION,\n negotiationHeaders,\n protocolToken,\n} from \"./wire/protocol\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isOptionalString = (value: unknown): boolean =>\n value === undefined || typeof value === \"string\";\n\nconst isPositiveSafeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value > 0;\n\nconst isStatement = (value: unknown): value is Record<string, unknown> =>\n isRecord(value) &&\n isProtocol(value[\"protocol\"]) &&\n isProducer(value[\"produced\"]) &&\n typeof value[\"method\"] === \"string\" &&\n Array.isArray(value[\"params\"]);\n\nconst isIdentified = (value: Record<string, unknown>) =>\n typeof value[\"id\"] === \"string\" &&\n value[\"id\"] !== \"\" &&\n typeof value[\"ts\"] === \"number\" &&\n Number.isFinite(value[\"ts\"]);\n\nconst isLegacyCommand = (value: unknown) =>\n isStatement(value) && isPositiveSafeInteger(value[\"seq\"]);\n\nconst isSessionCommand = (\n value: unknown,\n): value is StatewireClient.SessionCommand =>\n isLegacyCommand(value) &&\n isIdentified(value as Record<string, unknown>) &&\n isOptionalString((value as Record<string, unknown>)[\"owner\"]);\n\nconst isOutboxCommand = (\n value: unknown,\n): value is StatewireClient.OutboxCommand =>\n isStatement(value) &&\n isIdentified(value) &&\n (value[\"held\"] === undefined || value[\"held\"] === true) &&\n (value[\"released\"] === undefined || value[\"released\"] === true) &&\n isOptionalString(value[\"by\"]);\n\n// Format 4 outbox entries carried the hold as `hold: { meta }`.\nconst isLegacyOutboxCommand = (value: unknown) =>\n isStatement(value) &&\n isIdentified(value) &&\n (value[\"hold\"] === undefined || isRecord(value[\"hold\"])) &&\n (value[\"released\"] === undefined || value[\"released\"] === true) &&\n isOptionalString(value[\"by\"]);\n\nconst isStoredSettled = (\n value: unknown,\n): value is StatewireClient.StoredSettled =>\n isRecord(value) &&\n isIdentified(value) &&\n typeof value[\"method\"] === \"string\" &&\n Array.isArray(value[\"params\"]) &&\n (value[\"seq\"] === undefined || isPositiveSafeInteger(value[\"seq\"])) &&\n (value[\"failure\"] === undefined\n ? isRecord(value[\"result\"]) && Array.isArray(value[\"result\"][\"value\"])\n : value[\"result\"] === undefined && isSendFailure(value[\"failure\"]));\n\nconst isSessionVerdict = (\n value: unknown,\n): value is StatewireClient.SessionVerdict =>\n isRecord(value) &&\n isPositiveSafeInteger(value[\"seq\"]) &&\n isOptionalString(value[\"id\"]) &&\n (value[\"type\"] === \"result\" ||\n value[\"type\"] === \"rejected\" ||\n value[\"type\"] === \"failed\" ||\n value[\"type\"] === \"crashed\" ||\n value[\"type\"] === \"expired\") &&\n isOptionalString(value[\"code\"]) &&\n isOptionalString(value[\"message\"]);\n\nconst isSendFailure = (\n value: unknown,\n): value is StatewireClient.SendFailure => {\n if (!isRecord(value)) return false;\n switch (value[\"fate\"]) {\n case \"rejected\":\n return (\n value[\"cause\"] === \"server\" &&\n isOptionalString(value[\"code\"]) &&\n isOptionalString(value[\"message\"])\n );\n case \"failed\":\n return value[\"cause\"] === \"server\" && isOptionalString(value[\"message\"]);\n case \"crashed\":\n case \"expired\":\n return value[\"cause\"] === \"server\";\n case \"aborted\":\n return (\n (value[\"cause\"] === \"unmount\" ||\n value[\"cause\"] === \"stream-gone\" ||\n value[\"cause\"] === \"session-lost\" ||\n value[\"cause\"] === \"removed\" ||\n value[\"cause\"] === \"quota\") &&\n (value[\"predecessorLost\"] === undefined ||\n value[\"predecessorLost\"] === true)\n );\n case \"lost\":\n return (\n value[\"cause\"] === \"unmount\" ||\n value[\"cause\"] === \"stream-gone\" ||\n value[\"cause\"] === \"session-lost\"\n );\n default:\n return false;\n }\n};\n\ntype FailedCommand = {\n protocol: string;\n produced?: StatewireClient.SessionCommand[\"produced\"];\n command: string;\n params: unknown[];\n meta?: unknown;\n failure: StatewireClient.SendFailure;\n ts: number;\n seq: number;\n};\n\nconst isFailedCommand = (value: unknown): value is FailedCommand =>\n isRecord(value) &&\n isProtocol(value[\"protocol\"]) &&\n isProducer(value[\"produced\"]) &&\n typeof value[\"command\"] === \"string\" &&\n Array.isArray(value[\"params\"]) &&\n isSendFailure(value[\"failure\"]) &&\n typeof value[\"ts\"] === \"number\" &&\n Number.isFinite(value[\"ts\"]) &&\n isPositiveSafeInteger(value[\"seq\"]);\n\nconst isArrayOf = (value: unknown, is: (item: unknown) => boolean) =>\n value === undefined || (Array.isArray(value) && value.every(is));\n\nconst isMark = (mark: unknown) =>\n isRecord(mark) &&\n typeof mark[\"id\"] === \"string\" &&\n typeof mark[\"by\"] === \"string\" &&\n (mark[\"failure\"] === undefined || isSendFailure(mark[\"failure\"]));\n\nconst isLaneWith = (\n value: unknown,\n isCommand: (command: unknown) => boolean,\n legacy = false,\n): value is StatewireClient.SessionLane =>\n isRecord(value) &&\n isPositiveSafeInteger(value[\"nextSeq\"]) &&\n Array.isArray(value[\"commands\"]) &&\n value[\"commands\"].every(isCommand) &&\n isArrayOf(\n value[\"outbox\"],\n legacy ? isLegacyOutboxCommand : isOutboxCommand,\n ) &&\n isArrayOf(value[\"removed\"], isMark) &&\n isArrayOf(value[\"verdicts\"], isSessionVerdict) &&\n (legacy\n ? isArrayOf(value[\"failed\"], isFailedCommand)\n : value[\"failed\"] === undefined &&\n isArrayOf(value[\"inbox\"], isStoredSettled));\n\nconst isSessionLane = (value: unknown): value is StatewireClient.SessionLane =>\n isLaneWith(value, isSessionCommand);\n\nconst isClientId = (value: unknown): value is string =>\n typeof value === \"string\" && value.length > 0;\n\nconst isRecordWith = (\n value: unknown,\n isLane: (lane: unknown) => boolean,\n): value is StatewireClient.SessionRecord =>\n isRecord(value) &&\n isClientId(value[\"clientId\"]) &&\n isRecord(value[\"lanes\"]) &&\n Object.keys(value[\"lanes\"]).every(isProtocol) &&\n Object.values(value[\"lanes\"]).every(isLane);\n\nconst isSessionRecord = (\n value: unknown,\n): value is StatewireClient.SessionRecord => isRecordWith(value, isSessionLane);\n\n// Formats before 4 stamped commands without an id or an enqueue time.\nconst identify = (\n record: StatewireClient.SessionRecord,\n): StatewireClient.SessionRecord => ({\n ...record,\n lanes: Object.fromEntries(\n Object.entries(record.lanes).map(([protocol, lane]) => [\n protocol,\n {\n ...lane,\n commands: lane.commands.map((command) => ({\n ...command,\n // The statement shape is unchanged across the gap-fill contract.\n ...(command.produced?.wire.version === MIN_SERVED_WIRE_VERSION && {\n produced: { ...command.produced, wire: { version: WIRE_VERSION } },\n }),\n id: randomId(),\n ts: Date.now(),\n })),\n },\n ]),\n ),\n});\n\nconst isProtocol = (value: unknown) =>\n value === undefined ||\n (typeof value === \"string\" && value !== \"*\" && protocolToken.test(value));\n\nconst isProducer = (value: unknown) => {\n if (value === undefined) return true;\n if (!isRecord(value) || !isRecord(value[\"wire\"])) return false;\n try {\n negotiationHeaders({\n wireVersion: value[\"wire\"] as StatewireProtocol.Range,\n applicationProtocols: value[\"protocols\"] as\n | readonly StatewireProtocol.Offer[]\n | \"*\",\n });\n return value[\"protocols\"] !== undefined;\n } catch {\n return false;\n }\n};\n\nconst invalid = (): never => {\n throw new Error(\"statewire: invalid stored session record\");\n};\n\ntype LegacyLane = Record<string, unknown> & {\n commands: StatewireClient.SessionCommand[];\n outbox?: (Omit<StatewireClient.OutboxCommand, \"held\"> & {\n hold?: { meta?: unknown };\n })[];\n failed?: FailedCommand[];\n};\n\ntype LegacyRecord = { clientId: string; lanes: Record<string, LegacyLane> };\n\n// Formats 1 and 2 held one lane: it lifts under the primary protocol, failed\n// entries under their own.\nconst liftLegacy = (\n value: Record<string, unknown>,\n protocol: string,\n): LegacyRecord => {\n const { clientId, nextSeq, commands, verdicts, failed } = value;\n const lane = {\n nextSeq,\n commands: [],\n ...(verdicts !== undefined && { verdicts }),\n };\n if (!isClientId(clientId) || !isSessionLane(lane) || !Array.isArray(commands))\n return invalid();\n const legacyCommands = commands as (StatewireClient.SessionCommand & {\n protocol?: string;\n })[];\n if (!legacyCommands.every(isLegacyCommand)) return invalid();\n if (\n failed !== undefined &&\n (!Array.isArray(failed) || !failed.every(isFailedCommand))\n )\n return invalid();\n const lanes: Record<string, LegacyLane> = {\n [protocol]: {\n ...(lane as Record<string, unknown>),\n commands: legacyCommands\n .filter((command) => (command.protocol ?? protocol) === protocol)\n .map(({ protocol: _protocol, ...command }) => command),\n },\n };\n for (const entry of (failed ?? []) as FailedCommand[]) {\n const target = lanes[entry.protocol] ?? { nextSeq: 1, commands: [] };\n lanes[entry.protocol] = {\n ...target,\n failed: [...(target.failed ?? []), entry],\n };\n }\n return identify({ clientId, lanes } as never) as never;\n};\n\n// Format 5: holds are a flag with client-only localMeta; failed sends are\n// settled updates awaiting their onCommandChange ack.\nconst upgrade = (record: LegacyRecord): StatewireClient.SessionRecord => ({\n clientId: record.clientId,\n lanes: Object.fromEntries(\n Object.entries(record.lanes).map(([protocol, legacy]) => {\n const { outbox, failed, ...lane } = legacy;\n const inbox = [...(failed ?? [])]\n .sort((a, b) => a.ts - b.ts)\n .map((f): StatewireClient.StoredSettled => ({\n // Stable across re-migrations until the upgraded record is saved.\n id: `failed:${protocol}:${f.seq}:${f.ts}`,\n method: f.command,\n params: f.params,\n ...(f.meta !== undefined && { meta: f.meta }),\n ts: f.ts,\n failure: f.failure,\n }));\n return [\n protocol,\n {\n ...(lane as unknown as StatewireClient.SessionLane),\n ...(outbox?.length && {\n outbox: outbox.map(({ hold, ...command }) => ({\n ...command,\n ...(hold !== undefined && { held: true as const }),\n ...(hold?.meta !== undefined && { localMeta: hold.meta }),\n })),\n }),\n ...(inbox.length > 0 && { inbox }),\n },\n ];\n }),\n ),\n});\n\nconst isLegacyLane = (lane: unknown) =>\n isLaneWith(lane, isSessionCommand, true);\n\nconst normalize = (\n parsed: unknown,\n protocol: string,\n): StatewireClient.SessionRecord => {\n if (!isRecord(parsed)) return invalid();\n const {\n statewireStorageVersion: format,\n savedAt: _savedAt,\n ...value\n } = parsed;\n if (format === 5) return isSessionRecord(value) ? value : invalid();\n if (format === 4)\n return isRecordWith(value, isLegacyLane)\n ? upgrade(value as never)\n : invalid();\n if (format === 3)\n return isRecordWith(value, (lane) =>\n isLaneWith(lane, isLegacyCommand, true),\n )\n ? upgrade(identify(value) as never)\n : invalid();\n if (format !== undefined && format !== 1 && format !== 2)\n throw new Error(\"statewire: unsupported session storage version\");\n const { ctxNextSeq: _ctxNextSeq, context: _context, ...legacy } = value;\n return upgrade(liftLegacy(legacy, protocol));\n};\n\nexport const STORAGE_FORMAT = 5;\n\nconst parse = async (\n raw: string | null,\n codec: KeyValueSessionStorage.Codec | undefined,\n): Promise<unknown> =>\n raw === null\n ? null\n : JSON.parse(codec === undefined ? raw : await codec.decode(raw));\n\nconst decode = (\n raw: string | null,\n protocol: string,\n): StatewireClient.SessionRecord | null =>\n raw === null ? null : normalize(JSON.parse(raw), protocol);\n\nconst isUnsent = (lane: StatewireClient.SessionLane) =>\n lane.commands.length > 0 || (lane.outbox?.length ?? 0) > 0;\n\nconst entryCount = (record: StatewireClient.SessionRecord | null) =>\n record === null\n ? 0\n : Object.values(record.lanes).reduce(\n (sum, lane) => sum + lane.commands.length + (lane.outbox?.length ?? 0),\n 0,\n );\n\nconst noticesOf = (\n record: StatewireClient.SessionRecord,\n): Statewire.CommandUpdate[] =>\n Object.entries(record.lanes).flatMap(([protocol, lane]) =>\n (lane.inbox ?? []).map((n) => ({\n protocol,\n id: n.id,\n method: n.method,\n params: n.params as never[],\n ...(n.seq !== undefined && { seq: n.seq }),\n status: \"settled\" as const,\n ...(n.failure !== undefined && { failure: n.failure }),\n ...(n.localMeta !== undefined && { localMeta: n.localMeta }),\n })),\n );\n\nconst active = new WeakMap<\n KeyValueSessionStorage.Backend,\n Map<string, number>\n>();\n\n/** Same-runtime saves, per backend, for `subscribeOutboxes`. */\nconst savers = new WeakMap<\n KeyValueSessionStorage.Backend,\n Set<(key: string) => void>\n>();\n\nconst announce = (backend: KeyValueSessionStorage.Backend, key: string) => {\n for (const listener of savers.get(backend) ?? []) listener(key);\n};\n\ntype Candidate = {\n key: string;\n savedAt: number;\n record: StatewireClient.SessionRecord;\n};\n\nconst sweeping = new WeakMap<KeyValueSessionStorage.Backend, Promise<void>>();\n\n// Sweeps of one backend run one at a time.\nconst sweep = (\n options: KeyValueSessionStorage.Options,\n currentKey: string,\n quota = false,\n): Promise<void> => {\n const run = (sweeping.get(options.backend) ?? Promise.resolve())\n .catch(() => {})\n .then(() => sweepOnce(options, currentKey, quota));\n sweeping.set(options.backend, run);\n return run;\n};\n\n// Records with unsent commands are never evicted. Empty records go first;\n// records holding only failure notices go once past their age.\nconst sweepOnce = async (\n options: KeyValueSessionStorage.Options,\n currentKey: string,\n quota = false,\n) => {\n const { backend, retention, namespace = \"\", codec, onEvict } = options;\n if (!retention || !backend.getAllKeys) return;\n const candidate = async (raw: string | null) => {\n let value: unknown;\n try {\n value = await parse(raw, codec);\n } catch {\n return undefined;\n }\n if (value === null) return undefined;\n let record: StatewireClient.SessionRecord;\n try {\n record = normalize(value, DEFAULT_PROTOCOL);\n } catch {\n return undefined;\n }\n if (Object.values(record.lanes).some(isUnsent)) return undefined;\n const savedAt =\n (value as Record<string, unknown>)[\"savedAt\"] ??\n (value as Record<string, unknown>)[\"updatedAt\"];\n return typeof savedAt === \"number\" && Number.isFinite(savedAt)\n ? { savedAt, record }\n : undefined;\n };\n const empty: Candidate[] = [];\n const noticed: Candidate[] = [];\n for (const key of await backend.getAllKeys()) {\n if (\n !key.startsWith(namespace) ||\n key === currentKey ||\n active.get(backend)?.has(key)\n )\n continue;\n const found = await candidate(await backend.getItem(key));\n if (found === undefined) continue;\n (noticesOf(found.record).length > 0 ? noticed : empty).push({\n key,\n ...found,\n });\n }\n const remove = async (\n entry: Candidate,\n reason: KeyValueSessionStorage.EvictEvent[\"reason\"],\n ) => {\n const run = async () => {\n if (active.get(backend)?.has(entry.key)) return;\n const again = await candidate(await backend.getItem(entry.key));\n if (again?.savedAt !== entry.savedAt) return;\n if (active.get(backend)?.has(entry.key)) return;\n await backend.removeItem(entry.key);\n announce(backend, entry.key);\n onEvict?.({\n key: entry.key,\n reason,\n dropped: noticesOf(again.record),\n });\n };\n if (backend.withUnused) await backend.withUnused(entry.key, run);\n else await run();\n };\n const now = Date.now();\n const expired = (entry: Candidate) =>\n retention.maxAgeMs !== undefined &&\n now - entry.savedAt > retention.maxAgeMs;\n empty.sort((a, b) => b.savedAt - a.savedAt);\n let retained = 1;\n const quotaStart = Math.floor(empty.length / 2);\n for (const [index, entry] of empty.entries()) {\n const overflow =\n retention.maxEntries !== undefined && retained >= retention.maxEntries;\n if (expired(entry)) await remove(entry, \"expired\");\n else if (overflow) await remove(entry, \"overflow\");\n else if (quota && index >= quotaStart) await remove(entry, \"quota\");\n else retained++;\n }\n for (const entry of noticed)\n if (expired(entry)) await remove(entry, \"expired\");\n};\n\nconst isQuotaError = (error: unknown) =>\n error instanceof Error && error.name === \"QuotaExceededError\";\n\nconst quotaError = (limit: string) => {\n const error = new Error(`statewire: session ${limit} limit reached`);\n error.name = \"StatewireQuotaError\";\n return error;\n};\n\nconst otherBytes = async (\n backend: KeyValueSessionStorage.Backend,\n namespace: string,\n key: string,\n) => {\n let total = 0;\n for (const other of (await backend.getAllKeys?.()) ?? []) {\n if (other === key || !other.startsWith(namespace)) continue;\n total += (await backend.getItem(other))?.length ?? 0;\n }\n return total;\n};\n\nconst validLimit = (value: number | undefined, name: string) => {\n if (value !== undefined && (!Number.isSafeInteger(value) || value < 1))\n throw new Error(`statewire: invalid session limit ${name}`);\n};\n\nconst useKeyValueSessionStorage = (\n options: KeyValueSessionStorage.Options,\n): StatewireClient.SessionStorage => {\n const {\n backend,\n key,\n namespace = \"\",\n protocol = DEFAULT_PROTOCOL,\n migrate,\n retention: suppliedRetention,\n limits: suppliedLimits,\n codec,\n onError,\n onEvict,\n } = options;\n const latest = useRef({ onError, onEvict });\n latest.current = { onError, onEvict };\n const reportError = useMemo(\n () => (error: unknown) => latest.current.onError?.(error),\n [],\n );\n const reportEvict = useMemo(\n () => (event: KeyValueSessionStorage.EvictEvent) =>\n latest.current.onEvict?.(event),\n [],\n );\n const retain = suppliedRetention !== undefined;\n const maxAgeMs = suppliedRetention?.maxAgeMs;\n const maxEntries = suppliedRetention?.maxEntries;\n const retention = useMemo(\n () =>\n retain\n ? {\n ...(maxAgeMs === undefined ? {} : { maxAgeMs }),\n ...(maxEntries === undefined ? {} : { maxEntries }),\n }\n : undefined,\n [retain, maxAgeMs, maxEntries],\n );\n const outboxEntries = suppliedLimits?.outboxEntries;\n const recordBytes = suppliedLimits?.recordBytes;\n const totalBytes = suppliedLimits?.totalBytes;\n validLimit(outboxEntries, \"outboxEntries\");\n validLimit(recordBytes, \"recordBytes\");\n validLimit(totalBytes, \"totalBytes\");\n if (totalBytes !== undefined && !backend.getAllKeys)\n throw new Error(\"statewire: a totalBytes limit requires getAllKeys\");\n const configured = useMemo(\n () => ({\n backend,\n key,\n namespace,\n onEvict: reportEvict,\n ...(codec === undefined ? {} : { codec }),\n ...(retention === undefined ? {} : { retention }),\n }),\n [backend, key, namespace, retention, codec, reportEvict],\n );\n const storageKey = namespace + key;\n if (retention !== undefined) {\n if (!namespace)\n throw new Error(\"statewire: session retention requires a namespace\");\n if (!backend.getAllKeys)\n throw new Error(\"statewire: session retention requires getAllKeys\");\n if (\n retention.maxAgeMs !== undefined &&\n (!Number.isFinite(retention.maxAgeMs) || retention.maxAgeMs < 0)\n )\n throw new Error(\"statewire: invalid session retention maxAgeMs\");\n if (\n retention.maxEntries !== undefined &&\n (!Number.isSafeInteger(retention.maxEntries) || retention.maxEntries < 1)\n )\n throw new Error(\"statewire: invalid session retention maxEntries\");\n }\n const state = useMemo(() => {\n let raw: string | null | Promise<string | null>;\n try {\n raw = backend.getItem(storageKey);\n } catch (cause) {\n const error = wrapStorageError(cause);\n reportError(error);\n throw error;\n }\n const state = {\n record: null as StatewireClient.SessionRecord | null,\n bytes: 0,\n others: undefined as number | undefined,\n ready: undefined as Promise<void> | undefined,\n queue: Promise.resolve(),\n pending: 0,\n failure: undefined as unknown,\n asynchronous:\n codec !== undefined || (typeof raw !== \"string\" && raw !== null),\n hydrated: false,\n };\n const hydrate = (record: StatewireClient.SessionRecord | null) => {\n state.record = record;\n state.hydrated = true;\n };\n if (state.asynchronous) {\n state.ready = Promise.resolve(raw)\n .then(async (value) => {\n state.bytes = value?.length ?? 0;\n const parsed = await parse(value, codec);\n hydrate(parsed === null ? null : normalize(parsed, protocol));\n })\n .catch((cause: unknown) => {\n const error = wrapStorageError(cause);\n if (state.failure !== error) reportError(error);\n state.failure = error;\n throw error;\n });\n state.ready.catch(() => {});\n } else {\n try {\n state.bytes = (raw as string | null)?.length ?? 0;\n hydrate(decode(raw as string | null, protocol));\n } catch (cause) {\n const error = wrapStorageError(cause);\n reportError(error);\n throw error;\n }\n }\n return state;\n }, [backend, storageKey, protocol, codec, reportError]);\n\n useEffect(() => {\n const entries = active.get(backend) ?? new Map<string, number>();\n active.set(backend, entries);\n entries.set(storageKey, (entries.get(storageKey) ?? 0) + 1);\n return () => {\n const count = entries.get(storageKey)! - 1;\n if (count === 0) entries.delete(storageKey);\n else entries.set(storageKey, count);\n };\n }, [backend, storageKey]);\n\n useEffect(() => {\n if (retention !== undefined)\n void sweep(configured, storageKey).catch((cause: unknown) => {\n const error = wrapStorageError(cause);\n state.failure = error;\n reportError(error);\n });\n }, [state, configured, storageKey, retention, reportError]);\n\n useEffect(() => {\n if (totalBytes === undefined) return;\n void otherBytes(backend, namespace, storageKey).then(\n (bytes) => {\n state.others = bytes;\n },\n () => {},\n );\n }, [state, backend, namespace, storageKey, totalBytes]);\n\n return useMemo(() => {\n const checkLimits = (\n record: StatewireClient.SessionRecord,\n bytes: number,\n ) => {\n // Limits gate writes that add an entry; settling and stamping always land.\n if (entryCount(record) <= entryCount(state.record)) return;\n if (outboxEntries !== undefined && entryCount(record) > outboxEntries)\n throw quotaError(\"outboxEntries\");\n if (recordBytes !== undefined && bytes > recordBytes)\n throw quotaError(\"recordBytes\");\n if (\n totalBytes !== undefined &&\n state.others !== undefined &&\n state.others + bytes > totalBytes\n )\n throw quotaError(\"totalBytes\");\n };\n const persist = async (encoded: string) => {\n const stored =\n codec === undefined ? encoded : await codec.encode(encoded);\n try {\n await backend.setItem(storageKey, stored);\n } catch (error) {\n if (!isQuotaError(error)) throw error;\n if (retention !== undefined) await sweep(configured, storageKey, true);\n await backend.setItem(storageKey, stored);\n }\n announce(backend, storageKey);\n };\n return {\n durable: true,\n ...(state.ready === undefined ? {} : { ready: state.ready }),\n read: async () => {\n if (state.failure !== undefined) throw state.failure;\n await state.ready;\n await state.queue.catch(() => {});\n try {\n const raw = await backend.getItem(storageKey);\n const parsed = await parse(raw, codec);\n state.bytes = raw?.length ?? 0;\n state.record = parsed === null ? null : normalize(parsed, protocol);\n return state.record;\n } catch (cause) {\n const error = wrapStorageError(cause);\n reportError(error);\n throw error;\n }\n },\n load: () => {\n if (state.failure !== undefined) throw state.failure;\n if (!state.hydrated)\n throw new Error(\n \"statewire: await session storage readiness before loading\",\n );\n if (state.asynchronous || state.pending > 0) return state.record;\n let raw: string | null | Promise<string | null>;\n try {\n raw = backend.getItem(storageKey);\n } catch (cause) {\n const error = wrapStorageError(cause);\n reportError(error);\n throw error;\n }\n if (typeof raw !== \"string\" && raw !== null)\n throw new Error(\n \"statewire: storage backend changed from synchronous to asynchronous\",\n );\n try {\n state.record = decode(raw, protocol);\n return state.record;\n } catch (cause) {\n const error = wrapStorageError(cause);\n reportError(error);\n throw error;\n }\n },\n save: (record: StatewireClient.SessionRecord) => {\n if (state.failure !== undefined) throw state.failure;\n if (!state.hydrated)\n throw new Error(\n \"statewire: await session storage readiness before saving\",\n );\n if (!isSessionRecord(record))\n throw new Error(\"statewire: invalid session record\");\n const encoded = JSON.stringify({\n ...record,\n statewireStorageVersion: STORAGE_FORMAT,\n savedAt: Date.now(),\n });\n checkLimits(record, encoded.length);\n if (!state.asynchronous && state.pending === 0) {\n try {\n backend.setItem(storageKey, encoded) as void;\n } catch (error) {\n if (!isQuotaError(error)) {\n state.failure = wrapStorageError(error);\n reportError(state.failure);\n throw state.failure;\n }\n // A write that adds an entry is refused; the rest retry after the sweep.\n if (entryCount(record) > entryCount(state.record)) {\n if (retention !== undefined)\n void sweep(configured, storageKey, true).catch(() => {});\n throw quotaError(\"backend\");\n }\n state.record = record;\n state.bytes = encoded.length;\n state.pending++;\n state.queue = persist(encoded).finally(() => {\n state.pending--;\n });\n state.queue.catch((cause: unknown) => {\n const failure = wrapStorageError(cause);\n if (state.failure !== failure) reportError(failure);\n state.failure = failure;\n });\n return;\n }\n state.record = record;\n state.bytes = encoded.length;\n announce(backend, storageKey);\n return;\n }\n state.record = record;\n state.bytes = encoded.length;\n state.pending++;\n state.queue = state.queue\n .then(() => state.ready)\n .then(() => persist(encoded))\n .catch((cause: unknown) => {\n const error = wrapStorageError(cause);\n if (state.failure !== error) reportError(error);\n state.failure = error;\n throw error;\n })\n .finally(() => {\n state.pending--;\n });\n state.queue.catch(() => {});\n },\n flush: () => {\n if (state.failure !== undefined) throw state.failure;\n if (!state.asynchronous && state.pending === 0) return;\n return (async () => {\n await state.ready;\n for (;;) {\n const queue = state.queue;\n await queue;\n if (queue === state.queue) return;\n }\n })();\n },\n onEvict: ({ reason, dropped }) =>\n reportEvict({ key: storageKey, reason, dropped }),\n ...(migrate === undefined ? {} : { migrate }),\n } satisfies StatewireClient.SessionStorage;\n }, [\n state,\n backend,\n storageKey,\n protocol,\n migrate,\n retention,\n configured,\n codec,\n outboxEntries,\n recordBytes,\n totalBytes,\n reportError,\n reportEvict,\n ]);\n};\n\n/** Persist sessions through a synchronous or asynchronous string storage backend. */\nexport const KeyValueSessionStorage = resource(useKeyValueSessionStorage);\n\nexport namespace KeyValueSessionStorage {\n export type Backend = {\n getItem: (key: string) => string | null | Promise<string | null>;\n setItem: (key: string, value: string) => void | Promise<void>;\n removeItem: (key: string) => void | Promise<void>;\n getAllKeys?: () => readonly string[] | Promise<readonly string[]>;\n /** Runs cleanup under exclusive access, skipping keys in use by another runtime. */\n withUnused?: (key: string, action: () => Promise<void>) => Promise<void>;\n /** Notifies of keys other runtimes wrote; returns unsubscribe. */\n subscribe?: (listener: (key: string) => void) => () => void;\n };\n /** Transforms the stored string, e.g. encryption or compression. */\n export type Codec = {\n encode: (plain: string) => Promise<string>;\n decode: (stored: string) => Promise<string>;\n };\n export type EvictEvent = StatewireClient.EvictEvent;\n export type Options = {\n backend: Backend;\n key: string;\n namespace?: string;\n /** The lane that sessions saved in a single-lane format lift into; defaults to the client's default protocol. */\n protocol?: string;\n migrate?: StatewireClient.SessionStorage[\"migrate\"];\n retention?: { maxAgeMs?: number; maxEntries?: number };\n /** Off by default; a write that adds an entry past one rejects `{ fate: \"aborted\", cause: \"quota\" }`. */\n limits?: {\n outboxEntries?: number;\n recordBytes?: number;\n totalBytes?: number;\n };\n codec?: Codec;\n onError?: (error: unknown) => void;\n /** Reports evicted records and dropped failure notices. */\n onEvict?: (event: EvictEvent) => void;\n };\n}\n\nconst pages = new Map<string, StatewireClient.SessionRecord | null>();\n\nconst useMemorySessionStorage = ({\n scope,\n}: MemorySessionStorage.Options): StatewireClient.SessionStorage =>\n useMemo(\n () => ({\n durable: false,\n load: () => pages.get(scope) ?? null,\n save: (record) => {\n pages.set(scope, record);\n },\n }),\n [scope],\n );\n\n/** Session storage in page memory, keyed by scope: the record and client identity survive remounts, not reloads. */\nexport const MemorySessionStorage = resource(useMemorySessionStorage);\n\nexport namespace MemorySessionStorage {\n export type Options = { scope: string };\n}\n\nconst entriesOf = (\n record: StatewireClient.SessionRecord,\n): StatewireClient.OutboxEntry[] =>\n Object.entries(record.lanes).flatMap(([protocol, lane]) => {\n const view = (\n c: StatewireClient.OutboxCommand | StatewireClient.SessionCommand,\n state: StatewireClient.OutboxState,\n ): StatewireClient.OutboxEntry => ({\n id: c.id,\n protocol,\n command: {\n method: c.method,\n params:\n c.meta === undefined\n ? c.params\n : (reviveValue(structuredClone(c.params), c.meta) as unknown[]),\n },\n ts: c.ts,\n state,\n localMeta: c.localMeta,\n durable: true,\n });\n return [\n ...[...lane.commands]\n .sort((a, b) => a.seq - b.seq)\n .map((c) => view(c, \"sending\")),\n ...(lane.outbox ?? []).map((c) => view(c, c.held ? \"held\" : \"queued\")),\n ];\n });\n\n/** Reads the outboxes of every session under `namespace`, mounted or not. */\nexport const readOutboxes = async (\n backend: KeyValueSessionStorage.Backend,\n options: ReadOutboxes.Options,\n): Promise<readonly ReadOutboxes.Outbox[]> => {\n if (!backend.getAllKeys)\n throw new Error(\"statewire: readOutboxes requires getAllKeys\");\n const { namespace, codec, protocol = DEFAULT_PROTOCOL } = options;\n if (!namespace)\n throw new Error(\"statewire: readOutboxes requires a namespace\");\n const result: ReadOutboxes.Outbox[] = [];\n for (const key of await backend.getAllKeys()) {\n if (!key.startsWith(namespace)) continue;\n const parsed = await parse(await backend.getItem(key), codec);\n if (parsed === null) continue;\n const entries = entriesOf(normalize(parsed, protocol));\n if (entries.length > 0) result.push({ key, entries });\n }\n return result;\n};\n\n/** Calls `listener` with `readOutboxes` now and after every save under `namespace`; returns unsubscribe. */\nexport const subscribeOutboxes = (\n backend: KeyValueSessionStorage.Backend,\n options: ReadOutboxes.Options,\n listener: (outboxes: readonly ReadOutboxes.Outbox[]) => void,\n onError: (error: unknown) => void,\n): (() => void) => {\n let closed = false;\n let reading = Promise.resolve();\n const refresh = () => {\n reading = reading.then(async () => {\n if (closed) return;\n try {\n const outboxes = await readOutboxes(backend, options);\n if (!closed) listener(outboxes);\n } catch (error) {\n onError(error);\n }\n });\n };\n const onKey = (key: string) => {\n if (key.startsWith(options.namespace)) refresh();\n };\n const local = savers.get(backend) ?? new Set();\n savers.set(backend, local);\n local.add(onKey);\n const remote = backend.subscribe?.(onKey);\n refresh();\n return () => {\n closed = true;\n local.delete(onKey);\n remote?.();\n };\n};\n\nexport namespace ReadOutboxes {\n export type Options = {\n namespace: string;\n codec?: KeyValueSessionStorage.Codec;\n /** The lane that single-lane formats lift into. */\n protocol?: string;\n };\n export type Outbox = {\n key: string;\n entries: readonly StatewireClient.OutboxEntry[];\n };\n}\nexport { IndexedDbSession, indexedDbBackend } from \"./indexedDb\";\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/transports/remote.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAiB;AAe1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,6BAA0B;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,wBAAqB;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,iBAAc;AAE9D,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,SAAS;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC,UAAU,KAAK,IAAI,CAAC;IAC5D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB,GAAG,uBAAuB,EAE3B,SAAS,QAAQ,EACjB,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,oBAAoB,KAAK,UAAU,KACpE,SAAS,CAAC,GAAG,EAAE,GAAG,CAmDpB,CAAC"}
1
+ {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/transports/remote.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAiB;AAc1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,6BAA0B;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,wBAAqB;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,iBAAc;AAE9D,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,SAAS;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC,UAAU,KAAK,IAAI,CAAC;IAC5D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB,GAAG,uBAAuB,EAE3B,SAAS,QAAQ,EACjB,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,oBAAoB,KAAK,UAAU,KACpE,SAAS,CAAC,GAAG,EAAE,GAAG,CAmDpB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { LinkContext, ProtocolContext } from "../client/sessionStore.js";
2
- import { discardFailed, documentSource, failedCommands, holdOutbox, invokeProtocol, outboxEntries, releaseOutbox, removeOutbox, retryFailed, setContext, setTransport, useStatewireSession } from "../client/session.js";
2
+ import { documentSource, holdOutbox, insertOutbox, invokeProtocol, outboxEntries, releaseOutbox, removeOutbox, setContext, setTransport, updateOutbox, useStatewireSession } from "../client/session.js";
3
3
  import { useContext, useEffect, useMemo } from "@assistant-ui/tap/react-shim";
4
4
  // src/transports/remote.ts
5
5
  const useStatewireRemote = (options, useLink) => {
@@ -15,16 +15,14 @@ const useStatewireRemote = (options, useLink) => {
15
15
  documents: documentSource(s),
16
16
  setContext: (protocol, value) => setContext(s, protocol, value),
17
17
  invoke: (protocol_0, method, params, options_0) => invokeProtocol(s, protocol_0, method, params, options_0),
18
- failures: {
19
- list: () => failedCommands(s),
20
- retry: (entry) => retryFailed(s, entry),
21
- discard: (entry_0) => discardFailed(s, entry_0)
22
- },
23
18
  outbox: {
24
19
  list: () => outboxEntries(s),
25
- hold: (entry_1, meta) => holdOutbox(s, entry_1, meta),
26
- release: (entry_2) => releaseOutbox(s, entry_2),
27
- remove: (entry_3) => removeOutbox(s, entry_3)
20
+ clientId: () => s.record.clientId,
21
+ hold: (id) => holdOutbox(s, id),
22
+ release: (id_0) => releaseOutbox(s, id_0),
23
+ remove: (id_1) => removeOutbox(s, id_1),
24
+ update: (id_2, fn) => updateOutbox(s, id_2, fn),
25
+ insert: (entry) => insertOutbox(s, entry)
28
26
  }
29
27
  }), [s]);
30
28
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"remote.js","names":["useContext","useEffect","useMemo","LinkContext","ProtocolContext","Statewire","documentSource","invokeProtocol","discardFailed","failedCommands","holdOutbox","outboxEntries","releaseOutbox","removeOutbox","retryFailed","setTransport","useStatewireSession","setContext","StatewireSessionOptions","StatewireClient","RemoteLink","StatewireRemoteProps","useStatewireRemote","url","onChange","connection","Connection","onDone","options","TOptions","useLink","ctx","configured","s","conn","lanes","documents","protocol","value","Context","invoke","method","params","InvokeOptions","failures","list","retry","entry","FailedCommand","discard","outbox","hold","OutboxEntry","meta","release","remove","state","canonical","selection","commands","source","isBusy","idle"],"sources":["../../src/transports/remote.ts"],"sourcesContent":["import { useContext, useEffect, useMemo } from \"react\";\nimport { LinkContext, ProtocolContext } from \"../client/sessionStore\";\nimport type { Statewire } from \"../types\";\nimport {\n documentSource,\n invokeProtocol,\n discardFailed,\n failedCommands,\n holdOutbox,\n outboxEntries,\n releaseOutbox,\n removeOutbox,\n retryFailed,\n setTransport,\n useStatewireSession,\n setContext,\n} from \"../client/session\";\nimport type { StatewireSessionOptions } from \"../client/session\";\nimport type { StatewireClient } from \"../statewire\";\nimport type { RemoteLink, StatewireRemoteProps } from \"./sse\";\n\nexport const useStatewireRemote = <\n TOptions extends {\n url: string;\n onChange?: (connection: StatewireClient.Connection) => void;\n onDone?: () => void;\n } & StatewireSessionOptions,\n>(\n options: TOptions,\n useLink: (options: TOptions, ctx: StatewireRemoteProps) => RemoteLink,\n): Statewire<any, any> => {\n const configured = {\n ...useContext(ProtocolContext),\n ...useContext(LinkContext),\n ...options,\n };\n const s = useStatewireSession(configured);\n const conn = useLink(configured, s.ctx);\n useEffect(() => setTransport(s, conn), [s, conn]);\n const lanes = useMemo(\n () => ({\n documents: documentSource(s),\n setContext: (protocol: string, value: Statewire.Context) =>\n setContext(s, protocol, value),\n invoke: (\n protocol: string,\n method: string,\n params: readonly unknown[],\n options?: StatewireClient.InvokeOptions,\n ) => invokeProtocol(s, protocol, method, params, options),\n failures: {\n list: () => failedCommands(s),\n retry: (entry: StatewireClient.FailedCommand) => retryFailed(s, entry),\n discard: (entry: StatewireClient.FailedCommand) =>\n discardFailed(s, entry),\n },\n outbox: {\n list: () => outboxEntries(s),\n hold: (entry: StatewireClient.OutboxEntry, meta?: unknown) =>\n holdOutbox(s, entry, meta),\n release: (entry: StatewireClient.OutboxEntry) =>\n releaseOutbox(s, entry),\n remove: (entry: StatewireClient.OutboxEntry) => removeOutbox(s, entry),\n },\n }),\n [s],\n );\n\n return {\n state: s.canonical,\n ...lanes,\n get selection() {\n return s.selection;\n },\n commands: s.commands,\n connection: conn.connection,\n source: s.source,\n get isBusy() {\n return !s.idle;\n },\n };\n};\n"],"mappings":";;;;AAqBA,MAAasB,sBAOXM,SACAE,YACwB;CACxB,MAAME,aAAa;EACjB,GAAGhC,WAAWI,eAAe;EAC7B,GAAGJ,WAAWG,WAAW;EACzB,GAAGyB;CACL;CACA,MAAMK,IAAIjB,oBAAoBgB,UAAU;CACxC,MAAME,OAAOJ,QAAQE,YAAYC,EAAEF,GAAG;CACtC9B,gBAAgBc,aAAakB,GAAGC,IAAI,GAAG,CAACD,GAAGC,IAAI,CAAC;CAChD,MAAMC,QAAQjC,eACL;EACLkC,WAAW9B,eAAe2B,CAAC;EAC3BhB,aAAaoB,UAAkBC,UAC7BrB,WAAWgB,GAAGI,UAAUC,KAAK;EAC/BE,SACEH,YACAI,QACAC,QACAd,cACGrB,eAAe0B,GAAGI,YAAUI,QAAQC,QAAQd,SAAO;EACxDgB,UAAU;GACRC,YAAYpC,eAAewB,CAAC;GAC5Ba,QAAQC,UAAyCjC,YAAYmB,GAAGc,KAAK;GACrEE,UAAUF,YACRvC,cAAcyB,GAAGc,OAAK;EAC1B;EACAG,QAAQ;GACNL,YAAYlC,cAAcsB,CAAC;GAC3BkB,OAAOJ,SAAoCM,SACzC3C,WAAWuB,GAAGc,SAAOM,IAAI;GAC3BC,UAAUP,YACRnC,cAAcqB,GAAGc,OAAK;GACxBQ,SAASR,YAAuClC,aAAaoB,GAAGc,OAAK;EACvE;CACF,IACA,CAACd,CAAC,CACJ;CAEA,OAAO;EACLuB,OAAOvB,EAAEwB;EACT,GAAGtB;EACH,IAAIuB,YAAY;GACd,OAAOzB,EAAEyB;EACX;EACAC,UAAU1B,EAAE0B;EACZlC,YAAYS,KAAKT;EACjBmC,QAAQ3B,EAAE2B;EACV,IAAIC,SAAS;GACX,OAAO,CAAC5B,EAAE6B;EACZ;CACF;AACF"}
1
+ {"version":3,"file":"remote.js","names":["useContext","useEffect","useMemo","LinkContext","ProtocolContext","Statewire","documentSource","invokeProtocol","holdOutbox","insertOutbox","outboxEntries","releaseOutbox","removeOutbox","updateOutbox","setTransport","useStatewireSession","setContext","StatewireSessionOptions","StatewireClient","RemoteLink","StatewireRemoteProps","useStatewireRemote","url","onChange","connection","Connection","onDone","options","TOptions","useLink","ctx","configured","s","conn","lanes","documents","protocol","value","Context","invoke","method","params","InvokeOptions","outbox","list","clientId","record","hold","id","release","remove","update","fn","entry","OutboxEntry","OutboxPatch","insert","OutboxInsert","state","canonical","selection","commands","source","isBusy","idle"],"sources":["../../src/transports/remote.ts"],"sourcesContent":["import { useContext, useEffect, useMemo } from \"react\";\nimport { LinkContext, ProtocolContext } from \"../client/sessionStore\";\nimport type { Statewire } from \"../types\";\nimport {\n documentSource,\n invokeProtocol,\n holdOutbox,\n insertOutbox,\n outboxEntries,\n releaseOutbox,\n removeOutbox,\n updateOutbox,\n setTransport,\n useStatewireSession,\n setContext,\n} from \"../client/session\";\nimport type { StatewireSessionOptions } from \"../client/session\";\nimport type { StatewireClient } from \"../statewire\";\nimport type { RemoteLink, StatewireRemoteProps } from \"./sse\";\n\nexport const useStatewireRemote = <\n TOptions extends {\n url: string;\n onChange?: (connection: StatewireClient.Connection) => void;\n onDone?: () => void;\n } & StatewireSessionOptions,\n>(\n options: TOptions,\n useLink: (options: TOptions, ctx: StatewireRemoteProps) => RemoteLink,\n): Statewire<any, any> => {\n const configured = {\n ...useContext(ProtocolContext),\n ...useContext(LinkContext),\n ...options,\n };\n const s = useStatewireSession(configured);\n const conn = useLink(configured, s.ctx);\n useEffect(() => setTransport(s, conn), [s, conn]);\n const lanes = useMemo(\n () => ({\n documents: documentSource(s),\n setContext: (protocol: string, value: Statewire.Context) =>\n setContext(s, protocol, value),\n invoke: (\n protocol: string,\n method: string,\n params: readonly unknown[],\n options?: StatewireClient.InvokeOptions,\n ) => invokeProtocol(s, protocol, method, params, options),\n outbox: {\n list: () => outboxEntries(s),\n clientId: () => s.record.clientId,\n hold: (id: string) => holdOutbox(s, id),\n release: (id: string) => releaseOutbox(s, id),\n remove: (id: string) => removeOutbox(s, id),\n update: (\n id: string,\n fn: (\n entry: StatewireClient.OutboxEntry,\n ) => StatewireClient.OutboxPatch,\n ) => updateOutbox(s, id, fn),\n insert: (entry: StatewireClient.OutboxInsert) => insertOutbox(s, entry),\n },\n }),\n [s],\n );\n\n return {\n state: s.canonical,\n ...lanes,\n get selection() {\n return s.selection;\n },\n commands: s.commands,\n connection: conn.connection,\n source: s.source,\n get isBusy() {\n return !s.idle;\n },\n };\n};\n"],"mappings":";;;;AAoBA,MAAaqB,sBAOXM,SACAE,YACwB;CACxB,MAAME,aAAa;EACjB,GAAG/B,WAAWI,eAAe;EAC7B,GAAGJ,WAAWG,WAAW;EACzB,GAAGwB;CACL;CACA,MAAMK,IAAIjB,oBAAoBgB,UAAU;CACxC,MAAME,OAAOJ,QAAQE,YAAYC,EAAEF,GAAG;CACtC7B,gBAAgBa,aAAakB,GAAGC,IAAI,GAAG,CAACD,GAAGC,IAAI,CAAC;CAChD,MAAMC,QAAQhC,eACL;EACLiC,WAAW7B,eAAe0B,CAAC;EAC3BhB,aAAaoB,UAAkBC,UAC7BrB,WAAWgB,GAAGI,UAAUC,KAAK;EAC/BE,SACEH,YACAI,QACAC,QACAd,cACGpB,eAAeyB,GAAGI,YAAUI,QAAQC,QAAQd,SAAO;EACxDgB,QAAQ;GACNC,YAAYlC,cAAcsB,CAAC;GAC3Ba,gBAAgBb,EAAEc,OAAOD;GACzBE,OAAOC,OAAexC,WAAWwB,GAAGgB,EAAE;GACtCC,UAAUD,SAAerC,cAAcqB,GAAGgB,IAAE;GAC5CE,SAASF,SAAepC,aAAaoB,GAAGgB,IAAE;GAC1CG,SACEH,MACAI,OAGGvC,aAAamB,GAAGgB,MAAII,EAAE;GAC3BI,SAASH,UAAwC5C,aAAauB,GAAGqB,KAAK;EACxE;CACF,IACA,CAACrB,CAAC,CACJ;CAEA,OAAO;EACL0B,OAAO1B,EAAE2B;EACT,GAAGzB;EACH,IAAI0B,YAAY;GACd,OAAO5B,EAAE4B;EACX;EACAC,UAAU7B,EAAE6B;EACZrC,YAAYS,KAAKT;EACjBsC,QAAQ9B,EAAE8B;EACV,IAAIC,SAAS;GACX,OAAO,CAAC/B,EAAEgC;EACZ;CACF;AACF"}
package/dist/types.d.ts CHANGED
@@ -27,6 +27,8 @@ export declare namespace Statewire {
27
27
  status: "queued" | "posted" | "applied" | "settled";
28
28
  result?: unknown;
29
29
  failure?: StatewireClient.SendFailure;
30
+ /** The command's client-only `localMeta`. */
31
+ localMeta?: unknown;
30
32
  };
31
33
  }[keyof TCommands];
32
34
  /** Push-based canonical state feed a statewire hands to the client core. */
@@ -74,18 +76,15 @@ export interface Statewire<TState = any, TCommands extends Statewire.Commands =
74
76
  attaching?: (attach: StatewireHost.Attach) => void;
75
77
  /** Called by the serving host when an attach ends; its ephemeral documents and includes are gone. */
76
78
  detached?: (attach: StatewireHost.Attach) => void;
77
- /** The retained failed-send lane; present on transports with a durable session. */
78
- failures?: {
79
- list: () => readonly StatewireClient.FailedCommand[];
80
- retry: (entry: StatewireClient.FailedCommand) => Promise<unknown>;
81
- discard: (entry: StatewireClient.FailedCommand) => void;
82
- };
83
- /** The outbox of commands without a seq; present on transports with a durable session. */
79
+ /** The outbox; present on transports with a durable session. */
84
80
  outbox?: {
85
81
  list: () => readonly StatewireClient.OutboxEntry[];
82
+ clientId: () => string;
86
83
  hold: StatewireClient.Outbox["hold"];
87
84
  release: StatewireClient.Outbox["release"];
88
85
  remove: StatewireClient.Outbox["remove"];
86
+ update: StatewireClient.Outbox["update"];
87
+ insert: StatewireClient.Outbox["insert"];
89
88
  };
90
89
  }
91
90
  export declare class StatewireSendError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":["StatewireDocuments","StatewireHost","StatewireProtocol","StatewireClient","StatewirePath","Statewire","Context","Readonly","Record","Commands","args","Command","TCommands","method","K","params","Parameters","CommandsProxy","Promise","Awaited","ReturnType","CommandUpdate","protocol","id","seq","status","result","failure","SendFailure","StateSource","snapshot","takeChanged","setOnChange","listener","Op","op","path","value","Changes","isChangedAt","getChangedKeys","state","TState","documents","Source","selection","Selection","setContext","validateContext","attach","Attach","contextChanged","invoke","options","InvokeOptions","commands","connection","Connection","source","isBusy","work","isIdle","attaching","detached","failures","list","FailedCommand","retry","entry","discard","outbox","OutboxEntry","hold","Outbox","release","remove","describe","fate","code","message","cause","StatewireSendError","Error","constructor","name"],"sources":["../src/types.ts"],"sourcesContent":["import type { StatewireDocuments } from \"./wire/documents\";\nimport type { StatewireHost } from \"./host\";\nimport type { StatewireProtocol } from \"./wire/protocol\";\nimport type { StatewireClient } from \"./statewire\";\nimport type { StatewirePath } from \"./wire/ops\";\n\nexport namespace Statewire {\n export type Context = Readonly<Record<string, unknown>>;\n export type Commands = Record<string, (...args: never[]) => unknown>;\n\n export type Command<TCommands extends Commands = Commands> = {\n [K in keyof TCommands]: { method: K; params: Parameters<TCommands[K]> };\n }[keyof TCommands];\n\n export type CommandsProxy<TCommands extends Commands> = {\n [K in keyof TCommands]: (\n ...args: Parameters<TCommands[K]>\n ) => Promise<Awaited<ReturnType<TCommands[K]>>>;\n };\n\n export type CommandUpdate<TCommands extends Commands = Commands> = {\n [K in keyof TCommands]: {\n readonly protocol?: string;\n /** The command's client id (remote transports). */\n id?: string;\n method: K;\n params: Parameters<TCommands[K]>;\n /** Absent while queued in the outbox. */\n seq?: number;\n status: \"queued\" | \"posted\" | \"applied\" | \"settled\";\n result?: unknown;\n failure?: StatewireClient.SendFailure;\n };\n }[keyof TCommands];\n\n /** Push-based canonical state feed a statewire hands to the client core. */\n export type StateSource = {\n snapshot: () => unknown;\n /** Drain the paths changed since the last take (`[]` entry = whole state). */\n takeChanged: () => StatewirePath[];\n /** Synchronous, per change; the consumer owns coalescing. */\n setOnChange: (listener: (() => void) | null) => void;\n };\n\n export type Op =\n | { op: \"replace\"; path: StatewirePath; value: unknown }\n | { op: \"add\"; path: StatewirePath; value: unknown }\n | { op: \"remove\"; path: StatewirePath };\n\n export type Changes = {\n isChangedAt(path: readonly (string | number)[]): boolean;\n getChangedKeys(path: readonly (string | number)[]): string[];\n };\n}\n\nexport interface Statewire<\n TState = any,\n TCommands extends Statewire.Commands = Statewire.Commands,\n> {\n state: TState;\n documents?: StatewireDocuments.Source;\n selection?: StatewireProtocol.Selection | undefined;\n setContext?: (protocol: string, value: Statewire.Context) => void;\n validateContext?: (\n protocol: string,\n value: Statewire.Context,\n attach: StatewireHost.Attach,\n ) => void;\n contextChanged?: (\n protocol: string,\n value: Statewire.Context,\n attach: StatewireHost.Attach,\n ) => void;\n invoke?: (\n protocol: string,\n method: string,\n params: readonly unknown[],\n options?: StatewireClient.InvokeOptions,\n ) => Promise<unknown>;\n commands: Statewire.CommandsProxy<TCommands>;\n connection?: StatewireClient.Connection;\n source?: Statewire.StateSource;\n /** Negation of the server's broadcast idle level; absent means always busy. */\n isBusy?: boolean;\n work?: { readonly isIdle: boolean };\n /** Called by the serving host once an attach is registered, before its hello: documents mounted here ride the hello. */\n attaching?: (attach: StatewireHost.Attach) => void;\n /** Called by the serving host when an attach ends; its ephemeral documents and includes are gone. */\n detached?: (attach: StatewireHost.Attach) => void;\n /** The retained failed-send lane; present on transports with a durable session. */\n failures?: {\n list: () => readonly StatewireClient.FailedCommand[];\n retry: (entry: StatewireClient.FailedCommand) => Promise<unknown>;\n discard: (entry: StatewireClient.FailedCommand) => void;\n };\n /** The outbox of commands without a seq; present on transports with a durable session. */\n outbox?: {\n list: () => readonly StatewireClient.OutboxEntry[];\n hold: StatewireClient.Outbox[\"hold\"];\n release: StatewireClient.Outbox[\"release\"];\n remove: StatewireClient.Outbox[\"remove\"];\n };\n}\n\nconst describe = (failure: StatewireClient.SendFailure): string => {\n switch (failure.fate) {\n case \"rejected\":\n return `statewire: command rejected${failure.code ? ` (${failure.code})` : \"\"}${failure.message ? `: ${failure.message}` : \"\"}`;\n case \"aborted\":\n return `statewire: command aborted (${failure.cause})`;\n case \"lost\":\n return `statewire: command lost (${failure.cause})`;\n case \"failed\":\n return failure.message\n ? `statewire: command failed: ${failure.message}`\n : \"statewire: command failed\";\n case \"crashed\":\n return \"statewire: command crashed\";\n case \"expired\":\n return `statewire: command result expired (${failure.cause})`;\n }\n};\n\nexport class StatewireSendError extends Error {\n readonly failure: StatewireClient.SendFailure;\n\n constructor(failure: StatewireClient.SendFailure) {\n super(describe(failure));\n this.name = \"StatewireSendError\";\n this.failure = failure;\n }\n}\n"],"mappings":";AAwGA,MAAM4E,YAAYjD,YAAiD;CACjE,QAAQA,QAAQkD,MAAhB;EACE,KAAK,YACH,OAAO,8BAA8BlD,QAAQmD,OAAO,KAAKnD,QAAQmD,KAAI,KAAM,KAAKnD,QAAQoD,UAAU,KAAKpD,QAAQoD,YAAY;EAC7H,KAAK,WACH,OAAO,+BAA+BpD,QAAQqD,MAAK;EACrD,KAAK,QACH,OAAO,4BAA4BrD,QAAQqD,MAAK;EAClD,KAAK,UACH,OAAOrD,QAAQoD,UACX,8BAA8BpD,QAAQoD,YACtC;EACN,KAAK,WACH,OAAO;EACT,KAAK,WACH,OAAO,sCAAsCpD,QAAQqD,MAAK;CAC9D;AACF;AAEA,IAAaC,qBAAb,cAAwCC,MAAM;CAC5C;CAEAC,YAAYxD,SAAsC;EAChD,MAAMiD,SAASjD,OAAO,CAAC;EACvB,KAAKyD,OAAO;EACZ,KAAKzD,UAAUA;CACjB;AACF"}
1
+ {"version":3,"file":"types.js","names":["StatewireDocuments","StatewireHost","StatewireProtocol","StatewireClient","StatewirePath","Statewire","Context","Readonly","Record","Commands","args","Command","TCommands","method","K","params","Parameters","CommandsProxy","Promise","Awaited","ReturnType","CommandUpdate","protocol","id","seq","status","result","failure","SendFailure","localMeta","StateSource","snapshot","takeChanged","setOnChange","listener","Op","op","path","value","Changes","isChangedAt","getChangedKeys","state","TState","documents","Source","selection","Selection","setContext","validateContext","attach","Attach","contextChanged","invoke","options","InvokeOptions","commands","connection","Connection","source","isBusy","work","isIdle","attaching","detached","outbox","list","OutboxEntry","clientId","hold","Outbox","release","remove","update","insert","describe","fate","code","message","cause","StatewireSendError","Error","constructor","name"],"sources":["../src/types.ts"],"sourcesContent":["import type { StatewireDocuments } from \"./wire/documents\";\nimport type { StatewireHost } from \"./host\";\nimport type { StatewireProtocol } from \"./wire/protocol\";\nimport type { StatewireClient } from \"./statewire\";\nimport type { StatewirePath } from \"./wire/ops\";\n\nexport namespace Statewire {\n export type Context = Readonly<Record<string, unknown>>;\n export type Commands = Record<string, (...args: never[]) => unknown>;\n\n export type Command<TCommands extends Commands = Commands> = {\n [K in keyof TCommands]: { method: K; params: Parameters<TCommands[K]> };\n }[keyof TCommands];\n\n export type CommandsProxy<TCommands extends Commands> = {\n [K in keyof TCommands]: (\n ...args: Parameters<TCommands[K]>\n ) => Promise<Awaited<ReturnType<TCommands[K]>>>;\n };\n\n export type CommandUpdate<TCommands extends Commands = Commands> = {\n [K in keyof TCommands]: {\n readonly protocol?: string;\n /** The command's client id (remote transports). */\n id?: string;\n method: K;\n params: Parameters<TCommands[K]>;\n /** Absent while queued in the outbox. */\n seq?: number;\n status: \"queued\" | \"posted\" | \"applied\" | \"settled\";\n result?: unknown;\n failure?: StatewireClient.SendFailure;\n /** The command's client-only `localMeta`. */\n localMeta?: unknown;\n };\n }[keyof TCommands];\n\n /** Push-based canonical state feed a statewire hands to the client core. */\n export type StateSource = {\n snapshot: () => unknown;\n /** Drain the paths changed since the last take (`[]` entry = whole state). */\n takeChanged: () => StatewirePath[];\n /** Synchronous, per change; the consumer owns coalescing. */\n setOnChange: (listener: (() => void) | null) => void;\n };\n\n export type Op =\n | { op: \"replace\"; path: StatewirePath; value: unknown }\n | { op: \"add\"; path: StatewirePath; value: unknown }\n | { op: \"remove\"; path: StatewirePath };\n\n export type Changes = {\n isChangedAt(path: readonly (string | number)[]): boolean;\n getChangedKeys(path: readonly (string | number)[]): string[];\n };\n}\n\nexport interface Statewire<\n TState = any,\n TCommands extends Statewire.Commands = Statewire.Commands,\n> {\n state: TState;\n documents?: StatewireDocuments.Source;\n selection?: StatewireProtocol.Selection | undefined;\n setContext?: (protocol: string, value: Statewire.Context) => void;\n validateContext?: (\n protocol: string,\n value: Statewire.Context,\n attach: StatewireHost.Attach,\n ) => void;\n contextChanged?: (\n protocol: string,\n value: Statewire.Context,\n attach: StatewireHost.Attach,\n ) => void;\n invoke?: (\n protocol: string,\n method: string,\n params: readonly unknown[],\n options?: StatewireClient.InvokeOptions,\n ) => Promise<unknown>;\n commands: Statewire.CommandsProxy<TCommands>;\n connection?: StatewireClient.Connection;\n source?: Statewire.StateSource;\n /** Negation of the server's broadcast idle level; absent means always busy. */\n isBusy?: boolean;\n work?: { readonly isIdle: boolean };\n /** Called by the serving host once an attach is registered, before its hello: documents mounted here ride the hello. */\n attaching?: (attach: StatewireHost.Attach) => void;\n /** Called by the serving host when an attach ends; its ephemeral documents and includes are gone. */\n detached?: (attach: StatewireHost.Attach) => void;\n /** The outbox; present on transports with a durable session. */\n outbox?: {\n list: () => readonly StatewireClient.OutboxEntry[];\n clientId: () => string;\n hold: StatewireClient.Outbox[\"hold\"];\n release: StatewireClient.Outbox[\"release\"];\n remove: StatewireClient.Outbox[\"remove\"];\n update: StatewireClient.Outbox[\"update\"];\n insert: StatewireClient.Outbox[\"insert\"];\n };\n}\n\nconst describe = (failure: StatewireClient.SendFailure): string => {\n switch (failure.fate) {\n case \"rejected\":\n return `statewire: command rejected${failure.code ? ` (${failure.code})` : \"\"}${failure.message ? `: ${failure.message}` : \"\"}`;\n case \"aborted\":\n return `statewire: command aborted (${failure.cause})`;\n case \"lost\":\n return `statewire: command lost (${failure.cause})`;\n case \"failed\":\n return failure.message\n ? `statewire: command failed: ${failure.message}`\n : \"statewire: command failed\";\n case \"crashed\":\n return \"statewire: command crashed\";\n case \"expired\":\n return `statewire: command result expired (${failure.cause})`;\n }\n};\n\nexport class StatewireSendError extends Error {\n readonly failure: StatewireClient.SendFailure;\n\n constructor(failure: StatewireClient.SendFailure) {\n super(describe(failure));\n this.name = \"StatewireSendError\";\n this.failure = failure;\n }\n}\n"],"mappings":";AAuGA,MAAM2E,YAAYhD,YAAiD;CACjE,QAAQA,QAAQiD,MAAhB;EACE,KAAK,YACH,OAAO,8BAA8BjD,QAAQkD,OAAO,KAAKlD,QAAQkD,KAAI,KAAM,KAAKlD,QAAQmD,UAAU,KAAKnD,QAAQmD,YAAY;EAC7H,KAAK,WACH,OAAO,+BAA+BnD,QAAQoD,MAAK;EACrD,KAAK,QACH,OAAO,4BAA4BpD,QAAQoD,MAAK;EAClD,KAAK,UACH,OAAOpD,QAAQmD,UACX,8BAA8BnD,QAAQmD,YACtC;EACN,KAAK,WACH,OAAO;EACT,KAAK,WACH,OAAO,sCAAsCnD,QAAQoD,MAAK;CAC9D;AACF;AAEA,IAAaC,qBAAb,cAAwCC,MAAM;CAC5C;CAEAC,YAAYvD,SAAsC;EAChD,MAAMgD,SAAShD,OAAO,CAAC;EACvB,KAAKwD,OAAO;EACZ,KAAKxD,UAAUA;CACjB;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "statewire",
3
- "version": "0.23.0",
3
+ "version": "0.24.1",
4
4
  "description": "State over the wire: snapshot-first delta streaming and command submission for any state and any command",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -58,6 +58,7 @@
58
58
  "@types/react": "^19.3.0",
59
59
  "@vitest/coverage-v8": "^5.0.5",
60
60
  "babel-plugin-react-compiler": "^1.0.0",
61
+ "fake-indexeddb": "6.2.5",
61
62
  "react": "^19.3.1",
62
63
  "vitest": "^5.0.5"
63
64
  }