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
package/dist/http.d.ts CHANGED
@@ -1,37 +1,40 @@
1
- import { a as Event } from "./log-ldf5g8Cx.js";
2
- import { PushedEvent } from "./server.js";
3
- import { t as A2Error } from "./errors-xL_JTXsY.js";
4
- //#region src/http.d.ts
5
- /** The push envelope: what a client POSTs to append events. */
6
- type PushBody = {
7
- sessionId: string;
8
- /** Branded: `session.append` accepts these directly (the push route
9
- * path); schema validation still happens inside `append`. */
10
- events: PushedEvent[];
11
- };
1
+ import { a as EventDefs, o as PresenceDefs, r as ContractEvent } from "./contract-jIfaR085.js";
2
+ import { f as PushedEvent, i as DrainableServer, n as A2Server, p as PushedPresence } from "./server-DUF9pjsx.js";
3
+ import { t as A2Error } from "./errors-W6nwJ-fm.js";
4
+ //#region src/session-socket.d.ts
12
5
  /**
13
- * Validate the push envelope — `{ sessionId, events }` throwing
14
- * `INVALID_PAYLOAD` on a malformed body. Payload validation against the
15
- * machine's schemas happens in `append`, not here.
6
+ * The structural socket `sessionsSocket` speaks againstsatisfied
7
+ * by `ws` and by `@vercel/functions`' upgraded socket alike, so the
8
+ * platform upgrade API stays out of the library. `message` data
9
+ * arrives as whatever the platform delivers (string, Buffer,
10
+ * ArrayBuffer, or fragments); the handler normalizes defensively.
16
11
  */
17
- declare function parsePushBody(req: Request): Promise<PushBody>;
12
+ type A2Socket = {
13
+ send(data: string): void;
14
+ on(event: "message", listener: (data: unknown) => void): void;
15
+ on(event: "close", listener: () => void): void;
16
+ on(event: "error", listener: (error: unknown) => void): void;
17
+ close(code?: number, reason?: string): void;
18
+ /** Bytes queued but not yet transmitted — when exposed, the down
19
+ * pump uses it for backpressure (`SOCKET_TIMINGS`). */
20
+ bufferedAmount?: number;
21
+ };
22
+ //#endregion
23
+ //#region src/http.d.ts
18
24
  /**
19
- * Pipe a live event iterable into an SSE `Response`. Each event is one
20
- * frame `id:` carries the log index, `data:` the JSON event. A
21
- * disconnecting client cancels the stream, which closes the underlying
22
- * subscription. Two kinds of comment frames ride along: a `: connected`
23
- * prelude that flushes headers immediately, and a `: ping` heartbeat
24
- * every 15 seconds so clients (and proxies) can tell a quiet stream
25
- * from a dead connection — the session client's stall watchdog counts
26
- * on it.
25
+ * Create one scheduler callback route for servers sharing the same configured
26
+ * scheduler. Configuration mistakes throw immediately while the route module
27
+ * is evaluated, before a delivery can be acknowledged by the wrong adapter.
27
28
  */
28
- declare function sseResponse(iterable: AsyncIterable<Event>): Response;
29
+ declare function schedulerHandler(firstServer: DrainableServer, ...servers: DrainableServer[]): (req: Request) => Promise<Response>;
29
30
  /**
30
31
  * Serialize an error into the documented wire shape,
31
32
  * `{ error: { code, message, details } }`, with the mapped status
32
- * (400 for caller bugs, 503 for LOG_UNAVAILABLE). Non-A2Errors become a
33
- * 503 LOG_UNAVAILABLE — from the client's perspective an unknown server
34
- * failure is retryable-once, not a protocol contract.
33
+ * (400 for caller bugs, 503 for STORE_UNAVAILABLE). Non-A2Errors become a
34
+ * 503 STORE_UNAVAILABLE — from the client's perspective an unknown server
35
+ * failure is retryable-once, not a protocol contract. The natural
36
+ * return value of a `before` hook that wants the wire's own error
37
+ * shapes.
35
38
  */
