experimental-a2 0.16.1 → 0.18.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 (406) hide show
  1. package/CHANGELOG.md +373 -0
  2. package/README.md +1 -1
  3. package/dist/{actor-ohPC-81x.d.ts → actor-Bjce9_5U.d.ts} +21 -11
  4. package/dist/actor-Bjce9_5U.d.ts.map +1 -0
  5. package/dist/actor-client.d.ts +2 -5
  6. package/dist/actor-client.d.ts.map +1 -1
  7. package/dist/actor-client.js +13 -4
  8. package/dist/actor-client.js.map +1 -1
  9. package/dist/actor-react.d.ts +5 -3
  10. package/dist/actor-react.d.ts.map +1 -1
  11. package/dist/actor-react.js +20 -10
  12. package/dist/actor-react.js.map +1 -1
  13. package/dist/{actor-shared-B5tJfzt-.js → actor-shared-t7w8xIKP.js} +12 -7
  14. package/dist/actor-shared-t7w8xIKP.js.map +1 -0
  15. package/dist/actor.d.ts +1 -1
  16. package/dist/actor.js +42 -23
  17. package/dist/actor.js.map +1 -1
  18. package/dist/{ai-DgOBltJ_.js → ai-BpOGm-zB.js} +621 -216
  19. package/dist/ai-BpOGm-zB.js.map +1 -0
  20. package/dist/{ai-CrEf6p_W.d.ts → ai-DrUaMyRt.d.ts} +114 -100
  21. package/dist/ai-DrUaMyRt.d.ts.map +1 -0
  22. package/dist/ai-client.d.ts +27 -0
  23. package/dist/ai-client.d.ts.map +1 -0
  24. package/dist/ai-client.js +29 -0
  25. package/dist/ai-client.js.map +1 -0
  26. package/dist/ai-fx.browser.d.ts +1 -0
  27. package/dist/ai-fx.browser.js +6 -0
  28. package/dist/ai-fx.browser.js.map +1 -0
  29. package/dist/ai-fx.d.ts +10 -0
  30. package/dist/ai-fx.d.ts.map +1 -0
  31. package/dist/ai-fx.js +634 -0
  32. package/dist/ai-fx.js.map +1 -0
  33. package/dist/ai-harness-BuLh_EYi.js +273 -0
  34. package/dist/ai-harness-BuLh_EYi.js.map +1 -0
  35. package/dist/ai-harness-DvsPeJeB.d.ts +26 -0
  36. package/dist/ai-harness-DvsPeJeB.d.ts.map +1 -0
  37. package/dist/ai-pi.browser.d.ts +1 -0
  38. package/dist/ai-pi.browser.js +6 -0
  39. package/dist/ai-pi.browser.js.map +1 -0
  40. package/dist/ai-pi.d.ts +17 -0
  41. package/dist/ai-pi.d.ts.map +1 -0
  42. package/dist/ai-pi.js +904 -0
  43. package/dist/ai-pi.js.map +1 -0
  44. package/dist/ai-react.d.ts +96 -0
  45. package/dist/ai-react.d.ts.map +1 -0
  46. package/dist/ai-react.js +142 -0
  47. package/dist/ai-react.js.map +1 -0
  48. package/dist/ai-server.browser.js +2 -2
  49. package/dist/ai-server.browser.js.map +1 -1
  50. package/dist/ai-server.d.ts +109 -43
  51. package/dist/ai-server.d.ts.map +1 -1
  52. package/dist/ai-server.js +526 -283
  53. package/dist/ai-server.js.map +1 -1
  54. package/dist/ai.d.ts +2 -2
  55. package/dist/ai.js +2 -2
  56. package/dist/bounded-cache-CPHWF-8h.js +41 -0
  57. package/dist/bounded-cache-CPHWF-8h.js.map +1 -0
  58. package/dist/{client-BYzHjkwU.js → client-BReKqwZC.js} +447 -80
  59. package/dist/client-BReKqwZC.js.map +1 -0
  60. package/dist/{client-CzyacQpJ.d.ts → client-h_DKFAjj.d.ts} +14 -13
  61. package/dist/client-h_DKFAjj.d.ts.map +1 -0
  62. package/dist/client.d.ts +4 -2
  63. package/dist/client.js +1 -1
  64. package/dist/{contract-CKRg_E4q.js → contract-BYKASlCV.js} +12 -21
  65. package/dist/contract-BYKASlCV.js.map +1 -0
  66. package/dist/{idempotent-replay-DVOlyYbx.js → idempotent-replay-JdgMQRRm.js} +2 -2
  67. package/dist/{idempotent-replay-DVOlyYbx.js.map → idempotent-replay-JdgMQRRm.js.map} +1 -1
  68. package/dist/index.d.ts +6 -5
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +4 -3
  71. package/dist/{errors-DvhSXnxk.d.ts → initial-snapshot-Bx-c0pDP.d.ts} +7 -3
  72. package/dist/initial-snapshot-Bx-c0pDP.d.ts.map +1 -0
  73. package/dist/{internal-Dq2qYxou.js → internal-B2T3U4Rq.js} +29 -2
  74. package/dist/internal-B2T3U4Rq.js.map +1 -0
  75. package/dist/otel.d.ts +1 -1
  76. package/dist/react-BBXgHWFc.d.ts +86 -0
  77. package/dist/react-BBXgHWFc.d.ts.map +1 -0
  78. package/dist/react.d.ts +2 -122
  79. package/dist/react.js +107 -100
  80. package/dist/react.js.map +1 -1
  81. package/dist/reducer-BAXc8JyF.js +87 -0
  82. package/dist/reducer-BAXc8JyF.js.map +1 -0
  83. package/dist/{reducer-otzHjuJj.d.ts → reducer-CqA59Q6U.d.ts} +46 -30
  84. package/dist/reducer-CqA59Q6U.d.ts.map +1 -0
  85. package/dist/reducer-runtime-DQwz_J59.js +28 -0
  86. package/dist/reducer-runtime-DQwz_J59.js.map +1 -0
  87. package/dist/scheduler-qstash.d.ts +3 -3
  88. package/dist/scheduler-qstash.d.ts.map +1 -1
  89. package/dist/scheduler-qstash.js +33 -10
  90. package/dist/scheduler-qstash.js.map +1 -1
  91. package/dist/{scheduler-task-BpzhPnRS.js → scheduler-task-X1SToDjP.js} +18 -3
  92. package/dist/scheduler-task-X1SToDjP.js.map +1 -0
  93. package/dist/scheduler-vercel.d.ts +4 -9
  94. package/dist/scheduler-vercel.d.ts.map +1 -1
  95. package/dist/scheduler-vercel.js +25 -44
  96. package/dist/scheduler-vercel.js.map +1 -1
  97. package/dist/{server-BD5ckxZb.js → server-Dw_k_7kO.js} +904 -219
  98. package/dist/server-Dw_k_7kO.js.map +1 -0
  99. package/dist/{server-DbD7IJVK.d.ts → server-En7cbi3v.d.ts} +116 -26
  100. package/dist/server-En7cbi3v.d.ts.map +1 -0
  101. package/dist/server.d.ts +4 -4
  102. package/dist/server.js +2 -2
  103. package/dist/session-clear-Bo-XTFEy.d.ts +12 -0
  104. package/dist/session-clear-Bo-XTFEy.d.ts.map +1 -0
  105. package/dist/{errors-DCk6ch5n.js → session-clear-DGI4jTQ5.js} +17 -2
  106. package/dist/session-clear-DGI4jTQ5.js.map +1 -0
  107. package/dist/{store-DyZM6fS5.d.ts → store-Djdv0bnZ.d.ts} +73 -3
  108. package/dist/store-Djdv0bnZ.d.ts.map +1 -0
  109. package/dist/store-N8PXxDAS.js.map +1 -1
  110. package/dist/store-memory.d.ts +1 -1
  111. package/dist/store-memory.d.ts.map +1 -1
  112. package/dist/store-memory.js +205 -66
  113. package/dist/store-memory.js.map +1 -1
  114. package/dist/{store-polling-CmxUbV93.js → store-polling-B5FcwJfo.js} +21 -4
  115. package/dist/store-polling-B5FcwJfo.js.map +1 -0
  116. package/dist/store-postgres.d.ts +1 -1
  117. package/dist/store-postgres.d.ts.map +1 -1
  118. package/dist/store-postgres.js +450 -108
  119. package/dist/store-postgres.js.map +1 -1
  120. package/dist/{store-presence-polling-C7-XZyW9.js → store-presence-polling-BAwS8RWn.js} +3 -3
  121. package/dist/{store-presence-polling-C7-XZyW9.js.map → store-presence-polling-BAwS8RWn.js.map} +1 -1
  122. package/dist/store-redis-http.d.ts +1 -1
  123. package/dist/store-redis-http.d.ts.map +1 -1
  124. package/dist/store-redis-http.js +293 -11
  125. package/dist/store-redis-http.js.map +1 -1
  126. package/dist/store-redis-notify-BRITti_o.js +2493 -0
  127. package/dist/store-redis-notify-BRITti_o.js.map +1 -0
  128. package/dist/store-redis.d.ts +1 -1
  129. package/dist/store-redis.d.ts.map +1 -1
  130. package/dist/store-redis.js +11 -11
  131. package/dist/store-redis.js.map +1 -1
  132. package/dist/store-sqlite.d.ts +1 -1
  133. package/dist/store-sqlite.d.ts.map +1 -1
  134. package/dist/store-sqlite.js +197 -33
  135. package/dist/store-sqlite.js.map +1 -1
  136. package/dist/stream-buffer-Cx7AAPGq.js +23 -0
  137. package/dist/stream-buffer-Cx7AAPGq.js.map +1 -0
  138. package/dist/{telemetry-B5jzpy6y.d.ts → telemetry-Cyfqo6Qt.d.ts} +2 -2
  139. package/dist/telemetry-Cyfqo6Qt.d.ts.map +1 -0
  140. package/dist/{wire-BO5wWCb1.js → wire-rSUglYo8.js} +132 -10
  141. package/dist/wire-rSUglYo8.js.map +1 -0
  142. package/docs/01-quickstart.mdx +50 -84
  143. package/docs/{guides/07-examples.mdx → 02-examples.mdx} +10 -20
  144. package/docs/actors/01-introduction.mdx +48 -82
  145. package/docs/actors/02-concurrency.mdx +43 -70
  146. package/docs/actors/03-timers.mdx +28 -42
  147. package/docs/actors/04-routes.mdx +110 -137
  148. package/docs/actors/meta.ts +1 -1
  149. package/docs/agents/01-introduction.mdx +257 -0
  150. package/docs/agents/02-tools.mdx +247 -0
  151. package/docs/agents/03-conversations.mdx +538 -0
  152. package/docs/agents/04-harnesses.mdx +136 -0
  153. package/docs/agents/meta.ts +1 -0
  154. package/docs/client/01-react.mdx +294 -0
  155. package/docs/client/02-transports.mdx +86 -0
  156. package/docs/client/03-presence.mdx +224 -0
  157. package/docs/client/meta.ts +1 -0
  158. package/docs/contract/01-events.mdx +57 -0
  159. package/docs/contract/02-state.mdx +142 -0
  160. package/docs/contract/03-sessions.mdx +175 -0
  161. package/docs/index.mdx +112 -156
  162. package/docs/reference/01-core.mdx +139 -0
  163. package/docs/reference/02-server.mdx +855 -0
  164. package/docs/reference/03-client.mdx +301 -0
  165. package/docs/reference/04-ai.mdx +722 -0
  166. package/docs/reference/05-adapters.mdx +351 -0
  167. package/docs/reference/06-errors.mdx +138 -0
  168. package/docs/reference/meta.ts +1 -1
  169. package/docs/server/01-handlers.mdx +200 -0
  170. package/docs/server/02-timers.mdx +130 -0
  171. package/docs/server/03-cancellation.mdx +141 -0
  172. package/docs/server/04-routes.mdx +243 -0
  173. package/docs/server/05-production.mdx +322 -0
  174. package/docs/server/06-guarantees.mdx +123 -0
  175. package/examples/playground/DEPLOY.md +53 -7
  176. package/examples/playground/app/a0/[appId]/loading.tsx +16 -0
  177. package/examples/playground/app/a0/[appId]/page.tsx +53 -0
  178. package/examples/playground/app/a0/a0.css +818 -0
  179. package/examples/playground/app/a0/app-list.tsx +218 -0
  180. package/examples/playground/app/a0/app-view.tsx +63 -0
  181. package/examples/playground/app/a0/apps/[appId]/preview/route.ts +27 -0
  182. package/examples/playground/app/a0/apps/[appId]/route.ts +28 -0
  183. package/examples/playground/app/a0/apps.test.ts +128 -0
  184. package/examples/playground/app/a0/apps.ts +102 -0
  185. package/examples/playground/app/a0/chat.tsx +410 -0
  186. package/examples/playground/app/a0/columns.tsx +109 -0
  187. package/examples/playground/app/a0/context-menu.tsx +116 -0
  188. package/examples/playground/app/a0/cookies.ts +46 -0
  189. package/examples/playground/app/a0/crash-on-request.ts +72 -0
  190. package/examples/playground/app/a0/crashes/route.ts +3 -0
  191. package/examples/playground/app/a0/crashes.test.ts +33 -0
  192. package/examples/playground/app/a0/crashes.ts +28 -0
  193. package/examples/playground/app/a0/devtools.tsx +164 -0
  194. package/examples/playground/app/a0/events/route.ts +6 -0
  195. package/examples/playground/app/a0/flags.ts +30 -0
  196. package/examples/playground/app/a0/fx/events/route.ts +9 -0
  197. package/examples/playground/app/a0/fx/scheduler/route.ts +7 -0
  198. package/examples/playground/app/a0/fx/short/events/route.ts +11 -0
  199. package/examples/playground/app/a0/layout.tsx +38 -0
  200. package/examples/playground/app/a0/list/route.ts +10 -0
  201. package/examples/playground/app/a0/model.test.ts +73 -0
  202. package/examples/playground/app/a0/model.ts +95 -0
  203. package/examples/playground/app/a0/no-photon.cjs +4 -0
  204. package/examples/playground/app/a0/no-quickjs.cjs +3 -0
  205. package/examples/playground/app/a0/page.tsx +14 -0
  206. package/examples/playground/app/a0/pi/events/route.ts +9 -0
  207. package/examples/playground/app/a0/pi/scheduler/route.ts +7 -0
  208. package/examples/playground/app/a0/pi/short/events/route.ts +11 -0
  209. package/examples/playground/app/a0/preview-pane.tsx +145 -0
  210. package/examples/playground/app/a0/preview.test.ts +53 -0
  211. package/examples/playground/app/a0/preview.ts +26 -0
  212. package/examples/playground/app/a0/sandbox-log.ts +75 -0
  213. package/examples/playground/app/a0/sandbox-session.ts +152 -0
  214. package/examples/playground/app/a0/sandbox.ts +191 -0
  215. package/examples/playground/app/a0/sandboxes/scheduler/route.ts +6 -0
  216. package/examples/playground/app/a0/scheduler/route.ts +7 -0
  217. package/examples/playground/app/a0/server.ts +213 -0
  218. package/examples/playground/app/a0/session.ts +59 -0
  219. package/examples/playground/app/a0/shell.tsx +158 -0
  220. package/examples/playground/app/a0/short/events/route.ts +9 -0
  221. package/examples/playground/app/a0/splitter.tsx +120 -0
  222. package/examples/playground/app/agent/[agentId]/agent-client.tsx +144 -174
  223. package/examples/playground/app/agent/[agentId]/command-receipt.test.tsx +65 -0
  224. package/examples/playground/app/agent/[agentId]/command-receipt.tsx +27 -0
  225. package/examples/playground/app/agent/[agentId]/compaction-event.tsx +25 -24
  226. package/examples/playground/app/agent/[agentId]/compaction-panel.test.tsx +119 -0
  227. package/examples/playground/app/agent/[agentId]/compaction-panel.tsx +208 -165
  228. package/examples/playground/app/agent/[agentId]/page.tsx +2 -16
  229. package/examples/playground/app/agent/events/route.ts +5 -2
  230. package/examples/playground/app/agent/ingress.test.ts +101 -0
  231. package/examples/playground/app/agent/model-input.test.tsx +58 -0
  232. package/examples/playground/app/agent/model-input.tsx +115 -0
  233. package/examples/playground/app/agent/model.test.ts +73 -0
  234. package/examples/playground/app/agent/model.ts +58 -26
  235. package/examples/playground/app/agent/new-agent-session.tsx +37 -19
  236. package/examples/playground/app/agent/page.tsx +4 -4
  237. package/examples/playground/app/agent/server.ts +19 -15
  238. package/examples/playground/app/agent/session.ts +5 -6
  239. package/examples/playground/app/agent/telemetry.test.ts +189 -0
  240. package/examples/playground/app/agent/telemetry.ts +30 -0
  241. package/examples/playground/app/agent/trace.test.ts +23 -0
  242. package/examples/playground/app/agent/trace.ts +18 -0
  243. package/examples/playground/app/canvas/[canvasId]/canvas-client.tsx +12 -12
  244. package/examples/playground/app/canvas/[canvasId]/page.tsx +1 -2
  245. package/examples/playground/app/canvas/[canvasId]/session.ts +2 -2
  246. package/examples/playground/app/canvas/model.ts +53 -53
  247. package/examples/playground/app/chat/[chatId]/agent-state.test.ts +176 -0
  248. package/examples/playground/app/chat/[chatId]/agent-stream-drawer.tsx +16 -1
  249. package/examples/playground/app/chat/[chatId]/chat-client.tsx +55 -77
  250. package/examples/playground/app/chat/[chatId]/chat-view.ts +37 -3
  251. package/examples/playground/app/chat/[chatId]/page.tsx +7 -15
  252. package/examples/playground/app/chat/[chatId]/session.ts +2 -19
  253. package/examples/playground/app/chat/agent/route.ts +9 -0
  254. package/examples/playground/app/chat/model.test.ts +46 -119
  255. package/examples/playground/app/chat/model.ts +82 -128
  256. package/examples/playground/app/chat/scheduler/route.ts +2 -2
  257. package/examples/playground/app/chat/server.test.ts +112 -0
  258. package/examples/playground/app/chat/server.ts +113 -117
  259. package/examples/playground/app/components/activity-feed.tsx +30 -1
  260. package/examples/playground/app/components/activity-history.test.tsx +35 -0
  261. package/examples/playground/app/components/demo-icons.tsx +89 -0
  262. package/examples/playground/app/components/demos.tsx +33 -0
  263. package/examples/playground/app/components/fast-link.test.tsx +58 -0
  264. package/examples/playground/app/components/fast-link.tsx +55 -0
  265. package/examples/playground/app/components/site-header.tsx +96 -0
  266. package/examples/playground/app/counter/counter-client.tsx +3 -3
  267. package/examples/playground/app/counter/model.test.ts +3 -3
  268. package/examples/playground/app/counter/model.ts +11 -21
  269. package/examples/playground/app/counter/page.tsx +2 -15
  270. package/examples/playground/app/counter/session.ts +2 -2
  271. package/examples/playground/app/documents/[documentId]/code-editor.tsx +12 -1
  272. package/examples/playground/app/documents/[documentId]/document-client.tsx +10 -11
  273. package/examples/playground/app/documents/[documentId]/page.tsx +1 -2
  274. package/examples/playground/app/documents/[documentId]/session.ts +2 -2
  275. package/examples/playground/app/documents/model.ts +27 -27
  276. package/examples/playground/app/globals.css +420 -207
  277. package/examples/playground/app/initial-state.test.tsx +54 -0
  278. package/examples/playground/app/layout.tsx +7 -23
  279. package/examples/playground/app/orders/[orderId]/page.tsx +1 -2
  280. package/examples/playground/app/orders/[orderId]/session.ts +2 -2
  281. package/examples/playground/app/orders/model.ts +49 -49
  282. package/examples/playground/app/page.tsx +13 -102
  283. package/examples/playground/app/recovery/[recoveryId]/page.tsx +1 -2
  284. package/examples/playground/app/recovery/[recoveryId]/session.ts +2 -2
  285. package/examples/playground/app/recovery/model.ts +30 -30
  286. package/examples/playground/instrumentation.ts +5 -0
  287. package/examples/playground/next.config.ts +17 -5
  288. package/examples/playground/package.json +13 -2
  289. package/examples/playground/scripts/a0-template.ts +77 -0
  290. package/examples/playground/vercel.json +36 -0
  291. package/package.json +29 -3
  292. package/src/actor-client.ts +16 -4
  293. package/src/actor-react.ts +25 -11
  294. package/src/actor-shared.ts +21 -6
  295. package/src/actor.ts +76 -31
  296. package/src/ai-agent-actions.ts +219 -0
  297. package/src/ai-agent.ts +2517 -0
  298. package/src/ai-app-state.ts +91 -0
  299. package/src/ai-client-state.ts +6 -3
  300. package/src/ai-client.ts +62 -0
  301. package/src/ai-context-schema.ts +25 -5
  302. package/src/ai-context.ts +90 -40
  303. package/src/ai-control-server.ts +92 -72
  304. package/src/ai-coordinator.ts +23 -22
  305. package/src/ai-fx.browser.ts +5 -0
  306. package/src/ai-fx.ts +833 -0
  307. package/src/ai-harness.ts +518 -0
  308. package/src/ai-message-base.ts +209 -0
  309. package/src/ai-message-projection.ts +262 -64
  310. package/src/ai-model-metadata.ts +11 -6
  311. package/src/ai-pi.browser.ts +5 -0
  312. package/src/ai-pi.ts +1263 -0
  313. package/src/ai-progress-batches.ts +26 -0
  314. package/src/ai-projector.ts +95 -14
  315. package/src/ai-react.ts +146 -0
  316. package/src/ai-sdk-step.ts +2 -2
  317. package/src/ai-server.browser.ts +2 -2
  318. package/src/ai-server.ts +23 -1965
  319. package/src/ai-stored-state.ts +48 -163
  320. package/src/ai.ts +339 -155
  321. package/src/bootstrap-stream.ts +72 -0
  322. package/src/bounded-cache.ts +55 -0
  323. package/src/client-render-session.ts +49 -0
  324. package/src/client.ts +688 -151
  325. package/src/contract.ts +92 -42
  326. package/src/deterministic-id.ts +37 -0
  327. package/src/equal-json.ts +32 -0
  328. package/src/errors.ts +13 -1
  329. package/src/index.ts +5 -1
  330. package/src/initial-snapshot.ts +39 -0
  331. package/src/internal.ts +52 -0
  332. package/src/libfx.d.ts +34 -0
  333. package/src/postgres-notification-scope.ts +14 -3
  334. package/src/react.ts +171 -206
  335. package/src/redis-http-reply.ts +256 -0
  336. package/src/redis-http-stream.ts +73 -0
  337. package/src/redis-http-subscriptions.ts +13 -5
  338. package/src/reducer-runtime.ts +52 -0
  339. package/src/reducer.ts +93 -11
  340. package/src/scheduler-qstash.ts +49 -20
  341. package/src/scheduler-task.ts +34 -2
  342. package/src/scheduler-vercel.ts +32 -84
  343. package/src/server-fetch.ts +139 -35
  344. package/src/server.ts +1133 -255
  345. package/src/session-clear.ts +23 -0
  346. package/src/session-socket.ts +154 -49
  347. package/src/sse.ts +71 -4
  348. package/src/store-memory.ts +252 -75
  349. package/src/store-polling.ts +18 -4
  350. package/src/store-postgres.ts +541 -114
  351. package/src/store-redis-core.ts +1450 -493
  352. package/src/store-redis-http.ts +18 -2
  353. package/src/store-redis-notify.ts +262 -85
  354. package/src/store-redis.ts +19 -9
  355. package/src/store-sqlite.ts +319 -45
  356. package/src/store.ts +79 -1
  357. package/src/stream-buffer.ts +43 -0
  358. package/src/telemetry.ts +14 -1
  359. package/src/wire.ts +241 -13
  360. package/dist/actor-ohPC-81x.d.ts.map +0 -1
  361. package/dist/actor-shared-B5tJfzt-.js.map +0 -1
  362. package/dist/ai-CrEf6p_W.d.ts.map +0 -1
  363. package/dist/ai-DgOBltJ_.js.map +0 -1
  364. package/dist/client-BYzHjkwU.js.map +0 -1
  365. package/dist/client-CzyacQpJ.d.ts.map +0 -1
  366. package/dist/contract-CKRg_E4q.js.map +0 -1
  367. package/dist/errors-DCk6ch5n.js.map +0 -1
  368. package/dist/errors-DvhSXnxk.d.ts.map +0 -1
  369. package/dist/internal-Dq2qYxou.js.map +0 -1
  370. package/dist/react.d.ts.map +0 -1
  371. package/dist/reducer-DEMjEY_O.js +0 -29
  372. package/dist/reducer-DEMjEY_O.js.map +0 -1
  373. package/dist/reducer-otzHjuJj.d.ts.map +0 -1
  374. package/dist/scheduler-task-BpzhPnRS.js.map +0 -1
  375. package/dist/server-BD5ckxZb.js.map +0 -1
  376. package/dist/server-DbD7IJVK.d.ts.map +0 -1
  377. package/dist/store-DyZM6fS5.d.ts.map +0 -1
  378. package/dist/store-polling-CmxUbV93.js.map +0 -1
  379. package/dist/store-redis-notify-BVLUfI3j.js +0 -1583
  380. package/dist/store-redis-notify-BVLUfI3j.js.map +0 -1
  381. package/dist/telemetry-B5jzpy6y.d.ts.map +0 -1
  382. package/dist/validate-XKT4FSNn.js +0 -30
  383. package/dist/validate-XKT4FSNn.js.map +0 -1
  384. package/dist/wire-BO5wWCb1.js.map +0 -1
  385. package/docs/concepts/01-contracts.mdx +0 -142
  386. package/docs/concepts/02-handlers.mdx +0 -284
  387. package/docs/concepts/03-durability.mdx +0 -314
  388. package/docs/concepts/04-state.mdx +0 -209
  389. package/docs/guides/01-timers.mdx +0 -185
  390. package/docs/guides/02-cancellation.mdx +0 -161
  391. package/docs/guides/03-react.mdx +0 -384
  392. package/docs/guides/04-local-first.mdx +0 -88
  393. package/docs/guides/05-production.mdx +0 -521
  394. package/docs/guides/06-ai-agents.mdx +0 -1318
  395. package/docs/guides/08-application-data.mdx +0 -113
  396. package/docs/guides/09-presence.mdx +0 -266
  397. package/docs/guides/10-transports.mdx +0 -221
  398. package/docs/reference/01-api.mdx +0 -1896
  399. package/docs/reference/02-errors.mdx +0 -149
  400. package/examples/playground/app/agent/[agentId]/compaction/route.ts +0 -14
  401. package/examples/playground/app/agent/compaction-settings.test.ts +0 -144
  402. package/examples/playground/app/agent/compaction-settings.ts +0 -49
  403. package/examples/playground/app/agent/compaction-timeline.test.ts +0 -377
  404. package/examples/playground/app/agent/compaction-timeline.ts +0 -208
  405. /package/docs/{concepts → contract}/meta.ts +0 -0
  406. /package/docs/{guides → server}/meta.ts +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "experimental-a2",
