statewire 0.12.2 → 0.13.0

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.
@@ -22,6 +22,7 @@ type Core = {
22
22
  notifiedOverlayPaths: readonly StatewirePath[];
23
23
  notifiedConnection: StatewireClient.Connection | null;
24
24
  notifiedBusy: boolean;
25
+ notifiedFailed: readonly StatewireClient.FailedCommand[];
25
26
  stale: boolean;
26
27
  everAttached: boolean;
27
28
  overlaysDirty: boolean;
@@ -32,6 +33,7 @@ type Core = {
32
33
  commandsListener: CommandsListener;
33
34
  getState: () => unknown;
34
35
  getBusy: () => boolean;
36
+ getFailed: () => readonly StatewireClient.FailedCommand[];
35
37
  commands: Statewire.CommandsProxy<any>;
36
38
  subscribe: (listener: () => void) => () => void;
37
39
  };
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","names":[],"sources":["../../src/client/core.ts"],"mappings":";;;;;cAYa,iBAAiB,gBAAgB;KAczC;EAAY,KAAK;EAAoB;;KAErC;EACH,kBAAkB,gBAAgB;EAClC,OAAO;EACP,QAAQ,UAAU;EAClB,UAAU;EACV,SAAS,UAAU;EACnB,gBAAgB;EAChB;EACA;EACA,uBAAuB;EACvB;EACA,+BAA+B;EAC/B,oBAAoB,gBAAgB;EACpC;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;EACX;EACA,kBAAkB;EAClB;EACA;EACA,UAAU,UAAU;EACpB,YAAY;;cAyMD,mBACX,kBAAkB,gBAAgB,mBAClC,OAAO,uBAAkB"}
1
+ {"version":3,"file":"core.d.ts","names":[],"sources":["../../src/client/core.ts"],"mappings":";;;;;cAYa,iBAAiB,gBAAgB;KAgBzC;EAAY,KAAK;EAAoB;;KAErC;EACH,kBAAkB,gBAAgB;EAClC,OAAO;EACP,QAAQ,UAAU;EAClB,UAAU;EACV,SAAS,UAAU;EACnB,gBAAgB;EAChB;EACA;EACA,uBAAuB;EACvB;EACA,+BAA+B;EAC/B,oBAAoB,gBAAgB;EACpC;EACA,yBAAyB,gBAAgB;EACzC;EACA;EACA;EACA;EACA;EACA,WAAW;EACX;EACA,kBAAkB;EAClB;EACA;EACA,0BAA0B,gBAAgB;EAC1C,UAAU,UAAU;EACpB,YAAY;;cA+ND,mBACX,kBAAkB,gBAAgB,mBAClC,OAAO,uBAAkB"}
@@ -10,6 +10,7 @@ const LIVE_CONNECTION = {
10
10
  status: "live",
11
11
  reconnect: () => {}
12
12
  };
13
+ const NO_FAILED = [];
13
14
  const failureOf = (error) => error instanceof StatewireSendError ? error.failure : {
14
15
  fate: "rejected",
15
16
  cause: "server",
@@ -45,11 +46,18 @@ const drainCanonical = (c) => {
45
46
  }
46
47
  }
47
48
  };
