statewire 0.21.0 → 0.22.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 (134) hide show
  1. package/dist/client/changes.d.ts +3 -6
  2. package/dist/client/changes.d.ts.map +1 -1
  3. package/dist/client/changes.js +1 -2
  4. package/dist/client/connection.d.ts +80 -83
  5. package/dist/client/connection.d.ts.map +1 -1
  6. package/dist/client/connection.js +2 -3
  7. package/dist/client/connection.js.map +1 -1
  8. package/dist/client/core.d.ts +39 -41
  9. package/dist/client/core.d.ts.map +1 -1
  10. package/dist/client/core.js +2 -3
  11. package/dist/client/session.d.ts +93 -95
  12. package/dist/client/session.d.ts.map +1 -1
  13. package/dist/client/session.js +6 -7
  14. package/dist/client/session.js.map +1 -1
  15. package/dist/client/sessionStore.d.ts +11 -14
  16. package/dist/client/sessionStore.d.ts.map +1 -1
  17. package/dist/client/sessionStore.js +1 -2
  18. package/dist/client/storageError.d.ts +2 -5
  19. package/dist/client/storageError.d.ts.map +1 -1
  20. package/dist/client/storageError.js +1 -2
  21. package/dist/client/timing.d.ts +11 -14
  22. package/dist/client/timing.d.ts.map +1 -1
  23. package/dist/client/timing.js +1 -2
  24. package/dist/document.d.ts +17 -20
  25. package/dist/document.d.ts.map +1 -1
  26. package/dist/document.js +1 -2
  27. package/dist/host/adapter.d.ts +4 -7
  28. package/dist/host/adapter.d.ts.map +1 -1
  29. package/dist/host/adapter.js +1 -2
  30. package/dist/host/draft.d.ts +13 -16
  31. package/dist/host/draft.d.ts.map +1 -1
  32. package/dist/host/draft.js +1 -2
  33. package/dist/host/engine.d.ts +7 -10
  34. package/dist/host/engine.d.ts.map +1 -1
  35. package/dist/host/engine.js +1 -2
  36. package/dist/host/host.d.ts +42 -45
  37. package/dist/host/host.d.ts.map +1 -1
  38. package/dist/host/host.js +1 -2
  39. package/dist/host/http.d.ts +4 -7
  40. package/dist/host/http.d.ts.map +1 -1
  41. package/dist/host/http.js +2 -3
  42. package/dist/host/socket.d.ts +148 -145
  43. package/dist/host/socket.d.ts.map +1 -1
  44. package/dist/host/socket.js +30 -12
  45. package/dist/host/socket.js.map +1 -1
  46. package/dist/host/synced.d.ts +3 -6
  47. package/dist/host/synced.d.ts.map +1 -1
  48. package/dist/host/synced.js +1 -2
  49. package/dist/host/work.d.ts +2 -5
  50. package/dist/host/work.d.ts.map +1 -1
  51. package/dist/host/work.js +1 -2
  52. package/dist/host-internal.d.ts +101 -93
  53. package/dist/host-internal.d.ts.map +1 -1
  54. package/dist/host.d.ts +90 -91
  55. package/dist/host.d.ts.map +1 -1
  56. package/dist/index.d.ts +11 -8
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +1 -1
  59. package/dist/statewire.d.ts +265 -268
  60. package/dist/statewire.d.ts.map +1 -1
  61. package/dist/statewire.js +1 -2
  62. package/dist/storage.d.ts +23 -26
  63. package/dist/storage.d.ts.map +1 -1
  64. package/dist/storage.js +1 -2
  65. package/dist/transports/fake-sse.d.ts +7 -10
  66. package/dist/transports/fake-sse.d.ts.map +1 -1
  67. package/dist/transports/fake-sse.js +1 -2
  68. package/dist/transports/fixtures.d.ts +19 -25
  69. package/dist/transports/fixtures.d.ts.map +1 -1
  70. package/dist/transports/fixtures.js +1 -2
  71. package/dist/transports/remote.d.ts +8 -11
  72. package/dist/transports/remote.d.ts.map +1 -1
  73. package/dist/transports/remote.js +1 -2
  74. package/dist/transports/sse-parser.d.ts +1 -4
  75. package/dist/transports/sse-parser.d.ts.map +1 -1
  76. package/dist/transports/sse-parser.js +1 -2
  77. package/dist/transports/sse.d.ts +50 -53
  78. package/dist/transports/sse.d.ts.map +1 -1
  79. package/dist/transports/sse.js +2 -3
  80. package/dist/transports/testing.d.ts +31 -34
  81. package/dist/transports/testing.d.ts.map +1 -1
  82. package/dist/transports/testing.js +1 -2
  83. package/dist/transports/ws.d.ts +5 -7
  84. package/dist/transports/ws.d.ts.map +1 -1
  85. package/dist/transports/ws.js +3 -4
  86. package/dist/transports/ws.js.map +1 -1
  87. package/dist/types.d.ts +81 -78
  88. package/dist/types.d.ts.map +1 -1
  89. package/dist/types.js +1 -2
  90. package/dist/util/draftTraps.d.ts +2 -4
  91. package/dist/util/draftTraps.d.ts.map +1 -1
  92. package/dist/util/draftTraps.js +1 -2
  93. package/dist/util/macrotask.d.ts +1 -4
  94. package/dist/util/macrotask.d.ts.map +1 -1
  95. package/dist/util/macrotask.js +1 -2
  96. package/dist/util/methodProxy.d.ts +1 -4
  97. package/dist/util/methodProxy.d.ts.map +1 -1
  98. package/dist/util/methodProxy.js +1 -2
  99. package/dist/util/randomId.d.ts +1 -4
  100. package/dist/util/randomId.d.ts.map +1 -1
  101. package/dist/util/randomId.js +1 -2
  102. package/dist/util/recordMutations.d.ts +5 -7
  103. package/dist/util/recordMutations.d.ts.map +1 -1
  104. package/dist/util/recordMutations.js +1 -2
  105. package/dist/util/statePath.d.ts +9 -12
  106. package/dist/util/statePath.d.ts.map +1 -1
  107. package/dist/util/statePath.js +1 -2
  108. package/dist/wire/context.d.ts +7 -12
  109. package/dist/wire/context.d.ts.map +1 -1
  110. package/dist/wire/context.js +2 -3
  111. package/dist/wire/documents.d.ts +36 -39
  112. package/dist/wire/documents.d.ts.map +1 -1
  113. package/dist/wire/documents.js +2 -3
  114. package/dist/wire/documents.js.map +1 -1
  115. package/dist/wire/limits.d.ts +7 -10
  116. package/dist/wire/limits.d.ts.map +1 -1
  117. package/dist/wire/limits.js +1 -2
  118. package/dist/wire/meta.d.ts +9 -11
  119. package/dist/wire/meta.d.ts.map +1 -1
  120. package/dist/wire/meta.js +1 -2
  121. package/dist/wire/meta.js.map +1 -1
  122. package/dist/wire/ops.d.ts +9 -12
  123. package/dist/wire/ops.d.ts.map +1 -1
  124. package/dist/wire/ops.js +1 -2
  125. package/dist/wire/protocol.d.ts +53 -56
  126. package/dist/wire/protocol.d.ts.map +1 -1
  127. package/dist/wire/protocol.js +1 -2
  128. package/dist/wire/version.d.ts +1 -4
  129. package/dist/wire/version.d.ts.map +1 -1
  130. package/dist/wire/version.js +1 -2
  131. package/package.json +6 -6
  132. package/src/client/connection.ts +13 -15
  133. package/src/host/socket.ts +63 -6
  134. package/src/host-internal.ts +12 -0
