experimental-a2 0.2.0 → 0.4.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 +169 -0
- package/dist/ai-B4YhEnfw.d.ts +333 -0
- package/dist/ai-server.d.ts +48 -9
- package/dist/ai-server.js +121 -49
- package/dist/ai.d.ts +2 -303
- package/dist/ai.js +231 -86
- package/dist/cli-B3VuxoDe.js +597 -0
- package/dist/cli-bin.d.ts +1 -0
- package/dist/cli-bin.js +5 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.js +2 -0
- package/dist/client-BrfDXQ8A.d.ts +155 -0
- package/dist/client-Bt4tAKi9.js +798 -0
- package/dist/client.d.ts +2 -90
- package/dist/client.js +1 -409
- package/dist/{contract-CG_adnu_.js → contract-48bUMgcL.js} +10 -2
- package/dist/{contract-C_3dIIEU.d.ts → contract-jIfaR085.d.ts} +62 -8
- package/dist/devtools-J_jZ2vQf.d.ts +151 -0
- package/dist/devtools-kJJaORn-.js +338 -0
- package/dist/devtools-server.browser.js +1 -1
- package/dist/devtools-server.d.ts +2 -2
- package/dist/devtools-server.js +224 -43
- package/dist/devtools.d.ts +2 -0
- package/dist/devtools.js +2 -0
- package/dist/{errors-BJRMd-h6.js → errors-BQuJpe82.js} +4 -4
- package/dist/{errors-xL_JTXsY.d.ts → errors-W6nwJ-fm.d.ts} +1 -1
- package/dist/http.d.ts +71 -13
- package/dist/http.js +302 -41
- package/dist/{idempotent-replay-BMyHrP0L.js → idempotent-replay-DuqEkYA7.js} +2 -2
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/{inspection-E7qbD0Xj.js → inspection-DaxB5jM2.js} +2 -1
- package/dist/internal-aEotMzu_.js +209 -0
- package/dist/otel.d.ts +1 -1
- package/dist/platform-B4TnJtWu.js +32 -0
- package/dist/react.d.ts +37 -14
- package/dist/react.js +26 -15
- package/dist/scheduler-qstash.d.ts +78 -0
- package/dist/scheduler-qstash.js +499 -0
- package/dist/scheduler-task-BpzhPnRS.js +54 -0
- package/dist/{recovery-vercel.d.ts → scheduler-vercel.d.ts} +17 -24
- package/dist/scheduler-vercel.js +226 -0
- package/dist/server-CcNnFnoW.js +1405 -0
- package/dist/server-YtPq7hjw.d.ts +260 -0
- package/dist/server.d.ts +4 -155
- package/dist/server.js +2 -2
- package/dist/{log-ldf5g8Cx.d.ts → store-C3sNAaBT.d.ts} +111 -35
- package/dist/{log-yJbXUf72.js → store-N8PXxDAS.js} +1 -1
- package/dist/store-codec-DTG0Ftek.js +8 -0
- package/dist/store-memory.d.ts +11 -0
- package/dist/{log-memory.js → store-memory.js} +127 -24
- package/dist/{log-polling-6COoN60V.js → store-polling-DgrrAE3d.js} +7 -6
- package/dist/{log-postgres.d.ts → store-postgres.d.ts} +6 -6
- package/dist/{log-postgres.js → store-postgres.js} +158 -24
- package/dist/{log-redis.js → store-redis-core-DWqx3F47.js} +294 -156
- package/dist/store-redis-http.d.ts +21 -0
- package/dist/store-redis-http.js +70 -0
- package/dist/store-redis.d.ts +37 -0
- package/dist/store-redis.js +298 -0
- package/dist/{log-sqlite.d.ts → store-sqlite.d.ts} +6 -6
- package/dist/{log-sqlite.js → store-sqlite.js} +116 -22
- package/dist/{telemetry-Cso0qyHQ.d.ts → telemetry-BjYHTfh2.d.ts} +1 -1
- package/dist/testing.browser.d.ts +1 -0
- package/dist/testing.browser.js +4 -0
- package/dist/testing.d.ts +31 -0
- package/dist/testing.js +101 -0
- package/dist/wire-DCUZBUlT.js +222 -0
- package/docs/01-quickstart.mdx +4 -5
- package/docs/concepts/01-contracts.mdx +21 -17
- package/docs/concepts/02-handlers.mdx +7 -7
- package/docs/concepts/03-durability.mdx +26 -29
- package/docs/concepts/04-state.mdx +18 -21
- package/docs/guides/01-timers.mdx +154 -54
- package/docs/guides/02-cancellation.mdx +30 -4
- package/docs/guides/03-react.mdx +20 -21
- package/docs/guides/04-local-first.mdx +1 -1
- package/docs/guides/05-production.mdx +321 -60
- package/docs/guides/06-ai-agents.mdx +249 -49
- package/docs/guides/07-devtools.mdx +137 -12
- package/docs/guides/08-application-data.mdx +1 -1
- package/docs/guides/09-presence.mdx +284 -0
- package/docs/guides/10-transports.mdx +131 -0
- package/docs/index.mdx +22 -46
- package/docs/reference/01-api.mdx +751 -102
- package/docs/reference/02-errors.mdx +10 -5
- package/package.json +23 -6
- package/dist/internal-D6wNxTck.js +0 -36
- package/dist/log-memory.d.ts +0 -11
- package/dist/log-redis.d.ts +0 -31
- package/dist/recovery-vercel.js +0 -119
- package/dist/server-DJgD2YWP.js +0 -877
- package/dist/wire-BVsgR8o9.js +0 -62
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { a as EventDefs, c as PresencePatch, d as WithPresence, l as PresenceSnapshot, n as Contract, o as PresenceDefs, p as Reducer, r as ContractEvent, s as PresenceMap, t as AppendInput } from "./contract-jIfaR085.js";
|
|
2
|
+
import { t as A2Store } from "./store-C3sNAaBT.js";
|
|
3
|
+
import { i as A2Telemetry } from "./telemetry-BjYHTfh2.js";
|
|
4
|
+
//#region src/scheduler-task.d.ts
|
|
5
|
+
/** One event carried by a delayed append task. */
|
|
6
|
+
type ScheduledEvent = {
|
|
7
|
+
id: string;
|
|
8
|
+
type: string;
|
|
9
|
+
payload: unknown;
|
|
10
|
+
};
|
|
11
|
+
/** A durable wake-up for pending handler work. */
|
|
12
|
+
type SchedulerDrainTask = {
|
|
13
|
+
version: 1;
|
|
14
|
+
kind: "drain";
|
|
15
|
+
contract: string;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
/** Earliest useful delivery as epoch milliseconds. */
|
|
18
|
+
dueAt: number;
|
|
19
|
+
};
|
|
20
|
+
/** A durable delayed append. */
|
|
21
|
+
type SchedulerAppendTask = {
|
|
22
|
+
version: 1;
|
|
23
|
+
kind: "append";
|
|
24
|
+
/** Stable identity for provider-level deduplication. */
|
|
25
|
+
id: string;
|
|
26
|
+
contract: string;
|
|
27
|
+
sessionId: string;
|
|
28
|
+
/** Earliest useful delivery as epoch milliseconds. */
|
|
29
|
+
dueAt: number;
|
|
30
|
+
events: readonly ScheduledEvent[];
|
|
31
|
+
};
|
|
32
|
+
/** The versioned message protocol shared by scheduler adapters. */
|
|
33
|
+
type SchedulerTask = SchedulerDrainTask | SchedulerAppendTask;
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/server.d.ts
|
|
36
|
+
/**
|
|
37
|
+
* Events that arrived over the wire through `parsePushBody` — already
|
|
38
|
+
* envelope-validated, headed for schema validation inside `append`.
|
|
39
|
+
* The brand lets the documented push route hand them straight to
|
|
40
|
+
* `session.append` without weakening typed appends for app code: a
|
|
41
|
+
* hand-written `{ type: string }` literal still fails to compile.
|
|
42
|
+
*/
|
|
43
|
+
type PushedEvent = {
|
|
44
|
+
type: string;
|
|
45
|
+
payload: unknown;
|
|
46
|
+
id?: string;
|
|
47
|
+
readonly "~a2.pushed": true;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* A presence patch that arrived over the wire through `parsePushBody`
|
|
51
|
+
* — same provenance brand as `PushedEvent`, so the documented route
|
|
52
|
+
* hands it whole to `session.setPresence` while a hand-written
|
|
53
|
+
* untyped patch still fails to compile. Field validation happens
|
|
54
|
+
* inside `setPresence`.
|
|
55
|
+
*/
|
|
56
|
+
type PushedPresence = {
|
|
57
|
+
participant: string;
|
|
58
|
+
values: Record<string, unknown>;
|
|
59
|
+
seen?: number;
|
|
60
|
+
/** The sender's LWW stamp in epoch ms; receipt time when absent. */
|
|
61
|
+
at?: number;
|
|
62
|
+
readonly "~a2.pushed": true;
|
|
63
|
+
};
|
|
64
|
+
type PushValidationContext = {
|
|
65
|
+
sessionId: string;
|
|
66
|
+
events: readonly PushedEvent[];
|
|
67
|
+
/** The whole pushed patch — present exactly on the presence-plane
|
|
68
|
+
* invocation, so the callback authorizes the participant id and can
|
|
69
|
+
* apply size or cardinality policy. */
|
|
70
|
+
presence?: PushedPresence;
|
|
71
|
+
};
|
|
72
|
+
/** What every handler receives. */
|
|
73
|
+
type HandlerContext<D extends EventDefs, K extends keyof D & string = keyof D & string, P extends PresenceDefs = Record<never, never>> = {
|
|
74
|
+
/** The triggering event. */
|
|
75
|
+
event: ContractEvent<D, K>;
|
|
76
|
+
/** Durable, 1-based dispatch ordinal for this event. */
|
|
77
|
+
attempt: number;
|
|
78
|
+
/** This session, with handler-scoped idempotent append. */
|
|
79
|
+
session: Session<D, HandlerAppend<D>, P>;
|
|
80
|
+
/** Fires on `abortOn` events (cancellation slice); dormant otherwise. */
|
|
81
|
+
signal: AbortSignal;
|
|
82
|
+
};
|
|
83
|
+
type Handler<D extends EventDefs, K extends keyof D & string = keyof D & string, P extends PresenceDefs = Record<never, never>> = (ctx: HandlerContext<D, K, P>) => Promise<void | AppendInput<D> | readonly AppendInput<D>[]>;
|
|
84
|
+
type LaneContext<D extends EventDefs, K extends keyof D & string = keyof D & string> = {
|
|
85
|
+
sessionId: string;
|
|
86
|
+
event: Pick<ContractEvent<D, K>, "type" | "payload"> & {
|
|
87
|
+
id?: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
type Lane<D extends EventDefs, K extends keyof D & string = keyof D & string> = string | ((context: LaneContext<D, K>) => string);
|
|
91
|
+
type SessionDispatch<D extends EventDefs> = {
|
|
92
|
+
(...events: AppendInput<D>[]): Promise<ContractEvent<D>[]>;
|
|
93
|
+
/** The push-route path: events from `parsePushBody`. */
|
|
94
|
+
(...events: PushedEvent[]): Promise<ContractEvent<D>[]>;
|
|
95
|
+
};
|
|
96
|
+
type SessionAppend<D extends EventDefs> = SessionDispatch<D> & {
|
|
97
|
+
/** Commit, then hand pending work directly to configured scheduler. */
|
|
98
|
+
dispatch: SessionDispatch<D>;
|
|
99
|
+
};
|
|
100
|
+
type HandlerAppend<D extends EventDefs> = (name: string, ...events: AppendInput<D>[]) => Promise<ContractEvent<D>[]>;
|
|
101
|
+
type ScheduleDelay = `${number}${"ms" | "s" | "m" | "h" | "d"}`;
|
|
102
|
+
type ScheduleTiming = {
|
|
103
|
+
delay: ScheduleDelay;
|
|
104
|
+
at?: never;
|
|
105
|
+
} | {
|
|
106
|
+
at: Date;
|
|
107
|
+
delay?: never;
|
|
108
|
+
};
|
|
109
|
+
type SessionSchedule<D extends EventDefs> = (name: string, timing: ScheduleTiming, ...events: AppendInput<D>[]) => Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* The presence members of a session — intersected in via
|
|
112
|
+
* `WithPresence`, so they exist exactly when the contract declares
|
|
113
|
+
* presence fields. Intersected before the base members so the widened
|
|
114
|
+
* `stream` overload is tried first: the literal `presence: true`
|
|
115
|
+
* selects it, everything else falls through to the events-only base.
|
|
116
|
+
*/
|
|
117
|
+
type SessionPresence<D extends EventDefs, P extends PresenceDefs> = {
|
|
118
|
+
/**
|
|
119
|
+
* The two-plane feed: one snapshot of the current pruned map first
|
|
120
|
+
* (per-field stamps exact), then presence patches interleaved with
|
|
121
|
+
* events.
|
|
122
|
+
*/
|
|
123
|
+
stream(opts: {
|
|
124
|
+
startAfter?: number;
|
|
125
|
+
presence: true;
|
|
126
|
+
}): AsyncIterable<ContractEvent<D> | PresencePatch<P> | PresenceSnapshot<P>>;
|
|
127
|
+
/**
|
|
128
|
+
* Validate against the contract's presence schemas, then broadcast.
|
|
129
|
+
* Never an append: no log row, no dispatch, no scheduler arm. `at`
|
|
130
|
+
* is the sender's LWW stamp in epoch ms; omitted, receipt time
|
|
131
|
+
* stands in (single writer, so receipt order is sender order).
|
|
132
|
+
*/
|
|
133
|
+
setPresence(patch: {
|
|
134
|
+
participant: string;
|
|
135
|
+
values: PresencePatch<P>["values"];
|
|
136
|
+
seen?: number;
|
|
137
|
+
at?: number;
|
|
138
|
+
} | PushedPresence): Promise<void>;
|
|
139
|
+
/** The current map, expired values pruned — a point-in-time read. */
|
|
140
|
+
presence(): Promise<PresenceMap<P>>;
|
|
141
|
+
};
|
|
142
|
+
/** A handle on one instance of the machine. Creating it does no I/O. */
|
|
143
|
+
type Session<D extends EventDefs, Append = SessionAppend<D>, P extends PresenceDefs = Record<never, never>> = WithPresence<P, SessionPresence<D, P>> & {
|
|
144
|
+
readonly id: string;
|
|
145
|
+
append: Append;
|
|
146
|
+
schedule: SessionSchedule<D>;
|
|
147
|
+
history(options?: {
|
|
148
|
+
gte?: number;
|
|
149
|
+
lte?: number;
|
|
150
|
+
}): Promise<ContractEvent<D>[]>;
|
|
151
|
+
state<S>(reducer: Reducer<D, S>): Promise<{
|
|
152
|
+
state: S;
|
|
153
|
+
index: number;
|
|
154
|
+
}>;
|
|
155
|
+
/**
|
|
156
|
+
* A live feed of this session's events, starting after `startAfter`
|
|
157
|
+
* (exclusive). Server-side only — expose it over SSE with
|
|
158
|
+
* `sseResponse` from experimental-a2/http.
|
|
159
|
+
*/
|
|
160
|
+
stream(opts?: {
|
|
161
|
+
startAfter?: number;
|
|
162
|
+
}): AsyncIterable<ContractEvent<D>>;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* The public server shape scheduler handlers accept. It stays structural so
|
|
166
|
+
* servers of any contract mix in one route; A2's private server internals add
|
|
167
|
+
* delayed-append delivery without exposing an untyped append method here.
|
|
168
|
+
*/
|
|
169
|
+
type DrainableServer = {
|
|
170
|
+
readonly contract: {
|
|
171
|
+
readonly name: string;
|
|
172
|
+
};
|
|
173
|
+
drain(sessionId: string): Promise<{
|
|
174
|
+
settled: boolean;
|
|
175
|
+
}>;
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* The scheduler seam (a2-implementation.md §7, §9). `schedule` puts a
|
|
179
|
+
* versioned drain or delayed append task on durable infrastructure;
|
|
180
|
+
* `handler` returns the route the transport delivers to. Claim holders
|
|
181
|
+
* move the watchdog alongside their renewable execution window.
|
|
182
|
+
* Implementations ship as
|
|
183
|
+
* entry points (`experimental-a2/scheduler-vercel`); core never imports a
|
|
184
|
+
* transport.
|
|
185
|
+
*/
|
|
186
|
+
type A2Scheduler = {
|
|
187
|
+
schedule(task: SchedulerTask): Promise<void>;
|
|
188
|
+
handler(...servers: DrainableServer[]): (req: Request) => Promise<Response>;
|
|
189
|
+
};
|
|
190
|
+
type A2Server<D extends EventDefs, P extends PresenceDefs = Record<never, never>> = {
|
|
191
|
+
/** The contract this server implements. */
|
|
192
|
+
readonly contract: Contract<D, P>;
|
|
193
|
+
session(id: string): Session<D, SessionAppend<D>, P>;
|
|
194
|
+
/**
|
|
195
|
+
* Process every currently eligible event. `settled` means nothing
|
|
196
|
+
* actionable remains, including work blocked behind a dead letter.
|
|
197
|
+
*/
|
|
198
|
+
drain(sessionId: string): Promise<{
|
|
199
|
+
settled: boolean;
|
|
200
|
+
}>;
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Deliver one authenticated scheduler append through an A2 server's ordinary
|
|
204
|
+
* top-level append path. Custom scheduler adapters call this after validating
|
|
205
|
+
* their transport envelope; application code normally uses `session.schedule`.
|
|
206
|
+
*/
|
|
207
|
+
declare function deliverSchedulerAppend(server: DrainableServer, task: SchedulerAppendTask): Promise<void>;
|
|
208
|
+
/**
|
|
209
|
+
* Which events fire `ctx.signal` while a handler runs — the preemption
|
|
210
|
+
* channel for user cancellation. The array form matches by type; the
|
|
211
|
+
* object form takes per-type predicates for targeted cancellation
|
|
212
|
+
* (`(event, trigger) => event.payload.of === trigger.id`). Handlers
|
|
213
|
+
* without `abortOn` pay nothing. An aborted handler should catch and
|
|
214
|
+
* return normally; throwing means "retry me".
|
|
215
|
+
*/
|
|
216
|
+
type AbortSpec<D extends EventDefs, K extends keyof D & string> = Array<keyof D & string> | { [T in keyof D & string]?: true | ((event: ContractEvent<D, T>, trigger: ContractEvent<D, K>, context: {
|
|
217
|
+
attempt: number;
|
|
218
|
+
}) => boolean); };
|
|
219
|
+
type HandlerEntry<D extends EventDefs, K extends keyof D & string = keyof D & string, P extends PresenceDefs = Record<never, never>> = Handler<D, K, P> | {
|
|
220
|
+
abortOn?: AbortSpec<D, K>;
|
|
221
|
+
/** Session-scoped FIFO key, resolved and persisted when the event lands. */
|
|
222
|
+
lane?: Lane<D, K>;
|
|
223
|
+
handler: Handler<D, K, P>;
|
|
224
|
+
};
|
|
225
|
+
type ServerOptions<D extends EventDefs, P extends PresenceDefs = Record<never, never>> = {
|
|
226
|
+
/** The contract this server implements (see `a2.contract`). */
|
|
227
|
+
contract: Contract<D, P>;
|
|
228
|
+
/** Where events live. Defaults: sqlite in dev, memory in tests, required in prod. */
|
|
229
|
+
store?: A2Store;
|
|
230
|
+
/**
|
|
231
|
+
* Queue-backed scheduler — e.g. `vercelQueues()` from
|
|
232
|
+
* `experimental-a2/scheduler-vercel`. Absent means append-driven healing only: a
|
|
233
|
+
* working configuration, but a clockless one. Recommended in
|
|
234
|
+
* production.
|
|
235
|
+
*/
|
|
236
|
+
scheduler?: A2Scheduler;
|
|
237
|
+
/** Optional instrumentation — e.g. `otel()` from `experimental-a2/otel`. */
|
|
238
|
+
telemetry?: A2Telemetry;
|
|
239
|
+
/** Validate events that came through `parsePushBody` before writing them. */
|
|
240
|
+
validatePush?: (context: PushValidationContext) => void | PromiseLike<void>;
|
|
241
|
+
/**
|
|
242
|
+
* Presence-plane policy — valid only when the contract declares
|
|
243
|
+
* presence fields (TypeError at construction otherwise). `ttlMs` is
|
|
244
|
+
* how long a value survives without a refreshing set; default 60s.
|
|
245
|
+
*/
|
|
246
|
+
presence?: {
|
|
247
|
+
ttlMs?: number;
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* The reactions, keyed by event type — all present at construction,
|
|
251
|
+
* so a handler can never be silently missing because its module
|
|
252
|
+
* wasn't imported. Compose across files by spreading objects (note:
|
|
253
|
+
* a duplicate key under spread silently last-wins).
|
|
254
|
+
*/
|
|
255
|
+
handlers?: { [K in keyof D & string]?: HandlerEntry<D, K, P>; };
|
|
256
|
+
};
|
|
257
|
+
/** Implement a contract: bind its vocabulary to storage and reactions. */
|
|
258
|
+
declare function createServer<D extends EventDefs, P extends PresenceDefs = Record<never, never>>(options: ServerOptions<D, P>): A2Server<D, P>;
|
|
259
|
+
//#endregion
|
|
260
|
+
export { deliverSchedulerAppend as C, SchedulerTask as D, SchedulerDrainTask as E, createServer as S, SchedulerAppendTask as T, Session as _, Handler as a, SessionPresence as b, HandlerEntry as c, PushValidationContext as d, PushedEvent as f, ServerOptions as g, ScheduleTiming as h, DrainableServer as i, Lane as l, ScheduleDelay as m, A2Server as n, HandlerAppend as o, PushedPresence as p, AbortSpec as r, HandlerContext as s, A2Scheduler as t, LaneContext as u, SessionAppend as v, ScheduledEvent as w, SessionSchedule as x, SessionDispatch as y };
|
package/dist/server.d.ts
CHANGED
|
@@ -1,155 +1,4 @@
|
|
|
1
|
-
import { a as EventDefs, c as
|
|
2
|
-
import { a as Event, c as IdSource, d as
|
|
3
|
-
import { i as
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Events that arrived over the wire through `parsePushBody` — already
|
|
7
|
-
* envelope-validated, headed for schema validation inside `append`.
|
|
8
|
-
* The brand lets the documented push route hand them straight to
|
|
9
|
-
* `session.append` without weakening typed appends for app code: a
|
|
10
|
-
* hand-written `{ type: string }` literal still fails to compile.
|
|
11
|
-
*/
|
|
12
|
-
type PushedEvent = {
|
|
13
|
-
type: string;
|
|
14
|
-
payload: unknown;
|
|
15
|
-
id?: string;
|
|
16
|
-
readonly "~a2.pushed": true;
|
|
17
|
-
};
|
|
18
|
-
type PushValidationContext = {
|
|
19
|
-
sessionId: string;
|
|
20
|
-
events: readonly PushedEvent[];
|
|
21
|
-
};
|
|
22
|
-
/** What every handler receives. */
|
|
23
|
-
type HandlerContext<D extends EventDefs, K extends keyof D & string = keyof D & string> = {
|
|
24
|
-
/** The triggering event. */
|
|
25
|
-
event: ContractEvent<D, K>;
|
|
26
|
-
/** Durable, 1-based dispatch ordinal for this event. */
|
|
27
|
-
attempt: number;
|
|
28
|
-
/** This session, with handler-scoped idempotent append. */
|
|
29
|
-
session: Session<D, HandlerAppend<D>>;
|
|
30
|
-
/** Fires on `abortOn` events (cancellation slice); dormant otherwise. */
|
|
31
|
-
signal: AbortSignal;
|
|
32
|
-
};
|
|
33
|
-
type Handler<D extends EventDefs, K extends keyof D & string = keyof D & string> = (ctx: HandlerContext<D, K>) => Promise<void | AppendInput<D> | readonly AppendInput<D>[]>;
|
|
34
|
-
type LaneContext<D extends EventDefs, K extends keyof D & string = keyof D & string> = {
|
|
35
|
-
sessionId: string;
|
|
36
|
-
event: Pick<ContractEvent<D, K>, "type" | "payload"> & {
|
|
37
|
-
id?: string;
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
type Lane<D extends EventDefs, K extends keyof D & string = keyof D & string> = string | ((context: LaneContext<D, K>) => string);
|
|
41
|
-
type SessionDispatch<D extends EventDefs> = {
|
|
42
|
-
(...events: AppendInput<D>[]): Promise<ContractEvent<D>[]>;
|
|
43
|
-
/** The push-route path: events from `parsePushBody`. */
|
|
44
|
-
(...events: PushedEvent[]): Promise<ContractEvent<D>[]>;
|
|
45
|
-
};
|
|
46
|
-
type SessionAppend<D extends EventDefs> = SessionDispatch<D> & {
|
|
47
|
-
/** Commit, then hand pending work directly to configured recovery. */
|
|
48
|
-
dispatch: SessionDispatch<D>;
|
|
49
|
-
};
|
|
50
|
-
type HandlerAppend<D extends EventDefs> = (name: string, ...events: AppendInput<D>[]) => Promise<ContractEvent<D>[]>;
|
|
51
|
-
/** A handle on one instance of the machine. Creating it does no I/O. */
|
|
52
|
-
type Session<D extends EventDefs, Append = SessionAppend<D>> = {
|
|
53
|
-
readonly id: string;
|
|
54
|
-
append: Append;
|
|
55
|
-
history(): Promise<ContractEvent<D>[]>;
|
|
56
|
-
state<S>(reducer: Reducer<D, S>): Promise<{
|
|
57
|
-
state: S;
|
|
58
|
-
index: number;
|
|
59
|
-
}>;
|
|
60
|
-
/**
|
|
61
|
-
* A live feed of this session's events, starting after `startAt`
|
|
62
|
-
* (exclusive). Server-side only — expose it over SSE with
|
|
63
|
-
* `sseResponse` from experimental-a2/http.
|
|
64
|
-
*/
|
|
65
|
-
stream(opts?: {
|
|
66
|
-
startAt?: number;
|
|
67
|
-
}): AsyncIterable<ContractEvent<D>>;
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* What recovery needs from a server — structural, so servers of any
|
|
71
|
-
* contract mix in one `handler(...)` call. Deliberately tiny: recovery
|
|
72
|
-
* consults the log through `drain` and nothing else.
|
|
73
|
-
*/
|
|
74
|
-
type RecoverableServer = {
|
|
75
|
-
readonly contract: {
|
|
76
|
-
readonly name: string;
|
|
77
|
-
};
|
|
78
|
-
drain(sessionId: string): Promise<{
|
|
79
|
-
settled: boolean;
|
|
80
|
-
}>;
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* The recovery seam (a2-implementation.md §7, §9). `arm` puts a
|
|
84
|
-
* delayed, coalesced "drain this session" message on durable
|
|
85
|
-
* infrastructure while inline work starts; `handler` returns the route
|
|
86
|
-
* the transport delivers to. Claim holders move the watchdog alongside
|
|
87
|
-
* their renewable execution window. Implementations ship as
|
|
88
|
-
* entry points (`experimental-a2/recovery-vercel`); core never imports a transport.
|
|
89
|
-
*/
|
|
90
|
-
type A2Recovery = {
|
|
91
|
-
arm(opts: {
|
|
92
|
-
contract: string;
|
|
93
|
-
sessionId: string;
|
|
94
|
-
/** Earliest useful delivery as epoch milliseconds. */
|
|
95
|
-
dueAt?: number;
|
|
96
|
-
}): Promise<void>;
|
|
97
|
-
handler(...servers: RecoverableServer[]): (req: Request) => Promise<Response>;
|
|
98
|
-
};
|
|
99
|
-
type A2Server<D extends EventDefs> = {
|
|
100
|
-
/** The contract this server implements. */
|
|
101
|
-
readonly contract: Contract<D>;
|
|
102
|
-
session(id: string): Session<D>;
|
|
103
|
-
/**
|
|
104
|
-
* Process every currently eligible event. `settled` means nothing
|
|
105
|
-
* actionable remains, including work blocked behind a dead letter.
|
|
106
|
-
*/
|
|
107
|
-
drain(sessionId: string): Promise<{
|
|
108
|
-
settled: boolean;
|
|
109
|
-
}>;
|
|
110
|
-
};
|
|
111
|
-
/**
|
|
112
|
-
* Which events fire `ctx.signal` while a handler runs — the preemption
|
|
113
|
-
* channel for user cancellation. The array form matches by type; the
|
|
114
|
-
* object form takes per-type predicates for targeted cancellation
|
|
115
|
-
* (`(event, trigger) => event.payload.of === trigger.id`). Handlers
|
|
116
|
-
* without `abortOn` pay nothing. An aborted handler should catch and
|
|
117
|
-
* return normally; throwing means "retry me".
|
|
118
|
-
*/
|
|
119
|
-
type AbortSpec<D extends EventDefs, K extends keyof D & string> = Array<keyof D & string> | { [T in keyof D & string]?: true | ((event: ContractEvent<D, T>, trigger: ContractEvent<D, K>, context: {
|
|
120
|
-
attempt: number;
|
|
121
|
-
}) => boolean); };
|
|
122
|
-
type HandlerEntry<D extends EventDefs, K extends keyof D & string = keyof D & string> = Handler<D, K> | {
|
|
123
|
-
abortOn?: AbortSpec<D, K>;
|
|
124
|
-
/** Session-scoped FIFO key, resolved and persisted when the event lands. */
|
|
125
|
-
lane?: Lane<D, K>;
|
|
126
|
-
handler: Handler<D, K>;
|
|
127
|
-
};
|
|
128
|
-
type ServerOptions<D extends EventDefs> = {
|
|
129
|
-
/** The contract this server implements (see `a2.contract`). */
|
|
130
|
-
contract: Contract<D>;
|
|
131
|
-
/** Where events live. Defaults: sqlite in dev, memory in tests, required in prod. */
|
|
132
|
-
log?: A2Log;
|
|
133
|
-
/**
|
|
134
|
-
* Queue-backed recovery — e.g. `vercelQueues()` from
|
|
135
|
-
* `experimental-a2/recovery-vercel`. Absent means append-driven healing only: a
|
|
136
|
-
* working configuration, but a clockless one. Recommended in
|
|
137
|
-
* production.
|
|
138
|
-
*/
|
|
139
|
-
recovery?: A2Recovery;
|
|
140
|
-
/** Optional instrumentation — e.g. `otel()` from `experimental-a2/otel`. */
|
|
141
|
-
telemetry?: A2Telemetry;
|
|
142
|
-
/** Validate events that came through `parsePushBody` before writing them. */
|
|
143
|
-
validatePush?: (context: PushValidationContext) => void | PromiseLike<void>;
|
|
144
|
-
/**
|
|
145
|
-
* The reactions, keyed by event type — all present at construction,
|
|
146
|
-
* so a handler can never be silently missing because its module
|
|
147
|
-
* wasn't imported. Compose across files by spreading objects (note:
|
|
148
|
-
* a duplicate key under spread silently last-wins).
|
|
149
|
-
*/
|
|
150
|
-
handlers?: { [K in keyof D & string]?: HandlerEntry<D, K>; };
|
|
151
|
-
};
|
|
152
|
-
/** Implement a contract: bind its vocabulary to storage and reactions. */
|
|
153
|
-
declare function createServer<D extends EventDefs>(options: ServerOptions<D>): A2Server<D>;
|
|
154
|
-
//#endregion
|
|
155
|
-
export { type A2Log, type A2LogInspection, A2Recovery, A2Server, AbortSpec, type AppendEvent, type AppendInput, type Clock, type Contract, type ContractEvent, type Event, type EventCause, type EventDefs, type FailAttemptResult, Handler, HandlerAppend, HandlerContext, HandlerEntry, type IdSource, Lane, LaneContext, type LogAppendResult, type LogClaimAvailableResult, type LogStateRead, PushValidationContext, PushedEvent, RecoverableServer, ServerOptions, Session, SessionAppend, SessionDispatch, type StoredEvent, type StoredSessionPage, type StoredSessionSummary, type StoredSnapshot, createServer };
|
|
1
|
+
import { a as EventDefs, c as PresencePatch, l as PresenceSnapshot, n as Contract, o as PresenceDefs, r as ContractEvent, s as PresenceMap, t as AppendInput } from "./contract-jIfaR085.js";
|
|
2
|
+
import { a as Event, c as IdSource, d as StoreClaimAvailableResult, f as StoreStateRead, g as StoredSnapshot, h as StoredSessionSummary, i as Clock, l as PresenceRow, m as StoredSessionPage, n as A2StoreInspection, o as EventCause, p as StoredEvent, r as AppendEvent, s as FailAttemptResult, t as A2Store, u as StoreAppendResult } from "./store-C3sNAaBT.js";
|
|
3
|
+
import { C as deliverSchedulerAppend, D as SchedulerTask, E as SchedulerDrainTask, S as createServer, T as SchedulerAppendTask, _ as Session, a as Handler, b as SessionPresence, c as HandlerEntry, d as PushValidationContext, f as PushedEvent, g as ServerOptions, h as ScheduleTiming, i as DrainableServer, l as Lane, m as ScheduleDelay, n as A2Server, o as HandlerAppend, p as PushedPresence, r as AbortSpec, s as HandlerContext, t as A2Scheduler, u as LaneContext, v as SessionAppend, w as ScheduledEvent, x as SessionSchedule, y as SessionDispatch } from "./server-YtPq7hjw.js";
|
|
4
|
+
export { A2Scheduler, A2Server, type A2Store, type A2StoreInspection, AbortSpec, type AppendEvent, type AppendInput, type Clock, type Contract, type ContractEvent, DrainableServer, type Event, type EventCause, type EventDefs, type FailAttemptResult, Handler, HandlerAppend, HandlerContext, HandlerEntry, type IdSource, Lane, LaneContext, type PresenceDefs, type PresenceMap, type PresencePatch, type PresenceRow, type PresenceSnapshot, PushValidationContext, PushedEvent, PushedPresence, ScheduleDelay, ScheduleTiming, type ScheduledEvent, type SchedulerAppendTask, type SchedulerDrainTask, type SchedulerTask, ServerOptions, Session, SessionAppend, SessionDispatch, SessionPresence, SessionSchedule, type StoreAppendResult, type StoreClaimAvailableResult, type StoreStateRead, type StoredEvent, type StoredSessionPage, type StoredSessionSummary, type StoredSnapshot, createServer, deliverSchedulerAppend };
|
package/dist/server.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createServer } from "./server-
|
|
2
|
-
export { createServer };
|
|
1
|
+
import { n as deliverSchedulerAppend, t as createServer } from "./server-CcNnFnoW.js";
|
|
2
|
+
export { createServer, deliverSchedulerAppend };
|