36
39
  declare function errorResponse(error: unknown): Response;
37
40
  /**
@@ -40,5 +43,109 @@ declare function errorResponse(error: unknown): Response;
40
43
  * sides branch on identical codes.
41
44
  */
42
45
  declare function deserializeError(body: unknown): A2Error | null;
46
+ /**
47
+ * What a request (or socket frame) asks of a session, parsed — the
48
+ * argument policy hooks branch on. `stream` covers the SSE GET and the
49
+ * socket's subscribe frames; `push` covers the HTTP POST and the
50
+ * socket's push frames; `history` is the bounded cold read the
51
+ * client's `loadHistory` rides; `ws-upgrade` is the upgrade GET before
52
+ * any frame flows.
53
+ */
54
+ type A2Intent<D extends EventDefs = EventDefs> = {
55
+ type: "ws-upgrade";
56
+ } | {
57
+ type: "stream";
58
+ sessionId: string;
59
+ startAfter: number;
60
+ transport: "sse" | "ws";
61
+ } | {
62
+ type: "history";
63
+ sessionId: string;
64
+ gte: number;
65
+ lte: number;
66
+ } | {
67
+ type: "push";
68
+ sessionId: string;
69
+ /** Parsed and branded, payloads not yet validated — `type`
70
+ * autocompletes the contract's names but is any string off the
71
+ * wire; `append` rejects unknown types after the hooks run. */
72
+ events: Array<PushedEvent & {
73
+ type: SuggestedEventType<D>;
74
+ }>;
75
+ presence?: PushedPresence;
76
+ transport: "http" | "ws";
77
+ };
78
+ /** The contract's event names for editor completion, without excluding
79
+ * the wire's reality (any string can arrive; validation is later). */
80
+ type SuggestedEventType<D extends EventDefs> = (keyof D & string) | (string & Record<never, never>);
81
+ /** What the library did with an allowed intent — `after`'s view.
82
+ * `covered` = the closed range is fully present (an immutable slice of
83
+ * the append-only log), the one caching-relevant fact the library
84
+ * owns; policy over it belongs to the app's `after`. */
85
+ type A2Outcome<D extends EventDefs = EventDefs> = {
86
+ type: "stream";
87
+ } | {
88
+ type: "history";
89
+ covered: boolean;
90
+ events: ContractEvent<D>[];
91
+ } | {
92
+ type: "push";
93
+ appended: ContractEvent<D>[];
94
+ };
95
+ /**
96
+ * The platform's socket-upgrade seam: given the attach callback, return
97
+ * the 101 response. On Vercel:
98
+ * `upgrade: (attach) => experimental_upgradeWebSocket(attach)`.
99
+ */
100
+ type UpgradeFn = (attach: (socket: A2Socket) => void) => Response | Promise<Response>;
101
+ /** One bag: the policy hooks and the capability options — the names
102
+ * distinguish them, so `handle(server, { presence: true })` and
103
+ * `handle(server, { before, upgrade })` both read naturally. */
104
+ type HandleOptions<D extends EventDefs = EventDefs> = {
105
+ /** Return a Response to deny; thrown errors are treated as
106
+ * infrastructure failures and answer with the retryable wire shape. */
107
+ before?(args: {
108
+ request: Request;
109
+ intent: A2Intent<D>;
110
+ }): Response | undefined | void | Promise<Response | undefined | void>;
111
+ after?(args: {
112
+ request: Request;
113
+ intent: A2Intent<D>;
114
+ outcome: A2Outcome<D>;
115
+ response: Response;
116
+ }): Response | undefined | void | Promise<Response | undefined | void>;
117
+ upgrade?: UpgradeFn;
118
+ presence?: boolean;
119
+ deadline?: number;
120
+ };
121
+ /**
122
+ * The session route pair as one call: `export const { GET, POST } =
123
+ * handle(server, options?)` serves the live stream (SSE GET, resumed
124
+ * at `index`), the history slice (GET with `gte`/`lte`), the push
125
+ * envelope (POST), and — with `options.upgrade` — the multiplexed
126
+ * WebSocket, all through one pair of policy hooks.
127
+ *
128
+ * Parsing is protocol, hooks are policy: a request that fails to parse
129
+ * (missing sessionId, malformed bounds, bad push envelope) answers
130
+ * INVALID_PAYLOAD on the wire before any hook runs. `before` sees
131
+ * every parsed intent — HTTP requests and socket frames alike, with
132
+ * `request` always the original (for socket frames: upgrade) Request —
133
+ * and short-circuits by returning a Response: over HTTP it is the
134
+ * response verbatim; over the socket it is translated to the wire's
135
+ * own vocabulary (subscribe → `unsubscribed { reason: 'subscribe
136
+ * rejected' }`, push → an INVALID_PAYLOAD error ack), because a
137
+ * Response body cannot cross a socket. `after` runs only where the
138
+ * library produced an HTTP response — never after a short-circuit,
139
+ * never for socket frames — and may mutate `response.headers` in place
140
+ * or return a replacement (history caching policy lives here, on
141
+ * `outcome.covered`). `options.deadline` (epoch ms) closes sockets
142
+ * cleanly ahead of a known platform deadline, so clients reconnect on
143
+ * our schedule.
144
+ */
145
+ declare function handle<D extends EventDefs, P extends PresenceDefs = Record<never, never>>(server: A2Server<D, P>, options?: HandleOptions<D>): {
146
+ GET(req: Request): Promise<Response>;
147
+ POST(req: Request): Promise<Response>;
148
+ };
43
149
  //#endregion
