statewire 0.24.1 → 0.24.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
package/dist/storage.js CHANGED
@@ -46,7 +46,7 @@ const identify = (record) => ({
46
46
  ...command,
47
47
  ...command.produced?.wire.version === "2026-09-30" && { produced: {
48
48
  ...command.produced,
49
- wire: { version: "2026-11-01" }
49
+ wire: { version: "2026-11-02" }
50
50
  } },
51
51
  id: randomId(),
52
52
  ts: Date.now()
@@ -1 +1 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { negotiationHeaders, parseNegotiation } from "../wire/protocol.js";
2
2
  import { timing } from "../client/timing.js";
3
- import { classify, handleEnvelope, resolveHeaders, settleFin, useLink, validateRefusalSyn } from "../client/connection.js";
3
+ import { classify, handleEnvelope, replacing, resolveHeaders, settleFin, useLink, validateRefusalSyn } from "../client/connection.js";
4
4
  import { createSseParser } from "./sse-parser.js";
5
5
  import { useStatewireRemote } from "./remote.js";
6
6
  import { flushTapSync, resource } from "@assistant-ui/tap";
@@ -55,6 +55,7 @@ const attemptStream = async (c, options, abort) => {
55
55
  const headers = await resolveHeaders(options.headers, c.authStale);
56
56
  for (const [name, value] of Object.entries(negotiationHeaders(options))) if (!headers.has(name)) headers.set(name, value);
57
57
  c.negotiation = parseNegotiation(headers);
58
+ replacing(c, headers);
58
59
  c.authStale = false;
59
60
  const lanes = flushTapSync(() => c.ctx.takeAttachLanes());
60
61
  const body = lanes === null ? void 0 : JSON.stringify(lanes);
@@ -1 +1 @@
1
- {"version":3,"file":"sse.js","names":["StatewireDocument","flushTapSync","resource","ResourceElement","createSseParser","timing","settleFin","classify","handleEnvelope","resolveHeaders","useLink","validateRefusalSyn","AttemptOutcome","Conn","StatewireCmd","StatewireEnvelope","StatewireSyn","Statewire","StatewireClient","StatewireHost","useStatewireRemote","negotiationHeaders","parseNegotiation","StatewireFrame","ctx","protocol","Encoded","cmd","method","params","meta","seq","res","StatewireRemoteProps","beforeAttach","Promise","clientId","takeAttachLanes","onHello","args","ops","syn","onOps","cmds","onCmds","onRefusal","onIdle","level","onDetach","onFinish","Fin","StatewireSubmitResult","type","ConnectionState","RemoteLink","storageFailed","error","Error","protocolFailed","connection","Connection","parked","send","frame","LEASE_HEADER","warnedNoLease","warnNoLease","console","warn","baseUrl","options","HttpOptions","url","replace","withExtra","headers","Headers","extra","Record","merged","name","value","Object","entries","set","timedFetch","input","init","RequestInit","signal","AbortSignal","timeout","Response","fetch","globalThis","consume","c","reader","ReadableStreamDefaultReader","Uint8Array","heartbeat","AbortController","dead","decoder","TextDecoder","parse","timer","setTimeout","abort","heartbeatTimeoutMs","result","ReadableStreamReadResult","read","clearTimeout","done","data","decode","stream","env","JSON","attemptStream","persistence","aborted","lease","authStale","has","negotiation","lanes","body","undefined","stringify","headerTimer","accept","cache","any","ok","clone","json","catch","fin","httpFin","get","getReader","cancel","addEventListener","once","removeEventListener","postFrame","lifetime","retryAfterMs","header","trim","test","retry","Number","isSafeInteger","reason","status","message","code","refusalSyn","sendFrame","headerRetry","useSseLink","attemptOnce","SyntaxError","startsWith","useStatewireHttp","StatewireHttp","Commands","TState","TCommands"],"sources":["../../src/transports/sse.ts"],"sourcesContent":["import type { StatewireDocument } from \"../document\";\nimport { flushTapSync, resource } from \"@assistant-ui/tap\";\nimport type { ResourceElement } from \"@assistant-ui/tap\";\nimport { createSseParser } from \"./sse-parser\";\nimport { timing } from \"../client/timing\";\nimport {\n settleFin,\n classify,\n handleEnvelope,\n resolveHeaders,\n useLink,\n validateRefusalSyn,\n} from \"../client/connection\";\nimport type {\n AttemptOutcome,\n Conn,\n StatewireCmd,\n StatewireEnvelope,\n StatewireSyn,\n} from \"../client/connection\";\nimport type { Statewire } from \"../types\";\nimport type { StatewireClient } from \"../statewire\";\nimport type { StatewireHost } from \"../host\";\nimport { useStatewireRemote } from \"./remote\";\nimport { negotiationHeaders, parseNegotiation } from \"../wire/protocol\";\n\n/** A client frame's lanes: stamped statements, strictly consecutive per lane. */\nexport type StatewireFrame = {\n ctx?: ({ protocol: string } & StatewireDocument.Encoded)[];\n cmd?: {\n protocol: string;\n method: string;\n params: unknown[];\n meta?: unknown;\n seq: number;\n }[];\n /** Attach only: per durable lane, the seq through which the client holds every verdict. */\n res?: { protocol: string; seq: number }[];\n};\n\nexport type StatewireRemoteProps = {\n beforeAttach?: () => void | Promise<void>;\n clientId: string;\n /** Lanes to ride the attach frame: ephemeral-lane statements, plus durable cmds on no-lease supersession; records the included entries. */\n takeAttachLanes: () => StatewireFrame | null;\n onHello: (args: { ops: unknown[]; syn: StatewireSyn }) => void;\n onOps: (args: { ops: unknown[]; cmds: StatewireCmd[] }) => void;\n onCmds: (cmds: StatewireCmd[]) => void;\n onRefusal: (syn: StatewireSyn) => void;\n onIdle: (level: boolean) => void;\n onDetach: () => void;\n onFinish: (args: StatewireHost.Fin) => void;\n};\n\nexport type StatewireSubmitResult =\n | { type: \"ok\" }\n | { type: \"refusal\"; syn: StatewireSyn }\n | { type: \"stale-lease\" }\n | { type: \"no-lease\" };\n\nexport type ConnectionState = StatewireClient.ConnectionState;\n\n/** The live wire a remote session drives: connection status plus frame submission. */\nexport type RemoteLink = {\n storageFailed: (error: Error) => void;\n protocolFailed: (error: Error) => void;\n connection: StatewireClient.Connection;\n /** A deferred first attach still waiting; `reconnect()` releases it. */\n parked: boolean;\n send: (frame: StatewireFrame) => Promise<StatewireSubmitResult>;\n};\n\nconst LEASE_HEADER = \"Statewire-Lease\";\n\nlet warnedNoLease = false;\n\nconst warnNoLease = () => {\n if (warnedNoLease) return;\n warnedNoLease = true;\n console.warn(\n \"statewire: SSE attach returned no readable Statewire-Lease header; commands will re-attach the stream. Cross-origin hosts must expose it (Access-Control-Expose-Headers: Statewire-Lease).\",\n );\n};\n\nconst baseUrl = (options: StatewireClient.HttpOptions) =>\n options.url.replace(/\\/$/, \"\");\n\nconst withExtra = (headers: Headers, extra: Record<string, string>) => {\n const merged = new Headers(headers);\n for (const [name, value] of Object.entries(extra)) merged.set(name, value);\n return merged;\n};\n\nconst timedFetch = async (\n options: StatewireClient.HttpOptions,\n input: string,\n init: RequestInit & { signal: AbortSignal },\n timeout: AbortSignal,\n): Promise<Response> => {\n try {\n return await (options.fetch ?? globalThis.fetch)(input, init);\n } catch {\n throw classify(timeout);\n }\n};\n\nconst consume = async (\n c: Conn,\n reader: ReadableStreamDefaultReader<Uint8Array>,\n heartbeat: AbortController,\n dead: () => boolean,\n): Promise<AttemptOutcome> => {\n const decoder = new TextDecoder();\n const parse = createSseParser();\n for (;;) {\n const timer = setTimeout(\n () => heartbeat.abort(),\n timing.heartbeatTimeoutMs,\n );\n let result: ReadableStreamReadResult<Uint8Array>;\n try {\n result = await reader.read();\n } catch {\n throw classify(heartbeat.signal);\n } finally {\n clearTimeout(timer);\n }\n if (result.done) return \"ended\";\n for (const data of parse(decoder.decode(result.value, { stream: true }))) {\n if (dead()) return \"ended\";\n const env = JSON.parse(data) as StatewireEnvelope;\n const done = flushTapSync(() => handleEnvelope(c, env));\n if (done) return done;\n }\n }\n};\n\nconst attemptStream = async (\n c: Conn,\n options: StatewireClient.HttpOptions,\n abort: AbortController,\n): Promise<AttemptOutcome> => {\n const persistence = c.ctx.beforeAttach?.();\n if (persistence) await persistence;\n if (abort.signal.aborted) return \"ended\";\n c.lease = null;\n const headers = await resolveHeaders(options.headers, c.authStale);\n for (const [name, value] of Object.entries(negotiationHeaders(options))) {\n if (!headers.has(name)) headers.set(name, value);\n }\n c.negotiation = parseNegotiation(headers);\n c.authStale = false;\n const lanes = flushTapSync(() => c.ctx.takeAttachLanes());\n const body = lanes === null ? undefined : JSON.stringify(lanes);\n const heartbeat = new AbortController();\n const headerTimer = setTimeout(\n () => heartbeat.abort(),\n timing.heartbeatTimeoutMs,\n );\n let res: Response;\n try {\n res = await timedFetch(\n options,\n `${baseUrl(options)}/stream`,\n {\n method: body === undefined ? \"GET\" : \"POST\",\n headers: withExtra(headers, {\n \"content-type\": \"application/json\",\n \"Statewire-Client-Id\": c.ctx.clientId,\n accept: \"text/event-stream\",\n }),\n ...(body === undefined ? {} : { body }),\n cache: \"no-store\",\n signal: AbortSignal.any([abort.signal, heartbeat.signal]),\n },\n heartbeat.signal,\n );\n } finally {\n clearTimeout(headerTimer);\n }\n if (!res.ok) {\n const body = await res\n .clone()\n .json()\n .catch(() => null);\n return (\n flushTapSync(() =>\n body?.fin === undefined\n ? settleFin(c, httpFin(res))\n : handleEnvelope(c, body),\n ) ?? \"stop\"\n );\n }\n if (!res.body)\n throw new Error(\"statewire: protocol error: stream response has no body\");\n c.lease = res.headers.get(LEASE_HEADER);\n if (c.lease === null) warnNoLease();\n const reader = res.body.getReader();\n const cancel = () => {\n void reader.cancel().catch(() => {});\n };\n abort.signal.addEventListener(\"abort\", cancel, { once: true });\n try {\n return await consume(c, reader, heartbeat, () => abort.signal.aborted);\n } finally {\n abort.signal.removeEventListener(\"abort\", cancel);\n reader.cancel().catch(() => {});\n }\n};\n\nconst postFrame = async (\n c: Conn,\n options: StatewireClient.HttpOptions,\n lease: string,\n frame: StatewireFrame,\n timeout: AbortSignal,\n): Promise<Response> =>\n timedFetch(\n options,\n `${baseUrl(options)}/frames`,\n {\n method: \"POST\",\n headers: withExtra(new Headers(), {\n \"content-type\": \"application/json\",\n [LEASE_HEADER]: lease,\n }),\n body: JSON.stringify(frame),\n signal: AbortSignal.any([\n c.lifetime?.signal ?? AbortSignal.abort(),\n timeout,\n ]),\n },\n timeout,\n );\n\n// Delta-seconds only; anything else reads as absent.\nconst retryAfterMs = (res: Response): number | null => {\n const header = res.headers.get(\"retry-after\")?.trim();\n if (header === undefined || !/^\\d+$/.test(header)) return null;\n const retry = Number(header) * 1000;\n return Number.isSafeInteger(retry) ? retry : null;\n};\n\nconst httpFin = (res: Response): StatewireHost.Fin => ({\n reason:\n res.status === 401\n ? \"unauthorized\"\n : res.status === 403\n ? \"forbidden\"\n : res.status === 429 || res.status === 503\n ? \"reconnect\"\n : res.status >= 400 && res.status < 500\n ? \"protocol-error\"\n : \"error\",\n status: res.status,\n message: `HTTP ${res.status}`,\n ...(res.status === 429 || res.status === 503 ? { code: \"overloaded\" } : {}),\n ...(retryAfterMs(res) !== null ? { retry: retryAfterMs(res)! } : {}),\n});\n\nconst refusalSyn = async (res: Response): Promise<StatewireSyn> => {\n const body = (await res.json().catch(() => null)) as {\n syn?: StatewireSyn;\n } | null;\n const syn = body?.syn;\n if (typeof syn !== \"object\" || syn === null) {\n throw new Error(`HTTP ${res.status}`);\n }\n return validateRefusalSyn(syn);\n};\n\nconst sendFrame = async (\n c: Conn,\n options: StatewireClient.HttpOptions,\n frame: StatewireFrame,\n): Promise<StatewireSubmitResult> => {\n const lease = c.lease;\n if (lease === null) return { type: \"no-lease\" };\n const timeout = AbortSignal.timeout(timing.heartbeatTimeoutMs);\n const res = await postFrame(c, options, lease, frame, timeout);\n if (res.ok) return { type: \"ok\" };\n if (res.status === 429 || res.status === 409) {\n // The syn body retry wins; Retry-After covers 429s minted below the host.\n const headerRetry = res.status === 429 ? retryAfterMs(res) : null;\n const syn: StatewireSyn = await refusalSyn(res).catch((error: unknown) => {\n if (headerRetry === null) throw error;\n return { retry: headerRetry };\n });\n if (syn.retry === undefined && headerRetry !== null)\n syn.retry = headerRetry;\n return { type: \"refusal\", syn };\n }\n if (res.status === 423) return { type: \"stale-lease\" };\n flushTapSync(() => settleFin(c, httpFin(res)));\n c.abort?.abort();\n throw new Error(`HTTP ${res.status}`);\n};\n\nconst useSseLink = (\n options: StatewireClient.HttpOptions,\n ctx: StatewireRemoteProps,\n): RemoteLink =>\n useLink({\n ...options,\n ctx,\n attemptOnce: (c, abort) => attemptStream(c, options, abort),\n send: async (c, frame) => {\n try {\n return await sendFrame(c, options, frame);\n } catch (error) {\n if (\n error instanceof SyntaxError ||\n (error instanceof Error &&\n error.message.startsWith(\"statewire: protocol error:\"))\n ) {\n flushTapSync(() =>\n settleFin(c, { reason: \"protocol-error\", message: error.message }),\n );\n c.abort?.abort();\n }\n throw error;\n }\n },\n });\n\nconst useStatewireHttp = (\n options: StatewireClient.HttpOptions,\n): Statewire<any, any> => useStatewireRemote(options, useSseLink);\n\nexport const StatewireHttp = resource(useStatewireHttp) as <\n TState = any,\n TCommands extends Statewire.Commands = Statewire.Commands,\n>(\n options: StatewireClient.HttpOptions,\n) => ResourceElement<Statewire<TState | undefined, TCommands>>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"sse.js","names":["StatewireDocument","flushTapSync","resource","ResourceElement","createSseParser","timing","replacing","settleFin","classify","handleEnvelope","resolveHeaders","useLink","validateRefusalSyn","AttemptOutcome","Conn","StatewireCmd","StatewireEnvelope","StatewireSyn","Statewire","StatewireClient","StatewireHost","useStatewireRemote","negotiationHeaders","parseNegotiation","StatewireFrame","ctx","protocol","Encoded","cmd","method","params","meta","seq","res","StatewireRemoteProps","beforeAttach","Promise","clientId","takeAttachLanes","onHello","args","ops","syn","onOps","cmds","onCmds","onRefusal","onIdle","level","onDetach","onFinish","Fin","StatewireSubmitResult","type","ConnectionState","RemoteLink","storageFailed","error","Error","protocolFailed","connection","Connection","parked","send","frame","LEASE_HEADER","warnedNoLease","warnNoLease","console","warn","baseUrl","options","HttpOptions","url","replace","withExtra","headers","Headers","extra","Record","merged","name","value","Object","entries","set","timedFetch","input","init","RequestInit","signal","AbortSignal","timeout","Response","fetch","globalThis","consume","c","reader","ReadableStreamDefaultReader","Uint8Array","heartbeat","AbortController","dead","decoder","TextDecoder","parse","timer","setTimeout","abort","heartbeatTimeoutMs","result","ReadableStreamReadResult","read","clearTimeout","done","data","decode","stream","env","JSON","attemptStream","persistence","aborted","lease","authStale","has","negotiation","lanes","body","undefined","stringify","headerTimer","accept","cache","any","ok","clone","json","catch","fin","httpFin","get","getReader","cancel","addEventListener","once","removeEventListener","postFrame","lifetime","retryAfterMs","header","trim","test","retry","Number","isSafeInteger","reason","status","message","code","refusalSyn","sendFrame","headerRetry","useSseLink","attemptOnce","SyntaxError","startsWith","useStatewireHttp","StatewireHttp","Commands","TState","TCommands"],"sources":["../../src/transports/sse.ts"],"sourcesContent":["import type { StatewireDocument } from \"../document\";\nimport { flushTapSync, resource } from \"@assistant-ui/tap\";\nimport type { ResourceElement } from \"@assistant-ui/tap\";\nimport { createSseParser } from \"./sse-parser\";\nimport { timing } from \"../client/timing\";\nimport {\n replacing,\n settleFin,\n classify,\n handleEnvelope,\n resolveHeaders,\n useLink,\n validateRefusalSyn,\n} from \"../client/connection\";\nimport type {\n AttemptOutcome,\n Conn,\n StatewireCmd,\n StatewireEnvelope,\n StatewireSyn,\n} from \"../client/connection\";\nimport type { Statewire } from \"../types\";\nimport type { StatewireClient } from \"../statewire\";\nimport type { StatewireHost } from \"../host\";\nimport { useStatewireRemote } from \"./remote\";\nimport { negotiationHeaders, parseNegotiation } from \"../wire/protocol\";\n\n/** A client frame's lanes: stamped statements, strictly consecutive per lane. */\nexport type StatewireFrame = {\n ctx?: ({ protocol: string } & StatewireDocument.Encoded)[];\n cmd?: {\n protocol: string;\n method: string;\n params: unknown[];\n meta?: unknown;\n seq: number;\n }[];\n /** Attach only: per durable lane, the seq through which the client holds every verdict. */\n res?: { protocol: string; seq: number }[];\n};\n\nexport type StatewireRemoteProps = {\n beforeAttach?: () => void | Promise<void>;\n clientId: string;\n /** Lanes to ride the attach frame: ephemeral-lane statements, plus durable cmds on no-lease supersession; records the included entries. */\n takeAttachLanes: () => StatewireFrame | null;\n onHello: (args: { ops: unknown[]; syn: StatewireSyn }) => void;\n onOps: (args: { ops: unknown[]; cmds: StatewireCmd[] }) => void;\n onCmds: (cmds: StatewireCmd[]) => void;\n onRefusal: (syn: StatewireSyn) => void;\n onIdle: (level: boolean) => void;\n onDetach: () => void;\n onFinish: (args: StatewireHost.Fin) => void;\n};\n\nexport type StatewireSubmitResult =\n | { type: \"ok\" }\n | { type: \"refusal\"; syn: StatewireSyn }\n | { type: \"stale-lease\" }\n | { type: \"no-lease\" };\n\nexport type ConnectionState = StatewireClient.ConnectionState;\n\n/** The live wire a remote session drives: connection status plus frame submission. */\nexport type RemoteLink = {\n storageFailed: (error: Error) => void;\n protocolFailed: (error: Error) => void;\n connection: StatewireClient.Connection;\n /** A deferred first attach still waiting; `reconnect()` releases it. */\n parked: boolean;\n send: (frame: StatewireFrame) => Promise<StatewireSubmitResult>;\n};\n\nconst LEASE_HEADER = \"Statewire-Lease\";\n\nlet warnedNoLease = false;\n\nconst warnNoLease = () => {\n if (warnedNoLease) return;\n warnedNoLease = true;\n console.warn(\n \"statewire: SSE attach returned no readable Statewire-Lease header; commands will re-attach the stream. Cross-origin hosts must expose it (Access-Control-Expose-Headers: Statewire-Lease).\",\n );\n};\n\nconst baseUrl = (options: StatewireClient.HttpOptions) =>\n options.url.replace(/\\/$/, \"\");\n\nconst withExtra = (headers: Headers, extra: Record<string, string>) => {\n const merged = new Headers(headers);\n for (const [name, value] of Object.entries(extra)) merged.set(name, value);\n return merged;\n};\n\nconst timedFetch = async (\n options: StatewireClient.HttpOptions,\n input: string,\n init: RequestInit & { signal: AbortSignal },\n timeout: AbortSignal,\n): Promise<Response> => {\n try {\n return await (options.fetch ?? globalThis.fetch)(input, init);\n } catch {\n throw classify(timeout);\n }\n};\n\nconst consume = async (\n c: Conn,\n reader: ReadableStreamDefaultReader<Uint8Array>,\n heartbeat: AbortController,\n dead: () => boolean,\n): Promise<AttemptOutcome> => {\n const decoder = new TextDecoder();\n const parse = createSseParser();\n for (;;) {\n const timer = setTimeout(\n () => heartbeat.abort(),\n timing.heartbeatTimeoutMs,\n );\n let result: ReadableStreamReadResult<Uint8Array>;\n try {\n result = await reader.read();\n } catch {\n throw classify(heartbeat.signal);\n } finally {\n clearTimeout(timer);\n }\n if (result.done) return \"ended\";\n for (const data of parse(decoder.decode(result.value, { stream: true }))) {\n if (dead()) return \"ended\";\n const env = JSON.parse(data) as StatewireEnvelope;\n const done = flushTapSync(() => handleEnvelope(c, env));\n if (done) return done;\n }\n }\n};\n\nconst attemptStream = async (\n c: Conn,\n options: StatewireClient.HttpOptions,\n abort: AbortController,\n): Promise<AttemptOutcome> => {\n const persistence = c.ctx.beforeAttach?.();\n if (persistence) await persistence;\n if (abort.signal.aborted) return \"ended\";\n c.lease = null;\n const headers = await resolveHeaders(options.headers, c.authStale);\n for (const [name, value] of Object.entries(negotiationHeaders(options))) {\n if (!headers.has(name)) headers.set(name, value);\n }\n c.negotiation = parseNegotiation(headers);\n replacing(c, headers);\n c.authStale = false;\n const lanes = flushTapSync(() => c.ctx.takeAttachLanes());\n const body = lanes === null ? undefined : JSON.stringify(lanes);\n const heartbeat = new AbortController();\n const headerTimer = setTimeout(\n () => heartbeat.abort(),\n timing.heartbeatTimeoutMs,\n );\n let res: Response;\n try {\n res = await timedFetch(\n options,\n `${baseUrl(options)}/stream`,\n {\n method: body === undefined ? \"GET\" : \"POST\",\n headers: withExtra(headers, {\n \"content-type\": \"application/json\",\n \"Statewire-Client-Id\": c.ctx.clientId,\n accept: \"text/event-stream\",\n }),\n ...(body === undefined ? {} : { body }),\n cache: \"no-store\",\n signal: AbortSignal.any([abort.signal, heartbeat.signal]),\n },\n heartbeat.signal,\n );\n } finally {\n clearTimeout(headerTimer);\n }\n if (!res.ok) {\n const body = await res\n .clone()\n .json()\n .catch(() => null);\n return (\n flushTapSync(() =>\n body?.fin === undefined\n ? settleFin(c, httpFin(res))\n : handleEnvelope(c, body),\n ) ?? \"stop\"\n );\n }\n if (!res.body)\n throw new Error(\"statewire: protocol error: stream response has no body\");\n c.lease = res.headers.get(LEASE_HEADER);\n if (c.lease === null) warnNoLease();\n const reader = res.body.getReader();\n const cancel = () => {\n void reader.cancel().catch(() => {});\n };\n abort.signal.addEventListener(\"abort\", cancel, { once: true });\n try {\n return await consume(c, reader, heartbeat, () => abort.signal.aborted);\n } finally {\n abort.signal.removeEventListener(\"abort\", cancel);\n reader.cancel().catch(() => {});\n }\n};\n\nconst postFrame = async (\n c: Conn,\n options: StatewireClient.HttpOptions,\n lease: string,\n frame: StatewireFrame,\n timeout: AbortSignal,\n): Promise<Response> =>\n timedFetch(\n options,\n `${baseUrl(options)}/frames`,\n {\n method: \"POST\",\n headers: withExtra(new Headers(), {\n \"content-type\": \"application/json\",\n [LEASE_HEADER]: lease,\n }),\n body: JSON.stringify(frame),\n signal: AbortSignal.any([\n c.lifetime?.signal ?? AbortSignal.abort(),\n timeout,\n ]),\n },\n timeout,\n );\n\n// Delta-seconds only; anything else reads as absent.\nconst retryAfterMs = (res: Response): number | null => {\n const header = res.headers.get(\"retry-after\")?.trim();\n if (header === undefined || !/^\\d+$/.test(header)) return null;\n const retry = Number(header) * 1000;\n return Number.isSafeInteger(retry) ? retry : null;\n};\n\nconst httpFin = (res: Response): StatewireHost.Fin => ({\n reason:\n res.status === 401\n ? \"unauthorized\"\n : res.status === 403\n ? \"forbidden\"\n : res.status === 429 || res.status === 503\n ? \"reconnect\"\n : res.status >= 400 && res.status < 500\n ? \"protocol-error\"\n : \"error\",\n status: res.status,\n message: `HTTP ${res.status}`,\n ...(res.status === 429 || res.status === 503 ? { code: \"overloaded\" } : {}),\n ...(retryAfterMs(res) !== null ? { retry: retryAfterMs(res)! } : {}),\n});\n\nconst refusalSyn = async (res: Response): Promise<StatewireSyn> => {\n const body = (await res.json().catch(() => null)) as {\n syn?: StatewireSyn;\n } | null;\n const syn = body?.syn;\n if (typeof syn !== \"object\" || syn === null) {\n throw new Error(`HTTP ${res.status}`);\n }\n return validateRefusalSyn(syn);\n};\n\nconst sendFrame = async (\n c: Conn,\n options: StatewireClient.HttpOptions,\n frame: StatewireFrame,\n): Promise<StatewireSubmitResult> => {\n const lease = c.lease;\n if (lease === null) return { type: \"no-lease\" };\n const timeout = AbortSignal.timeout(timing.heartbeatTimeoutMs);\n const res = await postFrame(c, options, lease, frame, timeout);\n if (res.ok) return { type: \"ok\" };\n if (res.status === 429 || res.status === 409) {\n // The syn body retry wins; Retry-After covers 429s minted below the host.\n const headerRetry = res.status === 429 ? retryAfterMs(res) : null;\n const syn: StatewireSyn = await refusalSyn(res).catch((error: unknown) => {\n if (headerRetry === null) throw error;\n return { retry: headerRetry };\n });\n if (syn.retry === undefined && headerRetry !== null)\n syn.retry = headerRetry;\n return { type: \"refusal\", syn };\n }\n if (res.status === 423) return { type: \"stale-lease\" };\n flushTapSync(() => settleFin(c, httpFin(res)));\n c.abort?.abort();\n throw new Error(`HTTP ${res.status}`);\n};\n\nconst useSseLink = (\n options: StatewireClient.HttpOptions,\n ctx: StatewireRemoteProps,\n): RemoteLink =>\n useLink({\n ...options,\n ctx,\n attemptOnce: (c, abort) => attemptStream(c, options, abort),\n send: async (c, frame) => {\n try {\n return await sendFrame(c, options, frame);\n } catch (error) {\n if (\n error instanceof SyntaxError ||\n (error instanceof Error &&\n error.message.startsWith(\"statewire: protocol error:\"))\n ) {\n flushTapSync(() =>\n settleFin(c, { reason: \"protocol-error\", message: error.message }),\n );\n c.abort?.abort();\n }\n throw error;\n }\n },\n });\n\nconst useStatewireHttp = (\n options: StatewireClient.HttpOptions,\n): Statewire<any, any> => useStatewireRemote(options, useSseLink);\n\nexport const StatewireHttp = resource(useStatewireHttp) as <\n TState = any,\n TCommands extends Statewire.Commands = Statewire.Commands,\n>(\n options: StatewireClient.HttpOptions,\n) => ResourceElement<Statewire<TState | undefined, TCommands>>;\n"],"mappings":"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"}
@@ -30,9 +30,14 @@ export declare namespace StatewireProtocol {
30
30
  }[];
31
31
  };
32
32
  }
33
- export declare const WIRE_VERSION = "2026-11-01";
33
+ export declare const WIRE_VERSION = "2026-11-02";
34
34
  /** Attach carries a results cursor and gets its verdicts gap-filled; a re-sent seq at or below the watermark is a protocol error. */
35
35
  export declare const GAP_FILL_VERSION = "2026-11-01";
36
+ /** Every attach of a connection names its attacher; a host retires the attacher's earlier attaches before the hello. */
37
+ export declare const FENCE_VERSION = "2026-11-02";
38
+ /** The wire a client offers by default: the gap-fill contract and newer. */
39
+ export declare const CLIENT_WIRE: StatewireProtocol.Range;
40
+ export declare const ATTACHER_HEADER = "Statewire-Attacher";
36
41
  /** The oldest wire contract a host serves by default (re-sent seqs re-emit their verdicts). */
37
42
  export declare const MIN_SERVED_WIRE_VERSION = "2026-09-30";
38
43
  export declare const DEFAULT_PROTOCOL_VERSION = "2026-09-30";
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/wire/protocol.ts"],"names":[],"mappings":"AAAA,yBAAiB,iBAAiB,CAAC;IACjC,KAAY,KAAK,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,KAAY,KAAK,GAAG,KAAK,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACjE,KAAY,SAAS,GAAG;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,WAAW,CAAA;SAAE,EAAE,CAAC;KACtE,CAAC;IACF,KAAY,OAAO,GAAG;QACpB,WAAW,CAAC,EAAE,KAAK,CAAC;QACpB,oBAAoB,CAAC,EAAE,SAAS,KAAK,EAAE,GAAG,GAAG,CAAC;QAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;KAC3D,CAAC;IACF,KAAY,UAAU,GAAG,KAAK,GAAG;QAC/B,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QAC3C,YAAY,CAAC,EAAE,SAAS;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,WAAW,CAAA;SAAE,EAAE,CAAC;KAClE,CAAC;CACH;AAED,eAAO,MAAM,YAAY,eAAe,CAAC;AACzC,qIAAqI;AACrI,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAC7C,+FAA+F;AAC/F,eAAO,MAAM,uBAAuB,eAAe,CAAC;AACpD,eAAO,MAAM,wBAAwB,eAAe,CAAC;AACrD,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAC1C,eAAO,MAAM,eAAe,uBAAuB,CAAC;AACpD,eAAO,MAAM,cAAc,sBAAsB,CAAC;AAClD,eAAO,MAAM,aAAa,QAA6C,CAAC;AAMxE,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,MAWhD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,iBAAiB,CAAC,KAAK;;;CAQ3D,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,EAAE,OAAO,iBAAiB,CAAC,KAAK,YAGpE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS,iBAAiB,CAAC,OAAO,6CAM9D,CAAC;AAEJ,eAAO,MAAM,kBAAkB,GAC7B,SAAS,iBAAiB,CAAC,OAAO,KACjC,MAAM,CAAC,MAAM,EAAE,MAAM,CAgCvB,CAAC;AA6BF,eAAO,MAAM,gBAAgB,GAC3B,SAAS,OAAO,KACf,QAAQ,CACT,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,sBAAsB,CAAC,CAwDxE,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,OAAO,EACd,SAAS,iBAAiB,CAAC,OAAO,KACjC,iBAAiB,CAAC,SA2CpB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,OAAO,EAChB,MAAM,iBAAiB,CAAC,KAAK,EAC7B,aAAa,SAAS,iBAAiB,CAAC,UAAU,EAAE,KAElD,iBAAiB,CAAC,SAAS,GAC3B;IACE,GAAG,EAAE;QACH,MAAM,EAAE,gBAAgB,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CA2GP,CAAC"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/wire/protocol.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,15 @@
1
1
  // src/wire/protocol.ts
2
- const WIRE_VERSION = "2026-11-01";
2
+ const WIRE_VERSION = "2026-11-02";
3
3
  /** Attach carries a results cursor and gets its verdicts gap-filled; a re-sent seq at or below the watermark is a protocol error. */
4
4
  const GAP_FILL_VERSION = "2026-11-01";
5
+ /** Every attach of a connection names its attacher; a host retires the attacher's earlier attaches before the hello. */
6
+ const FENCE_VERSION = "2026-11-02";
7
+ /** The wire a client offers by default: the gap-fill contract and newer. */
8
+ const CLIENT_WIRE = {
9
+ version: WIRE_VERSION,
10
+ minVersion: GAP_FILL_VERSION
11
+ };
12
+ const ATTACHER_HEADER = "Statewire-Attacher";
5
13
  /** The oldest wire contract a host serves by default (re-sent seqs re-emit their verdicts). */
6
14
  const MIN_SERVED_WIRE_VERSION = "2026-09-30";
7
15
  const DEFAULT_PROTOCOL_VERSION = "2026-09-30";
@@ -44,7 +52,7 @@ const negotiationHeaders = (options) => {
44
52
  const seen = /* @__PURE__ */ new Set();
45
53
  if (offers !== "*" && !offers.length) invalid("protocol list must not be empty");
46
54
  return {
47
- [VERSION_HEADER]: suffix(options.wireVersion ?? { version: "2026-11-01" }),
55
+ [VERSION_HEADER]: suffix(options.wireVersion ?? CLIENT_WIRE),
48
56
  [PROTOCOL_HEADER]: offers === "*" ? "*" : offers.map((offer) => {
49
57
  if (!protocolToken.test(offer.name) || offer.name === "*" || seen.has(offer.name)) invalid("invalid or duplicate protocol name");
50
58
  if (offer.optional !== void 0 && typeof offer.optional !== "boolean") invalid("optional must be boolean");
@@ -128,7 +136,7 @@ const validateSelection = (value, options) => {
128
136
  if (typeof value !== "object" || value === null) return invalid("missing negotiation selection");
129
137
  const syn = value;
130
138
  const version = validateVersion(syn.version);
131
- if (!inRange(version, options.wireVersion ?? { version: "2026-11-01" })) invalid("selected wire version is outside offer");
139
+ if (!inRange(version, options.wireVersion ?? CLIENT_WIRE)) invalid("selected wire version is outside offer");
132
140
  if (!Array.isArray(syn.protocols)) return invalid("syn.protocols must be an array");
133
141
  const offers = protocolOffers(options);
134
142
  const seen = /* @__PURE__ */ new Map();
@@ -241,6 +249,6 @@ const negotiateProtocols = (headers, wire, definitions) => {
241
249
  })
242
250
  };
243
251
  };
244
- export { DEFAULT_PROTOCOL, DEFAULT_PROTOCOL_VERSION, GAP_FILL_VERSION, MIN_SERVED_WIRE_VERSION, PROTOCOL_HEADER, VERSION_HEADER, WIRE_VERSION, inRange, negotiateProtocols, negotiationHeaders, parseNegotiation, protocolOffers, protocolToken, validateRange, validateSelection, validateVersion };
252
+ export { ATTACHER_HEADER, CLIENT_WIRE, DEFAULT_PROTOCOL, DEFAULT_PROTOCOL_VERSION, FENCE_VERSION, GAP_FILL_VERSION, MIN_SERVED_WIRE_VERSION, PROTOCOL_HEADER, VERSION_HEADER, WIRE_VERSION, inRange, negotiateProtocols, negotiationHeaders, parseNegotiation, protocolOffers, protocolToken, validateRange, validateSelection, validateVersion };
245
253
 
246
254
  //# sourceMappingURL=protocol.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","names":["StatewireProtocol","Range","version","minVersion","Offer","name","optional","Selection","protocols","record","Options","wireVersion","applicationProtocols","protocol","keyPrefixes","Readonly","Record","Definition","requires","subprotocols","WIRE_VERSION","GAP_FILL_VERSION","MIN_SERVED_WIRE_VERSION","DEFAULT_PROTOCOL_VERSION","DEFAULT_PROTOCOL","PROTOCOL_HEADER","VERSION_HEADER","protocolToken","invalid","message","Error","validateVersion","value","test","parsed","Date","Number","isFinite","getTime","toISOString","slice","startsWith","validateRange","range","undefined","inRange","checked","protocolOffers","options","negotiationHeaders","suffix","offers","seen","Set","length","map","offer","has","add","join","parseItem","input","atom","String","raw","text","trim","match","RegExp","exec","quoted","decode","replace","params","Map","rest","parameter","key","set","parseNegotiation","headers","Headers","Required","Pick","wire","get","application","item","keys","some","k","names","split","includes","validateSelection","syn","Array","isArray","entry","parent","lastIndexOf","child","find","o","negotiateProtocols","definitions","fin","reason","code","status","payload","supported","d","failure","const","request","ReturnType","error","sort","registry","size","definition","children","offered","solve","active","dependency","Object","result","ranges","flatMap","lower","r","at","upper","selected","filter"],"sources":["../../src/wire/protocol.ts"],"sourcesContent":["export namespace StatewireProtocol {\n export type Range = { version: string; minVersion?: string };\n export type Offer = Range & { name: string; optional?: boolean };\n export type Selection = {\n version: string;\n protocols: { name: string; version: string; record?: \"ephemeral\" }[];\n };\n export type Options = {\n wireVersion?: Range;\n applicationProtocols?: readonly Offer[] | \"*\";\n protocol?: string;\n keyPrefixes?: Readonly<Record<string, readonly string[]>>;\n };\n export type Definition = Range & {\n name: string;\n requires?: Readonly<Record<string, Range>>;\n subprotocols?: readonly { name: string; record?: \"ephemeral\" }[];\n };\n}\n\nexport const WIRE_VERSION = \"2026-11-01\";\n/** Attach carries a results cursor and gets its verdicts gap-filled; a re-sent seq at or below the watermark is a protocol error. */\nexport const GAP_FILL_VERSION = \"2026-11-01\";\n/** The oldest wire contract a host serves by default (re-sent seqs re-emit their verdicts). */\nexport const MIN_SERVED_WIRE_VERSION = \"2026-09-30\";\nexport const DEFAULT_PROTOCOL_VERSION = \"2026-09-30\";\nexport const DEFAULT_PROTOCOL = \"default\";\nexport const PROTOCOL_HEADER = \"Statewire-Protocol\";\nexport const VERSION_HEADER = \"Statewire-Version\";\nexport const protocolToken = /^[A-Za-z*][A-Za-z0-9!#$%&'*+.^_`|~:/-]*$/;\n\nconst invalid = (message: string): never => {\n throw new Error(`statewire: protocol error: ${message}`);\n};\n\nexport const validateVersion = (value: unknown): string => {\n if (typeof value !== \"string\" || !/^\\d{4}-\\d{2}-\\d{2}$/.test(value))\n return invalid(\"version must be a YYYY-MM-DD date\");\n const parsed = new Date(`${value}T00:00:00.000Z`);\n if (\n !Number.isFinite(parsed.getTime()) ||\n parsed.toISOString().slice(0, 10) !== value ||\n value.startsWith(\"0000\")\n )\n return invalid(\"invalid version date\");\n return value;\n};\n\nexport const validateRange = (range: StatewireProtocol.Range) => {\n const version = validateVersion(range.version);\n const minVersion =\n range.minVersion === undefined\n ? version\n : validateVersion(range.minVersion);\n if (minVersion > version) invalid(\"min-version exceeds version\");\n return { version, minVersion };\n};\n\nexport const inRange = (value: string, range: StatewireProtocol.Range) => {\n const checked = validateRange(range);\n return value >= checked.minVersion && value <= checked.version;\n};\n\nexport const protocolOffers = (options: StatewireProtocol.Options) =>\n options.applicationProtocols ?? [\n {\n name: options.protocol ?? DEFAULT_PROTOCOL,\n version: DEFAULT_PROTOCOL_VERSION,\n },\n ];\n\nexport const negotiationHeaders = (\n options: StatewireProtocol.Options,\n): Record<string, string> => {\n const suffix = (range: StatewireProtocol.Range) => {\n const { version, minVersion } = validateRange(range);\n return `\"${version}\"${minVersion === version ? \"\" : `; min-version=\"${minVersion}\"`}`;\n };\n const offers = protocolOffers(options);\n const seen = new Set<string>();\n if (offers !== \"*\" && !offers.length)\n invalid(\"protocol list must not be empty\");\n return {\n [VERSION_HEADER]: suffix(options.wireVersion ?? { version: WIRE_VERSION }),\n [PROTOCOL_HEADER]:\n offers === \"*\"\n ? \"*\"\n : offers\n .map((offer) => {\n if (\n !protocolToken.test(offer.name) ||\n offer.name === \"*\" ||\n seen.has(offer.name)\n )\n invalid(\"invalid or duplicate protocol name\");\n if (\n offer.optional !== undefined &&\n typeof offer.optional !== \"boolean\"\n )\n invalid(\"optional must be boolean\");\n seen.add(offer.name);\n return `${offer.name}; version=${suffix(offer)}${offer.optional ? \"; optional\" : \"\"}`;\n })\n .join(\", \"),\n };\n};\n\nconst parseItem = (input: string) => {\n const atom = String.raw`\"(?:[\\x20-\\x21\\x23-\\x5b\\x5d-\\x7e]|\\\\[\"\\\\])*\"|[A-Za-z*][A-Za-z0-9!#$%&'*+.^_\\x60|~:/-]*|\\?[01]`;\n const text = input.trim();\n const match = new RegExp(`^(?:${atom})`).exec(text);\n if (!match) return invalid(\"invalid structured item\");\n const quoted = match[0].startsWith('\"');\n const decode = (raw: string) => raw.slice(1, -1).replace(/\\\\([\"\\\\])/g, \"$1\");\n const value = quoted ? decode(match[0]) : match[0];\n const params = new Map<string, string | boolean>();\n let rest = text.slice(match[0].length);\n while (rest) {\n const parameter = new RegExp(\n `^; *([a-z*][a-z0-9_.*-]*)(?:=(${atom}))?`,\n ).exec(rest);\n if (!parameter) return invalid(\"invalid structured parameters\");\n const key = parameter[1]!;\n const raw = parameter[2];\n if (params.has(key)) invalid(\"duplicate parameter\");\n if (raw === undefined || raw === \"?1\") params.set(key, true);\n else if (raw === \"?0\") params.set(key, false);\n else if (raw.startsWith('\"')) params.set(key, decode(raw));\n else invalid(\"parameter must be string or boolean\");\n rest = rest.slice(parameter[0].length);\n }\n return { value, quoted, params };\n};\n\nexport const parseNegotiation = (\n headers: Headers,\n): Required<\n Pick<StatewireProtocol.Options, \"wireVersion\" | \"applicationProtocols\">\n> => {\n const wire = headers.get(VERSION_HEADER);\n const application = headers.get(PROTOCOL_HEADER);\n if (wire === null || application === null)\n return invalid(\"negotiation fields are required\");\n const item = parseItem(wire);\n if (!item.quoted || [...item.params.keys()].some((k) => k !== \"min-version\"))\n invalid(\"invalid Statewire-Version\");\n const minVersion = item.params.get(\"min-version\");\n if (minVersion !== undefined && typeof minVersion !== \"string\")\n return invalid(\"min-version must be a string\");\n const wireVersion = validateRange({\n version: item.value,\n ...(minVersion === undefined ? {} : { minVersion }),\n });\n if (application.trim() === \"*\")\n return { wireVersion, applicationProtocols: \"*\" };\n const names = new Set<string>();\n const applicationProtocols = application\n .split(\",\")\n .map((text): StatewireProtocol.Offer => {\n const { value: name, quoted, params } = parseItem(text);\n if (\n quoted ||\n !protocolToken.test(name) ||\n name === \"*\" ||\n names.has(name)\n )\n invalid(\"invalid or duplicate protocol name\");\n names.add(name);\n if (\n [...params.keys()].some(\n (k) => ![\"version\", \"min-version\", \"optional\"].includes(k),\n )\n )\n invalid(\"unsupported parameter\");\n const version = params.get(\"version\");\n const minVersion = params.get(\"min-version\");\n const optional = params.get(\"optional\") ?? false;\n if (\n typeof version !== \"string\" ||\n (minVersion !== undefined && typeof minVersion !== \"string\") ||\n typeof optional !== \"boolean\"\n )\n return invalid(\"invalid protocol parameters\");\n return {\n name,\n ...validateRange({\n version,\n ...(minVersion === undefined ? {} : { minVersion }),\n }),\n optional,\n };\n });\n return { wireVersion, applicationProtocols };\n};\n\nexport const validateSelection = (\n value: unknown,\n options: StatewireProtocol.Options,\n): StatewireProtocol.Selection => {\n if (typeof value !== \"object\" || value === null)\n return invalid(\"missing negotiation selection\");\n const syn = value as Record<string, unknown>;\n const version = validateVersion(syn.version);\n if (!inRange(version, options.wireVersion ?? { version: WIRE_VERSION }))\n invalid(\"selected wire version is outside offer\");\n if (!Array.isArray(syn.protocols))\n return invalid(\"syn.protocols must be an array\");\n const offers = protocolOffers(options);\n const seen = new Map<string, string>();\n const protocols = syn.protocols.map((entry: unknown) => {\n if (typeof entry !== \"object\" || entry === null)\n return invalid(\"invalid selected protocol\");\n const item = entry as Record<string, unknown>;\n const name = item.name;\n if (\n typeof name !== \"string\" ||\n !protocolToken.test(name) ||\n name === \"*\" ||\n seen.has(name)\n )\n return invalid(\"invalid selected protocol name\");\n const version = validateVersion(item.version);\n if (item.record !== undefined && item.record !== \"ephemeral\")\n invalid(\"invalid selected protocol record\");\n const record = item.record as \"ephemeral\" | undefined;\n const parent = name.slice(0, name.lastIndexOf(\"/\"));\n const child = parent !== \"\" && seen.has(parent);\n if (child) {\n if (seen.get(parent) !== version)\n invalid(\"subprotocol version differs from its parent\");\n } else if (offers !== \"*\") {\n const offer = offers.find((o) => o.name === name);\n if (!offer || !inRange(version, offer))\n invalid(\"selected protocol is outside offer\");\n }\n seen.set(name, version);\n return { name, version, ...(record !== undefined && { record }) };\n });\n if (offers !== \"*\" && offers.some((o) => !o.optional && !seen.has(o.name)))\n invalid(\"required protocol missing from selection\");\n return { version, protocols };\n};\n\nexport const negotiateProtocols = (\n headers: Headers,\n wire: StatewireProtocol.Range,\n definitions: readonly StatewireProtocol.Definition[],\n):\n | StatewireProtocol.Selection\n | {\n fin: {\n reason: \"protocol-error\";\n code: string;\n status: number;\n message: string;\n payload?: unknown;\n };\n } => {\n const supported = {\n ...validateRange(wire),\n protocols: definitions.map((d) => ({ name: d.name, ...validateRange(d) })),\n };\n const failure = (code: string, message: string) => ({\n fin: {\n reason: \"protocol-error\" as const,\n code,\n message,\n status: code === \"invalid-negotiation\" ? 400 : 406,\n ...(code === \"invalid-negotiation\" ? {} : { payload: supported }),\n },\n });\n let request: ReturnType<typeof parseNegotiation>;\n try {\n request = parseNegotiation(headers);\n } catch (error) {\n return failure(\n \"invalid-negotiation\",\n error instanceof Error ? error.message : \"invalid negotiation\",\n );\n }\n const version = [wire.version, request.wireVersion.version].sort()[0]!;\n if (!inRange(version, wire) || !inRange(version, request.wireVersion))\n return failure(\"unsupported-version\", \"Statewire versions do not overlap\");\n const offers =\n request.applicationProtocols === \"*\"\n ? definitions.map((d) => ({\n name: d.name,\n version: d.version,\n optional: false,\n }))\n : request.applicationProtocols;\n const registry = new Map(definitions.map((d) => [d.name, d]));\n if (registry.size !== definitions.length)\n throw new Error(\"statewire: duplicate registered protocol\");\n for (const definition of definitions) {\n const children = new Set<string>();\n for (const child of definition.subprotocols ?? []) {\n if (\n !protocolToken.test(child.name) ||\n child.name.includes(\"/\") ||\n children.has(child.name) ||\n (child.record !== undefined && child.record !== \"ephemeral\")\n )\n throw new Error(\"statewire: invalid subprotocol registration\");\n children.add(child.name);\n }\n }\n const offered = new Map(offers.map((o) => [o.name, o]));\n const solve = (names: Set<string>) => {\n const active = new Set(names);\n for (const name of active) {\n const definition = registry.get(name);\n if (!definition || !offered.has(name)) return undefined;\n for (const dependency of Object.keys(definition.requires ?? {}))\n active.add(dependency);\n }\n const result = new Map<string, string>();\n for (const name of active) {\n const ranges = [\n registry.get(name)!,\n offered.get(name)!,\n ...[...active].flatMap((parent) => {\n const dependency = registry.get(parent)!.requires?.[name];\n return dependency ? [dependency] : [];\n }),\n ].map(validateRange);\n const lower = ranges\n .map((r) => r.minVersion)\n .sort()\n .at(-1)!;\n const upper = ranges.map((r) => r.version).sort()[0]!;\n if (lower > upper) return undefined;\n result.set(name, upper);\n }\n return result;\n };\n let selected = solve(\n new Set(offers.filter((o) => !o.optional).map((o) => o.name)),\n );\n if (!selected)\n return failure(\n \"unsupported-protocol\",\n \"required protocol combination is unsupported\",\n );\n for (const offer of offers) {\n if (offer.optional)\n selected = solve(new Set([...selected.keys(), offer.name])) ?? selected;\n }\n return {\n version,\n protocols: offers.flatMap((o) => {\n const version = selected!.get(o.name);\n if (version === undefined) return [];\n return [\n { name: o.name, version },\n ...(registry.get(o.name)!.subprotocols ?? []).map((child) => ({\n name: `${o.name}/${child.name}`,\n version,\n ...(child.record !== undefined && { record: child.record }),\n })),\n ];\n }),\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"protocol.js","names":["StatewireProtocol","Range","version","minVersion","Offer","name","optional","Selection","protocols","record","Options","wireVersion","applicationProtocols","protocol","keyPrefixes","Readonly","Record","Definition","requires","subprotocols","WIRE_VERSION","GAP_FILL_VERSION","FENCE_VERSION","CLIENT_WIRE","ATTACHER_HEADER","MIN_SERVED_WIRE_VERSION","DEFAULT_PROTOCOL_VERSION","DEFAULT_PROTOCOL","PROTOCOL_HEADER","VERSION_HEADER","protocolToken","invalid","message","Error","validateVersion","value","test","parsed","Date","Number","isFinite","getTime","toISOString","slice","startsWith","validateRange","range","undefined","inRange","checked","protocolOffers","options","negotiationHeaders","suffix","offers","seen","Set","length","map","offer","has","add","join","parseItem","input","atom","String","raw","text","trim","match","RegExp","exec","quoted","decode","replace","params","Map","rest","parameter","key","set","parseNegotiation","headers","Headers","Required","Pick","wire","get","application","item","keys","some","k","names","split","includes","validateSelection","syn","Array","isArray","entry","parent","lastIndexOf","child","find","o","negotiateProtocols","definitions","fin","reason","code","status","payload","supported","d","failure","const","request","ReturnType","error","sort","registry","size","definition","children","offered","solve","active","dependency","Object","result","ranges","flatMap","lower","r","at","upper","selected","filter"],"sources":["../../src/wire/protocol.ts"],"sourcesContent":["export namespace StatewireProtocol {\n export type Range = { version: string; minVersion?: string };\n export type Offer = Range & { name: string; optional?: boolean };\n export type Selection = {\n version: string;\n protocols: { name: string; version: string; record?: \"ephemeral\" }[];\n };\n export type Options = {\n wireVersion?: Range;\n applicationProtocols?: readonly Offer[] | \"*\";\n protocol?: string;\n keyPrefixes?: Readonly<Record<string, readonly string[]>>;\n };\n export type Definition = Range & {\n name: string;\n requires?: Readonly<Record<string, Range>>;\n subprotocols?: readonly { name: string; record?: \"ephemeral\" }[];\n };\n}\n\nexport const WIRE_VERSION = \"2026-11-02\";\n/** Attach carries a results cursor and gets its verdicts gap-filled; a re-sent seq at or below the watermark is a protocol error. */\nexport const GAP_FILL_VERSION = \"2026-11-01\";\n/** Every attach of a connection names its attacher; a host retires the attacher's earlier attaches before the hello. */\nexport const FENCE_VERSION = \"2026-11-02\";\n/** The wire a client offers by default: the gap-fill contract and newer. */\nexport const CLIENT_WIRE: StatewireProtocol.Range = {\n version: WIRE_VERSION,\n minVersion: GAP_FILL_VERSION,\n};\nexport const ATTACHER_HEADER = \"Statewire-Attacher\";\n/** The oldest wire contract a host serves by default (re-sent seqs re-emit their verdicts). */\nexport const MIN_SERVED_WIRE_VERSION = \"2026-09-30\";\nexport const DEFAULT_PROTOCOL_VERSION = \"2026-09-30\";\nexport const DEFAULT_PROTOCOL = \"default\";\nexport const PROTOCOL_HEADER = \"Statewire-Protocol\";\nexport const VERSION_HEADER = \"Statewire-Version\";\nexport const protocolToken = /^[A-Za-z*][A-Za-z0-9!#$%&'*+.^_`|~:/-]*$/;\n\nconst invalid = (message: string): never => {\n throw new Error(`statewire: protocol error: ${message}`);\n};\n\nexport const validateVersion = (value: unknown): string => {\n if (typeof value !== \"string\" || !/^\\d{4}-\\d{2}-\\d{2}$/.test(value))\n return invalid(\"version must be a YYYY-MM-DD date\");\n const parsed = new Date(`${value}T00:00:00.000Z`);\n if (\n !Number.isFinite(parsed.getTime()) ||\n parsed.toISOString().slice(0, 10) !== value ||\n value.startsWith(\"0000\")\n )\n return invalid(\"invalid version date\");\n return value;\n};\n\nexport const validateRange = (range: StatewireProtocol.Range) => {\n const version = validateVersion(range.version);\n const minVersion =\n range.minVersion === undefined\n ? version\n : validateVersion(range.minVersion);\n if (minVersion > version) invalid(\"min-version exceeds version\");\n return { version, minVersion };\n};\n\nexport const inRange = (value: string, range: StatewireProtocol.Range) => {\n const checked = validateRange(range);\n return value >= checked.minVersion && value <= checked.version;\n};\n\nexport const protocolOffers = (options: StatewireProtocol.Options) =>\n options.applicationProtocols ?? [\n {\n name: options.protocol ?? DEFAULT_PROTOCOL,\n version: DEFAULT_PROTOCOL_VERSION,\n },\n ];\n\nexport const negotiationHeaders = (\n options: StatewireProtocol.Options,\n): Record<string, string> => {\n const suffix = (range: StatewireProtocol.Range) => {\n const { version, minVersion } = validateRange(range);\n return `\"${version}\"${minVersion === version ? \"\" : `; min-version=\"${minVersion}\"`}`;\n };\n const offers = protocolOffers(options);\n const seen = new Set<string>();\n if (offers !== \"*\" && !offers.length)\n invalid(\"protocol list must not be empty\");\n return {\n [VERSION_HEADER]: suffix(options.wireVersion ?? CLIENT_WIRE),\n [PROTOCOL_HEADER]:\n offers === \"*\"\n ? \"*\"\n : offers\n .map((offer) => {\n if (\n !protocolToken.test(offer.name) ||\n offer.name === \"*\" ||\n seen.has(offer.name)\n )\n invalid(\"invalid or duplicate protocol name\");\n if (\n offer.optional !== undefined &&\n typeof offer.optional !== \"boolean\"\n )\n invalid(\"optional must be boolean\");\n seen.add(offer.name);\n return `${offer.name}; version=${suffix(offer)}${offer.optional ? \"; optional\" : \"\"}`;\n })\n .join(\", \"),\n };\n};\n\nconst parseItem = (input: string) => {\n const atom = String.raw`\"(?:[\\x20-\\x21\\x23-\\x5b\\x5d-\\x7e]|\\\\[\"\\\\])*\"|[A-Za-z*][A-Za-z0-9!#$%&'*+.^_\\x60|~:/-]*|\\?[01]`;\n const text = input.trim();\n const match = new RegExp(`^(?:${atom})`).exec(text);\n if (!match) return invalid(\"invalid structured item\");\n const quoted = match[0].startsWith('\"');\n const decode = (raw: string) => raw.slice(1, -1).replace(/\\\\([\"\\\\])/g, \"$1\");\n const value = quoted ? decode(match[0]) : match[0];\n const params = new Map<string, string | boolean>();\n let rest = text.slice(match[0].length);\n while (rest) {\n const parameter = new RegExp(\n `^; *([a-z*][a-z0-9_.*-]*)(?:=(${atom}))?`,\n ).exec(rest);\n if (!parameter) return invalid(\"invalid structured parameters\");\n const key = parameter[1]!;\n const raw = parameter[2];\n if (params.has(key)) invalid(\"duplicate parameter\");\n if (raw === undefined || raw === \"?1\") params.set(key, true);\n else if (raw === \"?0\") params.set(key, false);\n else if (raw.startsWith('\"')) params.set(key, decode(raw));\n else invalid(\"parameter must be string or boolean\");\n rest = rest.slice(parameter[0].length);\n }\n return { value, quoted, params };\n};\n\nexport const parseNegotiation = (\n headers: Headers,\n): Required<\n Pick<StatewireProtocol.Options, \"wireVersion\" | \"applicationProtocols\">\n> => {\n const wire = headers.get(VERSION_HEADER);\n const application = headers.get(PROTOCOL_HEADER);\n if (wire === null || application === null)\n return invalid(\"negotiation fields are required\");\n const item = parseItem(wire);\n if (!item.quoted || [...item.params.keys()].some((k) => k !== \"min-version\"))\n invalid(\"invalid Statewire-Version\");\n const minVersion = item.params.get(\"min-version\");\n if (minVersion !== undefined && typeof minVersion !== \"string\")\n return invalid(\"min-version must be a string\");\n const wireVersion = validateRange({\n version: item.value,\n ...(minVersion === undefined ? {} : { minVersion }),\n });\n if (application.trim() === \"*\")\n return { wireVersion, applicationProtocols: \"*\" };\n const names = new Set<string>();\n const applicationProtocols = application\n .split(\",\")\n .map((text): StatewireProtocol.Offer => {\n const { value: name, quoted, params } = parseItem(text);\n if (\n quoted ||\n !protocolToken.test(name) ||\n name === \"*\" ||\n names.has(name)\n )\n invalid(\"invalid or duplicate protocol name\");\n names.add(name);\n if (\n [...params.keys()].some(\n (k) => ![\"version\", \"min-version\", \"optional\"].includes(k),\n )\n )\n invalid(\"unsupported parameter\");\n const version = params.get(\"version\");\n const minVersion = params.get(\"min-version\");\n const optional = params.get(\"optional\") ?? false;\n if (\n typeof version !== \"string\" ||\n (minVersion !== undefined && typeof minVersion !== \"string\") ||\n typeof optional !== \"boolean\"\n )\n return invalid(\"invalid protocol parameters\");\n return {\n name,\n ...validateRange({\n version,\n ...(minVersion === undefined ? {} : { minVersion }),\n }),\n optional,\n };\n });\n return { wireVersion, applicationProtocols };\n};\n\nexport const validateSelection = (\n value: unknown,\n options: StatewireProtocol.Options,\n): StatewireProtocol.Selection => {\n if (typeof value !== \"object\" || value === null)\n return invalid(\"missing negotiation selection\");\n const syn = value as Record<string, unknown>;\n const version = validateVersion(syn.version);\n if (!inRange(version, options.wireVersion ?? CLIENT_WIRE))\n invalid(\"selected wire version is outside offer\");\n if (!Array.isArray(syn.protocols))\n return invalid(\"syn.protocols must be an array\");\n const offers = protocolOffers(options);\n const seen = new Map<string, string>();\n const protocols = syn.protocols.map((entry: unknown) => {\n if (typeof entry !== \"object\" || entry === null)\n return invalid(\"invalid selected protocol\");\n const item = entry as Record<string, unknown>;\n const name = item.name;\n if (\n typeof name !== \"string\" ||\n !protocolToken.test(name) ||\n name === \"*\" ||\n seen.has(name)\n )\n return invalid(\"invalid selected protocol name\");\n const version = validateVersion(item.version);\n if (item.record !== undefined && item.record !== \"ephemeral\")\n invalid(\"invalid selected protocol record\");\n const record = item.record as \"ephemeral\" | undefined;\n const parent = name.slice(0, name.lastIndexOf(\"/\"));\n const child = parent !== \"\" && seen.has(parent);\n if (child) {\n if (seen.get(parent) !== version)\n invalid(\"subprotocol version differs from its parent\");\n } else if (offers !== \"*\") {\n const offer = offers.find((o) => o.name === name);\n if (!offer || !inRange(version, offer))\n invalid(\"selected protocol is outside offer\");\n }\n seen.set(name, version);\n return { name, version, ...(record !== undefined && { record }) };\n });\n if (offers !== \"*\" && offers.some((o) => !o.optional && !seen.has(o.name)))\n invalid(\"required protocol missing from selection\");\n return { version, protocols };\n};\n\nexport const negotiateProtocols = (\n headers: Headers,\n wire: StatewireProtocol.Range,\n definitions: readonly StatewireProtocol.Definition[],\n):\n | StatewireProtocol.Selection\n | {\n fin: {\n reason: \"protocol-error\";\n code: string;\n status: number;\n message: string;\n payload?: unknown;\n };\n } => {\n const supported = {\n ...validateRange(wire),\n protocols: definitions.map((d) => ({ name: d.name, ...validateRange(d) })),\n };\n const failure = (code: string, message: string) => ({\n fin: {\n reason: \"protocol-error\" as const,\n code,\n message,\n status: code === \"invalid-negotiation\" ? 400 : 406,\n ...(code === \"invalid-negotiation\" ? {} : { payload: supported }),\n },\n });\n let request: ReturnType<typeof parseNegotiation>;\n try {\n request = parseNegotiation(headers);\n } catch (error) {\n return failure(\n \"invalid-negotiation\",\n error instanceof Error ? error.message : \"invalid negotiation\",\n );\n }\n const version = [wire.version, request.wireVersion.version].sort()[0]!;\n if (!inRange(version, wire) || !inRange(version, request.wireVersion))\n return failure(\"unsupported-version\", \"Statewire versions do not overlap\");\n const offers =\n request.applicationProtocols === \"*\"\n ? definitions.map((d) => ({\n name: d.name,\n version: d.version,\n optional: false,\n }))\n : request.applicationProtocols;\n const registry = new Map(definitions.map((d) => [d.name, d]));\n if (registry.size !== definitions.length)\n throw new Error(\"statewire: duplicate registered protocol\");\n for (const definition of definitions) {\n const children = new Set<string>();\n for (const child of definition.subprotocols ?? []) {\n if (\n !protocolToken.test(child.name) ||\n child.name.includes(\"/\") ||\n children.has(child.name) ||\n (child.record !== undefined && child.record !== \"ephemeral\")\n )\n throw new Error(\"statewire: invalid subprotocol registration\");\n children.add(child.name);\n }\n }\n const offered = new Map(offers.map((o) => [o.name, o]));\n const solve = (names: Set<string>) => {\n const active = new Set(names);\n for (const name of active) {\n const definition = registry.get(name);\n if (!definition || !offered.has(name)) return undefined;\n for (const dependency of Object.keys(definition.requires ?? {}))\n active.add(dependency);\n }\n const result = new Map<string, string>();\n for (const name of active) {\n const ranges = [\n registry.get(name)!,\n offered.get(name)!,\n ...[...active].flatMap((parent) => {\n const dependency = registry.get(parent)!.requires?.[name];\n return dependency ? [dependency] : [];\n }),\n ].map(validateRange);\n const lower = ranges\n .map((r) => r.minVersion)\n .sort()\n .at(-1)!;\n const upper = ranges.map((r) => r.version).sort()[0]!;\n if (lower > upper) return undefined;\n result.set(name, upper);\n }\n return result;\n };\n let selected = solve(\n new Set(offers.filter((o) => !o.optional).map((o) => o.name)),\n );\n if (!selected)\n return failure(\n \"unsupported-protocol\",\n \"required protocol combination is unsupported\",\n );\n for (const offer of offers) {\n if (offer.optional)\n selected = solve(new Set([...selected.keys(), offer.name])) ?? selected;\n }\n return {\n version,\n protocols: offers.flatMap((o) => {\n const version = selected!.get(o.name);\n if (version === undefined) return [];\n return [\n { name: o.name, version },\n ...(registry.get(o.name)!.subprotocols ?? []).map((child) => ({\n name: `${o.name}/${child.name}`,\n version,\n ...(child.record !== undefined && { record: child.record }),\n })),\n ];\n }),\n };\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "statewire",
3
- "version": "0.24.1",
3
+ "version": "0.24.2",
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": {
@@ -1,4 +1,5 @@
1
1
  import {
2
+ ATTACHER_HEADER,
2
3
  negotiationHeaders,
3
4
  validateSelection,
4
5
  parseNegotiation,
@@ -9,6 +10,7 @@ import { flushTapSync } from "@assistant-ui/tap";
9
10
  import { reviveOps, reviveValue } from "../wire/meta";
10
11
  import { backoff, retryHint, timing } from "./timing";
11
12
  import { isStorageError } from "./storageError";
13
+ import { randomId } from "../util/randomId";
12
14
  import type {
13
15
  ConnectionState,
14
16
  RemoteLink,
@@ -111,6 +113,8 @@ export type Conn = {
111
113
  connection: StatewireClient.Connection;
112
114
  parked: boolean;
113
115
  lease: string | null;
116
+ /** Names every attach of this connection, so a host retires the earlier ones (2026-11-02). */
117
+ attacher: string;
114
118
  attempt: number;
115
119
  authDenials: number;
116
120
  authStale: boolean;
@@ -642,6 +646,11 @@ export const resolveHeaders = async (
642
646
  );
643
647
 
644
648
  // The stale flag clears only once the resolver returns: a throwing refresh keeps it for the next attempt.
649
+ /** Names this connection, so a host retires its earlier attaches before the hello. */
650
+ export const replacing = (c: Conn, headers: Headers) => {
651
+ headers.set(ATTACHER_HEADER, c.attacher);
652
+ };
653
+
645
654
  export const attachFrame = async (
646
655
  c: Conn,
647
656
  headers: StatewireClient.HeadersOption | undefined,
@@ -654,6 +663,7 @@ export const attachFrame = async (
654
663
  )) {
655
664
  if (!resolved.has(name)) resolved.set(name, value);
656
665
  }
666
+ replacing(c, resolved);
657
667
  c.negotiation = parseNegotiation(resolved);
658
668
  c.authStale = false;
659
669
  const persistence = c.ctx.beforeAttach?.();
@@ -686,6 +696,7 @@ export const useLink = (
686
696
  const conn: Conn = {
687
697
  parked: props.isNew ?? false,
688
698
  lease: null,
699
+ attacher: randomId(),
689
700
  attempt: 0,
690
701
  authDenials: 0,
691
702
  authStale: false,
@@ -2,8 +2,8 @@ import { encodeContext } from "../wire/context";
2
2
  import { wrapStorageError } from "./storageError";
3
3
  import {
4
4
  DEFAULT_PROTOCOL,
5
+ CLIENT_WIRE,
5
6
  GAP_FILL_VERSION,
6
- WIRE_VERSION,
7
7
  protocolOffers,
8
8
  inRange,
9
9
  } from "../wire/protocol";
@@ -163,6 +163,8 @@ type Session = {
163
163
  /** Ephemeral lane clocks: restart at 1 on every attach. */
164
164
  ephemeralSeqs: Record<string, number>;
165
165
  resumeAt: number;
166
+ /** A refusal named sent durable stamps: a reattach's hello decides them, after `resumeAt`. */
167
+ reattach: boolean;
166
168
  idle: boolean;
167
169
  onSessionLost: StatewireClient.OnSessionLost | undefined;
168
170
  onDeprecatedPath: StatewireClient.OnDeprecatedPath | undefined;
@@ -1326,14 +1328,16 @@ const sessionLostInner = (s: Session, protocol: string, seqWm: number) => {
1326
1328
  },
1327
1329
  );
1328
1330
  } else {
1329
- // Default: the whole queue goes, each command a failure notice.
1331
+ // Default: the queue goes, each command a failure notice. Held entries
1332
+ // never went out: they stay held where they are.
1330
1333
  const stamps = mergeBacklog(s, protocol);
1331
- const queued = outboxOf(lane);
1332
- const { outbox: _outbox, ...rest } = lane;
1334
+ const held = outboxOf(lane).filter((c) => c.held);
1335
+ const queued = outboxOf(lane).filter((c) => !c.held);
1336
+ const keep = new Set(held.map((c) => c.id));
1333
1337
  setRecord(
1334
1338
  s,
1335
1339
  withLane(s.record, protocol, {
1336
- ...withNotices(rest, [
1340
+ ...withNotices(withOutbox(lane, held), [
1337
1341
  ...stamps.map((c) => lostNotice(c)),
1338
1342
  ...queued.map((c) => lostNotice(c)),
1339
1343
  ]),
@@ -1350,7 +1354,9 @@ const sessionLostInner = (s: Session, protocol: string, seqWm: number) => {
1350
1354
  ),
1351
1355
  }),
1352
1356
  );
1353
- for (const p of s.pending.filter((q) => q.command.protocol === protocol)) {
1357
+ for (const p of s.pending.filter(
1358
+ (q) => q.command.protocol === protocol && !keep.has(q.id),
1359
+ )) {
1354
1360
  s.lifecycle?.onCovered?.(p.inv);
1355
1361
  settleEntry(s, p, { ok: false, failure }, "noticed");
1356
1362
  }
@@ -1451,6 +1457,21 @@ const selectionOf = (
1451
1457
  };
1452
1458
  };
1453
1459
 
1460
+ // The host admits an attach's durable statements right after its hello.
1461
+ const carriedThrough = (
1462
+ lane: { name: string; seq?: number },
1463
+ attached: ReadonlySet<Pending>,
1464
+ ) => {
1465
+ const carried = new Set(
1466
+ [...attached]
1467
+ .filter((p) => p.command.protocol === lane.name)
1468
+ .map((p) => p.seq),
1469
+ );
1470
+ let seq = lane.seq ?? 0;
1471
+ while (carried.has(seq + 1)) seq += 1;
1472
+ return seq;
1473
+ };
1474
+
1454
1475
  const handleHello = (
1455
1476
  s: Session,
1456
1477
  { ops, syn }: { ops: unknown[]; syn: StatewireSyn },
@@ -1472,6 +1493,7 @@ const handleHello = (
1472
1493
  s.attachEpoch += 1;
1473
1494
  s.frameFailures = 0;
1474
1495
  s.resumeAt = 0;
1496
+ s.reattach = false;
1475
1497
  const lanes = syn.protocols ?? [];
1476
1498
  s.ephemeral =
1477
1499
  lanes.length > 0 && lanes.every((lane) => lane.record === "ephemeral");
@@ -1494,7 +1516,7 @@ const handleHello = (
1494
1516
  );
1495
1517
  continue;
1496
1518
  }
1497
- demote(s, lane.name, lane.seq ?? 0, demoted, waiting);
1519
+ demote(s, lane.name, carriedThrough(lane, attached), demoted, waiting);
1498
1520
  s.durableSeq[lane.name] = lane.seq ?? 0;
1499
1521
  }
1500
1522
  for (const entry of s.pending) {
@@ -1543,10 +1565,26 @@ const handleOps = (
1543
1565
  // A retry-less {syn} refusal is the one session-loss verdict: a gap against
1544
1566
  // a durable lane's exact watermark settles that lane's history lost; a
1545
1567
  // pushback (retry present) or a gapless refusal only reconciles the resend queues.
1568
+ // Under the gap-fill wire a refusal can predate frames sent since: durable
1569
+ // lanes never resend from it, a reattach's hello decides them.
1546
1570
  const handleRefusal = (s: Session, syn: StatewireSyn) => {
1547
- const lanes = (syn.protocols ?? []).filter(
1571
+ const stated = (syn.protocols ?? []).filter(
1548
1572
  (lane): lane is { name: string; seq: number } => lane.seq !== undefined,
1549
1573
  );
1574
+ const lanes = gapFill(s)
1575
+ ? stated.filter(({ name }) => isEphemeral(s, name))
1576
+ : stated;
1577
+ if (
1578
+ gapFill(s) &&
1579
+ s.pending.some((p) => {
1580
+ if (!isStamped(p) || !p.attempted) return false;
1581
+ const protocol = p.command.protocol;
1582
+ if (isEphemeral(s, protocol)) return false;
1583
+ const seq = stated.find((lane) => lane.name === protocol)?.seq ?? 0;
1584
+ return p.seq > Math.max(seq, durableSeqOf(s, protocol));
1585
+ })
1586
+ )
1587
+ s.reattach = true;
1550
1588
  for (const { name, seq } of lanes) {
1551
1589
  const watermark = isEphemeral(s, name)
1552
1590
  ? seq
@@ -1728,6 +1766,29 @@ const pump = async (s: Session) => {
1728
1766
  while (s.running && !isFinished(s)) {
1729
1767
  if (!s.hydrated) await s.ready;
1730
1768
  const transport = s.transport;
1769
+ if (s.reattach && s.attach === "attached" && transport) {
1770
+ const delay = s.resumeAt - Date.now();
1771
+ if (delay > 0) {
1772
+ await sleepUntilWake(s, delay);
1773
+ continue;
1774
+ }
1775
+ // Ephemeral answers ride only this attach: drain them first.
1776
+ if (
1777
+ s.pending.some(
1778
+ (p) =>
1779
+ isStamped(p) && p.attempted && isEphemeral(s, p.command.protocol),
1780
+ )
1781
+ ) {
1782
+ await waitForWake(s);
1783
+ continue;
1784
+ }
1785
+ s.reattach = false;
1786
+ const epoch = s.attachEpoch;
1787
+ transport.connection.reconnect();
1788
+ while (s.running && !isFinished(s) && epoch === s.attachEpoch)
1789
+ await waitForWake(s);
1790
+ continue;
1791
+ }
1731
1792
  const flushable = flushCandidates(s).length > 0;
1732
1793
  const queued =
1733
1794
  s.pending.some((p) => isOutboxed(p) && !p.inv.held) ||
@@ -2444,7 +2505,7 @@ export const updateOutbox = (
2444
2505
  const producedOf = (
2445
2506
  s: Session,
2446
2507
  ): NonNullable<StatewireClient.SessionCommand["produced"]> => ({
2447
- wire: s.options.wireVersion ?? { version: WIRE_VERSION },
2508
+ wire: s.options.wireVersion ?? CLIENT_WIRE,
2448
2509
  protocols:
2449
2510
  protocolOffers(s.options) === "*" && s.selection
2450
2511
  ? s.selection.protocols
@@ -2512,6 +2573,7 @@ export const insertOutbox = (
2512
2573
  return;
2513
2574
  }
2514
2575
  let base = s.record;
2576
+ let entered = stored;
2515
2577
  if (entry.from !== undefined) {
2516
2578
  // Re-inserting a settled update consumes it in the same write: a
2517
2579
  // redelivery finds it gone.
@@ -2519,16 +2581,27 @@ export const insertOutbox = (
2519
2581
  l.inbox?.some((n) => n.id === entry.from),
2520
2582
  );
2521
2583
  if (source === undefined || locate(s, id) !== undefined) return;
2584
+ const notice = source[1].inbox!.find((n) => n.id === entry.from)!;
2585
+ entered = { ...stored, ts: notice.ts };
2522
2586
  base = withLane(base, source[0], withoutNotice(source[1], entry.from));
2523
2587
  }
2524
2588
  const lane = laneOf(base, protocol);
2589
+ // A re-queued command keeps its place: ahead of what was queued after it.
2590
+ const later = outboxOf(lane).find((c) => c.ts >= entered.ts);
2591
+ const position =
2592
+ entry.from !== undefined &&
2593
+ entry.after === undefined &&
2594
+ entry.before === undefined &&
2595
+ later !== undefined
2596
+ ? { before: later.id }
2597
+ : entry;
2525
2598
  try {
2526
2599
  setRecord(
2527
2600
  s,
2528
2601
  withLane(
2529
2602
  base,
2530
2603
  protocol,
2531
- withOutbox(lane, placed(outboxOf(lane), stored, entry)),
2604
+ withOutbox(lane, placed(outboxOf(lane), entered, position)),
2532
2605
  ),
2533
2606
  );
2534
2607
  } catch (error) {
@@ -2800,7 +2873,7 @@ const loadSessionRecord = (
2800
2873
  let stored = store.load();
2801
2874
  if (stored !== null) validateLanes(stored);
2802
2875
  const current = {
2803
- wire: options.wireVersion ?? { version: WIRE_VERSION },
2876
+ wire: options.wireVersion ?? CLIENT_WIRE,
2804
2877
  protocols: protocolOffers(options),
2805
2878
  };
2806
2879
  const compatible = (record: StatewireClient.SessionRecord) =>
@@ -2933,6 +3006,7 @@ export const useStatewireSession = (
2933
3006
  durableSeq: {},
2934
3007
  ephemeralSeqs: {},
2935
3008
  resumeAt: 0,
3009
+ reattach: false,
2936
3010
  idle: false,
2937
3011
  onSessionLost: undefined,
2938
3012
  onDeprecatedPath: undefined,