experimental-a2 0.0.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 +128 -0
- package/dist/ai-server.browser.d.ts +1 -0
- package/dist/ai-server.browser.js +4 -0
- package/dist/ai-server.d.ts +65 -0
- package/dist/ai-server.js +494 -0
- package/dist/ai.d.ts +282 -0
- package/dist/ai.js +922 -0
- package/dist/cache-indexeddb.d.ts +1 -0
- package/dist/cache-indexeddb.js +0 -0
- package/dist/client.d.ts +90 -0
- package/dist/client.js +410 -0
- package/dist/contract-B0kAXoaL.js +60 -0
- package/dist/contract-DL8btVd9.d.ts +161 -0
- package/dist/devtools-server.browser.d.ts +1 -0
- package/dist/devtools-server.browser.js +4 -0
- package/dist/devtools-server.d.ts +22 -0
- package/dist/devtools-server.js +1087 -0
- package/dist/errors-BJRMd-h6.js +23 -0
- package/dist/errors-xL_JTXsY.d.ts +20 -0
- package/dist/http.d.ts +44 -0
- package/dist/http.js +119 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -0
- package/dist/inspection-E7qbD0Xj.js +10 -0
- package/dist/internal-Dm8Ejnud.js +36 -0
- package/dist/log-Dg1I8NRr.d.ts +245 -0
- package/dist/log-memory.d.ts +11 -0
- package/dist/log-memory.js +345 -0
- package/dist/log-polling-RO7kclzR.js +83 -0
- package/dist/log-postgres.d.ts +40 -0
- package/dist/log-postgres.js +628 -0
- package/dist/log-redis.d.ts +31 -0
- package/dist/log-redis.js +711 -0
- package/dist/log-sqlite.d.ts +17 -0
- package/dist/log-sqlite.js +450 -0
- package/dist/log-yJbXUf72.js +5 -0
- package/dist/otel.d.ts +12 -0
- package/dist/otel.js +41 -0
- package/dist/react.d.ts +54 -0
- package/dist/react.js +85 -0
- package/dist/recovery-vercel.d.ts +60 -0
- package/dist/recovery-vercel.js +120 -0
- package/dist/retryable-lazy-DZWmHpii.js +19 -0
- package/dist/server-DYsnKTTy.js +780 -0
- package/dist/server.browser.d.ts +1 -0
- package/dist/server.browser.js +11 -0
- package/dist/server.d.ts +136 -0
- package/dist/server.js +2 -0
- package/dist/telemetry-C78al20p.d.ts +32 -0
- package/dist/validate-XKT4FSNn.js +28 -0
- package/dist/wire-2QpU1EtJ.js +62 -0
- package/docs/01-quickstart.mdx +214 -0
- package/docs/concepts/01-contracts.mdx +138 -0
- package/docs/concepts/02-handlers.mdx +146 -0
- package/docs/concepts/03-durability.mdx +230 -0
- package/docs/concepts/04-state.mdx +133 -0
- package/docs/guides/01-timers.mdx +85 -0
- package/docs/guides/02-cancellation.mdx +107 -0
- package/docs/guides/03-react.mdx +234 -0
- package/docs/guides/04-local-first.mdx +88 -0
- package/docs/guides/05-production.mdx +179 -0
- package/docs/guides/06-ai-agents.mdx +659 -0
- package/docs/guides/07-devtools.mdx +101 -0
- package/docs/guides/08-application-data.mdx +114 -0
- package/docs/index.mdx +282 -0
- package/docs/reference/01-api.mdx +637 -0
- package/docs/reference/02-errors.mdx +77 -0
- package/package.json +111 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Errors
|
|
3
|
+
description: One error class, five codes, and clear rules about what append will never throw for.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## `A2Error`
|
|
7
|
+
|
|
8
|
+
Everything A2 throws is an `A2Error`, a single class discriminated by
|
|
9
|
+
`code`, not a subclass hierarchy. One class serializes cleanly across the
|
|
10
|
+
push-route boundary and keeps `instanceof` working after bundling.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
// e.g. in a route handler:
|
|
14
|
+
import { A2Error } from 'experimental-a2'
|
|
15
|
+
|
|
16
|
+
export async function POST(req: Request) {
|
|
17
|
+
const { orderId, payload } = await req.json()
|
|
18
|
+
try {
|
|
19
|
+
const events = await ordersServer
|
|
20
|
+
.session(orderId)
|
|
21
|
+
.append({ type: 'created', payload })
|
|
22
|
+
return Response.json(events)
|
|
23
|
+
} catch (err) {
|
|
24
|
+
if (err instanceof A2Error && err.code === 'INVALID_PAYLOAD') {
|
|
25
|
+
// err.details carries the schema issues, in Standard Schema format
|
|
26
|
+
return Response.json({ issues: err.details }, { status: 400 })
|
|
27
|
+
}
|
|
28
|
+
throw err
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## The codes
|
|
34
|
+
|
|
35
|
+
| Code | Thrown when | Retryable |
|
|
36
|
+
| ------------------------- | ------------------------------------------------------------------ | --------- |
|
|
37
|
+
| `INVALID_PAYLOAD` | a payload fails its schema; nothing was written, and `details` carries the issues ([Standard Schema](https://standardschema.dev) format) | no |
|
|
38
|
+
| `UNKNOWN_EVENT_TYPE` | an event type isn't in the contract's `events` map | no |
|
|
39
|
+
| `PARTIAL_DUPLICATE_BATCH` | a batch mixed already-appended and fresh events | no |
|
|
40
|
+
| `LOG_UNAVAILABLE` | the log backend failed; nothing was written, original error as `cause` | **yes** |
|
|
41
|
+
| `LOG_NOT_CONFIGURED` | production boot with no `log` configured (during `next build` page collection, deferred to first use) | no |
|
|
42
|
+
|
|
43
|
+
Retryability is derivable from the code. `LOG_UNAVAILABLE` is the only one
|
|
44
|
+
worth retrying; the rest are deterministic caller bugs, and retrying them
|
|
45
|
+
is wasted work.
|
|
46
|
+
|
|
47
|
+
On `PARTIAL_DUPLICATE_BATCH`: retrying an *identical* batch is not an
|
|
48
|
+
error. It's an idempotent success, and you get the previously appended
|
|
49
|
+
events back. Mixing already-sent events with fresh ones in a single batch
|
|
50
|
+
is always a caller bug, so A2 refuses it rather than quietly reinterpret
|
|
51
|
+
what "atomic" meant. The same code covers two adjacent bugs: a batch that
|
|
52
|
+
contains the same id twice, and an id that was already used in a
|
|
53
|
+
*different* session (event ids are globally unique). In every case,
|
|
54
|
+
nothing is written.
|
|
55
|
+
|
|
56
|
+
## What append never throws for
|
|
57
|
+
|
|
58
|
+
- **A failing handler.** Appends always land; handler failures are retried
|
|
59
|
+
and, if persistent, [dead-letter the event](/concepts/durability#when-a-handler-keeps-failing).
|
|
60
|
+
`append` never fails because a downstream handler is failing.
|
|
61
|
+
- **A duplicate of an identical batch.** That's a lost ack, not a bug.
|
|
62
|
+
|
|
63
|
+
## Over the wire
|
|
64
|
+
|
|
65
|
+
The push route serializes an `A2Error` as:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{ "error": { "code": "INVALID_PAYLOAD", "message": "...", "details": [] } }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
with a mapped status: `INVALID_PAYLOAD`, `UNKNOWN_EVENT_TYPE`, and
|
|
72
|
+
`PARTIAL_DUPLICATE_BATCH` are 400; `LOG_UNAVAILABLE` is 503.
|
|
73
|
+
|
|
74
|
+
The client's `push` deserializes the body back into an `A2Error`, so client
|
|
75
|
+
and server code branch on identical codes. `push` auto-retries only
|
|
76
|
+
`LOG_UNAVAILABLE`. The serializer pair ships in `experimental-a2/http`, alongside
|
|
77
|
+
`parsePushBody` and `sseResponse`.
|
package/package.json
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "experimental-a2",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Durable sync and reactions for things with a lifecycle: one event log, derived state, and live client per session.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=22.13"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/vercel-labs/a2.git",
|
|
14
|
+
"directory": "packages/a2"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public",
|
|
18
|
+
"registry": "https://registry.npmjs.org/"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"docs",
|
|
23
|
+
"CHANGELOG.md"
|
|
24
|
+
],
|
|
25
|
+
"exports": {
|
|
26
|
+
".": "./dist/index.js",
|
|
27
|
+
"./server": {
|
|
28
|
+
"browser": "./dist/server.browser.js",
|
|
29
|
+
"default": "./dist/server.js"
|
|
30
|
+
},
|
|
31
|
+
"./client": "./dist/client.js",
|
|
32
|
+
"./react": "./dist/react.js",
|
|
33
|
+
"./ai": "./dist/ai.js",
|
|
34
|
+
"./ai/server": {
|
|
35
|
+
"browser": "./dist/ai-server.browser.js",
|
|
36
|
+
"default": "./dist/ai-server.js"
|
|
37
|
+
},
|
|
38
|
+
"./http": "./dist/http.js",
|
|
39
|
+
"./log-memory": "./dist/log-memory.js",
|
|
40
|
+
"./log-sqlite": "./dist/log-sqlite.js",
|
|
41
|
+
"./log-postgres": "./dist/log-postgres.js",
|
|
42
|
+
"./log-redis": "./dist/log-redis.js",
|
|
43
|
+
"./recovery-vercel": "./dist/recovery-vercel.js",
|
|
44
|
+
"./cache-indexeddb": "./dist/cache-indexeddb.js",
|
|
45
|
+
"./otel": "./dist/otel.js",
|
|
46
|
+
"./devtools/server": {
|
|
47
|
+
"browser": "./dist/devtools-server.browser.js",
|
|
48
|
+
"default": "./dist/devtools-server.js"
|
|
49
|
+
},
|
|
50
|
+
"./package.json": "./package.json"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsdown",
|
|
54
|
+
"dev": "tsdown --watch",
|
|
55
|
+
"typecheck": "tsc --noEmit",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"test:watch": "vitest"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@opentelemetry/api": "^1.9.0",
|
|
61
|
+
"@vercel/queue": "*",
|
|
62
|
+
"ai": "^7.0.0",
|
|
63
|
+
"ioredis": "^5.4.0",
|
|
64
|
+
"pg": "^8.11.0",
|
|
65
|
+
"react": "^19.0.0"
|
|
66
|
+
},
|
|
67
|
+
"peerDependenciesMeta": {
|
|
68
|
+
"@opentelemetry/api": {
|
|
69
|
+
"optional": true
|
|
70
|
+
},
|
|
71
|
+
"@vercel/queue": {
|
|
72
|
+
"optional": true
|
|
73
|
+
},
|
|
74
|
+
"ai": {
|
|
75
|
+
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"ioredis": {
|
|
78
|
+
"optional": true
|
|
79
|
+
},
|
|
80
|
+
"pg": {
|
|
81
|
+
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"react": {
|
|
84
|
+
"optional": true
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"devDependencies": {
|
|
88
|
+
"@electric-sql/pglite": "catalog:",
|
|
89
|
+
"ai": "catalog:",
|
|
90
|
+
"ioredis": "catalog:",
|
|
91
|
+
"@opentelemetry/api": "catalog:",
|
|
92
|
+
"@types/pg": "catalog:",
|
|
93
|
+
"@vercel/queue": "catalog:",
|
|
94
|
+
"pg": "catalog:",
|
|
95
|
+
"@testing-library/react": "catalog:",
|
|
96
|
+
"@types/react": "catalog:",
|
|
97
|
+
"esbuild": "catalog:",
|
|
98
|
+
"@types/react-dom": "catalog:",
|
|
99
|
+
"jsdom": "catalog:",
|
|
100
|
+
"react": "catalog:",
|
|
101
|
+
"react-dom": "catalog:",
|
|
102
|
+
"@opentelemetry/context-async-hooks": "catalog:",
|
|
103
|
+
"@opentelemetry/sdk-trace-base": "catalog:",
|
|
104
|
+
"@types/node": "catalog:",
|
|
105
|
+
"publint": "catalog:",
|
|
106
|
+
"tsdown": "catalog:",
|
|
107
|
+
"typescript": "catalog:",
|
|
108
|
+
"vitest": "catalog:",
|
|
109
|
+
"zod": "catalog:"
|
|
110
|
+
}
|
|
111
|
+
}
|