3
- "version": "0.16.1",
4
- "description": "Durable sync and reactions for things with a lifecycle: one event log, derived state, and live client per session.",
3
+ "version": "0.18.0",
4
+ "description": "Syncs your immutable event log, from server to browser: one contract, handlers, derived state, and a live client per session.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -39,6 +39,16 @@
39
39
  "browser": "./dist/ai-server.browser.js",
40
40
  "default": "./dist/ai-server.js"
41
41
  },
42
+ "./ai/fx": {
43
+ "browser": "./dist/ai-fx.browser.js",
44
+ "default": "./dist/ai-fx.js"
45
+ },
46
+ "./ai/pi": {
47
+ "browser": "./dist/ai-pi.browser.js",
48
+ "default": "./dist/ai-pi.js"
49
+ },
50
+ "./ai/client": "./dist/ai-client.js",
51
+ "./ai/react": "./dist/ai-react.js",
42
52
  "./actor": {
43
53
  "browser": "./dist/actor.browser.js",
44
54
  "default": "./dist/actor.js"
@@ -59,9 +69,12 @@
59
69
  "peerDependencies": {
60
70
  "@opentelemetry/api": "^1.9.0",
61
71
  "@upstash/qstash": "^2.11.0",
72
+ "@earendil-works/pi-ai": "^1.0.2",
73
+ "@earendil-works/pi-coding-agent": "^1.0.2",
62
74
  "@vercel/queue": "*",
63
75
  "ai": "^7.0.0",
64
76
  "ioredis": "^5.4.0",
77
+ "libfx": "^0.0.12",
65
78
  "pg": "^8.11.0",
66
79
  "react": "^19.0.0"
67
80
  },
@@ -78,9 +91,18 @@
78
91
  "ai": {
79
92
  "optional": true
80
93
  },
94
+ "@earendil-works/pi-ai": {
95
+ "optional": true
96
+ },
97
+ "@earendil-works/pi-coding-agent": {
98
+ "optional": true
99
+ },
81
100
  "ioredis": {
82
101
  "optional": true
83
102
  },
103
+ "libfx": {
104
+ "optional": true
105
+ },
84
106
  "pg": {
85
107
  "optional": true
86
108
  },
@@ -113,7 +135,11 @@
113
135
  "tsdown": "^0.22.14",
114
136
  "typescript": "^7.0.2",
115
137
  "vitest": "^4.1.10",
116
- "zod": "^4.4.3"
138
+ "zod": "^4.4.3",
139
+ "libfx": "0.0.12",
140
+ "@earendil-works/pi-ai": "1.0.3",
141
+ "@earendil-works/pi-coding-agent": "1.0.2",
142
+ "@vercel/sandbox": "^3.0.0"
117
143
  },
