experimental-a2 0.17.0 → 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 +21 -0
- package/README.md +1 -1
- package/dist/{actor-DBbe5xeE.d.ts → actor-Bjce9_5U.d.ts} +5 -5
- package/dist/{actor-DBbe5xeE.d.ts.map → actor-Bjce9_5U.d.ts.map} +1 -1
- package/dist/actor-client.d.ts +1 -1
- package/dist/actor-react.d.ts +3 -3
- package/dist/actor-react.js +1 -1
- package/dist/actor.d.ts +1 -1
- package/dist/actor.js +2 -2
- package/dist/{ai-UrWfKeuv.js → ai-BpOGm-zB.js} +2 -2
- package/dist/{ai-UrWfKeuv.js.map → ai-BpOGm-zB.js.map} +1 -1
- package/dist/{ai-vpGtcaCB.d.ts → ai-DrUaMyRt.d.ts} +3 -3
- package/dist/{ai-vpGtcaCB.d.ts.map → ai-DrUaMyRt.d.ts.map} +1 -1
- package/dist/ai-client.d.ts +2 -2
- package/dist/ai-client.js +2 -2
- 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 +5 -5
- package/dist/ai-react.js +2 -2
- package/dist/ai-server.d.ts +47 -25
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +106 -37
- package/dist/ai-server.js.map +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.js +1 -1
- package/dist/bounded-cache-CPHWF-8h.js +41 -0
- package/dist/bounded-cache-CPHWF-8h.js.map +1 -0
- package/dist/{client-COaiaDub.js → client-BReKqwZC.js} +3 -3
- package/dist/{client-COaiaDub.js.map → client-BReKqwZC.js.map} +1 -1
- package/dist/{client-qRnRUzBS.d.ts → client-h_DKFAjj.d.ts} +3 -3
- package/dist/{client-qRnRUzBS.d.ts.map → client-h_DKFAjj.d.ts.map} +1 -1
- package/dist/client.d.ts +3 -3
- package/dist/client.js +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/{initial-snapshot-BrLso5x_.d.ts → initial-snapshot-Bx-c0pDP.d.ts} +2 -2
- package/dist/{initial-snapshot-BrLso5x_.d.ts.map → initial-snapshot-Bx-c0pDP.d.ts.map} +1 -1
- package/dist/{internal-CbVvEwad.js → internal-B2T3U4Rq.js} +8 -2
- package/dist/internal-B2T3U4Rq.js.map +1 -0
- package/dist/otel.d.ts +1 -1
- package/dist/{react-BbJ-g6Uu.d.ts → react-BBXgHWFc.d.ts} +4 -4
- package/dist/{react-BbJ-g6Uu.d.ts.map → react-BBXgHWFc.d.ts.map} +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/reducer-BAXc8JyF.js.map +1 -1
- package/dist/{reducer-BYu6DT7h.d.ts → reducer-CqA59Q6U.d.ts} +2 -2
- package/dist/{reducer-BYu6DT7h.d.ts.map → reducer-CqA59Q6U.d.ts.map} +1 -1
- package/dist/scheduler-qstash.d.ts +2 -2
- package/dist/scheduler-qstash.js +2 -2
- package/dist/scheduler-vercel.d.ts +2 -2
- package/dist/scheduler-vercel.js +2 -2
- package/dist/{server-Rj64fNvX.js → server-Dw_k_7kO.js} +93 -60
- package/dist/server-Dw_k_7kO.js.map +1 -0
- package/dist/{server-CGM8WzRG.d.ts → server-En7cbi3v.d.ts} +36 -7
- package/dist/server-En7cbi3v.d.ts.map +1 -0
- package/dist/server.d.ts +4 -4
- package/dist/server.js +1 -1
- package/dist/{session-clear-Dshpuhff.d.ts → session-clear-Bo-XTFEy.d.ts} +2 -2
- package/dist/session-clear-Bo-XTFEy.d.ts.map +1 -0
- package/dist/{store-Gpkq7WBo.d.ts → store-Djdv0bnZ.d.ts} +31 -2
- 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.js +32 -6
- package/dist/store-memory.js.map +1 -1
- package/dist/{store-polling-4_y8lETm.js → store-polling-B5FcwJfo.js} +2 -2
- package/dist/{store-polling-4_y8lETm.js.map → store-polling-B5FcwJfo.js.map} +1 -1
- package/dist/store-postgres.d.ts +1 -1
- package/dist/store-postgres.js +54 -3
- package/dist/store-postgres.js.map +1 -1
- package/dist/{store-presence-polling-Q1C-k2dd.js → store-presence-polling-BAwS8RWn.js} +3 -3
- package/dist/{store-presence-polling-Q1C-k2dd.js.map → store-presence-polling-BAwS8RWn.js.map} +1 -1
- package/dist/store-redis-http.d.ts +1 -1
- package/dist/store-redis-http.js +3 -3
- package/dist/{store-redis-notify-tqWNnMRu.js → store-redis-notify-BRITti_o.js} +187 -68
- package/dist/store-redis-notify-BRITti_o.js.map +1 -0
- package/dist/store-redis.d.ts +1 -1
- package/dist/store-redis.js +1 -1
- package/dist/store-sqlite.d.ts +1 -1
- package/dist/store-sqlite.js +32 -2
- package/dist/store-sqlite.js.map +1 -1
- package/dist/{telemetry-cZH-cibj.d.ts → telemetry-Cyfqo6Qt.d.ts} +2 -2
- package/dist/telemetry-Cyfqo6Qt.d.ts.map +1 -0
- package/dist/{wire-DjfHOvdW.js → wire-rSUglYo8.js} +2 -2
- package/dist/{wire-DjfHOvdW.js.map → wire-rSUglYo8.js.map} +1 -1
- package/docs/01-quickstart.mdx +49 -83
- package/docs/{guides/07-examples.mdx → 02-examples.mdx} +10 -20
- package/docs/actors/01-introduction.mdx +48 -86
- package/docs/actors/02-concurrency.mdx +43 -70
- package/docs/actors/03-timers.mdx +28 -42
- package/docs/actors/04-routes.mdx +110 -150
- 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 +108 -144
- 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 +1 -1
- package/examples/playground/app/a0/[appId]/page.tsx +11 -6
- package/examples/playground/app/a0/app-list.tsx +9 -2
- package/examples/playground/app/a0/app-view.tsx +9 -1
- package/examples/playground/app/a0/apps/[appId]/route.ts +10 -5
- package/examples/playground/app/a0/apps.test.ts +12 -0
- package/examples/playground/app/a0/apps.ts +22 -7
- package/examples/playground/app/a0/chat.tsx +47 -1
- 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/model.test.ts +18 -1
- package/examples/playground/app/a0/model.ts +47 -10
- 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/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/sandbox-log.ts +10 -4
- package/examples/playground/app/a0/sandbox-session.ts +152 -0
- package/examples/playground/app/a0/scheduler/route.ts +2 -2
- package/examples/playground/app/a0/server.ts +100 -45
- package/examples/playground/app/a0/session.ts +17 -5
- package/examples/playground/app/a0/shell.tsx +11 -3
- package/examples/playground/app/agent/ingress.test.ts +6 -3
- package/examples/playground/app/agent/server.ts +9 -6
- package/examples/playground/app/agent/telemetry.test.ts +71 -50
- package/examples/playground/app/canvas/[canvasId]/canvas-client.tsx +1 -1
- package/examples/playground/app/chat/server.test.ts +30 -26
- package/examples/playground/app/chat/server.ts +46 -46
- package/examples/playground/next.config.ts +17 -5
- package/examples/playground/package.json +4 -1
- package/examples/playground/vercel.json +18 -0
- package/package.json +27 -3
- package/src/ai-agent.ts +261 -87
- 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-model-metadata.ts +11 -6
- package/src/ai-pi.browser.ts +5 -0
- package/src/ai-pi.ts +1263 -0
- package/src/ai-sdk-step.ts +2 -2
- package/src/ai-server.ts +3 -1
- package/src/internal.ts +7 -0
- package/src/libfx.d.ts +34 -0
- package/src/reducer.ts +1 -1
- package/src/server.ts +177 -19
- package/src/store-memory.ts +42 -7
- package/src/store-postgres.ts +80 -0
- package/src/store-redis-core.ts +210 -79
- package/src/store-redis-notify.ts +2 -0
- package/src/store-sqlite.ts +60 -0
- package/src/store.ts +33 -0
- package/src/telemetry.ts +1 -0
- package/dist/internal-CbVvEwad.js.map +0 -1
- package/dist/server-CGM8WzRG.d.ts.map +0 -1
- package/dist/server-Rj64fNvX.js.map +0 -1
- package/dist/session-clear-Dshpuhff.d.ts.map +0 -1
- package/dist/store-Gpkq7WBo.d.ts.map +0 -1
- package/dist/store-redis-notify-tqWNnMRu.js.map +0 -1
- package/dist/telemetry-cZH-cibj.d.ts.map +0 -1
- package/docs/concepts/01-contracts.mdx +0 -237
- 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 -193
- package/docs/guides/02-cancellation.mdx +0 -161
- package/docs/guides/03-react.mdx +0 -324
- package/docs/guides/04-local-first.mdx +0 -47
- package/docs/guides/05-production.mdx +0 -534
- package/docs/guides/06-ai-agents.mdx +0 -1408
- package/docs/guides/08-application-data.mdx +0 -113
- package/docs/guides/09-presence.mdx +0 -262
- package/docs/guides/10-transports.mdx +0 -221
- package/docs/reference/01-api.mdx +0 -2358
- package/docs/reference/02-errors.mdx +0 -150
- /package/docs/{concepts → contract}/meta.ts +0 -0
- /package/docs/{guides → server}/meta.ts +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as POLL_TIMINGS } from "./internal-
|
|
2
|
-
import { t as defaultSleep } from "./store-polling-
|
|
1
|
+
import { i as POLL_TIMINGS } from "./internal-B2T3U4Rq.js";
|
|
2
|
+
import { t as defaultSleep } from "./store-polling-B5FcwJfo.js";
|
|
3
3
|
//#region src/store-presence-polling.ts
|
|
4
4
|
const key = ({ participant, field }) => JSON.stringify([participant, field]);
|
|
5
5
|
function pollPresence({ read, deliver, sleep = defaultSleep }) {
|
|
@@ -91,4 +91,4 @@ function pollPresence({ read, deliver, sleep = defaultSleep }) {
|
|
|
91
91
|
//#endregion
|
|
92
92
|
export { pollPresence as t };
|
|
93
93
|
|
|
94
|
-
//# sourceMappingURL=store-presence-polling-
|
|
94
|
+
//# sourceMappingURL=store-presence-polling-BAwS8RWn.js.map
|
package/dist/{store-presence-polling-Q1C-k2dd.js.map → store-presence-polling-BAwS8RWn.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-presence-polling-
|
|
1
|
+
{"version":3,"file":"store-presence-polling-BAwS8RWn.js","names":[],"sources":["../src/store-presence-polling.ts"],"sourcesContent":["import type { PresencePatch } from './contract.ts'\nimport { POLL_TIMINGS } from './internal.ts'\nimport { defaultSleep, type Sleeper } from './store-polling.ts'\nimport type { PresenceRow } from './store.ts'\n\nconst key = ({\n participant,\n field,\n}: Pick<PresenceRow, 'participant' | 'field'>): string =>\n JSON.stringify([participant, field])\n\nexport function pollPresence({\n read,\n deliver,\n sleep = defaultSleep,\n}: {\n read: () => Promise<PresenceRow[]>\n deliver: (patch: PresencePatch) => void\n sleep?: (ms: number) => Sleeper\n}): {\n ready: Promise<void>\n update(patch: PresencePatch): void\n wake(): void\n stop(): void\n} {\n let stopped = false\n let pending: Sleeper | undefined\n let interval = Math.min(\n POLL_TIMINGS.activeFloorMs,\n POLL_TIMINGS.idleCeilingMs,\n )\n let version = 0\n const seen = new Map<string, Omit<PresenceRow, 'expiresAt'>>()\n const activate = (): void => {\n version += 1\n interval = Math.min(POLL_TIMINGS.activeFloorMs, POLL_TIMINGS.idleCeilingMs)\n pending?.cancel()\n }\n const ready = read()\n .then((rows) => {\n if (stopped) return\n for (const row of rows) seen.set(key(row), row)\n return undefined\n })\n // Seeding is best effort; foreground snapshots still report read errors.\n .catch(() => undefined)\n\n const run = async (): Promise<void> => {\n await ready\n for (;;) {\n if (stopped) return\n const before = version\n pending = sleep(interval)\n // oxlint-disable-next-line no-await-in-loop -- adaptive presence polling\n await pending.promise\n if (stopped) return\n try {\n const reading = version\n // oxlint-disable-next-line no-await-in-loop -- read each new presence snapshot\n const rows = await read()\n if (stopped) return\n if (version !== reading) continue\n const live = new Set<string>()\n let changed = false\n for (const row of rows) {\n const id = key(row)\n live.add(id)\n const prior = seen.get(id)\n seen.set(id, row)\n if (\n prior?.seen === row.seen &&\n prior.at.getTime() === row.at.getTime() &&\n JSON.stringify(prior.value) === JSON.stringify(row.value)\n )\n continue\n changed = true\n deliver({\n participant: row.participant,\n values: { [row.field]: row.value },\n seen: row.seen,\n at: row.at,\n })\n }\n for (const [id, row] of seen) {\n if (live.has(id)) continue\n seen.delete(id)\n changed = true\n deliver({\n participant: row.participant,\n values: { [row.field]: null },\n seen: row.seen,\n at: new Date(),\n })\n }\n if (changed) activate()\n else if (version === before)\n interval = Math.min(interval * 2, POLL_TIMINGS.idleCeilingMs)\n } catch {\n interval = POLL_TIMINGS.idleCeilingMs\n }\n }\n }\n void run()\n return {\n ready,\n wake: activate,\n update(patch) {\n for (const [field, value] of Object.entries(patch.values)) {\n seen.set(key({ participant: patch.participant, field }), {\n participant: patch.participant,\n field,\n value,\n seen: patch.seen,\n at: patch.at,\n })\n }\n activate()\n },\n stop() {\n stopped = true\n pending?.cancel()\n seen.clear()\n },\n }\n}\n"],"mappings":";;;AAKA,MAAM,OAAO,EACX,aACA,YAEA,KAAK,UAAU,CAAC,aAAa,KAAK,CAAC;AAErC,SAAgB,aAAa,EAC3B,MACA,SACA,QAAQ,gBAUR;CACA,IAAI,UAAU;CACd,IAAI;CACJ,IAAI,WAAW,KAAK,IAClB,aAAa,eACb,aAAa,aACf;CACA,IAAI,UAAU;CACd,MAAM,uBAAO,IAAI,IAA4C;CAC7D,MAAM,iBAAuB;EAC3B,WAAW;EACX,WAAW,KAAK,IAAI,aAAa,eAAe,aAAa,aAAa;EAC1E,SAAS,OAAO;CAClB;CACA,MAAM,QAAQ,KAAK,CAAC,CACjB,MAAM,SAAS;EACd,IAAI,SAAS;EACb,KAAK,MAAM,OAAO,MAAM,KAAK,IAAI,IAAI,GAAG,GAAG,GAAG;CAEhD,CAAC,CAAC,CAED,YAAY,KAAA,CAAS;CAExB,MAAM,MAAM,YAA2B;EACrC,MAAM;EACN,SAAS;GACP,IAAI,SAAS;GACb,MAAM,SAAS;GACf,UAAU,MAAM,QAAQ;GAExB,MAAM,QAAQ;GACd,IAAI,SAAS;GACb,IAAI;IACF,MAAM,UAAU;IAEhB,MAAM,OAAO,MAAM,KAAK;IACxB,IAAI,SAAS;IACb,IAAI,YAAY,SAAS;IACzB,MAAM,uBAAO,IAAI,IAAY;IAC7B,IAAI,UAAU;IACd,KAAK,MAAM,OAAO,MAAM;KACtB,MAAM,KAAK,IAAI,GAAG;KAClB,KAAK,IAAI,EAAE;KACX,MAAM,QAAQ,KAAK,IAAI,EAAE;KACzB,KAAK,IAAI,IAAI,GAAG;KAChB,IACE,OAAO,SAAS,IAAI,QACpB,MAAM,GAAG,QAAQ,MAAM,IAAI,GAAG,QAAQ,KACtC,KAAK,UAAU,MAAM,KAAK,MAAM,KAAK,UAAU,IAAI,KAAK,GAExD;KACF,UAAU;KACV,QAAQ;MACN,aAAa,IAAI;MACjB,QAAQ,GAAG,IAAI,QAAQ,IAAI,MAAM;MACjC,MAAM,IAAI;MACV,IAAI,IAAI;KACV,CAAC;IACH;IACA,KAAK,MAAM,CAAC,IAAI,QAAQ,MAAM;KAC5B,IAAI,KAAK,IAAI,EAAE,GAAG;KAClB,KAAK,OAAO,EAAE;KACd,UAAU;KACV,QAAQ;MACN,aAAa,IAAI;MACjB,QAAQ,GAAG,IAAI,QAAQ,KAAK;MAC5B,MAAM,IAAI;MACV,oBAAI,IAAI,KAAK;KACf,CAAC;IACH;IACA,IAAI,SAAS,SAAS;SACjB,IAAI,YAAY,QACnB,WAAW,KAAK,IAAI,WAAW,GAAG,aAAa,aAAa;GAChE,QAAQ;IACN,WAAW,aAAa;GAC1B;EACF;CACF;CACA,IAAS;CACT,OAAO;EACL;EACA,MAAM;EACN,OAAO,OAAO;GACZ,KAAK,MAAM,CAAC,OAAO,UAAU,OAAO,QAAQ,MAAM,MAAM,GACtD,KAAK,IAAI,IAAI;IAAE,aAAa,MAAM;IAAa;GAAM,CAAC,GAAG;IACvD,aAAa,MAAM;IACnB;IACA;IACA,MAAM,MAAM;IACZ,IAAI,MAAM;GACZ,CAAC;GAEH,SAAS;EACX;EACA,OAAO;GACL,UAAU;GACV,SAAS,OAAO;GAChB,KAAK,MAAM;EACb;CACF;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as Clock, s as IdSource, t as A2Store } from "./store-
|
|
1
|
+
import { r as Clock, s as IdSource, t as A2Store } from "./store-Djdv0bnZ.js";
|
|
2
2
|
//#region src/store-redis-http.d.ts
|
|
3
3
|
type RedisHttpStoreOptions = {
|
|
4
4
|
/** REST endpoint, e.g. `process.env.UPSTASH_REDIS_REST_URL`. */
|
package/dist/store-redis-http.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { i as A2Error } from "./session-clear-DGI4jTQ5.js";
|
|
2
|
-
import { r as NOTIFY_TIMINGS } from "./internal-
|
|
3
|
-
import { t as defaultSleep } from "./store-polling-
|
|
2
|
+
import { r as NOTIFY_TIMINGS } from "./internal-B2T3U4Rq.js";
|
|
3
|
+
import { t as defaultSleep } from "./store-polling-B5FcwJfo.js";
|
|
4
4
|
import { n as SYSTEM_CLOCK, t as RANDOM_IDS } from "./store-N8PXxDAS.js";
|
|
5
|
-
import { t as createRedisNotifyStore } from "./store-redis-notify-
|
|
5
|
+
import { t as createRedisNotifyStore } from "./store-redis-notify-BRITti_o.js";
|
|
6
6
|
//#region src/redis-http-subscriptions.ts
|
|
7
7
|
function redisHttpSubscriptions({ url, token, onReconnect, fallback }) {
|
|
8
8
|
const subscriptions = /* @__PURE__ */ new Map();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { i as A2Error, r as sessionClearedError, s as supersededAttemptError, t as CLEAR_EVENT_TYPE } from "./session-clear-DGI4jTQ5.js";
|
|
2
|
-
import {
|
|
3
|
-
import { i as streamActivities, n as pollingStream, r as createStreamActivity, t as defaultSleep } from "./store-polling-
|
|
2
|
+
import { _ as nullProtoRecord, r as NOTIFY_TIMINGS, y as stateTailReaders } from "./internal-B2T3U4Rq.js";
|
|
3
|
+
import { i as streamActivities, n as pollingStream, r as createStreamActivity, t as defaultSleep } from "./store-polling-B5FcwJfo.js";
|
|
4
4
|
import { n as isSerializedEvent, r as parseSerializedEvent, t as bufferedEvents } from "./stream-buffer-Cx7AAPGq.js";
|
|
5
5
|
import { t as idempotentReplay } from "./idempotent-replay-JdgMQRRm.js";
|
|
6
6
|
import { t as decodeReturnedEventIds } from "./store-codec-DTG0Ftek.js";
|
|
7
|
-
import { t as pollPresence } from "./store-presence-polling-
|
|
7
|
+
import { t as pollPresence } from "./store-presence-polling-BAwS8RWn.js";
|
|
8
8
|
//#region src/presence-recovery.ts
|
|
9
9
|
const key = ({ participant, field }) => JSON.stringify([participant, field]);
|
|
10
10
|
function presenceRecovery({ read, deliver, isActive }) {
|
|
@@ -102,6 +102,22 @@ function presenceRecovery({ read, deliver, isActive }) {
|
|
|
102
102
|
const FEED_PAGE_SIZE = 1e3;
|
|
103
103
|
const READ_CONCURRENCY = 16;
|
|
104
104
|
const META_CHUNK_SIZE = 1e3;
|
|
105
|
+
/** The metadata columns of a full stored row. */
|
|
106
|
+
const STORED_EVENT_META_SUFFIXES = [
|
|
107
|
+
"p",
|
|
108
|
+
"pa",
|
|
109
|
+
"ri",
|
|
110
|
+
"ch",
|
|
111
|
+
"ce",
|
|
112
|
+
"f",
|
|
113
|
+
"fc",
|
|
114
|
+
"lc",
|
|
115
|
+
"lf",
|
|
116
|
+
"lfa",
|
|
117
|
+
"d",
|
|
118
|
+
"a",
|
|
119
|
+
"e"
|
|
120
|
+
];
|
|
105
121
|
/**
|
|
106
122
|
* Upstash bills every call a script makes, so scripts read the counter and
|
|
107
123
|
* split with one MGET, read metadata with one HMGET per hash (`read_fields`),
|
|
@@ -256,6 +272,32 @@ local function flush_queue()
|
|
|
256
272
|
end
|
|
257
273
|
`;
|
|
258
274
|
/**
|
|
275
|
+
* Settles one unfinished event for scripts that include ENQUEUE_LUA: it
|
|
276
|
+
* leaves the pending and ready sets, and a lane head hands its lane to the
|
|
277
|
+
* next unfinished event. A dead-lettered successor stays out of the ready set.
|
|
278
|
+
*/
|
|
279
|
+
const SETTLE_LUA = `
|
|
280
|
+
local function settle(field, lane, next_field)
|
|
281
|
+
redis.call('ZREM', PENDING, field)
|
|
282
|
+
redis.call('ZREM', READY, field)
|
|
283
|
+
if lane == '' then return end
|
|
284
|
+
local head_key = lane_field(lane, 'head')
|
|
285
|
+
if redis.call('HGET', META, head_key) ~= field then return end
|
|
286
|
+
while next_field do
|
|
287
|
+
local row = read_fields({ next_field }, { 'p', 'f', 'next' })[next_field]
|
|
288
|
+
if not row[1] then
|
|
289
|
+
redis.call('HSET', META, head_key, next_field)
|
|
290
|
+
if not row[2] then
|
|
291
|
+
redis.call('ZADD', READY, tonumber(next_field), next_field)
|
|
292
|
+
end
|
|
293
|
+
return
|
|
294
|
+
end
|
|
295
|
+
next_field = row[3]
|
|
296
|
+
end
|
|
297
|
+
clear_lane(lane)
|
|
298
|
+
end
|
|
299
|
+
`;
|
|
300
|
+
/**
|
|
259
301
|
* Event-id ownership for scripts that add events. Each script reads the
|
|
260
302
|
* counter, split, clear boundary, and per-id keys with one MGET and applies
|
|
261
303
|
* the first three. Returns the owner record, or false, per event, and the
|
|
@@ -580,25 +622,7 @@ ${ENQUEUE_LUA}
|
|
|
580
622
|
${ID_OWNERS_LUA}
|
|
581
623
|
${RELEASE_PINS_LUA}
|
|
582
624
|
${WAKE_LUA}
|
|
583
|
-
|
|
584
|
-
redis.call('ZREM', PENDING, field)
|
|
585
|
-
redis.call('ZREM', READY, field)
|
|
586
|
-
if lane == '' then return end
|
|
587
|
-
local head_key = lane_field(lane, 'head')
|
|
588
|
-
if redis.call('HGET', META, head_key) ~= field then return end
|
|
589
|
-
while next_field do
|
|
590
|
-
local row = read_fields({ next_field }, { 'p', 'f', 'next' })[next_field]
|
|
591
|
-
if not row[1] then
|
|
592
|
-
redis.call('HSET', META, head_key, next_field)
|
|
593
|
-
if not row[2] then
|
|
594
|
-
redis.call('ZADD', READY, tonumber(next_field), next_field)
|
|
595
|
-
end
|
|
596
|
-
return
|
|
597
|
-
end
|
|
598
|
-
next_field = row[3]
|
|
599
|
-
end
|
|
600
|
-
clear_lane(lane)
|
|
601
|
-
end
|
|
625
|
+
${SETTLE_LUA}
|
|
602
626
|
local parent = ARGV[3]
|
|
603
627
|
local attempt = tonumber(ARGV[4])
|
|
604
628
|
local n = tonumber(ARGV[5])
|
|
@@ -684,6 +708,76 @@ if n > 0 then wake(ARGV[6 + n * 5], tostring(total + n), ARGV[2]) end
|
|
|
684
708
|
return { 'ok', tostring(total + 1) }
|
|
685
709
|
`;
|
|
686
710
|
/**
|
|
711
|
+
* KEYS: counter, meta, pending, ready, metadata split.
|
|
712
|
+
* ARGV: idx, action ('retry' | 'skip'), nowMs.
|
|
713
|
+
* Returns [redriven, hasPending]. Acts only on an unfinished, dead-lettered
|
|
714
|
+
* event above the clear boundary. A retry keeps the event pending and makes
|
|
715
|
+
* it ready again when it is unlaned or its lane's head.
|
|
716
|
+
*/
|
|
717
|
+
const REDRIVE_LUA = `
|
|
718
|
+
local COUNTER, META, SPLIT, PENDING, READY = KEYS[1], KEYS[2], KEYS[5], KEYS[3], KEYS[4]
|
|
719
|
+
${META_LUA}
|
|
720
|
+
${ENQUEUE_LUA}
|
|
721
|
+
${SETTLE_LUA}
|
|
722
|
+
local function result(redriven)
|
|
723
|
+
return { redriven, redis.call('ZCARD', PENDING) > 0 and '1' or '0' }
|
|
724
|
+
end
|
|
725
|
+
local counts = redis.call('MGET', COUNTER, SPLIT, CLEAR)
|
|
726
|
+
local total = tonumber(counts[1] or '0')
|
|
727
|
+
use_split(counts[2], counts[1], counts[3])
|
|
728
|
+
local idx = tonumber(ARGV[1])
|
|
729
|
+
if idx <= boundary or idx > total then return result('0') end
|
|
730
|
+
local field = tostring(idx)
|
|
731
|
+
local row = read_fields({ field }, { 'p', 'f', 'l', 'next' })[field]
|
|
732
|
+
if row[1] or not row[2] then return result('0') end
|
|
733
|
+
local meta_key = mkey(field)
|
|
734
|
+
local lane = row[3] or ''
|
|
735
|
+
if ARGV[2] == 'skip' then
|
|
736
|
+
put(meta_key, field .. ':p', ARGV[3])
|
|
737
|
+
settle(field, lane, row[4])
|
|
738
|
+
flush_queue()
|
|
739
|
+
flush()
|
|
740
|
+
else
|
|
741
|
+
redis.call('HDEL', meta_key, field .. ':f', field .. ':a')
|
|
742
|
+
if lane == '' or redis.call('HGET', META, lane_field(lane, 'head')) == field then
|
|
743
|
+
redis.call('ZADD', READY, idx, field)
|
|
744
|
+
end
|
|
745
|
+
end
|
|
746
|
+
return result('1')
|
|
747
|
+
`;
|
|
748
|
+
/**
|
|
749
|
+
* KEYS: store, counter, meta, pending, metadata split.
|
|
750
|
+
* Returns the dead-lettered events above the clear boundary, oldest first,
|
|
751
|
+
* as pairs of a stream entry and its STORED_EVENT_META_SUFFIXES columns.
|
|
752
|
+
* Every unfinished event is in the pending set, so the scan is bounded by
|
|
753
|
+
* unfinished work, not history; only dead letters read their full columns.
|
|
754
|
+
*/
|
|
755
|
+
const DEAD_LETTERS_LUA = `
|
|
756
|
+
local COUNTER, META, SPLIT = KEYS[2], KEYS[3], KEYS[5]
|
|
757
|
+
${META_LUA}
|
|
758
|
+
local counts = redis.call('MGET', COUNTER, SPLIT, CLEAR)
|
|
759
|
+
use_split(counts[2], counts[1], counts[3])
|
|
760
|
+
local candidates = {}
|
|
761
|
+
for _, field in ipairs(redis.call('ZRANGE', KEYS[4], 0, -1)) do
|
|
762
|
+
if tonumber(field) > boundary then candidates[#candidates + 1] = field end
|
|
763
|
+
end
|
|
764
|
+
local status = read_fields(candidates, { 'p', 'f' })
|
|
765
|
+
local dead = {}
|
|
766
|
+
for _, field in ipairs(candidates) do
|
|
767
|
+
if status[field][2] and not status[field][1] then dead[#dead + 1] = field end
|
|
768
|
+
end
|
|
769
|
+
local rows = read_fields(dead, { ${STORED_EVENT_META_SUFFIXES.map((suffix) => `'${suffix}'`).join(", ")} })
|
|
770
|
+
local result = {}
|
|
771
|
+
for _, field in ipairs(dead) do
|
|
772
|
+
local entries = redis.call('XRANGE', KEYS[1], field .. '-0', field .. '-0')
|
|
773
|
+
if #entries > 0 then
|
|
774
|
+
result[#result + 1] = entries[1]
|
|
775
|
+
result[#result + 1] = rows[field]
|
|
776
|
+
end
|
|
777
|
+
end
|
|
778
|
+
return result
|
|
779
|
+
`;
|
|
780
|
+
/**
|
|
687
781
|
* KEYS: head, history, event counter, event meta, pin counts, metadata split.
|
|
688
782
|
* ARGV: nowMs, event pin key prefix, write count, then per write:
|
|
689
783
|
* index, snapshot JSON, pin count, pin event indexes; finally the reducer
|
|
@@ -1070,21 +1164,6 @@ const fieldMap = (fields) => {
|
|
|
1070
1164
|
for (let i = 0; i + 1 < fields.length; i += 2) map[fields[i]] = fields[i + 1];
|
|
1071
1165
|
return map;
|
|
1072
1166
|
};
|
|
1073
|
-
const STORED_EVENT_META_SUFFIXES = [
|
|
1074
|
-
"p",
|
|
1075
|
-
"pa",
|
|
1076
|
-
"ri",
|
|
1077
|
-
"ch",
|
|
1078
|
-
"ce",
|
|
1079
|
-
"f",
|
|
1080
|
-
"fc",
|
|
1081
|
-
"lc",
|
|
1082
|
-
"lf",
|
|
1083
|
-
"lfa",
|
|
1084
|
-
"d",
|
|
1085
|
-
"a",
|
|
1086
|
-
"e"
|
|
1087
|
-
];
|
|
1088
1167
|
const entryIndex = (entryId) => Number(entryId.slice(0, entryId.indexOf("-")));
|
|
1089
1168
|
const toEvent = (sessionId, entry) => {
|
|
1090
1169
|
const fields = fieldMap(entry[1]);
|
|
@@ -1153,6 +1232,36 @@ const toCause = (raw) => {
|
|
|
1153
1232
|
...value.batchSize === void 0 ? {} : { batchSize: Number(value.batchSize) }
|
|
1154
1233
|
};
|
|
1155
1234
|
};
|
|
1235
|
+
/** A stream entry joined with its metadata columns; absent columns are unset. */
|
|
1236
|
+
const toStoredEvent = (sessionId, entry, column) => {
|
|
1237
|
+
const fields = fieldMap(entry[1]);
|
|
1238
|
+
const date = (suffix) => {
|
|
1239
|
+
const value = column(suffix);
|
|
1240
|
+
return value === void 0 ? null : new Date(Number(value));
|
|
1241
|
+
};
|
|
1242
|
+
const count = (suffix) => {
|
|
1243
|
+
const value = column(suffix);
|
|
1244
|
+
return value === void 0 ? null : Number(value);
|
|
1245
|
+
};
|
|
1246
|
+
const returnedEventIds = column("ri");
|
|
1247
|
+
return Object.assign(toEvent(sessionId, entry), {
|
|
1248
|
+
cause: toCause(fields["cause"]),
|
|
1249
|
+
lane: fields["lane"] === "" ? null : fields["lane"],
|
|
1250
|
+
processedAt: date("p"),
|
|
1251
|
+
processedByAttempt: count("pa"),
|
|
1252
|
+
returnedEventIds: returnedEventIds === void 0 ? null : decodeReturnedEventIds(returnedEventIds),
|
|
1253
|
+
firstClaimedAt: date("fc"),
|
|
1254
|
+
lastClaimedAt: date("lc"),
|
|
1255
|
+
attemptCount: count("d") ?? 0,
|
|
1256
|
+
claimHolder: column("ch") ?? null,
|
|
1257
|
+
claimExpiresAt: date("ce"),
|
|
1258
|
+
failureCount: count("a") ?? 0,
|
|
1259
|
+
lastFailedAt: date("lf"),
|
|
1260
|
+
lastFailedAttempt: count("lfa"),
|
|
1261
|
+
lastError: column("e") ?? null,
|
|
1262
|
+
failedAt: date("f")
|
|
1263
|
+
});
|
|
1264
|
+
};
|
|
1156
1265
|
const toClaimAvailableResult = (sessionId, reply) => {
|
|
1157
1266
|
const outcome = String(reply[0]);
|
|
1158
1267
|
if (outcome === "claimed") {
|
|
@@ -1295,36 +1404,8 @@ function createRedisStoreCore(options) {
|
|
|
1295
1404
|
}
|
|
1296
1405
|
}
|
|
1297
1406
|
return entries.map((entry) => {
|
|
1298
|
-
const
|
|
1299
|
-
|
|
1300
|
-
const fields = fieldMap(entry[1]);
|
|
1301
|
-
const processedAt = meta[`${idx}:p`];
|
|
1302
|
-
const processedByAttempt = meta[`${idx}:pa`];
|
|
1303
|
-
const returnedEventIds = meta[`${idx}:ri`];
|
|
1304
|
-
const claimHolder = meta[`${idx}:ch`];
|
|
1305
|
-
const claimExpiresAt = meta[`${idx}:ce`];
|
|
1306
|
-
const failedAt = meta[`${idx}:f`];
|
|
1307
|
-
const firstClaimedAt = meta[`${idx}:fc`];
|
|
1308
|
-
const lastClaimedAt = meta[`${idx}:lc`];
|
|
1309
|
-
const lastFailedAt = meta[`${idx}:lf`];
|
|
1310
|
-
const lastFailedAttempt = meta[`${idx}:lfa`];
|
|
1311
|
-
return Object.assign(event, {
|
|
1312
|
-
cause: toCause(fields["cause"]),
|
|
1313
|
-
lane: fields["lane"] === "" ? null : fields["lane"],
|
|
1314
|
-
processedAt: processedAt === void 0 ? null : new Date(Number(processedAt)),
|
|
1315
|
-
processedByAttempt: processedByAttempt === void 0 ? null : Number(processedByAttempt),
|
|
1316
|
-
returnedEventIds: returnedEventIds === void 0 ? null : decodeReturnedEventIds(returnedEventIds),
|
|
1317
|
-
firstClaimedAt: firstClaimedAt === void 0 ? null : new Date(Number(firstClaimedAt)),
|
|
1318
|
-
lastClaimedAt: lastClaimedAt === void 0 ? null : new Date(Number(lastClaimedAt)),
|
|
1319
|
-
attemptCount: Number(meta[`${idx}:d`] ?? 0),
|
|
1320
|
-
claimHolder: claimHolder ?? null,
|
|
1321
|
-
claimExpiresAt: claimExpiresAt === void 0 ? null : new Date(Number(claimExpiresAt)),
|
|
1322
|
-
failureCount: Number(meta[`${idx}:a`] ?? 0),
|
|
1323
|
-
lastFailedAt: lastFailedAt === void 0 ? null : new Date(Number(lastFailedAt)),
|
|
1324
|
-
lastFailedAttempt: lastFailedAttempt === void 0 ? null : Number(lastFailedAttempt),
|
|
1325
|
-
lastError: meta[`${idx}:e`] ?? null,
|
|
1326
|
-
failedAt: failedAt === void 0 ? null : new Date(Number(failedAt))
|
|
1327
|
-
});
|
|
1407
|
+
const idx = entryIndex(entry[0]);
|
|
1408
|
+
return toStoredEvent(sessionId, entry, (suffix) => meta[`${idx}:${suffix}`]);
|
|
1328
1409
|
});
|
|
1329
1410
|
};
|
|
1330
1411
|
const readEventPages = async (sessionId, afterIndex, throughIndex) => {
|
|
@@ -1675,6 +1756,42 @@ function createRedisStoreCore(options) {
|
|
|
1675
1756
|
};
|
|
1676
1757
|
});
|
|
1677
1758
|
},
|
|
1759
|
+
async deadLetters(sessionId) {
|
|
1760
|
+
return wrap(async () => {
|
|
1761
|
+
const reply = await evalScript(DEAD_LETTERS_LUA, [
|
|
1762
|
+
storeKey(sessionId),
|
|
1763
|
+
countKey(sessionId),
|
|
1764
|
+
metaKey(sessionId),
|
|
1765
|
+
pendingKey(sessionId),
|
|
1766
|
+
metaSplitKey(sessionId)
|
|
1767
|
+
], []);
|
|
1768
|
+
const events = [];
|
|
1769
|
+
for (let i = 0; i + 1 < reply.length; i += 2) {
|
|
1770
|
+
const columns = reply[i + 1];
|
|
1771
|
+
events.push(toStoredEvent(sessionId, reply[i], (suffix) => columns[STORED_EVENT_META_SUFFIXES.indexOf(suffix)] ?? void 0));
|
|
1772
|
+
}
|
|
1773
|
+
return events;
|
|
1774
|
+
});
|
|
1775
|
+
},
|
|
1776
|
+
async redrive({ sessionId, index, action }) {
|
|
1777
|
+
return wrap(async () => {
|
|
1778
|
+
const [redriven, hasPending] = await evalScript(REDRIVE_LUA, [
|
|
1779
|
+
countKey(sessionId),
|
|
1780
|
+
metaKey(sessionId),
|
|
1781
|
+
pendingKey(sessionId),
|
|
1782
|
+
readyKey(sessionId),
|
|
1783
|
+
metaSplitKey(sessionId)
|
|
1784
|
+
], [
|
|
1785
|
+
index,
|
|
1786
|
+
action,
|
|
1787
|
+
clock.now().getTime()
|
|
1788
|
+
]);
|
|
1789
|
+
return {
|
|
1790
|
+
redriven: redriven === "1",
|
|
1791
|
+
hasPending: hasPending === "1"
|
|
1792
|
+
};
|
|
1793
|
+
});
|
|
1794
|
+
},
|
|
1678
1795
|
async readState(sessionId, reducerName, stateOptions) {
|
|
1679
1796
|
return wrap(() => retryAfterGap(async () => {
|
|
1680
1797
|
const reply = await evalScript(READ_STATE_LUA, [
|
|
@@ -2084,6 +2201,8 @@ function createRedisNotifyStore(options) {
|
|
|
2084
2201
|
putSnapshots: core.putSnapshots,
|
|
2085
2202
|
clear: core.clear,
|
|
2086
2203
|
reclaim: core.reclaim,
|
|
2204
|
+
deadLetters: core.deadLetters,
|
|
2205
|
+
redrive: core.redrive,
|
|
2087
2206
|
presence: {
|
|
2088
2207
|
async set(ns, participant, values, meta) {
|
|
2089
2208
|
const patch = await core.presence.set(ns, participant, values, meta);
|
|
@@ -2371,4 +2490,4 @@ function createRedisNotifyStore(options) {
|
|
|
2371
2490
|
//#endregion
|
|
2372
2491
|
export { createRedisNotifyStore as t };
|
|
2373
2492
|
|
|
2374
|
-
//# sourceMappingURL=store-redis-notify-
|
|
2493
|
+
//# sourceMappingURL=store-redis-notify-BRITti_o.js.map
|