@@ -1,7 +1,7 @@
1
- import { reviveDocumentValue } from "../document.js";
2
1
  import { protocolToken } from "./protocol.js";
2
+ import { reviveDocumentValue } from "../document.js";
3
3
  import { applyOps } from "./ops.js";
4
- //#region src/wire/documents.ts
4
+ // src/wire/documents.ts
5
5
  const invalid = (message) => {
6
6
  throw new Error(`statewire: protocol error: ${message}`);
7
7
  };
@@ -88,7 +88,6 @@ const findDocument = (state, protocol, key, prefix) => {
88
88
  const resolved = resolveDocumentKey(key, prefix);
89
89
  return [...state.documents.values()].find((document) => document.protocol === protocol && document.key !== null && (JSON.stringify(document.key) === JSON.stringify(key) || resolved !== void 0 && JSON.stringify(resolveDocumentKey(document.key, prefix)) === JSON.stringify(resolved)));
90
90
  };
91
- //#endregion
92
91
  export { applyDocumentOps, findDocument, mainDocument, resolveDocumentKey };
93
92
 
94
93
  //# sourceMappingURL=documents.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"documents.js","names":["applyOps","reviveValue","protocolToken","StatewirePath","StatewireDocuments","CacheEntry","version","value","Storage","namespace","load","identity","save","entry","subscribe","listener","Source","get","protocol","key","prefix","list","ReadonlyMap","Document","main","State","mode","documents","invalid","message","Error","applyDocumentOps","previous","ops","protocols","name","strict","undefined","length","Map","changedPaths","raw","Array","isArray","op","Record","doc","Number","isSafeInteger","includes","_doc","unknown","path","set","has","every","test","some","p","values","d","JSON","stringify","meta","rejectUnknown","push","document","delete","part","mutation","applied","state","mainDocument","find","resolveDocumentKey","slice","findDocument","resolved"],"sources":["../../src/wire/documents.ts"],"sourcesContent":["import { applyOps } from \"./ops\";\nimport { reviveValue } from \"./meta\";\nimport { protocolToken } from \"./protocol\";\nimport type { StatewirePath } from \"./ops\";\n\nexport namespace StatewireDocuments {\n export type CacheEntry = { version: string; value: unknown };\n export type Storage = {\n namespace?: string;\n load: (identity: readonly string[]) => CacheEntry | undefined;\n save: (identity: readonly string[], entry: CacheEntry) => void;\n subscribe?: (listener: () => void) => () => void;\n };\n export type Source = {\n get: (\n protocol: string,\n key?: readonly string[],\n prefix?: readonly string[],\n ) => unknown;\n list: () => ReadonlyMap<number, Document>;\n subscribe: (listener: () => void) => () => void;\n };\n export type Document = {\n key: readonly string[] | null;\n protocol?: string;\n main?: boolean;\n value: unknown;\n };\n export type State = {\n mode: \"mounted\" | \"keyless\" | null;\n documents: ReadonlyMap<number, Document>;\n };\n}\n\nconst invalid: (message: string) => never = (message) => {\n throw new Error(`statewire: protocol error: ${message}`);\n};\n\nexport const applyDocumentOps = (\n previous: StatewireDocuments.State,\n ops: readonly unknown[],\n protocols?: readonly { name: string; version: string }[],\n strict = false,\n) => {\n let mode =\n previous.mode ??\n (protocols !== undefined && ops.length === 0 ? \"mounted\" : null);\n const documents = new Map(previous.documents);\n const changedPaths: StatewirePath[] = [];\n for (const raw of ops) {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n invalid(\"operation must be an object\");\n }\n const op = raw as Record<string, unknown>;\n const doc = op.doc === undefined ? 0 : op.doc;\n if (typeof doc !== \"number\" || !Number.isSafeInteger(doc) || doc < 0) {\n invalid(\"doc must be a nonnegative safe integer\");\n }\n if (\n ![\"mount\", \"unmount\", \"add\", \"replace\", \"remove\"].includes(\n op.op as string,\n )\n ) {\n if (strict) invalid(\"unknown context operation\");\n const { doc: _doc, ...unknown } = op;\n applyOps(undefined, [unknown]);\n continue;\n }\n if (protocols !== undefined && mode === null && op.op !== \"mount\")\n invalid(\"negotiated state must start with mounts\");\n if (mode === null) {\n if (op.op === \"mount\") mode = \"mounted\";\n else if (\n op.op === \"replace\" &&\n doc === 0 &&\n Array.isArray(op.path) &&\n op.path.length === 0 &&\n \"value\" in op\n ) {\n mode = \"keyless\";\n documents.set(0, { key: null, value: undefined });\n } else\n invalid(\n \"first operation must mount a document or replace document 0 at the root\",\n );\n }\n if (\n mode === \"keyless\" &&\n (doc !== 0 || op.op === \"mount\" || op.op === \"unmount\")\n ) {\n invalid(\"keyless mode only supports mutations of document 0\");\n }\n if (op.op === \"mount\") {\n if (documents.has(doc)) invalid(\"document is already mounted\");\n if (\n (op.key !== undefined &&\n (!Array.isArray(op.key) ||\n !op.key.every((key) => typeof key === \"string\"))) ||\n !(\"value\" in op)\n ) {\n invalid(\"mount requires value and an optional key array\");\n }\n if (\n op.protocol !== undefined &&\n (typeof op.protocol !== \"string\" ||\n !protocolToken.test(op.protocol) ||\n op.protocol === \"*\")\n )\n invalid(\"invalid mount protocol\");\n if (\n protocols !== undefined &&\n !protocols.some((p) => p.name === op.protocol)\n )\n invalid(\"mount protocol was not negotiated\");\n if (op.main !== undefined && typeof op.main !== \"boolean\")\n invalid(\"main must be boolean\");\n if (\n op.main === true &&\n [...documents.values()].some(\n (d) => d.protocol === op.protocol && d.main,\n )\n )\n invalid(\"protocol already has a main document\");\n if (\n op.key !== undefined &&\n [...documents.values()].some(\n (d) =>\n d.protocol === op.protocol &&\n JSON.stringify(d.key) === JSON.stringify(op.key),\n )\n )\n invalid(\"protocol document key is already mounted\");\n documents.set(doc, {\n key: op.key === undefined ? null : (op.key as string[]),\n ...(op.protocol === undefined\n ? {}\n : { protocol: op.protocol as string }),\n ...(op.main === undefined ? {} : { main: op.main as boolean }),\n value:\n op.meta === undefined\n ? op.value\n : reviveValue(op.value, op.meta, { rejectUnknown: strict }),\n });\n if (doc === 0) changedPaths.push([]);\n } else if (op.op === \"unmount\") {\n const document = documents.get(doc);\n if (\n protocols !== undefined &&\n document !== undefined &&\n !protocols.some((p) => p.name === document.protocol)\n )\n invalid(\"document protocol was not negotiated\");\n if (!documents.delete(doc)) invalid(\"document is not mounted\");\n if (doc === 0) changedPaths.push([]);\n } else if (op.op === \"add\" || op.op === \"replace\" || op.op === \"remove\") {\n const document = documents.get(doc);\n if (\n protocols !== undefined &&\n document !== undefined &&\n !protocols.some((p) => p.name === document.protocol)\n )\n invalid(\"document protocol was not negotiated\");\n if (!document) invalid(\"document is not mounted\");\n if (\n !Array.isArray(op.path) ||\n !op.path.every(\n (part) =>\n typeof part === \"string\" ||\n (typeof part === \"number\" &&\n Number.isSafeInteger(part) &&\n part >= 0),\n )\n ) {\n invalid(\"operation requires a valid path\");\n }\n if (op.op !== \"remove\" && !(\"value\" in op))\n invalid(\"operation requires a value\");\n const { doc: _doc, meta, ...mutation } = op;\n if (meta !== undefined)\n mutation.value = reviveValue(mutation.value, meta, {\n rejectUnknown: strict,\n });\n const applied = applyOps(document.value, [mutation]);\n documents.set(doc, { ...document, value: applied.state });\n if (doc === 0) changedPaths.push(...applied.changedPaths);\n }\n }\n if (mode === null) invalid(\"hello missing snapshot\");\n return { mode, documents, changedPaths };\n};\n\nexport const mainDocument = (\n state: StatewireDocuments.State,\n protocol: string,\n) =>\n [...state.documents.values()].find(\n (document) => document.protocol === protocol && document.main,\n );\n\nexport const resolveDocumentKey = (\n key: readonly string[],\n prefix?: readonly string[],\n) =>\n key[0] === \".\"\n ? prefix === undefined\n ? undefined\n : [...prefix, ...key.slice(1)]\n : key;\n\nexport const findDocument = (\n state: StatewireDocuments.State,\n protocol: string,\n key?: readonly string[],\n prefix?: readonly string[],\n) => {\n if (key === undefined) return mainDocument(state, protocol);\n const resolved = resolveDocumentKey(key, prefix);\n return [...state.documents.values()].find(\n (document) =>\n document.protocol === protocol &&\n document.key !== null &&\n (JSON.stringify(document.key) === JSON.stringify(key) ||\n (resolved !== undefined &&\n JSON.stringify(resolveDocumentKey(document.key, prefix)) ===\n JSON.stringify(resolved))),\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"documents.js","names":["applyOps","reviveValue","protocolToken","StatewirePath","StatewireDocuments","CacheEntry","version","value","Storage","namespace","load","identity","save","entry","subscribe","listener","Source","get","protocol","key","prefix","list","ReadonlyMap","Document","main","State","mode","documents","invalid","message","Error","applyDocumentOps","previous","ops","protocols","name","strict","undefined","length","Map","changedPaths","raw","Array","isArray","op","Record","doc","Number","isSafeInteger","includes","_doc","unknown","path","set","has","every","test","some","p","values","d","JSON","stringify","meta","rejectUnknown","push","document","delete","part","mutation","applied","state","mainDocument","find","resolveDocumentKey","slice","findDocument","resolved","reviveValue"],"sources":["../../src/wire/documents.ts"],"sourcesContent":["import { applyOps } from \"./ops\";\nimport { reviveValue } from \"./meta\";\nimport { protocolToken } from \"./protocol\";\nimport type { StatewirePath } from \"./ops\";\n\nexport namespace StatewireDocuments {\n export type CacheEntry = { version: string; value: unknown };\n export type Storage = {\n namespace?: string;\n load: (identity: readonly string[]) => CacheEntry | undefined;\n save: (identity: readonly string[], entry: CacheEntry) => void;\n subscribe?: (listener: () => void) => () => void;\n };\n export type Source = {\n get: (\n protocol: string,\n key?: readonly string[],\n prefix?: readonly string[],\n ) => unknown;\n list: () => ReadonlyMap<number, Document>;\n subscribe: (listener: () => void) => () => void;\n };\n export type Document = {\n key: readonly string[] | null;\n protocol?: string;\n main?: boolean;\n value: unknown;\n };\n export type State = {\n mode: \"mounted\" | \"keyless\" | null;\n documents: ReadonlyMap<number, Document>;\n };\n}\n\nconst invalid: (message: string) => never = (message) => {\n throw new Error(`statewire: protocol error: ${message}`);\n};\n\nexport const applyDocumentOps = (\n previous: StatewireDocuments.State,\n ops: readonly unknown[],\n protocols?: readonly { name: string; version: string }[],\n strict = false,\n) => {\n let mode =\n previous.mode ??\n (protocols !== undefined && ops.length === 0 ? \"mounted\" : null);\n const documents = new Map(previous.documents);\n const changedPaths: StatewirePath[] = [];\n for (const raw of ops) {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n invalid(\"operation must be an object\");\n }\n const op = raw as Record<string, unknown>;\n const doc = op.doc === undefined ? 0 : op.doc;\n if (typeof doc !== \"number\" || !Number.isSafeInteger(doc) || doc < 0) {\n invalid(\"doc must be a nonnegative safe integer\");\n }\n if (\n ![\"mount\", \"unmount\", \"add\", \"replace\", \"remove\"].includes(\n op.op as string,\n )\n ) {\n if (strict) invalid(\"unknown context operation\");\n const { doc: _doc, ...unknown } = op;\n applyOps(undefined, [unknown]);\n continue;\n }\n if (protocols !== undefined && mode === null && op.op !== \"mount\")\n invalid(\"negotiated state must start with mounts\");\n if (mode === null) {\n if (op.op === \"mount\") mode = \"mounted\";\n else if (\n op.op === \"replace\" &&\n doc === 0 &&\n Array.isArray(op.path) &&\n op.path.length === 0 &&\n \"value\" in op\n ) {\n mode = \"keyless\";\n documents.set(0, { key: null, value: undefined });\n } else\n invalid(\n \"first operation must mount a document or replace document 0 at the root\",\n );\n }\n if (\n mode === \"keyless\" &&\n (doc !== 0 || op.op === \"mount\" || op.op === \"unmount\")\n ) {\n invalid(\"keyless mode only supports mutations of document 0\");\n }\n if (op.op === \"mount\") {\n if (documents.has(doc)) invalid(\"document is already mounted\");\n if (\n (op.key !== undefined &&\n (!Array.isArray(op.key) ||\n !op.key.every((key) => typeof key === \"string\"))) ||\n !(\"value\" in op)\n ) {\n invalid(\"mount requires value and an optional key array\");\n }\n if (\n op.protocol !== undefined &&\n (typeof op.protocol !== \"string\" ||\n !protocolToken.test(op.protocol) ||\n op.protocol === \"*\")\n )\n invalid(\"invalid mount protocol\");\n if (\n protocols !== undefined &&\n !protocols.some((p) => p.name === op.protocol)\n )\n invalid(\"mount protocol was not negotiated\");\n if (op.main !== undefined && typeof op.main !== \"boolean\")\n invalid(\"main must be boolean\");\n if (\n op.main === true &&\n [...documents.values()].some(\n (d) => d.protocol === op.protocol && d.main,\n )\n )\n invalid(\"protocol already has a main document\");\n if (\n op.key !== undefined &&\n [...documents.values()].some(\n (d) =>\n d.protocol === op.protocol &&\n JSON.stringify(d.key) === JSON.stringify(op.key),\n )\n )\n invalid(\"protocol document key is already mounted\");\n documents.set(doc, {\n key: op.key === undefined ? null : (op.key as string[]),\n ...(op.protocol === undefined\n ? {}\n : { protocol: op.protocol as string }),\n ...(op.main === undefined ? {} : { main: op.main as boolean }),\n value:\n op.meta === undefined\n ? op.value\n : reviveValue(op.value, op.meta, { rejectUnknown: strict }),\n });\n if (doc === 0) changedPaths.push([]);\n } else if (op.op === \"unmount\") {\n const document = documents.get(doc);\n if (\n protocols !== undefined &&\n document !== undefined &&\n !protocols.some((p) => p.name === document.protocol)\n )\n invalid(\"document protocol was not negotiated\");\n if (!documents.delete(doc)) invalid(\"document is not mounted\");\n if (doc === 0) changedPaths.push([]);\n } else if (op.op === \"add\" || op.op === \"replace\" || op.op === \"remove\") {\n const document = documents.get(doc);\n if (\n protocols !== undefined &&\n document !== undefined &&\n !protocols.some((p) => p.name === document.protocol)\n )\n invalid(\"document protocol was not negotiated\");\n if (!document) invalid(\"document is not mounted\");\n if (\n !Array.isArray(op.path) ||\n !op.path.every(\n (part) =>\n typeof part === \"string\" ||\n (typeof part === \"number\" &&\n Number.isSafeInteger(part) &&\n part >= 0),\n )\n ) {\n invalid(\"operation requires a valid path\");\n }\n if (op.op !== \"remove\" && !(\"value\" in op))\n invalid(\"operation requires a value\");\n const { doc: _doc, meta, ...mutation } = op;\n if (meta !== undefined)\n mutation.value = reviveValue(mutation.value, meta, {\n rejectUnknown: strict,\n });\n const applied = applyOps(document.value, [mutation]);\n documents.set(doc, { ...document, value: applied.state });\n if (doc === 0) changedPaths.push(...applied.changedPaths);\n }\n }\n if (mode === null) invalid(\"hello missing snapshot\");\n return { mode, documents, changedPaths };\n};\n\nexport const mainDocument = (\n state: StatewireDocuments.State,\n protocol: string,\n) =>\n [...state.documents.values()].find(\n (document) => document.protocol === protocol && document.main,\n );\n\nexport const resolveDocumentKey = (\n key: readonly string[],\n prefix?: readonly string[],\n) =>\n key[0] === \".\"\n ? prefix === undefined\n ? undefined\n : [...prefix, ...key.slice(1)]\n : key;\n\nexport const findDocument = (\n state: StatewireDocuments.State,\n protocol: string,\n key?: readonly string[],\n prefix?: readonly string[],\n) => {\n if (key === undefined) return mainDocument(state, protocol);\n const resolved = resolveDocumentKey(key, prefix);\n return [...state.documents.values()].find(\n (document) =>\n document.protocol === protocol &&\n document.key !== null &&\n (JSON.stringify(document.key) === JSON.stringify(key) ||\n (resolved !== undefined &&\n JSON.stringify(resolveDocumentKey(document.key, prefix)) ===\n JSON.stringify(resolved))),\n );\n};\n"],"mappings":"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"}