118
144
  "scripts": {
119
145
  "build": "tsdown",
@@ -6,7 +6,8 @@
6
6
  * `client.call` mirrors the server handle's `call` record over the
7
7
  * call lane `handle.fetch` serves — POST `{ event, input, messageId? }`
8
8
  * → the answer (post-state), a 409 refusal (revived as
9
- * `ActorRefusedError`), or a 400. Both ends of that wire are library
9
+ * `ActorRefusedError`), a 410 for a call cleared before its answer
10
+ * (an `ActorRequestError` whose `cause` is the `A2Error`), or a 400. Both ends of that wire are library
10
11
  * code: the types here are backed by `handle.fetch`, not by a
11
12
  * hand-written convention.
12
13
  *
@@ -19,6 +20,7 @@
19
20
 
20
21
  import { ActorRefusedError } from './actor-shared.ts'
21
22
  import type { ActorCallOptions, ActorCallResult } from './actor.ts'
23
+ import { A2Error } from './errors.ts'
22
24
 
23
25
  export { ActorRefusedError }
24
26
 
@@ -58,7 +60,7 @@ export type ActorClientCall<
58
60
  readonly [K in keyof HandleOf<D>['call']]: HandleOf<D>['call'][K] extends (
59
61
  ...args: infer P
60
62
  ) => Promise<{ state: unknown; index: number }>
