experimental-a2 0.21.1 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/{actor-HnGmrOZZ.d.ts → actor-CqibLgjQ.d.ts} +13 -5
  3. package/dist/actor-CqibLgjQ.d.ts.map +1 -0
  4. package/dist/actor-client.d.ts +1 -1
  5. package/dist/actor-react.d.ts +1 -1
  6. package/dist/actor-react.js +1 -1
  7. package/dist/actor-shared-DFET5q16.js.map +1 -1
  8. package/dist/actor.d.ts +1 -1
  9. package/dist/actor.js +3 -3
  10. package/dist/{ai-CvEnqVfo.d.ts → ai-DAu77CDr.d.ts} +2 -2
  11. package/dist/{ai-CvEnqVfo.d.ts.map → ai-DAu77CDr.d.ts.map} +1 -1
  12. package/dist/{ai-CzE672Q3.js → ai-EEfKyc-z.js} +2 -2
  13. package/dist/{ai-CzE672Q3.js.map → ai-EEfKyc-z.js.map} +1 -1
  14. package/dist/ai-client.d.ts +1 -1
  15. package/dist/ai-client.js +2 -2
  16. package/dist/ai-fx.d.ts +4 -2
  17. package/dist/ai-fx.d.ts.map +1 -1
  18. package/dist/ai-fx.js +234 -62
  19. package/dist/ai-fx.js.map +1 -1
  20. package/dist/{ai-harness-Bfk-Lycn.d.ts → ai-harness-DTjkAr2T.d.ts} +2 -2
  21. package/dist/{ai-harness-Bfk-Lycn.d.ts.map → ai-harness-DTjkAr2T.d.ts.map} +1 -1
  22. package/dist/ai-harness-dQeJaR1t.js.map +1 -1
  23. package/dist/ai-pi.d.ts +1 -1
  24. package/dist/ai-pi.js +1 -1
  25. package/dist/ai-react.d.ts +1 -1
  26. package/dist/ai-react.js +2 -2
  27. package/dist/ai-server.d.ts +3 -3
  28. package/dist/ai-server.d.ts.map +1 -1
  29. package/dist/ai-server.js +10 -4
  30. package/dist/ai-server.js.map +1 -1
  31. package/dist/ai.d.ts +1 -1
  32. package/dist/ai.js +1 -1
  33. package/dist/{client-9IeTsiAs.js → client-BQS4i_V9.js} +27 -4
  34. package/dist/client-BQS4i_V9.js.map +1 -0
  35. package/dist/client-CUMbS_38.d.ts.map +1 -1
  36. package/dist/client.js +1 -1
  37. package/dist/index.d.ts +2 -2
  38. package/dist/{internal-Bc4PvfHk.js → internal-CvsrprnU.js} +32 -15
  39. package/dist/{internal-Bc4PvfHk.js.map → internal-CvsrprnU.js.map} +1 -1
  40. package/dist/react.js +1 -1
  41. package/dist/{runtime-consumer-BWmht60z.js → runtime-consumer-CIeL33wj.js} +2 -2
  42. package/dist/{runtime-consumer-BWmht60z.js.map → runtime-consumer-CIeL33wj.js.map} +1 -1
  43. package/dist/scheduler-qstash.d.ts +2 -2
  44. package/dist/scheduler-qstash.js +2 -2
  45. package/dist/scheduler-vercel.d.ts +2 -2
  46. package/dist/scheduler-vercel.js +2 -2
  47. package/dist/{server-DvIB8kj5.js → server-DtFrWxi3.js} +30 -8
  48. package/dist/server-DtFrWxi3.js.map +1 -0
  49. package/dist/{server-BshFZ0eL.d.ts → server-qgez0Xny.d.ts} +3 -3
  50. package/dist/{server-BshFZ0eL.d.ts.map → server-qgez0Xny.d.ts.map} +1 -1
  51. package/dist/server.d.ts +2 -2
  52. package/dist/server.js +1 -1
  53. package/dist/{session-clear-Bk_29eEw.d.ts → session-clear-D1PFe7xl.d.ts} +2 -2
  54. package/dist/session-clear-D1PFe7xl.d.ts.map +1 -0
  55. package/dist/{store-Z2qjw50n.d.ts → store-D0MhBvg6.d.ts} +15 -6
  56. package/dist/store-D0MhBvg6.d.ts.map +1 -0
  57. package/dist/store-N8PXxDAS.js.map +1 -1
  58. package/dist/store-memory.d.ts +1 -1
  59. package/dist/store-memory.d.ts.map +1 -1
  60. package/dist/store-memory.js +15 -17
  61. package/dist/store-memory.js.map +1 -1
  62. package/dist/{store-polling-DYNyxCev.js → store-polling-BZt2Rf3D.js} +2 -2
  63. package/dist/{store-polling-DYNyxCev.js.map → store-polling-BZt2Rf3D.js.map} +1 -1
  64. package/dist/store-postgres.d.ts +1 -1
  65. package/dist/store-postgres.d.ts.map +1 -1
  66. package/dist/store-postgres.js +31 -40
  67. package/dist/store-postgres.js.map +1 -1
  68. package/dist/store-presence-polling-JuAy2Ck2.js +111 -0
  69. package/dist/store-presence-polling-JuAy2Ck2.js.map +1 -0
  70. package/dist/store-redis-http.d.ts +1 -1
  71. package/dist/store-redis-http.js +3 -3
  72. package/dist/{store-redis-notify-IiVdlYHc.js → store-redis-notify-CBDVJxA_.js} +545 -399
  73. package/dist/store-redis-notify-CBDVJxA_.js.map +1 -0
  74. package/dist/store-redis.d.ts +1 -1
  75. package/dist/store-redis.d.ts.map +1 -1
  76. package/dist/store-redis.js +3 -4
  77. package/dist/store-redis.js.map +1 -1
  78. package/dist/store-sqlite.d.ts +1 -1
  79. package/dist/store-sqlite.d.ts.map +1 -1
  80. package/dist/store-sqlite.js +16 -18
  81. package/dist/store-sqlite.js.map +1 -1
  82. package/dist/store-valkey.d.ts +33 -0
  83. package/dist/store-valkey.d.ts.map +1 -0
  84. package/dist/store-valkey.js +218 -0
  85. package/dist/store-valkey.js.map +1 -0
  86. package/dist/stream-buffer-DrTyiIuo.js +57 -0
  87. package/dist/stream-buffer-DrTyiIuo.js.map +1 -0
  88. package/dist/{wire-CZGqNZRx.js → wire-CV-Z7wz-.js} +3 -3
  89. package/dist/{wire-CZGqNZRx.js.map → wire-CV-Z7wz-.js.map} +1 -1
  90. package/docs/actors/01-introduction.mdx +5 -2
  91. package/docs/agents/03-conversations.mdx +9 -8
  92. package/docs/agents/04-harnesses.mdx +7 -4
  93. package/docs/client/03-presence.mdx +1 -0
  94. package/docs/reference/01-core.mdx +4 -2
  95. package/docs/reference/02-server.mdx +5 -1
  96. package/docs/reference/04-ai.mdx +13 -4
  97. package/docs/reference/06-errors.mdx +1 -1
  98. package/docs/server/01-consumers.mdx +4 -1
  99. package/docs/server/06-guarantees.mdx +7 -4
  100. package/docs/stores/01-overview.mdx +1 -0
  101. package/docs/stores/02-redis.mdx +18 -10
  102. package/docs/stores/03-redis-http.mdx +6 -4
  103. package/docs/stores/04-postgres.mdx +2 -2
  104. package/docs/stores/07-valkey.mdx +97 -0
  105. package/docs/upgrades/01-overview.mdx +1 -0
  106. package/docs/upgrades/78-0-22.mdx +115 -0
  107. package/examples/playground/app/a0/sandbox.ts +58 -13
  108. package/examples/playground/app/a2slack/db/a2.ts +7 -4
  109. package/examples/playground/app/a2slack/db/migrations/0004_a2_session_event_ids.sql +2 -0
  110. package/examples/playground/app/a2slack/db/migrations/meta/0004_snapshot.json +1165 -0
  111. package/examples/playground/app/a2slack/db/migrations/meta/_journal.json +8 -1
  112. package/examples/playground/app/chat/server.ts +2 -2
  113. package/examples/playground/lib/store.ts +1 -1
  114. package/examples/playground/package.json +1 -1
  115. package/package.json +8 -2
  116. package/sql/postgres/drizzle-schema.ts +7 -4
  117. package/sql/postgres/schema.sql +24 -3
  118. package/src/actor-shared.ts +10 -2
  119. package/src/ai-agent.ts +13 -0
  120. package/src/ai-fx.ts +365 -78
  121. package/src/ai-harness.ts +7 -0
  122. package/src/client.ts +19 -2
  123. package/src/deterministic-id.ts +1 -1
  124. package/src/internal.ts +42 -11
  125. package/src/libfx.d.ts +2 -0
  126. package/src/presence-recovery.ts +18 -11
  127. package/src/presence-tombstones.ts +52 -0
  128. package/src/push-envelope.ts +2 -2
  129. package/src/server.ts +49 -15
  130. package/src/store-memory.ts +24 -32
  131. package/src/store-postgres.ts +43 -53
  132. package/src/store-presence-polling.ts +59 -34
  133. package/src/store-redis-core.ts +595 -439
  134. package/src/store-redis-notify.ts +82 -28
  135. package/src/store-redis.ts +2 -3
  136. package/src/store-sqlite.ts +34 -40
  137. package/src/store-valkey.ts +376 -0
  138. package/src/store.ts +14 -5
  139. package/dist/actor-HnGmrOZZ.d.ts.map +0 -1
  140. package/dist/client-9IeTsiAs.js.map +0 -1
  141. package/dist/server-DvIB8kj5.js.map +0 -1
  142. package/dist/session-clear-Bk_29eEw.d.ts.map +0 -1
  143. package/dist/store-Z2qjw50n.d.ts.map +0 -1
  144. package/dist/store-presence-polling-CzQ0wdtM.js +0 -94
  145. package/dist/store-presence-polling-CzQ0wdtM.js.map +0 -1
  146. package/dist/store-redis-notify-IiVdlYHc.js.map +0 -1
  147. package/dist/stream-buffer-Cx7AAPGq.js +0 -23
  148. package/dist/stream-buffer-Cx7AAPGq.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-DtFrWxi3.js","names":[],"sources":["../src/push-envelope.ts","../src/session-socket.ts","../src/sse.ts","../src/bootstrap-stream.ts","../src/server-fetch.ts","../src/deterministic-id.ts","../src/telemetry.ts","../src/server.ts"],"sourcesContent":["/**\n * The push envelope's trust boundary for `{ sessionId, events, presence? }`,\n * shared verbatim by the HTTP\n * POST lane and the socket's push/presence frames so INVALID_PAYLOAD\n * shapes are one implementation. Internal module, not public API.\n */\n\nimport { A2Error } from './errors.ts'\nimport { MAX_DATE_MS, RESERVED_PARTICIPANT_IDS } from './internal.ts'\n\nexport type ParsedPushEvent = {\n type: string\n payload: unknown\n id?: string\n}\n\nexport type ParsedPushPresence = {\n participant: string\n values: Record<string, unknown>\n seen?: number\n at?: number\n}\n\nexport const invalidPushBody = (message: string): A2Error =>\n new A2Error('INVALID_PAYLOAD', `malformed push body: ${message}`)\n\nconst invalid = invalidPushBody\n\nexport type PushBody = {\n sessionId: string\n events: ParsedPushEvent[]\n presence?: ParsedPushPresence\n}\n\nexport function parsePresenceSibling(\n value: unknown,\n): ParsedPushPresence | undefined {\n if (value === undefined) return undefined\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw invalid('presence must be an object when present')\n }\n const { participant, values, seen, at } = value as Record<string, unknown>\n if (typeof participant !== 'string' || participant.length === 0) {\n throw invalid('presence.participant must be a non-empty string')\n }\n if (RESERVED_PARTICIPANT_IDS.has(participant)) {\n throw invalid(`presence.participant must not be '${participant}'`)\n }\n if (values === null || typeof values !== 'object' || Array.isArray(values)) {\n throw invalid('presence.values must be an object')\n }\n if (\n seen !== undefined &&\n (typeof seen !== 'number' || !Number.isFinite(seen) || seen < 0)\n ) {\n throw invalid('presence.seen must be a non-negative number when present')\n }\n if (\n at !== undefined &&\n (typeof at !== 'number' ||\n !Number.isFinite(at) ||\n at < 0 ||\n at > MAX_DATE_MS)\n ) {\n throw invalid(\n 'presence.at must be a non-negative epoch-milliseconds timestamp within the Date range when present',\n )\n }\n const out: {\n participant: string\n values: Record<string, unknown>\n seen?: number\n at?: number\n } = { participant, values: values as Record<string, unknown> }\n if (seen !== undefined) out.seen = seen\n if (at !== undefined) out.at = at\n return out\n}\n\n/** The longest event id a push may carry: ids are indexed, and Postgres's index rows have a limit. */\nconst MAX_PUSHED_ID = 256\n\n/** A UUIDv5, the shape of the ids A2 derives (deterministic-id.ts). */\nconst DERIVED_ID =\n /^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\n/** The events half of the envelope, shared by the POST body and socket\n * `push` frames so INVALID_PAYLOAD shapes have one implementation. */\nexport function parsePushEvents(events: unknown): ParsedPushEvent[] {\n if (!Array.isArray(events) || events.length === 0) {\n throw invalid('events must be a non-empty array')\n }\n return events.map((event, i) => {\n if (event === null || typeof event !== 'object') {\n throw invalid(`events[${i}] must be an object`)\n }\n const { type, payload, id } = event as Record<string, unknown>\n if (typeof type !== 'string' || type.length === 0) {\n throw invalid(`events[${i}].type must be a non-empty string`)\n }\n if (id !== undefined && typeof id !== 'string') {\n throw invalid(`events[${i}].id must be a string when present`)\n }\n if (id !== undefined && (id.length === 0 || id.length > MAX_PUSHED_ID)) {\n throw invalid(\n `events[${i}].id must be 1-${MAX_PUSHED_ID} characters when present`,\n )\n }\n // A2 derives the ids of what consumers append, return, and schedule as\n // UUIDv5s, from inputs a caller can know: one pushed first into the same\n // session would take its place. Callers' own ids are v4 (crypto.randomUUID) or v8 (idempotentId).\n if (id !== undefined && DERIVED_ID.test(id)) {\n throw invalid(\n `events[${i}].id is shaped like the ids A2 derives for consumers (a UUIDv5); use crypto.randomUUID() or idempotentId()`,\n )\n }\n const out: { type: string; payload: unknown; id?: string } = {\n type,\n payload,\n }\n if (id !== undefined) out.id = id\n return out\n })\n}\n\n/**\n * Validate the push envelope — `{ sessionId, events, presence? }` —\n * throwing `INVALID_PAYLOAD` on a malformed body. Payload validation\n * against the machine's schemas happens in `append` and `setPresence`,\n * not here. Either plane may appear alone: a presence-only push has no\n * (or empty) `events`.\n */\nexport async function parsePushBody(req: Request): Promise<PushBody> {\n let body: unknown\n try {\n body = await req.json()\n } catch (cause) {\n throw new A2Error('INVALID_PAYLOAD', 'push body is not valid JSON', {\n cause,\n })\n }\n if (body === null || typeof body !== 'object') {\n throw invalid('expected an object')\n }\n const { sessionId, events, presence } = body as Record<string, unknown>\n if (typeof sessionId !== 'string' || sessionId.length === 0) {\n throw invalid('sessionId must be a non-empty string')\n }\n const parsedPresence = parsePresenceSibling(presence)\n if (\n parsedPresence !== undefined &&\n (events === undefined || (Array.isArray(events) && events.length === 0))\n ) {\n return { sessionId, events: [], presence: parsedPresence }\n }\n const parsed = parsePushEvents(events)\n return parsedPresence !== undefined\n ? { sessionId, events: parsed, presence: parsedPresence }\n : { sessionId, events: parsed }\n}\n","/**\n * The A2 socket protocol's server half (specs/a2-api.md §13): the\n * per-socket shell — teardown, backpressure, heartbeat, the malformed\n * budget, and the in-flight bound. `sessionSocket` binds one session to\n * one socket; `sessionsSocket` is the opt-in multiplexed handler. Only\n * `A2Socket`, the structural socket the platform hands over, is public.\n */\n\nimport { A2Error } from './errors.ts'\nimport { SOCKET_TIMINGS, STREAM_TIMINGS } from './internal.ts'\nimport { streamActivities } from './stream-activity.ts'\nimport type { Event } from './store.ts'\nimport type { EventDefs, PresencePatch, PresenceSnapshot } from './contract.ts'\nimport type { ParsedPushEvent, ParsedPushPresence } from './push-envelope.ts'\nimport type { Session } from './server.ts'\nimport { parsePresenceSibling, parsePushEvents } from './push-envelope.ts'\nimport {\n type StateSnapshotFrame,\n type SocketSubscribeEntry,\n type SubscriptionStart,\n type WireVersion,\n SOCKET_PING_FRAME,\n asA2Error,\n compactEventJson,\n heldEventBatch,\n isStreamEvent,\n socketAckFor,\n socketErrorAckFor,\n socketEventsFor,\n socketFrameFor,\n socketSubscribedFor,\n socketUnsubscribedFor,\n} from './wire.ts'\n\n// ── the ws wire ───────────────────────────────────────────────────────\n\n/**\n * The structural socket `sessionsSocket` speaks against — satisfied\n * by `ws` and by `@vercel/functions`' upgraded socket alike, so the\n * platform upgrade API stays out of the library. `message` data\n * arrives as whatever the platform delivers (string, Buffer,\n * ArrayBuffer, or fragments); the handler normalizes defensively.\n */\nexport type A2Socket = {\n send(data: string): void\n on(event: 'message', listener: (data: unknown) => void): void\n on(event: 'close', listener: () => void): void\n on(event: 'error', listener: (error: unknown) => void): void\n close(code?: number, reason?: string): void\n /** Bytes queued but not yet transmitted — when exposed, the down\n * pump uses it for backpressure (`SOCKET_TIMINGS`). */\n bufferedAmount?: number\n}\n\nconst messageText = (data: unknown): string | null => {\n if (typeof data === 'string') return data\n if (data instanceof ArrayBuffer) return new TextDecoder().decode(data)\n if (ArrayBuffer.isView(data)) return new TextDecoder().decode(data)\n if (Array.isArray(data) && data.every(ArrayBuffer.isView)) {\n // ws delivers fragmented messages as a Buffer array; stream-decode\n // so multi-byte characters can span fragment boundaries.\n const decoder = new TextDecoder()\n let text = ''\n for (const part of data) text += decoder.decode(part, { stream: true })\n return text + decoder.decode()\n }\n return null\n}\n\n/**\n * How many unparseable or invalid frames a socket may send before it\n * is closed (1008): the budget absorbs isolated client bugs without\n * letting a broken peer spin the validation path forever. Push frames\n * with a usable `req` never count — their failures are answered with\n * error acks, exactly like the POST path's 4xx bodies.\n */\nconst MAX_MALFORMED_FRAMES = 5\n\n/**\n * The pump's runtime view of a session. The presence members are\n * conditional on the public surface (`WithPresence`) and therefore\n * invisible on a generic `Session<D>`, so capability is checked at\n * runtime (`setPresence` present). The cast stays inside the transport.\n */\nexport type SocketSession = {\n stream(opts: {\n startAfter: number\n presence?: boolean\n }): AsyncIterable<\n Event | PresencePatch | PresenceSnapshot | StateSnapshotFrame\n >\n append(...events: ParsedPushEvent[]): Promise<Event[]>\n setPresence?(patch: ParsedPushPresence): Promise<void>\n}\n\n/**\n * The per-socket machinery `sessionsSocket` builds on: the torn flag\n * with a release-once teardown, the backpressure-aware send with its\n * non-reader ceiling, the malformed budget, the in-flight bound, the\n * message normalization, the heartbeat, and the optional deadline.\n */\ntype SocketShell = {\n torn(): boolean\n send(data: string): void\n shutdown(code: number, reason?: string): void\n malformedFrame(reason: string): void\n buffered(): number\n overCap(): boolean\n track(work: Promise<void>): void\n}\n\nfunction socketShell(\n socket: A2Socket,\n release: () => void,\n onFrame: (frame: Record<string, unknown>) => void,\n deadlineAt: number | undefined,\n): SocketShell {\n let torn = false\n let malformed = 0\n let heartbeat: ReturnType<typeof setInterval> | undefined\n let deadline: ReturnType<typeof setTimeout> | undefined\n\n const teardown = (): void => {\n if (torn) return\n torn = true\n if (heartbeat !== undefined) clearInterval(heartbeat)\n if (deadline !== undefined) clearTimeout(deadline)\n release()\n }\n\n const shutdown = (code: number, reason?: string): void => {\n if (torn) return\n teardown()\n try {\n socket.close(code, reason)\n } catch {\n // Already closed underneath us — teardown has run either way.\n }\n }\n\n const send = (data: string): void => {\n if (torn) return\n // The pump parks at the high-water mark, but acks and pings are\n // exempt (small, correctness-relevant) — so a peer that never\n // reads while it keeps uploading grows the buffer through its own\n // acks. The ceiling closes the class: past it, the peer is not a\n // slow reader, it is a non-reader (adversarial F4).\n if (\n typeof socket.bufferedAmount === 'number' &&\n socket.bufferedAmount > SOCKET_TIMINGS.disconnectWaterMarkBytes\n ) {\n shutdown(1008, 'backpressure: peer not reading')\n return\n }\n try {\n socket.send(data)\n } catch {\n // The platform closed the socket without an event; closing it\n // again would throw the same way, so just tear down.\n teardown()\n }\n }\n\n const malformedFrame = (reason: string): void => {\n malformed += 1\n if (malformed >= MAX_MALFORMED_FRAMES) {\n shutdown(1008, `too many malformed frames (last: ${reason})`)\n }\n }\n\n // The up-lane bound (adversarial F3): one socket must not hold\n // unbounded concurrent appends. Shedding is per-plane semantics —\n // pushes are TOLD (retryable error ack, ids make the retry safe),\n // presence is silently dropped (a lost update is repainted by the\n // next one). Sheds are our load decision, never the peer's\n // malformedness, so they spend no budget.\n let inFlight = 0\n const track = (work: Promise<void>): void => {\n inFlight += 1\n void work.finally(() => {\n inFlight -= 1\n })\n }\n\n const handleMessage = (data: unknown): void => {\n if (torn) return\n const text = messageText(data)\n if (text === null) {\n malformedFrame('non-text frame')\n return\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n malformedFrame('frame is not valid JSON')\n return\n }\n if (\n parsed === null ||\n typeof parsed !== 'object' ||\n Array.isArray(parsed)\n ) {\n malformedFrame('frame is not an object')\n return\n }\n onFrame(parsed as Record<string, unknown>)\n }\n\n socket.on('message', handleMessage)\n socket.on('close', teardown)\n socket.on('error', teardown)\n\n heartbeat = setInterval(\n () => send(SOCKET_PING_FRAME),\n STREAM_TIMINGS.sseHeartbeatMs,\n )\n ;(heartbeat as { unref?: () => void }).unref?.()\n\n if (deadlineAt !== undefined) {\n deadline = setTimeout(\n () => shutdown(1000, 'deadline'),\n Math.max(0, deadlineAt - Date.now()),\n )\n ;(deadline as { unref?: () => void }).unref?.()\n }\n\n return {\n torn: () => torn,\n send,\n shutdown,\n malformedFrame,\n buffered: () =>\n typeof socket.bufferedAmount === 'number' ? socket.bufferedAmount : 0,\n overCap: () => inFlight >= SOCKET_TIMINGS.maxInFlightMessages,\n track,\n }\n}\n\n/**\n * The per-session authorization seam of `sessionsSocket`: called once\n * per `subscribe` entry (and never for the pushes and presence that\n * ride an accepted subscription). `null` rejects that session — the\n * socket answers `unsubscribed` with a rejection reason and every\n * other session on it is untouched.\n */\nexport type SessionsSocketResolve<D extends EventDefs> = (\n sessionId: string,\n /** The entry's resume frontier — `stream({ startAfter })`. */\n startAfter: number,\n selection?: SubscriptionStart,\n) =>\n | Pick<Session<D>, 'stream'>\n | Pick<SocketSession, 'stream'>\n | null\n | Promise<Pick<Session<D>, 'stream'> | Pick<SocketSession, 'stream'> | null>\n\nexport type SessionsSocketOptions = {\n /** The `stream()` presence opt-in for every session on the socket —\n * the server decides, same rule as the SSE route. */\n presence?: boolean\n /** Epoch ms: close cleanly (code 1000) at this time, ahead of a known\n * platform deadline, so clients reconnect on our schedule. */\n deadline?: number\n /** `2` sends live events as `events` batches (the client's `wire=2`). */\n wire?: WireVersion\n /** Runs after frame parsing and before append or presence I/O. */\n gatePush?(\n sessionId: string,\n events: ParsedPushEvent[],\n presence?: ParsedPushPresence,\n ): A2Error | null | Promise<A2Error | null>\n}\n\nexport type SessionSocketOptions = SessionsSocketOptions & {\n startAfter?: number\n}\n\ntype SocketSubscription = {\n target: SocketSession\n iterator: AsyncIterator<\n Event | PresencePatch | PresenceSnapshot | StateSnapshotFrame\n >\n stopped: boolean\n attempt?: number\n}\n\nconst socketSubscription = (options: {\n target: SocketSession\n startAfter: number\n presence: boolean\n attempt?: number | undefined\n}): SocketSubscription => {\n const { target, startAfter, presence, attempt } = options\n return {\n target,\n iterator: (presence\n ? target.stream({ startAfter, presence: true })\n : target.stream({ startAfter }))[Symbol.asyncIterator](),\n stopped: false,\n ...(attempt === undefined ? {} : { attempt }),\n }\n}\n\nconst stopSubscription = (subscription: SocketSubscription): void => {\n subscription.stopped = true\n void subscription.iterator.return?.()?.catch(() => {})\n}\n\n/**\n * Sends a subscription's items until it ends. With `batch`, an event and\n * the events its iterator already holds go out as one frame.\n */\nconst pumpSubscription = async (options: {\n shell: SocketShell\n subscription: SocketSubscription\n frameFor: (\n item: Event | PresencePatch | PresenceSnapshot | StateSnapshotFrame,\n ) => string\n batch?: (events: string[]) => string\n}): Promise<void> => {\n const { shell, subscription, frameFor, batch } = options\n for (;;) {\n while (\n !shell.torn() &&\n !subscription.stopped &&\n shell.buffered() > SOCKET_TIMINGS.highWaterMarkBytes\n ) {\n // oxlint-disable-next-line no-await-in-loop -- backpressure park\n await new Promise((wake) => setTimeout(wake, SOCKET_TIMINGS.resumePollMs))\n }\n if (shell.torn() || subscription.stopped) return\n // oxlint-disable-next-line no-await-in-loop -- stream pump\n const { value, done } = await subscription.iterator.next()\n if (shell.torn() || subscription.stopped || done) return\n if (!batch || !isStreamEvent(value)) {\n shell.send(frameFor(value))\n continue\n }\n const { events } = heldEventBatch({\n first: value,\n iterator: subscription.iterator,\n encode: compactEventJson,\n })\n shell.send(batch(events))\n }\n}\n\nconst handleSocketPush = async (\n shell: SocketShell,\n target: SocketSession,\n sessionId: string,\n frame: Record<string, unknown>,\n req: number,\n ackSessionId: string | undefined,\n gatePush: SessionsSocketOptions['gatePush'],\n activate: () => void,\n): Promise<void> => {\n try {\n const events = parsePushEvents(frame['events'])\n const denial = (await gatePush?.(sessionId, events, undefined)) ?? null\n if (denial !== null) {\n shell.send(socketErrorAckFor(req, denial, ackSessionId))\n return\n }\n activate()\n // oxlint-disable-next-line a2/await-consumer-append -- this transport append is awaited before its ack\n const appended = await target.append(...events)\n activate()\n shell.send(socketAckFor(req, appended, ackSessionId))\n } catch (error) {\n shell.send(socketErrorAckFor(req, asA2Error(error), ackSessionId))\n }\n}\n\nconst applySocketPresence = async (\n shell: SocketShell,\n target: SocketSession,\n sessionId: string,\n frame: Record<string, unknown>,\n gatePush: SessionsSocketOptions['gatePush'],\n): Promise<void> => {\n if (typeof target.setPresence !== 'function') {\n shell.malformedFrame('presence frame on a presence-less session')\n return\n }\n let patch: ParsedPushPresence | undefined\n try {\n patch = parsePresenceSibling(frame)\n } catch {\n shell.malformedFrame('invalid presence frame')\n return\n }\n if (!patch) return\n try {\n const denial = (await gatePush?.(sessionId, [], patch)) ?? null\n if (denial !== null) return\n await target.setPresence(patch)\n } catch (error) {\n const failure = asA2Error(error)\n if (\n failure.code === 'INVALID_PAYLOAD' ||\n failure.code === 'UNKNOWN_PRESENCE_FIELD'\n ) {\n shell.malformedFrame('invalid presence frame')\n return\n }\n shell.shutdown(1011, 'internal error')\n }\n}\n\nexport function sessionSocket<D extends EventDefs>(\n sessionId: string,\n session: Pick<Session<D>, 'stream'> | Pick<SocketSession, 'stream'>,\n socket: A2Socket,\n options?: SessionSocketOptions,\n): void {\n const target = session as unknown as SocketSession\n const subscription = socketSubscription({\n target,\n startAfter: options?.startAfter ?? 0,\n presence: options?.presence === true,\n })\n\n const handleFrame = (frame: Record<string, unknown>): void => {\n switch (frame['kind']) {\n case 'push': {\n const req = frame['req']\n if (typeof req !== 'number') {\n shell.malformedFrame('push frame without a numeric req')\n return\n }\n if (frame['sessionId'] !== undefined) {\n shell.send(\n socketErrorAckFor(\n req,\n new A2Error(\n 'INVALID_PAYLOAD',\n 'sessionId is not allowed on a single-session socket',\n ),\n ),\n )\n return\n }\n if (shell.overCap()) {\n shell.send(\n socketErrorAckFor(\n req,\n new A2Error(\n 'STORE_UNAVAILABLE',\n 'push shed: too many in flight on this socket',\n ),\n ),\n )\n return\n }\n shell.track(\n handleSocketPush(\n shell,\n target,\n sessionId,\n frame,\n req,\n undefined,\n options?.gatePush,\n () => streamActivities.get(subscription.iterator)?.activate(),\n ),\n )\n return\n }\n case 'presence':\n if (frame['sessionId'] !== undefined) {\n shell.malformedFrame(\n 'sessionId is not allowed on a single-session socket',\n )\n return\n }\n if (!shell.overCap()) {\n shell.track(\n applySocketPresence(\n shell,\n target,\n sessionId,\n frame,\n options?.gatePush,\n ),\n )\n }\n return\n default:\n return\n }\n }\n\n const shell = socketShell(\n socket,\n () => stopSubscription(subscription),\n handleFrame,\n options?.deadline,\n )\n\n void pumpSubscription({\n shell,\n subscription,\n frameFor: socketFrameFor,\n ...(options?.wire === 2\n ? { batch: (events) => socketEventsFor(events) }\n : {}),\n }).then(\n () => shell.shutdown(1000),\n () => shell.shutdown(1011, 'stream failed'),\n )\n}\n\nconst parseSubscribeEntries = (\n value: unknown,\n): SocketSubscribeEntry[] | null => {\n if (!Array.isArray(value) || value.length === 0) return null\n const entries: SocketSubscribeEntry[] = []\n for (const entry of value) {\n if (entry === null || typeof entry !== 'object') return null\n const { id, attempt, index, bootstrap, reducer } = entry as Record<\n string,\n unknown\n >\n if (typeof id !== 'string' || id.length === 0) return null\n if (\n attempt !== undefined &&\n (typeof attempt !== 'number' ||\n !Number.isSafeInteger(attempt) ||\n attempt < 0)\n )\n return null\n if (\n reducer !== undefined &&\n (typeof reducer !== 'string' || reducer.length === 0)\n )\n return null\n const lane = { id, ...(attempt === undefined ? {} : { attempt }) }\n if (bootstrap === true) {\n if (index !== undefined || typeof reducer !== 'string') return null\n entries.push({ ...lane, bootstrap: true, reducer })\n } else {\n if (\n bootstrap !== undefined ||\n typeof index !== 'number' ||\n !Number.isSafeInteger(index) ||\n index < 0\n )\n return null\n entries.push({\n ...lane,\n index,\n ...(reducer === undefined ? {} : { reducer: reducer as string }),\n })\n }\n }\n return entries\n}\n\n/**\n * Speak the multiplexed A2 socket protocol (specs/a2-api.md §13)\n * against many sessions on one socket. `subscribe` frames open a\n * per-session pump at that session's own resume frontier; push and\n * presence frames route by `sessionId` through the same validation\n * seams as the POST lane; every down frame carries the `sessionId` it\n * belongs to. One heartbeat, one\n * malformed budget, one in-flight bound, one backpressure gauge — per\n * socket, shared by all sessions. A session's stream ending or failing\n * answers `unsubscribed` for that session; only the peer, the\n * deadline, the malformed budget, or backpressure closes the socket.\n */\nexport function sessionsSocket<D extends EventDefs>(\n resolve: SessionsSocketResolve<D>,\n socket: A2Socket,\n options?: SessionsSocketOptions,\n): void {\n const presence = options?.presence === true\n const subscriptions = new Map<string, SocketSubscription>()\n\n const retire = (id: string, subscription: SocketSubscription): void => {\n if (subscriptions.get(id) === subscription) subscriptions.delete(id)\n }\n\n const runSubscription = async (\n id: string,\n subscription: SocketSubscription,\n ): Promise<void> => {\n const { attempt } = subscription\n try {\n await pumpSubscription({\n shell,\n subscription,\n frameFor: (item) => socketFrameFor(item, id),\n ...(options?.wire === 2\n ? { batch: (events) => socketEventsFor(events, id) }\n : {}),\n })\n if (shell.torn() || subscription.stopped) return\n retire(id, subscription)\n shell.send(socketUnsubscribedFor({ sessionId: id, attempt }))\n } catch (error) {\n if (shell.torn() || subscription.stopped) return\n retire(id, subscription)\n shell.send(\n socketUnsubscribedFor({\n sessionId: id,\n attempt,\n reason: 'stream failed',\n error: asA2Error(error),\n }),\n )\n }\n }\n\n const startSubscription = async (\n entry: SocketSubscribeEntry,\n ): Promise<void> => {\n const { id, attempt } = entry\n const index = entry.index ?? 0\n const existing = subscriptions.get(id)\n if (existing) {\n stopSubscription(existing)\n subscriptions.delete(id)\n }\n let session:\n Pick<Session<D>, 'stream'> | Pick<SocketSession, 'stream'> | null\n try {\n session = await resolve(id, index, entry)\n } catch (error) {\n if (!shell.torn()) {\n shell.send(\n socketUnsubscribedFor({\n sessionId: id,\n attempt,\n reason: 'stream failed',\n error: asA2Error(error),\n }),\n )\n }\n return\n }\n if (shell.torn()) return\n if (session === null) {\n shell.send(\n socketUnsubscribedFor({\n sessionId: id,\n attempt,\n reason: 'subscribe rejected',\n error: new A2Error('FORBIDDEN', 'the subscription is not authorized'),\n }),\n )\n return\n }\n const target = session as unknown as SocketSession\n const subscription = socketSubscription({\n target,\n startAfter: index,\n presence,\n attempt,\n })\n subscriptions.set(id, subscription)\n shell.send(socketSubscribedFor({ sessionId: id, attempt }))\n void runSubscription(id, subscription)\n }\n\n // Control frames (subscribe/unsubscribe) run in arrival order — an\n // unsubscribe can never overtake the subscribe it targets while the\n // resolve hook is still pending.\n let controlTail: Promise<void> = Promise.resolve()\n const control = (work: () => Promise<void> | void): void => {\n controlTail = controlTail.then(work).catch(() => {})\n }\n\n const handlePush = async (\n frame: Record<string, unknown>,\n req: number,\n sessionId: string,\n ): Promise<void> => {\n const subscription = subscriptions.get(sessionId)\n if (subscription === undefined) {\n // Retryable: the client re-subscribes on reconnect and the retry\n // rides the same client-generated event ids.\n shell.send(\n socketErrorAckFor(\n req,\n new A2Error(\n 'STORE_UNAVAILABLE',\n 'session is not subscribed on this socket',\n ),\n sessionId,\n ),\n )\n return\n }\n await handleSocketPush(\n shell,\n subscription.target,\n sessionId,\n frame,\n req,\n sessionId,\n options?.gatePush,\n () => {\n const current = subscriptions.get(sessionId)\n if (current) streamActivities.get(current.iterator)?.activate()\n },\n )\n }\n\n const handlePresence = async (\n frame: Record<string, unknown>,\n sessionId: string,\n ): Promise<void> => {\n const subscription = subscriptions.get(sessionId)\n // An unsubscribe race, not malformedness — the plane repaints.\n if (subscription === undefined) return\n await applySocketPresence(\n shell,\n subscription.target,\n sessionId,\n frame,\n options?.gatePush,\n )\n }\n\n const handleFrame = (frame: Record<string, unknown>): void => {\n switch (frame['kind']) {\n case 'subscribe': {\n const entries = parseSubscribeEntries(frame['sessions'])\n if (entries === null) {\n shell.malformedFrame('malformed subscribe frame')\n return\n }\n for (const entry of entries) {\n control(() => startSubscription(entry))\n }\n return\n }\n case 'unsubscribe': {\n const ids = frame['sessions']\n if (\n !Array.isArray(ids) ||\n ids.length === 0 ||\n !ids.every((id) => typeof id === 'string')\n ) {\n shell.malformedFrame('malformed unsubscribe frame')\n return\n }\n for (const id of ids as string[]) {\n control(() => {\n const subscription = subscriptions.get(id)\n if (subscription === undefined) return\n stopSubscription(subscription)\n subscriptions.delete(id)\n })\n }\n return\n }\n case 'push': {\n const req = frame['req']\n const sessionId = frame['sessionId']\n if (shell.overCap()) {\n if (typeof req === 'number') {\n shell.send(\n socketErrorAckFor(\n req,\n new A2Error(\n 'STORE_UNAVAILABLE',\n 'push shed: too many in flight on this socket',\n ),\n typeof sessionId === 'string' ? sessionId : undefined,\n ),\n )\n } else {\n shell.malformedFrame('push frame without a numeric req')\n }\n return\n }\n if (typeof req !== 'number') {\n shell.malformedFrame('push frame without a numeric req')\n return\n }\n if (typeof sessionId !== 'string' || sessionId.length === 0) {\n shell.send(\n socketErrorAckFor(\n req,\n new A2Error('INVALID_PAYLOAD', 'push frame without a sessionId'),\n ),\n )\n return\n }\n shell.track(handlePush(frame, req, sessionId))\n return\n }\n case 'presence': {\n if (shell.overCap()) return\n const sessionId = frame['sessionId']\n if (typeof sessionId !== 'string' || sessionId.length === 0) {\n shell.malformedFrame('presence frame without a sessionId')\n return\n }\n shell.track(handlePresence(frame, sessionId))\n return\n }\n default:\n return // unknown kinds are skipped — the forward-compatibility rule\n }\n }\n\n const shell = socketShell(\n socket,\n () => {\n for (const subscription of subscriptions.values()) {\n stopSubscription(subscription)\n }\n subscriptions.clear()\n },\n (frame) => handleFrame(frame),\n options?.deadline,\n )\n}\n","/**\n * The SSE response protocol — framing, heartbeat, deadline, and\n * teardown for the live stream lane. Internal module: `server.fetch` is\n * the sanctioned caller; the framing rules stay\n * documented on `sseResponse` because the client's parser (and the\n * stall watchdog) depend on them.\n */\n\nimport { STREAM_TIMINGS } from './internal.ts'\nimport type { Event } from './store.ts'\nimport type { PresencePatch, PresenceSnapshot } from './contract.ts'\nimport { invocationDeadlineMs } from './platform.ts'\nimport { streamActivities } from './stream-activity.ts'\nimport {\n isSerializedEvent,\n parseSerializedEvent,\n takeBuffered,\n type HeldEvent,\n} from './stream-buffer.ts'\nimport {\n type StateSnapshotFrame,\n type WireVersion,\n EVENT_WRITE_CHARS,\n compactEventJson,\n heldEventBatch,\n isStreamEvent,\n stateSnapshotToWire,\n eventToWire,\n serializedEventToWireJson,\n presencePatchToWire,\n presenceSnapshotToWire,\n} from './wire.ts'\n\n/**\n * Pipe a live event iterable into an SSE `Response`. Each event is one\n * frame — `id:` carries the event-log index, `data:` the JSON event.\n * Frames for events the iterable already holds are written together. With\n * `wire: 2` those events share one frame instead: `data:` is a JSON array of\n * `CompactWireEvent`s and `id:` the last one's index. A\n * `stream({ presence: true })` iterable also yields presence items,\n * which ride as named frames old clients skip: `event:\n * presence-snapshot` first (the map, ISO dates), then `event: presence`\n * per patch — no `id:`, presence never advances the resume frontier. A\n * disconnecting client cancels the stream, which closes the underlying\n * subscription. Two kinds of comment frames ride along: a `: connected`\n * prelude that flushes headers immediately, and a `: ping` heartbeat\n * every 15 seconds so clients (and proxies) can tell a quiet stream\n * from a dead connection — the session client's stall watchdog counts\n * on it. When the platform exposes an invocation deadline, the response\n * closes cleanly one second before it so the client reconnects without\n * a platform-timeout failure.\n */\nexport function sseResponse(\n iterable: AsyncIterable<\n Event | PresencePatch | PresenceSnapshot | StateSnapshotFrame\n >,\n options: { wire?: WireVersion } = {},\n): Response {\n const write = options.wire === 2 ? batchedFrames : eventFrames\n const iterator = iterable[Symbol.asyncIterator]()\n const encoder = new TextEncoder()\n let heartbeat: ReturnType<typeof setInterval> | undefined\n let deadlineTimer: ReturnType<typeof setTimeout> | undefined\n let closed = false\n let iteratorReturned = false\n let stopActivity: (() => void) | undefined\n const stopTimers = (): void => {\n stopActivity?.()\n stopActivity = undefined\n if (heartbeat !== undefined) clearInterval(heartbeat)\n if (deadlineTimer !== undefined) clearTimeout(deadlineTimer)\n heartbeat = undefined\n deadlineTimer = undefined\n }\n const returnIterator = async (): Promise<void> => {\n if (iteratorReturned) return\n iteratorReturned = true\n await iterator.return?.()\n }\n const stream = new ReadableStream<Uint8Array>({\n start(controller) {\n // Prelude comment frame: flushes headers immediately (a fresh\n // session may otherwise send nothing for a long time — some\n // servers buffer headers until the first byte, and clients can't\n // report \"live\" until they see the response), and gives proxies\n // early proof this is a stream. Comment frames are invisible to\n // SSE consumers.\n controller.enqueue(encoder.encode(': connected\\n\\n'))\n const activity = streamActivities.get(iterator)\n if (activity) {\n const announce = (idle: boolean): void => {\n if (closed) return\n controller.enqueue(\n encoder.encode(\n `event: a2-activity\\ndata: ${idle ? 'idle' : 'active'}\\n\\n`,\n ),\n )\n }\n stopActivity = activity.subscribe(announce)\n if (activity.idle) announce(true)\n }\n // Heartbeat: comment frames are ignored by SSE parsers but are\n // bytes on the wire — liveness proof for the client's watchdog\n // and for idle-timeout-happy intermediaries.\n heartbeat = setInterval(() => {\n try {\n controller.enqueue(encoder.encode(': ping\\n\\n'))\n } catch {\n // The stream closed underneath the timer.\n stopTimers()\n }\n }, STREAM_TIMINGS.sseHeartbeatMs)\n ;(heartbeat as { unref?: () => void }).unref?.()\n\n const invocationDeadline = invocationDeadlineMs()\n if (invocationDeadline !== null) {\n const delay = Math.max(\n 0,\n invocationDeadline - Date.now() - STREAM_TIMINGS.sseDeadlineGraceMs,\n )\n deadlineTimer = setTimeout(() => {\n if (closed) return\n closed = true\n stopTimers()\n void returnIterator().catch(() => {})\n try {\n controller.close()\n } catch {\n // The response already closed underneath the timer.\n }\n }, delay)\n ;(deadlineTimer as { unref?: () => void }).unref?.()\n }\n },\n async pull(controller) {\n try {\n const { value, done } = await iterator.next()\n if (closed) return\n if (done) {\n closed = true\n stopTimers()\n controller.close()\n return\n }\n controller.enqueue(encoder.encode(write(value, iterator)))\n } catch (error) {\n if (closed) return\n closed = true\n stopTimers()\n void returnIterator().catch(() => {})\n throw error\n }\n },\n async cancel() {\n if (closed) return\n closed = true\n stopTimers()\n await returnIterator()\n },\n })\n return new Response(stream, {\n status: 200,\n headers: {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache, no-transform',\n connection: 'keep-alive',\n },\n })\n}\n\ntype StreamItem =\n HeldEvent | PresencePatch | PresenceSnapshot | StateSnapshotFrame\n\n/** Version 1: one frame per event, then each event the iterator holds. */\nfunction eventFrames(first: StreamItem, iterator: object): string {\n let frames = frameFor(first)\n while (frames.length < EVENT_WRITE_CHARS) {\n const event = takeBuffered(iterator)\n if (!event) break\n frames += frameFor(event)\n }\n return frames\n}\n\n/**\n * Version 2: events this write carries share one frame, a JSON array whose\n * `id:` is its last index. Held events are always events, so only `first`\n * can be a snapshot or presence frame.\n */\nfunction batchedFrames(first: StreamItem, iterator: object): string {\n const lead = isStreamEvent(first) ? '' : frameFor(first)\n const head = isStreamEvent(first) ? first : takeBuffered(iterator)\n if (!head) return lead\n const { events, last } = heldEventBatch({\n first: head,\n iterator,\n encode: compactJsonLine,\n })\n return `${lead}id: ${last.index}\\ndata: [${events.join(',')}]\\n\\n`\n}\n\n// JSON.stringify output has no raw line breaks; any other stored text is\n// re-serialized so it stays on its data: line.\nconst compactJsonLine = (event: HeldEvent): string =>\n isSerializedEvent(event) && /[\\r\\n]/.test(event.payloadJson)\n ? compactEventJson(parseSerializedEvent(event))\n : compactEventJson(event)\n\nfunction frameFor(item: StreamItem): string {\n if ('kind' in item)\n return `event: a2-snapshot\\ndata: ${JSON.stringify(stateSnapshotToWire(item))}\\n\\n`\n if ('snapshot' in item) {\n return `event: presence-snapshot\\ndata: ${JSON.stringify(presenceSnapshotToWire(item))}\\n\\n`\n }\n if ('participant' in item) {\n return `event: presence\\ndata: ${JSON.stringify(presencePatchToWire(item))}\\n\\n`\n }\n // JSON.stringify output has no raw line breaks; any other stored text is\n // re-serialized so it stays on its data: line.\n if (isSerializedEvent(item))\n return /[\\r\\n]/.test(item.payloadJson)\n ? `id: ${item.index}\\ndata: ${JSON.stringify(eventToWire(parseSerializedEvent(item)))}\\n\\n`\n : `id: ${item.index}\\ndata: ${serializedEventToWireJson(item)}\\n\\n`\n return `id: ${item.index}\\ndata: ${JSON.stringify(eventToWire(item))}\\n\\n`\n}\n","import type { Event } from './store.ts'\nimport type { PresencePatch, PresenceSnapshot } from './contract.ts'\nimport type { StateSnapshotFrame } from './wire.ts'\nimport { createStreamActivity, streamActivities } from './stream-activity.ts'\nimport { bufferedEvents, takeBuffered } from './stream-buffer.ts'\n\ntype StreamItem = Event | PresencePatch | PresenceSnapshot\n\nexport function bootstrapStream(options: {\n snapshot(): Promise<StateSnapshotFrame>\n stream(index: number): AsyncIterable<StreamItem>\n}): AsyncIterable<StreamItem | StateSnapshotFrame> {\n return {\n [Symbol.asyncIterator]() {\n let closed = false\n let index: number | undefined\n let source: AsyncIterator<StreamItem> | undefined\n let stopActivity: (() => void) | undefined\n const abort = new AbortController()\n const activity = createStreamActivity(() => {\n if (source) streamActivities.get(source)?.activate()\n })\n const iterator: AsyncIterator<StreamItem | StateSnapshotFrame> = {\n async next() {\n if (closed) return { done: true, value: undefined }\n if (index === undefined) {\n let cancel: (() => void) | undefined\n const cancelled = new Promise<undefined>((resolve) => {\n cancel = () => resolve(undefined)\n abort.signal.addEventListener('abort', cancel, { once: true })\n })\n try {\n const snapshot = await Promise.race([\n options.snapshot(),\n cancelled,\n ])\n if (closed || snapshot === undefined)\n return { done: true, value: undefined }\n index = snapshot.index\n return { done: false, value: snapshot }\n } finally {\n if (cancel) abort.signal.removeEventListener('abort', cancel)\n }\n }\n if (!source) {\n source = options.stream(index)[Symbol.asyncIterator]()\n const sourceActivity = streamActivities.get(source)\n if (sourceActivity) {\n activity.setIdle(sourceActivity.idle)\n stopActivity = sourceActivity.subscribe(activity.setIdle)\n }\n }\n const result = await source.next()\n return closed ? { done: true, value: undefined } : result\n },\n async return() {\n if (closed) return { done: true, value: undefined }\n closed = true\n abort.abort()\n stopActivity?.()\n await source?.return?.()\n return { done: true, value: undefined }\n },\n }\n streamActivities.set(iterator, activity)\n bufferedEvents.set(iterator, () =>\n closed || !source ? undefined : takeBuffered(source),\n )\n return iterator\n },\n }\n}\n","import { encodeState } from './reducer-runtime.ts'\nimport type {\n AppendInput,\n ContractEvent,\n EventDefs,\n PresenceDefs,\n} from './contract.ts'\nimport { A2Error } from './errors.ts'\nimport { invocationDeadlineMs } from './platform.ts'\nimport {\n invalidPushBody,\n parsePushBody,\n type ParsedPushEvent,\n type ParsedPushPresence,\n} from './push-envelope.ts'\nimport type { A2Server, Session, SessionAppend } from './server.ts'\nimport {\n sessionSocket,\n sessionsSocket,\n type A2Socket,\n type SocketSession,\n} from './session-socket.ts'\nimport { sseResponse } from './sse.ts'\nimport { bootstrapStream } from './bootstrap-stream.ts'\nimport type { Reducer } from './reducer.ts'\nimport type { SubscriptionStart, WireVersion } from './wire.ts'\nimport {\n asA2Error,\n errorStatus,\n errorToWire,\n eventToWire,\n wireVersion,\n} from './wire.ts'\n\ntype SuggestedEventType<D extends EventDefs> =\n (keyof D & string) | (string & Record<never, never>)\n\ntype SuggestedPresenceValues<P extends PresenceDefs> = Readonly<\n { [F in keyof P & string]?: unknown } & Record<string, unknown>\n>\n\nexport type A2PushEvent<D extends EventDefs = EventDefs> = {\n readonly type: SuggestedEventType<D>\n readonly payload: unknown\n readonly id?: string\n}\n\nexport type A2PushPresence<P extends PresenceDefs = PresenceDefs> = {\n readonly participant: string\n readonly values: SuggestedPresenceValues<P>\n readonly seen?: number\n readonly at?: number\n}\n\nexport type A2Operation<\n D extends EventDefs = EventDefs,\n P extends PresenceDefs = Record<never, never>,\n> =\n | {\n readonly type: 'stream'\n readonly sessionId: string\n readonly startAfter: number\n readonly bootstrap?: true\n readonly transport: 'http' | 'websocket'\n }\n | {\n readonly type: 'history'\n readonly sessionId: string\n readonly gte: number\n readonly lte: number\n readonly transport: 'http'\n }\n | {\n readonly type: 'push'\n readonly sessionId: string\n readonly events: readonly A2PushEvent<D>[]\n readonly presence?: A2PushPresence<P>\n readonly transport: 'http' | 'websocket'\n }\n\nexport type UpgradeWebSocket = (\n attach: (socket: A2Socket) => void,\n) => Response | Promise<Response>\n\nexport type ServerFetchOptions<\n D extends EventDefs = EventDefs,\n P extends PresenceDefs = Record<never, never>,\n> = {\n authorize?: (operation: A2Operation<D, P>) => boolean | Promise<boolean>\n upgradeWebSocket?: UpgradeWebSocket\n /** Allow one upgraded connection to select more than one session. */\n multiplexWebSocket?: boolean\n}\n\nexport type ServerIngressContext = {\n sessionId: string\n events: readonly ParsedPushEvent[]\n presence?: ParsedPushPresence\n}\n\ntype ServerFetchHooks = {\n validateIngress?(context: ServerIngressContext): void | PromiseLike<void>\n}\n\nconst serverFetchHooks = new WeakMap<object, ServerFetchHooks>()\n\nexport function setServerFetchHooks<\n D extends EventDefs,\n P extends PresenceDefs,\n>(server: Pick<A2Server<D, P>, 'fetch'>, hooks: ServerFetchHooks): void {\n serverFetchHooks.set(server.fetch, hooks)\n}\n\ntype FetchServer<D extends EventDefs, P extends PresenceDefs> = {\n contract: A2Server<D, P>['contract']\n session(id: string): Session<D, SessionAppend<D>, P>\n /** Public history plus the latest clear marker when the range includes it. */\n historyPage(\n sessionId: string,\n bounds: { gte: number; lte: number },\n ): Promise<{ events: ContractEvent<D>[]; clearIndex?: number }>\n}\n\ntype ServerFetch<D extends EventDefs, P extends PresenceDefs> = {\n (request: Request): Promise<Response>\n (request: Request, options: ServerFetchOptions<D, P>): Promise<Response>\n}\n\nconst parseHistoryBounds = (\n gte: string | null,\n lte: string | null,\n): { gte: number; lte: number } => {\n if (gte === null || lte === null) {\n throw new A2Error(\n 'INVALID_PAYLOAD',\n 'a history read takes both gte and lte',\n )\n }\n const bounds = { gte: Number(gte), lte: Number(lte) }\n for (const [name, value] of Object.entries(bounds)) {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new A2Error(\n 'INVALID_PAYLOAD',\n `history ${name} must be a non-negative safe integer`,\n )\n }\n }\n if (bounds.gte > bounds.lte) {\n throw new A2Error(\n 'INVALID_PAYLOAD',\n 'history gte must be less than or equal to lte',\n )\n }\n return bounds\n}\n\nconst parseResumeIndex = (raw: string | null): number => {\n if (raw === null) return 0\n const index = Number(raw)\n if (!Number.isSafeInteger(index) || index < 0) {\n throw new A2Error(\n 'INVALID_PAYLOAD',\n 'stream index must be a non-negative safe integer',\n )\n }\n return index\n}\n\nconst parseSubscription = (params: URLSearchParams): SubscriptionStart => {\n const reducer = params.get('reducer')\n const bootstrap = params.get('bootstrap')\n const index = params.get('index')\n if (reducer === '') throw new A2Error('INVALID_PAYLOAD', 'empty reducer name')\n if (bootstrap !== null) {\n if (bootstrap !== '1' || index !== null || reducer === null)\n throw new A2Error(\n 'INVALID_PAYLOAD',\n 'bootstrap requires a reducer and no index',\n )\n return { bootstrap: true, reducer }\n }\n return {\n index: parseResumeIndex(index),\n ...(reducer === null ? {} : { reducer }),\n }\n}\n\nconst errorResponse = (error: unknown): Response => {\n const a2error = asA2Error(error)\n return Response.json(errorToWire(a2error), {\n status: errorStatus(a2error.code),\n })\n}\n\nconst forbidden = (): A2Error =>\n new A2Error('FORBIDDEN', 'the operation is not authorized')\n\nconst freezePush = <D extends EventDefs, P extends PresenceDefs>(\n sessionId: string,\n events: ParsedPushEvent[],\n presence: ParsedPushPresence | undefined,\n transport: 'http' | 'websocket',\n): A2Operation<D, P> & { type: 'push' } => {\n for (const event of events) Object.freeze(event)\n Object.freeze(events)\n if (presence !== undefined) {\n Object.freeze(presence.values)\n Object.freeze(presence)\n }\n return {\n type: 'push',\n sessionId,\n events,\n ...(presence === undefined\n ? {}\n : { presence: presence as A2PushPresence<P> }),\n transport,\n }\n}\n\nexport function createServerFetch<\n D extends EventDefs,\n P extends PresenceDefs = Record<never, never>,\n>(server: FetchServer<D, P>): ServerFetch<D, P> {\n const presence = Object.keys(server.contract.presence).length > 0\n\n const fetch = async (\n request: Request,\n options?: ServerFetchOptions<D, P>,\n ): Promise<Response> => {\n const authorized = async (\n operation: A2Operation<D, P>,\n ): Promise<boolean> => {\n try {\n return (await options?.authorize?.(Object.freeze(operation))) !== false\n } catch (cause) {\n throw new A2Error('STORE_UNAVAILABLE', 'authorization failed', {\n cause,\n })\n }\n }\n\n const authorize = async (operation: A2Operation<D, P>): Promise<void> => {\n if (!(await authorized(operation))) throw forbidden()\n }\n\n const validateIngress = async (\n context: ServerIngressContext,\n ): Promise<void> => {\n await serverFetchHooks.get(fetch)?.validateIngress?.(context)\n }\n\n const gateSocketPush = async (\n sessionId: string,\n events: ParsedPushEvent[],\n pushedPresence?: ParsedPushPresence,\n ): Promise<A2Error | null> => {\n try {\n await authorize(\n freezePush<D, P>(sessionId, events, pushedPresence, 'websocket'),\n )\n await validateIngress({\n sessionId,\n events,\n ...(pushedPresence === undefined ? {} : { presence: pushedPresence }),\n })\n return null\n } catch (error) {\n return asA2Error(error)\n }\n }\n\n const selectedSession = (\n sessionId: string,\n selection: SubscriptionStart,\n ): SocketSession => {\n const reducer = server.contract.reducer\n if (\n selection.reducer !== undefined &&\n reducer !== undefined &&\n reducer.name !== selection.reducer\n )\n throw new A2Error(\n 'INVALID_PAYLOAD',\n 'client reducer does not match the public contract reducer',\n )\n const target = server.session(sessionId)\n const streamTarget = target as unknown as SocketSession\n if (!selection.bootstrap) return streamTarget\n if (!reducer)\n throw new A2Error('INVALID_PAYLOAD', 'contract has no public reducer')\n return {\n ...streamTarget,\n stream: (streamOptions) =>\n bootstrapStream({\n snapshot: async () => {\n const initial = await target.state(\n reducer as unknown as Reducer<D, unknown>,\n )\n return {\n kind: 'snapshot',\n sessionId,\n name: reducer.name,\n index: initial.index,\n state: encodeState({ reducer, state: initial.state }),\n ...(initial.clearIndex === undefined\n ? {}\n : { clearIndex: initial.clearIndex }),\n }\n },\n stream: (index) => {\n const bounds = {\n startAfter: index,\n presence: streamOptions.presence === true,\n }\n return target.stream(bounds)\n },\n }),\n }\n }\n\n const attachMultiplexed =\n (wire: WireVersion) =>\n (socket: A2Socket): void => {\n const deadline = invocationDeadlineMs()\n sessionsSocket<D>(\n async (sessionId, startAfter, selection = { index: startAfter }) => {\n const operation: A2Operation<D, P> = {\n type: 'stream',\n sessionId,\n startAfter,\n ...(selection.bootstrap ? { bootstrap: true as const } : {}),\n transport: 'websocket',\n }\n return (await authorized(operation))\n ? selectedSession(sessionId, selection)\n : null\n },\n socket,\n {\n presence,\n wire,\n ...(deadline === null ? {} : { deadline }),\n gatePush: gateSocketPush,\n },\n )\n }\n\n try {\n if (request.method === 'GET') {\n if (request.headers.get('upgrade')?.toLowerCase() === 'websocket') {\n if (options?.upgradeWebSocket === undefined) {\n return new Response(\n 'WebSocket upgrade requested, but server.fetch() has no upgrade implementation',\n { status: 426 },\n )\n }\n const { searchParams } = new URL(request.url)\n const wire = wireVersion(searchParams.get('wire'))\n if (options.multiplexWebSocket === true) {\n return await options.upgradeWebSocket(attachMultiplexed(wire))\n }\n\n const sessionId = searchParams.get('sessionId')\n if (sessionId === null || sessionId.length === 0) {\n throw new A2Error('INVALID_PAYLOAD', 'missing sessionId')\n }\n const selection = parseSubscription(searchParams)\n const startAfter = selection.index ?? 0\n await authorize({\n type: 'stream',\n sessionId,\n startAfter,\n ...(selection.bootstrap ? { bootstrap: true as const } : {}),\n transport: 'websocket',\n })\n const target = selectedSession(sessionId, selection)\n const attach = (socket: A2Socket): void => {\n const deadline = invocationDeadlineMs()\n sessionSocket(sessionId, target, socket, {\n startAfter,\n presence,\n wire,\n ...(deadline === null ? {} : { deadline }),\n gatePush: gateSocketPush,\n })\n }\n return await options.upgradeWebSocket(attach)\n }\n\n const { searchParams } = new URL(request.url)\n const sessionId = searchParams.get('sessionId')\n if (sessionId === null || sessionId.length === 0) {\n throw new A2Error('INVALID_PAYLOAD', 'missing sessionId')\n }\n const gteRaw = searchParams.get('gte')\n const lteRaw = searchParams.get('lte')\n if (gteRaw !== null || lteRaw !== null) {\n const bounds = parseHistoryBounds(gteRaw, lteRaw)\n await authorize({\n type: 'history',\n sessionId,\n ...bounds,\n transport: 'http',\n })\n const { events, clearIndex } = await server.historyPage(\n sessionId,\n bounds,\n )\n const first = Math.max(bounds.gte, (clearIndex ?? 0) + 1)\n const covered = events.length === Math.max(0, bounds.lte - first + 1)\n return Response.json(events.map(eventToWire), {\n headers: {\n 'a2-history-covered': String(covered),\n ...(clearIndex === undefined\n ? {}\n : { 'a2-clear-index': String(clearIndex) }),\n },\n })\n }\n\n const selection = parseSubscription(searchParams)\n const startAfter = selection.index ?? 0\n await authorize({\n type: 'stream',\n sessionId,\n startAfter,\n ...(selection.bootstrap ? { bootstrap: true as const } : {}),\n transport: 'http',\n })\n const target = selectedSession(sessionId, selection)\n return sseResponse(\n presence\n ? target.stream({ startAfter, presence: true })\n : target.stream({ startAfter }),\n { wire: wireVersion(searchParams.get('wire')) },\n )\n }\n\n if (request.method === 'POST') {\n const body = await parsePushBody(request)\n await authorize(\n freezePush<D, P>(body.sessionId, body.events, body.presence, 'http'),\n )\n await validateIngress({\n sessionId: body.sessionId,\n events: body.events,\n ...(body.presence === undefined ? {} : { presence: body.presence }),\n })\n const session = server.session(body.sessionId)\n if (body.presence !== undefined) {\n const target = session as unknown as SocketSession\n if (typeof target.setPresence !== 'function') {\n throw invalidPushBody('presence is not declared by this contract')\n }\n await target.setPresence(body.presence)\n }\n const appended: ContractEvent<D>[] =\n body.events.length === 0\n ? []\n : await session.append(\n ...(body.events as unknown as AppendInput<D>[]),\n )\n return Response.json(appended.map(eventToWire))\n }\n\n return new Response('Method Not Allowed', {\n status: 405,\n headers: { allow: 'GET, POST' },\n })\n } catch (error) {\n return errorResponse(error)\n }\n }\n return fetch\n}\n","/**\n * Deterministic default ids for consumer `session.append` calls. A consumer\n * re-run after a crash calls `session.append` again; giving\n * each call a deterministic id — derived from the triggering event's id\n * and the caller's stable name — makes the re-run a no-op via the store's\n * per-session unique index on event ids.\n *\n * The id is a UUIDv5-shaped SHA-1 over\n * `(namespace, triggerEventId, name, itemOrdinal)`, computed with\n * WebCrypto so it runs on any platform a2 core targets.\n */\n\nconst APPEND_NAMESPACE = 'a2:handler-append:v2'\nconst RETURN_NAMESPACE = 'a2:handler-return:v1'\nconst SCHEDULE_NAMESPACE = 'a2:schedule:v1'\nconst SCHEDULED_EVENT_NAMESPACE = 'a2:scheduled-event:v1'\nconst SCHEDULE_CLEAR_NAMESPACE = 'a2:schedule-clear:v1'\n\nasync function deterministicIdFromInput(input: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n 'SHA-1',\n new TextEncoder().encode(input),\n )\n const bytes = new Uint8Array(digest).slice(0, 16)\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x50\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`\n}\n\nasync function deterministicId(parts: Array<string | number>): Promise<string> {\n return deterministicIdFromInput(parts.join('\\u0000'))\n}\n\n/**\n * `consumer` keys the id on the consumer that appends, so two consumers of\n * one event never collide. A2's own consumers pass none: their types are\n * disjoint, so the event alone keys them.\n */\nexport async function deterministicEventId(\n triggerEventId: string,\n name: string,\n itemOrdinal: number,\n consumer?: string,\n): Promise<string> {\n if (name.length === 0) throw new TypeError('append name must not be empty')\n return deterministicId([\n APPEND_NAMESPACE,\n triggerEventId,\n name,\n itemOrdinal,\n ...(consumer === undefined ? [] : [consumer]),\n ])\n}\n\nexport async function deterministicReturnedEventId(\n triggerEventId: string,\n itemOrdinal: number,\n consumer?: string,\n): Promise<string> {\n return deterministicId([\n RETURN_NAMESPACE,\n triggerEventId,\n itemOrdinal,\n ...(consumer === undefined ? [] : [consumer]),\n ])\n}\n\n/**\n * The id of a scheduled append. `clearIndex` is the lifetime the trigger was\n * claimed in; it joins the input only when positive, so a trigger id reused\n * after a clear schedules a distinct task while sessions never cleared keep\n * the ids they always had.\n */\nexport async function deterministicScheduleId(\n contract: string,\n sessionId: string,\n triggerEventId: string | null,\n name: string,\n clearIndex = 0,\n consumer?: string,\n): Promise<string> {\n return deterministicIdFromInput(\n JSON.stringify([\n SCHEDULE_NAMESPACE,\n contract,\n sessionId,\n triggerEventId,\n name,\n ...(clearIndex > 0 ? [clearIndex] : []),\n ...(consumer === undefined ? [] : [{ consumer }]),\n ]),\n )\n}\n\nexport async function deterministicScheduleClearId({\n contract,\n sessionId,\n triggerEventId,\n clearIndex,\n name,\n ifLastIndex,\n consumer,\n}: {\n contract: string\n sessionId: string\n triggerEventId: string | null\n clearIndex: number\n name: string\n ifLastIndex: number\n consumer?: string\n}): Promise<string> {\n return deterministicIdFromInput(\n JSON.stringify([\n SCHEDULE_CLEAR_NAMESPACE,\n contract,\n sessionId,\n triggerEventId,\n clearIndex,\n name,\n ifLastIndex,\n ...(consumer === undefined ? [] : [{ consumer }]),\n ]),\n )\n}\n\nexport async function deterministicScheduledEventId(\n scheduleId: string,\n itemOrdinal: number,\n): Promise<string> {\n return deterministicId([SCHEDULED_EVENT_NAMESPACE, scheduleId, itemOrdinal])\n}\n","/**\n * The A2Telemetry interface — the instrumentation seam. Same philosophy\n * as store backends: the interface lives in core, implementations ship as\n * entry points (`experimental-a2/otel` adapts it to OpenTelemetry). Without\n * one, spans are free and swallowed errors print to the console.\n */\n\n/** Attribute values a2 emits. */\nexport type A2AttributeValue = string | number | boolean\n\n/** The spans a2 emits today. The catalogue grows with the surface. */\nexport type A2SpanName =\n | 'a2.append'\n | 'a2.drain'\n | 'a2.event'\n | 'a2.claim'\n | 'a2.commit'\n | 'a2.state'\n | 'a2.snapshot'\n | 'a2.redrive'\n | 'a2.consume'\n | 'a2.ai.control'\n | 'a2.ai.ack'\n | 'a2.ai.generate'\n | 'a2.ai.context'\n | 'a2.ai.compaction'\n | 'a2.ai.tool'\n\nexport type A2SpanHandle = {\n /** Attach or update an attribute mid-span (e.g. the outcome). */\n setAttribute(key: string, value: A2AttributeValue): void\n /**\n * Mark the span failed without a2's control flow throwing — used for\n * consumer failures, which a2 swallows by design (they go into the\n * retry machinery, not up the stack) but telemetry must still see.\n */\n recordError(error: unknown): void\n}\n\nexport type A2Telemetry = {\n /**\n * Wrap one unit of a2 work. Implementations should time it, record a\n * thrown error as a failure, propagate context so nested spans tree\n * up, and always return `fn`'s result (or rethrow its error) —\n * telemetry observes, it never alters behavior.\n */\n span<T>(\n name: A2SpanName,\n attributes: Record<string, A2AttributeValue>,\n fn: (span: A2SpanHandle) => Promise<T>,\n ): Promise<T>\n}\n\n/**\n * The default when no telemetry is configured. Spans cost nothing, but\n * `recordError` prints: it only ever receives errors a2 swallows by\n * design, so without a configured sink the console is the one place\n * they can surface. Passing `telemetry` replaces this sink wholesale.\n */\nexport const CONSOLE_TELEMETRY: A2Telemetry = {\n span: (name, attributes, fn) =>\n fn({\n setAttribute: () => {},\n recordError: (error) => {\n // oxlint-disable-next-line no-console -- the whole point: swallowed errors must surface without configuration\n console.error(`[a2] error in ${name}`, attributes, error)\n },\n }),\n}\n","import { decodeState, encodeState } from './reducer-runtime.ts'\n// oxlint-disable no-await-in-loop -- scheduler advances after durable outcomes\n/**\n * experimental-a2/server — where a contract is implemented. `createServer({\n * contract, store, consumers, ... })` binds the vocabulary to storage and\n * reactions; sessions, drains, claims, and scheduler all live here.\n * Server-only by construction: this entry point is the only one that\n * can reach a store backend, and its exports map fails loudly in browser\n * bundles.\n */\n\nimport type {\n AppendInput,\n Contract,\n ContractEvent,\n EventDefs,\n PresenceDefs,\n PresenceMap,\n PresencePatch,\n PresenceSnapshot,\n WithPresence,\n} from './contract.ts'\nimport { A2Error, NonRetriableError, asStoreUnavailable } from './errors.ts'\nimport {\n DRAIN_TIMINGS,\n POLL_TIMINGS,\n MAX_DATE_MS,\n failedPreviousAttempt,\n RESERVED_PARTICIPANT_IDS,\n STATE_CACHE,\n markSchedulerSendFailure,\n stateTailReaders,\n nullProtoRecord,\n runtimeConsumerFactory,\n runtimeConsumers,\n serverInternals,\n drainSettledHooks,\n type DrainOutcome,\n type DrainResult,\n} from './internal.ts'\nimport {\n isSessionCleared,\n sessionClearedError,\n type SessionCleared,\n} from './session-clear.ts'\nimport { boundedCache } from './bounded-cache.ts'\nimport { presenceTombstones } from './presence-tombstones.ts'\nimport { defaultSleep, type Sleeper } from './store-polling.ts'\nimport { createStreamActivity, streamActivities } from './stream-activity.ts'\nimport {\n bufferedEvents,\n isSerializedEvent,\n takeBuffered,\n} from './stream-buffer.ts'\nimport type {\n A2Store,\n CompleteAttemptResult,\n AppendEvent,\n Event,\n EventCause,\n EventTarget,\n HeadEvent,\n HeadRef,\n StoreConsumer,\n StoreClaimAvailableResult,\n StoreClearResult,\n StoreReclaimResult,\n StoreRedriveResult,\n StoreSnapshotWrite,\n StoreStateRead,\n PresenceRow,\n ReturnedEvent,\n StoredEvent,\n} from './store.ts'\nimport {\n cloneInitial,\n foldEvent,\n type Reducer,\n type RegisteredReducer,\n} from './reducer.ts'\ntype PublicState<R> = undefined extends R\n ? never\n : R extends { initialState: infer S }\n ? S\n : never\nimport {\n createServerFetch,\n type A2Operation,\n type A2PushEvent,\n type A2PushPresence,\n type ServerFetchOptions,\n type UpgradeWebSocket,\n} from './server-fetch.ts'\nimport { validateSync } from './validate.ts'\nimport {\n deterministicEventId,\n deterministicReturnedEventId,\n deterministicScheduledEventId,\n deterministicScheduleClearId,\n deterministicScheduleId,\n} from './deterministic-id.ts'\nimport { invocationDeadlineMs, platformWaitUntil } from './platform.ts'\nimport { retryableLazy } from './retryable-lazy.ts'\nimport type {\n ScheduledEvent,\n SchedulerAppendTask,\n SchedulerClearTask,\n SchedulerTask,\n} from './scheduler-task.ts'\nimport {\n CONSOLE_TELEMETRY,\n type A2SpanHandle,\n type A2Telemetry,\n} from './telemetry.ts'\n\n/** What every consumer's `run` receives. */\nexport type ConsumerContext<\n D extends EventDefs,\n K extends keyof D & string = keyof D & string,\n P extends PresenceDefs = Record<never, never>,\n S = never,\n> = {\n /** The triggering event. */\n event: ContractEvent<D, K>\n /** Durable, 1-based dispatch ordinal for this event. */\n attempt: number\n /** This session, with consumer-scoped idempotent append. */\n session: Session<D, ConsumerAppend<D>, P, S>\n /** Fires on `abortOn` events (cancellation slice); dormant otherwise. */\n signal: AbortSignal\n}\n\nexport type LaneContext<\n D extends EventDefs,\n K extends keyof D & string = keyof D & string,\n> = {\n sessionId: string\n event: Pick<ContractEvent<D, K>, 'type' | 'payload'> & { id?: string }\n}\n\n/**\n * A consumer's lane: a string runs every event it takes in log order on one\n * cursor; a function returns each event's lane, or null to run it\n * concurrently.\n */\nexport type ConsumerLane<\n D extends EventDefs,\n K extends keyof D & string = keyof D & string,\n> = string | ((context: LaneContext<D, K>) => string | null)\n\nexport type SessionDispatch<D extends EventDefs> = (\n ...events: AppendInput<D>[]\n) => Promise<ContractEvent<D>[]>\n\nexport type SessionAppend<D extends EventDefs> = SessionDispatch<D> & {\n /** Commit, then hand pending work directly to configured scheduler. */\n dispatch: SessionDispatch<D>\n}\n\nexport type ConsumerAppend<D extends EventDefs> = (\n name: string,\n ...events: AppendInput<D>[]\n) => Promise<ContractEvent<D>[]>\n\nexport type ScheduleDelay = `${number}${'ms' | 's' | 'm' | 'h' | 'd'}`\n\nexport type ScheduleTiming =\n { delay: ScheduleDelay; at?: never } | { at: Date; delay?: never }\n\nexport type SessionSchedule<D extends EventDefs> = {\n (\n name: string,\n timing: ScheduleTiming,\n ...events: AppendInput<D>[]\n ): Promise<void>\n /**\n * Publish a durable conditional clear. Delivery clears only while\n * `ifLastIndex` is still the head, and finishes deleting before it\n * acknowledges.\n */\n clear(\n name: string,\n options: ScheduleTiming & { ifLastIndex: number },\n ): Promise<void>\n}\n\nexport type StateOptions = {\n through?: number | 'latest'\n}\n\nexport type SessionClearOptions = {\n /** Clear only while this is the head; a mismatch changes nothing. */\n ifLastIndex?: number\n}\n\nexport type SessionClearResult = { cleared: boolean; index: number }\n\nexport type SessionRedriveOptions = {\n /** `retry` runs the consumer again with a fresh failure budget; `skip` settles the event without running it. */\n action: 'retry' | 'skip'\n}\n\nexport type SessionRedriveResult = {\n /** Whether the event was dead-lettered and is now resolved. */\n redriven: boolean\n}\n\nexport type SessionConsumeOptions = {\n /**\n * Run until the consumer has handled every event it takes through this\n * index. Default: the session's head when the call starts. An index past\n * the head counts as the head.\n */\n through?: number\n /** Stops waiting: the call throws the signal's reason. */\n signal?: AbortSignal\n}\n\nexport type SessionConsumeResult = {\n /** The consumer has handled every event it takes through this index. */\n index: number\n}\n\n/** A dead-lettered event, with what an operator needs to resolve it. */\nexport type DeadLetter<D extends EventDefs> = ContractEvent<D> & {\n /** The consumer this event is dead for; it may be done for others. */\n consumer: string\n lane: string | null\n /** Durable dispatch claims, including claims abandoned by hard kills. */\n attemptCount: number\n /**\n * Failed attempts since the event was appended or last retried: caught\n * consumer failures, and attempts that ended before they finished.\n */\n failureCount: number\n /**\n * The last error the consumer threw, stringified; null when every failed\n * attempt ended before it finished.\n */\n lastError: string | null\n failedAt: Date\n}\n\n/** Dead-letter resolution; root sessions only. */\nexport type SessionDeadLetters<D extends EventDefs> = {\n /** The session's dead-lettered events, oldest first. */\n deadLetters(): Promise<DeadLetter<D>[]>\n /**\n * Atomically resolve one dead-lettered event, then wake the session like\n * an append. Any other event is left alone and reports `redriven: false`.\n */\n redrive(\n target: { consumer: string; index: number },\n options: SessionRedriveOptions,\n ): Promise<SessionRedriveResult>\n}\n\n/**\n * The presence members of a session — intersected in via\n * `WithPresence`, so they exist exactly when the contract declares\n * presence fields. Intersected before the base members so the widened\n * `stream` overload is tried first: the literal `presence: true`\n * selects it, everything else falls through to the events-only base.\n */\nexport type SessionPresence<D extends EventDefs, P extends PresenceDefs> = {\n /**\n * The two-plane feed: one snapshot of the current pruned map first\n * (per-field stamps exact), then presence patches interleaved with\n * events.\n */\n stream(opts: {\n startAfter?: number\n presence: true\n }): AsyncIterable<\n ContractEvent<D> | SessionCleared | PresencePatch<P> | PresenceSnapshot<P>\n >\n /**\n * Validate against the contract's presence schemas, then broadcast.\n * Never an append: no log row, no dispatch, no scheduler arm. `at`\n * is the sender's LWW stamp in epoch ms; omitted, receipt time\n * stands in (single writer, so receipt order is sender order).\n */\n setPresence(patch: {\n participant: string\n values: PresencePatch<P>['values']\n seen?: number\n at?: number\n }): Promise<void>\n /** The current map, expired values pruned — a point-in-time read. */\n presence(): Promise<PresenceMap<P>>\n}\n\n/** A handle on one instance of the machine. Creating it does no I/O. */\nexport type Session<\n D extends EventDefs,\n Append = SessionAppend<D>,\n P extends PresenceDefs = Record<never, never>,\n S = never,\n> = WithPresence<P, SessionPresence<D, P>> & {\n readonly id: string\n append: Append\n schedule: SessionSchedule<D>\n /**\n * End the current lifetime: atomically append a clear marker, then\n * delete the history below it. Indexes never restart.\n */\n clear(options?: SessionClearOptions): Promise<SessionClearResult>\n history(options?: { gte?: number; lte?: number }): Promise<ContractEvent<D>[]>\n /**\n * Run a consumer with a string lane on this session, here, until it has\n * handled every event it takes through `through`. The server's own\n * consumer shares its cursor with background work, so this waits for\n * whichever invocation holds it. A consumer the server doesn't run is\n * pulled only by `consume`, and keeps its place between calls.\n */\n consume(\n consumer: Consumer<D>,\n options?: SessionConsumeOptions,\n ): Promise<SessionConsumeResult>\n state: {\n <T>(\n reducer: Reducer<D, T, Record<never, never>>,\n options?: StateOptions,\n ): Promise<{ state: T; index: number; clearIndex?: number }>\n } & ([S] extends [never]\n ? unknown\n : { (): Promise<{ state: S; index: number; clearIndex?: number }> })\n /**\n * A live feed of this session's events, starting after `startAfter`\n * (exclusive). Server-side only. `server.fetch` exposes it over SSE.\n * A clear arrives as a `SessionCleared` marker.\n */\n stream(opts?: {\n startAfter?: number\n }): AsyncIterable<ContractEvent<D> | SessionCleared>\n}\n\n/**\n * The public server shape scheduler consumers accept. It stays structural so\n * servers of any contract mix in one route; A2's private server internals add\n * delayed-append delivery without exposing an untyped append method here.\n */\nexport type DrainableServer = {\n readonly contract: { readonly name: string }\n drain(sessionId: string): Promise<{ settled: boolean }>\n}\n\n/**\n * The scheduler seam (a2-implementation.md §7, §9). `schedule` puts a\n * versioned drain or delayed append task on durable infrastructure;\n * `handler` returns the route the transport delivers to. Claim holders\n * move the watchdog alongside their renewable execution window.\n * Implementations ship as\n * entry points (`experimental-a2/scheduler-vercel`); core never imports a\n * transport.\n */\nexport type A2Scheduler = {\n schedule(task: SchedulerTask): Promise<void>\n handler(...servers: DrainableServer[]): (req: Request) => Promise<Response>\n}\n\nexport type A2Server<\n D extends EventDefs,\n P extends PresenceDefs = Record<never, never>,\n R extends RegisteredReducer<D, P> | undefined =\n RegisteredReducer<D, P> | undefined,\n> = {\n /** The contract this server implements. */\n readonly contract: Contract<D, P, R>\n readonly fetch: {\n (request: Request): Promise<Response>\n (request: Request, options: ServerFetchOptions<D, P>): Promise<Response>\n }\n session(\n id: string,\n ): Session<D, SessionAppend<D>, P, PublicState<R>> & SessionDeadLetters<D>\n /**\n * Process every currently eligible event. `settled` means nothing\n * actionable remains, including work blocked behind a dead letter.\n */\n drain(sessionId: string): Promise<{ settled: boolean }>\n}\n\nexport type {\n A2Operation,\n A2PushEvent,\n A2PushPresence,\n ServerFetchOptions,\n UpgradeWebSocket,\n}\nexport type { A2Socket } from './session-socket.ts'\n\n/**\n * Deliver one authenticated scheduler append through an A2 server's ordinary\n * top-level append path. Custom scheduler adapters call this after validating\n * their transport envelope; application code normally uses `session.schedule`.\n */\nexport async function deliverSchedulerAppend(\n server: DrainableServer,\n task: SchedulerAppendTask,\n): Promise<void> {\n if (server.contract.name !== task.contract) {\n throw new TypeError(\n `a2 scheduler: append task for contract '${task.contract}' cannot be delivered to '${server.contract.name}'`,\n )\n }\n const { originIndex } = task\n // A malformed origin would read as cleared and drop the events silently.\n if (\n originIndex !== undefined &&\n (!Number.isSafeInteger(originIndex) || originIndex < 1)\n ) {\n throw new TypeError(\n 'a2 scheduler: append task originIndex must be a positive safe integer',\n )\n }\n const internals = serverInternals.get(server)\n if (!internals) {\n throw new TypeError(\n `a2 scheduler: server for contract '${task.contract}' cannot receive scheduled appends`,\n )\n }\n await internals.schedulerAppend(task.sessionId, task.events, originIndex)\n}\n\n/**\n * Deliver one authenticated scheduler clear: a conditional\n * `clear({ ifLastIndex })` that resolves after its deletion finishes, so a\n * provider retry resumes an interrupted deletion. Custom scheduler adapters\n * call this after validating their transport envelope; application code uses\n * `session.schedule.clear`.\n */\nexport async function deliverSchedulerClear(\n server: DrainableServer,\n task: SchedulerClearTask,\n): Promise<void> {\n if (server.contract.name !== task.contract) {\n throw new TypeError(\n `a2 scheduler: clear task for contract '${task.contract}' cannot be delivered to '${server.contract.name}'`,\n )\n }\n // Without its condition a clear task would erase the whole session.\n if (\n task.kind !== 'clear' ||\n !Number.isSafeInteger(task.ifLastIndex) ||\n task.ifLastIndex < 0\n ) {\n throw new TypeError(\n 'a2 scheduler: a clear task needs kind \"clear\" and a non-negative safe integer ifLastIndex',\n )\n }\n const internals = serverInternals.get(server)\n if (!internals) {\n throw new TypeError(\n `a2 scheduler: server for contract '${task.contract}' cannot receive scheduled clears`,\n )\n }\n await internals.schedulerClear(task.sessionId, task.ifLastIndex)\n}\n\n/**\n * Which events fire `ctx.signal` while a consumer runs — the preemption\n * channel for user cancellation. The array form matches by type; the\n * object form takes per-type predicates for targeted cancellation\n * (`(event, trigger) => event.payload.of === trigger.id`). Consumers\n * without `abortOn` pay nothing. An aborted consumer should catch and\n * return normally; throwing means \"retry me\".\n */\nexport type AbortSpec<D extends EventDefs, K extends keyof D & string> =\n | Array<keyof D & string>\n | {\n [T in keyof D & string]?:\n | true\n | ((\n event: ContractEvent<D, T>,\n trigger: ContractEvent<D, K>,\n context: { attempt: number },\n ) => boolean)\n }\n\n/** What a consumer's `run` returns: nothing, one event, or a batch. */\nexport type ConsumerResult<D extends EventDefs> = Promise<\n void | AppendInput<D> | readonly AppendInput<D>[]\n>\n\n/** How `createServer` runs a consumer. Built by `consumer().run()`. */\nexport type ConsumerSpec<D extends EventDefs> = {\n readonly types: readonly (keyof D & string)[] | null\n readonly lane: ConsumerLane<D> | null\n readonly backfill: boolean\n readonly abortOn: AbortSpec<D, keyof D & string> | null\n readonly run: (ctx: ConsumerContext<D>) => ConsumerResult<D>\n}\n\n/** A named reader of a session's log with its own durable cursors. */\nexport type Consumer<D extends EventDefs> = {\n readonly name: string\n readonly contract: { readonly name: string }\n readonly spec: ConsumerSpec<D>\n}\n\nexport type ConsumerOptions<\n D extends EventDefs,\n P extends PresenceDefs,\n R extends RegisteredReducer<D, P> | undefined,\n K extends keyof D & string,\n> = {\n /** The contract whose events it reads. */\n contract: Contract<D, P, R>\n /** Its identity, unique per server. A new name is a new consumer. */\n name: string\n /** The event types it runs on; default every type. */\n types?: readonly K[]\n /** Omitted: concurrent. A string: one ordered lane. A function: per event. */\n lane?: ConsumerLane<D, K>\n /** A new consumer starts at the beginning of the log. Needs a string lane. */\n backfill?: boolean\n abortOn?: AbortSpec<D, K>\n}\n\n/**\n * A consumer written in `createServer({ consumers })`: `consumer()`'s\n * options without the contract, which is the server's, and its `run`.\n */\nexport type InlineConsumer<\n D extends EventDefs,\n P extends PresenceDefs,\n R extends RegisteredReducer<D, P> | undefined,\n K extends keyof D & string,\n> = Omit<ConsumerOptions<D, P, R, K>, 'contract'> & {\n run: (ctx: ConsumerContext<D, K, P, PublicState<R>>) => ConsumerResult<D>\n}\n\n/** The types an inline consumer takes: the ones it lists, or every type. */\ntype InlineTypes<D extends EventDefs, X> = unknown extends X\n ? keyof D & string\n : Extract<X, keyof D & string>\n\n/**\n * `createServer`'s consumers: each a `consumer()` or written inline. `C` is\n * inferred per entry, so an inline `run` sees only the types it lists.\n */\nexport type ServerConsumers<\n D extends EventDefs,\n P extends PresenceDefs,\n R extends RegisteredReducer<D, P> | undefined,\n C extends readonly unknown[],\n> = {\n readonly [I in keyof C]:\n InlineConsumer<D, P, R, InlineTypes<D, C[I]>> | Extract<C[I], Consumer<D>>\n}\n\nconst CONSUMER_NAME = /^[a-z0-9][a-z0-9._:-]{0,127}$/i\n\n/** Define a consumer: a named reader of each session's log. */\nexport function consumer<\n D extends EventDefs,\n P extends PresenceDefs,\n R extends RegisteredReducer<D, P> | undefined,\n const K extends keyof D & string = keyof D & string,\n>(\n options: ConsumerOptions<D, P, R, K>,\n): {\n run(\n fn: (ctx: ConsumerContext<D, K, P, PublicState<R>>) => ConsumerResult<D>,\n ): Consumer<D>\n} {\n return defineConsumer(options, false)\n}\n\n/**\n * `consumer()`, and for A2's own runtimes (`runtime`) a name under `a2.` and\n * child ids without the name: their types are disjoint, so the event alone\n * keys them, and regrouping A2's consumers never changes an id.\n */\nfunction defineConsumer<\n D extends EventDefs,\n P extends PresenceDefs,\n R extends RegisteredReducer<D, P> | undefined,\n const K extends keyof D & string = keyof D & string,\n>(\n options: ConsumerOptions<D, P, R, K>,\n runtime: boolean,\n): {\n run(\n fn: (ctx: ConsumerContext<D, K, P, PublicState<R>>) => ConsumerResult<D>,\n ): Consumer<D>\n} {\n const contract = options?.contract\n if (!contract || typeof contract.name !== 'string') {\n throw new TypeError('consumer expects options with a contract')\n }\n const consumerName = options.name\n if (typeof consumerName !== 'string' || !CONSUMER_NAME.test(consumerName)) {\n throw new TypeError(\n 'consumer name must be 1-128 letters, digits, and . _ : - characters',\n )\n }\n if (consumerName.startsWith('a2.') !== runtime) {\n throw new TypeError(\n runtime\n ? `A2's own consumers are named under 'a2.'`\n : `consumer names starting with 'a2.' are reserved`,\n )\n }\n const types = options.types === undefined ? null : [...options.types]\n if (types?.length === 0) {\n throw new TypeError(\n `consumer '${consumerName}' lists no types; leave types out to take every type`,\n )\n }\n for (const type of types ?? []) {\n if (!Object.hasOwn(contract.events, type)) {\n throw new TypeError(\n `contract '${contract.name}' has no event type '${String(type)}'`,\n )\n }\n }\n const lane = options.lane ?? null\n if (\n lane !== null &&\n typeof lane !== 'function' &&\n (typeof lane !== 'string' || lane.length === 0)\n ) {\n throw new TypeError(\n `lane for consumer '${consumerName}' must be a non-empty string or a function`,\n )\n }\n const backfill = options.backfill ?? false\n if (backfill && typeof lane !== 'string') {\n throw new TypeError(\n `consumer '${consumerName}' backfills, so its lane must be a string`,\n )\n }\n // Cancellation is for work in progress. Checking it while replaying\n // history would read the rest of the log for every event replayed.\n if (backfill && options.abortOn !== undefined) {\n throw new TypeError(\n `consumer '${consumerName}' backfills, so it can't use abortOn`,\n )\n }\n return {\n run(fn) {\n if (typeof fn !== 'function') {\n throw new TypeError(`consumer '${consumerName}' needs a run function`)\n }\n const defined: Consumer<D> = {\n name: consumerName,\n contract: { name: contract.name },\n spec: {\n types,\n lane: lane as ConsumerLane<D> | null,\n backfill,\n abortOn: (options.abortOn ?? null) as AbortSpec<\n D,\n keyof D & string\n > | null,\n run: fn as unknown as (ctx: ConsumerContext<D>) => ConsumerResult<D>,\n },\n }\n if (runtime) runtimeConsumers.add(defined)\n return defined\n },\n }\n}\nruntimeConsumerFactory.define = (options) =>\n defineConsumer(options as Parameters<typeof consumer>[0], true)\n\n/** A registered consumer as the store needs to know it. */\nconst storeConsumerOf = (registered: {\n name: string\n log: StoreConsumer['log']\n}): StoreConsumer =>\n registered.log\n ? { name: registered.name, log: registered.log }\n : { name: registered.name }\n\nexport type ServerOptions<\n D extends EventDefs,\n P extends PresenceDefs = Record<never, never>,\n R extends RegisteredReducer<D, P> | undefined =\n RegisteredReducer<D, P> | undefined,\n C extends readonly unknown[] = readonly Consumer<D>[],\n> = {\n /** The contract this server implements (see `a2.contract`). */\n contract: Contract<D, P, R>\n /** Where events live. Defaults: sqlite in dev, memory in tests, required in prod. */\n store?: A2Store\n /**\n * Queue-backed scheduler — e.g. `vercelQueues()` from\n * `experimental-a2/scheduler-vercel`. Absent means append-driven healing only: a\n * working configuration, but a clockless one. Recommended in\n * production.\n */\n scheduler?: A2Scheduler\n /** Optional instrumentation — e.g. `otel()` from `experimental-a2/otel`. */\n telemetry?: A2Telemetry\n /**\n * Presence-plane policy — valid only when the contract declares\n * presence fields (TypeError at construction otherwise). `ttlMs` is\n * how long a value survives without a refreshing set; default 60s.\n */\n presence?: { ttlMs?: number }\n /**\n * The consumers, each a named reader of every session's log with its own\n * cursors: a `consumer()`, or its options and `run` written inline, on this\n * contract. Names are unique; a duplicate throws.\n */\n consumers?: ServerConsumers<D, P, R, C> | readonly Consumer<D>[]\n}\n\nconst MAX_FAILURES = 10\n\n/** How long `consume` waits before looking again at a head it can't run. */\nconst CONSUME_WAIT_MIN_MS = 25\nconst CONSUME_WAIT_MAX_MS = 1_000\n\n/**\n * `task`, or a rejection with `signal`'s reason once it aborts. The task runs\n * on either way, and its own failure is caught, so nothing goes unhandled.\n */\nconst untilAborted = <T>(\n task: Promise<T>,\n signal: AbortSignal | undefined,\n): Promise<T> => {\n if (!signal) return task\n task.catch(() => {})\n if (signal.aborted) return Promise.reject(signal.reason)\n return new Promise<T>((resolve, reject) => {\n const abort = (): void => reject(signal.reason)\n signal.addEventListener('abort', abort, { once: true })\n task.then(resolve, reject).finally(() => {\n signal.removeEventListener('abort', abort)\n })\n })\n}\n\n/** How long an event waits after its `failureCount`th failed attempt. */\nconst failureRetryDelayMs = (failureCount: number): number =>\n Math.min(\n DRAIN_TIMINGS.failureRetryBaseMs * 2 ** Math.max(failureCount - 1, 0),\n DRAIN_TIMINGS.failureRetryMaxMs,\n )\n\n/** Abort a lost attempt's consumer and release its drain slot. */\nfunction endSuperseded(\n entry: {\n supersede: AbortController\n fence: (outcome: {\n status: 'superseded'\n opensLane: false\n appendsEvents: false\n }) => void\n },\n message: string,\n): void {\n entry.supersede.abort(new A2Error('SUPERSEDED_ATTEMPT', message))\n entry.fence({ status: 'superseded', opensLane: false, appendsEvents: false })\n}\n\n/** Pause between clear-deletion batches that found only locked rows. */\nconst RECLAIM_STALL_MS = 20\nconst RECLAIM_STALL_LIMIT = 50\n\n/** Default: how long a presence value survives without a refreshing set. */\nconst PRESENCE_TTL_MS = 60_000\n\ntype ClaimWindow = {\n ttlMs: number\n expiresAtMs: number\n watchdogAtMs: number\n deadlineCapped: boolean\n pastDeadline: boolean\n}\n\ntype DrainSignal = {\n version: number\n closed: boolean\n notify(): void\n wait(version: number): { promise: Promise<void>; cancel(): void }\n}\n\ntype AbortSubscription = {\n controller: AbortController\n triggerIndex: number\n types: Set<string>\n matches(event: Event): boolean\n}\n\ntype AbortHub = {\n subscriptions: Set<AbortSubscription>\n seen: Map<number, Event>\n startAfter: number\n ready: Promise<void>\n watch: Promise<void> | null\n error: unknown\n iterator: AsyncIterator<Event> | null\n stopped: boolean\n}\n\nfunction createDrainSignal(): DrainSignal {\n const listeners = new Set<() => void>()\n return {\n version: 0,\n closed: false,\n notify() {\n this.version += 1\n for (const listener of listeners) listener()\n listeners.clear()\n },\n wait(version) {\n if (this.version !== version) {\n return { promise: Promise.resolve(), cancel: () => {} }\n }\n let resolve!: () => void\n const promise = new Promise<void>((done) => {\n resolve = done\n })\n listeners.add(resolve)\n return { promise, cancel: () => listeners.delete(resolve) }\n },\n }\n}\n\nfunction dispatchAbortEvent(hub: AbortHub, event: Event): void {\n let relevant = false\n for (const subscription of hub.subscriptions) {\n if (!subscription.types.has(event.type)) continue\n relevant = true\n if (subscription.matches(event)) subscription.controller.abort()\n }\n if (relevant) hub.seen.set(event.index, event)\n}\n\nfunction pruneAbortHub(hub: AbortHub): void {\n let minimum = Infinity\n const types = new Set<string>()\n for (const subscription of hub.subscriptions) {\n minimum = Math.min(minimum, subscription.triggerIndex)\n for (const type of subscription.types) types.add(type)\n }\n for (const [index, event] of hub.seen) {\n if (index <= minimum || !types.has(event.type)) hub.seen.delete(index)\n }\n}\n\n/**\n * Deadlines tighten the claim/watchdog window, and a passed deadline ends\n * claiming: a claim then could not run, only lapse and be claimed again until\n * the platform ends the process. A platform timeout otherwise follows the\n * same path as any other process death: the in-flight event remains pending\n * and a fresh invocation retries it.\n */\nfunction nextClaimWindow(): ClaimWindow {\n const nowMs = Date.now()\n const deadlineMs = invocationDeadlineMs()\n const deadlineTtlMs =\n deadlineMs === null ? DRAIN_TIMINGS.claimTtlMs : deadlineMs - nowMs\n const deadlineCapped =\n deadlineMs !== null && deadlineTtlMs <= DRAIN_TIMINGS.claimTtlMs\n const ttlMs = Math.max(1, Math.min(DRAIN_TIMINGS.claimTtlMs, deadlineTtlMs))\n const expiresAtMs = nowMs + ttlMs\n return {\n ttlMs,\n expiresAtMs,\n watchdogAtMs: expiresAtMs + DRAIN_TIMINGS.watchdogGraceMs,\n deadlineCapped,\n pastDeadline: deadlineMs !== null && deadlineTtlMs <= 0,\n }\n}\n\nfunction schedulerSlot(dueAt: number): number {\n return Math.ceil(dueAt / 1_000) * 1_000\n}\n\nfunction currentSchedulerSlot(now: number): number {\n return Math.floor(now / 1_000) * 1_000\n}\n\n/**\n * The namespace separator between machine name and session id in\n * storage. Machines sharing one store backend (the dev-default sqlite\n * file, a shared Postgres) must not collide on session ids; the machine\n * name is what makes multi-machine apps unambiguous (a2-api.md §1), so\n * it prefixes every storage key.\n */\nconst NS = '\\u001f'\n\nconst devDefaultStore = retryableLazy(() =>\n import('./store-sqlite.ts').then((m) => m.sqlite()),\n)\n\n/** Waits for a scheduler arm for at most `schedulerArmTimeoutMs`. */\nasync function joinSchedulerArm(arm: Promise<void>): Promise<void> {\n let timeout: ReturnType<typeof setTimeout> | null = null\n try {\n await Promise.race([\n arm,\n new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n reject(\n new Error(\n `a2 scheduler arm timed out after ${DRAIN_TIMINGS.schedulerArmTimeoutMs}ms`,\n ),\n )\n }, DRAIN_TIMINGS.schedulerArmTimeoutMs)\n }),\n ])\n } finally {\n if (timeout) clearTimeout(timeout)\n }\n}\n\nfunction environment(): 'development' | 'test' | 'production' {\n const env =\n typeof process === 'undefined' ? undefined : process.env?.['NODE_ENV']\n if (env === 'test') return 'test'\n if (env === 'production') return 'production'\n return 'development'\n}\n\nfunction describeError(err: unknown): string {\n if (err instanceof Error) return err.stack ?? `${err.name}: ${err.message}`\n return String(err)\n}\n\n/**\n * Comparison key for a presence value in the degraded-tier diff — an\n * LWW tie can replace a value without moving its `seen`/`at` stamp.\n */\nfunction fingerprint(value: unknown): string {\n return JSON.stringify(value) ?? ''\n}\n\nfunction foldPresenceRows(\n rows: PresenceRow[],\n): Record<string, Record<string, { value: unknown; seen: number; at: Date }>> {\n // Null-prototype at both levels: participants and fields are caller\n // strings, and a '__proto__' key on a normal object rewrites its\n // prototype instead of setting an own property.\n const map =\n nullProtoRecord<\n Record<string, Record<string, { value: unknown; seen: number; at: Date }>>\n >()\n for (const row of rows) {\n ;(map[row.participant] ??= nullProtoRecord())[row.field] = {\n value: row.value,\n seen: row.seen,\n at: row.at,\n }\n }\n return map\n}\n\ntype SnapshotWrites = Map<\n number,\n { state: unknown; pins: Map<string, HeadRef> }\n>\n\n/** One cursor head, as a map key. */\nconst headKey = (ref: HeadRef): string =>\n JSON.stringify([ref.consumer, ref.lane, ref.index])\n\nconst headRefOf = (head: HeadEvent): HeadRef => ({\n consumer: head.consumer,\n lane: head.lane,\n index: head.index,\n})\n\nconst addSnapshotWrite = (\n writes: SnapshotWrites,\n index: number,\n state: unknown,\n pin?: HeadRef,\n): void => {\n let write = writes.get(index)\n if (!write) {\n write = { state: cloneInitial(state), pins: new Map() }\n writes.set(index, write)\n }\n if (pin !== undefined) write.pins.set(headKey(pin), pin)\n}\n\n/** Whether a registered consumer runs events of this type. */\nconst takes = (\n registered: { readonly types: ReadonlySet<string> | null },\n type: string,\n): boolean => registered.types === null || registered.types.has(type)\n\n/** Implement a contract: bind its vocabulary to storage and reactions. */\nexport function createServer<\n D extends EventDefs,\n P extends PresenceDefs = Record<never, never>,\n R extends RegisteredReducer<D, P> | undefined =\n RegisteredReducer<D, P> | undefined,\n const C extends readonly unknown[] = readonly Consumer<D>[],\n>(options: ServerOptions<D, P, R, C>): A2Server<D, P, R> {\n const serverContract = options?.contract\n if (\n serverContract === null ||\n typeof serverContract !== 'object' ||\n typeof serverContract.name !== 'string' ||\n serverContract.events === null\n ) {\n throw new TypeError(\n 'createServer expects options with a contract (see a2.contract)',\n )\n }\n // Ignored, a handler table would run nothing and say nothing.\n if (Object.hasOwn(options, 'handlers')) {\n throw new TypeError(\n 'createServer no longer takes handlers: write each as a consumer in `consumers` (see https://www.a2.dev/upgrades/0-21)',\n )\n }\n const name = serverContract.name\n const defs = serverContract.events\n const presenceDefs: Readonly<PresenceDefs> = serverContract.presence\n const declaresPresence = Object.keys(presenceDefs).length > 0\n const presenceNotSupported = (): A2Error =>\n new A2Error(\n 'PRESENCE_NOT_SUPPORTED',\n `the contract '${name}' declares presence but the store backend for its server has no presence capability (A2Store.presence)`,\n )\n\n if (options.presence !== undefined) {\n // An option for a plane the contract doesn't declare is a mistake\n // worth failing loud at construction.\n if (!declaresPresence) {\n throw new TypeError(\n `the presence option requires a contract that declares presence fields — '${name}' has none`,\n )\n }\n const { ttlMs } = options.presence\n if (ttlMs !== undefined && (!Number.isInteger(ttlMs) || ttlMs <= 0)) {\n throw new TypeError(\n 'presence.ttlMs must be a positive integer of milliseconds',\n )\n }\n }\n const presenceTtlMs = options.presence?.ttlMs ?? PRESENCE_TTL_MS\n\n // Resolve where events live. Explicit store wins; otherwise the\n // environment decides — and production refuses to guess\n // (a2-implementation.md §8): a failed boot beats events written to an\n // ephemeral filesystem.\n let makeStore: () => Promise<A2Store>\n if (options.store) {\n const explicit = options.store\n // Fail at boot, not first use (a2-api.md §12).\n if (declaresPresence && !explicit.presence) throw presenceNotSupported()\n makeStore = () => Promise.resolve(explicit)\n } else {\n const env = environment()\n if (env === 'production') {\n const error = (): A2Error =>\n new A2Error(\n 'STORE_NOT_CONFIGURED',\n `the server for '${name}' has no store configured and NODE_ENV is 'production' — pass an explicit store backend (e.g. postgres from 'experimental-a2/store-postgres')`,\n )\n // `next build` evaluates route modules with NODE_ENV=production\n // to collect page data — in a CI without the runtime env vars, a\n // construction-time throw fails the build for nothing (the store is\n // never used during collection). During that phase only, defer\n // the failure to first use; a real production boot still fails at\n // construction, before any event can land somewhere ephemeral.\n if (process.env['NEXT_PHASE'] !== 'phase-production-build') {\n throw error()\n }\n makeStore = () => Promise.reject(error())\n } else {\n makeStore =\n env === 'test'\n ? () => import('./store-memory.ts').then((m) => m.memory())\n : devDefaultStore.get\n }\n }\n\n // Environment-resolved stores arrive lazily; assert the capability the\n // moment one resolves — the closest available moment to construction.\n if (declaresPresence && !options.store) {\n const inner = makeStore\n makeStore = async () => {\n const store = await inner()\n if (!store.presence) throw presenceNotSupported()\n return store\n }\n }\n\n const resolveStore = retryableLazy(makeStore).get\n\n const telemetry = options.telemetry ?? CONSOLE_TELEMETRY\n const scheduler = options.scheduler\n\n type AbortMatcher = Map<\n string,\n | true\n | ((\n event: ContractEvent<D>,\n trigger: ContractEvent<D>,\n context: { attempt: number },\n ) => boolean)\n >\n const abortMatcherOf = (\n spec: AbortSpec<D, keyof D & string> | null | undefined,\n ): AbortMatcher | null => {\n let abortOn: AbortMatcher | null = null\n if (spec !== undefined && spec !== null) {\n abortOn = new Map()\n const pairs = Array.isArray(spec)\n ? spec.map((abortType) => [abortType, true as const] as const)\n : (Object.entries(spec) as Array<\n [\n string,\n (\n | true\n | ((\n e: never,\n t: never,\n context: { attempt: number },\n ) => boolean)\n ),\n ]\n >)\n for (const [abortType, matcher] of pairs) {\n if (matcher === undefined) continue\n if (!Object.hasOwn(defs, abortType)) {\n throw new TypeError(\n `contract '${name}' has no event type '${String(abortType)}' — cannot abort on it`,\n )\n }\n abortOn.set(String(abortType), matcher as never)\n }\n if (abortOn.size === 0) abortOn = null\n }\n return abortOn\n }\n\n /** A consumer as this server runs it. */\n type RegisteredConsumer = {\n name: string\n types: ReadonlySet<string> | null\n /** Lane-function and concurrent consumers; log consumers resolve none. */\n laneOf: ((sessionId: string, event: AppendEvent) => string | null) | null\n log: StoreConsumer['log']\n abortOn: (type: string) => AbortMatcher | null\n run: (ctx: ConsumerContext<D>) => Promise<unknown>\n /** A2's own consumers: child and timer ids leave out the name. */\n anonymousIds: boolean\n }\n const laneContext = (sessionId: string, event: AppendEvent): LaneContext<D> =>\n ({\n sessionId,\n event: {\n type: event.type,\n payload: structuredClone(event.payload),\n ...(event.id === undefined ? {} : { id: event.id }),\n },\n }) as LaneContext<D>\n const registeredConsumers = new Map<string, RegisteredConsumer>()\n /** A consumer definition as the server runs it. */\n const registrationOf = (defined: Consumer<D>): RegisteredConsumer => {\n const { types, lane, backfill, abortOn, run } = defined.spec\n const matcher = abortMatcherOf(abortOn)\n return {\n name: defined.name,\n types: types === null ? null : new Set(types),\n laneOf:\n typeof lane === 'string'\n ? null\n : lane === null\n ? () => null\n : (sessionId, event) => {\n const resolved = lane(laneContext(sessionId, event))\n if (\n resolved !== null &&\n (typeof resolved !== 'string' || resolved.length === 0)\n ) {\n throw new TypeError(\n `lane for consumer '${defined.name}' must resolve to a non-empty string or null`,\n )\n }\n return resolved\n },\n log:\n typeof lane === 'string'\n ? { lane, types: types === null ? null : [...types], backfill }\n : undefined,\n abortOn: () => matcher,\n run: run as (ctx: ConsumerContext<D>) => Promise<unknown>,\n anonymousIds: runtimeConsumers.has(defined),\n }\n }\n /** The definitions the server runs, so `consume` can tell its own from another. */\n const definitions = new Map<string, Consumer<D>>()\n /** A consumer written inline is `consumer()`'s options and `run`, on this contract. */\n const definitionOf = (entry: unknown): Consumer<D> => {\n if (\n entry === null ||\n typeof entry !== 'object' ||\n 'spec' in entry ||\n !('run' in entry)\n ) {\n return entry as Consumer<D>\n }\n const { run, ...rest } = entry as InlineConsumer<D, P, R, keyof D & string>\n return consumer({ ...rest, contract: serverContract }).run(run)\n }\n for (const entry of (options.consumers ?? []) as readonly unknown[]) {\n const defined = definitionOf(entry)\n if (defined?.contract?.name !== name || !defined.spec) {\n throw new TypeError(\n `createServer for '${name}' got a consumer of another contract`,\n )\n }\n if (registeredConsumers.has(defined.name)) {\n throw new TypeError(`two consumers are named '${defined.name}'`)\n }\n registeredConsumers.set(defined.name, registrationOf(defined))\n definitions.set(defined.name, defined)\n }\n // Runtime consumers leave their name out of child ids, so no event may\n // start two of them: their first returned events would share an id.\n const anonymousTypes = new Map<string, string>()\n for (const registered of registeredConsumers.values()) {\n if (!registered.anonymousIds) continue\n for (const type of registered.types ?? Object.keys(defs)) {\n const other = anonymousTypes.get(type)\n if (other !== undefined) {\n throw new TypeError(\n `A2's consumers '${other}' and '${registered.name}' both take '${type}'`,\n )\n }\n anonymousTypes.set(type, registered.name)\n }\n }\n /** The consumers this server serves, as the store needs to know them. */\n const storeConsumers: StoreConsumer[] = [...registeredConsumers.values()].map(\n storeConsumerOf,\n )\n /** Whether an event starts cursor work for any consumer. */\n const startsWork = (event: AppendEvent): boolean =>\n (event.targets?.length ?? 0) > 0 ||\n [...registeredConsumers.values()].some(\n (registered) => registered.log && takes(registered, event.type),\n )\n\n const prefix = `${name}${NS}`\n const nsId = (sessionId: string): string => `${prefix}${sessionId}`\n const stripNs = (stored: string): string => stored.slice(prefix.length)\n\n const toPublic = (row: Event): ContractEvent<D> =>\n ({\n id: row.id,\n type: row.type,\n payload: row.payload,\n index: row.index,\n sessionId: stripNs(row.sessionId),\n createdAt: row.createdAt,\n }) as ContractEvent<D>\n\n // ── background work tracking ─────────────────────────────────────\n // Every fire-and-forget operation is tracked so (a) platforms with\n // waitUntil keep the invocation alive and (b) tests can flush\n // deterministically via serverInternals.\n const inFlight = new Set<Promise<unknown>>()\n const track = (p: Promise<unknown>): void => {\n inFlight.add(p)\n const drop = (): void => {\n inFlight.delete(p)\n }\n p.then(drop, drop)\n }\n\n type SchedulerArmSlot = {\n promise: Promise<void>\n forget: ReturnType<typeof setTimeout>\n }\n const schedulerArmSlots = new Map<string, SchedulerArmSlot>()\n\n /**\n * Start an optional scheduler arm without putting it on the execution path.\n * The returned raw promise lets the initial append report failure; the\n * tracked copy is always rejection-safe for heartbeat callers.\n */\n const startSchedulerArm = (\n sessionId: string,\n dueAt: number,\n ): Promise<void> | null => {\n if (!scheduler) return null\n const slottedDueAt = schedulerSlot(dueAt)\n const slotKey = JSON.stringify([sessionId, slottedDueAt])\n const existing = schedulerArmSlots.get(slotKey)\n if (existing) return existing.promise\n // Normalize even a custom adapter's synchronous throw into a rejected\n // promise. Optional scheduler must never stop inline claiming.\n const raw = Promise.resolve().then(() =>\n scheduler.schedule({\n version: 1,\n kind: 'drain',\n contract: name,\n sessionId,\n dueAt: slottedDueAt,\n }),\n )\n const forget = setTimeout(\n () => {\n if (schedulerArmSlots.get(slotKey)?.promise === raw) {\n schedulerArmSlots.delete(slotKey)\n }\n },\n Math.max(0, slottedDueAt - Date.now()) + 1_000,\n )\n ;(forget as { unref?: () => void }).unref?.()\n schedulerArmSlots.set(slotKey, { promise: raw, forget })\n void raw.then(undefined, () => {\n const current = schedulerArmSlots.get(slotKey)\n if (current?.promise !== raw) return\n clearTimeout(current.forget)\n schedulerArmSlots.delete(slotKey)\n })\n const safe = raw.catch(() => {})\n track(safe)\n platformWaitUntil(safe)\n return raw\n }\n\n const scheduledDrains = new Map<\n string,\n { signal: DrainSignal; promise: Promise<void> }\n >()\n\n const scheduleDrain = (sessionId: string, watchdogDueAt?: number): void => {\n const existing = scheduledDrains.get(sessionId)\n if (existing && !existing.signal.closed) {\n existing.signal.notify()\n return\n }\n if (existing) scheduledDrains.delete(sessionId)\n const signal = createDrainSignal()\n const p = new Promise<void>((resolve) => {\n queueMicrotask(() => {\n void drainSession(sessionId, { watchdogDueAt, signal })\n .then(() => resolve())\n .catch(() => resolve())\n })\n }).finally(() => {\n if (scheduledDrains.get(sessionId)?.promise === p) {\n scheduledDrains.delete(sessionId)\n }\n })\n scheduledDrains.set(sessionId, { signal, promise: p })\n track(p)\n platformWaitUntil(p)\n }\n\n // ── append ───────────────────────────────────────────────────────\n\n const validateEvents = (\n sessionId: string,\n events: AppendInput<D>[],\n resolveDispatchMetadata = true,\n ): AppendEvent[] => {\n if (events.length === 0) {\n throw new TypeError('append requires at least one event')\n }\n return events.map((e) => {\n const schema = Object.hasOwn(defs, e.type) ? defs[e.type] : undefined\n if (!schema) {\n throw new A2Error(\n 'UNKNOWN_EVENT_TYPE',\n `contract '${name}' has no event type '${String(e.type)}'`,\n )\n }\n const result = validateSync(schema, e.payload, `event '${e.type}'`)\n if (result.issues) {\n throw new A2Error(\n 'INVALID_PAYLOAD',\n `invalid payload for event '${e.type}' on machine '${name}'`,\n { details: result.issues },\n )\n }\n const validated: AppendEvent = { type: e.type, payload: result.value }\n if (e.id !== undefined) validated.id = e.id\n if (!resolveDispatchMetadata) return validated\n const targets: EventTarget[] = []\n for (const registered of registeredConsumers.values()) {\n if (!registered.laneOf || !takes(registered, e.type)) continue\n targets.push({\n consumer: registered.name,\n lane: registered.laneOf(sessionId, validated),\n })\n }\n if (targets.length > 0) validated.targets = targets\n return validated\n })\n }\n\n /**\n * Validate + write. `onAppended` runs inside the telemetry span, so\n * the drain it schedules is created in the append's active context —\n * with a real tracer, causal work remains connected.\n */\n const appendCore = (\n sessionId: string,\n events: AppendInput<D>[],\n source: 'external' | 'consumer',\n mode: 'inline' | 'dispatch',\n onAppended: (rows: ContractEvent<D>[], watchdogDueAt?: number) => void,\n cause?: EventCause,\n generatedIds?: readonly boolean[],\n requireDurableInitialArm = false,\n originIndex?: number,\n ): Promise<ContractEvent<D>[]> =>\n telemetry.span(\n 'a2.append',\n {\n 'a2.contract': name,\n 'a2.session_id': sessionId,\n 'a2.append.source': source,\n 'a2.append.mode': mode,\n 'a2.append.types': events.map((e) => String(e.type)).join(','),\n 'a2.append.count': events.length,\n },\n async (span) => {\n if (mode === 'dispatch' && !scheduler) {\n throw new TypeError(\n 'append.dispatch requires a configured scheduler adapter',\n )\n }\n assertSessionId(sessionId)\n const validated = validateEvents(sessionId, events)\n if (cause) {\n for (const [index, event] of validated.entries()) {\n event.cause = generatedIds?.[index]\n ? { ...cause, batchSize: events.length }\n : cause\n }\n }\n const store = await resolveStore()\n let rows: StoredEvent[]\n let shouldHealSession: boolean\n try {\n const result = await store.append(nsId(sessionId), validated, {\n consumers: storeConsumers,\n ...(originIndex === undefined ? {} : { originIndex }),\n })\n rows = result.events\n // A consumer appending events no consumer takes adds no work, and\n // the drain holding its trigger is already running.\n shouldHealSession =\n result.hasPending &&\n !(source === 'consumer' && !validated.some(startsWork))\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n const appended = rows.map(toPublic)\n\n const initialWatchdogAt =\n shouldHealSession &&\n scheduler &&\n source === 'external' &&\n mode === 'inline'\n ? schedulerSlot(nextClaimWindow().watchdogAtMs)\n : undefined\n const initialArm =\n initialWatchdogAt !== undefined\n ? startSchedulerArm(sessionId, initialWatchdogAt)\n : null\n const dispatchArm =\n shouldHealSession && mode === 'dispatch'\n ? startSchedulerArm(sessionId, currentSchedulerSlot(Date.now()))\n : null\n if (shouldHealSession && mode === 'inline') {\n onAppended(appended, initialWatchdogAt)\n }\n if (dispatchArm) {\n await dispatchArm\n }\n if (initialArm) {\n try {\n await joinSchedulerArm(initialArm)\n } catch (err) {\n span.setAttribute('a2.append.armed', false)\n span.recordError(err)\n if (requireDurableInitialArm) throw err\n }\n }\n return appended\n },\n )\n\n const readHistory = async (\n sessionId: string,\n bounds?: { gte?: number; lte?: number },\n ): Promise<Event[]> => {\n const gte = bounds?.gte\n const lte = bounds?.lte\n assertHistoryIndex('gte', gte)\n assertHistoryIndex('lte', lte)\n if (gte !== undefined && lte !== undefined && gte > lte) {\n throw new RangeError(\n 'history.gte must be less than or equal to history.lte',\n )\n }\n if (lte === 0) return []\n\n const store = await resolveStore()\n try {\n const readOptions =\n gte === undefined && lte === undefined\n ? undefined\n : {\n ...(gte === undefined\n ? {}\n : { afterIndex: Math.max(0, gte - 1) }),\n ...(lte === undefined ? {} : { throughIndex: lte }),\n }\n const rows = await (store.readHistory\n ? store.readHistory(nsId(sessionId), readOptions)\n : store.read(nsId(sessionId), readOptions))\n return rows.filter(\n (row) =>\n (gte === undefined || row.index >= gte) &&\n (lte === undefined || row.index <= lte),\n )\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n }\n\n const readStoreState = async (\n store: A2Store,\n sessionId: string,\n reducerName: string,\n throughIndex?: number,\n snapshotThroughIndex?: number,\n ): Promise<StoreStateRead> => {\n try {\n return await store.readState(\n nsId(sessionId),\n reducerName,\n throughIndex === undefined && snapshotThroughIndex === undefined\n ? undefined\n : {\n ...(throughIndex === undefined ? {} : { throughIndex }),\n ...(snapshotThroughIndex === undefined\n ? {}\n : { snapshotThroughIndex }),\n },\n )\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n }\n\n type StateResult = { state: unknown; index: number; clearIndex?: number }\n\n type PendingStateRead = {\n sessionId: string\n throughIndex?: number\n /** The id of the event at `throughIndex`, when the reader knows it. */\n throughEventId?: string\n pin?: HeadRef\n /** A consumer read: rejected once this trigger index has been cleared. */\n triggerIndex?: number\n span: A2SpanHandle\n resolve: (result: StateResult) => void\n reject: (reason: unknown) => void\n }\n\n type StateReadPlan = {\n sessionId: string\n entries: PendingStateRead[]\n throughIndex?: number\n snapshotThroughIndex?: number\n }\n\n const planStateReads = (batch: PendingStateRead[]): StateReadPlan[] => {\n const bySession = new Map<string, PendingStateRead[]>()\n for (const entry of batch) {\n const entries = bySession.get(entry.sessionId)\n if (entries) entries.push(entry)\n else bySession.set(entry.sessionId, [entry])\n }\n const plans: StateReadPlan[] = []\n for (const [sessionId, entries] of bySession) {\n const boundaries = entries.flatMap((entry) =>\n entry.throughIndex === undefined ? [] : [entry.throughIndex],\n )\n const plan: StateReadPlan = { sessionId, entries }\n if (boundaries.length === entries.length) {\n plan.throughIndex = Math.max(...boundaries)\n }\n if (boundaries.length > 0) {\n plan.snapshotThroughIndex = Math.min(...boundaries)\n }\n plans.push(plan)\n }\n return plans\n }\n\n const persistSnapshots = ({\n store,\n reducer,\n sessionId,\n snapshots,\n }: {\n store: A2Store\n reducer: Reducer<D, unknown>\n sessionId: string\n snapshots: StoreSnapshotWrite[]\n }): void => {\n const persistence = Promise.resolve()\n .then(() =>\n telemetry.span(\n 'a2.snapshot',\n {\n 'a2.contract': name,\n 'a2.session_id': sessionId,\n 'a2.snapshot.reducer': reducer.name,\n 'a2.snapshot.index': snapshots.at(-1)!.index,\n 'a2.snapshot.count': snapshots.length,\n },\n async (span) => {\n try {\n await store.putSnapshots(nsId(sessionId), reducer.name, snapshots)\n } catch (error) {\n try {\n span.recordError(error)\n } catch (telemetryError) {\n // oxlint-disable-next-line preserve-caught-error -- AggregateError preserves both failures.\n throw new AggregateError(\n [error, telemetryError],\n 'Snapshot write and error reporting failed',\n { cause: telemetryError },\n )\n }\n }\n },\n ),\n )\n .catch((error: unknown) => {\n // oxlint-disable-next-line no-console -- telemetry failure must not hide failed background work.\n console.error(\n '[a2] error in a2.snapshot telemetry',\n {\n sessionId,\n reducer: reducer.name,\n index: snapshots.at(-1)!.index,\n },\n error,\n )\n })\n track(persistence)\n platformWaitUntil(persistence)\n }\n\n // ── in-memory reducer state ──────────────────────────────────────\n /**\n * The latest folded state per (session, reducer) this process has seen,\n * with the index and id of the last event it reflects. An entry serves\n * only the reducer object that folded it, so a same-named reducer with\n * different logic reads the store. Cached states are never handed out;\n * readers get clones.\n */\n type CachedState = {\n reducer: Reducer<D, unknown>\n index: number\n lastId: string\n state: unknown\n bytes: number\n /** Events folded since `bytes` was last measured. */\n unmeasured: number\n persistedIndex: number\n /** The latest clear marker at or below `index`, or zero. */\n clearIndex: number\n }\n const stateCache = boundedCache<string, CachedState>(STATE_CACHE)\n const cacheState = (key: string, next: CachedState): void => {\n const current = stateCache.get(key)\n if (\n current?.reducer === next.reducer &&\n (current.index > next.index ||\n (current.index === next.index &&\n current.persistedIndex >= next.persistedIndex))\n )\n return\n stateCache.set(key, next, next.bytes)\n }\n\n const writeSnapshots = ({\n store,\n reducer,\n sessionId,\n writes,\n }: {\n store: A2Store\n reducer: Reducer<D, unknown>\n sessionId: string\n writes: SnapshotWrites\n }): StoreSnapshotWrite[] => {\n const snapshots = [...writes]\n .toSorted(([a], [b]) => a - b)\n .map(([index, write]) => {\n const snapshot: StoreSnapshotWrite = {\n index,\n state: encodeState({ reducer, state: write.state }),\n }\n if (write.pins.size > 0) snapshot.pins = [...write.pins.values()]\n return snapshot\n })\n if (snapshots.length > 0) {\n persistSnapshots({ store, reducer, sessionId, snapshots })\n }\n return snapshots\n }\n\n /**\n * Folds `rows` from `position` in bound order, resolving each entry with a\n * clone once the rows through its bound are folded. `visit` sees each\n * entry's state before later rows are folded into it.\n */\n const foldEntries = ({\n reducer,\n entries,\n rows,\n position,\n state,\n index,\n clearIndex,\n snapshot,\n visit,\n }: {\n reducer: Reducer<D, unknown>\n entries: PendingStateRead[]\n rows: Event[]\n position: number\n state: unknown\n index: number\n /** The latest clear marker the rows reflect, or zero. */\n clearIndex: number\n snapshot: string\n visit: (\n entry: PendingStateRead,\n state: unknown,\n index: number,\n folded: number,\n ) => void\n }): { state: unknown; index: number; position: number } => {\n const start = position\n const ordered = entries.toSorted(\n (a, b) =>\n (a.throughIndex ?? Number.POSITIVE_INFINITY) -\n (b.throughIndex ?? Number.POSITIVE_INFINITY),\n )\n for (const entry of ordered) {\n const target = entry.throughIndex ?? Number.POSITIVE_INFINITY\n while (position < rows.length && rows[position]!.index <= target) {\n const row = rows[position]!\n state = foldEvent(reducer, state, toPublic(row))\n index = row.index\n position += 1\n }\n if (\n (entry.triggerIndex !== undefined &&\n entry.triggerIndex <= clearIndex) ||\n (entry.throughIndex !== undefined &&\n entry.throughIndex > 0 &&\n entry.throughIndex < clearIndex)\n ) {\n entry.reject(\n sessionClearedError(\n `session '${entry.sessionId}' was cleared at index ${clearIndex}`,\n ),\n )\n continue\n }\n entry.span.setAttribute('a2.state.snapshot', snapshot)\n entry.span.setAttribute('a2.state.folded', position - start)\n entry.span.setAttribute('a2.state.index', index)\n visit(entry, state, index, position - start)\n // A result below the marker (the explicit seed) predates this lifetime.\n entry.resolve({\n state: cloneInitial(state),\n index,\n ...(clearIndex > 0 && index >= clearIndex ? { clearIndex } : {}),\n })\n }\n return { state, index, position }\n }\n\n /**\n * Events from `fromIndex` (inclusive) through `throughIndex` or the newest\n * event, or null when the tail is too long to be worth folding in memory.\n */\n const readCachedTail = async (\n store: A2Store,\n sessionId: string,\n fromIndex: number,\n throughIndex?: number,\n ): Promise<Event[] | null> => {\n const readTail = stateTailReaders.get(store)\n if (readTail) {\n try {\n return await readTail(nsId(sessionId), fromIndex, throughIndex)\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n }\n const limit = fromIndex + STATE_CACHE.maxTail\n const capped = throughIndex === undefined || throughIndex > limit\n const rows = await readHistory(sessionId, {\n gte: fromIndex,\n lte: capped ? limit : throughIndex,\n })\n return capped && rows.at(-1)?.index === limit ? null : rows\n }\n\n /**\n * Serves a plan from the cached state when every read is at or past the\n * cached index. A read bounded at the cached index by an event whose id\n * matches the cached one (a consumer's own trigger) needs no store request;\n * any other read fetches the tail from the cached event onward and checks\n * that event's id. Returns false when the store must answer instead.\n */\n const foldCachedPlan = async (\n store: A2Store,\n reducer: Reducer<D, unknown>,\n plan: StateReadPlan,\n ): Promise<boolean> => {\n const key = stateCacheKey(plan.sessionId, reducer.name)\n const cached = stateCache.get(key)\n if (cached?.reducer !== reducer) return false\n if (\n plan.entries.some(\n (entry) =>\n entry.throughIndex !== undefined && entry.throughIndex < cached.index,\n )\n )\n return false\n let rows: Event[] = []\n if (\n plan.entries.some(\n (entry) =>\n entry.throughIndex !== cached.index ||\n entry.throughEventId !== cached.lastId,\n )\n ) {\n const tail = await readCachedTail(\n store,\n plan.sessionId,\n cached.index,\n plan.throughIndex,\n )\n if (!tail) return false\n // A clear after the cached event, or a rewritten log, needs the store:\n // it applies the boundary and its fences.\n if (\n tail[0]?.index !== cached.index ||\n tail[0].id !== cached.lastId ||\n tail.some((row, position) => position > 0 && isSessionCleared(row))\n ) {\n stateCache.delete(key)\n return false\n }\n rows = tail\n }\n const writes: SnapshotWrites = new Map()\n const folded = foldEntries({\n reducer,\n entries: plan.entries,\n rows,\n position: 1,\n state: rows.length > 1 ? cloneInitial(cached.state) : cached.state,\n index: cached.index,\n clearIndex: cached.clearIndex,\n snapshot: 'memory',\n visit: (entry, state, index) => {\n if (entry.pin !== undefined) {\n addSnapshotWrite(writes, index, state, entry.pin)\n }\n },\n })\n const added = Math.max(0, folded.position - 1)\n const rewritesHead =\n folded.index - cached.persistedIndex >= STATE_CACHE.snapshotEvery\n if (rewritesHead && !writes.has(folded.index)) {\n writes.set(folded.index, {\n state: folded.state,\n pins: new Map(),\n })\n }\n const snapshots = writeSnapshots({\n store,\n reducer,\n sessionId: plan.sessionId,\n writes,\n })\n const measure =\n rewritesHead || cached.unmeasured + added >= STATE_CACHE.measureEvery\n let grown = 0\n if (!measure) {\n for (let position = 1; position < folded.position; position += 1) {\n grown += JSON.stringify(rows[position]!.payload)?.length ?? 0\n }\n }\n cacheState(key, {\n reducer,\n index: folded.index,\n lastId: added > 0 ? rows[folded.position - 1]!.id : cached.lastId,\n state: folded.state,\n bytes: measure\n ? measuredBytes(reducer, folded.state, folded.index, snapshots)\n : cached.bytes + grown,\n unmeasured: measure ? 0 : cached.unmeasured + added,\n persistedIndex: Math.max(\n cached.persistedIndex,\n snapshots.at(-1)?.index ?? 0,\n ),\n clearIndex: cached.clearIndex,\n })\n return true\n }\n\n // The cache is untrusted: schema rejection refolds from the raw store.\n const foldStatePlan = async (\n store: A2Store,\n reducer: Reducer<D, unknown>,\n plan: StateReadPlan,\n stateRead: StoreStateRead,\n ): Promise<void> => {\n let state = cloneInitial(reducer.initialState)\n let index = 0\n let snapshotOutcome = 'miss'\n const snap = stateRead.snapshot\n let rows = stateRead.events\n let clearIndex = stateRead.clearIndex ?? 0\n if (snap) {\n let decoded: unknown\n try {\n decoded = decodeState({ reducer, state: snap.state })\n } catch {\n snapshotOutcome = 'rejected'\n }\n if (snapshotOutcome !== 'rejected' && reducer.stateSchema) {\n const result = validateSync(\n reducer.stateSchema,\n decoded,\n 'the stateSchema',\n )\n if (result.issues) {\n snapshotOutcome = 'rejected'\n } else {\n state = result.value\n index = snap.index\n snapshotOutcome = 'hit'\n }\n } else if (snapshotOutcome !== 'rejected') {\n state = decoded\n index = snap.index\n snapshotOutcome = 'hit'\n }\n }\n if (snapshotOutcome === 'rejected') {\n try {\n rows = await store.read(\n nsId(plan.sessionId),\n plan.throughIndex === undefined\n ? undefined\n : { throughIndex: plan.throughIndex },\n )\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n // Reads start at the latest marker, so a clear since readState leads.\n if (rows[0] && isSessionCleared(rows[0]))\n clearIndex = Math.max(clearIndex, rows[0].index)\n }\n const writes: SnapshotWrites = new Map()\n const folded = foldEntries({\n reducer,\n entries: plan.entries,\n rows,\n position: 0,\n state,\n index,\n clearIndex,\n snapshot: snapshotOutcome,\n visit: (entry, entryState, entryIndex, count) => {\n if (entryIndex === 0) return\n if (count === 0 && entry.pin === undefined) return\n const advancesHead =\n stateRead.headIndex === null || entryIndex > stateRead.headIndex\n const repairsHead =\n snapshotOutcome === 'rejected' && entryIndex === stateRead.headIndex\n if (!advancesHead && !repairsHead && entry.pin === undefined) return\n addSnapshotWrite(writes, entryIndex, entryState, entry.pin)\n },\n })\n const snapshots = writeSnapshots({\n store,\n reducer,\n sessionId: plan.sessionId,\n writes,\n })\n if (folded.position > 0 && STATE_CACHE.maxEntries > 0) {\n cacheState(stateCacheKey(plan.sessionId, reducer.name), {\n reducer,\n index: folded.index,\n lastId: rows[folded.position - 1]!.id,\n state: folded.state,\n bytes: measuredBytes(reducer, folded.state, folded.index, snapshots),\n unmeasured: 0,\n persistedIndex: Math.min(\n Math.max(stateRead.headIndex ?? 0, ...writes.keys()),\n folded.index,\n ),\n clearIndex,\n })\n }\n }\n\n // ── same-tick state-read coalescing ──────────────────────────────\n const pendingStateReads = new Map<string, PendingStateRead[]>()\n\n // The flush microtask voids this promise, so the function must be\n // total: never reject, never leave an entry unresolved — even for a\n // synchronously throwing adapter or a read structuredClone rejects.\n const flushStateReads = async (\n store: A2Store,\n reducer: Reducer<D, unknown>,\n batch: PendingStateRead[],\n ): Promise<void> => {\n const plans: StateReadPlan[] = []\n await Promise.all(\n planStateReads(batch).map(async (plan) => {\n try {\n if (!(await foldCachedPlan(store, reducer, plan))) plans.push(plan)\n } catch (error) {\n for (const entry of plan.entries) entry.reject(error)\n }\n }),\n )\n if (plans.length === 0) return\n let reads: (StoreStateRead | Promise<StoreStateRead>)[]\n try {\n reads = store.readStates\n ? await store.readStates(\n plans.map((plan) => ({\n sessionId: nsId(plan.sessionId),\n ...(plan.throughIndex === undefined\n ? {}\n : { throughIndex: plan.throughIndex }),\n ...(plan.snapshotThroughIndex === undefined\n ? {}\n : { snapshotThroughIndex: plan.snapshotThroughIndex }),\n })),\n reducer.name,\n )\n : plans.map((plan) =>\n readStoreState(\n store,\n plan.sessionId,\n reducer.name,\n plan.throughIndex,\n plan.snapshotThroughIndex,\n ),\n )\n if (reads.length !== plans.length)\n throw new TypeError(\n 'store.readStates must return one result per request',\n )\n } catch (error) {\n const failure = asStoreUnavailable(error)\n for (const plan of plans)\n for (const entry of plan.entries) entry.reject(failure)\n return\n }\n await Promise.all(\n plans.map(async (plan, position) => {\n try {\n await foldStatePlan(store, reducer, plan, await reads[position]!)\n } catch (error) {\n for (const entry of plan.entries) entry.reject(error)\n }\n }),\n )\n }\n\n type StateReadBounds = {\n throughIndex?: number\n throughEventId?: string\n pin?: HeadRef\n triggerIndex?: number\n }\n\n const enqueueStateRead = (\n store: A2Store,\n sessionId: string,\n reducer: Reducer<D, unknown>,\n bounds: StateReadBounds,\n span: A2SpanHandle,\n ): Promise<StateResult> =>\n new Promise((resolve, reject) => {\n const reducerName = reducer.name\n let batch = pendingStateReads.get(reducerName)\n if (!batch) {\n const opened: PendingStateRead[] = []\n pendingStateReads.set(reducerName, opened)\n // One microtask is the whole batching window — deliberately NOT\n // DataLoader's post-promise-job nextTick, which would defer\n // consumer-internal reads past the entire microtask cascade and\n // reorder drain interleaving (and has no edge-runtime primitive).\n // It still coalesces reliably: siblings of one Promise.all\n // traverse identical awaits (store resolution, span wrapper), so\n // their enqueues sit at consecutive queue positions — cold or\n // warm — and this flush, queued by the first of them, runs after\n // the last. A deeper-staggered caller just opens the next batch.\n queueMicrotask(() => {\n pendingStateReads.delete(reducerName)\n void flushStateReads(store, reducer, opened)\n })\n batch = opened\n }\n batch.push({ sessionId, ...bounds, span, resolve, reject })\n })\n\n const readState = async <S>(\n sessionId: string,\n reducer: Reducer<D, S, Record<never, never>>,\n bounds: StateReadBounds,\n ): Promise<{ state: S; index: number; clearIndex?: number }> => {\n const store = await resolveStore()\n return telemetry.span(\n 'a2.state',\n {\n 'a2.contract': name,\n 'a2.session_id': sessionId,\n 'a2.state.reducer': reducer.name,\n },\n (span) =>\n enqueueStateRead(\n store,\n sessionId,\n reducer as Reducer<D, unknown>,\n bounds,\n span,\n ) as Promise<{ state: S; index: number; clearIndex?: number }>,\n )\n }\n\n const makeSchedule = (\n sessionId: string,\n trigger: HeadEvent | null,\n ): SessionSchedule<D> => {\n const triggerEventId = trigger?.id ?? null\n /** Timers a consumer sets key on its name, except A2's own. */\n const triggerConsumer =\n trigger && !registeredConsumers.get(trigger.consumer)?.anonymousIds\n ? trigger.consumer\n : undefined\n const triggerCreatedAt = trigger?.createdAt.getTime()\n const clearIndex = trigger?.clearIndex ?? 0\n const schedule = async (\n scheduleName: string,\n timing: ScheduleTiming,\n ...events: AppendInput<D>[]\n ): Promise<void> => {\n if (!scheduler) {\n throw new TypeError(\n 'session.schedule requires a configured scheduler adapter',\n )\n }\n assertScheduleName(scheduleName)\n if (events.length === 0) {\n throw new TypeError('schedule requires at least one event')\n }\n const dueAt = scheduleDueAt(timing, triggerCreatedAt ?? Date.now())\n const payloads = events.map((event) =>\n cloneScheduledPayload(event.payload),\n )\n const snapshottedEvents = events.map((event, index) =>\n event.id === undefined\n ? { type: event.type, payload: payloads[index] }\n : { type: event.type, payload: payloads[index], id: event.id },\n ) as AppendInput<D>[]\n const validated = validateEvents(\n sessionId,\n structuredClone(snapshottedEvents),\n false,\n )\n const scheduleId = await deterministicScheduleId(\n name,\n sessionId,\n triggerEventId,\n scheduleName,\n clearIndex,\n triggerConsumer,\n )\n const scheduledEvents: ScheduledEvent[] = await Promise.all(\n validated.map(async (event, item) => ({\n id:\n event.id ?? (await deterministicScheduledEventId(scheduleId, item)),\n type: event.type,\n payload: payloads[item],\n })),\n )\n if (\n new Set(scheduledEvents.map((event) => event.id)).size !==\n scheduledEvents.length\n ) {\n throw new A2Error(\n 'PARTIAL_DUPLICATE_BATCH',\n 'scheduled batch contains the same event id more than once',\n )\n }\n try {\n await scheduler.schedule({\n version: 1,\n kind: 'append',\n id: scheduleId,\n contract: name,\n sessionId,\n dueAt,\n events: scheduledEvents,\n ...(trigger ? { originIndex: trigger.index } : {}),\n })\n } catch (error) {\n throw markSchedulerSendFailure(error)\n }\n }\n const clear = async (\n scheduleName: string,\n clearOptions: ScheduleTiming & { ifLastIndex: number },\n ): Promise<void> => {\n if (!scheduler) {\n throw new TypeError(\n 'session.schedule.clear requires a configured scheduler adapter',\n )\n }\n assertScheduleName(scheduleName)\n if (clearOptions === null || typeof clearOptions !== 'object') {\n throw new TypeError('schedule.clear requires an ifLastIndex')\n }\n const { ifLastIndex, ...timing } = clearOptions\n assertClearIndex(ifLastIndex)\n const dueAt = scheduleDueAt(\n timing as ScheduleTiming,\n triggerCreatedAt ?? Date.now(),\n )\n const store = await resolveStore()\n if (!store.clear || !store.reclaim) {\n throw new TypeError(\n 'session.schedule.clear requires a store that supports clearing',\n )\n }\n const id = await deterministicScheduleClearId({\n contract: name,\n sessionId,\n triggerEventId,\n clearIndex,\n name: scheduleName,\n ifLastIndex,\n ...(triggerConsumer === undefined ? {} : { consumer: triggerConsumer }),\n })\n try {\n await scheduler.schedule({\n version: 1,\n kind: 'clear',\n id,\n contract: name,\n sessionId,\n dueAt,\n ifLastIndex,\n })\n } catch (error) {\n throw markSchedulerSendFailure(error)\n }\n }\n return Object.assign(schedule, { clear })\n }\n\n const toSessionEvent = (id: string, event: Event): ContractEvent<D> =>\n ({\n id: event.id,\n type: event.type,\n payload: event.payload,\n index: event.index,\n sessionId: id,\n createdAt: event.createdAt,\n }) as ContractEvent<D>\n\n const streamEvents = (\n id: string,\n startAfter: number,\n ): AsyncIterable<ContractEvent<D>> => {\n let closed = false\n let inner: AsyncIterator<Event> | undefined\n let stopActivity: (() => void) | undefined\n const activity = createStreamActivity(() => {\n if (inner && !closed) streamActivities.get(inner)?.activate()\n })\n let closing: Promise<void> | undefined\n const close = (): Promise<void> => {\n closed = true\n closing ??= (async () => {\n stopActivity?.()\n await inner?.return?.()\n })()\n return closing\n }\n const outer = async function* (): AsyncGenerator<ContractEvent<D>> {\n const store = await resolveStore()\n if (closed) return\n inner = store.stream(nsId(id), { startAfter })[Symbol.asyncIterator]()\n const sourceActivity = streamActivities.get(inner)\n if (sourceActivity) {\n stopActivity = sourceActivity.subscribe(activity.setIdle)\n activity.setIdle(sourceActivity.idle)\n }\n try {\n for (;;) {\n if (closed) return\n const result = await inner.next()\n if (closed || result.done) return\n yield toSessionEvent(id, result.value)\n }\n } finally {\n await close()\n }\n }\n const iterator = outer()\n return {\n [Symbol.asyncIterator]() {\n const stream = {\n next: () => iterator.next(),\n async return() {\n await close()\n return iterator.return(undefined)\n },\n async throw(error: unknown) {\n await close()\n return iterator.throw(error)\n },\n }\n streamActivities.set(stream, activity)\n bufferedEvents.set(stream, () => {\n const event = closed || !inner ? undefined : takeBuffered(inner)\n if (!event) return undefined\n if (!isSerializedEvent(event)) return toSessionEvent(id, event)\n // Taken rows belong to this stream alone.\n event.sessionId = id\n return event\n })\n return stream\n },\n }\n }\n\n // ── presence ──────────────────────────────────────────────\n\n const requirePresence = (\n store: A2Store,\n ): NonNullable<A2Store['presence']> => {\n if (!store.presence) throw presenceNotSupported()\n return store.presence\n }\n\n const setPresence = async (\n sessionId: string,\n patch: {\n participant: string\n values: Record<string, unknown>\n seen?: number\n at?: number\n },\n fallbackSeen: number,\n ): Promise<void> => {\n if (\n typeof patch.participant !== 'string' ||\n patch.participant.length === 0\n ) {\n throw new TypeError('presence participant must be a non-empty string')\n }\n if (RESERVED_PARTICIPANT_IDS.has(patch.participant)) {\n throw new TypeError(\n `presence participant must not be '${patch.participant}'`,\n )\n }\n if (\n patch.at !== undefined &&\n (typeof patch.at !== 'number' ||\n !Number.isFinite(patch.at) ||\n patch.at < 0 ||\n patch.at > MAX_DATE_MS)\n ) {\n throw new TypeError(\n 'presence at must be non-negative epoch milliseconds within the Date range',\n )\n }\n // Validate the whole patch before the adapter sees any of it — a\n // bad field means nothing is broadcast.\n const validated: Record<string, unknown> = nullProtoRecord()\n for (const [field, value] of Object.entries(patch.values)) {\n if (value === undefined) continue\n // '*' is a catch-all vocabulary entry: any field name (bar\n // object-plumbing names) validates against its schema. The\n // actor module declares it — presence vocabularies typed by the\n // protocol, values held to the JSON floor here.\n const schema = Object.hasOwn(presenceDefs, field)\n ? presenceDefs[field]\n : RESERVED_PARTICIPANT_IDS.has(field)\n ? undefined\n : presenceDefs['*']\n if (!schema) {\n throw new A2Error(\n 'UNKNOWN_PRESENCE_FIELD',\n `contract '${name}' has no presence field '${field}'`,\n )\n }\n if (value === null) {\n validated[field] = null\n continue\n }\n const result = validateSync(schema, value, `presence field '${field}'`)\n if (result.issues) {\n throw new A2Error(\n 'INVALID_PAYLOAD',\n `invalid value for presence field '${field}' on machine '${name}'`,\n { details: result.issues },\n )\n }\n validated[field] = result.value\n }\n const store = await resolveStore()\n try {\n await requirePresence(store).set(\n nsId(sessionId),\n patch.participant,\n validated,\n {\n seen: patch.seen ?? fallbackSeen,\n // The sender's stamp is the LWW order; receipt time is the\n // fallback for stampless callers (consumers, old wire\n // clients), where receipt order is sender order — single\n // writer. Storage anchors expiry on its own clock either way.\n at: new Date(patch.at ?? Date.now()),\n ttlMs: presenceTtlMs,\n },\n )\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n }\n\n const readPresenceMap = async (\n sessionId: string,\n ): Promise<PresenceMap<P>> => {\n const store = await resolveStore()\n let rows: PresenceRow[]\n try {\n rows = await requirePresence(store).read(nsId(sessionId))\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n return foldPresenceRows(rows) as PresenceMap<P>\n }\n\n /**\n * The two-plane feed. Patches ride `subscribe` when the adapter has\n * the push tier; without it the map is re-read and diffed whenever\n * the event feed wakes, and at the poll idle ceiling while it is\n * silent — degraded means later, not lost while watched.\n */\n const streamWithPresence = (\n id: string,\n startAfter: number,\n ): AsyncIterable<ContractEvent<D> | PresencePatch | PresenceSnapshot> => {\n const ns = nsId(id)\n let closed = false\n let events: AsyncIterator<Event> | undefined\n // An event read the merge loop started and has not yet yielded.\n let pendingEvent: Promise<IteratorResult<Event>> | null = null\n let unsubscribe: (() => void) | undefined\n let sleeper: Sleeper | null = null\n let wakeQueue: (() => void) | null = null\n let presenceInterval = Math.min(\n POLL_TIMINGS.activeFloorMs,\n POLL_TIMINGS.idleCeilingMs,\n )\n let presenceActivityVersion = 0\n let stopActivity: (() => void) | undefined\n const activity = createStreamActivity(() => {\n if (closed) return\n presenceActivityVersion += 1\n presenceInterval = Math.min(\n POLL_TIMINGS.activeFloorMs,\n POLL_TIMINGS.idleCeilingMs,\n )\n sleeper?.cancel()\n if (events) streamActivities.get(events)?.activate()\n })\n let closing: Promise<void> | undefined\n const close = (): Promise<void> => {\n closed = true\n sleeper?.cancel()\n wakeQueue?.()\n closing ??= (async () => {\n try {\n stopActivity?.()\n unsubscribe?.()\n } finally {\n await events?.return?.()\n }\n })()\n return closing\n }\n const outer = async function* (): AsyncGenerator<\n ContractEvent<D> | PresencePatch | PresenceSnapshot\n > {\n const store = await resolveStore()\n if (closed) return\n const api = requirePresence(store)\n\n const readRows = async (): Promise<PresenceRow[]> => {\n try {\n return await api.read(ns)\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n }\n\n // What this feed has already painted, per (participant, field) —\n // the comparison state for re-read diffs and for queued patches,\n // with the stamps of painted nulls kept beside it.\n const painted = new Map<\n string,\n Map<string, { seen: number; atMs: number; value: string }>\n >()\n const paintedDeletes = presenceTombstones()\n\n // One patch per (participant, field), never merged — a merged\n // stamp would let a stale field inherit a fresher sibling's\n // `seen` and survive the documented frontier reconciliation.\n const diffRows = (rows: PresenceRow[]): PresencePatch[] => {\n const patches: PresencePatch[] = []\n const live = new Map<string, Set<string>>()\n for (const row of rows) {\n let liveFields = live.get(row.participant)\n if (!liveFields) {\n liveFields = new Set()\n live.set(row.participant, liveFields)\n }\n liveFields.add(row.field)\n const stamp = {\n seen: row.seen,\n atMs: row.at.getTime(),\n value: fingerprint(row.value),\n }\n const prior = painted.get(row.participant)?.get(row.field)\n if (\n prior &&\n prior.seen === stamp.seen &&\n prior.atMs === stamp.atMs &&\n prior.value === stamp.value\n ) {\n continue\n }\n let paintedFields = painted.get(row.participant)\n if (!paintedFields) {\n paintedFields = new Map()\n painted.set(row.participant, paintedFields)\n }\n paintedFields.set(row.field, stamp)\n patches.push({\n participant: row.participant,\n values: { [row.field]: row.value },\n seen: row.seen,\n at: row.at,\n })\n }\n for (const [participant, fields] of painted) {\n for (const [field, prior] of fields) {\n if (live.get(participant)?.has(field)) continue\n fields.delete(field)\n patches.push({\n participant,\n values: { [field]: null },\n // A cleared field has no surviving row, so it keeps its\n // last painted stamps: only senders' clocks order the\n // plane, and an observer-stamped delete could outrank the\n // sender's next set.\n seen: prior.seen,\n at: new Date(prior.atMs),\n })\n }\n if (fields.size === 0) painted.delete(participant)\n }\n return patches\n }\n\n const paint = (patch: PresencePatch): void => {\n let fields = painted.get(patch.participant)\n for (const [field, value] of Object.entries(patch.values)) {\n const write = { participant: patch.participant, field, at: patch.at }\n if (value === null || value === undefined) {\n fields?.delete(field)\n if (value === null) paintedDeletes.keep(write)\n continue\n }\n paintedDeletes.drop(write)\n if (!fields) {\n fields = new Map()\n painted.set(patch.participant, fields)\n }\n fields.set(field, {\n seen: patch.seen,\n atMs: patch.at.getTime(),\n value: fingerprint(value),\n })\n }\n if (fields?.size === 0) painted.delete(patch.participant)\n }\n\n // Arrivals coalesce per (participant, field): latest value wins,\n // each field keeps its own seen/at stamps (never merged — a stale\n // field must not inherit a fresher sibling's `seen`), one patch\n // per (participant, field) on drain. A stalled consumer therefore\n // holds at most the live presence cardinality, never the arrival\n // history.\n const queue = new Map<\n string,\n Map<string, { value: unknown; seen: number; at: Date }>\n >()\n const enqueue = (patch: PresencePatch): void => {\n if (closed) return\n activity.activate()\n for (const [field, value] of Object.entries(patch.values)) {\n if (value === undefined) continue\n let fields = queue.get(patch.participant)\n if (!fields) {\n fields = new Map()\n queue.set(patch.participant, fields)\n }\n // Per-field LWW in the queue itself: pub/sub delivery order\n // is not apply order (two instances' PUBLISHes race), and an\n // unconditional overwrite would let an older patch swallow a\n // newer queued value that then never reaches the subscriber.\n // Ties go to the incoming patch, like every other comparator.\n const queued = fields.get(field)\n if (queued && queued.at.getTime() > patch.at.getTime()) continue\n fields.set(field, { value, seen: patch.seen, at: patch.at })\n }\n wakeQueue?.()\n }\n // A queued patch older than what this feed painted for its field —\n // the live value or its deletion — would repaint the past.\n const outdated = (\n write: Pick<PresenceRow, 'participant' | 'field' | 'at'>,\n ): boolean => {\n const prior = painted.get(write.participant)?.get(write.field)\n return (\n (prior !== undefined && prior.atMs > write.at.getTime()) ||\n paintedDeletes.outranks(write)\n )\n }\n const dequeue = (): PresencePatch | null => {\n for (const [participant, fields] of queue) {\n for (const [field, stamp] of fields) {\n fields.delete(field)\n if (fields.size === 0) queue.delete(participant)\n if (outdated({ participant, field, at: stamp.at })) continue\n return {\n participant,\n values: { [field]: stamp.value },\n seen: stamp.seen,\n at: stamp.at,\n }\n }\n queue.delete(participant)\n }\n return null\n }\n try {\n // Subscribe before the snapshot read: a patch landing between\n // the two is painted twice, never lost — repaints are idempotent.\n unsubscribe = api.subscribe?.(ns, enqueue)\n events = store.stream(ns, { startAfter })[Symbol.asyncIterator]()\n const sourceActivity = streamActivities.get(events)\n if (sourceActivity) {\n stopActivity = sourceActivity.subscribe(activity.setIdle)\n activity.setIdle(sourceActivity.idle)\n }\n // Exactly one snapshot before any live item: the pruned map,\n // per-field stamps exact — a reconnecting client replaces its\n // foreign entries wholesale from it.\n const snapshotRows = await readRows()\n if (closed) return\n for (const row of snapshotRows) {\n let fields = painted.get(row.participant)\n if (!fields) {\n fields = new Map()\n painted.set(row.participant, fields)\n }\n fields.set(row.field, {\n seen: row.seen,\n atMs: row.at.getTime(),\n value: fingerprint(row.value),\n })\n }\n yield { snapshot: foldPresenceRows(snapshotRows) }\n\n for (;;) {\n if (closed) return\n for (;;) {\n const patch = dequeue()\n if (!patch) break\n if (closed) return\n paint(patch)\n yield patch\n }\n pendingEvent ??= events.next()\n let woke: 'event' | 'patch' | 'tick'\n if (unsubscribe) {\n const arrival = new Promise<void>((resolve) => {\n wakeQueue = resolve\n })\n woke = await Promise.race([\n pendingEvent.then(() => 'event' as const),\n arrival.then(() => 'patch' as const),\n ])\n wakeQueue = null\n if (closed) return\n if (woke === 'patch') continue\n } else {\n sleeper = defaultSleep(presenceInterval)\n woke = await Promise.race([\n pendingEvent.then(() => 'event' as const),\n sleeper.promise.then(() => 'tick' as const),\n ])\n sleeper.cancel()\n sleeper = null\n }\n if (closed) return\n if (woke === 'event') {\n const result = await pendingEvent\n pendingEvent = null\n if (closed || result.done) return\n activity.activate()\n yield toSessionEvent(id, result.value)\n }\n if (!closed && !unsubscribe) {\n const version = presenceActivityVersion\n const rows = await readRows()\n if (closed) return\n const patches = diffRows(rows)\n if (patches.length > 0) activity.activate()\n else if (version === presenceActivityVersion) {\n presenceInterval = Math.min(\n presenceInterval * 2,\n POLL_TIMINGS.idleCeilingMs,\n )\n }\n for (const patch of patches) {\n if (closed) return\n yield patch\n }\n }\n }\n } finally {\n // The consumer may close while an event read is in flight; its\n // settlement is no longer anyone's business.\n pendingEvent?.catch(() => {})\n await close()\n wakeQueue = null\n }\n }\n const iterator = outer()\n return {\n [Symbol.asyncIterator]() {\n const stream = {\n next: () => iterator.next(),\n async return() {\n await close()\n return iterator.return(undefined)\n },\n async throw(error: unknown) {\n await close()\n return iterator.throw(error)\n },\n }\n streamActivities.set(stream, activity)\n bufferedEvents.set(stream, () => {\n // A held event may follow only events already yielded; while a\n // read is outstanding, its event must go first.\n if (closed || !events || pendingEvent) return undefined\n const event = takeBuffered(events)\n if (!event) return undefined\n if (!isSerializedEvent(event)) return toSessionEvent(id, event)\n // Taken rows belong to this stream alone.\n event.sessionId = id\n return event\n })\n return stream\n },\n }\n }\n\n // ── clearing (a2-implementation.md §17) ──────────────────────────\n\n const reclaimAll = async (store: A2Store, ns: string): Promise<void> => {\n for (let stalls = 0; ;) {\n let batch: StoreReclaimResult\n try {\n // oxlint-disable-next-line no-await-in-loop -- bounded batches, oldest first\n batch = await store.reclaim!(ns)\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n if (batch.done) return\n if (batch.deleted > 0) {\n stalls = 0\n continue\n }\n // Only rows other work holds locked remain; they free up shortly.\n stalls += 1\n if (stalls === RECLAIM_STALL_LIMIT) {\n throw new A2Error(\n 'STORE_UNAVAILABLE',\n `deleting the cleared history of session '${stripNs(ns)}' made no progress`,\n )\n }\n // oxlint-disable-next-line no-await-in-loop -- paced retry\n await defaultSleep(RECLAIM_STALL_MS).promise\n }\n }\n\n /** The consumer attempt a `ctx.session.clear()` belongs to. */\n type ClearingAttempt = {\n cause: EventCause\n end: () => void\n signal: AbortSignal\n }\n\n const clearSession = async (\n sessionId: string,\n clearOptions: SessionClearOptions | undefined,\n attempt: ClearingAttempt | undefined,\n ): Promise<SessionClearResult> => {\n const ifLastIndex = clearOptions?.ifLastIndex\n if (ifLastIndex !== undefined) assertClearIndex(ifLastIndex)\n const store = await resolveStore()\n if (!store.clear || !store.reclaim) {\n throw new TypeError(\n 'session.clear requires a store that supports clearing',\n )\n }\n const ns = nsId(sessionId)\n let result: StoreClearResult\n try {\n result = await store.clear({\n sessionId: ns,\n ...(ifLastIndex === undefined ? {} : { ifLastIndex }),\n ...(attempt ? { cause: attempt.cause } : {}),\n })\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n if (result.cleared) {\n // This instance's own reads after the clear, including the clearing\n // consumer's, go to the store and see the boundary.\n const cachePrefix = stateCacheKey(sessionId, '')\n stateCache.deleteWhere((key) => key.startsWith(cachePrefix))\n }\n const deletion = reclaimAll(store, ns)\n if (attempt) {\n if (attempt.cause.index <= result.clearIndex) attempt.end()\n // Ending the attempt releases its drain slot; the deletion must still\n // outlive the drain.\n const kept = deletion.catch(() => undefined)\n track(kept)\n platformWaitUntil(kept)\n }\n await deletion\n return { cleared: result.cleared, index: result.index }\n }\n\n // ── dead letters ─────────────────────────────────────────────────\n\n const redrivingStore = async (\n method: 'deadLetters' | 'redrive',\n ): Promise<A2Store & Required<Pick<A2Store, 'deadLetters' | 'redrive'>>> => {\n const store = await resolveStore()\n if (!store.deadLetters || !store.redrive) {\n throw new TypeError(\n `session.${method} requires a store that supports redriving dead letters`,\n )\n }\n return store as A2Store & Required<Pick<A2Store, 'deadLetters' | 'redrive'>>\n }\n\n const listDeadLetters = async (\n sessionId: string,\n ): Promise<DeadLetter<D>[]> => {\n const store = await redrivingStore('deadLetters')\n let rows: HeadEvent[]\n try {\n rows = await store.deadLetters(nsId(sessionId))\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n return rows.flatMap((row) =>\n row.failedAt === null\n ? []\n : [\n {\n ...toPublic(row),\n consumer: row.consumer,\n lane: row.lane,\n attemptCount: row.attemptCount,\n failureCount: row.failureCount,\n lastError: row.lastError,\n failedAt: row.failedAt,\n },\n ],\n )\n }\n\n const redriveEvent = async (\n sessionId: string,\n target: { consumer: string; index: number },\n redriveOptions: SessionRedriveOptions,\n ): Promise<SessionRedriveResult> => {\n const index = target?.index\n const redriven = target?.consumer\n assertRedriveIndex(index)\n if (typeof redriven !== 'string' || redriven.length === 0) {\n throw new TypeError('redrive requires a consumer name')\n }\n const action = redriveOptions?.action\n if (action !== 'retry' && action !== 'skip') {\n throw new TypeError(\"redrive requires action 'retry' or 'skip'\")\n }\n return telemetry.span(\n 'a2.redrive',\n {\n 'a2.contract': name,\n 'a2.session_id': sessionId,\n 'a2.redrive.index': index,\n 'a2.redrive.consumer': redriven,\n 'a2.redrive.action': action,\n },\n async (span) => {\n const store = await redrivingStore('redrive')\n let result: StoreRedriveResult\n try {\n result = await store.redrive({\n sessionId: nsId(sessionId),\n consumer: redriven,\n index,\n action,\n consumers: storeConsumers,\n })\n } catch (err) {\n throw asStoreUnavailable(err)\n }\n span.setAttribute('a2.redrive.redriven', result.redriven)\n // Healing like a top-level append, even when nothing was redriven, so\n // repeating a redrive whose wakeup was lost resumes the session.\n if (result.hasPending) {\n const watchdogAt = scheduler\n ? schedulerSlot(nextClaimWindow().watchdogAtMs)\n : undefined\n const arm =\n watchdogAt === undefined\n ? null\n : startSchedulerArm(sessionId, watchdogAt)\n scheduleDrain(sessionId, watchdogAt)\n if (arm) {\n try {\n await joinSchedulerArm(arm)\n } catch (err) {\n span.setAttribute('a2.redrive.armed', false)\n span.recordError(err)\n }\n }\n }\n return { redriven: result.redriven }\n },\n )\n }\n\n /**\n * `session.consume`: wakes the consumer's cursor, then drains only that\n * consumer until its head lies past `through`. A head another invocation\n * holds, or one waiting out a failure, is waited for; a dead-lettered head\n * throws.\n */\n /** Per session, which consumer's running head is waiting in `consume` on which: a cycle never ends. */\n const consumeWaits = new Map<string, Map<string, string>>()\n\n const consumeSession = (\n sessionId: string,\n defined: Consumer<D>,\n consumeOptions: SessionConsumeOptions = {},\n trigger: HeadEvent | null = null,\n ): Promise<SessionConsumeResult> => {\n assertSessionId(sessionId)\n if (defined?.contract?.name !== name || !defined.spec) {\n throw new TypeError(\n `session.consume for '${name}' got a consumer of another contract`,\n )\n }\n const own = definitions.get(defined.name)\n if (own !== undefined && own !== defined) {\n throw new TypeError(\n `this server runs a different consumer named '${defined.name}'`,\n )\n }\n if (defined.name === trigger?.consumer) {\n throw new TypeError(\n `consumer '${defined.name}' can't consume itself: its own head is running`,\n )\n }\n const registered = own\n ? registeredConsumers.get(defined.name)!\n : registrationOf(defined)\n const log = registered.log\n if (!log) {\n throw new TypeError(\n `consumer '${defined.name}' needs a string lane to be consumed: only then does it have one position`,\n )\n }\n const { through: requested, signal } = consumeOptions\n if (requested !== undefined) assertConsumeIndex(requested)\n // A run that waits on a consumer already waiting on it, here, would wait\n // forever. Checked and recorded before any await, so two can't both pass.\n // One that would close that cycle isn't recorded: it returns only if what\n // it asks for is done already, since the other's cursor can't move.\n const waiter = trigger?.consumer\n const waits =\n waiter === undefined\n ? undefined\n : (consumeWaits.get(sessionId) ??\n consumeWaits.set(sessionId, new Map()).get(sessionId)!)\n let cycle = false\n if (waiter !== undefined && waits) {\n for (\n let next: string | undefined = defined.name;\n next !== undefined && !cycle;\n next = waits.get(next)\n ) {\n cycle = next === waiter\n }\n if (!cycle) waits.set(waiter, defined.name)\n }\n const storeConsumer = { name: registered.name, log }\n const consumed = telemetry.span(\n 'a2.consume',\n {\n 'a2.contract': name,\n 'a2.session_id': sessionId,\n 'a2.consume.consumer': registered.name,\n },\n async (span) => {\n const store = await resolveStore()\n const ns = nsId(sessionId)\n let woken = await store.wakeLog({\n sessionId: ns,\n consumer: storeConsumer,\n })\n const through = Math.min(requested ?? woken.head, woken.head)\n span.setAttribute('a2.consume.through', through)\n const done = (): boolean =>\n woken.cursor.head === null || woken.cursor.head > through\n if (cycle && !done()) {\n throw new TypeError(\n `consumer '${waiter}' can't consume '${defined.name}' through ${through}: '${defined.name}' is waiting on it in session '${sessionId}'`,\n )\n }\n let drains = 0\n let wait = CONSUME_WAIT_MIN_MS\n while (!done()) {\n signal?.throwIfAborted()\n const { cursor } = woken\n if (cursor.failedAt !== null) {\n throw new A2Error(\n 'CONSUMER_DEAD_LETTERED',\n `consumer '${registered.name}' is dead-lettered at event ${cursor.head} in session '${sessionId}': ${cursor.lastError ?? 'every attempt ended before it finished'}`,\n )\n }\n drains += 1\n const drained = drainSession(sessionId, { only: registered, through })\n try {\n await untilAborted(drained, signal)\n } catch (error) {\n // An abort stops the wait at once; a run in progress carries on,\n // and what it appends still reaches the server's consumers.\n if (signal?.aborted)\n void drained.then(\n () => scheduleDrain(sessionId),\n () => {},\n )\n throw error\n }\n const before = cursor\n woken = await store.wakeLog({\n sessionId: ns,\n consumer: storeConsumer,\n })\n const moved =\n woken.cursor.head !== before.head ||\n woken.cursor.attemptCount !== before.attemptCount\n if (done() || moved) {\n wait = CONSUME_WAIT_MIN_MS\n continue\n }\n // Another invocation holds the head, or it waits out a failure.\n const sleep = defaultSleep(wait)\n const abort = (): void => sleep.cancel()\n signal?.addEventListener('abort', abort, { once: true })\n await sleep.promise\n signal?.removeEventListener('abort', abort)\n wait = Math.min(wait * 2, CONSUME_WAIT_MAX_MS)\n }\n // Work past `through` carries on in the background, as after an append,\n // and so do the server's consumers of what this consumer's runs appended.\n if (drains > 0 || (own && woken.cursor.head !== null))\n scheduleDrain(sessionId)\n const index =\n woken.cursor.head === null ? woken.head : woken.cursor.head - 1\n span.setAttribute('a2.consume.index', index)\n span.setAttribute('a2.consume.drains', drains)\n return { index }\n },\n )\n return waiter === undefined || cycle\n ? consumed\n : consumed.finally(() => {\n waits?.delete(waiter)\n if (waits?.size === 0) consumeWaits.delete(sessionId)\n })\n }\n\n const makeSession = <Append>(\n id: string,\n append: Append,\n trigger: HeadEvent | null,\n attempt?: ClearingAttempt,\n ): Session<D, Append, P> =>\n ({\n id,\n append,\n consume: (defined: Consumer<D>, consumeOptions?: SessionConsumeOptions) =>\n consumeSession(id, defined, consumeOptions, trigger),\n schedule: makeSchedule(id, trigger),\n clear: (clearOptions?: SessionClearOptions) =>\n clearSession(id, clearOptions, attempt),\n history: async (bounds?: { gte?: number; lte?: number }) =>\n (await readHistory(id, bounds))\n .filter((row) => !isSessionCleared(row))\n .map(toPublic),\n state: <S>(\n reducer: Reducer<\n D,\n S,\n Record<never, never>\n > = serverContract.reducer as unknown as Reducer<\n D,\n S,\n Record<never, never>\n >,\n stateOptions?: StateOptions,\n ) => {\n if (!reducer)\n throw new A2Error('INVALID_PAYLOAD', 'contract has no public reducer')\n const through = stateOptions?.through ?? trigger?.index\n if (through !== undefined && through !== 'latest') {\n assertStateIndex(through)\n }\n const bounds: StateReadBounds = {}\n if (through !== undefined && through !== 'latest') {\n bounds.throughIndex = through\n if (trigger) bounds.pin = headRefOf(trigger)\n // Only a live attempt may be answered from memory with no store\n // request; a superseded one (including by a clear) reads the store.\n if (through === trigger?.index && !attempt?.signal.aborted)\n bounds.throughEventId = trigger.id\n }\n if (trigger) bounds.triggerIndex = trigger.index\n return readState(id, reducer, bounds)\n },\n stream: (opts?: { startAfter?: number; presence?: boolean }) => {\n const startAfter = opts?.startAfter ?? 0\n assertStreamIndex(startAfter)\n return opts?.presence === true\n ? streamWithPresence(id, startAfter)\n : streamEvents(id, startAfter)\n },\n // Only on presence-declaring contracts — the type surface promises\n // no runtime-inert members (a2-api.md §12).\n ...(declaresPresence\n ? {\n setPresence: (patch: {\n participant: string\n values: Record<string, unknown>\n seen?: number\n at?: number\n }) => setPresence(id, patch, trigger?.index ?? 0),\n presence: () => readPresenceMap(id),\n }\n : {}),\n }) as Session<D, Append, P>\n\n // ── drain ────────────────────────────────────────────────────────\n\n /** The consumer name a trigger's child ids key on, if any. */\n const idConsumerOf = (trigger: HeadEvent): string | undefined =>\n registeredConsumers.get(trigger.consumer)?.anonymousIds\n ? undefined\n : trigger.consumer\n\n const makeCtx = (\n trigger: HeadEvent,\n attempt: number,\n signal: AbortSignal,\n endAttempt: () => void,\n ): ConsumerContext<D> => {\n const publicSessionId = stripNs(trigger.sessionId)\n const idConsumer = idConsumerOf(trigger)\n const cause: EventCause = {\n consumer: trigger.consumer,\n lane: trigger.lane,\n index: trigger.index,\n attempt,\n }\n const append: ConsumerAppend<D> = async (appendName, ...events) => {\n assertAppendName(appendName)\n const generatedIds = events.map((event) => event.id === undefined)\n const withIds = await Promise.all(\n // oxlint-disable-next-line no-map-spread\n events.map(async (event, item) => {\n if (event.id !== undefined) return event\n const id = await deterministicEventId(\n trigger.id,\n appendName,\n item,\n idConsumer,\n )\n return { ...event, id }\n }),\n )\n return appendCore(\n publicSessionId,\n withIds,\n 'consumer',\n 'inline',\n (_rows, watchdogDueAt) => scheduleDrain(publicSessionId, watchdogDueAt),\n cause,\n generatedIds,\n )\n }\n const ctx: ConsumerContext<D> = {\n event: toPublic(trigger),\n attempt,\n // The consumer-scoped `setPresence` stamps `seen` with the\n // triggering event's index by default — the frontier the consumer\n // provably reflects.\n session: makeSession(publicSessionId, append, trigger, {\n cause,\n end: endAttempt,\n signal,\n }),\n signal,\n }\n if (attempt > 1 && trigger.lastFailedAttempt === attempt - 1)\n failedPreviousAttempt.add(ctx)\n return ctx\n }\n\n const abortHubs = new Map<string, AbortHub>()\n\n const createAbortHub = (\n store: A2Store,\n ns: string,\n startAfter: number,\n ): AbortHub => {\n const hub: AbortHub = {\n subscriptions: new Set(),\n seen: new Map(),\n startAfter,\n ready: Promise.resolve(),\n watch: null,\n error: null,\n iterator: null,\n stopped: false,\n }\n hub.ready = (async () => {\n const existing = await store.read(ns, { afterIndex: startAfter })\n for (const event of existing) dispatchAbortEvent(hub, event)\n const tail = existing.at(-1)?.index ?? startAfter\n const feed = store.stream(ns, { startAfter: tail })\n const iterator = feed[Symbol.asyncIterator]()\n hub.iterator = iterator\n hub.watch = (async () => {\n for (;;) {\n const { value, done } = await iterator.next()\n if (done || value === undefined || hub.stopped) return\n dispatchAbortEvent(hub, value)\n }\n })().catch((error: unknown) => {\n hub.error = error\n })\n })().catch((error: unknown) => {\n hub.error = error\n if (abortHubs.get(ns) === hub) abortHubs.delete(ns)\n throw error\n })\n abortHubs.set(ns, hub)\n return hub\n }\n\n const subscribeAbort = async (\n store: A2Store,\n ns: string,\n trigger: StoredEvent,\n abortOn: AbortMatcher,\n attempt: number,\n ): Promise<{\n signal: AbortSignal\n monitor<T>(operation: Promise<T>): Promise<T>\n close(): Promise<void>\n }> => {\n let hub = abortHubs.get(ns)\n const created = hub === undefined\n if (!hub) hub = createAbortHub(store, ns, trigger.index)\n const activeTypes = new Set<string>()\n for (const active of hub.subscriptions) {\n for (const type of active.types) activeTypes.add(type)\n }\n const publicTrigger = toPublic(trigger)\n const subscription: AbortSubscription = {\n controller: new AbortController(),\n triggerIndex: trigger.index,\n types: new Set(abortOn.keys()),\n matches: (event) => {\n if (event.index <= trigger.index) return false\n const matcher = abortOn.get(event.type)\n if (matcher === undefined) return false\n return matcher === true\n ? true\n : matcher(toPublic(event as StoredEvent), publicTrigger, { attempt })\n },\n }\n hub.subscriptions.add(subscription)\n const needsCatchup =\n !created &&\n (trigger.index < hub.startAfter ||\n [...subscription.types].some((type) => !activeTypes.has(type)))\n if (needsCatchup) {\n const earlier = await store.read(ns, { afterIndex: trigger.index })\n hub.startAfter = Math.min(hub.startAfter, trigger.index)\n for (const event of earlier) dispatchAbortEvent(hub, event)\n }\n for (const event of hub.seen.values()) {\n if (subscription.matches(event)) subscription.controller.abort()\n }\n await hub.ready\n if (hub.error !== null) throw hub.error\n return {\n signal: subscription.controller.signal,\n monitor: async <T>(operation: Promise<T>): Promise<T> => {\n const outcome = await Promise.race([\n operation.then(\n (value) => ({ type: 'completed' as const, value }),\n (error: unknown) => ({ type: 'run-failed' as const, error }),\n ),\n hub.watch!.then(() =>\n hub.error === null\n ? { type: 'monitor-closed' as const }\n : { type: 'monitor-failed' as const, error: hub.error },\n ),\n ])\n if (outcome.type === 'completed') return outcome.value\n if (outcome.type === 'run-failed') throw outcome.error\n if (outcome.type === 'monitor-failed') {\n for (const active of hub.subscriptions) {\n active.controller.abort(outcome.error)\n }\n await operation.catch(() => {})\n throw outcome.error\n }\n await operation.catch(() => {})\n throw new Error('abort monitor closed while consumers were active')\n },\n close: async () => {\n hub.subscriptions.delete(subscription)\n if (hub.subscriptions.size > 0) {\n pruneAbortHub(hub)\n return\n }\n hub.stopped = true\n abortHubs.delete(ns)\n await hub.ready\n await hub.iterator?.return?.()\n await hub.watch\n },\n }\n }\n\n const returnedEvents = async (\n sessionId: string,\n trigger: HeadEvent,\n result: unknown,\n ): Promise<ReturnedEvent[]> => {\n if (result === undefined) return []\n const events = (\n Array.isArray(result) ? [...result] : [result]\n ) as AppendInput<D>[]\n if (events.length === 0) return []\n const idConsumer = idConsumerOf(trigger)\n const withIds = await Promise.all(\n // oxlint-disable-next-line oxc/no-map-spread -- consumer results remain caller-owned\n events.map(async (event, item) => {\n const withId = { ...event }\n withId.id =\n event.id ??\n (await deterministicReturnedEventId(trigger.id, item, idConsumer))\n return withId\n }),\n )\n return validateEvents(sessionId, withIds).map((event) =>\n Object.assign(event, {\n id: event.id!,\n cause: {\n consumer: trigger.consumer,\n lane: trigger.lane,\n index: trigger.index,\n attempt: trigger.attemptCount,\n },\n }),\n )\n }\n\n type EventStatus =\n 'processed' | 'failed' | 'dead_lettered' | 'superseded' | 'surrendered'\n\n type EventOutcome = {\n status: EventStatus\n opensLane: boolean\n appendsEvents: boolean\n }\n\n type DrainOptions = {\n watchdogDueAt?: number | undefined\n signal?: DrainSignal | undefined\n /** Return a failure after arming as `failed` instead of throwing it. */\n handOffFailure?: boolean\n /** Claim and run only this consumer's heads, for `consume`. */\n only?: RegisteredConsumer | undefined\n /** With `only`: claim no head past it; what's past it is the background's. */\n through?: number | undefined\n }\n\n const drainSession = async (\n sessionId: string,\n drainOptions: DrainOptions = {},\n ): Promise<DrainResult> => {\n const result = await runDrain(sessionId, drainOptions)\n // A settled `only` drain finished one consumer's heads, not the session's.\n if (result.settled && drainOptions.only === undefined)\n drainSettledHooks.get(self)?.(sessionId)\n return result\n }\n\n const runDrain = (\n sessionId: string,\n {\n watchdogDueAt,\n signal,\n handOffFailure = false,\n only,\n through,\n }: DrainOptions = {},\n ): Promise<DrainResult> =>\n telemetry.span(\n 'a2.drain',\n { 'a2.contract': name, 'a2.session_id': sessionId },\n async (span) => {\n const store = await resolveStore()\n const ns = nsId(sessionId)\n const holder = crypto.randomUUID()\n type ActiveEvent = {\n ref: HeadRef\n attempt: number\n execution: Promise<EventOutcome>\n supersede: AbortController\n /** Resolves the tracked execution early once supersession is durable. */\n fence: (outcome: EventOutcome) => void\n /** Local lease estimate: request time + ttl — at or before the store's. */\n expiresAtMs: number\n lapsed: boolean\n /**\n * Its completion is committing. A renewal may then find the cursor\n * already past the head; completion is the fence, not that report.\n */\n completing: boolean\n }\n /** Running heads, keyed by `headKey`: one event can run for several consumers. */\n const active = new Map<string, ActiveEvent>()\n const excluded = new Map<string, HeadRef>()\n let processed = 0\n let sawFailure = false\n let schedulerArm: Promise<void> | undefined\n let heartbeat: ReturnType<typeof setInterval> | null = null\n let lapseTimer: ReturnType<typeof setTimeout> | null = null\n let retryTimer: ReturnType<typeof setTimeout> | null = null\n let renewal: Promise<void> | null = null\n let stopRenewing = false\n\n // Self-fencing at local lease lapse: the drain wrote every expiry it\n // holds (request time + ttl, at or before the store's own stamp), so\n // it can conclude \"assume a successor\" with zero I/O — including\n // while the store is unreachable or in the first tick after a stall.\n const lapseDue = (): void => {\n lapseTimer = null\n const nowMs = Date.now()\n for (const entry of active.values()) {\n if (entry.lapsed || entry.expiresAtMs > nowMs) continue\n entry.lapsed = true\n entry.supersede.abort(\n new A2Error(\n 'CLAIM_EXPIRED',\n `the claim on event ${entry.ref.index} for consumer '${entry.ref.consumer}' in session '${sessionId}' lapsed without renewal`,\n ),\n )\n }\n scheduleLapse()\n }\n const scheduleLapse = (): void => {\n if (lapseTimer) {\n clearTimeout(lapseTimer)\n lapseTimer = null\n }\n let next = Number.POSITIVE_INFINITY\n for (const entry of active.values()) {\n if (!entry.lapsed) next = Math.min(next, entry.expiresAtMs)\n }\n if (next === Number.POSITIVE_INFINITY) return\n lapseTimer = setTimeout(lapseDue, Math.max(0, next - Date.now()))\n ;(lapseTimer as { unref?: () => void }).unref?.()\n }\n\n // A missed beat spends lease slack; the next scheduled beat may be\n // provably too late. Retry promptly (jittered against fleet-wide\n // synchronization on a struggling store) while a lease can still be\n // saved — the lapse ends the retries naturally.\n const scheduleRenewRetry = (): void => {\n if (stopRenewing || retryTimer) return\n const nowMs = Date.now()\n const saveable = [...active.values()].some(\n (entry) => !entry.lapsed && entry.expiresAtMs > nowMs,\n )\n if (!saveable) return\n const delay = DRAIN_TIMINGS.renewRetryMs * (0.5 + Math.random() * 0.5)\n retryTimer = setTimeout(() => {\n retryTimer = null\n void renew()\n }, delay)\n ;(retryTimer as { unref?: () => void }).unref?.()\n }\n\n const alignWatchdogAt = (minimumDueAt: number): number => {\n if (watchdogDueAt === undefined) return minimumDueAt\n const beats = Math.max(\n 0,\n Math.ceil(\n (minimumDueAt - watchdogDueAt) / DRAIN_TIMINGS.claimHeartbeatMs,\n ),\n )\n return watchdogDueAt + beats * DRAIN_TIMINGS.claimHeartbeatMs\n }\n\n const requestWatchdog = (dueAt: number): void => {\n const arm = startSchedulerArm(sessionId, alignWatchdogAt(dueAt))\n if (arm) schedulerArm = arm\n }\n\n const renew = (): Promise<void> => {\n if (stopRenewing || renewal || active.size === 0) {\n return renewal ?? Promise.resolve()\n }\n const window = nextClaimWindow()\n requestWatchdog(window.watchdogAtMs)\n const claims = [...active.values()].map((entry) => ({\n ...entry.ref,\n attempt: entry.attempt,\n }))\n const operation = store\n .renewClaims({\n sessionId: ns,\n holder,\n claims,\n ttlMs: window.ttlMs,\n ...(window.deadlineCapped\n ? { expiresAtMs: window.expiresAtMs }\n : {}),\n })\n .then(\n (result) => {\n for (const ref of result.renewed) {\n const entry = active.get(headKey(ref))\n if (entry && !entry.lapsed) {\n entry.expiresAtMs = window.expiresAtMs\n }\n }\n for (const ref of result.superseded) {\n const entry = active.get(headKey(ref))\n if (!entry || entry.completing) continue\n // Idempotent: the local lapse normally aborted this signal\n // already — this is the proof, whose job is the release.\n endSuperseded(\n entry,\n `a newer attempt owns event ${ref.index} for consumer '${ref.consumer}' in session '${sessionId}'`,\n )\n }\n if (window.deadlineCapped) stopRenewing = true\n scheduleLapse()\n return undefined\n },\n () => {\n scheduleRenewRetry()\n return undefined\n },\n )\n let tracked!: Promise<void>\n tracked = operation.finally(() => {\n if (renewal === tracked) renewal = null\n })\n renewal = tracked\n return tracked\n }\n\n /** Records a head the store dead-lettered on takeover; it never runs. */\n const reportExhausted = (event: HeadEvent): Promise<void> =>\n telemetry.span(\n 'a2.event',\n {\n 'a2.contract': name,\n 'a2.session_id': sessionId,\n 'a2.event.type': event.type,\n 'a2.event.index': event.index,\n 'a2.event.id': event.id,\n 'a2.event.consumer': event.consumer,\n 'a2.event.attempt': event.attemptCount,\n 'a2.event.handled': registeredConsumers.has(event.consumer),\n ...(event.lane === null ? {} : { 'a2.event.lane': event.lane }),\n },\n async (eventSpan) => {\n eventSpan.setAttribute('a2.event.outcome', 'dead_lettered')\n },\n )\n\n const runEvent = async (\n event: HeadEvent,\n supersedeSignal: AbortSignal,\n endAttempt: () => void,\n beginCompleting: () => void,\n sessionHead: number | undefined,\n ): Promise<EventOutcome> => {\n const registration =\n only?.name === event.consumer\n ? only\n : registeredConsumers.get(event.consumer)\n const abortOn = registration?.abortOn(event.type) ?? null\n return telemetry.span(\n 'a2.event',\n {\n 'a2.contract': name,\n 'a2.session_id': sessionId,\n 'a2.event.type': event.type,\n 'a2.event.index': event.index,\n 'a2.event.id': event.id,\n 'a2.event.consumer': event.consumer,\n 'a2.event.attempt': event.attemptCount,\n 'a2.event.handled': registration !== undefined,\n 'a2.event.age_ms': Math.max(\n 0,\n Date.now() - event.createdAt.getTime(),\n ),\n ...(sessionHead === undefined\n ? {}\n : { 'a2.event.lag': Math.max(0, sessionHead - event.index) }),\n ...(event.lane === null ? {} : { 'a2.event.lane': event.lane }),\n },\n async (eventSpan) => {\n let subscription:\n | {\n signal: AbortSignal\n monitor<T>(operation: Promise<T>): Promise<T>\n close(): Promise<void>\n }\n | undefined\n let runSignal = supersedeSignal\n let completion: CompleteAttemptResult\n let completing = false\n try {\n if (abortOn) {\n subscription = await subscribeAbort(\n store,\n ns,\n event,\n abortOn,\n event.attemptCount,\n )\n runSignal = AbortSignal.any([\n supersedeSignal,\n subscription.signal,\n ])\n }\n const operation = registration?.run(\n makeCtx(event, event.attemptCount, runSignal, endAttempt),\n )\n const result = operation\n ? await (subscription\n ? subscription.monitor(operation)\n : operation)\n : undefined\n if (subscription) {\n await subscription.close()\n subscription = undefined\n }\n const returned = await returnedEvents(sessionId, event, result)\n await renewal\n completing = true\n beginCompleting()\n completion = await telemetry.span(\n 'a2.commit',\n {\n 'a2.contract': name,\n 'a2.session_id': sessionId,\n 'a2.commit.operation': 'complete',\n 'a2.commit.index': event.index,\n 'a2.commit.attempt': event.attemptCount,\n },\n async (commitSpan) => {\n const committed = await store.completeAttempt({\n sessionId: ns,\n consumer: event.consumer,\n lane: event.lane,\n index: event.index,\n attempt: event.attemptCount,\n events: returned,\n consumers: storeConsumers,\n })\n commitSpan.setAttribute(\n 'a2.commit.outcome',\n committed.outcome,\n )\n return committed\n },\n )\n } catch (err) {\n if (supersedeSignal.aborted && err === supersedeSignal.reason) {\n // The consumer surrendered to its own abort — identity, not\n // code, so it cannot arrive from another context. A lapse\n // is not a consumer failure: no completion; the claim simply\n // expires, and the claim that takes it over counts it.\n eventSpan.setAttribute('a2.event.outcome', 'surrendered')\n return {\n status: 'surrendered',\n opensLane: false,\n appendsEvents: false,\n }\n }\n const refused =\n completing &&\n err instanceof A2Error &&\n err.code === 'PARTIAL_DUPLICATE_BATCH'\n // A store that cannot record the completion is not the\n // consumer failing: the claim lapses, and the claim that takes\n // it over counts it. A returned batch it refuses is.\n if (completing && !refused) throw err\n // Everything else — including a store fence rejection — is\n // adjudicated by failAttempt, which is itself fenced: a\n // genuinely superseded attempt gets 'superseded' back with\n // no mutation. One adjudicator, not two.\n eventSpan.recordError(err)\n const failure = await telemetry.span(\n 'a2.commit',\n {\n 'a2.contract': name,\n 'a2.session_id': sessionId,\n 'a2.commit.operation': 'fail',\n 'a2.commit.index': event.index,\n 'a2.commit.attempt': event.attemptCount,\n },\n async (commitSpan) => {\n const result = await store.failAttempt({\n sessionId: ns,\n consumer: event.consumer,\n lane: event.lane,\n index: event.index,\n attempt: event.attemptCount,\n error: describeError(err),\n // A NonRetriableError is terminal on its first throw,\n // and so is a refused batch, whose retry returns the\n // same ids: deterministic failures should not burn the\n // retry budget before dead-lettering.\n maxFailures:\n err instanceof NonRetriableError || refused\n ? 1\n : MAX_FAILURES,\n retryAfterMs: failureRetryDelayMs(event.failureCount + 1),\n })\n commitSpan.setAttribute('a2.commit.outcome', result.outcome)\n return result\n },\n )\n eventSpan.setAttribute('a2.event.outcome', failure.outcome)\n return {\n status: failure.outcome,\n opensLane: false,\n appendsEvents: false,\n }\n } finally {\n await subscription?.close()\n }\n eventSpan.setAttribute(\n 'a2.event.outcome',\n completion.outcome === 'completed'\n ? 'processed'\n : completion.outcome,\n )\n if (completion.outcome === 'superseded') {\n return {\n status: 'superseded',\n opensLane: false,\n appendsEvents: false,\n }\n }\n if (runSignal.aborted) {\n eventSpan.setAttribute('a2.event.aborted', true)\n }\n return {\n status: 'processed',\n opensLane: event.lane !== null,\n appendsEvents: completion.events.length > 0,\n }\n },\n )\n }\n\n let claimAgain = false\n\n const start = (\n event: HeadEvent,\n expiresAtMs: number,\n sessionHead: number | undefined,\n ): void => {\n const ref = headRefOf(event)\n const key = headKey(ref)\n // Re-claiming a head this drain still tracks is durable proof\n // that the old attempt lost: our own new claim advanced the\n // ordinal. Fence the old entry before it can be confused with\n // the new one.\n const previous = active.get(key)\n if (previous) {\n endSuperseded(\n previous,\n `a newer attempt owns event ${event.index} for consumer '${event.consumer}' in session '${sessionId}'`,\n )\n }\n const supersede = new AbortController()\n let fence!: (outcome: EventOutcome) => void\n const fenced = new Promise<EventOutcome>((resolve) => {\n fence = resolve\n })\n // A consumer's own committed clear supersedes it immediately.\n const endAttempt = (): void =>\n endSuperseded(\n { supersede, fence },\n `event ${event.index} for consumer '${event.consumer}' in session '${sessionId}' was cleared`,\n )\n // The race lets a durable supersession release this slot while the\n // zombie consumer keeps running — its completion and failure are\n // fenced by the store, so nothing it does from here is counted.\n let entry!: ActiveEvent\n const execution = Promise.race([\n runEvent(\n event,\n supersede.signal,\n endAttempt,\n () => {\n entry.completing = true\n },\n sessionHead,\n ),\n fenced,\n ]).then((eventOutcome) => {\n // Identity-guarded: a fenced predecessor's continuation must\n // not delete the entry of the attempt that replaced it.\n if (active.get(key) === entry) active.delete(key)\n if (eventOutcome.status === 'processed') processed += 1\n if (eventOutcome.status === 'failed') {\n excluded.set(key, ref)\n sawFailure = true\n }\n claimAgain ||= eventOutcome.opensLane || eventOutcome.appendsEvents\n return eventOutcome\n })\n entry = {\n ref,\n attempt: event.attemptCount,\n execution,\n supersede,\n fence,\n expiresAtMs,\n lapsed: false,\n completing: false,\n }\n active.set(key, entry)\n scheduleLapse()\n if (!heartbeat && !stopRenewing) {\n heartbeat = setInterval(\n () => void renew(),\n DRAIN_TIMINGS.claimHeartbeatMs,\n )\n ;(heartbeat as { unref?: () => void }).unref?.()\n }\n }\n\n let outcome: DrainOutcome = 'settled'\n let shouldClaim = true\n try {\n for (;;) {\n const signalVersion = signal?.version ?? 0\n let claim: StoreClaimAvailableResult | undefined\n if (shouldClaim) {\n const window = nextClaimWindow()\n if (window.pastDeadline) {\n outcome = 'busy'\n break\n }\n claim = await telemetry.span(\n 'a2.claim',\n { 'a2.contract': name, 'a2.session_id': sessionId },\n async (claimSpan) => {\n const result = await store.claimAvailable({\n sessionId: ns,\n holder,\n ttlMs: window.ttlMs,\n maxFailures: MAX_FAILURES,\n ...(window.deadlineCapped\n ? { expiresAtMs: window.expiresAtMs }\n : {}),\n consumers: only ? [storeConsumerOf(only)] : storeConsumers,\n ...(through === undefined ? {} : { through }),\n ...(excluded.size === 0\n ? {}\n : { exclude: [...excluded.values()] }),\n })\n claimSpan.setAttribute('a2.claim.outcome', result.outcome)\n claimSpan.setAttribute(\n 'a2.claim.count',\n result.outcome === 'claimed' ? result.events.length : 0,\n )\n return result\n },\n )\n if (claim.outcome === 'claimed') {\n // A takeover that spent the last failed attempt comes back\n // dead-lettered instead of claimed.\n const runnable = claim.events.filter(\n (event) => event.failedAt === null,\n )\n for (const event of claim.events)\n if (event.failedAt !== null) await reportExhausted(event)\n if (runnable.length > 0) requestWatchdog(window.watchdogAtMs)\n if (window.deadlineCapped) stopRenewing = true\n for (const event of runnable)\n start(event, window.expiresAtMs, claim.head)\n shouldClaim = false\n }\n }\n if (\n claim?.outcome === 'claimed' &&\n [...active.values()].some((entry) => entry.lapsed)\n ) {\n shouldClaim = true\n continue\n }\n if (active.size > 0) {\n const wake = signal?.wait(signalVersion)\n const hasLapsed = [...active.values()].some(\n (entry) => entry.lapsed,\n )\n const retry =\n claim?.outcome === 'busy' && hasLapsed\n ? defaultSleep(\n Math.max(0, claim.retryAt.getTime() - Date.now()),\n )\n : undefined\n const retryDue = await Promise.race([\n ...[...active.values()].map((entry) =>\n entry.execution.then(() => false),\n ),\n ...(wake ? [wake.promise.then(() => false)] : []),\n ...(retry ? [retry.promise.then(() => true)] : []),\n ])\n wake?.cancel()\n retry?.cancel()\n shouldClaim =\n retryDue ||\n claimAgain ||\n active.size === 0 ||\n hasLapsed ||\n (signal !== undefined && signal.version !== signalVersion)\n claimAgain = false\n continue\n }\n if (!shouldClaim) {\n shouldClaim = true\n continue\n }\n if (claim === undefined) continue\n if (signal && signal.version !== signalVersion) continue\n // A run that finished while the claim was in flight may have\n // moved its cursor to a head the claim's snapshot missed.\n if (claimAgain) {\n claimAgain = false\n continue\n }\n if (claim.outcome === 'busy') {\n requestWatchdog(\n claim.retryAt.getTime() + DRAIN_TIMINGS.watchdogGraceMs,\n )\n outcome = 'busy'\n } else if (sawFailure) {\n outcome = 'stalled'\n }\n if (signal) signal.closed = true\n break\n }\n } catch (error) {\n // The successor armed for this drain's claims drains the session\n // again, so the scheduler delivery need not stay as a second retry.\n if (!handOffFailure || schedulerArm === undefined) throw error\n span.recordError(error)\n outcome = 'failed'\n } finally {\n if (signal) signal.closed = true\n stopRenewing = true\n if (heartbeat) clearInterval(heartbeat)\n if (retryTimer) clearTimeout(retryTimer)\n await renewal\n await Promise.allSettled(\n [...active.values()].map((entry) => entry.execution),\n )\n if (lapseTimer) clearTimeout(lapseTimer)\n }\n span.setAttribute('a2.drain.processed', processed)\n span.setAttribute('a2.drain.outcome', outcome)\n return {\n settled: outcome === 'settled',\n outcome,\n processed,\n ...(schedulerArm ? { schedulerArm } : {}),\n }\n },\n )\n\n // ── public surface ───────────────────────────────────────────────\n\n const appendExternal = async (\n sessionId: string,\n mode: 'inline' | 'dispatch',\n events: AppendInput<D>[],\n requireDurableInitialArm = false,\n originIndex?: number,\n ): Promise<ContractEvent<D>[]> => {\n return appendCore(\n sessionId,\n events,\n 'external',\n mode,\n (_rows, watchdogDueAt) => scheduleDrain(sessionId, watchdogDueAt),\n undefined,\n undefined,\n requireDurableInitialArm,\n originIndex,\n )\n }\n\n const session = (\n id: string,\n ): Session<D, SessionAppend<D>, P> & SessionDeadLetters<D> => {\n assertSessionId(id)\n const appendInline = async (...events: AppendInput<D>[]) =>\n appendExternal(id, 'inline', events)\n const appendDispatch = async (...events: AppendInput<D>[]) =>\n appendExternal(id, 'dispatch', events)\n const append = Object.assign(appendInline, {\n dispatch: appendDispatch,\n }) as SessionAppend<D>\n return Object.assign(makeSession(id, append, null), {\n deadLetters: () => listDeadLetters(id),\n redrive: (\n target: { consumer: string; index: number },\n redriveOptions: SessionRedriveOptions,\n ) => redriveEvent(id, target, redriveOptions),\n })\n }\n\n const historyPage = async (\n sessionId: string,\n bounds: { gte: number; lte: number },\n ): Promise<{ events: ContractEvent<D>[]; clearIndex?: number }> => {\n assertSessionId(sessionId)\n const rows = await readHistory(sessionId, bounds)\n // Reads start at the latest marker, so it can only lead the page.\n const marker = rows[0] && isSessionCleared(rows[0]) ? rows[0] : undefined\n return {\n events: (marker ? rows.slice(1) : rows).map(toPublic),\n ...(marker ? { clearIndex: marker.index } : {}),\n }\n }\n\n const fetch = createServerFetch({\n contract: serverContract,\n session,\n historyPage,\n })\n const self: A2Server<D, P, R> = {\n contract: serverContract,\n fetch,\n session: session as A2Server<D, P, R>['session'],\n\n async drain(sessionId) {\n assertSessionId(sessionId)\n const { settled } = await drainSession(sessionId)\n return { settled }\n },\n }\n\n serverInternals.set(self, {\n settle: async () => {\n while (inFlight.size > 0) {\n await Promise.allSettled(inFlight)\n }\n },\n schedulerDrain: (sessionId, opts) => {\n assertSessionId(sessionId)\n return drainSession(sessionId, {\n watchdogDueAt: opts?.watchdogDueAt,\n handOffFailure: true,\n })\n },\n schedulerAppend: async (sessionId, events, originIndex) => {\n if (!scheduler) {\n throw new TypeError(\n 'scheduled append delivery requires a configured scheduler adapter',\n )\n }\n assertSessionId(sessionId)\n try {\n await appendExternal(\n sessionId,\n 'inline',\n [...events],\n true,\n originIndex,\n )\n } catch (error) {\n // The scheduling consumer's lifetime was cleared: an acknowledged no-op.\n if (\n originIndex !== undefined &&\n error instanceof A2Error &&\n error.code === 'SESSION_CLEARED'\n )\n return\n throw error\n }\n },\n historyWithMarkers: async (sessionId, gte) =>\n (await readHistory(sessionId, { gte })).map(toPublic),\n schedulerClear: async (sessionId, ifLastIndex) => {\n assertSessionId(sessionId)\n assertClearIndex(ifLastIndex)\n await clearSession(sessionId, { ifLastIndex }, undefined)\n },\n })\n return self\n}\n\nfunction assertSessionId(id: string): void {\n if (typeof id !== 'string' || id.length === 0) {\n throw new TypeError('session id must be a non-empty string')\n }\n if (id.includes(NS)) {\n throw new TypeError('session id contains a reserved control character')\n }\n}\n\nfunction assertHistoryIndex(name: 'gte' | 'lte', value?: number): void {\n if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {\n throw new TypeError(`history.${name} must be a non-negative safe integer`)\n }\n}\n\nfunction assertStreamIndex(value: number): void {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new TypeError('stream.startAfter must be a non-negative safe integer')\n }\n}\n\nfunction assertStateIndex(value: number): void {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new TypeError('state.through must be a non-negative safe integer')\n }\n}\n\nfunction assertConsumeIndex(value: number): void {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new TypeError('consume through must be a non-negative safe integer')\n }\n}\n\nfunction assertRedriveIndex(value: number): void {\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new TypeError('redrive requires a positive safe-integer index')\n }\n}\n\nfunction assertClearIndex(value: number): void {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new TypeError('ifLastIndex must be a non-negative safe integer')\n }\n}\n\nfunction assertAppendName(name: string): void {\n if (typeof name !== 'string' || name.length === 0) {\n throw new TypeError('consumer append name must be a non-empty string')\n }\n}\n\nfunction assertScheduleName(name: string): void {\n if (typeof name !== 'string' || name.length === 0) {\n throw new TypeError('schedule name must be a non-empty string')\n }\n}\n\nconst SCHEDULE_DELAY = /^(?:0|[1-9]\\d*)(?:\\.\\d+)?(ms|s|m|h|d)$/\nconst SCHEDULE_DELAY_MULTIPLIER: Record<'ms' | 's' | 'm' | 'h' | 'd', number> =\n {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n }\n\nfunction scheduleDueAt(timing: ScheduleTiming, baseTime: number): number {\n if (timing === null || typeof timing !== 'object' || Array.isArray(timing)) {\n throw new TypeError(\n \"schedule timing must contain exactly one of 'delay' or 'at'\",\n )\n }\n const record = timing as Record<string, unknown>\n const hasDelay = Object.hasOwn(record, 'delay')\n const hasAt = Object.hasOwn(record, 'at')\n if (hasDelay === hasAt) {\n throw new TypeError(\n \"schedule timing must contain exactly one of 'delay' or 'at'\",\n )\n }\n\n let dueAt: number\n if (hasAt) {\n const at = record['at']\n if (!(at instanceof Date) || !Number.isFinite(at.getTime())) {\n throw new TypeError('schedule at must be a valid Date')\n }\n dueAt = at.getTime()\n } else {\n const delay = record['delay']\n if (typeof delay !== 'string') {\n throw new TypeError(\n \"schedule delay must use ms, s, m, h, or d (for example '30s')\",\n )\n }\n const match = SCHEDULE_DELAY.exec(delay)\n const amount = match ? Number(delay.slice(0, -match[1]!.length)) : NaN\n if (!match || !Number.isFinite(amount) || amount <= 0) {\n throw new TypeError(\n \"schedule delay must be positive and use ms, s, m, h, or d (for example '30s')\",\n )\n }\n dueAt =\n baseTime +\n amount *\n SCHEDULE_DELAY_MULTIPLIER[\n match[1] as keyof typeof SCHEDULE_DELAY_MULTIPLIER\n ]\n }\n if (!Number.isFinite(dueAt)) {\n throw new TypeError('schedule due time must be a finite epoch time')\n }\n return dueAt\n}\n\nfunction assertScheduledPayload(payload: unknown): void {\n try {\n if (isJsonValue(payload, new WeakSet())) return\n } catch {\n // Proxies and hostile accessors are not stable transport values either.\n }\n throw new TypeError(\n 'session.schedule event payload must be JSON-serializable',\n )\n}\n\nfunction cloneScheduledPayload(payload: unknown): unknown {\n assertScheduledPayload(payload)\n try {\n const cloned = structuredClone(payload)\n const encoded = JSON.stringify(cloned)\n if (encoded === undefined) throw new TypeError()\n return JSON.parse(encoded) as unknown\n } catch {\n throw new TypeError(\n 'session.schedule event payload must be JSON-serializable',\n )\n }\n}\n\nfunction isJsonValue(value: unknown, ancestors: WeakSet<object>): boolean {\n if (value === null) return true\n if (typeof value === 'string' || typeof value === 'boolean') return true\n if (typeof value === 'number') {\n return Number.isFinite(value) && !Object.is(value, -0)\n }\n if (typeof value !== 'object') return false\n if (ancestors.has(value)) return false\n ancestors.add(value)\n try {\n if (Array.isArray(value)) {\n const keys = Reflect.ownKeys(value)\n if (keys.length !== value.length + 1 || !keys.includes('length')) {\n return false\n }\n for (let index = 0; index < value.length; index += 1) {\n const descriptor = Object.getOwnPropertyDescriptor(value, String(index))\n if (\n !descriptor ||\n !descriptor.enumerable ||\n !('value' in descriptor) ||\n !isJsonValue(descriptor.value, ancestors)\n ) {\n return false\n }\n }\n return true\n }\n const prototype = Object.getPrototypeOf(value)\n if (prototype !== Object.prototype) return false\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== 'string') return false\n const descriptor = Object.getOwnPropertyDescriptor(value, key)\n if (\n !descriptor ||\n !descriptor.enumerable ||\n !('value' in descriptor) ||\n !isJsonValue(descriptor.value, ancestors)\n ) {\n return false\n }\n }\n return true\n } finally {\n ancestors.delete(value)\n }\n}\n\nconst measuredBytes = (\n reducer: object,\n state: unknown,\n index: number,\n snapshots: StoreSnapshotWrite[],\n): number =>\n JSON.stringify(\n snapshots.find((snapshot) => snapshot.index === index)?.state ??\n encodeState({ reducer, state }),\n )?.length ?? 0\n\nconst stateCacheKey = (sessionId: string, reducerName: string): string =>\n `${sessionId}\\u0000${reducerName}`\n\n// Server-side types users need when passing custom stores or building\n// transports — re-exported so experimental-a2/server is self-sufficient.\nexport type {\n A2Store,\n AppendEvent,\n Clock,\n Event,\n EventCause,\n FailAttemptResult,\n IdSource,\n StoreAppendResult,\n StoreClaimAvailableResult,\n StoreStateRead,\n PresenceRow,\n StoredEvent,\n} from './store.ts'\nexport type {\n ScheduledEvent,\n SchedulerAppendTask,\n SchedulerClearTask,\n SchedulerDrainTask,\n SchedulerTask,\n} from './scheduler-task.ts'\nexport type {\n AppendInput,\n Contract,\n ContractEvent,\n EventDefs,\n PresenceDefs,\n PresenceMap,\n PresencePatch,\n PresenceSnapshot,\n} from './contract.ts'\n"],"mappings":"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"}