experimental-a2 0.19.0 → 0.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +1 -1
  3. package/dist/{actor-C7b-1arn.d.ts → actor-HnGmrOZZ.d.ts} +5 -5
  4. package/dist/{actor-C7b-1arn.d.ts.map → actor-HnGmrOZZ.d.ts.map} +1 -1
  5. package/dist/actor-client.d.ts +1 -1
  6. package/dist/actor-client.js +2 -2
  7. package/dist/actor-react.d.ts +3 -3
  8. package/dist/actor-react.js +5 -5
  9. package/dist/{actor-shared-t7w8xIKP.js → actor-shared-DFET5q16.js} +3 -3
  10. package/dist/{actor-shared-t7w8xIKP.js.map → actor-shared-DFET5q16.js.map} +1 -1
  11. package/dist/actor.d.ts +1 -1
  12. package/dist/actor.js +54 -43
  13. package/dist/actor.js.map +1 -1
  14. package/dist/{ai-Cz3hqVhk.d.ts → ai-CvEnqVfo.d.ts} +8 -8
  15. package/dist/{ai-Cz3hqVhk.d.ts.map → ai-CvEnqVfo.d.ts.map} +1 -1
  16. package/dist/{ai-mMiWul1T.js → ai-CzE672Q3.js} +9 -9
  17. package/dist/ai-CzE672Q3.js.map +1 -0
  18. package/dist/ai-client.d.ts +2 -2
  19. package/dist/ai-client.js +2 -2
  20. package/dist/ai-fx.d.ts +1 -1
  21. package/dist/ai-fx.d.ts.map +1 -1
  22. package/dist/ai-fx.js +36 -9
  23. package/dist/ai-fx.js.map +1 -1
  24. package/dist/{ai-harness-CV6rXbB3.d.ts → ai-harness-Bfk-Lycn.d.ts} +2 -2
  25. package/dist/ai-harness-Bfk-Lycn.d.ts.map +1 -0
  26. package/dist/{ai-harness-BuuC-gJ3.js → ai-harness-dQeJaR1t.js} +17 -4
  27. package/dist/ai-harness-dQeJaR1t.js.map +1 -0
  28. package/dist/ai-pi.d.ts +1 -1
  29. package/dist/ai-pi.js +4 -4
  30. package/dist/ai-pi.js.map +1 -1
  31. package/dist/ai-react.d.ts +5 -5
  32. package/dist/ai-react.js +2 -2
  33. package/dist/ai-server.d.ts +14 -17
  34. package/dist/ai-server.d.ts.map +1 -1
  35. package/dist/ai-server.js +84 -75
  36. package/dist/ai-server.js.map +1 -1
  37. package/dist/ai.d.ts +2 -2
  38. package/dist/ai.js +2 -2
  39. package/dist/{client-BhHLoNKF.js → client-9IeTsiAs.js} +5 -5
  40. package/dist/{client-BhHLoNKF.js.map → client-9IeTsiAs.js.map} +1 -1
  41. package/dist/{client-h_DKFAjj.d.ts → client-CUMbS_38.d.ts} +3 -3
  42. package/dist/{client-h_DKFAjj.d.ts.map → client-CUMbS_38.d.ts.map} +1 -1
  43. package/dist/client.d.ts +3 -3
  44. package/dist/client.js +1 -1
  45. package/dist/{contract-BYKASlCV.js → contract-CWukt01d.js} +2 -2
  46. package/dist/contract-CWukt01d.js.map +1 -0
  47. package/dist/index.d.ts +5 -5
  48. package/dist/index.js +3 -3
  49. package/dist/{initial-snapshot-Bx-c0pDP.d.ts → initial-snapshot-D3Lve43o.d.ts} +4 -4
  50. package/dist/initial-snapshot-D3Lve43o.d.ts.map +1 -0
  51. package/dist/{internal-CscSY7K_.js → internal-Bc4PvfHk.js} +10 -3
  52. package/dist/internal-Bc4PvfHk.js.map +1 -0
  53. package/dist/otel.d.ts +1 -1
  54. package/dist/otel.js +1 -1
  55. package/dist/otel.js.map +1 -1
  56. package/dist/{react-BBXgHWFc.d.ts → react-BoHvC3v9.d.ts} +4 -4
  57. package/dist/{react-BBXgHWFc.d.ts.map → react-BoHvC3v9.d.ts.map} +1 -1
  58. package/dist/react.d.ts +1 -1
  59. package/dist/react.js +1 -1
  60. package/dist/{reducer-CqA59Q6U.d.ts → reducer-CYPHsSmd.d.ts} +2 -2
  61. package/dist/{reducer-CqA59Q6U.d.ts.map → reducer-CYPHsSmd.d.ts.map} +1 -1
  62. package/dist/{reducer-BAXc8JyF.js → reducer-CjmvZSAb.js} +2 -2
  63. package/dist/{reducer-BAXc8JyF.js.map → reducer-CjmvZSAb.js.map} +1 -1
  64. package/dist/runtime-consumer-BWmht60z.js +12 -0
  65. package/dist/runtime-consumer-BWmht60z.js.map +1 -0
  66. package/dist/scheduler-qstash.d.ts +2 -2
  67. package/dist/scheduler-qstash.d.ts.map +1 -1
  68. package/dist/scheduler-qstash.js +7 -7
  69. package/dist/scheduler-qstash.js.map +1 -1
  70. package/dist/scheduler-task-X1SToDjP.js.map +1 -1
  71. package/dist/scheduler-vercel.d.ts +2 -2
  72. package/dist/scheduler-vercel.d.ts.map +1 -1
  73. package/dist/scheduler-vercel.js +5 -4
  74. package/dist/scheduler-vercel.js.map +1 -1
  75. package/dist/{server-DYAATFuT.d.ts → server-BshFZ0eL.d.ts} +108 -41
  76. package/dist/server-BshFZ0eL.d.ts.map +1 -0
  77. package/dist/{server-D-Y4pqwu.js → server-DvIB8kj5.js} +423 -135
  78. package/dist/server-DvIB8kj5.js.map +1 -0
  79. package/dist/server.browser.js +1 -1
  80. package/dist/server.browser.js.map +1 -1
  81. package/dist/server.d.ts +4 -4
  82. package/dist/server.js +2 -2
  83. package/dist/{session-clear-C-QwTXV1.d.ts → session-clear-Bk_29eEw.d.ts} +2 -2
  84. package/dist/session-clear-Bk_29eEw.d.ts.map +1 -0
  85. package/dist/{session-clear-DGI4jTQ5.js → session-clear-wHd5GCpZ.js} +5 -4
  86. package/dist/session-clear-wHd5GCpZ.js.map +1 -0
  87. package/dist/store-N8PXxDAS.js.map +1 -1
  88. package/dist/store-Z2qjw50n.d.ts +523 -0
  89. package/dist/store-Z2qjw50n.d.ts.map +1 -0
  90. package/dist/store-codec-DwrWlgQx.js +65 -0
  91. package/dist/store-codec-DwrWlgQx.js.map +1 -0
  92. package/dist/store-memory.d.ts +1 -1
  93. package/dist/store-memory.d.ts.map +1 -1
  94. package/dist/store-memory.js +393 -210
  95. package/dist/store-memory.js.map +1 -1
  96. package/dist/{store-polling-7WJV0YWP.js → store-polling-DYNyxCev.js} +2 -2
  97. package/dist/{store-polling-7WJV0YWP.js.map → store-polling-DYNyxCev.js.map} +1 -1
  98. package/dist/store-postgres.d.ts +1 -1
  99. package/dist/store-postgres.d.ts.map +1 -1
  100. package/dist/store-postgres.js +1595 -673
  101. package/dist/store-postgres.js.map +1 -1
  102. package/dist/{store-presence-polling-B1ixeqIS.js → store-presence-polling-CzQ0wdtM.js} +3 -3
  103. package/dist/{store-presence-polling-B1ixeqIS.js.map → store-presence-polling-CzQ0wdtM.js.map} +1 -1
  104. package/dist/store-redis-http.d.ts +1 -1
  105. package/dist/store-redis-http.js +4 -4
  106. package/dist/store-redis-notify-IiVdlYHc.js +2919 -0
  107. package/dist/store-redis-notify-IiVdlYHc.js.map +1 -0
  108. package/dist/store-redis.d.ts +1 -1
  109. package/dist/store-redis.js +2 -2
  110. package/dist/store-sqlite.d.ts +1 -1
  111. package/dist/store-sqlite.d.ts.map +1 -1
  112. package/dist/store-sqlite.js +517 -287
  113. package/dist/store-sqlite.js.map +1 -1
  114. package/dist/{telemetry-Cyfqo6Qt.d.ts → telemetry-CWwsh-Gx.d.ts} +3 -3
  115. package/dist/telemetry-CWwsh-Gx.d.ts.map +1 -0
  116. package/dist/{wire-BKxH1vbP.js → wire-CZGqNZRx.js} +5 -4
  117. package/dist/wire-CZGqNZRx.js.map +1 -0
  118. package/docs/01-quickstart.mdx +28 -19
  119. package/docs/02-examples.mdx +1 -1
  120. package/docs/actors/01-introduction.mdx +9 -1
  121. package/docs/actors/02-concurrency.mdx +1 -1
  122. package/docs/actors/meta.ts +1 -1
  123. package/docs/agents/01-introduction.mdx +1 -1
  124. package/docs/agents/02-tools.mdx +13 -12
  125. package/docs/agents/03-conversations.mdx +31 -21
  126. package/docs/agents/04-harnesses.mdx +7 -3
  127. package/docs/agents/meta.ts +1 -1
  128. package/docs/client/03-presence.mdx +18 -14
  129. package/docs/client/meta.ts +1 -1
  130. package/docs/contract/01-events.mdx +2 -2
  131. package/docs/contract/02-state.mdx +18 -14
  132. package/docs/contract/03-sessions.mdx +32 -25
  133. package/docs/index.mdx +31 -26
  134. package/docs/reference/01-core.mdx +12 -12
  135. package/docs/reference/02-server.mdx +247 -192
  136. package/docs/reference/04-ai.mdx +29 -20
  137. package/docs/reference/05-telemetry.mdx +146 -0
  138. package/docs/reference/06-errors.mdx +24 -18
  139. package/docs/reference/meta.ts +1 -1
  140. package/docs/schedulers/01-overview.mdx +112 -0
  141. package/docs/schedulers/02-vercel-queues.mdx +87 -0
  142. package/docs/schedulers/03-qstash.mdx +123 -0
  143. package/docs/schedulers/meta.ts +1 -0
  144. package/docs/server/01-consumers.mdx +415 -0
  145. package/docs/server/02-timers.mdx +33 -23
  146. package/docs/server/03-cancellation.mdx +52 -44
  147. package/docs/server/04-routes.mdx +4 -1
  148. package/docs/server/05-sql-projections.mdx +391 -0
  149. package/docs/server/06-guarantees.mdx +60 -50
  150. package/docs/stores/01-overview.mdx +37 -0
  151. package/docs/stores/02-redis.mdx +57 -0
  152. package/docs/stores/03-redis-http.mdx +56 -0
  153. package/docs/stores/04-postgres.mdx +172 -0
  154. package/docs/stores/05-sqlite.mdx +36 -0
  155. package/docs/stores/06-memory.mdx +22 -0
  156. package/docs/stores/meta.ts +1 -0
  157. package/docs/upgrades/01-overview.mdx +30 -0
  158. package/docs/upgrades/79-0-21.mdx +165 -0
  159. package/docs/upgrades/80-0-20.mdx +43 -0
  160. package/docs/upgrades/81-0-19.mdx +33 -0
  161. package/docs/upgrades/82-0-18.mdx +33 -0
  162. package/docs/upgrades/83-0-17.mdx +69 -0
  163. package/docs/upgrades/meta.ts +3 -0
  164. package/examples/playground/DEPLOY.md +48 -11
  165. package/examples/playground/app/a0/apps/[appId]/route.ts +6 -10
  166. package/examples/playground/app/a0/chat.test.tsx +421 -330
  167. package/examples/playground/app/a0/sandbox-log.ts +17 -15
  168. package/examples/playground/app/a0/server.ts +4 -4
  169. package/examples/playground/app/a0/shell.tsx +1 -1
  170. package/examples/playground/app/a0/uploads/route.test.ts +59 -0
  171. package/examples/playground/app/a2slack/a2slack.css +1067 -0
  172. package/examples/playground/app/a2slack/c/[channel]/page.tsx +20 -0
  173. package/examples/playground/app/a2slack/consumers/agent.ts +63 -0
  174. package/examples/playground/app/a2slack/consumers/feed.ts +164 -0
  175. package/examples/playground/app/a2slack/consumers/notify.ts +116 -0
  176. package/examples/playground/app/a2slack/consumers/search.ts +37 -0
  177. package/examples/playground/app/a2slack/consumers/triage.ts +31 -0
  178. package/examples/playground/app/a2slack/consumers/welcome.ts +25 -0
  179. package/examples/playground/app/a2slack/db/a2.ts +206 -0
  180. package/examples/playground/app/a2slack/db/index.ts +73 -0
  181. package/examples/playground/app/a2slack/db/migrations/0000_extensions.sql +4 -0
  182. package/examples/playground/app/a2slack/db/migrations/0001_workspace.sql +74 -0
  183. package/examples/playground/app/a2slack/db/migrations/0002_a2.sql +215 -0
  184. package/examples/playground/app/a2slack/db/migrations/0003_a2_batch.sql +67 -0
  185. package/examples/playground/app/a2slack/db/migrations/meta/0000_snapshot.json +18 -0
  186. package/examples/playground/app/a2slack/db/migrations/meta/0001_snapshot.json +500 -0
  187. package/examples/playground/app/a2slack/db/migrations/meta/0002_snapshot.json +1159 -0
  188. package/examples/playground/app/a2slack/db/migrations/meta/0003_snapshot.json +1159 -0
  189. package/examples/playground/app/a2slack/db/migrations/meta/_journal.json +34 -0
  190. package/examples/playground/app/a2slack/db/queries.ts +263 -0
  191. package/examples/playground/app/a2slack/db/schema.ts +145 -0
  192. package/examples/playground/app/a2slack/drills/a2slack.drill.ts +708 -0
  193. package/examples/playground/app/a2slack/drills/harness.ts +244 -0
  194. package/examples/playground/app/a2slack/events/route.ts +36 -0
  195. package/examples/playground/app/a2slack/identity.ts +44 -0
  196. package/examples/playground/app/a2slack/inbox/route.ts +8 -0
  197. package/examples/playground/app/a2slack/lag/data/route.ts +8 -0
  198. package/examples/playground/app/a2slack/lag/page.tsx +101 -0
  199. package/examples/playground/app/a2slack/lag.ts +73 -0
  200. package/examples/playground/app/a2slack/layout.tsx +43 -0
  201. package/examples/playground/app/a2slack/messages/route.ts +17 -0
  202. package/examples/playground/app/a2slack/model.test.ts +208 -0
  203. package/examples/playground/app/a2slack/model.ts +369 -0
  204. package/examples/playground/app/a2slack/models.test.ts +72 -0
  205. package/examples/playground/app/a2slack/page.tsx +10 -0
  206. package/examples/playground/app/a2slack/scheduler/route.ts +5 -0
  207. package/examples/playground/app/a2slack/search/route.ts +40 -0
  208. package/examples/playground/app/a2slack/search-index.ts +108 -0
  209. package/examples/playground/app/a2slack/server.test.ts +315 -0
  210. package/examples/playground/app/a2slack/server.ts +55 -0
  211. package/examples/playground/app/a2slack/sessions.ts +50 -0
  212. package/examples/playground/app/a2slack/thread/route.ts +8 -0
  213. package/examples/playground/app/a2slack/ui/ChannelView.tsx +87 -0
  214. package/examples/playground/app/a2slack/ui/Composer.tsx +117 -0
  215. package/examples/playground/app/a2slack/ui/DotsShadow.tsx +42 -0
  216. package/examples/playground/app/a2slack/ui/Feed.tsx +157 -0
  217. package/examples/playground/app/a2slack/ui/InboxContext.tsx +63 -0
  218. package/examples/playground/app/a2slack/ui/InboxView.tsx +82 -0
  219. package/examples/playground/app/a2slack/ui/Menu.tsx +128 -0
  220. package/examples/playground/app/a2slack/ui/MessageRow.tsx +314 -0
  221. package/examples/playground/app/a2slack/ui/NameGate.tsx +35 -0
  222. package/examples/playground/app/a2slack/ui/SearchContext.tsx +146 -0
  223. package/examples/playground/app/a2slack/ui/SearchResults.tsx +97 -0
  224. package/examples/playground/app/a2slack/ui/Shell.tsx +34 -0
  225. package/examples/playground/app/a2slack/ui/Sidebar.tsx +199 -0
  226. package/examples/playground/app/a2slack/ui/ThreadPanel.tsx +134 -0
  227. package/examples/playground/app/a2slack/ui/useInbox.ts +71 -0
  228. package/examples/playground/app/agent/[agentId]/agent-queue.test.tsx +116 -90
  229. package/examples/playground/app/agent/[agentId]/compaction-panel.test.tsx +107 -76
  230. package/examples/playground/app/agent/ingress.test.ts +41 -17
  231. package/examples/playground/app/agent/model-input.test.tsx +92 -43
  232. package/examples/playground/app/agent/server.ts +3 -3
  233. package/examples/playground/app/chat/[chatId]/agent-stream-drawer.test.tsx +2 -2
  234. package/examples/playground/app/chat/[chatId]/chat-client.tsx +1 -1
  235. package/examples/playground/app/chat/server.test.ts +38 -65
  236. package/examples/playground/app/chat/server.ts +45 -35
  237. package/examples/playground/app/components/activity-history.test.tsx +60 -18
  238. package/examples/playground/app/components/demo-icons.tsx +7 -0
  239. package/examples/playground/app/components/demos.tsx +7 -0
  240. package/examples/playground/app/components/fast-link.test.tsx +3 -5
  241. package/examples/playground/app/initial-state.test.tsx +86 -45
  242. package/examples/playground/app/orders/[orderId]/order-client.tsx +2 -2
  243. package/examples/playground/app/orders/page.tsx +1 -1
  244. package/examples/playground/app/orders/server.ts +49 -30
  245. package/examples/playground/app/recovery/[recoveryId]/recovery-client.tsx +14 -15
  246. package/examples/playground/app/recovery/page.tsx +4 -4
  247. package/examples/playground/app/recovery/server.ts +23 -32
  248. package/examples/playground/drizzle.config.ts +14 -0
  249. package/examples/playground/next.config.ts +6 -1
  250. package/examples/playground/package.json +13 -1
  251. package/examples/playground/scripts/migrate.mjs +31 -0
  252. package/examples/playground/test/agent.ts +35 -0
  253. package/examples/playground/test/model.ts +149 -0
  254. package/examples/playground/test/serve.ts +184 -0
  255. package/examples/playground/test/server-only.ts +1 -0
  256. package/examples/playground/vercel.json +9 -0
  257. package/examples/playground/vitest.config.ts +27 -0
  258. package/examples/playground/vitest.drills.config.ts +32 -0
  259. package/package.json +7 -2
  260. package/sql/postgres/drizzle-schema.ts +206 -0
  261. package/sql/postgres/notifications.sql +24 -0
  262. package/sql/postgres/schema.sql +276 -0
  263. package/src/actor.ts +101 -71
  264. package/src/ai-agent.ts +154 -115
  265. package/src/ai-control-server.ts +8 -8
  266. package/src/ai-fx.ts +41 -9
  267. package/src/ai-harness.ts +28 -2
  268. package/src/ai-pi.ts +2 -2
  269. package/src/ai-server.ts +2 -2
  270. package/src/ai.ts +7 -7
  271. package/src/contract.ts +1 -1
  272. package/src/deterministic-id.ts +26 -3
  273. package/src/errors.ts +9 -6
  274. package/src/idempotent-replay.ts +0 -1
  275. package/src/index.ts +1 -1
  276. package/src/internal.ts +17 -6
  277. package/src/otel.ts +1 -1
  278. package/src/postgres-notifications.ts +0 -22
  279. package/src/postgres-resources.ts +6 -9
  280. package/src/postgres-schema.ts +121 -0
  281. package/src/push-envelope.ts +20 -0
  282. package/src/runtime-consumer.ts +10 -0
  283. package/src/scheduler-qstash.ts +12 -5
  284. package/src/scheduler-task.ts +2 -2
  285. package/src/scheduler-vercel.ts +10 -4
  286. package/src/server.browser.ts +1 -1
  287. package/src/server.ts +839 -238
  288. package/src/session-socket.ts +1 -1
  289. package/src/store-codec.ts +66 -0
  290. package/src/store-memory.ts +581 -255
  291. package/src/store-postgres.ts +1984 -943
  292. package/src/store-redis-core.ts +1624 -1152
  293. package/src/store-redis-notify.ts +2 -0
  294. package/src/store-sqlite.ts +891 -486
  295. package/src/store.ts +227 -97
  296. package/src/telemetry.ts +2 -1
  297. package/src/wire.ts +1 -0
  298. package/dist/ai-harness-BuuC-gJ3.js.map +0 -1
  299. package/dist/ai-harness-CV6rXbB3.d.ts.map +0 -1
  300. package/dist/ai-mMiWul1T.js.map +0 -1
  301. package/dist/contract-BYKASlCV.js.map +0 -1
  302. package/dist/idempotent-replay-JdgMQRRm.js +0 -21
  303. package/dist/idempotent-replay-JdgMQRRm.js.map +0 -1
  304. package/dist/initial-snapshot-Bx-c0pDP.d.ts.map +0 -1
  305. package/dist/internal-CscSY7K_.js.map +0 -1
  306. package/dist/server-D-Y4pqwu.js.map +0 -1
  307. package/dist/server-DYAATFuT.d.ts.map +0 -1
  308. package/dist/session-clear-C-QwTXV1.d.ts.map +0 -1
  309. package/dist/session-clear-DGI4jTQ5.js.map +0 -1
  310. package/dist/store-CyLUy86v.d.ts +0 -404
  311. package/dist/store-CyLUy86v.d.ts.map +0 -1
  312. package/dist/store-codec-DTG0Ftek.js +0 -10
  313. package/dist/store-codec-DTG0Ftek.js.map +0 -1
  314. package/dist/store-redis-notify-CM0AfLY0.js +0 -2544
  315. package/dist/store-redis-notify-CM0AfLY0.js.map +0 -1
  316. package/dist/telemetry-Cyfqo6Qt.d.ts.map +0 -1
  317. package/dist/wire-BKxH1vbP.js.map +0 -1
  318. package/docs/reference/05-adapters.mdx +0 -351
  319. package/docs/server/01-handlers.mdx +0 -200
  320. package/docs/server/05-production.mdx +0 -323