49
+ const dropCovered = (c) => {
50
+ const { failureCovered } = c.getOptions();
51
+ const failures = c.value?.failures;
52
+ if (!failureCovered || !failures || c.canonical === void 0) return;
53
+ for (const entry of failures.list()) if (failureCovered(c.canonical, entry)) failures.discard(entry);
54
+ };
48
55
  const recompute = (c) => {
49
56
  if (!c.stale || !c.value) return;
50
57
  c.stale = false;
51
58
  const prevCanonical = c.canonical;
52
59
  drainCanonical(c);
60
+ if (c.canonical !== prevCanonical) dropCovered(c);
53
61
  if (c.canonical === prevCanonical && !c.overlaysDirty) return;
54
62
  c.overlaysDirty = false;
55
63
  const { optimistic, materialize } = c.getOptions();
@@ -86,7 +94,7 @@ const recompute = (c) => {
86
94
  c.overlayPaths = paths;
87
95
  };
88
96
  const getConnection = (c) => c.value?.connection ?? LIVE_CONNECTION;
89
- const flush = (c) => {
97
+ const flush = (c, scheduled = false) => {
90
98
  if (!c.value) return;
91
99
  if (c.flushing) {
92
100
  schedule(c);
@@ -121,7 +129,15 @@ const flush = (c) => {
121
129
  const busy = c.getBusy();
122
130
  const busyChanged = busy !== c.notifiedBusy;
123
131
  c.notifiedBusy = busy;
124
- if (stateChanged || connectionChanged || busyChanged) for (const listener of [...c.listeners]) listener();
132
+ const failed = c.value.failures?.list() ?? NO_FAILED;
133
+ let failedChanged = false;
134
+ if (failed !== c.notifiedFailed) {
135
+ if (scheduled) {
136
+ c.notifiedFailed = failed;
137
+ failedChanged = true;
138
+ } else schedule(c);
139
+ }
140
+ if (stateChanged || connectionChanged || busyChanged || failedChanged) for (const listener of [...c.listeners]) listener();
125
141
  } finally {
126
142
  c.flushing = false;
127
143
  }
@@ -185,6 +201,7 @@ const useStatewireCore = (getOptions, value) => {
185
201
  notifiedOverlayPaths: [],
186
202
  notifiedConnection: null,
187
203
  notifiedBusy: true,
204
+ notifiedFailed: NO_FAILED,
188
205
  stale: false,
189
206
  everAttached: false,
190
207
  overlaysDirty: false,
@@ -193,7 +210,7 @@ const useStatewireCore = (getOptions, value) => {
193
210
  listeners: /* @__PURE__ */ new Set(),
194
211
  post: createMacrotaskPoster(() => {
195
212
  c.scheduled = false;
196
- flush(c);
213
+ flush(c, true);
197
214
  }),
198
215
  commandsListener: {
199
216
  onStart: (inv) => {
@@ -223,6 +240,7 @@ const useStatewireCore = (getOptions, value) => {
223
240
  return c.published;
224
241
  },
225
242
  getBusy: () => c.value?.isBusy ?? true,
243
+ getFailed: () => c.notifiedFailed,
226
244
  commands: createMethodProxy((method, params) => {
227
245
  if (!c.value) return Promise.reject(new StatewireSendError({
228
246
  fate: "aborted",
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","names":["useEffect","useState","createChanges","getCommandsHost","getStateHost","CommandsInvocation","CommandsListener","recordMutations","createMacrotaskPoster","createMethodProxy","StatewirePath","StatewireSendError","Statewire","StatewireClient","LIVE_CONNECTION","Connection","status","reconnect","failureOf","error","SendFailure","failure","fate","cause","message","Error","String","Overlay","inv","dropped","Core","getOptions","Options","value","source","StateSource","overlays","updates","CommandUpdate","pendingChanged","canonical","published","overlayPaths","notifiedPublished","notifiedOverlayPaths","notifiedConnection","notifiedBusy","stale","everAttached","overlaysDirty","flushing","scheduled","listeners","Set","post","commandsListener","getState","getBusy","commands","CommandsProxy","subscribe","listener","schedule","c","markStale","drainCanonical","push","takeChanged","snapshot","undefined","next","initialState","state","recompute","prevCanonical","optimistic","materialize","paths","overlay","ctx","OptimisticContext","ts","seq","clientId","recorded","draft","method","params","Command","changedPaths","console","getConnection","connection","flush","options","stateChanged","prev","changed","onStateChange","changes","length","batch","update","onCommandChange","connectionChanged","onConnectionChange","busy","busyChanged","note","extra","result","attach","nextSource","setOnChange","setListener","detach","useStatewireCore","core","onStart","onPosted","onApplied","onCovered","some","o","filter","onSettle","outcome","type","payload","isBusy","Promise","reject","send","Record","args","promise","add","delete"],"sources":["../../src/client/core.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { createChanges } from \"./changes\";\nimport { getCommandsHost, getStateHost } from \"../host/host\";\nimport type { CommandsInvocation, CommandsListener } from \"../host/host\";\nimport { recordMutations } from \"../util/recordMutations\";\nimport { createMacrotaskPoster } from \"../util/macrotask\";\nimport { createMethodProxy } from \"../util/methodProxy\";\nimport type { StatewirePath } from \"../wire/ops\";\nimport { StatewireSendError } from \"../types\";\nimport type { Statewire } from \"../types\";\nimport type { StatewireClient } from \"../statewire\";\n\nexport const LIVE_CONNECTION: StatewireClient.Connection = {\n status: \"live\",\n reconnect: () => {},\n};\n\nconst failureOf = (error: unknown): StatewireClient.SendFailure =>\n error instanceof StatewireSendError\n ? error.failure\n : {\n fate: \"rejected\",\n cause: \"server\",\n message: error instanceof Error ? error.message : String(error),\n };\n\ntype Overlay = { inv: CommandsInvocation; dropped: boolean };\n\ntype Core = {\n getOptions: () => StatewireClient.Options<any, any>;\n value: Statewire<unknown> | null;\n source: Statewire.StateSource | null;\n overlays: Overlay[];\n updates: Statewire.CommandUpdate[];\n pendingChanged: StatewirePath[];\n canonical: unknown;\n published: unknown;\n overlayPaths: readonly StatewirePath[];\n notifiedPublished: unknown;\n notifiedOverlayPaths: readonly StatewirePath[];\n notifiedConnection: StatewireClient.Connection | null;\n notifiedBusy: boolean;\n stale: boolean;\n everAttached: boolean;\n overlaysDirty: boolean;\n flushing: boolean;\n scheduled: boolean;\n listeners: Set<() => void>;\n post: () => void;\n commandsListener: CommandsListener;\n getState: () => unknown;\n getBusy: () => boolean;\n commands: Statewire.CommandsProxy<any>;\n subscribe: (listener: () => void) => () => void;\n};\n\nconst schedule = (c: Core) => {\n if (c.scheduled) return;\n c.scheduled = true;\n c.post();\n};\n\nconst markStale = (c: Core) => {\n c.stale = true;\n schedule(c);\n};\n\n// initialState stands in for the canonical state only before the first\n// attach snapshot; replay boundaries after that read as loading, not preload.\nconst drainCanonical = (c: Core) => {\n if (c.source) {\n c.pendingChanged.push(...c.source.takeChanged());\n const snapshot = c.source.snapshot();\n if (snapshot !== undefined) {\n c.everAttached = true;\n c.canonical = snapshot;\n return;\n }\n const next = c.everAttached ? undefined : c.getOptions().initialState;\n if (next !== c.canonical) c.pendingChanged.push([]);\n c.canonical = next;\n } else if (c.value) {\n if (c.value.state !== undefined) c.everAttached = true;\n const next = c.everAttached ? c.value.state : c.getOptions().initialState;\n if (next !== c.canonical) {\n c.pendingChanged.push([]);\n c.canonical = next;\n }\n }\n};\n\nconst recompute = (c: Core) => {\n if (!c.stale || !c.value) return;\n c.stale = false;\n const prevCanonical = c.canonical;\n drainCanonical(c);\n if (c.canonical === prevCanonical && !c.overlaysDirty) return;\n c.overlaysDirty = false;\n const { optimistic, materialize } = c.getOptions();\n let next = c.canonical;\n let paths: readonly StatewirePath[] = [];\n if (optimistic && c.canonical !== undefined) {\n for (const overlay of c.overlays) {\n if (overlay.dropped) continue;\n const { inv } = overlay;\n const ctx: StatewireClient.OptimisticContext = {\n ts: inv.ts,\n seq: inv.seq,\n ...(inv.clientId !== undefined && { clientId: inv.clientId }),\n };\n try {\n const recorded = recordMutations(next, (draft) =>\n optimistic(\n draft as never,\n { method: inv.method, params: inv.params } as Statewire.Command,\n ctx,\n ),\n );\n next = recorded.state;\n paths = [...paths, ...recorded.changedPaths];\n } catch (error) {\n overlay.dropped = true;\n console.error(\n `statewire: optimistic reducer threw for \"${inv.method}\"; dropping its optimistic update`,\n error,\n );\n }\n }\n }\n if (materialize && next !== undefined) {\n try {\n const recorded = recordMutations(next, (draft) =>\n materialize(draft as never),\n );\n next = recorded.state;\n paths = [...paths, ...recorded.changedPaths];\n } catch (error) {\n console.error(\n \"statewire: materialize threw; publishing without its update\",\n error,\n );\n }\n }\n c.published = next;\n c.overlayPaths = paths;\n};\n\nconst getConnection = (c: Core): StatewireClient.Connection =>\n c.value?.connection ?? LIVE_CONNECTION;\n\nconst flush = (c: Core) => {\n if (!c.value) return;\n if (c.flushing) {\n schedule(c);\n return;\n }\n c.flushing = true;\n try {\n recompute(c);\n const options = c.getOptions();\n const stateChanged = c.published !== c.notifiedPublished;\n if (stateChanged) {\n const prev = c.notifiedPublished;\n const changed = [\n ...c.pendingChanged,\n ...c.notifiedOverlayPaths,\n ...c.overlayPaths,\n ];\n c.pendingChanged = [];\n c.notifiedPublished = c.published;\n c.notifiedOverlayPaths = c.overlayPaths;\n options.onStateChange?.(c.published as never, {\n changes: createChanges(prev, c.published, changed),\n });\n }\n if (c.updates.length > 0 && c.published !== undefined) {\n const batch = c.updates;\n c.updates = [];\n for (const update of batch) {\n options.onCommandChange?.(update, { state: c.published as never });\n }\n }\n const connection = getConnection(c);\n const connectionChanged = connection !== c.notifiedConnection;\n c.notifiedConnection = connection;\n if (connectionChanged) options.onConnectionChange?.(connection);\n const busy = c.getBusy();\n const busyChanged = busy !== c.notifiedBusy;\n c.notifiedBusy = busy;\n if (stateChanged || connectionChanged || busyChanged) {\n for (const listener of [...c.listeners]) listener();\n }\n } finally {\n c.flushing = false;\n }\n};\n\nconst note = (\n c: Core,\n inv: CommandsInvocation,\n status: Statewire.CommandUpdate[\"status\"],\n extra?: { result?: unknown; failure?: StatewireClient.SendFailure },\n) => {\n if (!c.getOptions().onCommandChange) return;\n c.updates.push({\n method: inv.method,\n params: inv.params as never[],\n seq: inv.seq,\n status,\n ...extra,\n });\n schedule(c);\n};\n\nconst attach = (c: Core, next: Statewire<unknown>) => {\n if (next === c.value) return;\n const prev = c.value;\n c.value = next;\n const nextSource =\n next.source ??\n (typeof next.state === \"object\" && next.state !== null\n ? getStateHost(next.state)\n : undefined) ??\n null;\n if (nextSource !== c.source) {\n c.source?.setOnChange(null);\n c.source = nextSource;\n c.source?.setOnChange(() => markStale(c));\n // A new source is a new attach lifecycle: initialState preloads again.\n c.everAttached = false;\n markStale(c);\n }\n if (next.commands !== prev?.commands) {\n if (prev) getCommandsHost(prev.commands)?.setListener(null);\n getCommandsHost(next.commands)?.setListener(c.commandsListener);\n if (c.overlays.length > 0) {\n c.overlays = [];\n c.overlaysDirty = true;\n }\n markStale(c);\n }\n if (!c.source) markStale(c);\n schedule(c);\n};\n\nconst detach = (c: Core) => {\n c.source?.setOnChange(null);\n c.source = null;\n if (c.value) {\n getCommandsHost(c.value.commands)?.setListener(null);\n c.value = null;\n }\n};\n\nexport const useStatewireCore = (\n getOptions: () => StatewireClient.Options<any, any>,\n value: Statewire<unknown>,\n) => {\n const [core] = useState((): Core => {\n const c: Core = {\n getOptions,\n value: null,\n source: null,\n overlays: [],\n updates: [],\n pendingChanged: [],\n canonical: undefined,\n published: undefined,\n overlayPaths: [],\n notifiedPublished: undefined,\n notifiedOverlayPaths: [],\n notifiedConnection: null,\n notifiedBusy: true,\n stale: false,\n everAttached: false,\n overlaysDirty: false,\n flushing: false,\n scheduled: false,\n listeners: new Set(),\n post: createMacrotaskPoster(() => {\n c.scheduled = false;\n flush(c);\n }),\n commandsListener: {\n onStart: (inv) => {\n c.overlays.push({ inv, dropped: false });\n c.overlaysDirty = true;\n markStale(c);\n note(c, inv, \"queued\");\n },\n onPosted: (inv) => note(c, inv, \"posted\"),\n onApplied: (inv) => note(c, inv, \"applied\"),\n onCovered: (inv) => {\n if (!c.overlays.some((o) => o.inv === inv)) return;\n c.overlays = c.overlays.filter((o) => o.inv !== inv);\n c.overlaysDirty = true;\n markStale(c);\n },\n onSettle: (inv, outcome) => {\n note(\n c,\n inv,\n \"settled\",\n outcome.type === \"accepted\"\n ? { result: outcome.payload }\n : { failure: failureOf(outcome.error) },\n );\n flush(c);\n },\n },\n getState: () => {\n recompute(c);\n return c.published;\n },\n getBusy: () => c.value?.isBusy ?? true,\n commands: createMethodProxy<Statewire.CommandsProxy<any>>(\n (method, params) => {\n if (!c.value) {\n return Promise.reject(\n new StatewireSendError({ fate: \"aborted\", cause: \"unmount\" }),\n );\n }\n const send = (\n c.value.commands as Record<\n string,\n (...args: unknown[]) => Promise<unknown>\n >\n )[method]!;\n const promise = send(...params);\n flush(c);\n return promise;\n },\n ),\n subscribe: (listener) => {\n c.listeners.add(listener);\n return () => {\n c.listeners.delete(listener);\n };\n },\n };\n return c;\n });\n core.getOptions = getOptions;\n // Attach during render so the first snapshot reads the transport's state;\n // re-attaching the same transport is a no-op and the single-slot host\n // listeners make a swap land on the last writer.\n attach(core, value);\n useEffect(() => {\n attach(core, value);\n });\n useEffect(() => () => detach(core), [core]);\n return core;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"core.js","names":["useEffect","useState","createChanges","getCommandsHost","getStateHost","CommandsInvocation","CommandsListener","recordMutations","createMacrotaskPoster","createMethodProxy","StatewirePath","StatewireSendError","Statewire","StatewireClient","LIVE_CONNECTION","Connection","status","reconnect","NO_FAILED","FailedCommand","failureOf","error","SendFailure","failure","fate","cause","message","Error","String","Overlay","inv","dropped","Core","getOptions","Options","value","source","StateSource","overlays","updates","CommandUpdate","pendingChanged","canonical","published","overlayPaths","notifiedPublished","notifiedOverlayPaths","notifiedConnection","notifiedBusy","notifiedFailed","stale","everAttached","overlaysDirty","flushing","scheduled","listeners","Set","post","commandsListener","getState","getBusy","getFailed","commands","CommandsProxy","subscribe","listener","schedule","c","markStale","drainCanonical","push","takeChanged","snapshot","undefined","next","initialState","state","dropCovered","failureCovered","failures","entry","list","discard","recompute","prevCanonical","optimistic","materialize","paths","overlay","ctx","OptimisticContext","ts","seq","clientId","recorded","draft","method","params","Command","changedPaths","console","getConnection","connection","flush","options","stateChanged","prev","changed","onStateChange","changes","length","batch","update","onCommandChange","connectionChanged","onConnectionChange","busy","busyChanged","failed","failedChanged","note","extra","result","attach","nextSource","setOnChange","setListener","detach","useStatewireCore","core","onStart","onPosted","onApplied","onCovered","some","o","filter","onSettle","outcome","type","payload","isBusy","Promise","reject","send","Record","args","promise","add","delete"],"sources":["../../src/client/core.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { createChanges } from \"./changes\";\nimport { getCommandsHost, getStateHost } from \"../host/host\";\nimport type { CommandsInvocation, CommandsListener } from \"../host/host\";\nimport { recordMutations } from \"../util/recordMutations\";\nimport { createMacrotaskPoster } from \"../util/macrotask\";\nimport { createMethodProxy } from \"../util/methodProxy\";\nimport type { StatewirePath } from \"../wire/ops\";\nimport { StatewireSendError } from \"../types\";\nimport type { Statewire } from \"../types\";\nimport type { StatewireClient } from \"../statewire\";\n\nexport const LIVE_CONNECTION: StatewireClient.Connection = {\n status: \"live\",\n reconnect: () => {},\n};\n\nconst NO_FAILED: readonly StatewireClient.FailedCommand[] = [];\n\nconst failureOf = (error: unknown): StatewireClient.SendFailure =>\n error instanceof StatewireSendError\n ? error.failure\n : {\n fate: \"rejected\",\n cause: \"server\",\n message: error instanceof Error ? error.message : String(error),\n };\n\ntype Overlay = { inv: CommandsInvocation; dropped: boolean };\n\ntype Core = {\n getOptions: () => StatewireClient.Options<any, any>;\n value: Statewire<unknown> | null;\n source: Statewire.StateSource | null;\n overlays: Overlay[];\n updates: Statewire.CommandUpdate[];\n pendingChanged: StatewirePath[];\n canonical: unknown;\n published: unknown;\n overlayPaths: readonly StatewirePath[];\n notifiedPublished: unknown;\n notifiedOverlayPaths: readonly StatewirePath[];\n notifiedConnection: StatewireClient.Connection | null;\n notifiedBusy: boolean;\n notifiedFailed: readonly StatewireClient.FailedCommand[];\n stale: boolean;\n everAttached: boolean;\n overlaysDirty: boolean;\n flushing: boolean;\n scheduled: boolean;\n listeners: Set<() => void>;\n post: () => void;\n commandsListener: CommandsListener;\n getState: () => unknown;\n getBusy: () => boolean;\n getFailed: () => readonly StatewireClient.FailedCommand[];\n commands: Statewire.CommandsProxy<any>;\n subscribe: (listener: () => void) => () => void;\n};\n\nconst schedule = (c: Core) => {\n if (c.scheduled) return;\n c.scheduled = true;\n c.post();\n};\n\nconst markStale = (c: Core) => {\n c.stale = true;\n schedule(c);\n};\n\n// initialState stands in for the canonical state only before the first\n// attach snapshot; replay boundaries after that read as loading, not preload.\nconst drainCanonical = (c: Core) => {\n if (c.source) {\n c.pendingChanged.push(...c.source.takeChanged());\n const snapshot = c.source.snapshot();\n if (snapshot !== undefined) {\n c.everAttached = true;\n c.canonical = snapshot;\n return;\n }\n const next = c.everAttached ? undefined : c.getOptions().initialState;\n if (next !== c.canonical) c.pendingChanged.push([]);\n c.canonical = next;\n } else if (c.value) {\n if (c.value.state !== undefined) c.everAttached = true;\n const next = c.everAttached ? c.value.state : c.getOptions().initialState;\n if (next !== c.canonical) {\n c.pendingChanged.push([]);\n c.canonical = next;\n }\n }\n};\n\nconst dropCovered = (c: Core) => {\n const { failureCovered } = c.getOptions();\n const failures = c.value?.failures;\n if (!failureCovered || !failures || c.canonical === undefined) return;\n for (const entry of failures.list()) {\n if (failureCovered(c.canonical as never, entry)) failures.discard(entry);\n }\n};\n\nconst recompute = (c: Core) => {\n if (!c.stale || !c.value) return;\n c.stale = false;\n const prevCanonical = c.canonical;\n drainCanonical(c);\n if (c.canonical !== prevCanonical) dropCovered(c);\n if (c.canonical === prevCanonical && !c.overlaysDirty) return;\n c.overlaysDirty = false;\n const { optimistic, materialize } = c.getOptions();\n let next = c.canonical;\n let paths: readonly StatewirePath[] = [];\n if (optimistic && c.canonical !== undefined) {\n for (const overlay of c.overlays) {\n if (overlay.dropped) continue;\n const { inv } = overlay;\n const ctx: StatewireClient.OptimisticContext = {\n ts: inv.ts,\n seq: inv.seq,\n ...(inv.clientId !== undefined && { clientId: inv.clientId }),\n };\n try {\n const recorded = recordMutations(next, (draft) =>\n optimistic(\n draft as never,\n { method: inv.method, params: inv.params } as Statewire.Command,\n ctx,\n ),\n );\n next = recorded.state;\n paths = [...paths, ...recorded.changedPaths];\n } catch (error) {\n overlay.dropped = true;\n console.error(\n `statewire: optimistic reducer threw for \"${inv.method}\"; dropping its optimistic update`,\n error,\n );\n }\n }\n }\n if (materialize && next !== undefined) {\n try {\n const recorded = recordMutations(next, (draft) =>\n materialize(draft as never),\n );\n next = recorded.state;\n paths = [...paths, ...recorded.changedPaths];\n } catch (error) {\n console.error(\n \"statewire: materialize threw; publishing without its update\",\n error,\n );\n }\n }\n c.published = next;\n c.overlayPaths = paths;\n};\n\nconst getConnection = (c: Core): StatewireClient.Connection =>\n c.value?.connection ?? LIVE_CONNECTION;\n\nconst flush = (c: Core, scheduled = false) => {\n if (!c.value) return;\n if (c.flushing) {\n schedule(c);\n return;\n }\n c.flushing = true;\n try {\n recompute(c);\n const options = c.getOptions();\n const stateChanged = c.published !== c.notifiedPublished;\n if (stateChanged) {\n const prev = c.notifiedPublished;\n const changed = [\n ...c.pendingChanged,\n ...c.notifiedOverlayPaths,\n ...c.overlayPaths,\n ];\n c.pendingChanged = [];\n c.notifiedPublished = c.published;\n c.notifiedOverlayPaths = c.overlayPaths;\n options.onStateChange?.(c.published as never, {\n changes: createChanges(prev, c.published, changed),\n });\n }\n if (c.updates.length > 0 && c.published !== undefined) {\n const batch = c.updates;\n c.updates = [];\n for (const update of batch) {\n options.onCommandChange?.(update, { state: c.published as never });\n }\n }\n const connection = getConnection(c);\n const connectionChanged = connection !== c.notifiedConnection;\n c.notifiedConnection = connection;\n if (connectionChanged) options.onConnectionChange?.(connection);\n const busy = c.getBusy();\n const busyChanged = busy !== c.notifiedBusy;\n c.notifiedBusy = busy;\n // The failed snapshot advances only on the scheduled pass: settles land\n // mid-unmount, where a changed snapshot re-renders the unmounting tree.\n const failed = c.value.failures?.list() ?? NO_FAILED;\n let failedChanged = false;\n if (failed !== c.notifiedFailed) {\n if (scheduled) {\n c.notifiedFailed = failed;\n failedChanged = true;\n } else {\n schedule(c);\n }\n }\n if (stateChanged || connectionChanged || busyChanged || failedChanged) {\n for (const listener of [...c.listeners]) listener();\n }\n } finally {\n c.flushing = false;\n }\n};\n\nconst note = (\n c: Core,\n inv: CommandsInvocation,\n status: Statewire.CommandUpdate[\"status\"],\n extra?: { result?: unknown; failure?: StatewireClient.SendFailure },\n) => {\n if (!c.getOptions().onCommandChange) return;\n c.updates.push({\n method: inv.method,\n params: inv.params as never[],\n seq: inv.seq,\n status,\n ...extra,\n });\n schedule(c);\n};\n\nconst attach = (c: Core, next: Statewire<unknown>) => {\n if (next === c.value) return;\n const prev = c.value;\n c.value = next;\n const nextSource =\n next.source ??\n (typeof next.state === \"object\" && next.state !== null\n ? getStateHost(next.state)\n : undefined) ??\n null;\n if (nextSource !== c.source) {\n c.source?.setOnChange(null);\n c.source = nextSource;\n c.source?.setOnChange(() => markStale(c));\n // A new source is a new attach lifecycle: initialState preloads again.\n c.everAttached = false;\n markStale(c);\n }\n if (next.commands !== prev?.commands) {\n if (prev) getCommandsHost(prev.commands)?.setListener(null);\n getCommandsHost(next.commands)?.setListener(c.commandsListener);\n if (c.overlays.length > 0) {\n c.overlays = [];\n c.overlaysDirty = true;\n }\n markStale(c);\n }\n if (!c.source) markStale(c);\n schedule(c);\n};\n\nconst detach = (c: Core) => {\n c.source?.setOnChange(null);\n c.source = null;\n if (c.value) {\n getCommandsHost(c.value.commands)?.setListener(null);\n c.value = null;\n }\n};\n\nexport const useStatewireCore = (\n getOptions: () => StatewireClient.Options<any, any>,\n value: Statewire<unknown>,\n) => {\n const [core] = useState((): Core => {\n const c: Core = {\n getOptions,\n value: null,\n source: null,\n overlays: [],\n updates: [],\n pendingChanged: [],\n canonical: undefined,\n published: undefined,\n overlayPaths: [],\n notifiedPublished: undefined,\n notifiedOverlayPaths: [],\n notifiedConnection: null,\n notifiedBusy: true,\n notifiedFailed: NO_FAILED,\n stale: false,\n everAttached: false,\n overlaysDirty: false,\n flushing: false,\n scheduled: false,\n listeners: new Set(),\n post: createMacrotaskPoster(() => {\n c.scheduled = false;\n flush(c, true);\n }),\n commandsListener: {\n onStart: (inv) => {\n c.overlays.push({ inv, dropped: false });\n c.overlaysDirty = true;\n markStale(c);\n note(c, inv, \"queued\");\n },\n onPosted: (inv) => note(c, inv, \"posted\"),\n onApplied: (inv) => note(c, inv, \"applied\"),\n onCovered: (inv) => {\n if (!c.overlays.some((o) => o.inv === inv)) return;\n c.overlays = c.overlays.filter((o) => o.inv !== inv);\n c.overlaysDirty = true;\n markStale(c);\n },\n onSettle: (inv, outcome) => {\n note(\n c,\n inv,\n \"settled\",\n outcome.type === \"accepted\"\n ? { result: outcome.payload }\n : { failure: failureOf(outcome.error) },\n );\n flush(c);\n },\n },\n getState: () => {\n recompute(c);\n return c.published;\n },\n getBusy: () => c.value?.isBusy ?? true,\n getFailed: () => c.notifiedFailed,\n commands: createMethodProxy<Statewire.CommandsProxy<any>>(\n (method, params) => {\n if (!c.value) {\n return Promise.reject(\n new StatewireSendError({ fate: \"aborted\", cause: \"unmount\" }),\n );\n }\n const send = (\n c.value.commands as Record<\n string,\n (...args: unknown[]) => Promise<unknown>\n >\n )[method]!;\n const promise = send(...params);\n flush(c);\n return promise;\n },\n ),\n subscribe: (listener) => {\n c.listeners.add(listener);\n return () => {\n c.listeners.delete(listener);\n };\n },\n };\n return c;\n });\n core.getOptions = getOptions;\n // Attach during render so the first snapshot reads the transport's state;\n // re-attaching the same transport is a no-op and the single-slot host\n // listeners make a swap land on the last writer.\n attach(core, value);\n useEffect(() => {\n attach(core, value);\n });\n useEffect(() => () => detach(core), [core]);\n return core;\n};\n"],"mappings":"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"}
@@ -73,9 +73,12 @@ type Session = {
73
73
  notify: () => void;
74
74
  commands: Record<string, (...params: unknown[]) => Promise<unknown>>;
75
75
  };
76
+ declare const failedCommands: (s: Session) => readonly StatewireClient.FailedCommand[];
76
77
  declare const setTransport: (s: Session, transport: RemoteLink) => void;
78
+ declare const discardFailed: (s: Session, entry: StatewireClient.FailedCommand) => void;
79
+ declare const retryFailed: (s: Session, entry: StatewireClient.FailedCommand) => Promise<unknown>;
77
80
  declare const setContext: (s: Session, value: Record<string, unknown>) => void;
78
81
  declare const useStatewireSession: (options: StatewireSessionOptions) => Session;
79
82
  //#endregion
80
- export { StatewireSessionOptions, setContext, setTransport, useStatewireSession };
83
+ export { StatewireSessionOptions, discardFailed, failedCommands, retryFailed, setContext, setTransport, useStatewireSession };
81
84
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","names":[],"sources":["../../src/client/session.ts"],"mappings":";;;;;;KA6BK;EACH;EACA;EACA;;KAGG;WACM;WACA,SAAS;WACT,KAAK;;EAEd;;EAEA;;EAEA;EACA,UAAU;EACV,SAAS,OAAO;;KAGb;WACM;WACA;EACT;;KAiBG;KAEO;EACV,eAAe,gBAAgB;EAC/B,gBAAgB,gBAAgB;EAChC;;KAGG;EACH,KAAK;EACL,QAAQ,gBAAgB;EACxB;;KAGG;EACH,QAAQ,gBAAgB;EACxB,KAAK;EACL;EACA,OAAO,gBAAgB;EACvB,QAAQ;EACR;;EAEA;EACA;EACA;EACA;EACA;EACA,eAAe,gBAAgB;EAC/B;EACA;EACA,YAAY;EACZ;EACA,0BAA0B,qBAAqB;EAC/C;EACA,SAAS;EACT;EACA;EACA,SAAS;EACT,QAAQ,UAAU;EAClB,QAAQ;EACR;EACA;EACA;EACA,WAAW;EACX;EACA,WAAW;EACX;EACA,UAAU,mBAAmB,sBAAsB;;cA4oB/C,eAAgB,GAAG,SAAS,WAAW;cA8GvC,aAAc,GAAG,SAAS,OAAO;cAgC1B,sBACX,SAAS,4BACR"}
1
+ {"version":3,"file":"session.d.ts","names":[],"sources":["../../src/client/session.ts"],"mappings":";;;;;;KA6BK;EACH;EACA;EACA;;KAGG;WACM;WACA,SAAS;WACT,KAAK;;EAEd;;EAEA;;EAEA;EACA,UAAU;EACV,SAAS,OAAO;;KAGb;WACM;WACA;EACT;;KAiBG;KAEO;EACV,eAAe,gBAAgB;EAC/B,gBAAgB,gBAAgB;EAChC;;KAGG;EACH,KAAK;EACL,QAAQ,gBAAgB;EACxB;;KAGG;EACH,QAAQ,gBAAgB;EACxB,KAAK;EACL;EACA,OAAO,gBAAgB;EACvB,QAAQ;EACR;;EAEA;EACA;EACA;EACA;EACA;EACA,eAAe,gBAAgB;EAC/B;EACA;EACA,YAAY;EACZ;EACA,0BAA0B,qBAAqB;EAC/C;EACA,SAAS;EACT;EACA;EACA,SAAS;EACT,QAAQ,UAAU;EAClB,QAAQ;EACR;EACA;EACA;EACA,WAAW;EACX;EACA,WAAW;EACX;EACA,UAAU,mBAAmB,sBAAsB;;cAwHxC,iBACX,GAAG,qBACO,gBAAgB;cA8jBtB,eAAgB,GAAG,SAAS,WAAW;cA+HhC,gBACX,GAAG,SACH,OAAO,gBAAgB;cAKZ,cACX,GAAG,SACH,OAAO,gBAAgB,kBACtB;cA6BG,aAAc,GAAG,SAAS,OAAO;cAgC1B,sBACX,SAAS,4BACR"}
@@ -97,6 +97,22 @@ const cover = (s, entry) => {
97
97
  s.lifecycle?.onApplied(entry.inv);
98
98
  s.lifecycle?.onCovered?.(entry.inv);
99
99
  };
100
+ const NO_FAILED = [];
101
+ const failedCommands = (s) => s.record.failed ?? NO_FAILED;
102
+ const retainFailed = (s, entry, failure) => {
103
+ setRecord(s, {
104
+ ...s.record,
105
+ failed: [...s.record.failed ?? [], {
106
+ command: entry.command.method,
107
+ params: entry.command.params,
108
+ ...entry.command.meta !== void 0 && { meta: entry.command.meta },
109
+ failure,
110
+ ts: entry.inv.ts,
111
+ seq: entry.seq
112
+ }]
113
+ });
114
+ s.notify();
115
+ };
100
116
  const settleEntry = (s, entry, outcome) => {
101
117
  s.pending = s.pending.filter((p) => p !== entry);
102
118
  if (outcome.ok) {
@@ -106,6 +122,7 @@ const settleEntry = (s, entry, outcome) => {
106
122
  payload: outcome.payload
107
123
  });
108
124
  } else {
125
+ if (!((outcome.failure.cause === "unmount" || outcome.failure.cause === "stream-gone") && entry.seq > s.durableSeq)) retainFailed(s, entry, outcome.failure);
109
126
  entry.reject(new StatewireSendError(outcome.failure));
110
127
  s.lifecycle?.onSettle(entry.inv, {
111
128
  type: "rejected",
@@ -173,7 +190,12 @@ const rebaseRecord = (s, adopt) => {
173
190
  settleLost(s, held.filter((p) => p.attempted || p.applied));
174
191
  s.pending = [];
175
192
  s.durableSeq = 0;
193
+ const failed = s.record.failed;
176
194
  adopt();
195
+ if (failed !== void 0 && s.record.failed !== failed) setRecord(s, {
196
+ ...s.record,
197
+ failed: [...s.record.failed ?? [], ...failed]
198
+ });
177
199
  for (const old of survivors) {
178
200
  s.lifecycle?.onCovered?.(old.inv);
179
201
  enqueueInner(s, old.command, old.inv.params, old.resolve, old.reject);
@@ -321,7 +343,8 @@ const sessionLostInner = (s, seqWm, ctxWm) => {
321
343
  clientId: s.record.clientId,
322
344
  nextSeq: seqWm + 1,
323
345
  ctxNextSeq: ctxWm + 1,
324
- commands: []
346
+ commands: [],
347
+ ...s.record.failed !== void 0 && { failed: s.record.failed }
325
348
  });
326
349
  restateContext(s);
327
350
  if (held.length > 0 && s.onSessionLost?.(held.map((p) => p.inv)) === "requeue") for (const old of held) enqueueInner(s, old.command, old.inv.params, () => {}, () => {});
@@ -630,6 +653,41 @@ const sendCommand = (s, method, params) => {
630
653
  result.catch(() => {});
631
654
  return result;
632
655
  };
656
+ const takeFailed = (s, entry) => {
657
+ const failed = s.record.failed ?? [];
658
+ const found = failed.find((f) => f.seq === entry.seq && f.ts === entry.ts && f.command === entry.command);
659
+ if (found === void 0) throw new Error(`statewire: unknown failed command "${entry.command}"`);
660
+ setRecord(s, {
661
+ ...s.record,
662
+ failed: failed.filter((f) => f !== found)
663
+ });
664
+ s.notify();
665
+ return found;
666
+ };
667
+ const discardFailed = (s, entry) => {
668
+ takeFailed(s, entry);
669
+ };
670
+ const retryFailed = (s, entry) => {
671
+ if (!s.running) return rejectedSend({
672
+ fate: "aborted",
673
+ cause: "unmount"
674
+ });
675
+ if (isFinished(s)) return rejectedSend({
676
+ fate: "aborted",
677
+ cause: "stream-gone"
678
+ });
679
+ const found = takeFailed(s, entry);
680
+ const params = found.meta === void 0 ? found.params : reviveValue([...found.params], found.meta);
681
+ const result = new Promise((resolve, reject) => {
682
+ enqueue(s, {
683
+ method: found.command,
684
+ params: [...found.params],
685
+ ...found.meta !== void 0 && { meta: found.meta }
686
+ }, params, resolve, reject);
687
+ });
688
+ result.catch(() => {});
689
+ return result;
690
+ };
633
691
  const setContext = (s, value) => {
634
692
  if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("statewire: context must be a plain object");
635
693
  if (!s.running || isFinished(s)) return;
@@ -754,6 +812,6 @@ const useStatewireSession = (options) => {
754
812
  return s;
755
813
  };
756
814
  //#endregion
757
- export { setContext, setTransport, useStatewireSession };
815
+ export { discardFailed, failedCommands, retryFailed, setContext, setTransport, useStatewireSession };
758
816
 
759
817
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","names":["useContext","useEffect","useState","applyOps","StatewirePath","TERMINAL","StatewireCmd","StatewireSyn","encodeParams","encodeValue","reviveResponse","reviveValue","bindCommandsHost","CommandsInvocation","CommandsListener","Statewire","StatewireClient","SessionStorageContext","createMemorySessionStore","backoff","createMethodProxy","randomId","StatewireSendError","RemoteLink","StatewireFrame","StatewireRemoteProps","WireCommand","method","params","meta","Pending","seq","command","inv","attempted","posted","applied","resolve","payload","reject","error","CtxPending","ops","protocolError","message","Error","newClientId","rejectedSend","failure","SendFailure","Promise","result","catch","AttachState","StatewireSessionOptions","sessionStore","SessionStorage","onSessionLost","OnSessionLost","onDone","Shared","txq","parked","SessionVerdict","unsubscribe","Session","record","SessionRecord","ctx","recordPersisted","store","shared","ephemeral","deactivated","sessionKnown","durableSeq","resumeAt","idle","ctxOps","ctxPending","lanesOnAttach","attachLaneSeqs","ReadonlySet","frameFailures","pending","canonical","lastPublished","changed","source","StateSource","attach","attachEpoch","running","pumping","transport","waiters","lifecycle","notify","commands","Record","publish","s","wake","waiter","waitForWake","r","push","sleepUntilWake","delayMs","clearTimeout","timer","setTimeout","filter","w","setRecord","save","backlog","SessionCommand","p","map","mergeBacklog","own","known","Set","foreign","c","has","sort","a","b","MAX_PARKED_VERDICTS","syncBacklogInner","splice","parkedSeqs","v","verdicts","length","slice","unchanged","every","i","undefined","syncBacklog","transact","fn","run","then","lock","stored","load","clientId","adoptReset","setIdle","level","cover","entry","onApplied","onCovered","settleEntry","outcome","ok","onSettle","type","settleAll","detach","cause","const","batch","detachFailure","predecessorLost","some","fate","restateContext","ctxNextSeq","settleLost","entries","rebaseRecord","adopt","held","survivors","old","enqueueInner","pump","resetRecord","nextSeq","ephemeralDetach","rejectedFailure","cmd","code","outcomeOf","String","TERMINAL_CMD_TYPES","parkVerdict","handleCmd","Number","isSafeInteger","dur","Math","max","find","consumeVerdicts","consumed","verdict","add","size","handleCmds","cmds","ingestOps","state","changedPaths","publishIngested","snapCtxClock","ctxWm","ctxAligned","sessionLostInner","seqWm","handleHello","syn","attachCmd","attachCtx","reconcile","adoptStored","ctxWatermark","ctxSeq","handleOps","handleRefusal","watermark","retry","Date","now","firstCmd","firstCtx","cmdGap","ctxGap","handleDetach","handleFinish","reason","isFinished","Lanes","frame","cmdEntries","ctxEntries","buildLanes","at","takeAttachLanes","wanted","lanes","connection","status","reconnect","resumeDelay","epoch","send","includes","onPosted","start","subscribe","stop","setTransport","ts","onStart","enqueue","sendCommand","encoded","setContext","value","Array","isArray","op","path","mint","useStatewireSession","options","defaultStore","mounted","session","onHello","args","onOps","onCmds","onRefusal","onIdle","onDetach","onFinish","snapshot","takeChanged","setOnChange","listener","setListener"],"sources":["../../src/client/session.ts"],"sourcesContent":["import { useContext, useEffect, useState } from \"react\";\nimport { applyOps } from \"../wire/ops\";\nimport type { StatewirePath } from \"../wire/ops\";\nimport { TERMINAL } from \"./connection\";\nimport type { StatewireCmd, StatewireSyn } from \"./connection\";\nimport {\n encodeParams,\n encodeValue,\n reviveResponse,\n reviveValue,\n} from \"../wire/meta\";\nimport { bindCommandsHost } from \"../host/host\";\nimport type { CommandsInvocation, CommandsListener } from \"../host/host\";\nimport type { Statewire } from \"../types\";\nimport type { StatewireClient } from \"../statewire\";\nimport {\n SessionStorageContext,\n createMemorySessionStore,\n} from \"./sessionStore\";\nimport { backoff } from \"./timing\";\nimport { createMethodProxy } from \"../util/methodProxy\";\nimport { randomId } from \"../util/randomId\";\nimport { StatewireSendError } from \"../types\";\nimport type {\n RemoteLink,\n StatewireFrame,\n StatewireRemoteProps,\n} from \"../transports/sse\";\n\ntype WireCommand = {\n method: string;\n params: unknown[];\n meta?: unknown;\n};\n\ntype Pending = {\n readonly seq: number;\n readonly command: WireCommand;\n readonly inv: CommandsInvocation;\n /** A send carrying this statement may have reached the server. */\n attempted: boolean;\n /** In the resend queue when false. */\n posted: boolean;\n /** The server acknowledged admission; the terminal verdict is still due. */\n applied: boolean;\n resolve: (payload: unknown) => void;\n reject: (error: StatewireSendError) => void;\n};\n\ntype CtxPending = {\n readonly seq: number;\n readonly ops: unknown[];\n posted: boolean;\n};\n\nconst protocolError = (message: string): never => {\n throw new Error(`statewire: protocol error: ${message}`);\n};\n\nconst newClientId = () => `c-${randomId()}`;\n\nconst rejectedSend = (\n failure: StatewireClient.SendFailure,\n): Promise<unknown> => {\n const result = Promise.reject<unknown>(new StatewireSendError(failure));\n result.catch(() => {});\n return result;\n};\n\ntype AttachState = \"detached\" | \"attached\" | \"finished\";\n\nexport type StatewireSessionOptions = {\n sessionStore?: StatewireClient.SessionStorage | undefined;\n onSessionLost?: StatewireClient.OnSessionLost | undefined;\n onDone?: (() => void) | undefined;\n};\n\ntype Shared = {\n txq: Promise<void>;\n parked: StatewireClient.SessionVerdict[];\n unsubscribe: (() => void) | null;\n};\n\ntype Session = {\n record: StatewireClient.SessionRecord;\n ctx: StatewireRemoteProps;\n recordPersisted: boolean;\n store: StatewireClient.SessionStorage;\n shared: Shared | false;\n ephemeral: boolean;\n /** An ephemeral record died with its attach: the storage is off for good. */\n deactivated: boolean;\n sessionKnown: boolean;\n durableSeq: number;\n resumeAt: number;\n idle: boolean;\n onSessionLost: StatewireClient.OnSessionLost | undefined;\n onDone: (() => void) | undefined;\n ctxOps: unknown[] | undefined;\n ctxPending: CtxPending[];\n lanesOnAttach: boolean;\n attachLaneSeqs: readonly [ReadonlySet<number>, ReadonlySet<number>];\n frameFailures: number;\n pending: Pending[];\n canonical: unknown;\n lastPublished: unknown;\n changed: StatewirePath[];\n source: Statewire.StateSource;\n attach: AttachState;\n attachEpoch: number;\n running: boolean;\n pumping: boolean;\n transport: RemoteLink | null;\n waiters: (() => void)[];\n lifecycle: CommandsListener | null;\n notify: () => void;\n commands: Record<string, (...params: unknown[]) => Promise<unknown>>;\n};\n\nconst publish = (s: Session) => {\n if (s.canonical === s.lastPublished) return;\n s.lastPublished = s.canonical;\n s.notify();\n};\n\nconst wake = (s: Session) => {\n const waiters = s.waiters;\n s.waiters = [];\n for (const waiter of waiters) waiter();\n};\n\nconst waitForWake = (s: Session) => new Promise<void>((r) => s.waiters.push(r));\n\nconst sleepUntilWake = (s: Session, delayMs: number) =>\n new Promise<void>((resolve) => {\n const waiter = () => {\n clearTimeout(timer);\n resolve();\n };\n const timer = setTimeout(() => {\n s.waiters = s.waiters.filter((w) => w !== waiter);\n resolve();\n }, delayMs);\n s.waiters.push(waiter);\n });\n\nconst setRecord = (s: Session, record: StatewireClient.SessionRecord) => {\n s.record = record;\n if (!s.deactivated) s.store.save(record);\n};\n\nconst backlog = (s: Session): StatewireClient.SessionCommand[] =>\n s.pending\n .filter((p) => p.seq > s.durableSeq)\n .map((p) => ({ seq: p.seq, ...p.command }));\n\nconst mergeBacklog = (s: Session): StatewireClient.SessionCommand[] => {\n const own = backlog(s);\n if (!s.shared) return own;\n const known = new Set(s.pending.map((p) => p.seq));\n const foreign = s.record.commands.filter(\n (c) => !known.has(c.seq) && c.seq > s.durableSeq,\n );\n return [...foreign, ...own].sort((a, b) => a.seq - b.seq);\n};\n\nconst MAX_PARKED_VERDICTS = 64;\n\n// Storage holds what a reload must resend: a command leaves at its dur, at a\n// server verdict, or at a record reset — never at a local channel death.\nconst syncBacklogInner = (s: Session) => {\n const parked = s.shared ? s.shared.parked.splice(0) : [];\n const parkedSeqs = new Set(parked.map((v) => v.seq));\n const commands = mergeBacklog(s).filter((c) => !parkedSeqs.has(c.seq));\n const verdicts =\n parked.length > 0\n ? [...(s.record.verdicts ?? []), ...parked].slice(-MAX_PARKED_VERDICTS)\n : s.record.verdicts;\n const unchanged =\n verdicts === s.record.verdicts &&\n commands.length === s.record.commands.length &&\n commands.every((c, i) => c.seq === s.record.commands[i]!.seq);\n if (unchanged) return;\n setRecord(s, {\n ...s.record,\n commands,\n ...(verdicts !== undefined && { verdicts }),\n });\n};\n\nconst syncBacklog = (s: Session) => {\n if (!s.shared) return syncBacklogInner(s);\n void transact(s, () => syncBacklogInner(s));\n};\n\n// Every record mutation over shared storage is a locked read-modify-write.\nconst transact = (s: Session, fn: () => void): Promise<void> => {\n if (!s.shared || s.deactivated) {\n fn();\n return Promise.resolve();\n }\n const shared = s.shared;\n const run = shared.txq.then(() =>\n s.store.lock!(async () => {\n const stored = s.store.load();\n if (stored !== null && stored.clientId !== s.record.clientId) {\n adoptReset(s, stored);\n } else if (stored !== null) {\n s.record = stored;\n }\n fn();\n }),\n );\n shared.txq = run.then(\n () => {},\n () => {},\n );\n return run;\n};\n\nconst setIdle = (s: Session, level: boolean) => {\n if (level === s.idle) return;\n s.idle = level;\n s.notify();\n if (level) s.onDone?.();\n};\n\nconst cover = (s: Session, entry: Pending) => {\n if (entry.applied) return;\n entry.applied = true;\n s.lifecycle?.onApplied(entry.inv);\n s.lifecycle?.onCovered?.(entry.inv);\n};\n\nconst settleEntry = (\n s: Session,\n entry: Pending,\n outcome:\n | { ok: true; payload: unknown }\n | { ok: false; failure: StatewireClient.SendFailure },\n) => {\n s.pending = s.pending.filter((p) => p !== entry);\n if (outcome.ok) {\n entry.resolve(outcome.payload);\n s.lifecycle?.onSettle(entry.inv, {\n type: \"accepted\",\n payload: outcome.payload,\n });\n } else {\n entry.reject(new StatewireSendError(outcome.failure));\n s.lifecycle?.onSettle(entry.inv, {\n type: \"rejected\",\n error: new StatewireSendError(outcome.failure),\n });\n }\n};\n\nconst settleAll = (s: Session, detach: \"unmount\" | \"gone\") => {\n const cause =\n detach === \"unmount\" ? (\"unmount\" as const) : (\"stream-gone\" as const);\n const batch = s.pending;\n const detachFailure = (entry: Pending): StatewireClient.SendFailure => {\n if (!entry.attempted) {\n const predecessorLost = batch.some(\n (p) => p.seq < entry.seq && p.attempted,\n );\n return predecessorLost\n ? { fate: \"aborted\", cause, predecessorLost }\n : { fate: \"aborted\", cause };\n }\n return { fate: \"lost\", cause };\n };\n for (const entry of [...batch]) {\n s.lifecycle?.onCovered?.(entry.inv);\n settleEntry(s, entry, { ok: false, failure: detachFailure(entry) });\n }\n};\n\nconst restateContext = (s: Session) => {\n s.ctxPending = [];\n if (s.ctxOps === undefined) return;\n const seq = s.record.ctxNextSeq;\n setRecord(s, { ...s.record, ctxNextSeq: seq + 1 });\n s.ctxPending.push({ seq, ops: s.ctxOps, posted: false });\n};\n\nconst settleLost = (s: Session, entries: Pending[]) => {\n for (const entry of entries) {\n s.lifecycle?.onCovered?.(entry.inv);\n settleEntry(s, entry, {\n ok: false,\n failure: { fate: \"lost\", cause: \"session-lost\" },\n });\n }\n};\n\n// The server-side record's dedup memory is gone: history that may have\n// reached a server settles lost — the new hello's snapshot is the only\n// truth about what survived — and never-attempted statements re-stamp\n// on the adopted lane clocks.\nconst rebaseRecord = (s: Session, adopt: () => void) => {\n const held = [...s.pending];\n const survivors = held.filter((p) => !p.attempted && !p.applied);\n settleLost(\n s,\n held.filter((p) => p.attempted || p.applied),\n );\n s.pending = [];\n s.durableSeq = 0;\n adopt();\n for (const old of survivors) {\n s.lifecycle?.onCovered?.(old.inv);\n enqueueInner(s, old.command, old.inv.params, old.resolve, old.reject);\n }\n restateContext(s);\n publish(s);\n wake(s);\n void pump(s);\n};\n\nconst resetRecord = (s: Session, clientId: string) =>\n rebaseRecord(s, () =>\n setRecord(s, { clientId, nextSeq: 1, ctxNextSeq: 1, commands: [] }),\n );\n\n// Another sharer replaced the record's identity: their reset settles our\n// attempted history and our survivors re-stamp on the stored clocks.\nconst adoptReset = (s: Session, stored: StatewireClient.SessionRecord) =>\n rebaseRecord(s, () => {\n s.record = stored;\n });\n\n// The record died with the attach: mint a fresh id for the next one.\nconst ephemeralDetach = (s: Session) => {\n s.ephemeral = false;\n s.sessionKnown = false;\n resetRecord(s, newClientId());\n};\n\nconst rejectedFailure = (cmd: StatewireCmd): StatewireClient.SendFailure => {\n return {\n fate: \"rejected\",\n cause: \"server\",\n ...(cmd.code !== undefined && { code: cmd.code }),\n ...(cmd.message !== undefined && { message: cmd.message }),\n ...(cmd.payload !== undefined && { payload: cmd.payload }),\n };\n};\n\nconst outcomeOf = (\n cmd: StatewireCmd,\n):\n | { ok: true; payload: unknown }\n | { ok: false; failure: StatewireClient.SendFailure } => {\n switch (cmd.type) {\n case \"result\":\n return { ok: true, payload: reviveResponse(cmd).payload };\n case \"rejected\":\n return { ok: false, failure: rejectedFailure(reviveResponse(cmd)) };\n case \"failed\":\n return {\n ok: false,\n failure: {\n fate: \"failed\",\n cause: \"server\",\n ...(cmd.message !== undefined && { message: cmd.message }),\n },\n };\n case \"crashed\":\n return { ok: false, failure: { fate: \"crashed\", cause: \"server\" } };\n case \"expired\":\n return { ok: false, failure: { fate: \"expired\", cause: \"server\" } };\n default:\n return protocolError(`unknown cmd type: ${String(cmd.type)}`);\n }\n};\n\nconst TERMINAL_CMD_TYPES: ReadonlySet<string> = new Set(TERMINAL);\n\nconst parkVerdict = (s: Session, cmd: StatewireCmd) => {\n if (!s.shared || !TERMINAL_CMD_TYPES.has(cmd.type!)) return;\n s.shared.parked.push({\n seq: cmd.seq,\n type: cmd.type as StatewireClient.SessionVerdict[\"type\"],\n ...(cmd.code !== undefined && { code: cmd.code }),\n ...(cmd.message !== undefined && { message: cmd.message }),\n ...(cmd.payload !== undefined && { payload: cmd.payload }),\n ...(cmd.meta !== undefined && { meta: cmd.meta }),\n });\n};\n\nconst handleCmd = (s: Session, cmd: StatewireCmd) => {\n if (!Number.isSafeInteger(cmd.seq) || cmd.seq <= 0) {\n protocolError(\"cmd.seq must be a positive safe integer\");\n }\n if (cmd.dur === true) {\n s.durableSeq = Math.max(s.durableSeq, cmd.seq);\n for (const entry of s.pending) {\n if (entry.seq <= s.durableSeq) entry.posted = true;\n }\n }\n if (cmd.type === undefined) return;\n const entry = s.pending.find((p) => p.seq === cmd.seq);\n if (cmd.type === \"applied\") {\n if (entry) cover(s, entry);\n return;\n }\n parkVerdict(s, cmd);\n if (!entry) return;\n cover(s, entry);\n settleEntry(s, entry, outcomeOf(cmd));\n};\n\nconst consumeVerdicts = (s: Session) => {\n const verdicts = s.record.verdicts ?? [];\n const consumed = new Set<number>();\n for (const verdict of verdicts) {\n const entry = s.pending.find((p) => p.seq === verdict.seq);\n if (!entry) continue;\n consumed.add(verdict.seq);\n cover(s, entry);\n settleEntry(s, entry, outcomeOf(verdict as StatewireCmd));\n }\n if (consumed.size === 0) return;\n setRecord(s, {\n ...s.record,\n commands: s.record.commands.filter((c) => !consumed.has(c.seq)),\n verdicts: verdicts.filter((v) => !consumed.has(v.seq)),\n });\n publish(s);\n wake(s);\n};\n\nconst handleCmds = (s: Session, cmds: StatewireCmd[]) => {\n for (const cmd of cmds) handleCmd(s, cmd);\n syncBacklog(s);\n wake(s);\n};\n\nconst ingestOps = (s: Session, ops: unknown[]) => {\n const applied = applyOps(s.canonical, ops);\n s.canonical = applied.state;\n s.changed.push(...applied.changedPaths);\n};\n\nconst publishIngested = (s: Session) => {\n publish(s);\n wake(s);\n};\n\n// A hello's cmd watermark may understate a durable record (cold host, tray\n// unloaded): held seqs resend as-is and the frame's answer arbitrates —\n// absorption where the record survived, a gap refusal where it did not.\nconst snapCtxClock = (s: Session, ctxWm: number) => {\n const ctxAligned =\n s.ctxPending.every((c, i) => c.seq === ctxWm + 1 + i) &&\n s.record.ctxNextSeq === ctxWm + s.ctxPending.length + 1;\n if (!ctxAligned) {\n setRecord(s, { ...s.record, ctxNextSeq: ctxWm + 1 });\n restateContext(s);\n }\n};\n\n// The refusal's watermarks are exact: every held statement above them was\n// never admitted by the live record, and the first unposted seq being beyond\n// watermark+1 proves the record that admitted the missing prefix is gone —\n// its history settles lost and the lane clocks restart at the watermarks.\nconst sessionLostInner = (s: Session, seqWm: number, ctxWm: number) => {\n const held = [...s.pending];\n settleLost(s, held);\n s.pending = [];\n s.durableSeq = seqWm;\n setRecord(s, {\n clientId: s.record.clientId,\n nextSeq: seqWm + 1,\n ctxNextSeq: ctxWm + 1,\n commands: [],\n });\n restateContext(s);\n if (\n held.length > 0 &&\n s.onSessionLost?.(held.map((p) => p.inv)) === \"requeue\"\n ) {\n for (const old of held) {\n enqueueInner(\n s,\n old.command,\n old.inv.params,\n () => {},\n () => {},\n );\n }\n }\n publish(s);\n wake(s);\n};\n\nconst handleHello = (\n s: Session,\n { ops, syn }: { ops: unknown[]; syn: StatewireSyn },\n) => {\n if (syn.record !== undefined && syn.record !== \"ephemeral\") {\n protocolError(`unknown record: ${String(syn.record)}`);\n }\n ingestOps(s, ops);\n s.attach = \"attached\";\n s.attachEpoch += 1;\n s.frameFailures = 0;\n s.resumeAt = 0;\n s.ephemeral = syn.record === \"ephemeral\";\n if (s.ephemeral) s.deactivated = true;\n const [attachCmd, attachCtx] = s.attachLaneSeqs;\n s.attachLaneSeqs = [new Set(), new Set()];\n const reconcile = () => {\n if (s.shared) adoptStored(s);\n // Resending unsettled statements is exactly-once-safe: absorbed replays\n // re-emit their stored verdicts (applied while still in flight).\n s.durableSeq = syn.seq ?? 0;\n for (const entry of s.pending) {\n entry.posted = attachCmd.has(entry.seq);\n }\n const ctxWatermark = syn.ctxSeq ?? 0;\n s.ctxPending = s.ctxPending.filter((c) => c.seq > ctxWatermark);\n for (const c of s.ctxPending) c.posted = attachCtx.has(c.seq);\n snapCtxClock(s, ctxWatermark);\n syncBacklogInner(s);\n s.sessionKnown = true;\n };\n if (!s.shared || s.deactivated) {\n reconcile();\n publishIngested(s);\n void pump(s);\n return;\n }\n void transact(s, reconcile).then(() => {\n publishIngested(s);\n void pump(s);\n });\n};\n\nconst handleOps = (\n s: Session,\n { ops, cmds }: { ops: unknown[]; cmds: StatewireCmd[] },\n) => {\n ingestOps(s, ops);\n for (const cmd of cmds) handleCmd(s, cmd);\n syncBacklog(s);\n publishIngested(s);\n};\n\n// A retry-less {syn} refusal is the one session-loss verdict: a cmd gap\n// against its exact watermark settles the held history lost; a pushback\n// (retry present) or a gapless refusal only reconciles the resend queues.\nconst handleRefusal = (s: Session, syn: StatewireSyn) => {\n const { seq, ctxSeq } = syn;\n if (typeof seq === \"number\") {\n const watermark = Math.max(seq, s.durableSeq);\n for (const entry of s.pending) entry.posted = entry.seq <= watermark;\n }\n if (typeof ctxSeq === \"number\") {\n s.ctxPending = s.ctxPending.filter((c) => c.seq > ctxSeq);\n for (const c of s.ctxPending) c.posted = false;\n }\n if (typeof syn.retry === \"number\") {\n s.resumeAt = Date.now() + syn.retry;\n wake(s);\n void pump(s);\n return;\n }\n const firstCmd = s.pending.find((p) => !p.posted);\n const firstCtx = s.ctxPending.find((c) => !c.posted);\n const cmdGap =\n typeof seq === \"number\" &&\n firstCmd !== undefined &&\n firstCmd.seq > Math.max(seq, s.durableSeq) + 1;\n const ctxGap =\n typeof ctxSeq === \"number\" &&\n firstCtx !== undefined &&\n firstCtx.seq > ctxSeq + 1;\n if (cmdGap || ctxGap) {\n void transact(s, () => {\n if (cmdGap) sessionLostInner(s, seq!, ctxSeq ?? 0);\n else snapCtxClock(s, ctxSeq!);\n }).then(() => {\n wake(s);\n void pump(s);\n });\n return;\n }\n wake(s);\n void pump(s);\n};\n\nconst handleDetach = (s: Session) => {\n if (s.attach === \"attached\") s.attach = \"detached\";\n if (s.ephemeral) ephemeralDetach(s);\n wake(s);\n};\n\nconst handleFinish = (s: Session, { reason }: { reason: string }) => {\n if (reason === \"evicted\" || reason === \"error\") return;\n s.attach = \"finished\";\n settleAll(s, \"gone\");\n publish(s);\n wake(s);\n};\n\nconst isFinished = (s: Session) => s.attach === \"finished\";\n\ntype Lanes = {\n frame: StatewireFrame;\n cmdEntries: Pending[];\n ctxEntries: CtxPending[];\n};\n\n// A lane must be strictly consecutive within a frame: the first unposted run\n// per lane rides now, later runs ride follow-up frames.\nconst buildLanes = (s: Session): Lanes | null => {\n const ctxEntries: CtxPending[] = [];\n for (const entry of s.ctxPending) {\n if (entry.posted) continue;\n if (ctxEntries.length > 0 && entry.seq !== ctxEntries.at(-1)!.seq + 1)\n break;\n ctxEntries.push(entry);\n }\n const cmdEntries: Pending[] = [];\n for (const entry of s.pending) {\n if (entry.posted) continue;\n if (cmdEntries.length > 0 && entry.seq !== cmdEntries.at(-1)!.seq + 1)\n break;\n cmdEntries.push(entry);\n }\n if (ctxEntries.length === 0 && cmdEntries.length === 0) return null;\n return {\n frame: {\n ...(ctxEntries.length > 0 && {\n ctx: ctxEntries.map((c) => ({ ops: c.ops, seq: c.seq })),\n }),\n ...(cmdEntries.length > 0 && {\n cmd: cmdEntries.map((p) => ({ ...p.command, seq: p.seq })),\n }),\n },\n cmdEntries,\n ctxEntries,\n };\n};\n\nconst takeAttachLanes = (s: Session): StatewireFrame | null => {\n s.attachLaneSeqs = [new Set(), new Set()];\n const wanted = s.lanesOnAttach;\n s.lanesOnAttach = false;\n if (!wanted || !s.sessionKnown) return null;\n const lanes = buildLanes(s);\n if (!lanes) return null;\n s.attachLaneSeqs = [\n new Set(lanes.cmdEntries.map((p) => p.seq)),\n new Set(lanes.ctxEntries.map((c) => c.seq)),\n ];\n for (const entry of lanes.cmdEntries) entry.attempted = true;\n return lanes.frame;\n};\n\nconst pump = async (s: Session) => {\n if (s.pumping) return;\n s.pumping = true;\n try {\n while (s.running && !isFinished(s)) {\n const transport = s.transport;\n if (buildLanes(s) === null) return;\n if (s.attach !== \"attached\" || !transport) {\n if (transport?.connection.status === \"idle\") {\n transport.connection.reconnect();\n }\n await waitForWake(s);\n continue;\n }\n const resumeDelay = s.resumeAt - Date.now();\n if (resumeDelay > 0) {\n await sleepUntilWake(s, resumeDelay);\n continue;\n }\n const lanes = buildLanes(s);\n if (!lanes) continue;\n const epoch = s.attachEpoch;\n for (const entry of lanes.cmdEntries) entry.attempted = true;\n let result;\n try {\n // Shared storage: the lock across the send keeps per-lane arrival\n // ordered across sharers during attach handover.\n const send = () => transport.send(lanes.frame);\n result = await (s.shared && !s.deactivated\n ? s.store.lock!(send)\n : send());\n } catch {\n if (!s.running || isFinished(s)) return;\n s.frameFailures += 1;\n await sleepUntilWake(s, backoff(s.frameFailures));\n continue;\n }\n if (!s.running) return;\n s.frameFailures = 0;\n if (result.type === \"ok\") {\n if (epoch === s.attachEpoch) {\n for (const entry of lanes.cmdEntries) {\n if (s.pending.includes(entry)) {\n entry.posted = true;\n s.lifecycle?.onPosted?.(entry.inv);\n }\n }\n for (const entry of lanes.ctxEntries) entry.posted = true;\n }\n } else if (result.type === \"refusal\") {\n if (epoch === s.attachEpoch) handleRefusal(s, result.syn);\n } else if (result.type === \"stale-lease\") {\n // A POST outlived its attach: reattach first, the hello arbitrates.\n if (epoch === s.attachEpoch) {\n transport.connection.reconnect();\n await waitForWake(s);\n }\n } else if (result.type === \"no-lease\") {\n // No out-of-band write channel: the frame rides a fresh attach.\n if (epoch === s.attachEpoch) {\n s.lanesOnAttach = true;\n transport.connection.reconnect();\n while (s.running && !isFinished(s) && epoch === s.attachEpoch) {\n await waitForWake(s);\n }\n }\n }\n }\n } finally {\n s.pumping = false;\n }\n};\n\nconst start = (s: Session) => {\n if (s.shared) {\n s.shared.unsubscribe = s.store.subscribe!(() => {\n void transact(s, () => consumeVerdicts(s));\n });\n s.running = true;\n void transact(s, () => {\n if (s.store.load() === null) s.store.save(s.record);\n s.recordPersisted = true;\n adoptStored(s);\n consumeVerdicts(s);\n }).then(() => void pump(s));\n return;\n }\n if (!s.recordPersisted) {\n s.recordPersisted = true;\n s.store.save(s.record);\n }\n adoptStored(s);\n s.running = true;\n void pump(s);\n};\n\nconst stop = (s: Session) => {\n s.running = false;\n if (s.shared) {\n s.shared.unsubscribe?.();\n s.shared.unsubscribe = null;\n }\n wake(s);\n settleAll(s, \"unmount\");\n};\n\nconst setTransport = (s: Session, transport: RemoteLink) => {\n if (s.transport === transport) return;\n s.transport = transport;\n wake(s);\n};\n\nconst enqueueInner = (\n s: Session,\n command: WireCommand,\n params: readonly unknown[],\n resolve: (payload: unknown) => void,\n reject: (error: StatewireSendError) => void,\n) => {\n const seq = s.record.nextSeq;\n const entry: Pending = {\n seq,\n command,\n inv: {\n method: command.method,\n params,\n ts: Date.now(),\n seq,\n clientId: s.record.clientId,\n },\n attempted: false,\n posted: false,\n applied: false,\n resolve,\n reject,\n };\n s.pending.push(entry);\n setRecord(s, { ...s.record, nextSeq: seq + 1, commands: mergeBacklog(s) });\n s.lifecycle?.onStart(entry.inv);\n};\n\nconst enqueue = (\n s: Session,\n command: WireCommand,\n params: readonly unknown[],\n resolve: (payload: unknown) => void,\n reject: (error: StatewireSendError) => void,\n) => {\n if (!s.shared) {\n enqueueInner(s, command, params, resolve, reject);\n void pump(s);\n return;\n }\n void transact(s, () =>\n enqueueInner(s, command, params, resolve, reject),\n ).then(() => void pump(s));\n};\n\n// A stored command may have reached a server: attempted settles it lost,\n// never aborted, when a channel death ends the session.\nconst adoptStored = (s: Session) => {\n const known = new Set(s.pending.map((p) => p.seq));\n const stored = s.record.commands.filter((c) => !known.has(c.seq));\n if (stored.length === 0) return;\n for (const { seq, ...command } of stored) {\n const params =\n command.meta === undefined\n ? command.params\n : (reviveValue([...command.params], command.meta) as unknown[]);\n const entry: Pending = {\n seq,\n command,\n inv: {\n method: command.method,\n params,\n ts: Date.now(),\n seq,\n clientId: s.record.clientId,\n },\n attempted: true,\n posted: false,\n applied: false,\n resolve: () => {},\n reject: () => {},\n };\n s.pending.push(entry);\n s.lifecycle?.onStart(entry.inv);\n }\n s.pending.sort((a, b) => a.seq - b.seq);\n};\n\nconst sendCommand = (\n s: Session,\n method: string,\n params: readonly unknown[],\n): Promise<unknown> => {\n if (!s.running) {\n return rejectedSend({ fate: \"aborted\", cause: \"unmount\" });\n }\n if (isFinished(s)) {\n return rejectedSend({ fate: \"aborted\", cause: \"stream-gone\" });\n }\n const result = new Promise<unknown>((resolve, reject) => {\n const { params: encoded, meta } = encodeParams(params);\n enqueue(\n s,\n { method, params: encoded, ...(meta !== undefined && { meta }) },\n params,\n resolve,\n reject,\n );\n });\n result.catch(() => {});\n return result;\n};\n\nconst setContext = (s: Session, value: Record<string, unknown>): void => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(\"statewire: context must be a plain object\");\n }\n if (!s.running || isFinished(s)) return;\n const { value: encoded, meta } = encodeValue(value);\n const ops = [\n {\n op: \"replace\",\n path: [],\n value: encoded,\n ...(meta !== undefined && { meta }),\n },\n ];\n s.ctxOps = ops;\n const mint = () => {\n const seq = s.record.ctxNextSeq;\n setRecord(s, { ...s.record, ctxNextSeq: seq + 1 });\n s.ctxPending.push({ seq, ops, posted: false });\n };\n if (!s.shared) {\n mint();\n wake(s);\n void pump(s);\n return;\n }\n void transact(s, mint).then(() => {\n wake(s);\n void pump(s);\n });\n};\n\nexport const useStatewireSession = (\n options: StatewireSessionOptions,\n): Session => {\n const [defaultStore] = useState(createMemorySessionStore);\n const mounted = useContext(SessionStorageContext);\n if (options.sessionStore !== undefined && mounted !== undefined) {\n throw new Error(\n \"statewire: session storage is set twice — drop the transport's sessionStore or the client's storage.session\",\n );\n }\n const store = options.sessionStore ?? mounted ?? defaultStore;\n if ((store.lock === undefined) !== (store.subscribe === undefined)) {\n throw new Error(\n \"statewire: session storage must provide lock and subscribe together\",\n );\n }\n const [s] = useState((): Session => {\n const stored = store.load();\n if (stored !== null && !Array.isArray(stored.commands)) {\n throw new Error(\n \"statewire: session storage loaded a record without a commands array\",\n );\n }\n const record = stored ?? {\n clientId: newClientId(),\n nextSeq: 1,\n ctxNextSeq: 1,\n commands: [],\n };\n const session: Session = {\n record,\n ctx: {\n get clientId() {\n return session.record.clientId;\n },\n takeAttachLanes: () => takeAttachLanes(session),\n onHello: (args) => handleHello(session, args),\n onOps: (args) => handleOps(session, args),\n onCmds: (cmds) => handleCmds(session, cmds),\n onRefusal: (syn) => handleRefusal(session, syn),\n onIdle: (level) => setIdle(session, level),\n onDetach: () => handleDetach(session),\n onFinish: (args) => handleFinish(session, args),\n },\n recordPersisted: stored !== null,\n store,\n shared:\n store.lock !== undefined\n ? { txq: Promise.resolve(), parked: [], unsubscribe: null }\n : false,\n ephemeral: false,\n deactivated: false,\n sessionKnown: false,\n durableSeq: 0,\n resumeAt: 0,\n idle: false,\n onSessionLost: undefined,\n onDone: undefined,\n ctxOps: undefined,\n ctxPending: [],\n lanesOnAttach: false,\n attachLaneSeqs: [new Set(), new Set()],\n frameFailures: 0,\n pending: [],\n canonical: undefined,\n lastPublished: undefined,\n changed: [],\n source: {\n snapshot: () => session.canonical,\n takeChanged: () => {\n const changed = session.changed;\n session.changed = [];\n return changed;\n },\n setOnChange: (listener) => {\n session.notify = listener ?? (() => {});\n },\n },\n attach: \"detached\",\n attachEpoch: 0,\n running: false,\n pumping: false,\n transport: null,\n waiters: [],\n lifecycle: null,\n notify: () => {},\n commands: createMethodProxy((method, params) =>\n sendCommand(session, method, params),\n ),\n };\n bindCommandsHost(session.commands, {\n setListener: (listener) => {\n session.lifecycle = listener;\n },\n });\n return session;\n });\n if ((store.lock !== undefined) !== (s.shared !== false)) {\n throw new Error(\n \"statewire: session storage changed sharedness across renders — lock/subscribe must be present from the first render or never\",\n );\n }\n s.store = store;\n s.onSessionLost = options.onSessionLost;\n s.onDone = options.onDone;\n useEffect(() => {\n start(s);\n return () => stop(s);\n }, [s]);\n return s;\n};\n\nexport { setContext, setTransport };\n"],"mappings":"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"}
1
+ {"version":3,"file":"session.js","names":["useContext","useEffect","useState","applyOps","StatewirePath","TERMINAL","StatewireCmd","StatewireSyn","encodeParams","encodeValue","reviveResponse","reviveValue","bindCommandsHost","CommandsInvocation","CommandsListener","Statewire","StatewireClient","SessionStorageContext","createMemorySessionStore","backoff","createMethodProxy","randomId","StatewireSendError","RemoteLink","StatewireFrame","StatewireRemoteProps","WireCommand","method","params","meta","Pending","seq","command","inv","attempted","posted","applied","resolve","payload","reject","error","CtxPending","ops","protocolError","message","Error","newClientId","rejectedSend","failure","SendFailure","Promise","result","catch","AttachState","StatewireSessionOptions","sessionStore","SessionStorage","onSessionLost","OnSessionLost","onDone","Shared","txq","parked","SessionVerdict","unsubscribe","Session","record","SessionRecord","ctx","recordPersisted","store","shared","ephemeral","deactivated","sessionKnown","durableSeq","resumeAt","idle","ctxOps","ctxPending","lanesOnAttach","attachLaneSeqs","ReadonlySet","frameFailures","pending","canonical","lastPublished","changed","source","StateSource","attach","attachEpoch","running","pumping","transport","waiters","lifecycle","notify","commands","Record","publish","s","wake","waiter","waitForWake","r","push","sleepUntilWake","delayMs","clearTimeout","timer","setTimeout","filter","w","setRecord","save","backlog","SessionCommand","p","map","mergeBacklog","own","known","Set","foreign","c","has","sort","a","b","MAX_PARKED_VERDICTS","syncBacklogInner","splice","parkedSeqs","v","verdicts","length","slice","unchanged","every","i","undefined","syncBacklog","transact","fn","run","then","lock","stored","load","clientId","adoptReset","setIdle","level","cover","entry","onApplied","onCovered","NO_FAILED","FailedCommand","failedCommands","failed","retainFailed","ts","settleEntry","outcome","ok","onSettle","type","rides","cause","settleAll","detach","const","batch","detachFailure","predecessorLost","some","fate","restateContext","ctxNextSeq","settleLost","entries","rebaseRecord","adopt","held","survivors","old","enqueueInner","pump","resetRecord","nextSeq","ephemeralDetach","rejectedFailure","cmd","code","outcomeOf","String","TERMINAL_CMD_TYPES","parkVerdict","handleCmd","Number","isSafeInteger","dur","Math","max","find","consumeVerdicts","consumed","verdict","add","size","handleCmds","cmds","ingestOps","state","changedPaths","publishIngested","snapCtxClock","ctxWm","ctxAligned","sessionLostInner","seqWm","handleHello","syn","attachCmd","attachCtx","reconcile","adoptStored","ctxWatermark","ctxSeq","handleOps","handleRefusal","watermark","retry","Date","now","firstCmd","firstCtx","cmdGap","ctxGap","handleDetach","handleFinish","reason","isFinished","Lanes","frame","cmdEntries","ctxEntries","buildLanes","at","takeAttachLanes","wanted","lanes","connection","status","reconnect","resumeDelay","epoch","send","includes","onPosted","start","subscribe","stop","setTransport","onStart","enqueue","sendCommand","encoded","takeFailed","found","f","discardFailed","retryFailed","setContext","value","Array","isArray","op","path","mint","useStatewireSession","options","defaultStore","mounted","session","onHello","args","onOps","onCmds","onRefusal","onIdle","onDetach","onFinish","snapshot","takeChanged","setOnChange","listener","setListener"],"sources":["../../src/client/session.ts"],"sourcesContent":["import { useContext, useEffect, useState } from \"react\";\nimport { applyOps } from \"../wire/ops\";\nimport type { StatewirePath } from \"../wire/ops\";\nimport { TERMINAL } from \"./connection\";\nimport type { StatewireCmd, StatewireSyn } from \"./connection\";\nimport {\n encodeParams,\n encodeValue,\n reviveResponse,\n reviveValue,\n} from \"../wire/meta\";\nimport { bindCommandsHost } from \"../host/host\";\nimport type { CommandsInvocation, CommandsListener } from \"../host/host\";\nimport type { Statewire } from \"../types\";\nimport type { StatewireClient } from \"../statewire\";\nimport {\n SessionStorageContext,\n createMemorySessionStore,\n} from \"./sessionStore\";\nimport { backoff } from \"./timing\";\nimport { createMethodProxy } from \"../util/methodProxy\";\nimport { randomId } from \"../util/randomId\";\nimport { StatewireSendError } from \"../types\";\nimport type {\n RemoteLink,\n StatewireFrame,\n StatewireRemoteProps,\n} from \"../transports/sse\";\n\ntype WireCommand = {\n method: string;\n params: unknown[];\n meta?: unknown;\n};\n\ntype Pending = {\n readonly seq: number;\n readonly command: WireCommand;\n readonly inv: CommandsInvocation;\n /** A send carrying this statement may have reached the server. */\n attempted: boolean;\n /** In the resend queue when false. */\n posted: boolean;\n /** The server acknowledged admission; the terminal verdict is still due. */\n applied: boolean;\n resolve: (payload: unknown) => void;\n reject: (error: StatewireSendError) => void;\n};\n\ntype CtxPending = {\n readonly seq: number;\n readonly ops: unknown[];\n posted: boolean;\n};\n\nconst protocolError = (message: string): never => {\n throw new Error(`statewire: protocol error: ${message}`);\n};\n\nconst newClientId = () => `c-${randomId()}`;\n\nconst rejectedSend = (\n failure: StatewireClient.SendFailure,\n): Promise<unknown> => {\n const result = Promise.reject<unknown>(new StatewireSendError(failure));\n result.catch(() => {});\n return result;\n};\n\ntype AttachState = \"detached\" | \"attached\" | \"finished\";\n\nexport type StatewireSessionOptions = {\n sessionStore?: StatewireClient.SessionStorage | undefined;\n onSessionLost?: StatewireClient.OnSessionLost | undefined;\n onDone?: (() => void) | undefined;\n};\n\ntype Shared = {\n txq: Promise<void>;\n parked: StatewireClient.SessionVerdict[];\n unsubscribe: (() => void) | null;\n};\n\ntype Session = {\n record: StatewireClient.SessionRecord;\n ctx: StatewireRemoteProps;\n recordPersisted: boolean;\n store: StatewireClient.SessionStorage;\n shared: Shared | false;\n ephemeral: boolean;\n /** An ephemeral record died with its attach: the storage is off for good. */\n deactivated: boolean;\n sessionKnown: boolean;\n durableSeq: number;\n resumeAt: number;\n idle: boolean;\n onSessionLost: StatewireClient.OnSessionLost | undefined;\n onDone: (() => void) | undefined;\n ctxOps: unknown[] | undefined;\n ctxPending: CtxPending[];\n lanesOnAttach: boolean;\n attachLaneSeqs: readonly [ReadonlySet<number>, ReadonlySet<number>];\n frameFailures: number;\n pending: Pending[];\n canonical: unknown;\n lastPublished: unknown;\n changed: StatewirePath[];\n source: Statewire.StateSource;\n attach: AttachState;\n attachEpoch: number;\n running: boolean;\n pumping: boolean;\n transport: RemoteLink | null;\n waiters: (() => void)[];\n lifecycle: CommandsListener | null;\n notify: () => void;\n commands: Record<string, (...params: unknown[]) => Promise<unknown>>;\n};\n\nconst publish = (s: Session) => {\n if (s.canonical === s.lastPublished) return;\n s.lastPublished = s.canonical;\n s.notify();\n};\n\nconst wake = (s: Session) => {\n const waiters = s.waiters;\n s.waiters = [];\n for (const waiter of waiters) waiter();\n};\n\nconst waitForWake = (s: Session) => new Promise<void>((r) => s.waiters.push(r));\n\nconst sleepUntilWake = (s: Session, delayMs: number) =>\n new Promise<void>((resolve) => {\n const waiter = () => {\n clearTimeout(timer);\n resolve();\n };\n const timer = setTimeout(() => {\n s.waiters = s.waiters.filter((w) => w !== waiter);\n resolve();\n }, delayMs);\n s.waiters.push(waiter);\n });\n\nconst setRecord = (s: Session, record: StatewireClient.SessionRecord) => {\n s.record = record;\n if (!s.deactivated) s.store.save(record);\n};\n\nconst backlog = (s: Session): StatewireClient.SessionCommand[] =>\n s.pending\n .filter((p) => p.seq > s.durableSeq)\n .map((p) => ({ seq: p.seq, ...p.command }));\n\nconst mergeBacklog = (s: Session): StatewireClient.SessionCommand[] => {\n const own = backlog(s);\n if (!s.shared) return own;\n const known = new Set(s.pending.map((p) => p.seq));\n const foreign = s.record.commands.filter(\n (c) => !known.has(c.seq) && c.seq > s.durableSeq,\n );\n return [...foreign, ...own].sort((a, b) => a.seq - b.seq);\n};\n\nconst MAX_PARKED_VERDICTS = 64;\n\n// Storage holds what a reload must resend: a command leaves at its dur, at a\n// server verdict, or at a record reset — never at a local channel death.\nconst syncBacklogInner = (s: Session) => {\n const parked = s.shared ? s.shared.parked.splice(0) : [];\n const parkedSeqs = new Set(parked.map((v) => v.seq));\n const commands = mergeBacklog(s).filter((c) => !parkedSeqs.has(c.seq));\n const verdicts =\n parked.length > 0\n ? [...(s.record.verdicts ?? []), ...parked].slice(-MAX_PARKED_VERDICTS)\n : s.record.verdicts;\n const unchanged =\n verdicts === s.record.verdicts &&\n commands.length === s.record.commands.length &&\n commands.every((c, i) => c.seq === s.record.commands[i]!.seq);\n if (unchanged) return;\n setRecord(s, {\n ...s.record,\n commands,\n ...(verdicts !== undefined && { verdicts }),\n });\n};\n\nconst syncBacklog = (s: Session) => {\n if (!s.shared) return syncBacklogInner(s);\n void transact(s, () => syncBacklogInner(s));\n};\n\n// Every record mutation over shared storage is a locked read-modify-write.\nconst transact = (s: Session, fn: () => void): Promise<void> => {\n if (!s.shared || s.deactivated) {\n fn();\n return Promise.resolve();\n }\n const shared = s.shared;\n const run = shared.txq.then(() =>\n s.store.lock!(async () => {\n const stored = s.store.load();\n if (stored !== null && stored.clientId !== s.record.clientId) {\n adoptReset(s, stored);\n } else if (stored !== null) {\n s.record = stored;\n }\n fn();\n }),\n );\n shared.txq = run.then(\n () => {},\n () => {},\n );\n return run;\n};\n\nconst setIdle = (s: Session, level: boolean) => {\n if (level === s.idle) return;\n s.idle = level;\n s.notify();\n if (level) s.onDone?.();\n};\n\nconst cover = (s: Session, entry: Pending) => {\n if (entry.applied) return;\n entry.applied = true;\n s.lifecycle?.onApplied(entry.inv);\n s.lifecycle?.onCovered?.(entry.inv);\n};\n\nconst NO_FAILED: readonly StatewireClient.FailedCommand[] = [];\n\nexport const failedCommands = (\n s: Session,\n): readonly StatewireClient.FailedCommand[] => s.record.failed ?? NO_FAILED;\n\nconst retainFailed = (\n s: Session,\n entry: Pending,\n failure: StatewireClient.SendFailure,\n) => {\n setRecord(s, {\n ...s.record,\n failed: [\n ...(s.record.failed ?? []),\n {\n command: entry.command.method,\n params: entry.command.params,\n ...(entry.command.meta !== undefined && { meta: entry.command.meta }),\n failure,\n ts: entry.inv.ts,\n seq: entry.seq,\n },\n ],\n });\n s.notify();\n};\n\nconst settleEntry = (\n s: Session,\n entry: Pending,\n outcome:\n | { ok: true; payload: unknown }\n | { ok: false; failure: StatewireClient.SendFailure },\n) => {\n s.pending = s.pending.filter((p) => p !== entry);\n if (outcome.ok) {\n entry.resolve(outcome.payload);\n s.lifecycle?.onSettle(entry.inv, {\n type: \"accepted\",\n payload: outcome.payload,\n });\n } else {\n // A statement the record still carries resends on the next attach; only\n // invocations the record no longer owns become failed history.\n const rides =\n (outcome.failure.cause === \"unmount\" ||\n outcome.failure.cause === \"stream-gone\") &&\n entry.seq > s.durableSeq;\n if (!rides) retainFailed(s, entry, outcome.failure);\n entry.reject(new StatewireSendError(outcome.failure));\n s.lifecycle?.onSettle(entry.inv, {\n type: \"rejected\",\n error: new StatewireSendError(outcome.failure),\n });\n }\n};\n\nconst settleAll = (s: Session, detach: \"unmount\" | \"gone\") => {\n const cause =\n detach === \"unmount\" ? (\"unmount\" as const) : (\"stream-gone\" as const);\n const batch = s.pending;\n const detachFailure = (entry: Pending): StatewireClient.SendFailure => {\n if (!entry.attempted) {\n const predecessorLost = batch.some(\n (p) => p.seq < entry.seq && p.attempted,\n );\n return predecessorLost\n ? { fate: \"aborted\", cause, predecessorLost }\n : { fate: \"aborted\", cause };\n }\n return { fate: \"lost\", cause };\n };\n for (const entry of [...batch]) {\n s.lifecycle?.onCovered?.(entry.inv);\n settleEntry(s, entry, { ok: false, failure: detachFailure(entry) });\n }\n};\n\nconst restateContext = (s: Session) => {\n s.ctxPending = [];\n if (s.ctxOps === undefined) return;\n const seq = s.record.ctxNextSeq;\n setRecord(s, { ...s.record, ctxNextSeq: seq + 1 });\n s.ctxPending.push({ seq, ops: s.ctxOps, posted: false });\n};\n\nconst settleLost = (s: Session, entries: Pending[]) => {\n for (const entry of entries) {\n s.lifecycle?.onCovered?.(entry.inv);\n settleEntry(s, entry, {\n ok: false,\n failure: { fate: \"lost\", cause: \"session-lost\" },\n });\n }\n};\n\n// The server-side record's dedup memory is gone: history that may have\n// reached a server settles lost — the new hello's snapshot is the only\n// truth about what survived — and never-attempted statements re-stamp\n// on the adopted lane clocks.\nconst rebaseRecord = (s: Session, adopt: () => void) => {\n const held = [...s.pending];\n const survivors = held.filter((p) => !p.attempted && !p.applied);\n settleLost(\n s,\n held.filter((p) => p.attempted || p.applied),\n );\n s.pending = [];\n s.durableSeq = 0;\n // Failed entries are user-owned history: they ride through every record replacement.\n const failed = s.record.failed;\n adopt();\n if (failed !== undefined && s.record.failed !== failed) {\n setRecord(s, {\n ...s.record,\n failed: [...(s.record.failed ?? []), ...failed],\n });\n }\n for (const old of survivors) {\n s.lifecycle?.onCovered?.(old.inv);\n enqueueInner(s, old.command, old.inv.params, old.resolve, old.reject);\n }\n restateContext(s);\n publish(s);\n wake(s);\n void pump(s);\n};\n\nconst resetRecord = (s: Session, clientId: string) =>\n rebaseRecord(s, () =>\n setRecord(s, { clientId, nextSeq: 1, ctxNextSeq: 1, commands: [] }),\n );\n\n// Another sharer replaced the record's identity: their reset settles our\n// attempted history and our survivors re-stamp on the stored clocks.\nconst adoptReset = (s: Session, stored: StatewireClient.SessionRecord) =>\n rebaseRecord(s, () => {\n s.record = stored;\n });\n\n// The record died with the attach: mint a fresh id for the next one.\nconst ephemeralDetach = (s: Session) => {\n s.ephemeral = false;\n s.sessionKnown = false;\n resetRecord(s, newClientId());\n};\n\nconst rejectedFailure = (cmd: StatewireCmd): StatewireClient.SendFailure => {\n return {\n fate: \"rejected\",\n cause: \"server\",\n ...(cmd.code !== undefined && { code: cmd.code }),\n ...(cmd.message !== undefined && { message: cmd.message }),\n ...(cmd.payload !== undefined && { payload: cmd.payload }),\n };\n};\n\nconst outcomeOf = (\n cmd: StatewireCmd,\n):\n | { ok: true; payload: unknown }\n | { ok: false; failure: StatewireClient.SendFailure } => {\n switch (cmd.type) {\n case \"result\":\n return { ok: true, payload: reviveResponse(cmd).payload };\n case \"rejected\":\n return { ok: false, failure: rejectedFailure(reviveResponse(cmd)) };\n case \"failed\":\n return {\n ok: false,\n failure: {\n fate: \"failed\",\n cause: \"server\",\n ...(cmd.message !== undefined && { message: cmd.message }),\n },\n };\n case \"crashed\":\n return { ok: false, failure: { fate: \"crashed\", cause: \"server\" } };\n case \"expired\":\n return { ok: false, failure: { fate: \"expired\", cause: \"server\" } };\n default:\n return protocolError(`unknown cmd type: ${String(cmd.type)}`);\n }\n};\n\nconst TERMINAL_CMD_TYPES: ReadonlySet<string> = new Set(TERMINAL);\n\nconst parkVerdict = (s: Session, cmd: StatewireCmd) => {\n if (!s.shared || !TERMINAL_CMD_TYPES.has(cmd.type!)) return;\n s.shared.parked.push({\n seq: cmd.seq,\n type: cmd.type as StatewireClient.SessionVerdict[\"type\"],\n ...(cmd.code !== undefined && { code: cmd.code }),\n ...(cmd.message !== undefined && { message: cmd.message }),\n ...(cmd.payload !== undefined && { payload: cmd.payload }),\n ...(cmd.meta !== undefined && { meta: cmd.meta }),\n });\n};\n\nconst handleCmd = (s: Session, cmd: StatewireCmd) => {\n if (!Number.isSafeInteger(cmd.seq) || cmd.seq <= 0) {\n protocolError(\"cmd.seq must be a positive safe integer\");\n }\n if (cmd.dur === true) {\n s.durableSeq = Math.max(s.durableSeq, cmd.seq);\n for (const entry of s.pending) {\n if (entry.seq <= s.durableSeq) entry.posted = true;\n }\n }\n if (cmd.type === undefined) return;\n const entry = s.pending.find((p) => p.seq === cmd.seq);\n if (cmd.type === \"applied\") {\n if (entry) cover(s, entry);\n return;\n }\n parkVerdict(s, cmd);\n if (!entry) return;\n cover(s, entry);\n settleEntry(s, entry, outcomeOf(cmd));\n};\n\nconst consumeVerdicts = (s: Session) => {\n const verdicts = s.record.verdicts ?? [];\n const consumed = new Set<number>();\n for (const verdict of verdicts) {\n const entry = s.pending.find((p) => p.seq === verdict.seq);\n if (!entry) continue;\n consumed.add(verdict.seq);\n cover(s, entry);\n settleEntry(s, entry, outcomeOf(verdict as StatewireCmd));\n }\n if (consumed.size === 0) return;\n setRecord(s, {\n ...s.record,\n commands: s.record.commands.filter((c) => !consumed.has(c.seq)),\n verdicts: verdicts.filter((v) => !consumed.has(v.seq)),\n });\n publish(s);\n wake(s);\n};\n\nconst handleCmds = (s: Session, cmds: StatewireCmd[]) => {\n for (const cmd of cmds) handleCmd(s, cmd);\n syncBacklog(s);\n wake(s);\n};\n\nconst ingestOps = (s: Session, ops: unknown[]) => {\n const applied = applyOps(s.canonical, ops);\n s.canonical = applied.state;\n s.changed.push(...applied.changedPaths);\n};\n\nconst publishIngested = (s: Session) => {\n publish(s);\n wake(s);\n};\n\n// A hello's cmd watermark may understate a durable record (cold host, tray\n// unloaded): held seqs resend as-is and the frame's answer arbitrates —\n// absorption where the record survived, a gap refusal where it did not.\nconst snapCtxClock = (s: Session, ctxWm: number) => {\n const ctxAligned =\n s.ctxPending.every((c, i) => c.seq === ctxWm + 1 + i) &&\n s.record.ctxNextSeq === ctxWm + s.ctxPending.length + 1;\n if (!ctxAligned) {\n setRecord(s, { ...s.record, ctxNextSeq: ctxWm + 1 });\n restateContext(s);\n }\n};\n\n// The refusal's watermarks are exact: every held statement above them was\n// never admitted by the live record, and the first unposted seq being beyond\n// watermark+1 proves the record that admitted the missing prefix is gone —\n// its history settles lost and the lane clocks restart at the watermarks.\nconst sessionLostInner = (s: Session, seqWm: number, ctxWm: number) => {\n const held = [...s.pending];\n settleLost(s, held);\n s.pending = [];\n s.durableSeq = seqWm;\n setRecord(s, {\n clientId: s.record.clientId,\n nextSeq: seqWm + 1,\n ctxNextSeq: ctxWm + 1,\n commands: [],\n ...(s.record.failed !== undefined && { failed: s.record.failed }),\n });\n restateContext(s);\n if (\n held.length > 0 &&\n s.onSessionLost?.(held.map((p) => p.inv)) === \"requeue\"\n ) {\n for (const old of held) {\n enqueueInner(\n s,\n old.command,\n old.inv.params,\n () => {},\n () => {},\n );\n }\n }\n publish(s);\n wake(s);\n};\n\nconst handleHello = (\n s: Session,\n { ops, syn }: { ops: unknown[]; syn: StatewireSyn },\n) => {\n if (syn.record !== undefined && syn.record !== \"ephemeral\") {\n protocolError(`unknown record: ${String(syn.record)}`);\n }\n ingestOps(s, ops);\n s.attach = \"attached\";\n s.attachEpoch += 1;\n s.frameFailures = 0;\n s.resumeAt = 0;\n s.ephemeral = syn.record === \"ephemeral\";\n if (s.ephemeral) s.deactivated = true;\n const [attachCmd, attachCtx] = s.attachLaneSeqs;\n s.attachLaneSeqs = [new Set(), new Set()];\n const reconcile = () => {\n if (s.shared) adoptStored(s);\n // Resending unsettled statements is exactly-once-safe: absorbed replays\n // re-emit their stored verdicts (applied while still in flight).\n s.durableSeq = syn.seq ?? 0;\n for (const entry of s.pending) {\n entry.posted = attachCmd.has(entry.seq);\n }\n const ctxWatermark = syn.ctxSeq ?? 0;\n s.ctxPending = s.ctxPending.filter((c) => c.seq > ctxWatermark);\n for (const c of s.ctxPending) c.posted = attachCtx.has(c.seq);\n snapCtxClock(s, ctxWatermark);\n syncBacklogInner(s);\n s.sessionKnown = true;\n };\n if (!s.shared || s.deactivated) {\n reconcile();\n publishIngested(s);\n void pump(s);\n return;\n }\n void transact(s, reconcile).then(() => {\n publishIngested(s);\n void pump(s);\n });\n};\n\nconst handleOps = (\n s: Session,\n { ops, cmds }: { ops: unknown[]; cmds: StatewireCmd[] },\n) => {\n ingestOps(s, ops);\n for (const cmd of cmds) handleCmd(s, cmd);\n syncBacklog(s);\n publishIngested(s);\n};\n\n// A retry-less {syn} refusal is the one session-loss verdict: a cmd gap\n// against its exact watermark settles the held history lost; a pushback\n// (retry present) or a gapless refusal only reconciles the resend queues.\nconst handleRefusal = (s: Session, syn: StatewireSyn) => {\n const { seq, ctxSeq } = syn;\n if (typeof seq === \"number\") {\n const watermark = Math.max(seq, s.durableSeq);\n for (const entry of s.pending) entry.posted = entry.seq <= watermark;\n }\n if (typeof ctxSeq === \"number\") {\n s.ctxPending = s.ctxPending.filter((c) => c.seq > ctxSeq);\n for (const c of s.ctxPending) c.posted = false;\n }\n if (typeof syn.retry === \"number\") {\n s.resumeAt = Date.now() + syn.retry;\n wake(s);\n void pump(s);\n return;\n }\n const firstCmd = s.pending.find((p) => !p.posted);\n const firstCtx = s.ctxPending.find((c) => !c.posted);\n const cmdGap =\n typeof seq === \"number\" &&\n firstCmd !== undefined &&\n firstCmd.seq > Math.max(seq, s.durableSeq) + 1;\n const ctxGap =\n typeof ctxSeq === \"number\" &&\n firstCtx !== undefined &&\n firstCtx.seq > ctxSeq + 1;\n if (cmdGap || ctxGap) {\n void transact(s, () => {\n if (cmdGap) sessionLostInner(s, seq!, ctxSeq ?? 0);\n else snapCtxClock(s, ctxSeq!);\n }).then(() => {\n wake(s);\n void pump(s);\n });\n return;\n }\n wake(s);\n void pump(s);\n};\n\nconst handleDetach = (s: Session) => {\n if (s.attach === \"attached\") s.attach = \"detached\";\n if (s.ephemeral) ephemeralDetach(s);\n wake(s);\n};\n\nconst handleFinish = (s: Session, { reason }: { reason: string }) => {\n if (reason === \"evicted\" || reason === \"error\") return;\n s.attach = \"finished\";\n settleAll(s, \"gone\");\n publish(s);\n wake(s);\n};\n\nconst isFinished = (s: Session) => s.attach === \"finished\";\n\ntype Lanes = {\n frame: StatewireFrame;\n cmdEntries: Pending[];\n ctxEntries: CtxPending[];\n};\n\n// A lane must be strictly consecutive within a frame: the first unposted run\n// per lane rides now, later runs ride follow-up frames.\nconst buildLanes = (s: Session): Lanes | null => {\n const ctxEntries: CtxPending[] = [];\n for (const entry of s.ctxPending) {\n if (entry.posted) continue;\n if (ctxEntries.length > 0 && entry.seq !== ctxEntries.at(-1)!.seq + 1)\n break;\n ctxEntries.push(entry);\n }\n const cmdEntries: Pending[] = [];\n for (const entry of s.pending) {\n if (entry.posted) continue;\n if (cmdEntries.length > 0 && entry.seq !== cmdEntries.at(-1)!.seq + 1)\n break;\n cmdEntries.push(entry);\n }\n if (ctxEntries.length === 0 && cmdEntries.length === 0) return null;\n return {\n frame: {\n ...(ctxEntries.length > 0 && {\n ctx: ctxEntries.map((c) => ({ ops: c.ops, seq: c.seq })),\n }),\n ...(cmdEntries.length > 0 && {\n cmd: cmdEntries.map((p) => ({ ...p.command, seq: p.seq })),\n }),\n },\n cmdEntries,\n ctxEntries,\n };\n};\n\nconst takeAttachLanes = (s: Session): StatewireFrame | null => {\n s.attachLaneSeqs = [new Set(), new Set()];\n const wanted = s.lanesOnAttach;\n s.lanesOnAttach = false;\n if (!wanted || !s.sessionKnown) return null;\n const lanes = buildLanes(s);\n if (!lanes) return null;\n s.attachLaneSeqs = [\n new Set(lanes.cmdEntries.map((p) => p.seq)),\n new Set(lanes.ctxEntries.map((c) => c.seq)),\n ];\n for (const entry of lanes.cmdEntries) entry.attempted = true;\n return lanes.frame;\n};\n\nconst pump = async (s: Session) => {\n if (s.pumping) return;\n s.pumping = true;\n try {\n while (s.running && !isFinished(s)) {\n const transport = s.transport;\n if (buildLanes(s) === null) return;\n if (s.attach !== \"attached\" || !transport) {\n if (transport?.connection.status === \"idle\") {\n transport.connection.reconnect();\n }\n await waitForWake(s);\n continue;\n }\n const resumeDelay = s.resumeAt - Date.now();\n if (resumeDelay > 0) {\n await sleepUntilWake(s, resumeDelay);\n continue;\n }\n const lanes = buildLanes(s);\n if (!lanes) continue;\n const epoch = s.attachEpoch;\n for (const entry of lanes.cmdEntries) entry.attempted = true;\n let result;\n try {\n // Shared storage: the lock across the send keeps per-lane arrival\n // ordered across sharers during attach handover.\n const send = () => transport.send(lanes.frame);\n result = await (s.shared && !s.deactivated\n ? s.store.lock!(send)\n : send());\n } catch {\n if (!s.running || isFinished(s)) return;\n s.frameFailures += 1;\n await sleepUntilWake(s, backoff(s.frameFailures));\n continue;\n }\n if (!s.running) return;\n s.frameFailures = 0;\n if (result.type === \"ok\") {\n if (epoch === s.attachEpoch) {\n for (const entry of lanes.cmdEntries) {\n if (s.pending.includes(entry)) {\n entry.posted = true;\n s.lifecycle?.onPosted?.(entry.inv);\n }\n }\n for (const entry of lanes.ctxEntries) entry.posted = true;\n }\n } else if (result.type === \"refusal\") {\n if (epoch === s.attachEpoch) handleRefusal(s, result.syn);\n } else if (result.type === \"stale-lease\") {\n // A POST outlived its attach: reattach first, the hello arbitrates.\n if (epoch === s.attachEpoch) {\n transport.connection.reconnect();\n await waitForWake(s);\n }\n } else if (result.type === \"no-lease\") {\n // No out-of-band write channel: the frame rides a fresh attach.\n if (epoch === s.attachEpoch) {\n s.lanesOnAttach = true;\n transport.connection.reconnect();\n while (s.running && !isFinished(s) && epoch === s.attachEpoch) {\n await waitForWake(s);\n }\n }\n }\n }\n } finally {\n s.pumping = false;\n }\n};\n\nconst start = (s: Session) => {\n if (s.shared) {\n s.shared.unsubscribe = s.store.subscribe!(() => {\n void transact(s, () => consumeVerdicts(s));\n });\n s.running = true;\n void transact(s, () => {\n if (s.store.load() === null) s.store.save(s.record);\n s.recordPersisted = true;\n adoptStored(s);\n consumeVerdicts(s);\n }).then(() => void pump(s));\n return;\n }\n if (!s.recordPersisted) {\n s.recordPersisted = true;\n s.store.save(s.record);\n }\n adoptStored(s);\n s.running = true;\n void pump(s);\n};\n\nconst stop = (s: Session) => {\n s.running = false;\n if (s.shared) {\n s.shared.unsubscribe?.();\n s.shared.unsubscribe = null;\n }\n wake(s);\n settleAll(s, \"unmount\");\n};\n\nconst setTransport = (s: Session, transport: RemoteLink) => {\n if (s.transport === transport) return;\n s.transport = transport;\n wake(s);\n};\n\nconst enqueueInner = (\n s: Session,\n command: WireCommand,\n params: readonly unknown[],\n resolve: (payload: unknown) => void,\n reject: (error: StatewireSendError) => void,\n) => {\n const seq = s.record.nextSeq;\n const entry: Pending = {\n seq,\n command,\n inv: {\n method: command.method,\n params,\n ts: Date.now(),\n seq,\n clientId: s.record.clientId,\n },\n attempted: false,\n posted: false,\n applied: false,\n resolve,\n reject,\n };\n s.pending.push(entry);\n setRecord(s, { ...s.record, nextSeq: seq + 1, commands: mergeBacklog(s) });\n s.lifecycle?.onStart(entry.inv);\n};\n\nconst enqueue = (\n s: Session,\n command: WireCommand,\n params: readonly unknown[],\n resolve: (payload: unknown) => void,\n reject: (error: StatewireSendError) => void,\n) => {\n if (!s.shared) {\n enqueueInner(s, command, params, resolve, reject);\n void pump(s);\n return;\n }\n void transact(s, () =>\n enqueueInner(s, command, params, resolve, reject),\n ).then(() => void pump(s));\n};\n\n// A stored command may have reached a server: attempted settles it lost,\n// never aborted, when a channel death ends the session.\nconst adoptStored = (s: Session) => {\n const known = new Set(s.pending.map((p) => p.seq));\n const stored = s.record.commands.filter((c) => !known.has(c.seq));\n if (stored.length === 0) return;\n for (const { seq, ...command } of stored) {\n const params =\n command.meta === undefined\n ? command.params\n : (reviveValue([...command.params], command.meta) as unknown[]);\n const entry: Pending = {\n seq,\n command,\n inv: {\n method: command.method,\n params,\n ts: Date.now(),\n seq,\n clientId: s.record.clientId,\n },\n attempted: true,\n posted: false,\n applied: false,\n resolve: () => {},\n reject: () => {},\n };\n s.pending.push(entry);\n s.lifecycle?.onStart(entry.inv);\n }\n s.pending.sort((a, b) => a.seq - b.seq);\n};\n\nconst sendCommand = (\n s: Session,\n method: string,\n params: readonly unknown[],\n): Promise<unknown> => {\n if (!s.running) {\n return rejectedSend({ fate: \"aborted\", cause: \"unmount\" });\n }\n if (isFinished(s)) {\n return rejectedSend({ fate: \"aborted\", cause: \"stream-gone\" });\n }\n const result = new Promise<unknown>((resolve, reject) => {\n const { params: encoded, meta } = encodeParams(params);\n enqueue(\n s,\n { method, params: encoded, ...(meta !== undefined && { meta }) },\n params,\n resolve,\n reject,\n );\n });\n result.catch(() => {});\n return result;\n};\n\nconst takeFailed = (\n s: Session,\n entry: StatewireClient.FailedCommand,\n): StatewireClient.FailedCommand => {\n const failed = s.record.failed ?? [];\n const found = failed.find(\n (f) =>\n f.seq === entry.seq && f.ts === entry.ts && f.command === entry.command,\n );\n if (found === undefined) {\n throw new Error(`statewire: unknown failed command \"${entry.command}\"`);\n }\n setRecord(s, { ...s.record, failed: failed.filter((f) => f !== found) });\n s.notify();\n return found;\n};\n\nexport const discardFailed = (\n s: Session,\n entry: StatewireClient.FailedCommand,\n): void => {\n takeFailed(s, entry);\n};\n\nexport const retryFailed = (\n s: Session,\n entry: StatewireClient.FailedCommand,\n): Promise<unknown> => {\n if (!s.running) {\n return rejectedSend({ fate: \"aborted\", cause: \"unmount\" });\n }\n if (isFinished(s)) {\n return rejectedSend({ fate: \"aborted\", cause: \"stream-gone\" });\n }\n const found = takeFailed(s, entry);\n const params =\n found.meta === undefined\n ? found.params\n : (reviveValue([...found.params], found.meta) as unknown[]);\n const result = new Promise<unknown>((resolve, reject) => {\n enqueue(\n s,\n {\n method: found.command,\n params: [...found.params],\n ...(found.meta !== undefined && { meta: found.meta }),\n },\n params,\n resolve,\n reject,\n );\n });\n result.catch(() => {});\n return result;\n};\n\nconst setContext = (s: Session, value: Record<string, unknown>): void => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(\"statewire: context must be a plain object\");\n }\n if (!s.running || isFinished(s)) return;\n const { value: encoded, meta } = encodeValue(value);\n const ops = [\n {\n op: \"replace\",\n path: [],\n value: encoded,\n ...(meta !== undefined && { meta }),\n },\n ];\n s.ctxOps = ops;\n const mint = () => {\n const seq = s.record.ctxNextSeq;\n setRecord(s, { ...s.record, ctxNextSeq: seq + 1 });\n s.ctxPending.push({ seq, ops, posted: false });\n };\n if (!s.shared) {\n mint();\n wake(s);\n void pump(s);\n return;\n }\n void transact(s, mint).then(() => {\n wake(s);\n void pump(s);\n });\n};\n\nexport const useStatewireSession = (\n options: StatewireSessionOptions,\n): Session => {\n const [defaultStore] = useState(createMemorySessionStore);\n const mounted = useContext(SessionStorageContext);\n if (options.sessionStore !== undefined && mounted !== undefined) {\n throw new Error(\n \"statewire: session storage is set twice — drop the transport's sessionStore or the client's storage.session\",\n );\n }\n const store = options.sessionStore ?? mounted ?? defaultStore;\n if ((store.lock === undefined) !== (store.subscribe === undefined)) {\n throw new Error(\n \"statewire: session storage must provide lock and subscribe together\",\n );\n }\n const [s] = useState((): Session => {\n const stored = store.load();\n if (stored !== null && !Array.isArray(stored.commands)) {\n throw new Error(\n \"statewire: session storage loaded a record without a commands array\",\n );\n }\n const record = stored ?? {\n clientId: newClientId(),\n nextSeq: 1,\n ctxNextSeq: 1,\n commands: [],\n };\n const session: Session = {\n record,\n ctx: {\n get clientId() {\n return session.record.clientId;\n },\n takeAttachLanes: () => takeAttachLanes(session),\n onHello: (args) => handleHello(session, args),\n onOps: (args) => handleOps(session, args),\n onCmds: (cmds) => handleCmds(session, cmds),\n onRefusal: (syn) => handleRefusal(session, syn),\n onIdle: (level) => setIdle(session, level),\n onDetach: () => handleDetach(session),\n onFinish: (args) => handleFinish(session, args),\n },\n recordPersisted: stored !== null,\n store,\n shared:\n store.lock !== undefined\n ? { txq: Promise.resolve(), parked: [], unsubscribe: null }\n : false,\n ephemeral: false,\n deactivated: false,\n sessionKnown: false,\n durableSeq: 0,\n resumeAt: 0,\n idle: false,\n onSessionLost: undefined,\n onDone: undefined,\n ctxOps: undefined,\n ctxPending: [],\n lanesOnAttach: false,\n attachLaneSeqs: [new Set(), new Set()],\n frameFailures: 0,\n pending: [],\n canonical: undefined,\n lastPublished: undefined,\n changed: [],\n source: {\n snapshot: () => session.canonical,\n takeChanged: () => {\n const changed = session.changed;\n session.changed = [];\n return changed;\n },\n setOnChange: (listener) => {\n session.notify = listener ?? (() => {});\n },\n },\n attach: \"detached\",\n attachEpoch: 0,\n running: false,\n pumping: false,\n transport: null,\n waiters: [],\n lifecycle: null,\n notify: () => {},\n commands: createMethodProxy((method, params) =>\n sendCommand(session, method, params),\n ),\n };\n bindCommandsHost(session.commands, {\n setListener: (listener) => {\n session.lifecycle = listener;\n },\n });\n return session;\n });\n if ((store.lock !== undefined) !== (s.shared !== false)) {\n throw new Error(\n \"statewire: session storage changed sharedness across renders — lock/subscribe must be present from the first render or never\",\n );\n }\n s.store = store;\n s.onSessionLost = options.onSessionLost;\n s.onDone = options.onDone;\n useEffect(() => {\n start(s);\n return () => stop(s);\n }, [s]);\n return s;\n};\n\nexport { setContext, setTransport };\n"],"mappings":"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"}