@vercel/board 0.16.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/README.md +27 -27
- package/dist/{a2-C41hD8SF.mjs → a2-ChRLRupa.mjs} +969 -25
- package/dist/access.d.mts +1 -1
- package/dist/access.mjs +3 -3
- package/dist/{actors-DjMeZpnU.mjs → actors-BOamkEuz.mjs} +3 -73
- package/dist/attempts-CLG840Oj.mjs +20 -0
- package/dist/{auth-COzc09sn.mjs → auth-Drg9FiC2.mjs} +225 -2
- package/dist/backend-B-SJ7p6p.d.mts +680 -0
- package/dist/backend-a2/contract.d.mts +873 -2
- package/dist/backend-a2/contract.mjs +2 -2
- package/dist/backend-a2/scheduler-local.d.mts +1 -1
- package/dist/backend-a2/scheduler-local.mjs +1 -1
- package/dist/backend-a2/scheduler-qstash.d.mts +78 -1
- package/dist/backend-a2/scheduler-qstash.mjs +521 -1
- package/dist/backend-a2/scheduler-vercel.d.mts +37 -1
- package/dist/backend-a2/scheduler-vercel.mjs +203 -1
- package/dist/backend-a2/store-memory.d.mts +2 -2
- package/dist/backend-a2/store-memory.mjs +3 -3
- package/dist/backend-a2/store-postgres.d.mts +1 -1
- package/dist/backend-a2/store-postgres.mjs +2850 -2
- package/dist/backend-a2/store-redis-http.d.mts +1 -1
- package/dist/backend-a2/store-redis-http.mjs +490 -2
- package/dist/backend-a2/store-redis.d.mts +10 -2
- package/dist/backend-a2/store-redis.mjs +51 -2
- package/dist/backend-a2/store-sqlite.d.mts +1 -1
- package/dist/backend-a2/store-sqlite.mjs +3 -3
- package/dist/backend-a2.d.mts +2706 -3
- package/dist/backend-a2.mjs +1 -1
- package/dist/{backend-http-Bid7RIpC.d.mts → backend-http-7cNb8nJI.d.mts} +10 -3
- package/dist/{backend-http-0roEmjl0.mjs → backend-http-CMlL3yq3.mjs} +2 -2
- package/dist/{backend-http-BVRno-ca.mjs → backend-http-Ddzd5kTS.mjs} +32 -3
- package/dist/backend-http.d.mts +1 -1
- package/dist/backend-http.mjs +1 -1
- package/dist/backend-http.node.d.mts +1 -1
- package/dist/backend-http.node.mjs +1 -1
- package/dist/{chat-provider-XCnQlxq6.d.mts → chat-provider-DNJQyajS.d.mts} +16 -4
- package/dist/{chat-provider-jFSeyNmB.mjs → chat-provider-YHy-WbrB.mjs} +15 -9
- package/dist/cli.mjs +30 -10
- package/dist/{client-DGDPaN7U.mjs → client-BA-J7usH.mjs} +10 -2
- package/dist/{conformance-DRR23YNy.mjs → conformance-CT5EeHeC.mjs} +5 -2
- package/dist/conformance.d.mts +1 -1
- package/dist/conformance.mjs +1 -1
- package/dist/{engine-Bir5s8ts.mjs → engine-D0oBUBEK.mjs} +249 -163
- package/dist/events-CewD4kw7.mjs +75 -0
- package/dist/{exports-Dvc1o52I.mjs → exports-CgjfMrQ-.mjs} +35 -32
- package/dist/exports-ZsgjzEnM.d.mts +4 -0
- package/dist/external-BV_cUncs.mjs +151 -0
- package/dist/folds-CRYY14kc.d.mts +534 -0
- package/dist/{reducers-mUPFuFJV.mjs → folds-Dyjput8M.mjs} +6 -73
- package/dist/ids-C6AYo1bu.mjs +31 -0
- package/dist/index.d.mts +4 -4
- package/dist/{index.default-Bkg77Pxn.mjs → index.default-C5Cpz3sa.mjs} +1 -1
- package/dist/index.mjs +5 -5
- package/dist/index.node.d.mts +4 -4
- package/dist/index.node.mjs +3 -3
- package/dist/inspect/app.js +31 -31
- package/dist/inspect/engine.js +5 -5
- package/dist/internal-CvsrprnU-CRY89I-b.mjs +203 -0
- package/dist/{local-Cr_dSjvs.mjs → local-DhkrAqPP.mjs} +1 -1
- package/dist/mentions-CB6ShY4R.mjs +72 -0
- package/dist/{targets-yM5JBUgr.mjs → middleware-CqaCwucP.mjs} +1 -33
- package/dist/platform-B4TnJtWu-CwcTyKg2.mjs +32 -0
- package/dist/{project-CFiArraX.mjs → project-DMDST9kl.mjs} +1 -1
- package/dist/{provider-BGjz-mDa.d.mts → provider-B0b9Qxw4.d.mts} +170 -40
- package/dist/provider-B3DpYSDq.mjs +220 -0
- package/dist/redis-tables-DN9PfIDi.mjs +3897 -0
- package/dist/reducer-CYPHsSmd-BQIfozGi.d.mts +170 -0
- package/dist/reducer-CjmvZSAb-D_OSISmj.mjs +74 -0
- package/dist/{contract-CuJmlrhw.mjs → reducers-BFmIXilu.mjs} +260 -287
- package/dist/retryable-lazy-DZWmHpii-Bye-W8q7.mjs +19 -0
- package/dist/scheduler-task-X1SToDjP-BVoWuInI.mjs +69 -0
- package/dist/{serve-BsOOc-6_.mjs → serve-BGYw0uNL.mjs} +5 -5
- package/dist/{server-jwPY7_wi.mjs → server-DPxBSogx.mjs} +4 -4
- package/dist/server-DtFrWxi3-Boa6gdWO.mjs +3602 -0
- package/dist/server-qgez0Xny-D5mLfqFQ.d.mts +385 -0
- package/dist/{serving-BNbzc96L.mjs → serving-CNkgUPW1.mjs} +1 -1
- package/dist/session-clear-wHd5GCpZ-BnKSxReK.mjs +51 -0
- package/dist/{sql-DbiEnqM0.mjs → sql-U9WTxrwJ.mjs} +2 -2
- package/dist/{sqlite-db-Cbj03vmp.mjs → sqlite-db-Ds4majtT.mjs} +1 -1
- package/dist/store-D0MhBvg6-4Z2L0Kqd.d.mts +530 -0
- package/dist/store-N8PXxDAS-BWBgzBHp.mjs +5 -0
- package/dist/store-codec-DwrWlgQx-CYxGW0aD.mjs +61 -0
- package/dist/store-memory-Bas9Uq5C.mjs +872 -0
- package/dist/store-memory-ZLiZbH3R.mjs +2 -0
- package/dist/store-polling-BZt2Rf3D-BiEM6_HB.mjs +148 -0
- package/dist/store-presence-polling-JuAy2Ck2-CYpuK75X.mjs +109 -0
- package/dist/store-sqlite-BmwL3pUR.mjs +2 -0
- package/dist/store-sqlite-CxxPCcCT.mjs +1053 -0
- package/dist/stream-buffer-DrTyiIuo-BKy-vI14.mjs +53 -0
- package/dist/sync-github.d.mts +24 -17
- package/dist/sync-github.mjs +89 -22
- package/dist/sync-kapso.d.mts +15 -13
- package/dist/sync-kapso.mjs +17 -14
- package/dist/sync-linear.d.mts +219 -0
- package/dist/sync-linear.mjs +311 -0
- package/dist/sync-slack.d.mts +12 -17
- package/dist/sync-slack.mjs +54 -42
- package/dist/sync.chat.d.mts +1 -1
- package/dist/sync.chat.mjs +1 -1
- package/dist/sync.d.mts +3 -3
- package/dist/sync.mjs +5 -4
- package/dist/targets-C-wdR5wP.mjs +33 -0
- package/dist/{tokens-DKLn5P9B.mjs → tokens-DhuzKzAl.mjs} +1 -1
- package/dist/{types-BHCjTZdB.d.mts → types-8yq2VnKI.d.mts} +2 -2
- package/dist/{users-Dls7_ANV.mjs → users-yryHKFMo.mjs} +2 -2
- package/dist/{watch-spec-W0c7ypHJ.mjs → watchers-hash-RLtnSF-t.mjs} +233 -28
- package/docs/01-board/01-mounting.md +1 -1
- package/docs/02-sync/01-overview.md +72 -48
- package/docs/02-sync/02-functions.md +398 -0
- package/docs/02-sync/03-slack.md +30 -25
- package/docs/02-sync/04-github.md +62 -26
- package/docs/02-sync/05-whatsapp.md +23 -19
- package/docs/02-sync/06-providers.md +60 -27
- package/docs/02-sync/07-linear.md +129 -0
- package/docs/03-guides/04-triage.md +1 -1
- package/docs/04-reference/01-cli.md +26 -6
- package/docs/04-reference/02-board.md +18 -5
- package/docs/04-reference/03-http.md +5 -2
- package/docs/04-reference/05-conformance.md +1 -1
- package/docs/index.md +5 -10
- package/package.json +31 -6
- package/dist/a2-D24cvwpN.d.mts +0 -3359
- package/dist/access-CJU2-vaa.mjs +0 -226
- package/dist/attempts-Bxp9KgPf.mjs +0 -919
- package/dist/exports-DLiE7fLY.d.mts +0 -4
- package/dist/provider-CuewcDNZ.mjs +0 -205
- package/dist/redis-tables-B35vv4CZ.mjs +0 -842
- package/dist/reducers-B_vUGQRp.d.mts +0 -1172
- package/dist/watchers-hash-CLjsa6od.mjs +0 -225
- package/docs/02-sync/02-callbacks.md +0 -265
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { a as PresenceDefs, c as PresenceSnapshot, d as WithPresence, i as EventDefs, l as Reducer, n as Contract, o as PresenceMap, r as ContractEvent, s as PresencePatch, t as AppendInput, u as RegisteredReducer } from "./reducer-CYPHsSmd-BQIfozGi.mjs";
|
|
2
|
+
import { r as Event } from "./store-D0MhBvg6-4Z2L0Kqd.mjs";
|
|
3
|
+
//#region ../../node_modules/.pnpm/experimental-a2@0.22.0_@upstash+qstash@2.12.0_@vercel+queue@0.7.0_ai@7.0.130_zod@4.6.5__52060f00b21aecfab049c27fa3abd2f9/node_modules/experimental-a2/dist/session-clear-D1PFe7xl.d.ts
|
|
4
|
+
//#region src/session-clear.d.ts
|
|
5
|
+
/** Reserved type of the marker a clear appends. */
|
|
6
|
+
declare const CLEAR_EVENT_TYPE = "a2.cleared";
|
|
7
|
+
/** The marker `session.stream()` yields where a clear ended a lifetime. */
|
|
8
|
+
type SessionCleared = Event & {
|
|
9
|
+
type: typeof CLEAR_EVENT_TYPE;
|
|
10
|
+
payload: null;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region ../../node_modules/.pnpm/experimental-a2@0.22.0_@upstash+qstash@2.12.0_@vercel+queue@0.7.0_ai@7.0.130_zod@4.6.5__52060f00b21aecfab049c27fa3abd2f9/node_modules/experimental-a2/dist/server-qgez0Xny.d.ts
|
|
14
|
+
//#region src/session-socket.d.ts
|
|
15
|
+
/**
|
|
16
|
+
* The structural socket `sessionsSocket` speaks against — satisfied
|
|
17
|
+
* by `ws` and by `@vercel/functions`' upgraded socket alike, so the
|
|
18
|
+
* platform upgrade API stays out of the library. `message` data
|
|
19
|
+
* arrives as whatever the platform delivers (string, Buffer,
|
|
20
|
+
* ArrayBuffer, or fragments); the handler normalizes defensively.
|
|
21
|
+
*/
|
|
22
|
+
type A2Socket = {
|
|
23
|
+
send(data: string): void;
|
|
24
|
+
on(event: "message", listener: (data: unknown) => void): void;
|
|
25
|
+
on(event: "close", listener: () => void): void;
|
|
26
|
+
on(event: "error", listener: (error: unknown) => void): void;
|
|
27
|
+
close(code?: number, reason?: string): void;
|
|
28
|
+
/** Bytes queued but not yet transmitted — when exposed, the down
|
|
29
|
+
* pump uses it for backpressure (`SOCKET_TIMINGS`). */
|
|
30
|
+
bufferedAmount?: number;
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/server-fetch.d.ts
|
|
34
|
+
type SuggestedEventType<D extends EventDefs> = (keyof D & string) | (string & Record<never, never>);
|
|
35
|
+
type SuggestedPresenceValues<P extends PresenceDefs> = Readonly<{ [F in keyof P & string]?: unknown; } & Record<string, unknown>>;
|
|
36
|
+
type A2PushEvent<D extends EventDefs = EventDefs> = {
|
|
37
|
+
readonly type: SuggestedEventType<D>;
|
|
38
|
+
readonly payload: unknown;
|
|
39
|
+
readonly id?: string;
|
|
40
|
+
};
|
|
41
|
+
type A2PushPresence<P extends PresenceDefs = PresenceDefs> = {
|
|
42
|
+
readonly participant: string;
|
|
43
|
+
readonly values: SuggestedPresenceValues<P>;
|
|
44
|
+
readonly seen?: number;
|
|
45
|
+
readonly at?: number;
|
|
46
|
+
};
|
|
47
|
+
type A2Operation<D extends EventDefs = EventDefs, P extends PresenceDefs = Record<never, never>> = {
|
|
48
|
+
readonly type: "stream";
|
|
49
|
+
readonly sessionId: string;
|
|
50
|
+
readonly startAfter: number;
|
|
51
|
+
readonly bootstrap?: true;
|
|
52
|
+
readonly transport: "http" | "websocket";
|
|
53
|
+
} | {
|
|
54
|
+
readonly type: "history";
|
|
55
|
+
readonly sessionId: string;
|
|
56
|
+
readonly gte: number;
|
|
57
|
+
readonly lte: number;
|
|
58
|
+
readonly transport: "http";
|
|
59
|
+
} | {
|
|
60
|
+
readonly type: "push";
|
|
61
|
+
readonly sessionId: string;
|
|
62
|
+
readonly events: readonly A2PushEvent<D>[];
|
|
63
|
+
readonly presence?: A2PushPresence<P>;
|
|
64
|
+
readonly transport: "http" | "websocket";
|
|
65
|
+
};
|
|
66
|
+
type UpgradeWebSocket = (attach: (socket: A2Socket) => void) => Response | Promise<Response>;
|
|
67
|
+
type ServerFetchOptions<D extends EventDefs = EventDefs, P extends PresenceDefs = Record<never, never>> = {
|
|
68
|
+
authorize?: (operation: A2Operation<D, P>) => boolean | Promise<boolean>;
|
|
69
|
+
upgradeWebSocket?: UpgradeWebSocket;
|
|
70
|
+
/** Allow one upgraded connection to select more than one session. */
|
|
71
|
+
multiplexWebSocket?: boolean;
|
|
72
|
+
};
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/scheduler-task.d.ts
|
|
75
|
+
/** One event carried by a delayed append task. */
|
|
76
|
+
type ScheduledEvent = {
|
|
77
|
+
id: string;
|
|
78
|
+
type: string;
|
|
79
|
+
payload: unknown;
|
|
80
|
+
};
|
|
81
|
+
/** A durable wake-up for pending consumer work. */
|
|
82
|
+
type SchedulerDrainTask = {
|
|
83
|
+
version: 1;
|
|
84
|
+
kind: "drain";
|
|
85
|
+
contract: string;
|
|
86
|
+
sessionId: string;
|
|
87
|
+
/** Earliest useful delivery as epoch milliseconds. */
|
|
88
|
+
dueAt: number;
|
|
89
|
+
};
|
|
90
|
+
/** A durable delayed append. */
|
|
91
|
+
type SchedulerAppendTask = {
|
|
92
|
+
version: 1;
|
|
93
|
+
kind: "append";
|
|
94
|
+
/** Stable identity for provider-level deduplication. */
|
|
95
|
+
id: string;
|
|
96
|
+
contract: string;
|
|
97
|
+
sessionId: string;
|
|
98
|
+
/** Earliest useful delivery as epoch milliseconds. */
|
|
99
|
+
dueAt: number;
|
|
100
|
+
events: readonly ScheduledEvent[];
|
|
101
|
+
/** The scheduling consumer's event; delivery skips once it is cleared. */
|
|
102
|
+
originIndex?: number;
|
|
103
|
+
};
|
|
104
|
+
/** A durable conditional clear. */
|
|
105
|
+
type SchedulerClearTask = {
|
|
106
|
+
version: 1;
|
|
107
|
+
kind: "clear";
|
|
108
|
+
/** Stable identity for provider-level deduplication. */
|
|
109
|
+
id: string;
|
|
110
|
+
contract: string;
|
|
111
|
+
sessionId: string;
|
|
112
|
+
/** Earliest useful delivery as epoch milliseconds. */
|
|
113
|
+
dueAt: number;
|
|
114
|
+
/** Clear only while this is still the head. */
|
|
115
|
+
ifLastIndex: number;
|
|
116
|
+
};
|
|
117
|
+
/** The versioned message protocol shared by scheduler adapters. */
|
|
118
|
+
type SchedulerTask = SchedulerDrainTask | SchedulerAppendTask | SchedulerClearTask;
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/server.d.ts
|
|
121
|
+
type PublicState<R> = undefined extends R ? never : R extends {
|
|
122
|
+
initialState: infer S;
|
|
123
|
+
} ? S : never;
|
|
124
|
+
/** What every consumer's `run` receives. */
|
|
125
|
+
type ConsumerContext<D extends EventDefs, K extends keyof D & string = keyof D & string, P extends PresenceDefs = Record<never, never>, S = never> = {
|
|
126
|
+
/** The triggering event. */
|
|
127
|
+
event: ContractEvent<D, K>;
|
|
128
|
+
/** Durable, 1-based dispatch ordinal for this event. */
|
|
129
|
+
attempt: number;
|
|
130
|
+
/** This session, with consumer-scoped idempotent append. */
|
|
131
|
+
session: Session<D, ConsumerAppend<D>, P, S>;
|
|
132
|
+
/** Fires on `abortOn` events (cancellation slice); dormant otherwise. */
|
|
133
|
+
signal: AbortSignal;
|
|
134
|
+
};
|
|
135
|
+
type LaneContext<D extends EventDefs, K extends keyof D & string = keyof D & string> = {
|
|
136
|
+
sessionId: string;
|
|
137
|
+
event: Pick<ContractEvent<D, K>, "type" | "payload"> & {
|
|
138
|
+
id?: string;
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* A consumer's lane: a string runs every event it takes in log order on one
|
|
143
|
+
* cursor; a function returns each event's lane, or null to run it
|
|
144
|
+
* concurrently.
|
|
145
|
+
*/
|
|
146
|
+
type ConsumerLane<D extends EventDefs, K extends keyof D & string = keyof D & string> = string | ((context: LaneContext<D, K>) => string | null);
|
|
147
|
+
type SessionDispatch<D extends EventDefs> = (...events: AppendInput<D>[]) => Promise<ContractEvent<D>[]>;
|
|
148
|
+
type SessionAppend<D extends EventDefs> = SessionDispatch<D> & {
|
|
149
|
+
/** Commit, then hand pending work directly to configured scheduler. */
|
|
150
|
+
dispatch: SessionDispatch<D>;
|
|
151
|
+
};
|
|
152
|
+
type ConsumerAppend<D extends EventDefs> = (name: string, ...events: AppendInput<D>[]) => Promise<ContractEvent<D>[]>;
|
|
153
|
+
type ScheduleDelay = `${number}${"ms" | "s" | "m" | "h" | "d"}`;
|
|
154
|
+
type ScheduleTiming = {
|
|
155
|
+
delay: ScheduleDelay;
|
|
156
|
+
at?: never;
|
|
157
|
+
} | {
|
|
158
|
+
at: Date;
|
|
159
|
+
delay?: never;
|
|
160
|
+
};
|
|
161
|
+
type SessionSchedule<D extends EventDefs> = {
|
|
162
|
+
(name: string, timing: ScheduleTiming, ...events: AppendInput<D>[]): Promise<void>;
|
|
163
|
+
/**
|
|
164
|
+
* Publish a durable conditional clear. Delivery clears only while
|
|
165
|
+
* `ifLastIndex` is still the head, and finishes deleting before it
|
|
166
|
+
* acknowledges.
|
|
167
|
+
*/
|
|
168
|
+
clear(name: string, options: ScheduleTiming & {
|
|
169
|
+
ifLastIndex: number;
|
|
170
|
+
}): Promise<void>;
|
|
171
|
+
};
|
|
172
|
+
type StateOptions = {
|
|
173
|
+
through?: number | "latest";
|
|
174
|
+
};
|
|
175
|
+
type SessionClearOptions = {
|
|
176
|
+
/** Clear only while this is the head; a mismatch changes nothing. */
|
|
177
|
+
ifLastIndex?: number;
|
|
178
|
+
};
|
|
179
|
+
type SessionClearResult = {
|
|
180
|
+
cleared: boolean;
|
|
181
|
+
index: number;
|
|
182
|
+
};
|
|
183
|
+
type SessionRedriveOptions = {
|
|
184
|
+
/** `retry` runs the consumer again with a fresh failure budget; `skip` settles the event without running it. */
|
|
185
|
+
action: "retry" | "skip";
|
|
186
|
+
};
|
|
187
|
+
type SessionRedriveResult = {
|
|
188
|
+
/** Whether the event was dead-lettered and is now resolved. */
|
|
189
|
+
redriven: boolean;
|
|
190
|
+
};
|
|
191
|
+
type SessionConsumeOptions = {
|
|
192
|
+
/**
|
|
193
|
+
* Run until the consumer has handled every event it takes through this
|
|
194
|
+
* index. Default: the session's head when the call starts. An index past
|
|
195
|
+
* the head counts as the head.
|
|
196
|
+
*/
|
|
197
|
+
through?: number;
|
|
198
|
+
/** Stops waiting: the call throws the signal's reason. */
|
|
199
|
+
signal?: AbortSignal;
|
|
200
|
+
};
|
|
201
|
+
type SessionConsumeResult = {
|
|
202
|
+
/** The consumer has handled every event it takes through this index. */
|
|
203
|
+
index: number;
|
|
204
|
+
};
|
|
205
|
+
/** A dead-lettered event, with what an operator needs to resolve it. */
|
|
206
|
+
type DeadLetter<D extends EventDefs> = ContractEvent<D> & {
|
|
207
|
+
/** The consumer this event is dead for; it may be done for others. */
|
|
208
|
+
consumer: string;
|
|
209
|
+
lane: string | null;
|
|
210
|
+
/** Durable dispatch claims, including claims abandoned by hard kills. */
|
|
211
|
+
attemptCount: number;
|
|
212
|
+
/**
|
|
213
|
+
* Failed attempts since the event was appended or last retried: caught
|
|
214
|
+
* consumer failures, and attempts that ended before they finished.
|
|
215
|
+
*/
|
|
216
|
+
failureCount: number;
|
|
217
|
+
/**
|
|
218
|
+
* The last error the consumer threw, stringified; null when every failed
|
|
219
|
+
* attempt ended before it finished.
|
|
220
|
+
*/
|
|
221
|
+
lastError: string | null;
|
|
222
|
+
failedAt: Date;
|
|
223
|
+
};
|
|
224
|
+
/** Dead-letter resolution; root sessions only. */
|
|
225
|
+
type SessionDeadLetters<D extends EventDefs> = {
|
|
226
|
+
/** The session's dead-lettered events, oldest first. */
|
|
227
|
+
deadLetters(): Promise<DeadLetter<D>[]>;
|
|
228
|
+
/**
|
|
229
|
+
* Atomically resolve one dead-lettered event, then wake the session like
|
|
230
|
+
* an append. Any other event is left alone and reports `redriven: false`.
|
|
231
|
+
*/
|
|
232
|
+
redrive(target: {
|
|
233
|
+
consumer: string;
|
|
234
|
+
index: number;
|
|
235
|
+
}, options: SessionRedriveOptions): Promise<SessionRedriveResult>;
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* The presence members of a session — intersected in via
|
|
239
|
+
* `WithPresence`, so they exist exactly when the contract declares
|
|
240
|
+
* presence fields. Intersected before the base members so the widened
|
|
241
|
+
* `stream` overload is tried first: the literal `presence: true`
|
|
242
|
+
* selects it, everything else falls through to the events-only base.
|
|
243
|
+
*/
|
|
244
|
+
type SessionPresence<D extends EventDefs, P extends PresenceDefs> = {
|
|
245
|
+
/**
|
|
246
|
+
* The two-plane feed: one snapshot of the current pruned map first
|
|
247
|
+
* (per-field stamps exact), then presence patches interleaved with
|
|
248
|
+
* events.
|
|
249
|
+
*/
|
|
250
|
+
stream(opts: {
|
|
251
|
+
startAfter?: number;
|
|
252
|
+
presence: true;
|
|
253
|
+
}): AsyncIterable<ContractEvent<D> | SessionCleared | PresencePatch<P> | PresenceSnapshot<P>>;
|
|
254
|
+
/**
|
|
255
|
+
* Validate against the contract's presence schemas, then broadcast.
|
|
256
|
+
* Never an append: no log row, no dispatch, no scheduler arm. `at`
|
|
257
|
+
* is the sender's LWW stamp in epoch ms; omitted, receipt time
|
|
258
|
+
* stands in (single writer, so receipt order is sender order).
|
|
259
|
+
*/
|
|
260
|
+
setPresence(patch: {
|
|
261
|
+
participant: string;
|
|
262
|
+
values: PresencePatch<P>["values"];
|
|
263
|
+
seen?: number;
|
|
264
|
+
at?: number;
|
|
265
|
+
}): Promise<void>;
|
|
266
|
+
/** The current map, expired values pruned — a point-in-time read. */
|
|
267
|
+
presence(): Promise<PresenceMap<P>>;
|
|
268
|
+
};
|
|
269
|
+
/** A handle on one instance of the machine. Creating it does no I/O. */
|
|
270
|
+
type Session<D extends EventDefs, Append = SessionAppend<D>, P extends PresenceDefs = Record<never, never>, S = never> = WithPresence<P, SessionPresence<D, P>> & {
|
|
271
|
+
readonly id: string;
|
|
272
|
+
append: Append;
|
|
273
|
+
schedule: SessionSchedule<D>;
|
|
274
|
+
/**
|
|
275
|
+
* End the current lifetime: atomically append a clear marker, then
|
|
276
|
+
* delete the history below it. Indexes never restart.
|
|
277
|
+
*/
|
|
278
|
+
clear(options?: SessionClearOptions): Promise<SessionClearResult>;
|
|
279
|
+
history(options?: {
|
|
280
|
+
gte?: number;
|
|
281
|
+
lte?: number;
|
|
282
|
+
}): Promise<ContractEvent<D>[]>;
|
|
283
|
+
/**
|
|
284
|
+
* Run a consumer with a string lane on this session, here, until it has
|
|
285
|
+
* handled every event it takes through `through`. The server's own
|
|
286
|
+
* consumer shares its cursor with background work, so this waits for
|
|
287
|
+
* whichever invocation holds it. A consumer the server doesn't run is
|
|
288
|
+
* pulled only by `consume`, and keeps its place between calls.
|
|
289
|
+
*/
|
|
290
|
+
consume(consumer: Consumer<D>, options?: SessionConsumeOptions): Promise<SessionConsumeResult>;
|
|
291
|
+
state: {
|
|
292
|
+
<T>(reducer: Reducer<D, T, Record<never, never>>, options?: StateOptions): Promise<{
|
|
293
|
+
state: T;
|
|
294
|
+
index: number;
|
|
295
|
+
clearIndex?: number;
|
|
296
|
+
}>;
|
|
297
|
+
} & ([S] extends [never] ? unknown : {
|
|
298
|
+
(): Promise<{
|
|
299
|
+
state: S;
|
|
300
|
+
index: number;
|
|
301
|
+
clearIndex?: number;
|
|
302
|
+
}>;
|
|
303
|
+
});
|
|
304
|
+
/**
|
|
305
|
+
* A live feed of this session's events, starting after `startAfter`
|
|
306
|
+
* (exclusive). Server-side only. `server.fetch` exposes it over SSE.
|
|
307
|
+
* A clear arrives as a `SessionCleared` marker.
|
|
308
|
+
*/
|
|
309
|
+
stream(opts?: {
|
|
310
|
+
startAfter?: number;
|
|
311
|
+
}): AsyncIterable<ContractEvent<D> | SessionCleared>;
|
|
312
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* The public server shape scheduler consumers accept. It stays structural so
|
|
315
|
+
* servers of any contract mix in one route; A2's private server internals add
|
|
316
|
+
* delayed-append delivery without exposing an untyped append method here.
|
|
317
|
+
*/
|
|
318
|
+
type DrainableServer = {
|
|
319
|
+
readonly contract: {
|
|
320
|
+
readonly name: string;
|
|
321
|
+
};
|
|
322
|
+
drain(sessionId: string): Promise<{
|
|
323
|
+
settled: boolean;
|
|
324
|
+
}>;
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* The scheduler seam (a2-implementation.md §7, §9). `schedule` puts a
|
|
328
|
+
* versioned drain or delayed append task on durable infrastructure;
|
|
329
|
+
* `handler` returns the route the transport delivers to. Claim holders
|
|
330
|
+
* move the watchdog alongside their renewable execution window.
|
|
331
|
+
* Implementations ship as
|
|
332
|
+
* entry points (`experimental-a2/scheduler-vercel`); core never imports a
|
|
333
|
+
* transport.
|
|
334
|
+
*/
|
|
335
|
+
type A2Scheduler = {
|
|
336
|
+
schedule(task: SchedulerTask): Promise<void>;
|
|
337
|
+
handler(...servers: DrainableServer[]): (req: Request) => Promise<Response>;
|
|
338
|
+
};
|
|
339
|
+
type A2Server<D extends EventDefs, P extends PresenceDefs = Record<never, never>, R extends RegisteredReducer<D, P> | undefined = RegisteredReducer<D, P> | undefined> = {
|
|
340
|
+
/** The contract this server implements. */
|
|
341
|
+
readonly contract: Contract<D, P, R>;
|
|
342
|
+
readonly fetch: {
|
|
343
|
+
(request: Request): Promise<Response>;
|
|
344
|
+
(request: Request, options: ServerFetchOptions<D, P>): Promise<Response>;
|
|
345
|
+
};
|
|
346
|
+
session(id: string): Session<D, SessionAppend<D>, P, PublicState<R>> & SessionDeadLetters<D>;
|
|
347
|
+
/**
|
|
348
|
+
* Process every currently eligible event. `settled` means nothing
|
|
349
|
+
* actionable remains, including work blocked behind a dead letter.
|
|
350
|
+
*/
|
|
351
|
+
drain(sessionId: string): Promise<{
|
|
352
|
+
settled: boolean;
|
|
353
|
+
}>;
|
|
354
|
+
};
|
|
355
|
+
/**
|
|
356
|
+
* Which events fire `ctx.signal` while a consumer runs — the preemption
|
|
357
|
+
* channel for user cancellation. The array form matches by type; the
|
|
358
|
+
* object form takes per-type predicates for targeted cancellation
|
|
359
|
+
* (`(event, trigger) => event.payload.of === trigger.id`). Consumers
|
|
360
|
+
* without `abortOn` pay nothing. An aborted consumer should catch and
|
|
361
|
+
* return normally; throwing means "retry me".
|
|
362
|
+
*/
|
|
363
|
+
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: {
|
|
364
|
+
attempt: number;
|
|
365
|
+
}) => boolean); };
|
|
366
|
+
/** What a consumer's `run` returns: nothing, one event, or a batch. */
|
|
367
|
+
type ConsumerResult<D extends EventDefs> = Promise<void | AppendInput<D> | readonly AppendInput<D>[]>;
|
|
368
|
+
/** How `createServer` runs a consumer. Built by `consumer().run()`. */
|
|
369
|
+
type ConsumerSpec<D extends EventDefs> = {
|
|
370
|
+
readonly types: readonly (keyof D & string)[] | null;
|
|
371
|
+
readonly lane: ConsumerLane<D> | null;
|
|
372
|
+
readonly backfill: boolean;
|
|
373
|
+
readonly abortOn: AbortSpec<D, keyof D & string> | null;
|
|
374
|
+
readonly run: (ctx: ConsumerContext<D>) => ConsumerResult<D>;
|
|
375
|
+
};
|
|
376
|
+
/** A named reader of a session's log with its own durable cursors. */
|
|
377
|
+
type Consumer<D extends EventDefs> = {
|
|
378
|
+
readonly name: string;
|
|
379
|
+
readonly contract: {
|
|
380
|
+
readonly name: string;
|
|
381
|
+
};
|
|
382
|
+
readonly spec: ConsumerSpec<D>;
|
|
383
|
+
};
|
|
384
|
+
//#endregion
|
|
385
|
+
export { SessionAppend as a, SessionConsumeOptions as c, SessionSchedule as d, StateOptions as f, SchedulerTask as i, SessionConsumeResult as l, A2Server as n, SessionClearOptions as o, SessionCleared as p, Consumer as r, SessionClearResult as s, A2Scheduler as t, SessionDeadLetters as u };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as ownTeamId, n as discoveryIdentity, r as ownProjectId, t as oidcTokens } from "./tokens-
|
|
1
|
+
import { i as ownTeamId, n as discoveryIdentity, r as ownProjectId, t as oidcTokens } from "./tokens-DhuzKzAl.mjs";
|
|
2
2
|
export { discoveryIdentity, oidcTokens, ownProjectId, ownTeamId };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region ../../node_modules/.pnpm/experimental-a2@0.22.0_@upstash+qstash@2.12.0_@vercel+queue@0.7.0_ai@7.0.130_zod@4.6.5__52060f00b21aecfab049c27fa3abd2f9/node_modules/experimental-a2/dist/session-clear-wHd5GCpZ.js
|
|
2
|
+
var A2Error = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
/** e.g. the Standard Schema issues for INVALID_PAYLOAD */
|
|
5
|
+
details;
|
|
6
|
+
constructor(code, message, options) {
|
|
7
|
+
super(message, options && "cause" in options ? { cause: options.cause } : void 0);
|
|
8
|
+
this.name = "A2Error";
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.details = options?.details;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
/** A consumer write whose attempt no longer owns its triggering event. */
|
|
14
|
+
function supersededAttemptError(sessionId, cause) {
|
|
15
|
+
const of = cause.consumer === void 0 ? "" : ` for consumer '${cause.consumer}'`;
|
|
16
|
+
return new A2Error("SUPERSEDED_ATTEMPT", `attempt ${cause.attempt} no longer owns event ${cause.index}${of} in session '${sessionId}'`);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Wrap an arbitrary thrown value as STORE_UNAVAILABLE, preserving the
|
|
20
|
+
* original as `cause`. A2Errors pass through untouched — they already
|
|
21
|
+
* carry their own meaning.
|
|
22
|
+
*/
|
|
23
|
+
function asStoreUnavailable(err) {
|
|
24
|
+
if (err instanceof A2Error) return err;
|
|
25
|
+
return new A2Error("STORE_UNAVAILABLE", "the store backend failed", { cause: err });
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Throw from a consumer to reject retrying: the failure is adjudicated
|
|
29
|
+
* terminal immediately (dead-lettered on the first throw) instead of
|
|
30
|
+
* consuming the ten-failure retry budget. For deterministic failures —
|
|
31
|
+
* a guard that will refuse identically on every attempt — retrying is
|
|
32
|
+
* waste and dead-lettering is the honest outcome. Matched by
|
|
33
|
+
* `instanceof`, so subclasses carry domain meaning.
|
|
34
|
+
*/
|
|
35
|
+
var NonRetriableError = class extends Error {
|
|
36
|
+
constructor(message, options) {
|
|
37
|
+
super(message, options);
|
|
38
|
+
this.name = "NonRetriableError";
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/** Reserved type of the marker a clear appends. */
|
|
42
|
+
const CLEAR_EVENT_TYPE = "a2.cleared";
|
|
43
|
+
/** Accepts any stream item, including presence patches and snapshots. */
|
|
44
|
+
function isSessionCleared(item) {
|
|
45
|
+
return item.type === CLEAR_EVENT_TYPE;
|
|
46
|
+
}
|
|
47
|
+
function sessionClearedError(message) {
|
|
48
|
+
return new A2Error("SESSION_CLEARED", message);
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { isSessionCleared as a, asStoreUnavailable as i, CLEAR_EVENT_TYPE as n, sessionClearedError as o, NonRetriableError as r, supersededAttemptError as s, A2Error as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { c as externalMessageKey } from "./external-BV_cUncs.mjs";
|
|
1
2
|
import { n as setOwn } from "./own-OwgPWdmh.mjs";
|
|
2
|
-
import { r as
|
|
3
|
-
import { i as syncReads, n as project, r as projectSync, t as concernedMessageId } from "./project-CFiArraX.mjs";
|
|
3
|
+
import { i as syncReads, n as project, r as projectSync, t as concernedMessageId } from "./project-DMDST9kl.mjs";
|
|
4
4
|
//#region src/store/sql.ts
|
|
5
5
|
/** The projection's name in `board_positions`, and the A2 consumer that runs it. */
|
|
6
6
|
const TABLES_CONSUMER = "board-tables";
|