@@ -1 +0,0 @@
1
- {"version":3,"file":"contract-BYKASlCV.js","names":[],"sources":["../src/contract.ts"],"sourcesContent":["import {\n makeReducerBuilder,\n type Reducer,\n type RegisteredReducer,\n} from './reducer.ts'\nimport { RESERVED_EVENT_PREFIX } from './session-clear.ts'\nimport type { StandardSchemaV1 } from './standard-schema.ts'\nimport { assertSyncSchema } from './validate.ts'\n\n/** The event vocabulary shape: event name → payload schema. */\nexport type EventDefs = Record<string, StandardSchemaV1>\n\n/** The presence vocabulary shape: field name → value schema. */\nexport type PresenceDefs = Record<string, StandardSchemaV1>\n\n/** One event of a contract, narrowed to type `K`. */\nexport type ContractEvent<\n D extends EventDefs,\n K extends keyof D & string = keyof D & string,\n> = {\n [T in keyof D & string]: {\n id: string\n type: T\n payload: StandardSchemaV1.InferOutput<D[T]>\n index: number\n sessionId: string\n createdAt: Date\n }\n}[K]\n\n/** Input to `append`/`push`, typed against the contract's schemas. */\nexport type AppendInput<D extends EventDefs> = {\n [T in keyof D & string]: {\n type: T\n payload: StandardSchemaV1.InferInput<D[T]>\n id?: string\n }\n}[keyof D & string]\n\nexport type EventBatchFactory<D extends EventDefs> = <\n const E extends readonly AppendInput<D>[],\n>(\n ...events: E\n) => E\n\n/**\n * One presence update: a participant's changed fields (`null` marks a\n * cleared one), stamped with the sender's stream frontier (`seen`).\n * This is what `stream({ presence: true })` interleaves with events.\n */\nexport type PresencePatch<P extends PresenceDefs = PresenceDefs> = {\n participant: string\n values: {\n [F in keyof P & string]?: StandardSchemaV1.InferOutput<P[F]> | null\n }\n seen: number\n at: Date\n}\n\n/**\n * The replicated ephemeral map: participant → field → latest value,\n * last-writer-wins per field. Never stored in the log; how long a\n * value stays painted is view logic, decided at render time against\n * `at`.\n */\nexport type PresenceMap<P extends PresenceDefs = PresenceDefs> = {\n [participant: string]: {\n [F in keyof P & string]?: {\n value: StandardSchemaV1.InferOutput<P[F]>\n seen: number\n at: Date\n }\n }\n}\n\n/**\n * The one item a presence stream yields before live patches: the\n * current pruned map, per-field stamps exact. Discriminate\n * structurally (`'snapshot' in item`).\n */\nexport type PresenceSnapshot<P extends PresenceDefs = PresenceDefs> = {\n snapshot: PresenceMap<P>\n}\n\n/**\n * Intersect into a surface type to add `Members` only when the\n * contract declares presence fields — on presence-less contracts the\n * members do not exist, a type error rather than a runtime throw.\n */\nexport type WithPresence<\n P extends PresenceDefs,\n Members,\n> = keyof P extends never ? unknown : Members\n\nexport type ReducerOptions<Seed, S> = {\n /**\n * Identity and snapshot cache key. Rename it when the fold's logic\n * changes — snapshots under the old name are ignored and refolded.\n */\n name: string\n /**\n * The seed the fold starts from. With a `stateSchema`, it's typed as\n * the schema's *input*: validated at definition, and the validated\n * output (defaults applied) is what the fold actually starts from.\n */\n initialState: Seed\n /**\n * Optional: declares the state's shape (the fold's state type becomes\n * the schema's output) and guards cached folds — server snapshots and\n * the browser cache reject mismatching shapes and refold.\n */\n stateSchema?: StandardSchemaV1<Seed, S>\n}\n\nexport type Contract<\n D extends EventDefs = EventDefs,\n P extends PresenceDefs = Record<never, never>,\n R = RegisteredReducer<D, P> | undefined,\n> = {\n /** Identity — prefixes storage keys and queue messages. */\n readonly name: string\n /** The vocabulary. */\n readonly events: Readonly<D>\n /** The presence vocabulary — empty unless declared. */\n readonly presence: Readonly<P>\n /** Preserve literal types for a handler-returned event batch. */\n readonly batch: EventBatchFactory<D>\n readonly reducer: R\n}\n\n/**\n * Define a contract: a name plus the events it understands. Validators\n * must be synchronous — async ones are rejected here, at definition\n * time. The result is a plain, importable, isomorphic value.\n */\ntype ContractOptions<D extends EventDefs, P extends PresenceDefs> = {\n name: string\n events: D\n presence?: P\n}\n\nexport function contract<\n D extends EventDefs,\n P extends PresenceDefs = Record<never, never>,\n Schema extends StandardSchemaV1 = StandardSchemaV1,\n>(\n options: ContractOptions<D, P> & {\n reducer: {\n name: string\n initialState: StandardSchemaV1.InferInput<NoInfer<Schema>>\n stateSchema: Schema\n fold: (\n state: StandardSchemaV1.InferOutput<Schema>,\n event: ContractEvent<NoInfer<D>>,\n ) => StandardSchemaV1.InferOutput<Schema>\n }\n },\n): Contract<D, P, Reducer<D, StandardSchemaV1.InferOutput<Schema>, P>>\nexport function contract<\n D extends EventDefs,\n P extends PresenceDefs = Record<never, never>,\n S = unknown,\n>(\n options: ContractOptions<D, P> & {\n reducer: {\n name: string\n initialState: S\n fold: (state: NoInfer<S>, event: ContractEvent<NoInfer<D>>) => NoInfer<S>\n }\n },\n): Contract<D, P, Reducer<D, S, P>>\nexport function contract<\n D extends EventDefs,\n P extends PresenceDefs = Record<never, never>,\n R extends RegisteredReducer<D, P> = RegisteredReducer<D, P>,\n>(options: ContractOptions<D, P> & { reducer: R }): Contract<D, P, R>\nexport function contract<\n D extends EventDefs,\n P extends PresenceDefs = Record<never, never>,\n>(\n options: ContractOptions<D, P> & { reducer?: undefined },\n): Contract<D, P, undefined>\nexport function contract(options: AnyContractOptions): unknown {\n for (const type of Object.keys(options.events ?? {})) {\n if (type.startsWith(RESERVED_EVENT_PREFIX)) {\n throw new TypeError(\n `contract '${String(options.name)}': event types starting with '${RESERVED_EVENT_PREFIX}' are reserved`,\n )\n }\n }\n return defineContract(options)\n}\n\n/** A2's own contracts, which may declare reserved `a2.` event types. */\nexport const internalContract: typeof contract =\n defineContract as typeof contract\n\ntype AnyContractOptions = ContractOptions<EventDefs, PresenceDefs> & {\n reducer?:\n | (ReducerOptions<unknown, unknown> & {\n fold: (state: never, event: never) => unknown\n })\n | undefined\n}\n\nfunction defineContract(options: AnyContractOptions): unknown {\n const { name } = options\n if (typeof name !== 'string' || name.length === 0) {\n throw new TypeError('contract name must be a non-empty string')\n }\n if (name.includes('\\u001f')) {\n throw new TypeError('contract name contains a reserved control character')\n }\n const defs = options.events\n for (const [type, schema] of Object.entries(defs)) {\n if (typeof schema?.['~standard']?.validate !== 'function') {\n throw new TypeError(\n `contract '${name}': the value for '${type}' is not a Standard Schema (expected an object with '~standard')`,\n )\n }\n assertSyncSchema(schema, `event '${type}'`)\n }\n const events = Object.freeze({ ...defs })\n\n const presenceDefs = options.presence ?? {}\n for (const [field, schema] of Object.entries(presenceDefs)) {\n if (typeof schema?.['~standard']?.validate !== 'function') {\n throw new TypeError(\n `contract '${name}': the value for presence field '${field}' is not a Standard Schema (expected an object with '~standard')`,\n )\n }\n assertSyncSchema(schema, `presence field '${field}'`)\n }\n const presence = Object.freeze({ ...presenceDefs })\n\n return {\n name,\n events,\n presence,\n batch: <const E extends readonly AppendInput<EventDefs>[]>(\n ...items: E\n ): E => items,\n reducer:\n options.reducer === undefined\n ? undefined\n : {\n ...options.reducer,\n ...makeReducerBuilder(events, presence, options.reducer).fold(\n options.reducer.fold as (\n state: unknown,\n event: ContractEvent<EventDefs>,\n ) => unknown,\n ),\n },\n }\n}\n"],"mappings":";;AAsLA,SAAgB,SAAS,SAAsC;CAC7D,KAAK,MAAM,QAAQ,OAAO,KAAK,QAAQ,UAAU,CAAC,CAAC,GACjD,IAAI,KAAK,WAAA,KAAgC,GACvC,MAAM,IAAI,UACR,aAAa,OAAO,QAAQ,IAAI,EAAE,gDACpC;CAGJ,OAAO,eAAe,OAAO;AAC/B;;AAGA,MAAa,mBACX;AAUF,SAAS,eAAe,SAAsC;CAC5D,MAAM,EAAE,SAAS;CACjB,IAAI,OAAO,SAAS,YAAY,KAAK,WAAW,GAC9C,MAAM,IAAI,UAAU,0CAA0C;CAEhE,IAAI,KAAK,SAAS,GAAQ,GACxB,MAAM,IAAI,UAAU,qDAAqD;CAE3E,MAAM,OAAO,QAAQ;CACrB,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,IAAI,GAAG;EACjD,IAAI,OAAO,SAAS,YAAY,EAAE,aAAa,YAC7C,MAAM,IAAI,UACR,aAAa,KAAK,oBAAoB,KAAK,iEAC7C;EAEF,iBAAiB,QAAQ,UAAU,KAAK,EAAE;CAC5C;CACA,MAAM,SAAS,OAAO,OAAO,EAAE,GAAG,KAAK,CAAC;CAExC,MAAM,eAAe,QAAQ,YAAY,CAAC;CAC1C,KAAK,MAAM,CAAC,OAAO,WAAW,OAAO,QAAQ,YAAY,GAAG;EAC1D,IAAI,OAAO,SAAS,YAAY,EAAE,aAAa,YAC7C,MAAM,IAAI,UACR,aAAa,KAAK,mCAAmC,MAAM,iEAC7D;EAEF,iBAAiB,QAAQ,mBAAmB,MAAM,EAAE;CACtD;CACA,MAAM,WAAW,OAAO,OAAO,EAAE,GAAG,aAAa,CAAC;CAElD,OAAO;EACL;EACA;EACA;EACA,QACE,GAAG,UACG;EACR,SACE,QAAQ,YAAY,KAAA,IAChB,KAAA,IACA;GACE,GAAG,QAAQ;GACX,GAAG,mBAAmB,QAAQ,UAAU,QAAQ,OAAO,CAAC,CAAC,KACvD,QAAQ,QAAQ,IAIlB;EACF;CACR;AACF"}
@@ -1,21 +0,0 @@
1
- import { i as A2Error } from "./session-clear-DGI4jTQ5.js";
2
- //#region src/idempotent-replay.ts
3
- const canonicalJson = (value) => JSON.stringify(value, (_key, candidate) => {
4
- if (candidate === null || typeof candidate !== "object" || Array.isArray(candidate)) return candidate;
5
- return Object.fromEntries(Object.entries(candidate).toSorted(([left], [right]) => left < right ? -1 : left > right ? 1 : 0));
6
- }) ?? "null";
7
- const idempotentReplay = (events, existing) => {
8
- const byId = new Map(existing.map((event) => [event.id, event]));
9
- const ordered = events.map((event) => event.id === void 0 ? void 0 : byId.get(event.id));
10
- const firstIndex = ordered[0]?.index;
11
- const batchSize = events[0]?.cause?.batchSize;
12
- if (firstIndex === void 0 || batchSize !== void 0 && batchSize !== events.length || ordered.some((stored, index) => {
13
- const event = events[index];
14
- return stored === void 0 || stored.index !== firstIndex + index || stored.type !== event.type || stored.lane !== (event.lane ?? null) || stored.cause?.batchSize !== event.cause?.batchSize || canonicalJson(stored.payload) !== canonicalJson(event.payload);
15
- })) throw new A2Error("PARTIAL_DUPLICATE_BATCH", "already-appended events do not match the retried batch");
16
- return ordered;
17
- };
18
- //#endregion
19
- export { idempotentReplay as t };
20
-
21
- //# sourceMappingURL=idempotent-replay-JdgMQRRm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"idempotent-replay-JdgMQRRm.js","names":[],"sources":["../src/idempotent-replay.ts"],"sourcesContent":["import { A2Error } from './errors.ts'\nimport type { AppendEvent, StoredEvent } from './store.ts'\n\nconst canonicalJson = (value: unknown): string =>\n JSON.stringify(value, (_key, candidate: unknown) => {\n if (\n candidate === null ||\n typeof candidate !== 'object' ||\n Array.isArray(candidate)\n ) {\n return candidate\n }\n return Object.fromEntries(\n Object.entries(candidate).toSorted(([left], [right]) =>\n left < right ? -1 : left > right ? 1 : 0,\n ),\n )\n }) ?? 'null'\n\nexport const idempotentReplay = (\n events: readonly AppendEvent[],\n existing: readonly StoredEvent[],\n): StoredEvent[] => {\n const byId = new Map(existing.map((event) => [event.id, event]))\n const ordered = events.map((event) =>\n event.id === undefined ? undefined : byId.get(event.id),\n )\n const firstIndex = ordered[0]?.index\n const batchSize = events[0]?.cause?.batchSize\n\n if (\n firstIndex === undefined ||\n (batchSize !== undefined && batchSize !== events.length) ||\n ordered.some((stored, index) => {\n const event = events[index]!\n return (\n stored === undefined ||\n stored.index !== firstIndex + index ||\n stored.type !== event.type ||\n stored.lane !== (event.lane ?? null) ||\n stored.cause?.batchSize !== event.cause?.batchSize ||\n canonicalJson(stored.payload) !== canonicalJson(event.payload)\n )\n })\n ) {\n throw new A2Error(\n 'PARTIAL_DUPLICATE_BATCH',\n 'already-appended events do not match the retried batch',\n )\n }\n\n return ordered as StoredEvent[]\n}\n"],"mappings":";;AAGA,MAAM,iBAAiB,UACrB,KAAK,UAAU,QAAQ,MAAM,cAAuB;CAClD,IACE,cAAc,QACd,OAAO,cAAc,YACrB,MAAM,QAAQ,SAAS,GAEvB,OAAO;CAET,OAAO,OAAO,YACZ,OAAO,QAAQ,SAAS,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,WAC3C,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI,CACzC,CACF;AACF,CAAC,KAAK;AAER,MAAa,oBACX,QACA,aACkB;CAClB,MAAM,OAAO,IAAI,IAAI,SAAS,KAAK,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;CAC/D,MAAM,UAAU,OAAO,KAAK,UAC1B,MAAM,OAAO,KAAA,IAAY,KAAA,IAAY,KAAK,IAAI,MAAM,EAAE,CACxD;CACA,MAAM,aAAa,QAAQ,EAAE,EAAE;CAC/B,MAAM,YAAY,OAAO,EAAE,EAAE,OAAO;CAEpC,IACE,eAAe,KAAA,KACd,cAAc,KAAA,KAAa,cAAc,OAAO,UACjD,QAAQ,MAAM,QAAQ,UAAU;EAC9B,MAAM,QAAQ,OAAO;EACrB,OACE,WAAW,KAAA,KACX,OAAO,UAAU,aAAa,SAC9B,OAAO,SAAS,MAAM,QACtB,OAAO,UAAU,MAAM,QAAQ,SAC/B,OAAO,OAAO,cAAc,MAAM,OAAO,aACzC,cAAc,OAAO,OAAO,MAAM,cAAc,MAAM,OAAO;CAEjE,CAAC,GAED,MAAM,IAAI,QACR,2BACA,wDACF;CAGF,OAAO;AACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"initial-snapshot-Bx-c0pDP.d.ts","names":[],"sources":["../src/errors.ts","../src/initial-snapshot.ts"],"mappings":";;KAAY;KAaA,cACV;cAEW,gBAAgB;WAClB,MAAM;;WAEN;EAET,YACE,MAAM,aACN,iBACA;IAAY;IAAmB;;;;;;;;;;;cA2CtB,0BAA0B;EACrC,YAAY,iBAAiB;IAAY;;;;;KClE/B,gBAAgB,KACxB,cAAc,wBAGd,QAAQ,cAAc"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"internal-CscSY7K_.js","names":[],"sources":["../src/internal.ts"],"sourcesContent":["/**\n * Private seams shared by a2 entry points and a2's own tests. Not exported\n * from the package. Nothing here is public API.\n */\n\nimport type { ScheduledEvent } from './scheduler-task.ts'\nimport type { DrainableServer } from './server.ts'\nimport type { Event } from './store.ts'\n\nexport type DrainOutcome = 'busy' | 'stalled' | 'settled'\n\n/**\n * A null-prototype record for maps keyed by caller-controlled strings\n * (participant ids, presence field names). On a normal object,\n * assigning to '__proto__' rewrites the prototype instead of creating\n * an own property — the prototype-pollution class. Null-prototype\n * objects still satisfy Record types and JSON.stringify cleanly.\n */\nexport function nullProtoRecord<T extends object>(): T {\n return Object.create(null) as T\n}\n\n/**\n * ECMA-262's maximum Date value (±8.64e15 ms). A presence stamp past\n * it becomes an Invalid Date whose toISOString throws — one hostile\n * stamp would poison every subscriber's snapshot frame — so both\n * seams bound `at` to the representable range.\n */\nexport const MAX_DATE_MS = 8_640_000_000_000_000\n\n/**\n * Participant ids that collide with Object.prototype plumbing.\n * Null-prototype construction already defuses them, but they are\n * rejected at both seams (`parsePushBody`, `setPresence`) so a hostile\n * id never propagates into userland maps either.\n */\nexport const RESERVED_PARTICIPANT_IDS: ReadonlySet<string> = new Set([\n '__proto__',\n 'constructor',\n 'prototype',\n])\n\nexport type DrainResult = {\n settled: boolean\n outcome: DrainOutcome\n /** Existing successor arm a scheduler callback may join before acking. */\n schedulerArm?: Promise<void>\n}\n\nexport type ServerInternals = {\n /**\n * Await every in-flight background drain this machine has scheduled,\n * including ones scheduled while waiting. Lets tests flush the\n * fire-and-forget inline path deterministically — no sleeps.\n */\n settle(): Promise<void>\n /** The public `server.drain()` result deliberately remains `{ settled }`. */\n schedulerDrain(\n sessionId: string,\n opts?: { watchdogDueAt?: number },\n ): Promise<DrainResult>\n /** Deliver a scheduler-owned delayed append through the normal root path. */\n schedulerAppend(\n sessionId: string,\n events: readonly ScheduledEvent[],\n originIndex?: number,\n ): Promise<void>\n /** Deliver a scheduler-owned conditional clear, deletion included. */\n schedulerClear(sessionId: string, ifLastIndex: number): Promise<void>\n /** `session.history` with clear markers kept; reads start at the latest one. */\n historyWithMarkers(sessionId: string, gte: number): Promise<Event[]>\n}\n\nexport const serverInternals: WeakMap<object, ServerInternals> = new WeakMap()\n\n/**\n * Handler contexts whose previous attempt ended in a failure the handler\n * threw, as opposed to a claim that lapsed (a crash, a timeout, a frozen\n * process). Only the attempt's own outcome is known, not how far it got.\n */\nexport const failedPreviousAttempt: WeakSet<object> = new WeakSet()\n\nconst objectLike = (value: unknown): value is object =>\n (typeof value === 'object' && value !== null) || typeof value === 'function'\n\n/** The ambient value delivered to `handlerContext` during a tool execution. */\nexport type AmbientToolScope = {\n /** Executing server identity; a test scope from `runWithHandlerContext` has none. */\n contract?: { readonly name: string }\n context: unknown\n}\n\n/**\n * Structural AsyncLocalStorage surface for the ambient tool scope. The\n * instance is created by the server-only AI entry point (the only place\n * `node:async_hooks` may be imported) and shared through a global\n * symbol slot, so `handlerContext` in the isomorphic AI entry point and\n * independently bundled A2 copies all read the same scope.\n */\nexport type AmbientToolScopeStorage = {\n getStore(): AmbientToolScope | undefined\n run<R>(store: AmbientToolScope, callback: () => R): R\n}\n\nconst TOOL_SCOPE_STORAGE = Symbol.for('experimental-a2.ai.tool-scope')\n\nexport function ambientToolScopeStorage(): AmbientToolScopeStorage | undefined {\n const value = Reflect.get(globalThis, TOOL_SCOPE_STORAGE)\n if (\n !objectLike(value) ||\n typeof Reflect.get(value, 'getStore') !== 'function' ||\n typeof Reflect.get(value, 'run') !== 'function'\n ) {\n return undefined\n }\n return value as AmbientToolScopeStorage\n}\n\nexport function installAmbientToolScopeStorage(\n create: () => AmbientToolScopeStorage,\n): AmbientToolScopeStorage {\n const existing = ambientToolScopeStorage()\n if (existing !== undefined) return existing\n const storage = create()\n Reflect.set(globalThis, TOOL_SCOPE_STORAGE, storage)\n return storage\n}\n\nexport type SchedulerSendFailureDisposition = 'retryable' | 'terminal'\n\ntype SchedulerSendFailureMarker = {\n readonly version: 1\n readonly pending: SchedulerSendFailureDisposition[]\n readonly active: SchedulerSendFailureDisposition[]\n}\n\nconst SCHEDULER_SEND_FAILURE = Symbol.for(\n 'experimental-a2.scheduler.send-failure',\n)\n\nconst schedulerSendFailureMarker = (\n value: unknown,\n): SchedulerSendFailureMarker | undefined => {\n if (!objectLike(value)) return undefined\n const marker = Reflect.get(value, SCHEDULER_SEND_FAILURE)\n if (\n !objectLike(marker) ||\n Reflect.get(marker, 'version') !== 1 ||\n !Array.isArray(Reflect.get(marker, 'pending')) ||\n !Array.isArray(Reflect.get(marker, 'active'))\n ) {\n return undefined\n }\n return marker as SchedulerSendFailureMarker\n}\n\nconst schedulerFailureObject = (error: unknown): object => {\n if (\n objectLike(error) &&\n (schedulerSendFailureMarker(error) !== undefined ||\n Object.isExtensible(error))\n ) {\n return error\n }\n return new Error(String(error), { cause: error })\n}\n\nconst schedulerSendFailureState = (\n error: object,\n): SchedulerSendFailureMarker => {\n const existing = schedulerSendFailureMarker(error)\n if (existing !== undefined) return existing\n const marker: SchedulerSendFailureMarker = {\n version: 1,\n pending: [],\n active: [],\n }\n Object.defineProperty(error, SCHEDULER_SEND_FAILURE, {\n value: marker,\n enumerable: false,\n configurable: true,\n writable: false,\n })\n return marker\n}\n\nconst clearSchedulerSendFailureState = (\n error: object,\n marker: SchedulerSendFailureMarker,\n): void => {\n if (marker.pending.length === 0 && marker.active.length === 0) {\n Reflect.deleteProperty(error, SCHEDULER_SEND_FAILURE)\n }\n}\n\n/**\n * Classify an adapter error before throwing it. Unclassified adapter failures\n * are retryable because the caller cannot know whether a remote send landed.\n */\nexport function classifySchedulerSendFailure(\n error: unknown,\n disposition: SchedulerSendFailureDisposition,\n): unknown {\n const classified = schedulerFailureObject(error)\n schedulerSendFailureState(classified).pending.push(disposition)\n return classified\n}\n\n/** Consume a pending adapter classification and count this rejected send. */\nexport function markSchedulerSendFailure(error: unknown): unknown {\n const marked = schedulerFailureObject(error)\n const marker = schedulerSendFailureState(marked)\n marker.active.push(marker.pending.pop() ?? 'retryable')\n return marked\n}\n\nexport function consumeSchedulerSendFailure(\n error: unknown,\n): SchedulerSendFailureDisposition | undefined {\n if (!objectLike(error)) return undefined\n const marker = schedulerSendFailureMarker(error)\n const disposition = marker?.active.pop()\n if (marker !== undefined) clearSchedulerSendFailureState(error, marker)\n return disposition\n}\n\nconst isDrainableServer = (value: unknown): value is DrainableServer => {\n if (value === null || typeof value !== 'object') return false\n const contract = Reflect.get(value, 'contract')\n return (\n contract !== null &&\n typeof contract === 'object' &&\n typeof Reflect.get(contract, 'name') === 'string' &&\n typeof Reflect.get(value, 'drain') === 'function'\n )\n}\n\n/**\n * Validate the server list captured by a scheduler route at construction time.\n * The seam stays structural so custom scheduler integrations can supply their\n * own drainable targets.\n */\nexport function assertSchedulerTargets(\n servers: readonly unknown[],\n): asserts servers is readonly DrainableServer[] {\n const contracts = new Set<string>()\n for (const target of servers) {\n if (!isDrainableServer(target)) {\n throw new TypeError('a2 scheduler: expected a server from createServer()')\n }\n const name = target.contract.name\n if (contracts.has(name)) {\n throw new TypeError(\n `a2 scheduler: duplicate server contract '${name}' in one handler`,\n )\n }\n contracts.add(name)\n }\n}\n\n/**\n * Drain timing knobs. Mutable only as a white-box test seam. Claim\n * heartbeats run on real timers, so tests shrink these to keep suites\n * fast. Production always uses the defaults.\n */\nexport const DRAIN_TIMINGS: {\n /** How long a claim lives without renewal. */\n claimTtlMs: number\n /** Heartbeat cadence while a handler is running. */\n claimHeartbeatMs: number\n /** Base delay before retrying a failed renewal while the lease lives. */\n renewRetryMs: number\n /** Delay between a claim's expiry and its scheduler watchdog. */\n watchdogGraceMs: number\n /** Maximum time a top-level append waits for its initial scheduler arm. */\n schedulerArmTimeoutMs: number\n /** First retry delay after a caught failure, doubling per failure. */\n failureRetryBaseMs: number\n /** Ceiling of the caught-failure retry delay. */\n failureRetryMaxMs: number\n} = {\n claimTtlMs: 5_000,\n claimHeartbeatMs: 2_000,\n renewRetryMs: 400,\n watchdogGraceMs: 1_000,\n schedulerArmTimeoutMs: 2_000,\n failureRetryBaseMs: 1_000,\n failureRetryMaxMs: 30_000,\n}\n\n/**\n * Stream liveness knobs — the server-side SSE heartbeat and the\n * client-side stall watchdog. Paired by design: the client declares a\n * connection dead after roughly two missed heartbeats. Mutable only as\n * a white-box test seam; production always uses the defaults.\n */\n/**\n * Poll cadence for the poll-based store streams (sqlite, postgres) —\n * owned, not configurable: adaptive polling removed the operator's\n * reason to tune it (the floor keeps active streams smooth; the\n * ceiling bounds idle cost). Mutable only as a white-box test seam so\n * suites don't wait out real idle gaps.\n */\nexport const POLL_TIMINGS: {\n /** Gap between polls while a session is producing events. */\n activeFloorMs: number\n /** The idle ceiling — the longest gap between polls. */\n idleCeilingMs: number\n} = {\n activeFloorMs: 25,\n idleCeilingMs: 2_000,\n}\n\n/**\n * Safety-read cadence for the notify-driven redis live stream. A\n * parked feed re-reads the store at this interval even without a\n * pub/sub wake-up, so a lost notification (subscriber reconnect gap,\n * dropped PUBLISH) costs latency, never an event. Mutable only as a\n * white-box test seam.\n */\nexport const NOTIFY_TIMINGS: {\n safetyReadMs: number\n} = {\n safetyReadMs: 10_000,\n}\n\n/**\n * Bounds for each server instance's in-memory reducer-state cache. Sizes are\n * encoded JSON lengths, re-measured every `measureEvery` folded events, so\n * the byte budget is approximate. Mutable only as a white-box test seam.\n */\nexport const STATE_CACHE: {\n maxEntries: number\n maxBytes: number\n /** Events a cached state may advance before it writes a snapshot. */\n snapshotEvery: number\n /** Events a warm read may fold; longer tails read the stored snapshot. */\n maxTail: number\n /** Events folded between re-measuring a cached state's encoded size. */\n measureEvery: number\n} = {\n maxEntries: 1_000,\n maxBytes: 32 * 1024 * 1024,\n snapshotEvery: 128,\n maxTail: 255,\n measureEvery: 16,\n}\n\n/**\n * Warm state-read tails for stores that can serve one in a single request:\n * events from `fromIndex` (inclusive) through `throughIndex` or the newest\n * event, or null when that needs more than one request. Like every store\n * read, a tail starts no lower than the latest clear marker. Keyed by the exact\n * store object, so a wrapper built by spreading or proxying a store reads\n * through its own `readHistory` instead.\n */\nexport const stateTailReaders: WeakMap<\n object,\n (\n sessionId: string,\n fromIndex: number,\n throughIndex?: number,\n ) => Promise<Event[] | null>\n> = new WeakMap()\n\nexport const STREAM_TIMINGS: {\n /** Cadence of `: ping` comment frames from `sseResponse`. */\n sseHeartbeatMs: number\n /** How far ahead of an invocation deadline an SSE response closes. */\n sseDeadlineGraceMs: number\n /** Client: silence longer than this means the connection is dead. */\n stallTimeoutMs: number\n /** Client reconnect backoff: first retry delay, doubling per attempt. */\n reconnectBaseMs: number\n /** Client reconnect backoff ceiling. */\n reconnectMaxMs: number\n} = {\n sseHeartbeatMs: 15_000,\n sseDeadlineGraceMs: 1_000,\n stallTimeoutMs: 35_000,\n reconnectBaseMs: 500,\n reconnectMaxMs: 5_000,\n}\n\n/**\n * WebSocket down-pump backpressure — `sessionsSocket` parks its pull\n * loop while the socket reports more buffered bytes than the\n * high-water mark and re-checks on the poll cadence, so a slow reader\n * applies backpressure to the store subscription instead of buffering\n * without bound in the socket. Acks and heartbeats stay exempt: they\n * are small and correctness-relevant. Mutable only as a white-box test\n * seam.\n */\nexport const SOCKET_TIMINGS: {\n highWaterMarkBytes: number\n resumePollMs: number\n /** Up-lane bound: concurrent push/presence handlers per socket. POST\n * gets per-request platform limits for free; the socket must bring\n * its own. Over the cap, pushes are answered with a retryable error\n * ack and presence frames are shed (that plane repaints). */\n maxInFlightMessages: number\n /** Hard ceiling on `bufferedAmount`: past it the peer is a\n * non-reader (acks and pings are park-exempt, so only a peer that\n * never reads can reach it) and the socket closes 1008. */\n disconnectWaterMarkBytes: number\n} = {\n highWaterMarkBytes: 1_048_576,\n resumePollMs: 25,\n maxInFlightMessages: 32,\n disconnectWaterMarkBytes: 8_388_608,\n}\n\n/**\n * Client presence send cadence — a leading send immediately, then at\n * most one merged send per interval (~15Hz). Owned, not configurable\n * (decision #36's rule): coupling the cadence to the POST ack tied\n * remote cursor smoothness to RTT, and the ack serves no correctness\n * purpose on a fire-and-forget LWW plane. Mutable only as a white-box\n * test seam.\n */\nexport const PRESENCE_TIMINGS: {\n sendIntervalMs: number\n} = {\n sendIntervalMs: 66,\n}\n"],"mappings":"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"}