@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.
Files changed (130) hide show
  1. package/README.md +27 -27
  2. package/dist/{a2-C41hD8SF.mjs → a2-ChRLRupa.mjs} +969 -25
  3. package/dist/access.d.mts +1 -1
  4. package/dist/access.mjs +3 -3
  5. package/dist/{actors-DjMeZpnU.mjs → actors-BOamkEuz.mjs} +3 -73
  6. package/dist/attempts-CLG840Oj.mjs +20 -0
  7. package/dist/{auth-COzc09sn.mjs → auth-Drg9FiC2.mjs} +225 -2
  8. package/dist/backend-B-SJ7p6p.d.mts +680 -0
  9. package/dist/backend-a2/contract.d.mts +873 -2
  10. package/dist/backend-a2/contract.mjs +2 -2
  11. package/dist/backend-a2/scheduler-local.d.mts +1 -1
  12. package/dist/backend-a2/scheduler-local.mjs +1 -1
  13. package/dist/backend-a2/scheduler-qstash.d.mts +78 -1
  14. package/dist/backend-a2/scheduler-qstash.mjs +521 -1
  15. package/dist/backend-a2/scheduler-vercel.d.mts +37 -1
  16. package/dist/backend-a2/scheduler-vercel.mjs +203 -1
  17. package/dist/backend-a2/store-memory.d.mts +2 -2
  18. package/dist/backend-a2/store-memory.mjs +3 -3
  19. package/dist/backend-a2/store-postgres.d.mts +1 -1
  20. package/dist/backend-a2/store-postgres.mjs +2850 -2
  21. package/dist/backend-a2/store-redis-http.d.mts +1 -1
  22. package/dist/backend-a2/store-redis-http.mjs +490 -2
  23. package/dist/backend-a2/store-redis.d.mts +10 -2
  24. package/dist/backend-a2/store-redis.mjs +51 -2
  25. package/dist/backend-a2/store-sqlite.d.mts +1 -1
  26. package/dist/backend-a2/store-sqlite.mjs +3 -3
  27. package/dist/backend-a2.d.mts +2706 -3
  28. package/dist/backend-a2.mjs +1 -1
  29. package/dist/{backend-http-Bid7RIpC.d.mts → backend-http-7cNb8nJI.d.mts} +10 -3
  30. package/dist/{backend-http-0roEmjl0.mjs → backend-http-CMlL3yq3.mjs} +2 -2
  31. package/dist/{backend-http-BVRno-ca.mjs → backend-http-Ddzd5kTS.mjs} +32 -3
  32. package/dist/backend-http.d.mts +1 -1
  33. package/dist/backend-http.mjs +1 -1
  34. package/dist/backend-http.node.d.mts +1 -1
  35. package/dist/backend-http.node.mjs +1 -1
  36. package/dist/{chat-provider-XCnQlxq6.d.mts → chat-provider-DNJQyajS.d.mts} +16 -4
  37. package/dist/{chat-provider-jFSeyNmB.mjs → chat-provider-YHy-WbrB.mjs} +15 -9
  38. package/dist/cli.mjs +30 -10
  39. package/dist/{client-DGDPaN7U.mjs → client-BA-J7usH.mjs} +10 -2
  40. package/dist/{conformance-DRR23YNy.mjs → conformance-CT5EeHeC.mjs} +5 -2
  41. package/dist/conformance.d.mts +1 -1
  42. package/dist/conformance.mjs +1 -1
  43. package/dist/{engine-Bir5s8ts.mjs → engine-D0oBUBEK.mjs} +249 -163
  44. package/dist/events-CewD4kw7.mjs +75 -0
  45. package/dist/{exports-Dvc1o52I.mjs → exports-CgjfMrQ-.mjs} +35 -32
  46. package/dist/exports-ZsgjzEnM.d.mts +4 -0
  47. package/dist/external-BV_cUncs.mjs +151 -0
  48. package/dist/folds-CRYY14kc.d.mts +534 -0
  49. package/dist/{reducers-mUPFuFJV.mjs → folds-Dyjput8M.mjs} +6 -73
  50. package/dist/ids-C6AYo1bu.mjs +31 -0
  51. package/dist/index.d.mts +4 -4
  52. package/dist/{index.default-Bkg77Pxn.mjs → index.default-C5Cpz3sa.mjs} +1 -1
  53. package/dist/index.mjs +5 -5
  54. package/dist/index.node.d.mts +4 -4
  55. package/dist/index.node.mjs +3 -3
  56. package/dist/inspect/app.js +31 -31
  57. package/dist/inspect/engine.js +5 -5
  58. package/dist/internal-CvsrprnU-CRY89I-b.mjs +203 -0
  59. package/dist/{local-Cr_dSjvs.mjs → local-DhkrAqPP.mjs} +1 -1
  60. package/dist/mentions-CB6ShY4R.mjs +72 -0
  61. package/dist/{targets-yM5JBUgr.mjs → middleware-CqaCwucP.mjs} +1 -33
  62. package/dist/platform-B4TnJtWu-CwcTyKg2.mjs +32 -0
  63. package/dist/{project-CFiArraX.mjs → project-DMDST9kl.mjs} +1 -1
  64. package/dist/{provider-BGjz-mDa.d.mts → provider-B0b9Qxw4.d.mts} +170 -40
  65. package/dist/provider-B3DpYSDq.mjs +220 -0
  66. package/dist/redis-tables-DN9PfIDi.mjs +3897 -0
  67. package/dist/reducer-CYPHsSmd-BQIfozGi.d.mts +170 -0
  68. package/dist/reducer-CjmvZSAb-D_OSISmj.mjs +74 -0
  69. package/dist/{contract-CuJmlrhw.mjs → reducers-BFmIXilu.mjs} +260 -287
  70. package/dist/retryable-lazy-DZWmHpii-Bye-W8q7.mjs +19 -0
  71. package/dist/scheduler-task-X1SToDjP-BVoWuInI.mjs +69 -0
  72. package/dist/{serve-BsOOc-6_.mjs → serve-BGYw0uNL.mjs} +5 -5
  73. package/dist/{server-jwPY7_wi.mjs → server-DPxBSogx.mjs} +4 -4
  74. package/dist/server-DtFrWxi3-Boa6gdWO.mjs +3602 -0
  75. package/dist/server-qgez0Xny-D5mLfqFQ.d.mts +385 -0
  76. package/dist/{serving-BNbzc96L.mjs → serving-CNkgUPW1.mjs} +1 -1
  77. package/dist/session-clear-wHd5GCpZ-BnKSxReK.mjs +51 -0
  78. package/dist/{sql-DbiEnqM0.mjs → sql-U9WTxrwJ.mjs} +2 -2
  79. package/dist/{sqlite-db-Cbj03vmp.mjs → sqlite-db-Ds4majtT.mjs} +1 -1
  80. package/dist/store-D0MhBvg6-4Z2L0Kqd.d.mts +530 -0
  81. package/dist/store-N8PXxDAS-BWBgzBHp.mjs +5 -0
  82. package/dist/store-codec-DwrWlgQx-CYxGW0aD.mjs +61 -0
  83. package/dist/store-memory-Bas9Uq5C.mjs +872 -0
  84. package/dist/store-memory-ZLiZbH3R.mjs +2 -0
  85. package/dist/store-polling-BZt2Rf3D-BiEM6_HB.mjs +148 -0
  86. package/dist/store-presence-polling-JuAy2Ck2-CYpuK75X.mjs +109 -0
  87. package/dist/store-sqlite-BmwL3pUR.mjs +2 -0
  88. package/dist/store-sqlite-CxxPCcCT.mjs +1053 -0
  89. package/dist/stream-buffer-DrTyiIuo-BKy-vI14.mjs +53 -0
  90. package/dist/sync-github.d.mts +24 -17
  91. package/dist/sync-github.mjs +89 -22
  92. package/dist/sync-kapso.d.mts +15 -13
  93. package/dist/sync-kapso.mjs +17 -14
  94. package/dist/sync-linear.d.mts +219 -0
  95. package/dist/sync-linear.mjs +311 -0
  96. package/dist/sync-slack.d.mts +12 -17
  97. package/dist/sync-slack.mjs +54 -42
  98. package/dist/sync.chat.d.mts +1 -1
  99. package/dist/sync.chat.mjs +1 -1
  100. package/dist/sync.d.mts +3 -3
  101. package/dist/sync.mjs +5 -4
  102. package/dist/targets-C-wdR5wP.mjs +33 -0
  103. package/dist/{tokens-DKLn5P9B.mjs → tokens-DhuzKzAl.mjs} +1 -1
  104. package/dist/{types-BHCjTZdB.d.mts → types-8yq2VnKI.d.mts} +2 -2
  105. package/dist/{users-Dls7_ANV.mjs → users-yryHKFMo.mjs} +2 -2
  106. package/dist/{watch-spec-W0c7ypHJ.mjs → watchers-hash-RLtnSF-t.mjs} +233 -28
  107. package/docs/01-board/01-mounting.md +1 -1
  108. package/docs/02-sync/01-overview.md +72 -48
  109. package/docs/02-sync/02-functions.md +398 -0
  110. package/docs/02-sync/03-slack.md +30 -25
  111. package/docs/02-sync/04-github.md +62 -26
  112. package/docs/02-sync/05-whatsapp.md +23 -19
  113. package/docs/02-sync/06-providers.md +60 -27
  114. package/docs/02-sync/07-linear.md +129 -0
  115. package/docs/03-guides/04-triage.md +1 -1
  116. package/docs/04-reference/01-cli.md +26 -6
  117. package/docs/04-reference/02-board.md +18 -5
  118. package/docs/04-reference/03-http.md +5 -2
  119. package/docs/04-reference/05-conformance.md +1 -1
  120. package/docs/index.md +5 -10
  121. package/package.json +31 -6
  122. package/dist/a2-D24cvwpN.d.mts +0 -3359
  123. package/dist/access-CJU2-vaa.mjs +0 -226
  124. package/dist/attempts-Bxp9KgPf.mjs +0 -919
  125. package/dist/exports-DLiE7fLY.d.mts +0 -4
  126. package/dist/provider-CuewcDNZ.mjs +0 -205
  127. package/dist/redis-tables-B35vv4CZ.mjs +0 -842
  128. package/dist/reducers-B_vUGQRp.d.mts +0 -1172
  129. package/dist/watchers-hash-CLjsa6od.mjs +0 -225
  130. 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-DKLn5P9B.mjs";
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 externalMessageKey } from "./reducers-mUPFuFJV.mjs";
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";
@@ -1,4 +1,4 @@
1
- import { n as ddl } from "./sql-DbiEnqM0.mjs";
1
+ import { n as ddl } from "./sql-U9WTxrwJ.mjs";
2
2
  import { mkdirSync } from "node:fs";
3
3
  import { dirname, resolve } from "node:path";
4
4
  //#region src/store/sqlite-db.ts