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.
- package/CHANGELOG.md +373 -0
- package/README.md +1 -1
- package/dist/{actor-ohPC-81x.d.ts → actor-Bjce9_5U.d.ts} +21 -11
- package/dist/actor-Bjce9_5U.d.ts.map +1 -0
- package/dist/actor-client.d.ts +2 -5
- package/dist/actor-client.d.ts.map +1 -1
- package/dist/actor-client.js +13 -4
- package/dist/actor-client.js.map +1 -1
- package/dist/actor-react.d.ts +5 -3
- package/dist/actor-react.d.ts.map +1 -1
- package/dist/actor-react.js +20 -10
- package/dist/actor-react.js.map +1 -1
- package/dist/{actor-shared-B5tJfzt-.js → actor-shared-t7w8xIKP.js} +12 -7
- package/dist/actor-shared-t7w8xIKP.js.map +1 -0
- package/dist/actor.d.ts +1 -1
- package/dist/actor.js +42 -23
- package/dist/actor.js.map +1 -1
- package/dist/{ai-DgOBltJ_.js → ai-BpOGm-zB.js} +621 -216
- package/dist/ai-BpOGm-zB.js.map +1 -0
- package/dist/{ai-CrEf6p_W.d.ts → ai-DrUaMyRt.d.ts} +114 -100
- package/dist/ai-DrUaMyRt.d.ts.map +1 -0
- package/dist/ai-client.d.ts +27 -0
- package/dist/ai-client.d.ts.map +1 -0
- package/dist/ai-client.js +29 -0
- package/dist/ai-client.js.map +1 -0
- package/dist/ai-fx.browser.d.ts +1 -0
- package/dist/ai-fx.browser.js +6 -0
- package/dist/ai-fx.browser.js.map +1 -0
- package/dist/ai-fx.d.ts +10 -0
- package/dist/ai-fx.d.ts.map +1 -0
- package/dist/ai-fx.js +634 -0
- package/dist/ai-fx.js.map +1 -0
- package/dist/ai-harness-BuLh_EYi.js +273 -0
- package/dist/ai-harness-BuLh_EYi.js.map +1 -0
- package/dist/ai-harness-DvsPeJeB.d.ts +26 -0
- package/dist/ai-harness-DvsPeJeB.d.ts.map +1 -0
- package/dist/ai-pi.browser.d.ts +1 -0
- package/dist/ai-pi.browser.js +6 -0
- package/dist/ai-pi.browser.js.map +1 -0
- package/dist/ai-pi.d.ts +17 -0
- package/dist/ai-pi.d.ts.map +1 -0
- package/dist/ai-pi.js +904 -0
- package/dist/ai-pi.js.map +1 -0
- package/dist/ai-react.d.ts +96 -0
- package/dist/ai-react.d.ts.map +1 -0
- package/dist/ai-react.js +142 -0
- package/dist/ai-react.js.map +1 -0
- package/dist/ai-server.browser.js +2 -2
- package/dist/ai-server.browser.js.map +1 -1
- package/dist/ai-server.d.ts +109 -43
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +526 -283
- package/dist/ai-server.js.map +1 -1
- package/dist/ai.d.ts +2 -2
- package/dist/ai.js +2 -2
- package/dist/bounded-cache-CPHWF-8h.js +41 -0
- package/dist/bounded-cache-CPHWF-8h.js.map +1 -0
- package/dist/{client-BYzHjkwU.js → client-BReKqwZC.js} +447 -80
- package/dist/client-BReKqwZC.js.map +1 -0
- package/dist/{client-CzyacQpJ.d.ts → client-h_DKFAjj.d.ts} +14 -13
- package/dist/client-h_DKFAjj.d.ts.map +1 -0
- package/dist/client.d.ts +4 -2
- package/dist/client.js +1 -1
- package/dist/{contract-CKRg_E4q.js → contract-BYKASlCV.js} +12 -21
- package/dist/contract-BYKASlCV.js.map +1 -0
- package/dist/{idempotent-replay-DVOlyYbx.js → idempotent-replay-JdgMQRRm.js} +2 -2
- package/dist/{idempotent-replay-DVOlyYbx.js.map → idempotent-replay-JdgMQRRm.js.map} +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/{errors-DvhSXnxk.d.ts → initial-snapshot-Bx-c0pDP.d.ts} +7 -3
- package/dist/initial-snapshot-Bx-c0pDP.d.ts.map +1 -0
- package/dist/{internal-Dq2qYxou.js → internal-B2T3U4Rq.js} +29 -2
- package/dist/internal-B2T3U4Rq.js.map +1 -0
- package/dist/otel.d.ts +1 -1
- package/dist/react-BBXgHWFc.d.ts +86 -0
- package/dist/react-BBXgHWFc.d.ts.map +1 -0
- package/dist/react.d.ts +2 -122
- package/dist/react.js +107 -100
- package/dist/react.js.map +1 -1
- package/dist/reducer-BAXc8JyF.js +87 -0
- package/dist/reducer-BAXc8JyF.js.map +1 -0
- package/dist/{reducer-otzHjuJj.d.ts → reducer-CqA59Q6U.d.ts} +46 -30
- package/dist/reducer-CqA59Q6U.d.ts.map +1 -0
- package/dist/reducer-runtime-DQwz_J59.js +28 -0
- package/dist/reducer-runtime-DQwz_J59.js.map +1 -0
- package/dist/scheduler-qstash.d.ts +3 -3
- package/dist/scheduler-qstash.d.ts.map +1 -1
- package/dist/scheduler-qstash.js +33 -10
- package/dist/scheduler-qstash.js.map +1 -1
- package/dist/{scheduler-task-BpzhPnRS.js → scheduler-task-X1SToDjP.js} +18 -3
- package/dist/scheduler-task-X1SToDjP.js.map +1 -0
- package/dist/scheduler-vercel.d.ts +4 -9
- package/dist/scheduler-vercel.d.ts.map +1 -1
- package/dist/scheduler-vercel.js +25 -44
- package/dist/scheduler-vercel.js.map +1 -1
- package/dist/{server-BD5ckxZb.js → server-Dw_k_7kO.js} +904 -219
- package/dist/server-Dw_k_7kO.js.map +1 -0
- package/dist/{server-DbD7IJVK.d.ts → server-En7cbi3v.d.ts} +116 -26
- package/dist/server-En7cbi3v.d.ts.map +1 -0
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/session-clear-Bo-XTFEy.d.ts +12 -0
- package/dist/session-clear-Bo-XTFEy.d.ts.map +1 -0
- package/dist/{errors-DCk6ch5n.js → session-clear-DGI4jTQ5.js} +17 -2
- package/dist/session-clear-DGI4jTQ5.js.map +1 -0
- package/dist/{store-DyZM6fS5.d.ts → store-Djdv0bnZ.d.ts} +73 -3
- package/dist/store-Djdv0bnZ.d.ts.map +1 -0
- package/dist/store-N8PXxDAS.js.map +1 -1
- package/dist/store-memory.d.ts +1 -1
- package/dist/store-memory.d.ts.map +1 -1
- package/dist/store-memory.js +205 -66
- package/dist/store-memory.js.map +1 -1
- package/dist/{store-polling-CmxUbV93.js → store-polling-B5FcwJfo.js} +21 -4
- package/dist/store-polling-B5FcwJfo.js.map +1 -0
- package/dist/store-postgres.d.ts +1 -1
- package/dist/store-postgres.d.ts.map +1 -1
- package/dist/store-postgres.js +450 -108
- package/dist/store-postgres.js.map +1 -1
- package/dist/{store-presence-polling-C7-XZyW9.js → store-presence-polling-BAwS8RWn.js} +3 -3
- package/dist/{store-presence-polling-C7-XZyW9.js.map → store-presence-polling-BAwS8RWn.js.map} +1 -1
- package/dist/store-redis-http.d.ts +1 -1
- package/dist/store-redis-http.d.ts.map +1 -1
- package/dist/store-redis-http.js +293 -11
- package/dist/store-redis-http.js.map +1 -1
- package/dist/store-redis-notify-BRITti_o.js +2493 -0
- package/dist/store-redis-notify-BRITti_o.js.map +1 -0
- package/dist/store-redis.d.ts +1 -1
- package/dist/store-redis.d.ts.map +1 -1
- package/dist/store-redis.js +11 -11
- package/dist/store-redis.js.map +1 -1
- package/dist/store-sqlite.d.ts +1 -1
- package/dist/store-sqlite.d.ts.map +1 -1
- package/dist/store-sqlite.js +197 -33
- package/dist/store-sqlite.js.map +1 -1
- package/dist/stream-buffer-Cx7AAPGq.js +23 -0
- package/dist/stream-buffer-Cx7AAPGq.js.map +1 -0
- package/dist/{telemetry-B5jzpy6y.d.ts → telemetry-Cyfqo6Qt.d.ts} +2 -2
- package/dist/telemetry-Cyfqo6Qt.d.ts.map +1 -0
- package/dist/{wire-BO5wWCb1.js → wire-rSUglYo8.js} +132 -10
- package/dist/wire-rSUglYo8.js.map +1 -0
- package/docs/01-quickstart.mdx +50 -84
- package/docs/{guides/07-examples.mdx → 02-examples.mdx} +10 -20
- package/docs/actors/01-introduction.mdx +48 -82
- package/docs/actors/02-concurrency.mdx +43 -70
- package/docs/actors/03-timers.mdx +28 -42
- package/docs/actors/04-routes.mdx +110 -137
- package/docs/actors/meta.ts +1 -1
- package/docs/agents/01-introduction.mdx +257 -0
- package/docs/agents/02-tools.mdx +247 -0
- package/docs/agents/03-conversations.mdx +538 -0
- package/docs/agents/04-harnesses.mdx +136 -0
- package/docs/agents/meta.ts +1 -0
- package/docs/client/01-react.mdx +294 -0
- package/docs/client/02-transports.mdx +86 -0
- package/docs/client/03-presence.mdx +224 -0
- package/docs/client/meta.ts +1 -0
- package/docs/contract/01-events.mdx +57 -0
- package/docs/contract/02-state.mdx +142 -0
- package/docs/contract/03-sessions.mdx +175 -0
- package/docs/index.mdx +112 -156
- package/docs/reference/01-core.mdx +139 -0
- package/docs/reference/02-server.mdx +855 -0
- package/docs/reference/03-client.mdx +301 -0
- package/docs/reference/04-ai.mdx +722 -0
- package/docs/reference/05-adapters.mdx +351 -0
- package/docs/reference/06-errors.mdx +138 -0
- package/docs/reference/meta.ts +1 -1
- package/docs/server/01-handlers.mdx +200 -0
- package/docs/server/02-timers.mdx +130 -0
- package/docs/server/03-cancellation.mdx +141 -0
- package/docs/server/04-routes.mdx +243 -0
- package/docs/server/05-production.mdx +322 -0
- package/docs/server/06-guarantees.mdx +123 -0
- package/examples/playground/DEPLOY.md +53 -7
- package/examples/playground/app/a0/[appId]/loading.tsx +16 -0
- package/examples/playground/app/a0/[appId]/page.tsx +53 -0
- package/examples/playground/app/a0/a0.css +818 -0
- package/examples/playground/app/a0/app-list.tsx +218 -0
- package/examples/playground/app/a0/app-view.tsx +63 -0
- package/examples/playground/app/a0/apps/[appId]/preview/route.ts +27 -0
- package/examples/playground/app/a0/apps/[appId]/route.ts +28 -0
- package/examples/playground/app/a0/apps.test.ts +128 -0
- package/examples/playground/app/a0/apps.ts +102 -0
- package/examples/playground/app/a0/chat.tsx +410 -0
- package/examples/playground/app/a0/columns.tsx +109 -0
- package/examples/playground/app/a0/context-menu.tsx +116 -0
- package/examples/playground/app/a0/cookies.ts +46 -0
- package/examples/playground/app/a0/crash-on-request.ts +72 -0
- package/examples/playground/app/a0/crashes/route.ts +3 -0
- package/examples/playground/app/a0/crashes.test.ts +33 -0
- package/examples/playground/app/a0/crashes.ts +28 -0
- package/examples/playground/app/a0/devtools.tsx +164 -0
- package/examples/playground/app/a0/events/route.ts +6 -0
- package/examples/playground/app/a0/flags.ts +30 -0
- package/examples/playground/app/a0/fx/events/route.ts +9 -0
- package/examples/playground/app/a0/fx/scheduler/route.ts +7 -0
- package/examples/playground/app/a0/fx/short/events/route.ts +11 -0
- package/examples/playground/app/a0/layout.tsx +38 -0
- package/examples/playground/app/a0/list/route.ts +10 -0
- package/examples/playground/app/a0/model.test.ts +73 -0
- package/examples/playground/app/a0/model.ts +95 -0
- package/examples/playground/app/a0/no-photon.cjs +4 -0
- package/examples/playground/app/a0/no-quickjs.cjs +3 -0
- package/examples/playground/app/a0/page.tsx +14 -0
- package/examples/playground/app/a0/pi/events/route.ts +9 -0
- package/examples/playground/app/a0/pi/scheduler/route.ts +7 -0
- package/examples/playground/app/a0/pi/short/events/route.ts +11 -0
- package/examples/playground/app/a0/preview-pane.tsx +145 -0
- package/examples/playground/app/a0/preview.test.ts +53 -0
- package/examples/playground/app/a0/preview.ts +26 -0
- package/examples/playground/app/a0/sandbox-log.ts +75 -0
- package/examples/playground/app/a0/sandbox-session.ts +152 -0
- package/examples/playground/app/a0/sandbox.ts +191 -0
- package/examples/playground/app/a0/sandboxes/scheduler/route.ts +6 -0
- package/examples/playground/app/a0/scheduler/route.ts +7 -0
- package/examples/playground/app/a0/server.ts +213 -0
- package/examples/playground/app/a0/session.ts +59 -0
- package/examples/playground/app/a0/shell.tsx +158 -0
- package/examples/playground/app/a0/short/events/route.ts +9 -0
- package/examples/playground/app/a0/splitter.tsx +120 -0
- package/examples/playground/app/agent/[agentId]/agent-client.tsx +144 -174
- package/examples/playground/app/agent/[agentId]/command-receipt.test.tsx +65 -0
- package/examples/playground/app/agent/[agentId]/command-receipt.tsx +27 -0
- package/examples/playground/app/agent/[agentId]/compaction-event.tsx +25 -24
- package/examples/playground/app/agent/[agentId]/compaction-panel.test.tsx +119 -0
- package/examples/playground/app/agent/[agentId]/compaction-panel.tsx +208 -165
- package/examples/playground/app/agent/[agentId]/page.tsx +2 -16
- package/examples/playground/app/agent/events/route.ts +5 -2
- package/examples/playground/app/agent/ingress.test.ts +101 -0
- package/examples/playground/app/agent/model-input.test.tsx +58 -0
- package/examples/playground/app/agent/model-input.tsx +115 -0
- package/examples/playground/app/agent/model.test.ts +73 -0
- package/examples/playground/app/agent/model.ts +58 -26
- package/examples/playground/app/agent/new-agent-session.tsx +37 -19
- package/examples/playground/app/agent/page.tsx +4 -4
- package/examples/playground/app/agent/server.ts +19 -15
- package/examples/playground/app/agent/session.ts +5 -6
- package/examples/playground/app/agent/telemetry.test.ts +189 -0
- package/examples/playground/app/agent/telemetry.ts +30 -0
- package/examples/playground/app/agent/trace.test.ts +23 -0
- package/examples/playground/app/agent/trace.ts +18 -0
- package/examples/playground/app/canvas/[canvasId]/canvas-client.tsx +12 -12
- package/examples/playground/app/canvas/[canvasId]/page.tsx +1 -2
- package/examples/playground/app/canvas/[canvasId]/session.ts +2 -2
- package/examples/playground/app/canvas/model.ts +53 -53
- package/examples/playground/app/chat/[chatId]/agent-state.test.ts +176 -0
- package/examples/playground/app/chat/[chatId]/agent-stream-drawer.tsx +16 -1
- package/examples/playground/app/chat/[chatId]/chat-client.tsx +55 -77
- package/examples/playground/app/chat/[chatId]/chat-view.ts +37 -3
- package/examples/playground/app/chat/[chatId]/page.tsx +7 -15
- package/examples/playground/app/chat/[chatId]/session.ts +2 -19
- package/examples/playground/app/chat/agent/route.ts +9 -0
- package/examples/playground/app/chat/model.test.ts +46 -119
- package/examples/playground/app/chat/model.ts +82 -128
- package/examples/playground/app/chat/scheduler/route.ts +2 -2
- package/examples/playground/app/chat/server.test.ts +112 -0
- package/examples/playground/app/chat/server.ts +113 -117
- package/examples/playground/app/components/activity-feed.tsx +30 -1
- package/examples/playground/app/components/activity-history.test.tsx +35 -0
- package/examples/playground/app/components/demo-icons.tsx +89 -0
- package/examples/playground/app/components/demos.tsx +33 -0
- package/examples/playground/app/components/fast-link.test.tsx +58 -0
- package/examples/playground/app/components/fast-link.tsx +55 -0
- package/examples/playground/app/components/site-header.tsx +96 -0
- package/examples/playground/app/counter/counter-client.tsx +3 -3
- package/examples/playground/app/counter/model.test.ts +3 -3
- package/examples/playground/app/counter/model.ts +11 -21
- package/examples/playground/app/counter/page.tsx +2 -15
- package/examples/playground/app/counter/session.ts +2 -2
- package/examples/playground/app/documents/[documentId]/code-editor.tsx +12 -1
- package/examples/playground/app/documents/[documentId]/document-client.tsx +10 -11
- package/examples/playground/app/documents/[documentId]/page.tsx +1 -2
- package/examples/playground/app/documents/[documentId]/session.ts +2 -2
- package/examples/playground/app/documents/model.ts +27 -27
- package/examples/playground/app/globals.css +420 -207
- package/examples/playground/app/initial-state.test.tsx +54 -0
- package/examples/playground/app/layout.tsx +7 -23
- package/examples/playground/app/orders/[orderId]/page.tsx +1 -2
- package/examples/playground/app/orders/[orderId]/session.ts +2 -2
- package/examples/playground/app/orders/model.ts +49 -49
- package/examples/playground/app/page.tsx +13 -102
- package/examples/playground/app/recovery/[recoveryId]/page.tsx +1 -2
- package/examples/playground/app/recovery/[recoveryId]/session.ts +2 -2
- package/examples/playground/app/recovery/model.ts +30 -30
- package/examples/playground/instrumentation.ts +5 -0
- package/examples/playground/next.config.ts +17 -5
- package/examples/playground/package.json +13 -2
- package/examples/playground/scripts/a0-template.ts +77 -0
- package/examples/playground/vercel.json +36 -0
- package/package.json +29 -3
- package/src/actor-client.ts +16 -4
- package/src/actor-react.ts +25 -11
- package/src/actor-shared.ts +21 -6
- package/src/actor.ts +76 -31
- package/src/ai-agent-actions.ts +219 -0
- package/src/ai-agent.ts +2517 -0
- package/src/ai-app-state.ts +91 -0
- package/src/ai-client-state.ts +6 -3
- package/src/ai-client.ts +62 -0
- package/src/ai-context-schema.ts +25 -5
- package/src/ai-context.ts +90 -40
- package/src/ai-control-server.ts +92 -72
- package/src/ai-coordinator.ts +23 -22
- package/src/ai-fx.browser.ts +5 -0
- package/src/ai-fx.ts +833 -0
- package/src/ai-harness.ts +518 -0
- package/src/ai-message-base.ts +209 -0
- package/src/ai-message-projection.ts +262 -64
- package/src/ai-model-metadata.ts +11 -6
- package/src/ai-pi.browser.ts +5 -0
- package/src/ai-pi.ts +1263 -0
- package/src/ai-progress-batches.ts +26 -0
- package/src/ai-projector.ts +95 -14
- package/src/ai-react.ts +146 -0
- package/src/ai-sdk-step.ts +2 -2
- package/src/ai-server.browser.ts +2 -2
- package/src/ai-server.ts +23 -1965
- package/src/ai-stored-state.ts +48 -163
- package/src/ai.ts +339 -155
- package/src/bootstrap-stream.ts +72 -0
- package/src/bounded-cache.ts +55 -0
- package/src/client-render-session.ts +49 -0
- package/src/client.ts +688 -151
- package/src/contract.ts +92 -42
- package/src/deterministic-id.ts +37 -0
- package/src/equal-json.ts +32 -0
- package/src/errors.ts +13 -1
- package/src/index.ts +5 -1
- package/src/initial-snapshot.ts +39 -0
- package/src/internal.ts +52 -0
- package/src/libfx.d.ts +34 -0
- package/src/postgres-notification-scope.ts +14 -3
- package/src/react.ts +171 -206
- package/src/redis-http-reply.ts +256 -0
- package/src/redis-http-stream.ts +73 -0
- package/src/redis-http-subscriptions.ts +13 -5
- package/src/reducer-runtime.ts +52 -0
- package/src/reducer.ts +93 -11
- package/src/scheduler-qstash.ts +49 -20
- package/src/scheduler-task.ts +34 -2
- package/src/scheduler-vercel.ts +32 -84
- package/src/server-fetch.ts +139 -35
- package/src/server.ts +1133 -255
- package/src/session-clear.ts +23 -0
- package/src/session-socket.ts +154 -49
- package/src/sse.ts +71 -4
- package/src/store-memory.ts +252 -75
- package/src/store-polling.ts +18 -4
- package/src/store-postgres.ts +541 -114
- package/src/store-redis-core.ts +1450 -493
- package/src/store-redis-http.ts +18 -2
- package/src/store-redis-notify.ts +262 -85
- package/src/store-redis.ts +19 -9
- package/src/store-sqlite.ts +319 -45
- package/src/store.ts +79 -1
- package/src/stream-buffer.ts +43 -0
- package/src/telemetry.ts +14 -1
- package/src/wire.ts +241 -13
- package/dist/actor-ohPC-81x.d.ts.map +0 -1
- package/dist/actor-shared-B5tJfzt-.js.map +0 -1
- package/dist/ai-CrEf6p_W.d.ts.map +0 -1
- package/dist/ai-DgOBltJ_.js.map +0 -1
- package/dist/client-BYzHjkwU.js.map +0 -1
- package/dist/client-CzyacQpJ.d.ts.map +0 -1
- package/dist/contract-CKRg_E4q.js.map +0 -1
- package/dist/errors-DCk6ch5n.js.map +0 -1
- package/dist/errors-DvhSXnxk.d.ts.map +0 -1
- package/dist/internal-Dq2qYxou.js.map +0 -1
- package/dist/react.d.ts.map +0 -1
- package/dist/reducer-DEMjEY_O.js +0 -29
- package/dist/reducer-DEMjEY_O.js.map +0 -1
- package/dist/reducer-otzHjuJj.d.ts.map +0 -1
- package/dist/scheduler-task-BpzhPnRS.js.map +0 -1
- package/dist/server-BD5ckxZb.js.map +0 -1
- package/dist/server-DbD7IJVK.d.ts.map +0 -1
- package/dist/store-DyZM6fS5.d.ts.map +0 -1
- package/dist/store-polling-CmxUbV93.js.map +0 -1
- package/dist/store-redis-notify-BVLUfI3j.js +0 -1583
- package/dist/store-redis-notify-BVLUfI3j.js.map +0 -1
- package/dist/telemetry-B5jzpy6y.d.ts.map +0 -1
- package/dist/validate-XKT4FSNn.js +0 -30
- package/dist/validate-XKT4FSNn.js.map +0 -1
- package/dist/wire-BO5wWCb1.js.map +0 -1
- package/docs/concepts/01-contracts.mdx +0 -142
- package/docs/concepts/02-handlers.mdx +0 -284
- package/docs/concepts/03-durability.mdx +0 -314
- package/docs/concepts/04-state.mdx +0 -209
- package/docs/guides/01-timers.mdx +0 -185
- package/docs/guides/02-cancellation.mdx +0 -161
- package/docs/guides/03-react.mdx +0 -384
- package/docs/guides/04-local-first.mdx +0 -88
- package/docs/guides/05-production.mdx +0 -521
- package/docs/guides/06-ai-agents.mdx +0 -1318
- package/docs/guides/08-application-data.mdx +0 -113
- package/docs/guides/09-presence.mdx +0 -266
- package/docs/guides/10-transports.mdx +0 -221
- package/docs/reference/01-api.mdx +0 -1896
- package/docs/reference/02-errors.mdx +0 -149
- package/examples/playground/app/agent/[agentId]/compaction/route.ts +0 -14
- package/examples/playground/app/agent/compaction-settings.test.ts +0 -144
- package/examples/playground/app/agent/compaction-settings.ts +0 -49
- package/examples/playground/app/agent/compaction-timeline.test.ts +0 -377
- package/examples/playground/app/agent/compaction-timeline.ts +0 -208
- /package/docs/{concepts → contract}/meta.ts +0 -0
- /package/docs/{guides → server}/meta.ts +0 -0
package/src/store.ts
CHANGED
|
@@ -65,6 +65,8 @@ export type StoredEvent = Event & {
|
|
|
65
65
|
lastError: string | null
|
|
66
66
|
/** Adapter clock time recorded when dead-lettered; null otherwise. */
|
|
67
67
|
failedAt: Date | null
|
|
68
|
+
/** Latest clear marker, on claimed events of a cleared session. */
|
|
69
|
+
clearIndex?: number
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
/**
|
|
@@ -91,6 +93,8 @@ export type StoreStateRead = {
|
|
|
91
93
|
snapshot: { index: number; state: unknown } | null
|
|
92
94
|
/** Immutable events strictly after `snapshot.index`, or the full log on a miss. */
|
|
93
95
|
events: Event[]
|
|
96
|
+
/** Latest clear marker; omitted when the session was never cleared. */
|
|
97
|
+
clearIndex?: number
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
export type StoreSnapshotWrite = {
|
|
@@ -153,6 +157,37 @@ export type StoreAppendResult = {
|
|
|
153
157
|
hasPending: boolean
|
|
154
158
|
}
|
|
155
159
|
|
|
160
|
+
export type StoreClearOptions = {
|
|
161
|
+
sessionId: string
|
|
162
|
+
ifLastIndex?: number
|
|
163
|
+
/** The clearing handler's dispatch, fenced like a handler append. */
|
|
164
|
+
cause?: EventCause
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export type StoreClearResult = {
|
|
168
|
+
cleared: boolean
|
|
169
|
+
/** The head after the operation. */
|
|
170
|
+
index: number
|
|
171
|
+
/** The latest clear marker after the operation, or 0. */
|
|
172
|
+
clearIndex: number
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export type StoreReclaimResult = { deleted: number; done: boolean }
|
|
176
|
+
|
|
177
|
+
export type StoreRedriveOptions = {
|
|
178
|
+
sessionId: string
|
|
179
|
+
index: number
|
|
180
|
+
/** `retry` clears the dead letter; `skip` settles it without a handler. */
|
|
181
|
+
action: 'retry' | 'skip'
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export type StoreRedriveResult = {
|
|
185
|
+
/** Whether the event was dead-lettered and this operation resolved it. */
|
|
186
|
+
redriven: boolean
|
|
187
|
+
/** Whether the session contains an event without a completion marker. */
|
|
188
|
+
hasPending: boolean
|
|
189
|
+
}
|
|
190
|
+
|
|
156
191
|
/**
|
|
157
192
|
* An injectable clock. Adapters take one so tests can drive claim
|
|
158
193
|
* expiry, failure timestamps, and (later) stuck-session detection
|
|
@@ -193,8 +228,51 @@ export interface A2Store {
|
|
|
193
228
|
* `claimAvailable` — an unlocked read of the parent admits write skew.
|
|
194
229
|
* The idempotent-replay path runs first, so a batch whose ids all exist
|
|
195
230
|
* replays regardless of the current attempt.
|
|
231
|
+
*
|
|
232
|
+
* Clearing stores (a2-implementation.md §17.2) fence one level earlier:
|
|
233
|
+
* a `cause` at or below the latest clear marker throws
|
|
234
|
+
* `SUPERSEDED_ATTEMPT`, an `originIndex` there throws `SESSION_CLEARED`,
|
|
235
|
+
* and ids whose rows lie below the marker are free to reuse.
|
|
236
|
+
*/
|
|
237
|
+
append(
|
|
238
|
+
sessionId: string,
|
|
239
|
+
events: AppendEvent[],
|
|
240
|
+
options?: { originIndex?: number },
|
|
241
|
+
): Promise<StoreAppendResult>
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Optional with `reclaim`. Serialized with `append`: checks
|
|
245
|
+
* `ifLastIndex` against the head and the latest marker, then appends a
|
|
246
|
+
* settled clear marker at the next index without touching existing
|
|
247
|
+
* rows. Afterwards every event at or below the marker is superseded.
|
|
248
|
+
*/
|
|
249
|
+
clear?(options: StoreClearOptions): Promise<StoreClearResult>
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Deletes one bounded batch of rows below the latest clear marker, with
|
|
253
|
+
* their bookkeeping, id records, and cached folds. `done` once nothing
|
|
254
|
+
* remains below it. Never waits on a lock that other operations hold.
|
|
255
|
+
*/
|
|
256
|
+
reclaim?(sessionId: string): Promise<StoreReclaimResult>
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Optional with `redrive`. The session's dead-lettered events above the
|
|
260
|
+
* latest clear marker, oldest first.
|
|
261
|
+
*/
|
|
262
|
+
deadLetters?(sessionId: string): Promise<StoredEvent[]>
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Optional with `deadLetters`. Atomically resolves one dead-lettered event
|
|
266
|
+
* above the latest clear marker; any other event is untouched and reports
|
|
267
|
+
* `redriven: false`. `retry` clears `failedAt` and `failureCount`, so the
|
|
268
|
+
* event is claimable again with a fresh failure budget, keeping its claim
|
|
269
|
+
* history and last failure. `skip` records `processedAt` with no
|
|
270
|
+
* `processedByAttempt` or `returnedEventIds` and exposes the next event in
|
|
271
|
+
* its lane. Both serialize with `claimAvailable` and the handler-append
|
|
272
|
+
* parent fence; `skip` also serializes with lane promotion in `append` and
|
|
273
|
+
* `completeAttempt`. `hasPending` is read in the same step.
|
|
196
274
|
*/
|
|
197
|
-
|
|
275
|
+
redrive?(options: StoreRedriveOptions): Promise<StoreRedriveResult>
|
|
198
276
|
|
|
199
277
|
/** Events for one session, oldest first. Bounds form `(afterIndex, throughIndex]`. */
|
|
200
278
|
read(
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Event } from './store.ts'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An event as a store returned it, its payload still the JSON text A2's
|
|
5
|
+
* store wrote with `JSON.stringify`. For payloads built from ordinary objects,
|
|
6
|
+
* parsing and re-serializing that text yields the same text, so the SSE lane
|
|
7
|
+
* can write it into a frame unchanged.
|
|
8
|
+
*/
|
|
9
|
+
export type SerializedEvent = {
|
|
10
|
+
id: string
|
|
11
|
+
type: string
|
|
12
|
+
payloadJson: string
|
|
13
|
+
index: number
|
|
14
|
+
sessionId: string
|
|
15
|
+
createdAtMs: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type HeldEvent = Event | SerializedEvent
|
|
19
|
+
|
|
20
|
+
export const isSerializedEvent = (event: object): event is SerializedEvent =>
|
|
21
|
+
'payloadJson' in event
|
|
22
|
+
|
|
23
|
+
export const parseSerializedEvent = (event: SerializedEvent): Event => ({
|
|
24
|
+
id: event.id,
|
|
25
|
+
type: event.type,
|
|
26
|
+
payload: JSON.parse(event.payloadJson),
|
|
27
|
+
index: event.index,
|
|
28
|
+
sessionId: event.sessionId,
|
|
29
|
+
createdAt: new Date(event.createdAtMs),
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The next event a stream iterator already holds, removed without
|
|
34
|
+
* awaiting its `next()`, which then continues after it; `undefined` when
|
|
35
|
+
* it holds none. Call only while no `next()` is pending. The SSE encoder
|
|
36
|
+
* writes these with the event `next()` just returned, so a buffered
|
|
37
|
+
* backlog leaves in few writes.
|
|
38
|
+
*/
|
|
39
|
+
export const bufferedEvents: WeakMap<object, () => HeldEvent | undefined> =
|
|
40
|
+
new WeakMap()
|
|
41
|
+
|
|
42
|
+
export const takeBuffered = (iterator: object): HeldEvent | undefined =>
|
|
43
|
+
bufferedEvents.get(iterator)?.()
|
package/src/telemetry.ts
CHANGED
|
@@ -10,7 +10,20 @@ export type A2AttributeValue = string | number | boolean
|
|
|
10
10
|
|
|
11
11
|
/** The spans a2 emits today. The catalogue grows with the surface. */
|
|
12
12
|
export type A2SpanName =
|
|
13
|
-
|
|
13
|
+
| 'a2.append'
|
|
14
|
+
| 'a2.drain'
|
|
15
|
+
| 'a2.event'
|
|
16
|
+
| 'a2.claim'
|
|
17
|
+
| 'a2.commit'
|
|
18
|
+
| 'a2.state'
|
|
19
|
+
| 'a2.snapshot'
|
|
20
|
+
| 'a2.redrive'
|
|
21
|
+
| 'a2.ai.control'
|
|
22
|
+
| 'a2.ai.ack'
|
|
23
|
+
| 'a2.ai.generate'
|
|
24
|
+
| 'a2.ai.context'
|
|
25
|
+
| 'a2.ai.compaction'
|
|
26
|
+
| 'a2.ai.tool'
|
|
14
27
|
|
|
15
28
|
export type A2SpanHandle = {
|
|
16
29
|
/** Attach or update an attribute mid-span (e.g. the outcome). */
|
package/src/wire.ts
CHANGED
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
import { A2Error, type A2ErrorCode, type A2ServerErrorCode } from './errors.ts'
|
|
9
9
|
import { nullProtoRecord } from './internal.ts'
|
|
10
10
|
import type { Event } from './store.ts'
|
|
11
|
+
import {
|
|
12
|
+
isSerializedEvent,
|
|
13
|
+
takeBuffered,
|
|
14
|
+
type HeldEvent,
|
|
15
|
+
type SerializedEvent,
|
|
16
|
+
} from './stream-buffer.ts'
|
|
11
17
|
import type {
|
|
12
18
|
PresenceMap,
|
|
13
19
|
PresencePatch,
|
|
@@ -36,6 +42,128 @@ export function eventToWire(event: Event): WireEvent {
|
|
|
36
42
|
}
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
// Consecutive frames usually repeat a stream's session, an event type, and
|
|
46
|
+
// the timestamp of events appended together; each keeps its last encoding.
|
|
47
|
+
const lastEncoding = <T>(encode: (value: T) => string) => {
|
|
48
|
+
let last: T | undefined
|
|
49
|
+
let text = ''
|
|
50
|
+
return (value: T): string => {
|
|
51
|
+
if (value !== last) {
|
|
52
|
+
text = encode(value)
|
|
53
|
+
last = value
|
|
54
|
+
}
|
|
55
|
+
return text
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const isoJson = lastEncoding((ms: number) =>
|
|
59
|
+
JSON.stringify(new Date(ms).toISOString()),
|
|
60
|
+
)
|
|
61
|
+
const sessionJson = lastEncoding((id: string) => JSON.stringify(id))
|
|
62
|
+
const typeJson = lastEncoding((type: string) => JSON.stringify(type))
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* `JSON.stringify(eventToWire(event))` for the parsed event, built around the
|
|
66
|
+
* stored payload text instead of parsing and re-serializing it.
|
|
67
|
+
*/
|
|
68
|
+
export function serializedEventToWireJson(event: SerializedEvent): string {
|
|
69
|
+
return `{"id":${JSON.stringify(event.id)},"type":${typeJson(event.type)},"payload":${event.payloadJson},"index":${event.index},"sessionId":${sessionJson(event.sessionId)},"createdAt":${isoJson(event.createdAtMs)}}`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Wire version 2: what a client opts into with `wire=2` on the stream URL.
|
|
74
|
+
* Live events travel in batches, without the `sessionId` the connection
|
|
75
|
+
* already names, with `createdAt` as epoch milliseconds. Any other value,
|
|
76
|
+
* or none, selects version 1.
|
|
77
|
+
*/
|
|
78
|
+
export type WireVersion = 1 | 2
|
|
79
|
+
|
|
80
|
+
export function wireVersion(value: string | null): WireVersion {
|
|
81
|
+
return value === '2' ? 2 : 1
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Events already held by a stream join one write while it is shorter than
|
|
86
|
+
* this many characters, so a write can exceed it by the event that crosses it.
|
|
87
|
+
*/
|
|
88
|
+
export const EVENT_WRITE_CHARS: number = 64 * 1024
|
|
89
|
+
|
|
90
|
+
/** Stream items that are events, as opposed to snapshot or presence frames. */
|
|
91
|
+
export function isStreamEvent(item: object): item is HeldEvent {
|
|
92
|
+
return !('kind' in item) && !('snapshot' in item) && !('participant' in item)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* `first` and the events `iterator` already holds, encoded, until the batch
|
|
97
|
+
* reaches `EVENT_WRITE_CHARS`; `last` is the batch's final event.
|
|
98
|
+
*/
|
|
99
|
+
export function heldEventBatch(options: {
|
|
100
|
+
first: HeldEvent
|
|
101
|
+
iterator: object
|
|
102
|
+
encode: (event: HeldEvent) => string
|
|
103
|
+
}): { events: string[]; last: HeldEvent } {
|
|
104
|
+
const { iterator, encode } = options
|
|
105
|
+
let last = options.first
|
|
106
|
+
const events = [encode(last)]
|
|
107
|
+
let chars = events[0]!.length
|
|
108
|
+
while (chars < EVENT_WRITE_CHARS) {
|
|
109
|
+
const held = takeBuffered(iterator)
|
|
110
|
+
if (!held) break
|
|
111
|
+
const json = encode(held)
|
|
112
|
+
events.push(json)
|
|
113
|
+
chars += json.length + 1
|
|
114
|
+
last = held
|
|
115
|
+
}
|
|
116
|
+
return { events, last }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** A version 2 live event: `WireEvent` minus `sessionId`, ms timestamp. */
|
|
120
|
+
export type CompactWireEvent = {
|
|
121
|
+
id: string
|
|
122
|
+
type: string
|
|
123
|
+
payload: unknown
|
|
124
|
+
index: number
|
|
125
|
+
createdAt: number
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** One version 2 event as JSON, splicing a held row's stored payload. */
|
|
129
|
+
export function compactEventJson(event: HeldEvent): string {
|
|
130
|
+
if (!isSerializedEvent(event))
|
|
131
|
+
return JSON.stringify({
|
|
132
|
+
id: event.id,
|
|
133
|
+
type: event.type,
|
|
134
|
+
payload: event.payload,
|
|
135
|
+
index: event.index,
|
|
136
|
+
createdAt: event.createdAt.getTime(),
|
|
137
|
+
})
|
|
138
|
+
return `{"id":${JSON.stringify(event.id)},"type":${typeJson(event.type)},"payload":${event.payloadJson},"index":${event.index},"createdAt":${event.createdAtMs}}`
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function isCompactWireEvent(value: unknown): value is CompactWireEvent {
|
|
142
|
+
if (value === null || typeof value !== 'object') return false
|
|
143
|
+
const v = value as Record<string, unknown>
|
|
144
|
+
return (
|
|
145
|
+
typeof v['id'] === 'string' &&
|
|
146
|
+
typeof v['type'] === 'string' &&
|
|
147
|
+
typeof v['index'] === 'number' &&
|
|
148
|
+
typeof v['createdAt'] === 'number' &&
|
|
149
|
+
Number.isFinite(v['createdAt'])
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function eventFromCompactWire(
|
|
154
|
+
wire: CompactWireEvent,
|
|
155
|
+
sessionId: string,
|
|
156
|
+
): Event {
|
|
157
|
+
return {
|
|
158
|
+
id: wire.id,
|
|
159
|
+
type: wire.type,
|
|
160
|
+
payload: wire.payload,
|
|
161
|
+
index: wire.index,
|
|
162
|
+
sessionId,
|
|
163
|
+
createdAt: new Date(wire.createdAt),
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
39
167
|
export function eventFromWire(wire: WireEvent): Event {
|
|
40
168
|
return {
|
|
41
169
|
id: wire.id,
|
|
@@ -180,6 +308,7 @@ const ERROR_STATUS: Record<A2ServerErrorCode, number> = {
|
|
|
180
308
|
UNKNOWN_EVENT_TYPE: 400,
|
|
181
309
|
PARTIAL_DUPLICATE_BATCH: 400,
|
|
182
310
|
SUPERSEDED_ATTEMPT: 409,
|
|
311
|
+
SESSION_CLEARED: 409,
|
|
183
312
|
CLAIM_EXPIRED: 409,
|
|
184
313
|
STORE_UNAVAILABLE: 503,
|
|
185
314
|
STORE_NOT_CONFIGURED: 500,
|
|
@@ -249,8 +378,57 @@ const isServerErrorCode = (code: string): code is A2ServerErrorCode =>
|
|
|
249
378
|
* guard) come back `null`. `sessionId` is present on frames from a
|
|
250
379
|
* multiplexed socket and absent on a single-session one.
|
|
251
380
|
*/
|
|
381
|
+
export type StateSnapshotFrame = {
|
|
382
|
+
kind: 'snapshot'
|
|
383
|
+
sessionId: string
|
|
384
|
+
name: string
|
|
385
|
+
index: number
|
|
386
|
+
state: unknown
|
|
387
|
+
stateUndefined?: true
|
|
388
|
+
/** The session's latest clear marker, when it has been cleared. */
|
|
389
|
+
clearIndex?: number
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export function stateSnapshotToWire(
|
|
393
|
+
frame: StateSnapshotFrame,
|
|
394
|
+
): StateSnapshotFrame {
|
|
395
|
+
return frame.state === undefined
|
|
396
|
+
? { ...frame, state: null, stateUndefined: true }
|
|
397
|
+
: frame
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export function isStateSnapshotFrame(
|
|
401
|
+
value: unknown,
|
|
402
|
+
): value is StateSnapshotFrame {
|
|
403
|
+
if (value === null || typeof value !== 'object') return false
|
|
404
|
+
const frame = value as Record<string, unknown>
|
|
405
|
+
return (
|
|
406
|
+
frame['kind'] === 'snapshot' &&
|
|
407
|
+
typeof frame['sessionId'] === 'string' &&
|
|
408
|
+
typeof frame['name'] === 'string' &&
|
|
409
|
+
frame['name'].length > 0 &&
|
|
410
|
+
typeof frame['index'] === 'number' &&
|
|
411
|
+
Number.isSafeInteger(frame['index']) &&
|
|
412
|
+
frame['index'] >= 0 &&
|
|
413
|
+
Object.hasOwn(frame, 'state') &&
|
|
414
|
+
(!Object.hasOwn(frame, 'stateUndefined') ||
|
|
415
|
+
(frame['stateUndefined'] === true && frame['state'] === null)) &&
|
|
416
|
+
(!Object.hasOwn(frame, 'clearIndex') ||
|
|
417
|
+
(typeof frame['clearIndex'] === 'number' &&
|
|
418
|
+
Number.isSafeInteger(frame['clearIndex']) &&
|
|
419
|
+
frame['clearIndex'] > 0 &&
|
|
420
|
+
frame['clearIndex'] <= frame['index']))
|
|
421
|
+
)
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
export type SubscriptionStart =
|
|
425
|
+
| { index: number; bootstrap?: never; reducer?: string }
|
|
426
|
+
| { bootstrap: true; reducer: string; index?: never }
|
|
427
|
+
|
|
252
428
|
export type SocketDownFrame =
|
|
429
|
+
| StateSnapshotFrame
|
|
253
430
|
| { kind: 'event'; event: WireEvent }
|
|
431
|
+
| { kind: 'events'; events: CompactWireEvent[]; sessionId?: string }
|
|
254
432
|
| { kind: 'presence'; patch: WirePresencePatch; sessionId?: string }
|
|
255
433
|
| {
|
|
256
434
|
kind: 'presence-snapshot'
|
|
@@ -259,10 +437,11 @@ export type SocketDownFrame =
|
|
|
259
437
|
}
|
|
260
438
|
| { kind: 'ack'; req: number; events: WireEvent[]; sessionId?: string }
|
|
261
439
|
| { kind: 'ack'; req: number; error: A2Error; sessionId?: string }
|
|
262
|
-
| { kind: 'subscribed'; sessionId: string }
|
|
440
|
+
| { kind: 'subscribed'; sessionId: string; attempt?: number }
|
|
263
441
|
| {
|
|
264
442
|
kind: 'unsubscribed'
|
|
265
443
|
sessionId: string
|
|
444
|
+
attempt?: number
|
|
266
445
|
reason?: string
|
|
267
446
|
error?: A2Error
|
|
268
447
|
}
|
|
@@ -291,11 +470,19 @@ export type SocketPresenceFrame = {
|
|
|
291
470
|
sessionId?: string
|
|
292
471
|
}
|
|
293
472
|
|
|
473
|
+
/** One session lane in a subscribe frame. The server echoes `attempt`
|
|
474
|
+
* on that lane's `subscribed`/`unsubscribed` answers, so a client that
|
|
475
|
+
* re-subscribed before an answer arrived can tell the answers apart. */
|
|
476
|
+
export type SocketSubscribeEntry = {
|
|
477
|
+
id: string
|
|
478
|
+
attempt?: number
|
|
479
|
+
} & SubscriptionStart
|
|
480
|
+
|
|
294
481
|
/** Open per-session lanes on a multiplexed socket. `index` is each
|
|
295
482
|
* session's exclusive resume frontier — `stream({ startAfter })`. */
|
|
296
483
|
export type SocketSubscribeFrame = {
|
|
297
484
|
kind: 'subscribe'
|
|
298
|
-
sessions:
|
|
485
|
+
sessions: SocketSubscribeEntry[]
|
|
299
486
|
}
|
|
300
487
|
|
|
301
488
|
export type SocketUnsubscribeFrame = {
|
|
@@ -316,10 +503,11 @@ export const SOCKET_PING_FRAME: string = JSON.stringify({ kind: 'ping' })
|
|
|
316
503
|
* multiplexed socket presence frames carry the `sessionId` tag; events
|
|
317
504
|
* already carry theirs in the wire event. */
|
|
318
505
|
export function socketFrameFor(
|
|
319
|
-
item: Event | PresencePatch | PresenceSnapshot,
|
|
506
|
+
item: Event | PresencePatch | PresenceSnapshot | StateSnapshotFrame,
|
|
320
507
|
sessionId?: string,
|
|
321
508
|
): string {
|
|
322
509
|
const tag = sessionId === undefined ? {} : { sessionId }
|
|
510
|
+
if ('kind' in item) return JSON.stringify(stateSnapshotToWire(item))
|
|
323
511
|
if ('snapshot' in item) {
|
|
324
512
|
return JSON.stringify({
|
|
325
513
|
kind: 'presence-snapshot',
|
|
@@ -337,6 +525,14 @@ export function socketFrameFor(
|
|
|
337
525
|
return JSON.stringify({ kind: 'event', ...eventToWire(item) })
|
|
338
526
|
}
|
|
339
527
|
|
|
528
|
+
/** A version 2 batch frame from compact event JSON; a multiplexed
|
|
529
|
+
* socket names the batch's session once. */
|
|
530
|
+
export function socketEventsFor(events: string[], sessionId?: string): string {
|
|
531
|
+
const tag =
|
|
532
|
+
sessionId === undefined ? '' : `"sessionId":${JSON.stringify(sessionId)},`
|
|
533
|
+
return `{"kind":"events",${tag}"events":[${events.join(',')}]}`
|
|
534
|
+
}
|
|
535
|
+
|
|
340
536
|
export function socketAckFor(
|
|
341
537
|
req: number,
|
|
342
538
|
events: Event[],
|
|
@@ -363,25 +559,39 @@ export function socketErrorAckFor(
|
|
|
363
559
|
})
|
|
364
560
|
}
|
|
365
561
|
|
|
366
|
-
export function socketSubscribedFor(
|
|
367
|
-
|
|
562
|
+
export function socketSubscribedFor(options: {
|
|
563
|
+
sessionId: string
|
|
564
|
+
attempt?: number | undefined
|
|
565
|
+
}): string {
|
|
566
|
+
const { sessionId, attempt } = options
|
|
567
|
+
return JSON.stringify({
|
|
568
|
+
kind: 'subscribed',
|
|
569
|
+
sessionId,
|
|
570
|
+
...(attempt === undefined ? {} : { attempt }),
|
|
571
|
+
})
|
|
368
572
|
}
|
|
369
573
|
|
|
370
574
|
/** The subscription-over notice: with a `reason` the server rejected
|
|
371
575
|
* or lost the session's stream, without one it ended cleanly. */
|
|
372
|
-
export function socketUnsubscribedFor(
|
|
373
|
-
sessionId: string
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
576
|
+
export function socketUnsubscribedFor(options: {
|
|
577
|
+
sessionId: string
|
|
578
|
+
attempt?: number | undefined
|
|
579
|
+
reason?: string
|
|
580
|
+
error?: A2Error
|
|
581
|
+
}): string {
|
|
582
|
+
const { sessionId, attempt, reason, error } = options
|
|
377
583
|
return JSON.stringify({
|
|
378
584
|
kind: 'unsubscribed',
|
|
379
585
|
sessionId,
|
|
586
|
+
...(attempt === undefined ? {} : { attempt }),
|
|
380
587
|
...(reason === undefined ? {} : { reason }),
|
|
381
588
|
...(error === undefined ? {} : errorToWire(error)),
|
|
382
589
|
})
|
|
383
590
|
}
|
|
384
591
|
|
|
592
|
+
const isAttempt = (value: unknown): value is number =>
|
|
593
|
+
typeof value === 'number' && Number.isSafeInteger(value) && value >= 0
|
|
594
|
+
|
|
385
595
|
export function parseSocketFrame(data: string): SocketDownFrame | null {
|
|
386
596
|
let parsed: unknown
|
|
387
597
|
try {
|
|
@@ -394,6 +604,10 @@ export function parseSocketFrame(data: string): SocketDownFrame | null {
|
|
|
394
604
|
}
|
|
395
605
|
const frame = parsed as Record<string, unknown>
|
|
396
606
|
switch (frame['kind']) {
|
|
607
|
+
case 'snapshot':
|
|
608
|
+
if (!isStateSnapshotFrame(parsed))
|
|
609
|
+
throw new A2Error('INVALID_PAYLOAD', 'invalid bootstrap snapshot')
|
|
610
|
+
return parsed
|
|
397
611
|
case 'ping':
|
|
398
612
|
return { kind: 'ping' }
|
|
399
613
|
case 'event': {
|
|
@@ -404,6 +618,13 @@ export function parseSocketFrame(data: string): SocketDownFrame | null {
|
|
|
404
618
|
event: { id, type, payload, index, sessionId, createdAt },
|
|
405
619
|
}
|
|
406
620
|
}
|
|
621
|
+
case 'events': {
|
|
622
|
+
// Dropping a batch would leave a gap the frontier then skips past.
|
|
623
|
+
const events = frame['events']
|
|
624
|
+
if (!Array.isArray(events) || !events.every(isCompactWireEvent))
|
|
625
|
+
throw new A2Error('INVALID_PAYLOAD', 'invalid event batch')
|
|
626
|
+
return { kind: 'events', events, ...sessionTag(frame) }
|
|
627
|
+
}
|
|
407
628
|
case 'presence': {
|
|
408
629
|
if (!isWirePresencePatch(parsed)) return null
|
|
409
630
|
const { participant, values, seen, at } = parsed
|
|
@@ -422,13 +643,19 @@ export function parseSocketFrame(data: string): SocketDownFrame | null {
|
|
|
422
643
|
}
|
|
423
644
|
}
|
|
424
645
|
case 'subscribed': {
|
|
425
|
-
const sessionId = frame
|
|
646
|
+
const { sessionId, attempt } = frame
|
|
426
647
|
if (typeof sessionId !== 'string') return null
|
|
427
|
-
|
|
648
|
+
if (attempt !== undefined && !isAttempt(attempt)) return null
|
|
649
|
+
return {
|
|
650
|
+
kind: 'subscribed',
|
|
651
|
+
sessionId,
|
|
652
|
+
...(attempt === undefined ? {} : { attempt }),
|
|
653
|
+
}
|
|
428
654
|
}
|
|
429
655
|
case 'unsubscribed': {
|
|
430
|
-
const sessionId = frame
|
|
656
|
+
const { sessionId, attempt } = frame
|
|
431
657
|
if (typeof sessionId !== 'string') return null
|
|
658
|
+
if (attempt !== undefined && !isAttempt(attempt)) return null
|
|
432
659
|
const reason = frame['reason']
|
|
433
660
|
const error =
|
|
434
661
|
errorFromWire(parsed) ??
|
|
@@ -441,6 +668,7 @@ export function parseSocketFrame(data: string): SocketDownFrame | null {
|
|
|
441
668
|
return {
|
|
442
669
|
kind: 'unsubscribed',
|
|
443
670
|
sessionId,
|
|
671
|
+
...(attempt === undefined ? {} : { attempt }),
|
|
444
672
|
...(typeof reason === 'string' ? { reason } : {}),
|
|
445
673
|
...(error === null ? {} : { error }),
|
|
446
674
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"actor-ohPC-81x.d.ts","names":[],"sources":["../src/actor-shared.ts","../src/actor.ts"],"mappings":";;;;;;;;;;;cAgCa,0BAA0B;;WAE5B;;WAEA;EACT,YAAY,eAAe,mBAAmB;;;;;;;;;KAepC;EACV;EACA;;;;;;;EAOA;;;KAIU,gBAAgB,UAAU,iBAAiB;EACrD,gBAAgB;IAEd;;KAIQ,oBAAoB,QAC7B,WAAW,cAAc,EAAE;;;;;;KAQlB,iBAAiB;GAExB,yBAAA,WAAW;IAAgB,OAAO,EAAE;IAAI;IAAc,IAAI;;;;;;;;;;;;KAanD,UAAU,iBACV,WAAW,eAAe,EAAE,MACjC,QAAQ,EAAE,eACV,OAAO,EAAE;;;;;;;;;KAWJ,uBAAuB;EAAmB;;;;;;;;;;;;KAY1C,kBAAkB,iBAClB,WAAW,eAAe,EAAE,MACjC,OAAO,EAAE,gBAAgB,SAAS,yBAAyB,iBAC3D,OAAO,EAAE,IAAI,SAAS,yBAAyB;;KAI1C,aAAa,UAAU;;EAEjC,OAAO;;EAEP;;EAEA;;EAEA,QAAQ;;EAER,MAAM,UAAU;;EAEhB,UAAU,kBAAkB;;;;;;;;KASlB,uBAAuB,UAAU;;EAE3C;;EAEA;;EAEA,QAAQ;;EAER,SAAS;IAAU,OAAO;IAAY;;;EAEtC,MAAM,UAAU;;EAEhB,UAAU,kBAAkB;;KAGlB,kBAAkB;EAC5B,OAAO;;EAEP;;EAEA;;;KAWU,qBAAqB;EAC/B,kBAAkB,iBAAiB,kBAAkB;;;;;;;;;;;;;;KCzE3C,aAAa,UAAU,eAAe,gBAAgB,iBAC5D,KAAK,aAAa,IAAI,OAAO,YAAY,cAAc;EAEvD;EACA,SACE,KAAK,uBAAuB,IAC5B,OAAO,YAAY,cACT;;;;;;;;;;;;;;;;iBAiBF,WAAW,KAAK,GAC9B,SAAS,KAAK,KAAK,OAAO,aAAa;EACpC;EAAkB,SAAS,KAAK,KAAK,OAAO,aAAa;;KAIlD,aAAa,UAAU;;EAEjC;;EAEA,OAAO;;;;;EAKP,aAAa,WAAW,cAAc,aAAa,GAAG;EACtD,QAAQ;EACR,YAAY;EACZ,YAAY;MACR,gBAAgB;EAChB;;;;;;;;;;;;EAYA;;;;;;;KAQM;WACG;WAAwB;;WAExB;WACA;WACA;;WAGA;WACA;WACA;WACA;WACA;;WAGA;WACA;WACA;WACA,QAAQ,SAAS;;KAGpB,kBAAkB,UAAU;;EAEtC,aAAa,WAAW,6BAA6B;;;;;;;;;;;;EAYrD,QAAQ,OAAO;;KAGL;;EAEV;;KAGU,mBAAmB;;EAE7B;;KAGU,gBAAgB;;EAE1B,OAAO;;EAEP;;KAGG,WACH,UAAU,eACV,gBAAgB,0BACH,YAAY,MAErB,QAAQ,YAAY,IACpB,UAAU,qBACP,QAAQ,gBAAgB,gBAE3B,OAAO,YAAY,IACnB,UAAU,qBACP,QAAQ,gBAAgB;KAE5B,WACH,UAAU,eACV,gBAAgB,0BACH,YAAY,MAErB,QAAQ,YAAY,IACpB,UAAU,qBACP;EAAU;EAAY;MAEzB,OAAO,YAAY,IACnB,UAAU,qBACP;EAAU;EAAY;;;KAGnB,YAAY,UAAU;WACvB;;;;;;WAMA,kBAAkB,WAAW,cAAc,WAAW,GAAG;;WAEzD,kBAAkB,WAAW,cAAc,WAAW,GAAG;;WAEzD,aAAa,QAAQ,gBAAgB;;;;;;;;;;WAUrC,QACP,SAAS,SACT,UAAU,kBAAkB,OACzB,QAAQ;;WAEJ,SAAS,QAAQ;;KAGhB,gBAAgB,UAAU;WAC3B;;;;;;WAMA,WAAW;;WAEX,UAAU,SAAS;;WAEnB,QAAQ,SAAS;;WAEjB,SAAS,QAAQ,qBAAqB,aAAa;EAC5D,MAAM,aAAa,YAAY;;;;;;;iBAsDjB,MAAM,UAAU,eAC9B,SAAS,aAAa,KACrB,gBAAgB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"actor-shared-B5tJfzt-.js","names":["createContract"],"sources":["../src/actor-shared.ts"],"sourcesContent":["/**\n * Internal shared vocabulary of the actor module — the reserved event\n * envelopes, the protocol and context types, the state fold. Not an\n * entry point: the public surfaces are experimental-a2/actor (server),\n * /actor/client, and /actor/react.\n *\n * An actor is a durable mailbox with memory: one session per instance,\n * events processed one at a time (a lane) unless a handler opts out\n * with `concurrent: true`, state materialized as `a2.actor.state`\n * events committed atomically with each handler's completion.\n */\n\nimport { contract as createContract } from './contract.ts'\nimport type { Reducer } from './reducer.ts'\nimport type { ScheduleTiming } from './server.ts'\nimport type { StandardSchemaV1 } from './standard-schema.ts'\n\n/** Event type of a committed state change — one per completed serial handler. */\nexport const ACTOR_STATE_EVENT = 'a2.actor.state'\n/** Event type of a refusal — a handler that answered by throwing NonRetriableError. */\nexport const ACTOR_FAILED_EVENT = 'a2.actor.failed'\n/** The per-instance lane every serial handler shares — the state's write lock. */\nexport const ACTOR_LANE = 'a2.actor'\n/** Reducer identity — bump when the fold's meaning changes. */\nexport const ACTOR_REDUCER_NAME = 'a2.actor.v1'\n\n/**\n * A handler answered by throwing `NonRetriableError`: the event\n * settled, the state did not change. Isomorphic — the server raises it\n * from calls and `fetch()` serializes it as a 409; the client's `call`\n * proxy revives it from that response.\n */\nexport class ActorRefusedError extends Error {\n /** The refused event's name. */\n readonly event: string\n /** The refused event's message id. */\n readonly messageId: string\n constructor(event: string, messageId: string, message: string) {\n super(message)\n this.name = 'ActorRefusedError'\n this.event = event\n this.messageId = messageId\n }\n}\n\n/**\n * The declaration an actor is defined over: its state shape and its\n * event vocabulary, as types. Core A2 contracts are schemas because\n * the wire is untrusted; actor protocols are types because your\n * server is trusted — same contract-first design language, dialed to\n * the trust level.\n */\nexport type ActorProtocol = {\n state: object\n events: object\n /**\n * Optional third vocabulary: presence field → value type. Ephemeral\n * audience state (who is here, cursors), replicated to subscribers\n * and never stored in the log. Declaring it requires `presence:\n * true` in the actor options — the wire bit types cannot carry.\n */\n presence?: object\n}\n\n/** The protocol's presence vocabulary, `never` when undeclared. */\nexport type ActorPresenceOf<D extends ActorProtocol> = D extends {\n presence: infer P extends object\n}\n ? P\n : never\n\n/** A `setPresence` patch: changed fields, `null` clears one. */\nexport type ActorPresenceValues<P> = {\n [F in keyof P & string]?: P[F] | null\n}\n\n/**\n * The replicated presence map: participant → field → latest value,\n * last write wins per field. Values are peer-authored — render them\n * like user input.\n */\nexport type ActorPresenceMap<P> = {\n [participant: string]: {\n [F in keyof P & string]?: { value: P[F]; seen: number; at: Date }\n }\n}\n\n/**\n * The typed self-send surface: one method per declared event —\n * `ctx.send.transfer({ ref, amount })`. Buffered, not immediate: every\n * send requested during a handler commits atomically with that\n * handler's completion (a serial handler's state commit, a concurrent\n * handler's settlement), riding core's returned-events semantics — so\n * a reserve-and-trigger can never half-happen, and re-runs converge on\n * the same deterministic message ids.\n */\nexport type ActorSend<E> = {\n readonly [K in keyof E]: {} extends E[K]\n ? (input?: E[K]) => void\n : (input: E[K]) => void\n}\n\n/**\n * Timing for a scheduled event: exactly `{ delay: '5d' }` or\n * `{ at: Date }` (core §6 semantics — relative delays anchor to the\n * triggering message's durable `createdAt`, so re-runs resolve the\n * same due time). `name` overrides the timer's identity — it defaults\n * to the target event name, scoped to the triggering message, so one\n * handler run gets one timer per target event unless named apart.\n */\nexport type ActorScheduleOptions = ScheduleTiming & { name?: string }\n\n/**\n * The typed durable-timer surface: one method per declared event —\n * `ctx.schedule.refund({ ref: ctx.id }, { delay: '1h' })`. Unlike\n * `send`, scheduling is immediate, not buffered: it awaits provider\n * acceptance at call time (a timer is provider-side, not a log row),\n * so a handler that schedules and then refuses has still armed the\n * timer. That is safe by the guarded-delivery idiom — the stale timer\n * fires into an idempotent no-op — but it is the one exception to\n * \"refusals are total\". Requires a configured `scheduler`.\n */\nexport type ActorScheduleSend<E> = {\n readonly [K in keyof E]: {} extends E[K]\n ? (input: E[K] | undefined, options: ActorScheduleOptions) => Promise<void>\n : (input: E[K], options: ActorScheduleOptions) => Promise<void>\n}\n\n/** What a serial handler receives alongside its typed input. */\nexport type ActorContext<D extends ActorProtocol> = {\n /** Mutable draft, committed atomically with the handler's completion. */\n state: D['state']\n /** The message id — stable across re-runs; the idempotency key for external I/O. */\n id: string\n /** Durable 1-based dispatch ordinal of this message. */\n attempt: number\n /** The ordinary A2 handler signal — fires on claim expiry or supersession. */\n signal: AbortSignal\n /** Typed buffered self-send — committed atomically with the state commit. */\n send: ActorSend<D['events']>\n /** Typed durable timers — immediate provider handoff, see ActorScheduleSend. */\n schedule: ActorScheduleSend<D['events']>\n}\n\n/**\n * What a `concurrent: true` handler receives. No draft — concurrent\n * handlers run off the lane, in parallel, so state is a snapshot read\n * (honest about staleness) and mutations happen by sending events\n * whose serial handlers decide against fresh state.\n */\nexport type ActorConcurrentContext<D extends ActorProtocol> = {\n /** The message id — stable across re-runs; the idempotency key for external I/O. */\n id: string\n /** Durable 1-based dispatch ordinal of this message. */\n attempt: number\n /** The ordinary A2 handler signal — fires on claim expiry or supersession. */\n signal: AbortSignal\n /** Snapshot read — observational; the world moves while this runs. */\n state(): Promise<{ state: D['state']; index: number }>\n /** Typed buffered self-send — committed atomically with settlement. */\n send: ActorSend<D['events']>\n /** Typed durable timers — immediate provider handoff, see ActorScheduleSend. */\n schedule: ActorScheduleSend<D['events']>\n}\n\nexport type ActorStatePayload<S> = {\n state: S\n /** The event whose handler committed this state. */\n event: string\n /** The message (invocation event) id this state answers. */\n message: string\n}\n\nexport type ActorFailedPayload = {\n /** The message (invocation event) id this refusal answers. */\n message: string\n event: string\n error: string\n}\n\n/** The event vocabulary a client needs to follow an actor's state. */\nexport type ActorClientEventDefs<S> = {\n 'a2.actor.state': StandardSchemaV1<ActorStatePayload<S>>\n}\n\ntype SchemaResult<T> = StandardSchemaV1.Result<T>\n\nconst issue = <T>(message: string): SchemaResult<T> => ({\n issues: [{ message }],\n})\n\nconst schema = <T>(\n label: string,\n parse: (value: unknown) => SchemaResult<T>,\n): StandardSchemaV1<T> => ({\n '~standard': {\n version: 1,\n vendor: 'a2',\n validate(value) {\n try {\n return parse(value)\n } catch (error) {\n return issue(\n `${label}: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n },\n },\n})\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/** True for plain JSON trees — what the log can store without loss. */\nexport function isJsonTree(\n value: unknown,\n seen: Set<object> = new Set(),\n): boolean {\n if (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'boolean'\n ) {\n return true\n }\n if (typeof value === 'number') return Number.isFinite(value)\n if (typeof value !== 'object') return false\n if (seen.has(value)) return false\n seen.add(value)\n const valid = Array.isArray(value)\n ? value.every((item) => isJsonTree(item, seen))\n : Object.getPrototypeOf(value) === Object.prototype &&\n Object.values(value).every(\n (item) => item === undefined || isJsonTree(item, seen),\n )\n seen.delete(value)\n return valid\n}\n\n/** Per-field ceiling for presence values — presence is a cursor, not a document. */\nexport const PRESENCE_VALUE_MAX_BYTES = 8_192\n\n/**\n * The open presence vocabulary: the '*' catch-all validates any field\n * name against the JSON floor. The protocol types the vocabulary at\n * compile time; the route's `authorize` sees every set before\n * acceptance; renderers treat values as user input. Meaning has three\n * guards — this schema only owns the bytes.\n */\nexport const openPresenceDefs: Readonly<\n Record<string, StandardSchemaV1<unknown>>\n> = Object.freeze({\n '*': {\n '~standard': {\n version: 1,\n vendor: 'a2',\n validate: (value: unknown) => {\n if (!isJsonTree(value)) {\n return {\n issues: [{ message: 'presence values must be plain JSON trees' }],\n }\n }\n if (JSON.stringify(value).length > PRESENCE_VALUE_MAX_BYTES) {\n return {\n issues: [\n {\n message: `presence values are capped at ${PRESENCE_VALUE_MAX_BYTES} bytes`,\n },\n ],\n }\n }\n return { value }\n },\n },\n } satisfies StandardSchemaV1<unknown>,\n})\n\n/**\n * The `a2.actor.state` envelope: provenance plus the state, held to a\n * plain JSON tree (a `Date` or `Map` in state fails loudly at commit,\n * never silently coerces in the log).\n */\nexport function actorStateSchema<S>(): StandardSchemaV1<ActorStatePayload<S>> {\n return schema(ACTOR_STATE_EVENT, (value) => {\n if (\n !isRecord(value) ||\n typeof value['event'] !== 'string' ||\n typeof value['message'] !== 'string'\n ) {\n return issue(`invalid ${ACTOR_STATE_EVENT} payload`)\n }\n const state = value['state']\n if (!isJsonTree(state)) {\n return issue('the actor state must be a plain JSON tree')\n }\n return {\n value: {\n state: state as S,\n event: value['event'],\n message: value['message'],\n },\n }\n })\n}\n\nexport const actorFailedSchema: StandardSchemaV1<ActorFailedPayload> = schema(\n ACTOR_FAILED_EVENT,\n (value) => {\n if (\n !isRecord(value) ||\n typeof value['message'] !== 'string' ||\n typeof value['event'] !== 'string' ||\n typeof value['error'] !== 'string'\n ) {\n return issue(`invalid ${ACTOR_FAILED_EVENT} payload`)\n }\n return {\n value: {\n message: value['message'],\n event: value['event'],\n error: value['error'],\n },\n }\n },\n)\n\nexport type ActorReducerOptions<S> = {\n /** The actor's name — must match the server-side definition. */\n name: string\n /** The initial state — a plain JSON tree, the fold's seed. */\n state: S\n}\n\n/**\n * The library fold over an actor's state commits — last write wins.\n * Pure library code: a browser bundle folds an actor's live state with\n * no user code, so the actor definition itself stays server-only\n * (import the server module's type for typing, this reducer for data).\n */\nexport function actorReducer<S>(\n options: ActorReducerOptions<S>,\n): Reducer<ActorClientEventDefs<S>, S> {\n if (!isJsonTree(options.state)) {\n throw new TypeError(\n `actor '${options.name}': the initial state must be a plain JSON tree`,\n )\n }\n const events: ActorClientEventDefs<S> = {\n [ACTOR_STATE_EVENT]: actorStateSchema(),\n }\n return createContract({ name: options.name, events })\n .reducer({ name: ACTOR_REDUCER_NAME, initialState: options.state })\n .fold((state, event) =>\n event.type === ACTOR_STATE_EVENT ? event.payload.state : state,\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ai-CrEf6p_W.d.ts","names":[],"sources":["../src/ai-control.ts","../src/ai-client-state.ts","../src/ai-projector.ts","../src/ai-progress-batches.ts","../src/ai-message-projection.ts","../src/ai-stored-state.ts","../src/ai.ts"],"mappings":";;;;KAcY,UAAU,UAAU,YAAY;EAC1C;EACA,SAAS;EACT;EACA;;KAGU,eAAe,UAAU,YAAY;EAC3C;EAAgB,SAAS;EAAG;;EAC5B;EAAgB,SAAS;;EACzB;EAAgB;EAAiB;;EACjC;EAAkB;;EAElB;EACA;EACA;EACA;;EAEA;EAAgB;EAAgB;;EAChC;EAAiB;EAAgB,SAAS;EAAG;;EAC7C;EAAiB;;EACjB;;EACA;EAAuB,QAAQ;;EAC/B;EAAoB,UAAU;;EAC9B;EAAiB,UAAU;;EAC3B;EAAyB,SAAS;;EAClC;EAAiB,SAAS;;EAC1B;EAAqB,SAAS;;KAExB;EACV;EACA;EACA;EACA;;KAUU,WAAW,UAAU,YAAY;EAC3C;EACA,OAAO,UAAU;EACjB;;KA+BU;EAAa;EAAc;EAAY;;KACvC;EACV;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;;KAGE;EACV;EACA;EACA,MAAM;EACN,YAAY;;KAYF;EACV;EACA;EACA;EACA;IAAW;IAAe;IAAqB;;EAC/C;IAAS;IAAc;;;KAGb;EACV,SAAS;EACT;IACE;IACA;IACA,OAAO;IACP;IACA;IACA;IACA,eAAe;IACf;IACA;;;;;KCpIQ,aAAa,UAAU,aAAa,QAC9C,eAAe;EAEb;;KAYQ,oBAAoB,UAAU;EACxC;EACA,SAAS,aAAa;;;;KCjBnB;EACH;EACA;EACA;EACA;EACA;EACA;EACA;;KAmHU;EACV,MAAM;EACN,WAAW;EACX,OAAO,eAAe;;;;KChIZ;EAAkB;EAAe,QAAQ;;KAChD,aAAa;EAAoB,MAAM;EAAY,OAAO;;KAEnD;EACV;EACA,MAAM;EACN,QAAQ,MAAM;;;;KCcJ,kBAAkB,UAAU,aAAa,KACnD,2BAA2B;;;KChBxB,2CACgC;GAA2B,cAAA;;KAC3D;EAAY;;KACZ;EACC,OAAO;;EACP;EAAgB,OAAO,eAAe;;EACtC,QAAQ,eAAe;EAAO;;KAE/B;EACH,QAAQ;EACR;EACA,UAAU;EACV,QAAQ;;KAGE;EACV;EACA,QAAQ;EACR,YAAY;EACZ,QAAQ;;KAGE;EACV,UAAU;EACV,mBACG,kBAAkB;IAAe,YAAY;;EAChD,QAAQ;EACR,QAAQ;;cAGG;KAED,gBACV,UAAU,WACV,UAAU,gBACR,QAAQ,GAAG,eAAe,sBAAsB;YACxC,iBAAiB,QAAQ,GAAG;EACtC,KAAK,OAAO,gBAAgB;EAC5B,SAAS,OAAO,IAAI;;;;KC6BV;KAGA;KAEA;EAA0B,WAAW;;KACrC;EAAyB;;KACzB,sBAAsB,UAAU;EAC1C,SAAS;;EAET;;KAEU;EAA4B;;KACnC;EACH;EACA;;EAEA;;KAEU,4BAA4B;EAEhC;EAAsB;;EACtB;EAAmB;;KAEf;EACV;IAAY;IAAgB;;EAC5B;EACA,QAAQ;EACR;EACA;;KAEU;EACV;EACA;EACA;;KAEU,wBAAwB;KACxB;EACV;EACA;EACA;EACA;EACA;EACA;EACA;;KAEU;EACV;EACA;EACA;EACA;EACA;EACA,QAAQ;;KAEE;EACV;EACA;EACA;EACA;EACA,eAAe;EACf,QAAQ;EACR;;KAEU;EACV;EACA;EACA;EACA;EACA;;EAEA;EACA;;KAEU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAEU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAEU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;;KAEU;EACV;EACA;EACA;EACA;EACA;EACA;;KAEU;EACV;EACA;EACA;EACA;EACA;EACA,WAAW;;KAED;EACV;EACA;EACA;EACA;EACA;EACA,OAAO;;KAEG;EACV;EACA;;KAEU;EAAkC;;KAClC;EACV;EACA,QAAQ;;KAEE;EACN;;EACA;EAAoB,QAAQ;;EAC5B;;KAEM;EACV;EACA;EACA;EACA;EACA;EACA;;KAEU,2BAA2B,UAAU;EAC/C;EACA;EACA;EACA,UAAU;EACV;EACA;EACA,QAAQ;;KAGE,YAAY,UAAU,cAAY;EAC5C,wBAAwB,iBAAiB,eAAe;EACxD,wBAAwB,iBAAiB;EACzC,sBAAsB,iBAAiB;EACvC,oBAAoB,iBAAiB;EACrC,+BAA+B,iBAAiB;EAChD,wBAAwB;IACtB;IACA;;EAEF,sBAAsB,iBAAiB;EACvC,qBAAqB,iBAAiB;EACtC,sBAAsB,iBAAiB,sBAAsB;EAC7D,wBAAwB,iBAAiB;EACzC,0BAA0B,iBAAiB;EAC3C,2BAA2B,iBAAiB;EAC5C,sBAAsB,iBAAiB;EACvC,yBAAyB,iBAAiB;EAC1C,0BAA0B,iBAAiB;EAC3C,2BAA2B,iBAAiB;EAC5C,wBAAwB,iBAAiB;EACzC,kBAAkB,iBAAiB;EACnC,kBAAkB,iBAAiB;EACnC,yBAAyB,iBAAiB;EAC1C,yBAAyB,iBAAiB;EAC1C,sBAAsB,iBAAiB;EACvC,sBAAsB,iBAAiB;EACvC,2BAA2B,iBAAiB;EAC5C,2BAA2B,iBAAiB,2BAA2B;EACvE,+BAA+B,iBAAiB;EAChD,8BAA8B,iBAAiB;;KAGrC,mBAAmB;KAEnB,2BAA2B,UAAU,cAAY;EAC3D;EACA;;EAEA;EACA,cAAc;EACd;EACA;IAAW;IAAsB,QAAQ;;EACzC,iBAAiB,gBAAgB;EACjC,SAAS;EACT,WAAW;EACX,YAAY;IACN;IAAe;IAAwB,SAAS;;IAChD;IAAe;IAAwB,SAAS;;EAEtD,gBAAgB;IAEV;IACA;IACA,SAAS;;IAGT;IACA;IACA,SAAS;;;KAKL,kBAAkB;KAClB,eAAe;KAEf;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,gBAAgB,UAAU;EACpC;EACA;EACA;EACA;EACA,WAAW;EACX;EACA;EACA,QAAQ;;KAGE;EACV;EACA,OAAO;;KAGG,QAAQ,UAAU,cAAY;EACxC;IAAS;IAAiB,OAAO,UAAU;;EAC3C,uBAAuB,oBAAoB;EAC3C,QAAQ,WAAW;EACnB;EACA,SAAS;EACT,sBAAsB;EACtB;IAAW;IAAkB,WAAW;;EACxC,UAAU;EACV,QAAQ;EACR,kBAAkB;EAClB;EACA,qBAAqB;EACrB;EACA;EACA,kBAAkB,2BAA2B;EAC7C,gBAAgB,eAEd,KAAK;EAEP,qBAAqB;EACrB,sBAAsB;EAItB,kBAAkB;EAClB,eAAe;EACf,OAAO;EACP,YAAY,gBAAgB;EAC5B,eAAe,eAAe;EAC9B,OAAO;EACP;;KAGU,gBACV,UAAU,cAAY,aACtB,UAAU,YAAY,YAAY;WAEzB,UAAU,SAAS;WACnB,SAAS,gBAAgB,GAAG,QAAQ;;KAGnC,qBAAqB,YAC/B,KAAK;;KAGK,iBAAiB,UAAU,sBAAsB,eAC3D;KAIU,aAAa,UAAU,aAAW,UAAU;EACtD;EACA,SAAS;;EAET,gBAAgB,iBAAiB;;EAEjC;;KAGG,cAAc,UAAU,aAC3B,UAAU,mCAAmC,UAAU,oBACnD,iBAAiB,YAAY,WAAW,4BAChC,UAAU,eAEhB,IACA,cACF;iBAgNU,aAAa,UAAU,cAAY,aAAW;EAC5D,gBAAgB,iBAAiB;IAC/B,YAAY;cAsUH,QAAQ,YAAY;;iBAgGjB,cAAc,UAAU,aACtC,OAAO,QAAQ,IACf;EAAS;EAAc;EAAkB;EAAe;IACvD,QAAQ;;iBAmmCK,iBAAiB,UAAU,cAAY,aACrD;EAAoB;EAAc;EAAkB;MACnD;;iBAOa,cAAc,UAAU,WAAW;EACjD,UAAU,SAAS;EACnB;EACA,OAAO,QAAQ,GAAG,QAAQ,cAAc;EACxC,cAAc,0BAA0B,QAAQ,cAAc;IAC5D,gBAAgB,GAAG,QAAQ,cAAc;KAiBxC,aAAa;EAAO;EAA8B,SAAS;EAAG;;KAC9D,aACH,UAAU,aACV,UAAU,eAAe,gBACvB,aAAa,QAAQ,eAAe;EAAM,QAAQ;OACnD;EAA+B;;KAEtB;EACV,QAAQ,UAAU,aAChB,SAAS,GACT;IAAY;MACX,aAAa;EAChB,KAAK,UAAU,aAAW,SAAS,IAAI,aAAa;EACpD;IACE,OAAO;MAAW;QAAoB,aAAa;IACnD,QAAQ;MACN;MACA;MACA;QACE,aAAa;IACjB,KAAK,UAAU,aAAW;MACxB,SAAS;QACP,aAAa;IACjB,KAAK;MACH;MACA;QACE,aAAa;;EAEnB,KAAK;IACH;IACA;MACE,aAAa;EACjB,MAAM,UAAU,aAAW;IACzB;IACA,SAAS;IACT;MACE,aAAa;EACjB,MAAM;IACJ;MACE,aAAa;EACjB,UAAU,aAAa;EACvB,SACE,UAAU,2BACT,aAAa;EAChB,MAAM,UAAU,wBAAwB,aAAa;EACrD,aACE,SAAS,wBACR,aAAa;EAChB,MAAM,SAAS,yBAAyB,aAAa;EACrD,UACE,SAAS,4BACR,aAAa;EAChB,WACE,QAAQ,oBACP,aAAa;;;cAsBL,QAAQ;;;;;;;;;iBAgEL,eAAe,UAAU,oBACvC,iBAAiB,SAAS;WAAgB,UAAU,SAAS;IAC5D,iBAAiB;;;;;iBAqBJ,MACd,UAAU,cAAY,aACtB,UAAU,YAAY,sBACtB,SAAS,aAAa,GAAG,KAAK,gBAAgB,GAAG,YAAY,KAAK"}
|