61
- ? (...args: P) => Promise<{ state: View; index: number }>
63
+ ? (...args: P) => Promise<ActorCallResult<View>>
62
64
  : never
63
65
  }
64
66
 
@@ -111,7 +113,12 @@ const callOverWire = async (
111
113
  typeof body['error'] === 'string'
112
114
  ? body['error']
113
115
  : `actor call failed (${response.status})`
114
- throw new ActorRequestError(message, { status: response.status })
116
+ throw new ActorRequestError(message, {
117
+ status: response.status,
118
+ ...(response.status === 410 && body['code'] === 'SESSION_CLEARED'
119
+ ? { cause: new A2Error('SESSION_CLEARED', message) }
120
+ : {}),
121
+ })
115
122
  }
116
123
  return snapshotBody(body, response.status)
117
124
  }
@@ -150,10 +157,15 @@ const snapshotBody = (
150
157
  body: Record<string, unknown>,
151
158
  status: number,
152
159
  ): ActorCallResult<unknown> => {
160
+ const clearIndex = body['clearIndex']
153
161
  if (
154
162
  !('state' in body) ||
155
163
  !Number.isSafeInteger(body['index']) ||
156
- (body['index'] as number) < 0
164
+ (body['index'] as number) < 0 ||
165
+ (clearIndex !== undefined &&
166
+ (!Number.isSafeInteger(clearIndex) ||
167
+ (clearIndex as number) < 1 ||
168
+ (clearIndex as number) > (body['index'] as number)))
157
169
  ) {
158
170
  throw new ActorRequestError('actor request returned an invalid snapshot', {
159
171
  status,
@@ -37,14 +37,22 @@ import {
37
37
  type AnyActorDefinition,
38
38
  } from './actor-client.ts'
39
39
  import { createClient } from './client.ts'
40
+ import { foldsClearMarkers } from './reducer.ts'
41
+ import { isSessionCleared } from './session-clear.ts'
40
42
  import type { A2Client, Connection } from './client.ts'
41
43
  import type { ContractEvent, EventDefs, PresenceDefs } from './contract.ts'
44
+ import { internalContract as contract } from './contract.ts'
42
45
  import type { Reducer } from './reducer.ts'
43
46
  import { useSession } from './react.ts'
44
47
  import { useMemo } from 'react'
45
48
 
46
49
  /** The server-to-client handoff: `await def.actor(id).state()`. */
47
- export type ActorSnapshot<S> = { state: S; index: number }
50
+ export type ActorSnapshot<S> = {
51
+ state: S
52
+ index: number
53
+ /** The latest clear marker, once the actor has been cleared. */
54
+ clearIndex?: number
55
+ }
48
56
 
49
57
  export type UseActorOptions<View> = {
50
58
  /** The route whose handler delegates to `handle.fetch` for this instance. */
@@ -104,14 +112,23 @@ const followerReducer: Reducer<EventDefs, unknown, PresenceDefs> = {
104
112
  // server-defined field list, so the server stays the authority and
105
113
  // the protocol types honest callers at compile time.
106
114
  presence: openPresenceDefs,
107
- fold: (state, event) =>
108
- event.type === ACTOR_STATE_EVENT
109
- ? (event.payload as { state: unknown }).state
115
+ // A clear marker from the actor route carries the actor's initial state.
116
+ fold: foldsClearMarkers((state: unknown, event: ContractEvent<EventDefs>) =>
117
+ event.type === ACTOR_STATE_EVENT || isSessionCleared(event)
118
+ ? (event.payload as { state?: unknown } | null)?.state
110
119
  : state,
120
+ ),
111
121
  initialState: undefined,
112
122
  stateSchema: undefined,
113
123
  }
114
124
 
125
+ const followerContract = contract({
126
+ name: 'a2.actor.follower',
127
+ events: followerReducer.events,
128
+ presence: followerReducer.presence,
129
+ reducer: followerReducer,
130
+ })
131
+
115
132
  const clients = new Map<string, A2Client<EventDefs, unknown, PresenceDefs>>()
116
133
 
117
134
  /** Use one actor instance: live state plus typed calls. No provider. */
@@ -121,11 +138,11 @@ export function useActor<D extends AnyActorDefinition, View = ActorStateOf<D>>(
121
138
  const { api } = options
122
139
  let client = clients.get(api)
123
140
  if (!client) {
124
- client = createClient({ reducer: followerReducer, api })
141
+ client = createClient({ contract: followerContract, api })
125
142
  clients.set(api, client)
126
143
  }
127
144
  const session = useSession(client, options.id, {
128
- hydrate: options.initial,
145
+ initial: options.initial,
129
146
  ...(options.participant === undefined
130
147
  ? {}
131
148
  : { participant: options.participant }),
@@ -134,11 +151,8 @@ export function useActor<D extends AnyActorDefinition, View = ActorStateOf<D>>(
134
151
  () =>
135
152
  createActorClient<D, View>({
136
153
  api,
137
- onSnapshot: ({ state, index }) => {
138
- client.session(options.id, {
139
- initialState: state,
140
- initialIndex: index,
141
- })
154
+ onSnapshot: ({ state, index, clearIndex }) => {
155
+ client.session(options.id, { initial: { state, index, clearIndex } })
142
156
  },
143
157
  }),
144
158
  [api, client, options.id],
@@ -1,3 +1,4 @@
1
+ import { reducer } from './reducer.ts'
1
2
  /**
2
3
  * Internal shared vocabulary of the actor module — the reserved event
3
4
  * envelopes, the protocol and context types, the state fold. Not an
@@ -10,7 +11,7 @@
10
11
  * events committed atomically with each handler's completion.
11
12
  */
12
13
 
13
- import { contract as createContract } from './contract.ts'
14
+ import { internalContract as createContract } from './contract.ts'
14
15
  import type { Reducer } from './reducer.ts'
15
16
  import type { ScheduleTiming } from './server.ts'
16
17
  import type { StandardSchemaV1 } from './standard-schema.ts'
@@ -169,6 +170,8 @@ export type ActorStatePayload<S> = {
169
170
  event: string
170
171
  /** The message (invocation event) id this state answers. */
171
172
  message: string
173
+ /** The session's latest clear marker when this state was read. */
174
+ clearIndex?: number
172
175
  }
173
176
 
174
177
  export type ActorFailedPayload = {
@@ -293,11 +296,21 @@ export function actorStateSchema<S>(): StandardSchemaV1<ActorStatePayload<S>> {
293
296
  if (!isJsonTree(state)) {
294
297
  return issue('the actor state must be a plain JSON tree')
295
298
  }
299
+ const clearIndex = value['clearIndex']
300
+ if (
301
+ clearIndex !== undefined &&
302
+ (!Number.isSafeInteger(clearIndex) || (clearIndex as number) < 1)
303
+ ) {
304
+ return issue('the actor clearIndex must be a positive safe integer')
305
+ }
296
306
  return {
297
307
  value: {
298
308
  state: state as S,
299
309
  event: value['event'],
300
310
  message: value['message'],
311
+ ...(clearIndex === undefined
312
+ ? {}
313
+ : { clearIndex: clearIndex as number }),
301
314
  },
302
315
  }
303
316
  })
@@ -348,9 +361,11 @@ export function actorReducer<S>(
348
361
  const events: ActorClientEventDefs<S> = {
349
362
  [ACTOR_STATE_EVENT]: actorStateSchema(),
350
363
  }
351
- return createContract({ name: options.name, events })
352
- .reducer({ name: ACTOR_REDUCER_NAME, initialState: options.state })
353
- .fold((state, event) =>
354
- event.type === ACTOR_STATE_EVENT ? event.payload.state : state,
355
- )
364
+ return reducer({
365
+ contract: createContract({ name: options.name, events }),
366
+ name: ACTOR_REDUCER_NAME,
367
+ initialState: options.state,
368
+ }).fold((state, event) =>
369
+ event.type === ACTOR_STATE_EVENT ? event.payload.state : state,
370
+ )
356
371
  }
package/src/actor.ts CHANGED
@@ -71,14 +71,17 @@ import type {
71
71
  } from './actor-shared.ts'
72
72
  import { parsePresenceSibling } from './push-envelope.ts'
73
73
  import type { ParsedPushPresence } from './push-envelope.ts'
74
- import { contract as createContract } from './contract.ts'
74
+ import { internalContract as createContract } from './contract.ts'
75
75
  import type { PresencePatch, PresenceSnapshot } from './contract.ts'
76
76
  import type { Contract, EventDefs } from './contract.ts'
77
77
  import type { Reducer } from './reducer.ts'
78
78
  import { A2Error, NonRetriableError } from './errors.ts'
79
+ import { serverInternals } from './internal.ts'
79
80
  import { createServer } from './server.ts'
80
81
  import { setServerFetchHooks } from './server-fetch.ts'
81
82
  import { sseResponse } from './sse.ts'
83
+ import { isSessionCleared, sessionClearedError } from './session-clear.ts'
84
+ import type { SessionCleared } from './session-clear.ts'
82
85
  import type { A2Scheduler, A2Server, HandlerEntry, Session } from './server.ts'
83
86
  import type { A2Store } from './store.ts'
84
87
  import type { StandardSchemaV1 } from './standard-schema.ts'
@@ -224,6 +227,11 @@ export type ActorCallResult<S> = {
224
227
  state: S
225
228
  /** Log index of the state commit that answered this message. */
226
229
  index: number
230
+ /**
231
+ * The clear marker this state's lifetime began at, once the actor has been
232
+ * cleared. For a call answer it is the lifetime the handler read.
233
+ */
234
+ clearIndex?: number
227
235
  }
228
236
 
229
237
  type CallMethod<
@@ -257,8 +265,10 @@ export type ActorHandle<D extends ActorProtocol> = {
257
265
  readonly id: string
258
266
  /**
259
267
  * Send the event and await its answer: the state after the handler
260
- * ran, or a rejection with `ActorRefusedError`. Serial events only —
261
- * concurrent handlers produce no answer to await; `send` them.
268
+ * ran, or a rejection with `ActorRefusedError`. A clear before the call
269
+ * receives its answer rejects with `A2Error('SESSION_CLEARED')`. Serial
270
+ * events only — concurrent handlers produce no answer to await; `send`
271
+ * them.
262
272
  */
263
273
  readonly call: { readonly [K in keyof D['events']]: CallMethod<D, K> }
264
274
  /** Cast: validate, append the event durably, return without waiting. */
@@ -268,9 +278,10 @@ export type ActorHandle<D extends ActorProtocol> = {
268
278
  /**
269
279
  * The managed door — the actor mirror of `server.fetch`, bound to
270
280
  * this instance. GET streams the state plane (`a2.actor.state`
271
- * commits only, `?index` resume, heartbeat, deadline rotation);
272
- * POST is the call lane `createActorClient` speaks (`{ event,
273
- * input, messageId? }` → the answer, 409 for a refusal). Your route
281
+ * commits and clear resets, `?index` resume, heartbeat, deadline
282
+ * rotation); POST is the call lane `createActorClient` speaks
283
+ * (`{ event, input, messageId? }` → the answer, 409 for a refusal,
284
+ * 410 for a call cleared before its answer). Your route
274
285
  * authenticates and picks the instance; `authorize` sees every
275
286
  * operation. Custom endpoints are route code around this call.
276
287
  */
@@ -294,7 +305,7 @@ export type ActorDefinition<D extends ActorProtocol> = {
294
305
  readonly contract: Contract<EventDefs>
295
306
  /** The underlying A2 server — `server.fetch` mounts the full session wire. */
296
307
  readonly server: A2Server<EventDefs>
297
- /** The state fold — same identity as the client's follower fold. */
308
+ /** The state fold over commits; a clear resets it to the initial state. */
298
309
  readonly reducer: Reducer<ActorClientEventDefs<D['state']>, D['state']>
299
310
  actor(id: string): ActorHandle<D>
300
311
  }
@@ -516,7 +527,7 @@ export function actor<D extends ActorProtocol>(
516
527
  // an event-relative read would miss them and lose updates.
517
528
  // 'latest' is deterministic here because the lane makes this
518
529
  // attempt the only possible writer while it runs.
519
- const { state } = await ctx.session.state(serverReducer, {
530
+ const { state, clearIndex } = await ctx.session.state(serverReducer, {
520
531
  through: 'latest',
521
532
  })
522
533
  const draft = structuredClone(state)
@@ -565,6 +576,7 @@ export function actor<D extends ActorProtocol>(
565
576
  state: draft,
566
577
  event: eventName,
567
578
  message: ctx.event.id,
579
+ ...(clearIndex === undefined ? {} : { clearIndex }),
568
580
  }
569
581
  return [...sends, { type: ACTOR_STATE_EVENT, payload }]
570
582
  },
@@ -600,6 +612,8 @@ export function actor<D extends ActorProtocol>(
600
612
  },
601
613
  })
602
614
 
615
+ const internals = serverInternals.get(server)!
616
+
603
617
  const makeHandle = (id: string): ActorHandle<D> => {
604
618
  const session = server.session(id)
605
619
 
@@ -634,12 +648,26 @@ export function actor<D extends ActorProtocol>(
634
648
  // Drain participates in processing (usually answering inline in
635
649
  // this invocation); claims arbitrate if another process runs.
636
650
  await server.drain(id)
637
- const tail = await session.history({ gte: cursor })
651
+ const tail = await internals.historyWithMarkers(id, cursor)
638
652
  for (const event of tail) {
653
+ // Reads start at the latest marker, so a clear after the message
654
+ // arrives before any answer from the next lifetime, including one
655
+ // from a message that reuses this id.
656
+ if (isSessionCleared(event)) {
657
+ throw sessionClearedError(
658
+ `actor '${name}': '${eventName}' (message ${message.id}) was cleared before the call received its answer`,
659
+ )
660
+ }
639
661
  if (event.type === ACTOR_STATE_EVENT) {
640
662
  const payload = event.payload as ActorStatePayload<D['state']>
641
663
  if (payload.message === message.id) {
642
- return { state: payload.state, index: event.index }
664
+ return {
665
+ state: payload.state,
666
+ index: event.index,
667
+ ...(payload.clearIndex === undefined
668
+ ? {}
669
+ : { clearIndex: payload.clearIndex }),
670
+ }
643
671
  }
644
672
  }
645
673
  if (event.type === ACTOR_FAILED_EVENT) {
@@ -661,10 +689,19 @@ export function actor<D extends ActorProtocol>(
661
689
  }
662
690
 
663
691
  const readState = async (): Promise<ActorCallResult<D['state']>> => {
664
- const { state, index } = await session.state(serverReducer)
665
- return { state, index }
692
+ const { state, index, clearIndex } = await session.state(serverReducer)
693
+ return clearIndex === undefined
694
+ ? { state, index }
695
+ : { state, index, clearIndex }
666
696
  }
667
697
 
698
+ /** A snapshot or call answer through the route's view. */
699
+ const projected = (
700
+ result: ActorCallResult<D['state']>,
701
+ view: ((state: D['state']) => unknown) | undefined,
702
+ ): ActorCallResult<unknown> =>
703
+ view ? { ...result, state: applyView(view, result.state) } : result
704
+
668
705
  const applyView = (
669
706
  view: (state: D['state']) => unknown,
670
707
  state: D['state'],
@@ -689,6 +726,7 @@ export function actor<D extends ActorProtocol>(
689
726
  // advance the resume frontier.
690
727
  const source: AsyncIterable<
691
728
  | Awaited<ReturnType<typeof session.history>>[number]
729
+ | SessionCleared
692
730
  | PresencePatch
693
731
  | PresenceSnapshot
694
732
  > = presenceEnabled
@@ -707,6 +745,16 @@ export function actor<D extends ActorProtocol>(
707
745
  continue
708
746
  }
709
747
  const event = item
748
+ if (isSessionCleared(event)) {
749
+ // The follower has no seed of its own: the marker carries the
750
+ // actor's initial state, projected like any commit.
751
+ const initial = structuredClone(options.state)
752
+ yield {
753
+ ...event,
754
+ payload: { state: view ? applyView(view, initial) : initial },
755
+ }
756
+ continue
757
+ }
710
758
  // The state plane only: subscribers see what the actor is,
711
759
  // never other callers' inputs. Refusals answer only their
712
760
  // caller (the POST 409); the full mailbox stays server-side.
@@ -724,10 +772,11 @@ export function actor<D extends ActorProtocol>(
724
772
  }
725
773
 
726
774
  // The managed door — the actor mirror of `server.fetch`: GET is
727
- // the state-plane SSE (`a2.actor.state` commits only, `?index`
728
- // resume), POST is the call lane (`{ event, input, messageId? }`
729
- // → the answer, 409 for a refusal). Authentication happens in the
730
- // surrounding route; per-operation policy in `authorize`.
775
+ // the state-plane SSE (`a2.actor.state` commits and clear resets,
776
+ // `?index` resume), POST is the call lane (`{ event, input,
777
+ // messageId? }` → the answer, 409 for a refusal, 410 for a cleared
778
+ // call). Authentication happens in the surrounding route;
779
+ // per-operation policy in `authorize`.
731
780
  const handleFetch = async (
732
781
  request: Request,
733
782
  fetchOptions?: ActorFetchOptions<D>,
@@ -739,15 +788,11 @@ export function actor<D extends ActorProtocol>(
739
788
  const url = new URL(request.url)
740
789
  if (url.searchParams.has('snapshot')) {
741
790
  if (!(await authorized({ type: 'state', id }))) return forbidden()
742
- const result = await readState()
743
791
  return Response.json(
792
+ projected(await readState(), fetchOptions?.view),
744
793
  {
745
- state: fetchOptions?.view
746
- ? applyView(fetchOptions.view, result.state)
747
- : result.state,
748
- index: result.index,
794
+ headers: { 'cache-control': 'private, no-store' },
749
795
  },
750
- { headers: { 'cache-control': 'private, no-store' } },
751
796
  )
752
797
  }
753
798
  const raw = Number(url.searchParams.get('index'))
@@ -858,15 +903,9 @@ export function actor<D extends ActorProtocol>(
858
903
  input,
859
904
  messageId === undefined ? undefined : { id: messageId },
860
905
  )
861
- return Response.json(
862
- fetchOptions?.view
863
- ? {
864
- state: applyView(fetchOptions.view, result.state),
865
- index: result.index,
866
- }
867
- : result,
868
- { headers: { 'cache-control': 'private, no-store' } },
869
- )
906
+ return Response.json(projected(result, fetchOptions?.view), {
907
+ headers: { 'cache-control': 'private, no-store' },
908
+ })
870
909
  } catch (error) {
871
910
  if (error instanceof ActorRefusedError) {
872
911
  return Response.json(
@@ -878,6 +917,12 @@ export function actor<D extends ActorProtocol>(
878
917
  { status: 409 },
879
918
  )
880
919
  }
920
+ if (error instanceof A2Error && error.code === 'SESSION_CLEARED') {
921
+ return Response.json(
922
+ { code: error.code, error: error.message },
923
+ { status: 410 },
924
+ )
925
+ }
881
926
  if (
882
927
  error instanceof A2Error &&
883
928
  (error.code === 'INVALID_PAYLOAD' ||