@@ -1,11 +1,8 @@
1
- //#region src/wire/limits.d.ts
2
- declare const MAX_COMMANDS_PER_FRAME = 256;
3
- declare const MAX_INFLIGHT_COMMANDS_PER_CLIENT = 256;
4
- declare const MAX_FRAME_BODY_BYTES: number;
5
- declare const MAX_EPHEMERAL_DOCUMENT_BYTES: number;
6
- declare const MAX_INFLIGHT_COMMANDS_PER_HOST = 1024;
7
- declare const COMMAND_CAPACITY_RETRY_MS = 1000;
8
- declare const MAX_CONTEXT_BYTES: number;
9
- //#endregion
10
- export { COMMAND_CAPACITY_RETRY_MS, MAX_COMMANDS_PER_FRAME, MAX_CONTEXT_BYTES, MAX_EPHEMERAL_DOCUMENT_BYTES, MAX_FRAME_BODY_BYTES, MAX_INFLIGHT_COMMANDS_PER_CLIENT, MAX_INFLIGHT_COMMANDS_PER_HOST };
1
+ export declare const MAX_COMMANDS_PER_FRAME = 256;
2
+ export declare const MAX_INFLIGHT_COMMANDS_PER_CLIENT = 256;
3
+ export declare const MAX_FRAME_BODY_BYTES: number;
4
+ export declare const MAX_EPHEMERAL_DOCUMENT_BYTES: number;
5
+ export declare const MAX_INFLIGHT_COMMANDS_PER_HOST = 1024;
6
+ export declare const COMMAND_CAPACITY_RETRY_MS = 1000;
7
+ export declare const MAX_CONTEXT_BYTES: number;
11
8
  //# sourceMappingURL=limits.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"limits.d.ts","names":[],"sources":["../../src/wire/limits.ts"],"mappings":";cAAa;cACA;cACA;cACA;cACA;cACA;cAEA"}
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/wire/limits.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD,eAAO,MAAM,oBAAoB,QAAkB,CAAC;AACpD,eAAO,MAAM,4BAA4B,QAAY,CAAC;AACtD,eAAO,MAAM,8BAA8B,OAAO,CAAC;AACnD,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAE/C,eAAO,MAAM,iBAAiB,QAAY,CAAC"}
@@ -1,4 +1,4 @@
1
- //#region src/wire/limits.ts
1
+ // src/wire/limits.ts
2
2
  const MAX_COMMANDS_PER_FRAME = 256;
