experimental-a2 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/CHANGELOG.md +207 -0
  2. package/dist/ai-CFNeCrRl.d.ts +334 -0
  3. package/dist/ai-CFNeCrRl.d.ts.map +1 -0
  4. package/dist/ai-server.browser.js +2 -0
  5. package/dist/ai-server.browser.js.map +1 -0
  6. package/dist/ai-server.d.ts +49 -9
  7. package/dist/ai-server.d.ts.map +1 -0
  8. package/dist/ai-server.js +123 -49
  9. package/dist/ai-server.js.map +1 -0
  10. package/dist/ai.d.ts +2 -303
  11. package/dist/ai.js +233 -86
  12. package/dist/ai.js.map +1 -0
  13. package/dist/cli-B3VuxoDe.js +599 -0
  14. package/dist/cli-B3VuxoDe.js.map +1 -0
  15. package/dist/cli-bin.d.ts +1 -0
  16. package/dist/cli-bin.js +7 -0
  17. package/dist/cli-bin.js.map +1 -0
  18. package/dist/cli.d.ts +20 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.js +2 -0
  21. package/dist/client-BKlyLiOU.js +1008 -0
  22. package/dist/client-BKlyLiOU.js.map +1 -0
  23. package/dist/client-D7mvIXrF.d.ts +191 -0
  24. package/dist/client-D7mvIXrF.d.ts.map +1 -0
  25. package/dist/client.d.ts +2 -90
  26. package/dist/client.js +1 -409
  27. package/dist/{contract-CG_adnu_.js → contract-48bUMgcL.js} +12 -2
  28. package/dist/contract-48bUMgcL.js.map +1 -0
  29. package/dist/{contract-C_3dIIEU.d.ts → contract-jIfaR085.d.ts} +63 -8
  30. package/dist/contract-jIfaR085.d.ts.map +1 -0
  31. package/dist/devtools-J_jZ2vQf.d.ts +152 -0
  32. package/dist/devtools-J_jZ2vQf.d.ts.map +1 -0
  33. package/dist/devtools-kJJaORn-.js +340 -0
  34. package/dist/devtools-kJJaORn-.js.map +1 -0
  35. package/dist/devtools-server.browser.js +3 -1
  36. package/dist/devtools-server.browser.js.map +1 -0
  37. package/dist/devtools-server.d.ts +4 -3
  38. package/dist/devtools-server.d.ts.map +1 -0
  39. package/dist/devtools-server.js +226 -43
  40. package/dist/devtools-server.js.map +1 -0
  41. package/dist/devtools.d.ts +2 -0
  42. package/dist/devtools.js +2 -0
  43. package/dist/{errors-BJRMd-h6.js → errors-BQuJpe82.js} +6 -4
  44. package/dist/errors-BQuJpe82.js.map +1 -0
  45. package/dist/{errors-xL_JTXsY.d.ts → errors-W6nwJ-fm.d.ts} +3 -2
  46. package/dist/errors-W6nwJ-fm.d.ts.map +1 -0
  47. package/dist/http.d.ts +135 -28
  48. package/dist/http.d.ts.map +1 -0
  49. package/dist/http.js +647 -61
  50. package/dist/http.js.map +1 -0
  51. package/dist/{idempotent-replay-BMyHrP0L.js → idempotent-replay-DuqEkYA7.js} +4 -2
  52. package/dist/idempotent-replay-DuqEkYA7.js.map +1 -0
  53. package/dist/index.d.ts +5 -5
  54. package/dist/index.js +2 -2
  55. package/dist/{inspection-E7qbD0Xj.js → inspection-DaxB5jM2.js} +4 -1
  56. package/dist/inspection-DaxB5jM2.js.map +1 -0
  57. package/dist/internal-DstsI6Re.js +211 -0
  58. package/dist/internal-DstsI6Re.js.map +1 -0
  59. package/dist/otel.d.ts +3 -2
  60. package/dist/otel.d.ts.map +1 -0
  61. package/dist/otel.js +2 -0
  62. package/dist/otel.js.map +1 -0
  63. package/dist/platform-B4TnJtWu.js +34 -0
  64. package/dist/platform-B4TnJtWu.js.map +1 -0
  65. package/dist/react.d.ts +47 -15
  66. package/dist/react.d.ts.map +1 -0
  67. package/dist/react.js +30 -15
  68. package/dist/react.js.map +1 -0
  69. package/dist/retryable-lazy-DZWmHpii.js +2 -0
  70. package/dist/retryable-lazy-DZWmHpii.js.map +1 -0
  71. package/dist/scheduler-qstash.d.ts +79 -0
  72. package/dist/scheduler-qstash.d.ts.map +1 -0
  73. package/dist/scheduler-qstash.js +501 -0
  74. package/dist/scheduler-qstash.js.map +1 -0
  75. package/dist/scheduler-task-BpzhPnRS.js +56 -0
  76. package/dist/scheduler-task-BpzhPnRS.js.map +1 -0
  77. package/dist/{recovery-vercel.d.ts → scheduler-vercel.d.ts} +18 -24
  78. package/dist/scheduler-vercel.d.ts.map +1 -0
  79. package/dist/scheduler-vercel.js +228 -0
  80. package/dist/scheduler-vercel.js.map +1 -0
  81. package/dist/server-C72KOw51.js +1457 -0
  82. package/dist/server-C72KOw51.js.map +1 -0
  83. package/dist/server-DUF9pjsx.d.ts +261 -0
  84. package/dist/server-DUF9pjsx.d.ts.map +1 -0
  85. package/dist/server.browser.js +2 -0
  86. package/dist/server.browser.js.map +1 -0
  87. package/dist/server.d.ts +4 -155
  88. package/dist/server.js +2 -2
  89. package/dist/{log-ldf5g8Cx.d.ts → store-DysUkTH3.d.ts} +120 -35
  90. package/dist/store-DysUkTH3.d.ts.map +1 -0
  91. package/dist/{log-yJbXUf72.js → store-N8PXxDAS.js} +3 -1
  92. package/dist/store-N8PXxDAS.js.map +1 -0
  93. package/dist/store-codec-DTG0Ftek.js +10 -0
  94. package/dist/store-codec-DTG0Ftek.js.map +1 -0
  95. package/dist/store-memory.d.ts +12 -0
  96. package/dist/store-memory.d.ts.map +1 -0
  97. package/dist/{log-memory.js → store-memory.js} +145 -34
  98. package/dist/store-memory.js.map +1 -0
  99. package/dist/{log-polling-DZ1MiKLg.js → store-polling-dSeLxzfb.js} +7 -5
  100. package/dist/store-polling-dSeLxzfb.js.map +1 -0
  101. package/dist/{log-postgres.d.ts → store-postgres.d.ts} +7 -6
  102. package/dist/store-postgres.d.ts.map +1 -0
  103. package/dist/{log-postgres.js → store-postgres.js} +214 -24
  104. package/dist/store-postgres.js.map +1 -0
  105. package/dist/{log-redis-core-CyJ5L8yR.js → store-redis-core-BFLwz0Wj.js} +271 -66
  106. package/dist/store-redis-core-BFLwz0Wj.js.map +1 -0
  107. package/dist/{log-redis-http.d.ts → store-redis-http.d.ts} +8 -7
  108. package/dist/store-redis-http.d.ts.map +1 -0
  109. package/dist/{log-redis-http.js → store-redis-http.js} +22 -12
  110. package/dist/store-redis-http.js.map +1 -0
  111. package/dist/{log-redis.d.ts → store-redis.d.ts} +7 -6
  112. package/dist/store-redis.d.ts.map +1 -0
  113. package/dist/{log-redis.js → store-redis.js} +101 -39
  114. package/dist/store-redis.js.map +1 -0
  115. package/dist/{log-sqlite.d.ts → store-sqlite.d.ts} +7 -6
  116. package/dist/store-sqlite.d.ts.map +1 -0
  117. package/dist/{log-sqlite.js → store-sqlite.js} +118 -22
  118. package/dist/store-sqlite.js.map +1 -0
  119. package/dist/{telemetry-Cso0qyHQ.d.ts → telemetry-BjYHTfh2.d.ts} +3 -2
  120. package/dist/telemetry-BjYHTfh2.d.ts.map +1 -0
  121. package/dist/testing.browser.d.ts +1 -0
  122. package/dist/testing.browser.js +6 -0
  123. package/dist/testing.browser.js.map +1 -0
  124. package/dist/testing.d.ts +32 -0
  125. package/dist/testing.d.ts.map +1 -0
  126. package/dist/testing.js +103 -0
  127. package/dist/testing.js.map +1 -0
  128. package/dist/validate-XKT4FSNn.js +2 -0
  129. package/dist/validate-XKT4FSNn.js.map +1 -0
  130. package/dist/wire-BFQmSJ-9.js +284 -0
  131. package/dist/wire-BFQmSJ-9.js.map +1 -0
  132. package/docs/01-quickstart.mdx +3 -3
  133. package/docs/concepts/01-contracts.mdx +18 -13
  134. package/docs/concepts/02-handlers.mdx +7 -7
  135. package/docs/concepts/03-durability.mdx +21 -21
  136. package/docs/concepts/04-state.mdx +18 -21
  137. package/docs/guides/01-timers.mdx +154 -49
  138. package/docs/guides/02-cancellation.mdx +30 -4
  139. package/docs/guides/03-react.mdx +76 -57
  140. package/docs/guides/04-local-first.mdx +1 -1
  141. package/docs/guides/05-production.mdx +310 -61
  142. package/docs/guides/06-ai-agents.mdx +252 -74
  143. package/docs/guides/07-devtools.mdx +137 -12
  144. package/docs/guides/08-application-data.mdx +1 -1
  145. package/docs/guides/09-presence.mdx +263 -0
  146. package/docs/guides/10-transports.mdx +140 -0
  147. package/docs/index.mdx +18 -14
  148. package/docs/reference/01-api.mdx +839 -110
  149. package/docs/reference/02-errors.mdx +13 -6
  150. package/package.json +24 -7
  151. package/src/ai-coordinator.ts +358 -0
  152. package/src/ai-projector.ts +524 -0
  153. package/src/ai-sdk-step.ts +261 -0
  154. package/src/ai-server.browser.ts +5 -0
  155. package/src/ai-server.ts +1719 -0
  156. package/src/ai.ts +2155 -0
  157. package/src/cache-indexeddb.ts +10 -0
  158. package/src/cli-bin.ts +5 -0
  159. package/src/cli.ts +1046 -0
  160. package/src/client.ts +1826 -0
  161. package/src/contract.ts +206 -0
  162. package/src/deterministic-id.ts +72 -0
  163. package/src/devtools-app.ts +989 -0
  164. package/src/devtools-server.browser.ts +5 -0
  165. package/src/devtools-server.ts +604 -0
  166. package/src/devtools.ts +716 -0
  167. package/src/errors.ts +50 -0
  168. package/src/http.ts +394 -0
  169. package/src/idempotent-replay.ts +53 -0
  170. package/src/index.ts +37 -0
  171. package/src/inspection.ts +39 -0
  172. package/src/internal.ts +426 -0
  173. package/src/otel.ts +59 -0
  174. package/src/platform.ts +60 -0
  175. package/src/push-envelope.ts +137 -0
  176. package/src/react.ts +284 -0
  177. package/src/reducer.ts +108 -0
  178. package/src/retryable-lazy.ts +27 -0
  179. package/src/scheduler-qstash.ts +915 -0
  180. package/src/scheduler-task.ts +106 -0
  181. package/src/scheduler-vercel.ts +437 -0
  182. package/src/server.browser.ts +12 -0
  183. package/src/server.ts +2700 -0
  184. package/src/session-socket.ts +548 -0
  185. package/src/sse.ts +141 -0
  186. package/src/standard-schema.ts +77 -0
  187. package/src/store-codec.ts +10 -0
  188. package/src/store-memory.ts +788 -0
  189. package/src/store-polling.ts +102 -0
  190. package/src/store-postgres.ts +1212 -0
  191. package/src/store-redis-core.ts +1494 -0
  192. package/src/store-redis-http.ts +116 -0
  193. package/src/store-redis.ts +458 -0
  194. package/src/store-sqlite.ts +1108 -0
  195. package/src/store.ts +385 -0
  196. package/src/telemetry.ts +47 -0
  197. package/src/testing.browser.ts +5 -0
  198. package/src/testing.ts +185 -0
  199. package/src/validate.ts +39 -0
  200. package/src/wire.ts +454 -0
  201. package/dist/internal-gCd5qMry.js +0 -44
  202. package/dist/log-memory.d.ts +0 -11
  203. package/dist/recovery-vercel.js +0 -119
  204. package/dist/server-BcLa4RFL.js +0 -877
  205. package/dist/wire-BVsgR8o9.js +0 -62
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","names":[],"sources":["../src/react.ts"],"mappings":";;;;KA8CY,qBAAqB,UAAU,WAAW;;EAEpD;;EAEA;;EAEA,cAAc;;EAEd;;EAEA,gBAAgB,cAAc;;;;;;EAM9B;EACA,WAAW;;KAGD,0BAA0B,UAAU,WAAW,KAAK,KAC9D,qBAAqB,GAAG;;;;;;KASd,mBAAmB,UAAU;;EAEvC,UAAU,YAAY;;;;;;;;EAQtB,cAAc,QAAQ,cAAc;;KAG1B,iBACV,UAAU,WACV,GACA,UAAU,eAAe,wBACvB,aAAa,GAAG,mBAAmB;;EAErC,OAAO;;EAEP,QAAQ,cAAc;;EAEtB;;;;;;EAMA,YAAY;;;;;;EAMZ,UAAU,QAAQ,YAAY,SAAS,WAAW;;;;;;EAMlD,cAAc,UAAU,uBAAuB,QAAQ,cAAc;;EAErE,SAAS;;KAGC,QACV,UAAU,WACV,GACA,UAAU,eAAe;EAEzB,kBAAkB,OAAO,qBAAqB,GAAG,OAAO;EACxD,kBAAkB,iBAAiB,GAAG,GAAG;;KAG/B,aACV,UAAU,WACV,GACA,UAAU,eAAe;EAEzB,kBAAkB,OAAO,0BAA0B,GAAG,OAAO;EAC7D,kBAAkB,iBAAiB,GAAG,GAAG;;iBAG3B,YACd,UAAU,WACV,GACA,UAAU,eAAe,sBACzB;EAAW,QAAQ,SAAS,GAAG,GAAG;IAAO,aAAa,GAAG,GAAG;iBAC9C,YACd,UAAU,WACV,GACA,UAAU,eAAe,sBACzB;EAAW,SAAS,QAAQ,GAAG,GAAG;IAAO,QAAQ,GAAG,GAAG"}
package/dist/react.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { createClient } from "./client.js";
2
+ import { t as createClient } from "./client-BKlyLiOU.js";
3
3
  import { createContext, createElement, useContext, useEffect, useMemo, useSyncExternalStore } from "react";