44
- export { PushBody, deserializeError, errorResponse, parsePushBody, sseResponse };
150
+ export { A2Intent, A2Outcome, type A2Socket, HandleOptions, UpgradeFn, deserializeError, errorResponse, handle, schedulerHandler };
151
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","names":[],"sources":["../src/session-socket.ts","../src/http.ts"],"mappings":";;;;;;;;;;;KAkCY;EACV,KAAK;EACL,GAAG,kBAAkB,WAAW;EAChC,GAAG,gBAAgB;EACnB,GAAG,gBAAgB,WAAW;EAC9B,MAAM,eAAe;;;EAGrB;;;;;;;;;iBCUc,iBACd,aAAa,oBACV,SAAS,qBACV,KAAK,YAAY,QAAQ;;;;;;;;;;iBAoBb,cAAc,iBAAiB;;;;;;iBAY/B,iBAAiB,gBAAgB;;;;;;;;;KAcrC,SAAS,UAAU,YAAY;EACrC;;EAEA;EACA;EACA;EACA;;EAEA;EAAiB;EAAmB;EAAa;;EAEjD;EACA;;;;EAIA,QAAQ,MAAM;IAAgB,MAAM,mBAAmB;;EACvD,WAAW;EACX;;;;KAKD,mBAAmB,UAAU,oBACzB,wBAAwB;;;;;KAMrB,UAAU,UAAU,YAAY;EACtC;;EACA;EAAiB;EAAkB,QAAQ,cAAc;;EACzD;EAAc,UAAU,cAAc;;;;;;;KAOhC,aACV,SAAS,QAAQ,sBACd,WAAW,QAAQ;;;;KA6CZ,cAAc,UAAU,YAAY;;;EAG9C,QAAQ;IACN,SAAS;IACT,QAAQ,SAAS;MACf,8BAA8B,QAAQ;EAC1C,OAAO;IACL,SAAS;IACT,QAAQ,SAAS;IACjB,SAAS,UAAU;IACnB,UAAU;MACR,8BAA8B,QAAQ;EAC1C,UAAU;EACV;EACA;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2Bc,OACd,UAAU,WACV,UAAU,eAAe,sBAEzB,QAAQ,SAAS,GAAG,IACpB,UAAU,cAAc;EAExB,IAAI,KAAK,UAAU,QAAQ;EAC3B,KAAK,KAAK,UAAU,QAAQ"}