3
3
  const MAX_INFLIGHT_COMMANDS_PER_CLIENT = 256;
4
4
  const MAX_FRAME_BODY_BYTES = 8388608;
@@ -6,7 +6,6 @@ const MAX_EPHEMERAL_DOCUMENT_BYTES = 65536;
6
6
  const MAX_INFLIGHT_COMMANDS_PER_HOST = 1024;
7
7
  const COMMAND_CAPACITY_RETRY_MS = 1e3;
8
8
  const MAX_CONTEXT_BYTES = 65536;
9
- //#endregion
10
9
  export { COMMAND_CAPACITY_RETRY_MS, MAX_COMMANDS_PER_FRAME, MAX_CONTEXT_BYTES, MAX_EPHEMERAL_DOCUMENT_BYTES, MAX_FRAME_BODY_BYTES, MAX_INFLIGHT_COMMANDS_PER_CLIENT, MAX_INFLIGHT_COMMANDS_PER_HOST };
11
10
 
12
11
  //# sourceMappingURL=limits.js.map
@@ -1,14 +1,12 @@
1
- import { StatewireDocument, reviveDocumentValue } from "../document.js";
2
- //#region src/wire/meta.d.ts
3
- declare const reviveOps: (ops: unknown[]) => unknown[];
4
- declare const reviveResponse: <T extends {
5
- payload?: unknown;
6
- meta?: unknown;
1
+ import type { StatewireDocument } from "../document.js";
2
+ export { reviveDocumentValue as reviveValue } from "../document.js";
3
+ export declare const reviveOps: (ops: unknown[]) => unknown[];
4
+ export declare const reviveResponse: <T extends {
5
+ payload?: unknown;
6
+ meta?: unknown;
7
7
  }>(response: T) => T;
8
- declare const encodeParams: (params: readonly unknown[]) => {
9
- params: unknown[];
10
- meta?: StatewireDocument.MetaEntry[];
8
+ export declare const encodeParams: (params: readonly unknown[]) => {
9
+ params: unknown[];
10
+ meta?: StatewireDocument.MetaEntry[];
11
11
  };
12
- //#endregion
13
- export { encodeParams, reviveOps, reviveResponse, reviveDocumentValue as reviveValue };
14
12
  //# sourceMappingURL=meta.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"meta.d.ts","names":[],"sources":["../../src/wire/meta.ts"],"mappings":";;cAQa,YAAa;cAOb,iBAAkB;EAAY;EAAmB;GAC5D,UAAU,MACT;cAMU,eACX;EACG;EAAmB,OAAO,kBAAkB"}
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/wire/meta.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAoB;AAErD,OAAO,EAAE,mBAAmB,IAAI,WAAW,EAAE,uBAAoB;AAEjE,eAAO,MAAM,SAAS,GAAI,KAAK,OAAO,EAAE,KAAG,OAAO,EAK9C,CAAC;AAEL,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EAC5E,UAAU,CAAC,KACV,CAIF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,QAAQ,SAAS,OAAO,EAAE,KACzB;IAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC,SAAS,EAAE,CAAA;CAK3D,CAAC"}
package/dist/wire/meta.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { encodeDocument, reviveDocumentValue } from "../document.js";
2
- //#region src/wire/meta.ts
2
+ // src/wire/meta.ts
3
3
  const reviveOps = (ops) => ops.map((op) => {
4
4
  if (typeof op !== "object" || op === null || !("meta" in op)) return op;
5
5
  const { meta, ...rest } = op;
@@ -23,7 +23,6 @@ const encodeParams = (params) => {
23
23
  meta
24
24
  } : { params: value };
25
25
  };
26
- //#endregion
27
26
  export { encodeParams, reviveOps, reviveResponse, reviveDocumentValue as reviveValue };
28
27
 
29
28
  //# sourceMappingURL=meta.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"meta.js","names":["encodeDocument","reviveDocumentValue","reviveValue","StatewireDocument","reviveOps","ops","map","op","meta","rest","value","reviveResponse","payload","response","T","undefined","encodeParams","params","MetaEntry"],"sources":["../../src/wire/meta.ts"],"sourcesContent":["import {\n encodeDocument,\n reviveDocumentValue as reviveValue,\n} from \"../document\";\nimport type { StatewireDocument } from \"../document\";\n\nexport { reviveDocumentValue as reviveValue } from \"../document\";\n\nexport const reviveOps = (ops: unknown[]): unknown[] =>\n ops.map((op) => {\n if (typeof op !== \"object\" || op === null || !(\"meta\" in op)) return op;\n const { meta, ...rest } = op as { meta: unknown; value?: unknown };\n return { ...rest, value: reviveValue(rest.value, meta) };\n });\n\nexport const reviveResponse = <T extends { payload?: unknown; meta?: unknown }>(\n response: T,\n): T => {\n if (response.meta === undefined) return response;\n const { meta, ...rest } = response;\n return { ...rest, payload: reviveValue(rest.payload, meta) } as T;\n};\n\nexport const encodeParams = (\n params: readonly unknown[],\n): { params: unknown[]; meta?: StatewireDocument.MetaEntry[] } => {\n const { value, meta } = encodeDocument(params);\n return meta\n ? { params: value as unknown[], meta }\n : { params: value as unknown[] };\n};\n"],"mappings":";;AAQA,MAAaI,aAAaC,QACxBA,IAAIC,KAAKC,OAAO;CACd,IAAI,OAAOA,OAAO,YAAYA,OAAO,QAAQ,EAAE,UAAUA,KAAK,OAAOA;CACrE,MAAM,EAAEC,MAAM,GAAGC,SAASF;CAC1B,OAAO;EAAE,GAAGE;EAAMC,OAAOR,oBAAYO,KAAKC,OAAOF,IAAI;CAAE;AACzD,CAAC;AAEH,MAAaG,kBACXE,aACM;CACN,IAAIA,SAASL,SAASO,KAAAA,GAAW,OAAOF;CACxC,MAAM,EAAEL,MAAM,GAAGC,SAASI;CAC1B,OAAO;EAAE,GAAGJ;EAAMG,SAASV,oBAAYO,KAAKG,SAASJ,IAAI;CAAE;AAC7D;AAEA,MAAaQ,gBACXC,WACgE;CAChE,MAAM,EAAEP,OAAOF,SAASR,eAAeiB,MAAM;CAC7C,OAAOT,OACH;EAAES,QAAQP;EAAoBF;CAAK,IACnC,EAAES,QAAQP,MAAmB;AACnC"}
1
+ {"version":3,"file":"meta.js","names":["encodeDocument","reviveDocumentValue","reviveValue","StatewireDocument","reviveOps","ops","map","op","meta","rest","value","reviveResponse","payload","response","T","undefined","encodeParams","params","MetaEntry","reviveValue"],"sources":["../../src/wire/meta.ts"],"sourcesContent":["import {\n encodeDocument,\n reviveDocumentValue as reviveValue,\n} from \"../document\";\nimport type { StatewireDocument } from \"../document\";\n\nexport { reviveDocumentValue as reviveValue } from \"../document\";\n\nexport const reviveOps = (ops: unknown[]): unknown[] =>\n ops.map((op) => {\n if (typeof op !== \"object\" || op === null || !(\"meta\" in op)) return op;\n const { meta, ...rest } = op as { meta: unknown; value?: unknown };\n return { ...rest, value: reviveValue(rest.value, meta) };\n });\n\nexport const reviveResponse = <T extends { payload?: unknown; meta?: unknown }>(\n response: T,\n): T => {\n if (response.meta === undefined) return response;\n const { meta, ...rest } = response;\n return { ...rest, payload: reviveValue(rest.payload, meta) } as T;\n};\n\nexport const encodeParams = (\n params: readonly unknown[],\n): { params: unknown[]; meta?: StatewireDocument.MetaEntry[] } => {\n const { value, meta } = encodeDocument(params);\n return meta\n ? { params: value as unknown[], meta }\n : { params: value as unknown[] };\n};\n"],"mappings":";;AAQA,MAAaI,aAAaC,QACxBA,IAAIC,KAAKC,OAAO;CACd,IAAI,OAAOA,OAAO,YAAYA,OAAO,QAAQ,EAAE,UAAUA,KAAK,OAAOA;CACrE,MAAM,EAAEC,MAAM,GAAGC,SAASF;CAC1B,OAAO;EAAE,GAAGE;EAAMC,OAAOR,oBAAYO,KAAKC,OAAOF,IAAI;CAAE;AACzD,CAAC;AAEH,MAAaG,kBACXE,aACM;CACN,IAAIA,SAASL,SAASO,KAAAA,GAAW,OAAOF;CACxC,MAAM,EAAEL,MAAM,GAAGC,SAASI;CAC1B,OAAO;EAAE,GAAGJ;EAAMG,SAASV,oBAAYO,KAAKG,SAASJ,IAAI;CAAE;AAC7D;AAEA,MAAaQ,gBACXC,WACgE;CAChE,MAAM,EAAEP,OAAOF,SAASR,eAAeiB,MAAM;CAC7C,OAAOT,OACH;EAAES,QAAQP;EAAoBF;CAAK,IACnC,EAAES,QAAQP,MAAmB;AACnC"}
@@ -1,15 +1,12 @@
1
- import { Statewire } from "../types.js";
2
- //#region src/wire/ops.d.ts
3
- type StatewirePath = readonly (string | number)[];
4
- declare const sanitizeValue: (value: unknown, parent?: string) => unknown;
5
- declare const applyOp: (root: unknown, op: Statewire.Op) => {
6
- state: unknown;
7
- changedPaths: StatewirePath[];
1
+ import type { Statewire } from "../types.js";
2
+ export type StatewirePath = readonly (string | number)[];
3
+ export declare const sanitizeValue: (value: unknown, parent?: string) => unknown;
4
+ export declare const applyOp: (root: unknown, op: Statewire.Op) => {
5
+ state: unknown;
6
+ changedPaths: StatewirePath[];
8
7
  };
9
- declare const applyOps: (state: unknown, ops: readonly unknown[]) => {
10
- state: unknown;
11
- changedPaths: StatewirePath[];
8
+ export declare const applyOps: (state: unknown, ops: readonly unknown[]) => {
9
+ state: unknown;
10
+ changedPaths: StatewirePath[];
12
11
  };
13
- //#endregion
14
- export { StatewirePath, applyOp, applyOps, sanitizeValue };
15
12
  //# sourceMappingURL=ops.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ops.d.ts","names":[],"sources":["../../src/wire/ops.ts"],"mappings":";;KAIY;cAwDC,gBAAiB,gBAAgB;cAgIjC,UACX,eACA,IAAI,UAAU;EACX;EAAgB,cAAc;;cAUtB,WACX,gBACA;EAEA;EACA,cAAc"}
1
+ {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/wire/ops.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAiB;AAE1C,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;AAwDzD,eAAO,MAAM,aAAa,GAAI,OAAO,OAAO,EAAE,SAAS,MAAM,KAAG,OACC,CAAC;AA+HlE,eAAO,MAAM,OAAO,GAClB,MAAM,OAAO,EACb,IAAI,SAAS,CAAC,EAAE,KACf;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,aAAa,EAAE,CAAA;CAQjD,CAAC;AAEF,eAAO,MAAM,QAAQ,GACnB,OAAO,OAAO,EACd,KAAK,SAAS,OAAO,EAAE,KACtB;IACD,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,aAAa,EAAE,CAAC;CAkB/B,CAAC"}
package/dist/wire/ops.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isUnsafeKey, walkStatePath } from "../util/statePath.js";
2
2
  import { recordMutations } from "../util/recordMutations.js";
3
- //#region src/wire/ops.ts
3
+ // src/wire/ops.ts
4
4
  const warnStripped = (key, parent) => {
5
5
  if (typeof process === "undefined" || process.env["NODE_ENV"] !== "production") console.warn(`statewire: stripped unsafe key "${key}"` + (parent === void 0 ? "" : ` under "${parent}"`));
6
6
  };
@@ -130,7 +130,6 @@ const applyOps = (state, ops) => {
130
130
  changedPaths: unboxPaths(recorded.changedPaths)
131
131
  };
132
132
  };
133
- //#endregion
134
133
  export { applyOp, applyOps, sanitizeValue };
135
134
 
136
135
  //# sourceMappingURL=ops.js.map
@@ -1,60 +1,57 @@
1
- //#region src/wire/protocol.d.ts
2
- declare namespace StatewireProtocol {
3
- type Range = {
4
- version: string;
5
- minVersion?: string;
6
- };
7
- type Offer = Range & {
8
- name: string;
9
- optional?: boolean;
10
- };
11
- type Selection = {
12
- version: string;
13
- protocols: {
14
- name: string;
15
- version: string;
16
- record?: "ephemeral";
17
- }[];
18
- };
19
- type Options = {
20
- wireVersion?: Range;
21
- applicationProtocols?: readonly Offer[] | "*";
22
- protocol?: string;
23
- keyPrefixes?: Readonly<Record<string, readonly string[]>>;
24
- };
25
- type Definition = Range & {
26
- name: string;
27
- requires?: Readonly<Record<string, Range>>;
28
- subprotocols?: readonly {
29
- name: string;
30
- record?: "ephemeral";
31
- }[];
32
- };
1
+ export declare namespace StatewireProtocol {
2
+ type Range = {
3
+ version: string;
4
+ minVersion?: string;
5
+ };
6
+ type Offer = Range & {
7
+ name: string;
8
+ optional?: boolean;
9
+ };
10
+ type Selection = {
11
+ version: string;
12
+ protocols: {
13
+ name: string;
14
+ version: string;
15
+ record?: "ephemeral";
16
+ }[];
17
+ };
18
+ type Options = {
19
+ wireVersion?: Range;
20
+ applicationProtocols?: readonly Offer[] | "*";
21
+ protocol?: string;
22
+ keyPrefixes?: Readonly<Record<string, readonly string[]>>;
23
+ };
24
+ type Definition = Range & {
25
+ name: string;
26
+ requires?: Readonly<Record<string, Range>>;
27
+ subprotocols?: readonly {
28
+ name: string;
29
+ record?: "ephemeral";
30
+ }[];
31
+ };
33
32
  }
34
- declare const WIRE_VERSION = "2026-09-30";
35
- declare const DEFAULT_PROTOCOL = "default";
36
- declare const PROTOCOL_HEADER = "Statewire-Protocol";
37
- declare const VERSION_HEADER = "Statewire-Version";
38
- declare const protocolToken: RegExp;
39
- declare const validateVersion: (value: unknown) => string;
40
- declare const validateRange: (range: StatewireProtocol.Range) => {
41
- version: string;
42
- minVersion: string;
33
+ export declare const WIRE_VERSION = "2026-09-30";
34
+ export declare const DEFAULT_PROTOCOL = "default";
35
+ export declare const PROTOCOL_HEADER = "Statewire-Protocol";
36
+ export declare const VERSION_HEADER = "Statewire-Version";
37
+ export declare const protocolToken: RegExp;
38
+ export declare const validateVersion: (value: unknown) => string;
39
+ export declare const validateRange: (range: StatewireProtocol.Range) => {
40
+ version: string;
41
+ minVersion: string;
43
42
  };
44
- declare const inRange: (value: string, range: StatewireProtocol.Range) => boolean;
45
- declare const protocolOffers: (options: StatewireProtocol.Options) => readonly StatewireProtocol.Offer[] | "*";
46
- declare const negotiationHeaders: (options: StatewireProtocol.Options) => Record<string, string>;
47
- declare const parseNegotiation: (headers: Headers) => Required<Pick<StatewireProtocol.Options, "wireVersion" | "applicationProtocols">>;
48
- declare const validateSelection: (value: unknown, options: StatewireProtocol.Options) => StatewireProtocol.Selection;
49
- declare const negotiateProtocols: (headers: Headers, wire: StatewireProtocol.Range, definitions: readonly StatewireProtocol.Definition[]) => StatewireProtocol.Selection | {
50
- fin: {
51
- reason: "protocol-error";
52
- code: string;
53
- status: number;
54
- message: string;
55
- payload?: unknown;
56
- };
43
+ export declare const inRange: (value: string, range: StatewireProtocol.Range) => boolean;
44
+ export declare const protocolOffers: (options: StatewireProtocol.Options) => readonly StatewireProtocol.Offer[] | "*";
45
+ export declare const negotiationHeaders: (options: StatewireProtocol.Options) => Record<string, string>;
46
+ export declare const parseNegotiation: (headers: Headers) => Required<Pick<StatewireProtocol.Options, "wireVersion" | "applicationProtocols">>;
47
+ export declare const validateSelection: (value: unknown, options: StatewireProtocol.Options) => StatewireProtocol.Selection;
48
+ export declare const negotiateProtocols: (headers: Headers, wire: StatewireProtocol.Range, definitions: readonly StatewireProtocol.Definition[]) => StatewireProtocol.Selection | {
49
+ fin: {
50
+ reason: "protocol-error";
51
+ code: string;
52
+ status: number;
53
+ message: string;
54
+ payload?: unknown;
55
+ };
57
56
  };
58
- //#endregion
59
- export { DEFAULT_PROTOCOL, PROTOCOL_HEADER, StatewireProtocol, VERSION_HEADER, WIRE_VERSION, inRange, negotiateProtocols, negotiationHeaders, parseNegotiation, protocolOffers, protocolToken, validateRange, validateSelection, validateVersion };
60
57
  //# sourceMappingURL=protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","names":[],"sources":["../../src/wire/protocol.ts"],"mappings":";kBAAiB;OACH;IAAU;IAAiB;;OAC3B,QAAQ;IAAU;IAAc;;OAChC;IACV;IACA;MAAa;MAAc;MAAiB;;;OAElC;IACV,cAAc;IACd,gCAAgC;IAChC;IACA,cAAc,SAAS;;OAEb,aAAa;IACvB;IACA,WAAW,SAAS,eAAe;IACnC;MAA0B;MAAc;;;;cAI/B;cACA;cACA;cACA;cACA,eAAa;cAMb,kBAAmB;cAanB,gBAAiB,OAAO,kBAAkB;;;;cAU1C,UAAW,eAAe,OAAO,kBAAkB;cAKnD,iBAAkB,SAAS,kBAAkB,qBAAO,kBAAA;cAKpD,qBACX,SAAS,kBAAkB,YAC1B;cA6DU,mBACX,SAAS,YACR,SACD,KAAK,kBAAkB;cA0DZ,oBACX,gBACA,SAAS,kBAAkB,YAC1B,kBAAkB;cA6CR,qBACX,SAAS,SACT,MAAM,kBAAkB,OACxB,sBAAsB,kBAAkB,iBAEtC,kBAAkB;EAEhB;IACE;IACA;IACA;IACA;IACA"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/wire/protocol.ts"],"names":[],"mappings":"AAAA,yBAAiB,iBAAiB,CAAC;IACjC,KAAY,KAAK,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,KAAY,KAAK,GAAG,KAAK,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACjE,KAAY,SAAS,GAAG;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,WAAW,CAAA;SAAE,EAAE,CAAC;KACtE,CAAC;IACF,KAAY,OAAO,GAAG;QACpB,WAAW,CAAC,EAAE,KAAK,CAAC;QACpB,oBAAoB,CAAC,EAAE,SAAS,KAAK,EAAE,GAAG,GAAG,CAAC;QAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;KAC3D,CAAC;IACF,KAAY,UAAU,GAAG,KAAK,GAAG;QAC/B,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QAC3C,YAAY,CAAC,EAAE,SAAS;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,WAAW,CAAA;SAAE,EAAE,CAAC;KAClE,CAAC;CACH;AAED,eAAO,MAAM,YAAY,eAAe,CAAC;AACzC,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAC1C,eAAO,MAAM,eAAe,uBAAuB,CAAC;AACpD,eAAO,MAAM,cAAc,sBAAsB,CAAC;AAClD,eAAO,MAAM,aAAa,QAA6C,CAAC;AAMxE,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,MAWhD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,iBAAiB,CAAC,KAAK;;;CAQ3D,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,EAAE,OAAO,iBAAiB,CAAC,KAAK,YAGpE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS,iBAAiB,CAAC,OAAO,6CAG9D,CAAC;AAEJ,eAAO,MAAM,kBAAkB,GAC7B,SAAS,iBAAiB,CAAC,OAAO,KACjC,MAAM,CAAC,MAAM,EAAE,MAAM,CAgCvB,CAAC;AA6BF,eAAO,MAAM,gBAAgB,GAC3B,SAAS,OAAO,KACf,QAAQ,CACT,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,sBAAsB,CAAC,CAwDxE,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,OAAO,EACd,SAAS,iBAAiB,CAAC,OAAO,KACjC,iBAAiB,CAAC,SA2CpB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,OAAO,EAChB,MAAM,iBAAiB,CAAC,KAAK,EAC7B,aAAa,SAAS,iBAAiB,CAAC,UAAU,EAAE,KAElD,iBAAiB,CAAC,SAAS,GAC3B;IACE,GAAG,EAAE;QACH,MAAM,EAAE,gBAAgB,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CA2GP,CAAC"}
@@ -1,4 +1,4 @@
1
- //#region src/wire/protocol.ts
1
+ // src/wire/protocol.ts
2
2
  const WIRE_VERSION = "2026-09-30";
3
3
  const DEFAULT_PROTOCOL = "default";
4
4
  const PROTOCOL_HEADER = "Statewire-Protocol";
@@ -236,7 +236,6 @@ const negotiateProtocols = (headers, wire, definitions) => {
236
236
  })
237
237
  };
238
238
  };
239
- //#endregion
240
239
  export { DEFAULT_PROTOCOL, PROTOCOL_HEADER, VERSION_HEADER, WIRE_VERSION, inRange, negotiateProtocols, negotiationHeaders, parseNegotiation, protocolOffers, protocolToken, validateRange, validateSelection, validateVersion };
241
240
 
242
241
  //# sourceMappingURL=protocol.js.map
@@ -1,5 +1,2 @@
1
- //#region src/wire/version.d.ts
2
- declare const WS_SUBPROTOCOL = "statewire.v1";
3
- //#endregion
4
- export { WS_SUBPROTOCOL };
1
+ export declare const WS_SUBPROTOCOL = "statewire.v1";
5
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","names":[],"sources":["../../src/wire/version.ts"],"mappings":";cAAa"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/wire/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,iBAAiB,CAAC"}
@@ -1,6 +1,5 @@
1
- //#region src/wire/version.ts
1
+ // src/wire/version.ts
2
2
  const WS_SUBPROTOCOL = "statewire.v1";
3
- //#endregion
4
3
  export { WS_SUBPROTOCOL };
5
4
 
6
5
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "statewire",
3
- "version": "0.21.0",
3
+ "version": "0.22.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": {
@@ -47,16 +47,16 @@
47
47
  "test": "vitest run"
48
48
  },
49
49
  "dependencies": {
50
- "@assistant-ui/tap": "^0.9.6"
50
+ "@assistant-ui/tap": "^0.9.24"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "react": "^18 || ^19"
54
54
  },
55
55
  "devDependencies": {
56
- "@assistant-ui/x-buildutils": "^0.0.20",
57
- "@types/react": "^19.2.17",
56
+ "@assistant-ui/x-buildutils": "^0.0.31",
57
+ "@types/react": "^19.3.0",
58
58
  "babel-plugin-react-compiler": "^1.0.0",
59
- "react": "^19.2.8",
60
- "vitest": "^4.1.10"
59
+ "react": "^19.3.1",
60
+ "vitest": "^5.0.5"
61
61
  }
62
62
  }
@@ -718,21 +718,19 @@ export const useLink = (
718
718
  };
719
719
  return conn;
720
720
  });