4
4
  //#region src/react.ts
5
5
  /**
@@ -17,13 +17,14 @@ import { createContext, createElement, useContext, useEffect, useMemo, useSyncEx
17
17
  function createReact(options) {
18
18
  const Context = createContext(null);
19
19
  const providerMounts = /* @__PURE__ */ new WeakMap();
20
- const resolveSession = "client" in options ? (sessionId, _api, initialState, initialIndex, initialEvents) => options.client.session(sessionId, {
20
+ const resolveSession = "client" in options ? (sessionId, _api, initialState, initialIndex, initialEvents, participant) => options.client.session(sessionId, {
21
21
  initialState,
22
22
  initialIndex,
23
- ...initialEvents === void 0 ? {} : { initialEvents }
23
+ ...initialEvents === void 0 ? {} : { initialEvents },
24
+ ...participant === void 0 ? {} : { participant }
24
25
  }) : (() => {
25
26
  const clients = /* @__PURE__ */ new Map();
26
- return (sessionId, api, initialState, initialIndex, initialEvents) => {
27
+ return (sessionId, api, initialState, initialIndex, initialEvents, participant) => {
27
28
  if (api === void 0) throw new TypeError("SessionProvider requires api when createReact binds a reducer");
28
29
  let client = clients.get(api);
29
30
  if (!client) {
@@ -36,19 +37,21 @@ function createReact(options) {
36
37
  return client.session(sessionId, {
37
38
  initialState,
38
39
  initialIndex,
39
- ...initialEvents === void 0 ? {} : { initialEvents }
40
+ ...initialEvents === void 0 ? {} : { initialEvents },
41
+ ...participant === void 0 ? {} : { participant }
40
42
  });
41
43
  };
42
44
  })();
43
45
  function SessionProvider(props) {
44
- const { sessionId, initialState, initialIndex, initialEvents } = props;
46
+ const { sessionId, initialState, initialIndex, initialEvents, participant } = props;
45
47
  const api = "api" in props ? props.api : void 0;
46
- const client = useMemo(() => resolveSession(sessionId, api, initialState, initialIndex, initialEvents), [
48
+ const client = useMemo(() => resolveSession(sessionId, api, initialState, initialIndex, initialEvents, participant), [
47
49
  sessionId,
48
50
  api,
49
51
  initialState,
50
52
  initialIndex,
51
- initialEvents
53
+ initialEvents,
54
+ participant
52
55
  ]);
53
56
  useEffect(() => {
54
57
  const mounts = providerMounts.get(client) ?? 0;
@@ -68,13 +71,23 @@ function createReact(options) {
68
71
  const client = useContext(Context);
69
72
  if (!client) throw new Error("useSession must be rendered inside its matching SessionProvider");
70
73
  const snapshot = useSyncExternalStore(client.subscribe, client.getSnapshot, client.getSnapshot);
71
- return useMemo(() => ({
72
- state: snapshot.state,
73
- events: snapshot.events,
74
- index: snapshot.index,
75
- connection: snapshot.connection,
76
- push: client.push
77
- }), [snapshot, client]);
74
+ return useMemo(() => {
75
+ const { setPresence } = client;
76
+ const { presence } = snapshot;
77
+ return {
78
+ state: snapshot.state,
79
+ events: snapshot.events,
80
+ index: snapshot.index,
81
+ connection: snapshot.connection,
82
+ push: client.push,
83
+ loadHistory: client.loadHistory,
84
+ history: snapshot.history,
85
+ ...setPresence && presence ? {
86
+ presence,
87
+ setPresence
88
+ } : {}
89
+ };
90
+ }, [snapshot, client]);
78
91
  }
79
92
  return {
80
93
  SessionProvider,
@@ -83,3 +96,5 @@ function createReact(options) {
83
96
  }
84
97
  //#endregion
85
98
  export { createReact };
99
+
100
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","names":[],"sources":["../src/react.ts"],"sourcesContent":["'use client'\n/**\n * experimental-a2/react — React bindings over experimental-a2/client.\n *\n * `createReact({ client })` is a factory (like createContext): call it\n * once in a `'use client'` module with a shared A2 client and export the\n * bound pair. Server components import `SessionProvider` from that module\n * as a client reference; client components import `useSession` from the\n * same file. The shared client also makes imperative pushes and provider\n * renders resolve the same live session. Everything is typed by the\n * reducer value — no type arguments, and nothing here ever touches the\n * machine module.\n */\n\nimport {\n createContext,\n createElement,\n useContext,\n useEffect,\n useMemo,\n useSyncExternalStore,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport {\n createClient,\n type A2Client,\n type Connection,\n type HistoryState,\n type LoadHistoryOptions,\n type PushResult,\n type SessionClient,\n type SessionClientPresence,\n type SessionSnapshot,\n} from './client.ts'\nimport type {\n AppendInput,\n ContractEvent,\n EventDefs,\n PresenceDefs,\n PresenceMap,\n PresencePatch,\n WithPresence,\n} from './contract.ts'\nimport type { Reducer } from './reducer.ts'\n\nexport type SessionProviderProps<D extends EventDefs, S> = {\n /** Which session to subscribe to. */\n sessionId: string\n /** Base path of the route exposing GET (stream) and POST (push). */\n api: string\n /** The server-rendered fold — the first paint, no client JS needed. */\n initialState: S\n /** The fold's frontier — the stream resumes exactly there. */\n initialIndex: number\n /** Server-rendered event history through `initialIndex`. */\n initialEvents?: ContractEvent<D>[]\n /**\n * This client's presence identity — required to call `setPresence`.\n * Caller-supplied (a user id, a tab nonce, a guest name): A2 does\n * not invent an identity story.\n */\n participant?: string\n children?: ReactNode\n}\n\nexport type BoundSessionProviderProps<D extends EventDefs, S> = Omit<\n SessionProviderProps<D, S>,\n 'api'\n>\n\n/**\n * The presence members of the hook result — intersected in via\n * `WithPresence`, so they exist exactly when the contract declares\n * presence fields (the reducer is the client's typed handle on it).\n */\nexport type UseSessionPresence<P extends PresenceDefs> = {\n /** The replicated presence map, this client included (local echo). */\n presence: PresenceMap<P>\n /**\n * Fire-and-forget: validated locally, echoed into the map\n * immediately, coalesced on the wire to a fixed cadence (a leading\n * send immediately, then at most one merged send per interval;\n * later values win per field), stamped with the frontier at send\n * time as `seen`. Requires the provider's `participant`.\n */\n setPresence: (values: PresencePatch<P>['values']) => void\n}\n\nexport type UseSessionResult<\n D extends EventDefs,\n S,\n P extends PresenceDefs = Record<never, never>,\n> = WithPresence<P, UseSessionPresence<P>> & {\n /** The live view, folded through the shared reducer. */\n state: S\n /** The raw event feed — observed, seeded, or backscrolled. */\n events: ContractEvent<D>[]\n /** The stream frontier — `lastSeenIndex` for cancellation. */\n index: number\n /**\n * The connection, as a discriminated union — `error` exists only\n * while disconnected; \"reconnecting…\" is\n * `status === 'connecting' && reconnects > 0`.\n */\n connection: Connection\n /**\n * Typed optimistic append. Awaiting it gives the server ack;\n * `.confirmed` resolves when the live stream has delivered the batch\n * back. Rejects with the server's A2Error codes.\n */\n push: (...events: AppendInput<D>[]) => PushResult<D>\n /**\n * Backscroll: fetch a bounded slice of older events into `events`.\n * Defaults page backward 50 at a time from the oldest loaded event.\n * Display data only — `state` and the optimistic overlay never move.\n */\n loadHistory: (options?: LoadHistoryOptions) => Promise<ContractEvent<D>[]>\n /** Backscroll progress: `complete` means the feed reaches index 1. */\n history: HistoryState\n}\n\nexport type A2React<\n D extends EventDefs,\n S,\n P extends PresenceDefs = Record<never, never>,\n> = {\n SessionProvider: (props: SessionProviderProps<D, S>) => ReactElement\n useSession: () => UseSessionResult<D, S, P>\n}\n\nexport type BoundA2React<\n D extends EventDefs,\n S,\n P extends PresenceDefs = Record<never, never>,\n> = {\n SessionProvider: (props: BoundSessionProviderProps<D, S>) => ReactElement\n useSession: () => UseSessionResult<D, S, P>\n}\n\nexport function createReact<\n D extends EventDefs,\n S,\n P extends PresenceDefs = Record<never, never>,\n>(options: { client: A2Client<D, S, P> }): BoundA2React<D, S, P>\nexport function createReact<\n D extends EventDefs,\n S,\n P extends PresenceDefs = Record<never, never>,\n>(options: { reducer: Reducer<D, S, P> }): A2React<D, S, P>\nexport function createReact<\n D extends EventDefs,\n S,\n P extends PresenceDefs = Record<never, never>,\n>(\n options: { client: A2Client<D, S, P> } | { reducer: Reducer<D, S, P> },\n): BoundA2React<D, S, P> | A2React<D, S, P> {\n const Context = createContext<SessionClient<D, S, P> | null>(null)\n const providerMounts = new WeakMap<SessionClient<D, S, P> & object, number>()\n const resolveSession: (\n sessionId: string,\n api: string | undefined,\n initialState: S,\n initialIndex: number,\n initialEvents: ContractEvent<D>[] | undefined,\n participant: string | undefined,\n ) => SessionClient<D, S, P> =\n 'client' in options\n ? (\n sessionId,\n _api,\n initialState,\n initialIndex,\n initialEvents,\n participant,\n ) =>\n options.client.session(sessionId, {\n initialState,\n initialIndex,\n ...(initialEvents === undefined ? {} : { initialEvents }),\n ...(participant === undefined ? {} : { participant }),\n })\n : (() => {\n const clients = new Map<string, A2Client<D, S, P>>()\n return (\n sessionId: string,\n api: string | undefined,\n initialState: S,\n initialIndex: number,\n initialEvents: ContractEvent<D>[] | undefined,\n participant: string | undefined,\n ) => {\n if (api === undefined) {\n throw new TypeError(\n 'SessionProvider requires api when createReact binds a reducer',\n )\n }\n let client = clients.get(api)\n if (!client) {\n client = createClient({ reducer: options.reducer, api })\n clients.set(api, client)\n }\n return client.session(sessionId, {\n initialState,\n initialIndex,\n ...(initialEvents === undefined ? {} : { initialEvents }),\n ...(participant === undefined ? {} : { participant }),\n })\n }\n })()\n\n function SessionProvider(\n props: SessionProviderProps<D, S> | BoundSessionProviderProps<D, S>,\n ): ReactElement {\n const {\n sessionId,\n initialState,\n initialIndex,\n initialEvents,\n participant,\n } = props\n const api = 'api' in props ? props.api : undefined\n const client = useMemo(\n () =>\n resolveSession(\n sessionId,\n api,\n initialState,\n initialIndex,\n initialEvents,\n participant,\n ),\n [sessionId, api, initialState, initialIndex, initialEvents, participant],\n )\n useEffect(() => {\n const mounts = providerMounts.get(client) ?? 0\n providerMounts.set(client, mounts + 1)\n if (mounts === 0) client.connect()\n return () => {\n const remaining = (providerMounts.get(client) ?? 1) - 1\n if (remaining === 0) {\n providerMounts.delete(client)\n client.close()\n } else {\n providerMounts.set(client, remaining)\n }\n }\n }, [client])\n return createElement(Context.Provider, { value: client }, props.children)\n }\n\n function useSession(): UseSessionResult<D, S, P> {\n const client = useContext(Context)\n if (!client) {\n throw new Error(\n 'useSession must be rendered inside its matching SessionProvider',\n )\n }\n const snapshot: SessionSnapshot<D, S, P> = useSyncExternalStore(\n client.subscribe,\n client.getSnapshot,\n client.getSnapshot,\n )\n return useMemo(() => {\n // Runtime mirror of the WithPresence surface: the client attaches\n // setPresence (and the snapshot carries presence) exactly when the\n // reducer declares presence fields — no runtime-inert members.\n const { setPresence } = client as Partial<SessionClientPresence<P>>\n const { presence } = snapshot as Partial<{ presence: PresenceMap<P> }>\n return {\n state: snapshot.state,\n events: snapshot.events,\n index: snapshot.index,\n connection: snapshot.connection,\n push: client.push,\n loadHistory: client.loadHistory,\n history: snapshot.history,\n ...(setPresence && presence ? { presence, setPresence } : {}),\n } as UseSessionResult<D, S, P>\n }, [snapshot, client])\n }\n\n return { SessionProvider, useSession }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAsJA,SAAgB,YAKd,SAC0C;CAC1C,MAAM,UAAU,cAA6C,IAAI;CACjE,MAAM,iCAAiB,IAAI,QAAiD;CAC5E,MAAM,iBAQJ,YAAY,WAEN,WACA,MACA,cACA,cACA,eACA,gBAEA,QAAQ,OAAO,QAAQ,WAAW;EAChC;EACA;EACA,GAAI,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc;EACvD,GAAI,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY;CACrD,CAAC,WACI;EACL,MAAM,0BAAU,IAAI,IAA+B;EACnD,QACE,WACA,KACA,cACA,cACA,eACA,gBACG;GACH,IAAI,QAAQ,KAAA,GACV,MAAM,IAAI,UACR,+DACF;GAEF,IAAI,SAAS,QAAQ,IAAI,GAAG;GAC5B,IAAI,CAAC,QAAQ;IACX,SAAS,aAAa;KAAE,SAAS,QAAQ;KAAS;IAAI,CAAC;IACvD,QAAQ,IAAI,KAAK,MAAM;GACzB;GACA,OAAO,OAAO,QAAQ,WAAW;IAC/B;IACA;IACA,GAAI,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc;IACvD,GAAI,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY;GACrD,CAAC;EACH;CACF,EAAA,CAAG;CAET,SAAS,gBACP,OACc;EACd,MAAM,EACJ,WACA,cACA,cACA,eACA,gBACE;EACJ,MAAM,MAAM,SAAS,QAAQ,MAAM,MAAM,KAAA;EACzC,MAAM,SAAS,cAEX,eACE,WACA,KACA,cACA,cACA,eACA,WACF,GACF;GAAC;GAAW;GAAK;GAAc;GAAc;GAAe;EAAW,CACzE;EACA,gBAAgB;GACd,MAAM,SAAS,eAAe,IAAI,MAAM,KAAK;GAC7C,eAAe,IAAI,QAAQ,SAAS,CAAC;GACrC,IAAI,WAAW,GAAG,OAAO,QAAQ;GACjC,aAAa;IACX,MAAM,aAAa,eAAe,IAAI,MAAM,KAAK,KAAK;IACtD,IAAI,cAAc,GAAG;KACnB,eAAe,OAAO,MAAM;KAC5B,OAAO,MAAM;IACf,OACE,eAAe,IAAI,QAAQ,SAAS;GAExC;EACF,GAAG,CAAC,MAAM,CAAC;EACX,OAAO,cAAc,QAAQ,UAAU,EAAE,OAAO,OAAO,GAAG,MAAM,QAAQ;CAC1E;CAEA,SAAS,aAAwC;EAC/C,MAAM,SAAS,WAAW,OAAO;EACjC,IAAI,CAAC,QACH,MAAM,IAAI,MACR,iEACF;EAEF,MAAM,WAAqC,qBACzC,OAAO,WACP,OAAO,aACP,OAAO,WACT;EACA,OAAO,cAAc;GAInB,MAAM,EAAE,gBAAgB;GACxB,MAAM,EAAE,aAAa;GACrB,OAAO;IACL,OAAO,SAAS;IAChB,QAAQ,SAAS;IACjB,OAAO,SAAS;IAChB,YAAY,SAAS;IACrB,MAAM,OAAO;IACb,aAAa,OAAO;IACpB,SAAS,SAAS;IAClB,GAAI,eAAe,WAAW;KAAE;KAAU;IAAY,IAAI,CAAC;GAC7D;EACF,GAAG,CAAC,UAAU,MAAM,CAAC;CACvB;CAEA,OAAO;EAAE;EAAiB;CAAW;AACvC"}
@@ -17,3 +17,5 @@ const retryableLazy = (initialize) => {
17
17
  };
18
18
  //#endregion
19
19
  export { retryableLazy as t };
20
+
21
+ //# sourceMappingURL=retryable-lazy-DZWmHpii.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryable-lazy-DZWmHpii.js","names":[],"sources":["../src/retryable-lazy.ts"],"sourcesContent":["/**\n * One lazy in-flight attempt: concurrent callers share it, fulfilled values\n * stay cached, and rejected attempts are evicted so a later call can retry.\n */\nexport type RetryableLazy<T> = {\n get(): Promise<T>\n peek(): Promise<T> | null\n}\n\nexport const retryableLazy = <T>(\n initialize: () => Promise<T>,\n): RetryableLazy<T> => {\n let current: Promise<T> | null = null\n\n const get = (): Promise<T> => {\n if (current) return current\n\n const attempt = Promise.resolve().then(initialize)\n current = attempt\n void attempt.catch(() => {\n if (current === attempt) current = null\n })\n return attempt\n }\n\n return { get, peek: () => current }\n}\n"],"mappings":";AASA,MAAa,iBACX,eACqB;CACrB,IAAI,UAA6B;CAEjC,MAAM,YAAwB;EAC5B,IAAI,SAAS,OAAO;EAEpB,MAAM,UAAU,QAAQ,QAAQ,CAAC,CAAC,KAAK,UAAU;EACjD,UAAU;EACV,QAAa,YAAY;GACvB,IAAI,YAAY,SAAS,UAAU;EACrC,CAAC;EACD,OAAO;CACT;CAEA,OAAO;EAAE;EAAK,YAAY;CAAQ;AACpC"}
@@ -0,0 +1,79 @@
1
+ import { i as Clock } from "./store-DysUkTH3.js";
2
+ import { D as SchedulerTask, t as A2Scheduler } from "./server-DUF9pjsx.js";
3
+ //#region src/scheduler-qstash.d.ts
4
+ type QStashStoreOutage = {
5
+ version: 1;
6
+ /** Zero is the first successor created for a store outage. */
7
+ generation: number;
8
+ /** The first failing drain task's due time. Append identity lives on the task. */
9
+ rootDueAt?: number;
10
+ };
11
+ type QStashMessage = SchedulerTask & {
12
+ /** Provider-private state authenticated as part of QStash's signed body. */
13
+ _a2QStash?: QStashStoreOutage;
14
+ };
15
+ type QStashPublishRequest = {
16
+ url: string;
17
+ body: QStashMessage;
18
+ /** Headers the transport must deliver to the callback. */
19
+ headers?: Readonly<Record<string, string>>;
20
+ /** Header names the transport must redact from provider dashboard/API views. */
21
+ redact?: {
22
+ header: readonly string[];
23
+ };
24
+ /** Whole-second Unix timestamp. Omitted for an immediate delivery. */
25
+ notBefore?: number;
26
+ deduplicationId: string;
27
+ /** Delivery retries after the initial attempt. */
28
+ retries?: number;
29
+ };
30
+ /** The request shape passed to an injected `@upstash/qstash` client. */
31
+ type QStashClientPublishRequest = Omit<QStashPublishRequest, "headers" | "redact"> & {
32
+ headers?: Record<string, string>;
33
+ redact?: {
34
+ header: string[];
35
+ };
36
+ };
37
+ /** The outbound part of `@upstash/qstash` used by the built-in transport. */
38
+ type QStashPublishingClient = {
39
+ publishJSON(request: QStashClientPublishRequest): Promise<unknown>;
40
+ };
41
+ type QStashVerifyRequest = {
42
+ signature: string;
43
+ /** The untouched request body covered by the signature. */
44
+ body: string;
45
+ /** Exact destination URL, checked against the signature subject. */
46
+ url: string;
47
+ upstashRegion?: string;
48
+ };
49
+ /** The small part of `@upstash/qstash` this adapter needs. */
50
+ type QStashTransport = {
51
+ publish(request: QStashPublishRequest): Promise<unknown>;
52
+ verify(request: QStashVerifyRequest): Promise<boolean>;
53
+ };
54
+ type QStashSchedulerOptions = {
55
+ /** Exact URL mounted with `schedulerHandler(...)`. Inferred in local dev and on Vercel. */
56
+ url?: string;
57
+ /** QStash API token. Default: `QSTASH_TOKEN`. */
58
+ token?: string;
59
+ /** QStash signing key. Default: `QSTASH_CURRENT_SIGNING_KEY`. */
60
+ currentSigningKey?: string;
61
+ /** Next QStash signing key. Default: `QSTASH_NEXT_SIGNING_KEY`. */
62
+ nextSigningKey?: string;
63
+ /** Delivery retries after the initial attempt. Default: provider default. */
64
+ retries?: number;
65
+ /** Maximum callback body and outbound task with outage headroom. Default 1 MiB. */
66
+ maxBodyBytes?: number;
67
+ /** Static callback headers. QStash receives them; A2 requests dashboard/API redaction. */
68
+ headers?: Readonly<Record<string, string>>;
69
+ /** Injectable publishing client. The built-in receiver still verifies callbacks. */
70
+ client?: QStashPublishingClient;
71
+ /** Injectable transport (tests). Default: `@upstash/qstash`. */
72
+ transport?: QStashTransport;
73
+ /** Injectable clock for due-time calculations (tests). */
74
+ clock?: Clock;
75
+ };
76
+ declare function qstash(options?: QStashSchedulerOptions): A2Scheduler;
77
+ //#endregion
78
+ export { QStashClientPublishRequest, QStashPublishRequest, QStashPublishingClient, QStashSchedulerOptions, QStashTransport, QStashVerifyRequest, qstash };
79
+ //# sourceMappingURL=scheduler-qstash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler-qstash.d.ts","names":[],"sources":["../src/scheduler-qstash.ts"],"mappings":";;;KAmCK;EACH;;EAEA;;EAEA;;KAGG,gBAAgB;;EAEnB,YAAY;;KAGF;EACV;EACA,MAAM;;EAEN,UAAU,SAAS;;EAEnB;IACE;;;EAGF;EACA;;EAEA;;;KAIU,6BAA6B,KACvC;EAGA,UAAU;EACV;IACE;;;;KAKQ;EACV,YAAY,SAAS,6BAA6B;;KAGxC;EACV;;EAEA;;EAEA;EACA;;;KAIU;EACV,QAAQ,SAAS,uBAAuB;EACxC,OAAO,SAAS,sBAAsB;;KAG5B;;EAEV;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,UAAU,SAAS;;EAEnB,SAAS;;EAET,YAAY;;EAEZ,QAAQ;;iBA4eM,OAAO,UAAS,yBAA8B"}