statewire 0.19.2 → 0.19.3

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.
@@ -138,7 +138,7 @@ const flush = (c, scheduled = false) => {
138
138
  const busy = c.getBusy();
139
139
  const busyChanged = busy !== c.notifiedBusy;
140
140
  c.notifiedBusy = busy;
141
- const failed = c.value.failures?.list() ?? NO_FAILED;
141
+ const failed = c.value?.failures?.list() ?? NO_FAILED;
142
142
  let failedChanged = false;
143
143
  if (failed !== c.notifiedFailed) {
144
144
  if (scheduled) {
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","names":["useEffect","useState","createChanges","getCommandsHost","getStateHost","CommandsInvocation","CommandsListener","recordMutations","createMacrotaskPoster","createMethodProxy","StatewirePath","StatewireSendError","Statewire","StatewireClient","CONNECTED_CONNECTION","Connection","status","degraded","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","notifiedError","ConnectionError","notifiedBusy","notifiedFailed","stale","everAttached","overlaysDirty","materializeKey","flushing","scheduled","listeners","Set","post","commandsListener","getState","getBusy","getFailed","rematerialize","commands","CommandsProxy","subscribe","listener","schedule","c","markStale","drainCanonical","push","takeChanged","snapshot","undefined","next","initialState","state","dropCovered","failureCovered","failures","entry","list","discard","recompute","optimistic","materialize","rekeyed","Object","is","prevCanonical","paths","overlay","protocol","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","onError","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 CONNECTED_CONNECTION: StatewireClient.Connection = {\n status: \"connected\",\n degraded: false,\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 notifiedError: StatewireClient.ConnectionError | undefined;\n notifiedBusy: boolean;\n notifiedFailed: readonly StatewireClient.FailedCommand[];\n stale: boolean;\n everAttached: boolean;\n overlaysDirty: boolean;\n materializeKey: unknown;\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 rematerialize: () => void;\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.value) return;\n const { optimistic, materialize, materializeKey } = c.getOptions();\n const rekeyed = !Object.is(materializeKey, c.materializeKey);\n if (!c.stale && !rekeyed) 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 && !rekeyed) return;\n c.overlaysDirty = false;\n c.materializeKey = materializeKey;\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 if (\n inv.protocol !== undefined &&\n inv.protocol !== (c.getOptions().protocol ?? \"default\")\n )\n continue;\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 ?? CONNECTED_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 if (connection.error !== c.notifiedError) {\n c.notifiedError = connection.error;\n if (connection.error) options.onError?.(connection.error);\n }\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 ...(inv.protocol !== undefined && { protocol: inv.protocol }),\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 notifiedError: undefined,\n notifiedBusy: true,\n notifiedFailed: NO_FAILED,\n stale: false,\n everAttached: false,\n overlaysDirty: false,\n materializeKey: undefined,\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 rematerialize: () => flush(c),\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","CONNECTED_CONNECTION","Connection","status","degraded","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","notifiedError","ConnectionError","notifiedBusy","notifiedFailed","stale","everAttached","overlaysDirty","materializeKey","flushing","scheduled","listeners","Set","post","commandsListener","getState","getBusy","getFailed","rematerialize","commands","CommandsProxy","subscribe","listener","schedule","c","markStale","drainCanonical","push","takeChanged","snapshot","undefined","next","initialState","state","dropCovered","failureCovered","failures","entry","list","discard","recompute","optimistic","materialize","rekeyed","Object","is","prevCanonical","paths","overlay","protocol","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","onError","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 CONNECTED_CONNECTION: StatewireClient.Connection = {\n status: \"connected\",\n degraded: false,\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 notifiedError: StatewireClient.ConnectionError | undefined;\n notifiedBusy: boolean;\n notifiedFailed: readonly StatewireClient.FailedCommand[];\n stale: boolean;\n everAttached: boolean;\n overlaysDirty: boolean;\n materializeKey: unknown;\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 rematerialize: () => void;\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.value) return;\n const { optimistic, materialize, materializeKey } = c.getOptions();\n const rekeyed = !Object.is(materializeKey, c.materializeKey);\n if (!c.stale && !rekeyed) 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 && !rekeyed) return;\n c.overlaysDirty = false;\n c.materializeKey = materializeKey;\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 if (\n inv.protocol !== undefined &&\n inv.protocol !== (c.getOptions().protocol ?? \"default\")\n )\n continue;\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 ?? CONNECTED_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 if (connection.error !== c.notifiedError) {\n c.notifiedError = connection.error;\n if (connection.error) options.onError?.(connection.error);\n }\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 ...(inv.protocol !== undefined && { protocol: inv.protocol }),\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 notifiedError: undefined,\n notifiedBusy: true,\n notifiedFailed: NO_FAILED,\n stale: false,\n everAttached: false,\n overlaysDirty: false,\n materializeKey: undefined,\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 rematerialize: () => flush(c),\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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "statewire",
3
- "version": "0.19.2",
3
+ "version": "0.19.3",
4
4
  "description": "State over the wire: snapshot-first delta streaming and command submission for any state and any command",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -219,7 +219,7 @@ const flush = (c: Core, scheduled = false) => {
219
219
  c.notifiedBusy = busy;
220
220
  // The failed snapshot advances only on the scheduled pass: settles land
221
221
  // mid-unmount, where a changed snapshot re-renders the unmounting tree.
222
- const failed = c.value.failures?.list() ?? NO_FAILED;
222
+ const failed = c.value?.failures?.list() ?? NO_FAILED;
223
223
  let failedChanged = false;
224
224
  if (failed !== c.notifiedFailed) {
225
225
  if (scheduled) {