721
- const [link] = useState(
722
- (): RemoteLink => ({
723
- get connection() {
724
- return c.connection;
725
- },
726
- get parked() {
727
- return c.parked;
728
- },
729
- send: (frame) => latest.current.send(c, frame),
730
- storageFailed: (error) =>
731
- stopForError({ connection: c, error, reason: "storage-error" }),
732
- protocolFailed: (error) =>
733
- stopForError({ connection: c, error, reason: "protocol-error" }),
734
- }),
735
- );
721
+ const [link] = useState((): RemoteLink => ({
722
+ get connection() {
723
+ return c.connection;
724
+ },
725
+ get parked() {
726
+ return c.parked;
727
+ },
728
+ send: (frame) => latest.current.send(c, frame),
729
+ storageFailed: (error) =>
730
+ stopForError({ connection: c, error, reason: "storage-error" }),
731
+ protocolFailed: (error) =>
732
+ stopForError({ connection: c, error, reason: "protocol-error" }),
733
+ }));
736
734
 
737
735
  const negotiation = JSON.stringify([
738
736
  props.protocol,
@@ -130,10 +130,14 @@ export type Conn = {
130
130
  auth: unknown;
131
131
  authorizedAt: number | undefined;
132
132
  leaseTimer: ReturnType<typeof setTimeout> | null;
133
+ timedLease: boolean;
133
134
  lanes: Map<string, Lane>;
134
135
  contexts: Map<string, Statewire.Context>;
135
136
  documents: Map<string, StatewireHost.Document>;
136
137
  included: Set<string>;
138
+ onIncludedChange:
139
+ | ((included: readonly StatewireHostInternal.IncludedDocument[]) => void)
140
+ | undefined;
137
141
  view: Map<string, { doc: number; value: unknown }>;
138
142
  nextDoc: number;
139
143
  pendingApplied: Cmd[];
@@ -357,6 +361,7 @@ export type SocketHostState = {
357
361
  wireVersion: StatewireProtocol.Range;
358
362
  heartbeatMs: number;
359
363
  maxLeaseLifetimeMs: number | null;
364
+ leaseTimers: boolean;
360
365
  wsInitTimeoutMs: number;
361
366
  maxSubscribers: number;
362
367
  maxInflightCommands: number;
@@ -508,7 +513,12 @@ export const expireLease = (h: SocketHostState, conn: Conn): boolean => {
508
513
  const armLeaseTimer = (h: SocketHostState, conn: Conn) => {
509
514
  if (conn.leaseTimer !== null) clearTimeout(conn.leaseTimer);
510
515
  conn.leaseTimer = null;
511
- if (h.disposed || h.maxLeaseLifetimeMs === null || expireLease(h, conn))
516
+ if (
517
+ h.disposed ||
518
+ h.maxLeaseLifetimeMs === null ||
519
+ expireLease(h, conn) ||
520
+ !conn.timedLease
521
+ )
512
522
  return;
513
523
  const delay = h.maxLeaseLifetimeMs - (Date.now() - conn.authorizedAt!);
514
524
  conn.leaseTimer = setTimeout(
@@ -540,7 +550,8 @@ const ensureHeartbeat = (h: SocketHostState) => {
540
550
  h.heartbeatTimer = setInterval(() => {
541
551
  const now = Date.now();
542
552
  for (const conn of [...h.conns]) {
543
- if (now - conn.lastSentAt >= h.heartbeatMs) sendTo(h, conn, "{}");
553
+ if (now - conn.lastSentAt >= h.heartbeatMs && !expireLease(h, conn))
554
+ sendTo(h, conn, "{}");
544
555
  }
545
556
  }, h.heartbeatMs);
546
557
  (h.heartbeatTimer as unknown as { unref?: () => void }).unref?.();
@@ -641,6 +652,33 @@ const diffView = (h: SocketHostState, conn: Conn): WireOp[] => {
641
652
  return ops;
642
653
  };
643
654
 
655
+ const notifyIncluded = (conn: Conn) =>
656
+ conn.onIncludedChange?.(
657
+ [...conn.included].map(
658
+ (id) => JSON.parse(id) as StatewireHostInternal.IncludedDocument,
659
+ ),
660
+ );
661
+
662
+ const restoredIncluded = (
663
+ included: readonly StatewireHostInternal.IncludedDocument[],
664
+ ): Set<string> =>
665
+ new Set(
666
+ included.map((entry) => {
667
+ if (
668
+ !Array.isArray(entry) ||
669
+ entry.length !== 2 ||
670
+ typeof entry[0] !== "string" ||
671
+ !(
672
+ entry[1] === null ||
673
+ (Array.isArray(entry[1]) &&
674
+ entry[1].every((part) => typeof part === "string"))
675
+ )
676
+ )
677
+ throw new TypeError("statewire: invalid restored include");
678
+ return documentIdentity(entry[0], entry[1] ?? undefined);
679
+ }),
680
+ );
681
+
644
682
  const attachOf = (h: SocketHostState, conn: Conn): StatewireHost.Attach => {
645
683
  const requireSelected = (protocol: string) => {
646
684
  const entry = conn.selection.protocols.find((p) => p.name === protocol);
@@ -700,11 +738,15 @@ const attachOf = (h: SocketHostState, conn: Conn): StatewireHost.Attach => {
700
738
  include: (protocol, key) => {
701
739
  if (requireSelected(protocol).record !== undefined)
702
740
  throw new Error(`statewire: protocol ${protocol} is not durable`);
703
- conn.included.add(documentIdentity(protocol, key));
741
+ const id = documentIdentity(protocol, key);
742
+ if (conn.included.has(id)) return;
743
+ conn.included.add(id);
744
+ notifyIncluded(conn);
704
745
  markViews(h);
705
746
  },
706
747
  exclude: (protocol, key) => {
707
- conn.included.delete(documentIdentity(protocol, key));
748
+ if (!conn.included.delete(documentIdentity(protocol, key))) return;
749
+ notifyIncluded(conn);
708
750
  markViews(h);
709
751
  },
710
752
  };
@@ -751,7 +793,7 @@ export const flush = (h: SocketHostState, fin?: StatewireHost.Fin) => {
751
793
  h.pendingCmds = new Map();
752
794
  // One packet per flush: ops first, then applied entries, then verdicts.
753
795
  for (const conn of [...h.conns]) {
754
- if (!conn.ready) continue;
796
+ if (!conn.ready || expireLease(h, conn)) continue;
755
797
  const forConn = (list: Cmd[] | undefined) =>
756
798
  (list ?? []).filter((cmd) => selects(conn, cmd.protocol));
757
799
  const ops = [
@@ -1343,6 +1385,7 @@ const connectAuthorized = (
1343
1385
  options.selection,
1344
1386
  undefined,
1345
1387
  options.authorizedAt,
1388
+ { ...options, timedLease: h.leaseTimers },
1346
1389
  );
1347
1390
  return registration?.connection ?? null;
1348
1391
  }
@@ -1496,6 +1539,12 @@ const connectAuthorized = (
1496
1539
  selection,
1497
1540
  frame,
1498
1541
  authorizedAt,
1542
+ {
1543
+ timedLease: h.leaseTimers,
1544
+ ...(options.onIncludedChange !== undefined && {
1545
+ onIncludedChange: options.onIncludedChange,
1546
+ }),
1547
+ },
1499
1548
  );
1500
1549
  } catch (error) {
1501
1550
  if (violationReason(error) === null) throw error;
@@ -1559,7 +1608,12 @@ export const register = (
1559
1608
  },
1560
1609
  frame: ParsedFrame = { cmd: [] },
1561
1610
  authorizedAt?: number,
1611
+ included: Pick<
1612
+ StatewireHostInternal.SocketConnectOptions,
1613
+ "included" | "onIncludedChange"
1614
+ > & { timedLease?: boolean } = {},
1562
1615
  ): Registration | null => {
1616
+ const restored = restoredIncluded(included.included ?? []);
1563
1617
  const refuse = (code: number, reason: string) => {
1564
1618
  try {
1565
1619
  socket.close(code, reason);
@@ -1633,10 +1687,12 @@ export const register = (
1633
1687
  auth,
1634
1688
  authorizedAt,
1635
1689
  leaseTimer: null,
1690
+ timedLease: included.timedLease ?? true,
1636
1691
  lanes: new Map(),
1637
1692
  contexts: new Map(),
1638
1693
  documents: new Map(),
1639
- included: new Set(),
1694
+ included: restored,
1695
+ onIncludedChange: included.onIncludedChange,
1640
1696
  view: new Map(),
1641
1697
  nextDoc: 1,
1642
1698
  pendingApplied: [],
@@ -1814,6 +1870,7 @@ const useSocketHost = (
1814
1870
  wireVersion: { version: WIRE_VERSION },
1815
1871
  heartbeatMs: 15_000,
1816
1872
  maxLeaseLifetimeMs: 86_400_000,
1873
+ leaseTimers: persistence?.hibernatable !== true,
1817
1874
  wsInitTimeoutMs: 5_000,
1818
1875
  maxSubscribers: MAX_SUBSCRIBERS,
1819
1876
  maxInflightCommands: MAX_INFLIGHT_COMMANDS_PER_HOST,