@vercel/board 0.26.0 → 0.26.1

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 (29) hide show
  1. package/dist/{a2-Qzj0kCWU.mjs → a2-C4A4vr0M.mjs} +4 -4
  2. package/dist/{attempts-CLG840Oj.mjs → attempts-HXcskN1w.mjs} +1 -11
  3. package/dist/backend-a2.mjs +1 -1
  4. package/dist/{backend-http-BB0Gld6Q.mjs → backend-http-3IxGe13a.mjs} +18 -4
  5. package/dist/{backend-http-F0W6e36G.mjs → backend-http-CQWTNzym.mjs} +1 -1
  6. package/dist/backend-http.mjs +1 -1
  7. package/dist/backend-http.node.mjs +1 -1
  8. package/dist/{backend-vercel-DUWIcFi9.mjs → backend-vercel-BPyPi8Cv.mjs} +8 -3
  9. package/dist/{backend-vercel-CtB46vMQ.mjs → backend-vercel-l5465vyw.mjs} +3 -3
  10. package/dist/backend-vercel.mjs +1 -1
  11. package/dist/backend-vercel.node.mjs +1 -1
  12. package/dist/cli-embedded.mjs +1 -1
  13. package/dist/cli.mjs +2 -2
  14. package/dist/{engine-ROa7-IQY.mjs → engine-Bfe6pcXb.mjs} +2 -2
  15. package/dist/{exports-NFjBgIT2.mjs → exports-B-AeCbYw.mjs} +2 -2
  16. package/dist/{index.default-Boe7x-mK.mjs → index.default-CfAjbQrU.mjs} +1 -1
  17. package/dist/index.mjs +3 -3
  18. package/dist/index.node.mjs +1 -1
  19. package/dist/inspect/app.js +29 -29
  20. package/dist/inspect/engine.js +5 -5
  21. package/dist/{main-BuahKR16.mjs → main-DGyQ4gje.mjs} +9 -4
  22. package/dist/{serve-BbHEQk_Y.mjs → serve-BDLJebk7.mjs} +2 -2
  23. package/dist/{server-Bphio_82.mjs → server-BSXTDTOp.mjs} +3 -3
  24. package/dist/{ids-C6AYo1bu.mjs → wait-until-Dw4XrIDQ.mjs} +12 -1
  25. package/dist/{watchers-hash-BfDPW95j.mjs → watchers-hash-BTF_bMIN.mjs} +1 -1
  26. package/docs/01-board/06-watchers.md +4 -2
  27. package/docs/04-reference/01-cli.md +2 -1
  28. package/docs/04-reference/03-http.md +1 -1
  29. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
1
  import { n as DIRECT_UPLOAD_BYTES_MAX, r as IMPORT_BYTES_MAX, t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
2
2
  import { _ as RemoteWatcherId, b as actorKind, i as Attachment, x as platformAvatar } from "./schemas-Be08nyfW.mjs";
3
3
  import "./external-BV_cUncs.mjs";
4
- import { a as METHODS, d as VERSION, f as SYNC, n as compileWatcher, r as hasCriteria, t as canonicalWatchers } from "./watchers-hash-BfDPW95j.mjs";
4
+ import { a as METHODS, d as VERSION, f as SYNC, n as compileWatcher, r as hasCriteria, t as canonicalWatchers } from "./watchers-hash-BTF_bMIN.mjs";
5
5
  import { r as duration, t as BoardError } from "./client-D0Px7KzF.mjs";
6
- import { n as derivedId, r as isKeyIdOf } from "./ids-C6AYo1bu.mjs";
6
+ import { i as isKeyIdOf, r as derivedId, t as waitUntil } from "./wait-until-Dw4XrIDQ.mjs";
7
7
  import { a as forbidden, c as toErrorResponse, i as duplicateId, r as badRequest, s as notFound, t as HttpError } from "./errors-CusN4x2l.mjs";
8
8
  import { t as own } from "./own-OwgPWdmh.mjs";
9
9
  import { n as replaceMentions } from "./mentions-CB6ShY4R.mjs";
@@ -18,7 +18,7 @@ import { n as createServer, t as consumer } from "./server-DtFrWxi3-Boa6gdWO.mjs
18
18
  import { a as linkedTo, i as iso, n as foldMessages, o as personOf, t as foldActors } from "./folds-Dyjput8M.mjs";
19
19
  import { t as concernedMessageId } from "./project-DMDST9kl.mjs";
20
20
  import { t as TABLES_CONSUMER } from "./sql-U9WTxrwJ.mjs";
21
- import { n as waitUntil, t as afterRetry } from "./attempts-CLG840Oj.mjs";
21
+ import { t as afterRetry } from "./attempts-HXcskN1w.mjs";
22
22
  import { createHash, randomBytes } from "node:crypto";
23
23
  import { mkdir, readFile, writeFile } from "node:fs/promises";
24
24
  import { dirname, join } from "node:path";
@@ -2467,7 +2467,7 @@ function scheduleAt(value) {
2467
2467
  return index;
2468
2468
  }
2469
2469
  new AbortController().signal;
2470
- /** A wake-up only has to arrive: the board it wakes runs what it pulls before it answers. */
2470
+ /** A wake-up only has to arrive: the board it wakes answers once what it pulls has run, or after 2 seconds while it keeps going. */
2471
2471
  const WAKE_TIMEOUT_MS = 5e3;
2472
2472
  /**
2473
2473
  * `idempotentId`'s shape, a UUIDv8: the IDs the board derives for its own writes (schedule
@@ -1,13 +1,3 @@
1
- //#region src/server/wait-until.ts
2
- /**
3
- * Keeps `task` running after the response, where the platform offers it: Vercel's request context, as A2
4
- * reads it too. Elsewhere it runs on in the process.
5
- */
6
- function waitUntil(task) {
7
- try {
8
- Reflect.get(globalThis, Symbol.for("@vercel/request-context"))?.get?.()?.waitUntil?.(task);
9
- } catch {}
10
- }
11
1
  /**
12
2
  * Whether a run comes after a retry from a dead letter. A2 keeps counting
13
3
  * `ctx.attempt` across one, and no earlier run sees an attempt past A2_TRIES:
@@ -17,4 +7,4 @@ function waitUntil(task) {
17
7
  */
18
8
  const afterRetry = (attempt) => attempt > 10;
19
9
  //#endregion
20
- export { waitUntil as n, afterRetry as t };
10
+ export { afterRetry as t };
@@ -1,2 +1,2 @@
1
- import { n as fsBlob, r as memoryBlob, t as a2 } from "./a2-Qzj0kCWU.mjs";
1
+ import { n as fsBlob, r as memoryBlob, t as a2 } from "./a2-C4A4vr0M.mjs";
2
2
  export { a2, fsBlob, memoryBlob };
@@ -1,14 +1,16 @@
1
1
  import "./files-SniSmeEr.mjs";
2
2
  import "./schemas-Be08nyfW.mjs";
3
- import { K as routes, O as RegisterBody, a as METHODS, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-BfDPW95j.mjs";
3
+ import { K as routes, O as RegisterBody, a as METHODS, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-BTF_bMIN.mjs";
4
4
  import { n as createBoardClient, t as BoardError } from "./client-D0Px7KzF.mjs";
5
- import { a as sha256, i as keyId, n as derivedId, t as DERIVED_ID } from "./ids-C6AYo1bu.mjs";
5
+ import { a as keyId, n as DERIVED_ID, o as sha256, r as derivedId, t as waitUntil } from "./wait-until-Dw4XrIDQ.mjs";
6
6
  import { a as forbidden, o as json, t as HttpError } from "./errors-CusN4x2l.mjs";
7
7
  //#region src/server/registrant.ts
8
8
  /** Registering again this soon after the same registration only repeats it. */
9
9
  const REGISTER_EVERY_MS = 1e4;
10
10
  /** How long one wake-up runs matches before it leaves the rest to the next. */
11
11
  const DRAIN_MS = 24e4;
12
+ /** How long a wake-up waits for what it pulled to run before it answers: under the 3 seconds Vercel's API gives it. */
13
+ const WAKE_ANSWER_MS = 2e3;
12
14
  /** A pull with nothing to hand out holds this long, when the board pulls on its own. */
13
15
  const POLL_WAIT_S = 25;
14
16
  const describe$1 = (error) => ((error instanceof Error ? error.message : String(error)) || "unknown error").slice(0, 500);
@@ -142,8 +144,20 @@ function registrant(options) {
142
144
  path: "/wake",
143
145
  async handle(request) {
144
146
  started ??= Promise.resolve();
145
- if (request.headers.get("x-board-watchers") !== await options.hash()) await register(wakeable(bound().url())).catch(rethrow);
146
- return json({ ran: await drain().catch(rethrow) });
147
+ const stale = request.headers.get("x-board-watchers") !== await options.hash();
148
+ const running = (async () => {
149
+ if (stale) await register(wakeable(bound().url()));
150
+ return drain();
151
+ })();
152
+ waitUntil(running.catch((error) => console.error(`[board] couldn't run what woke it:`, describe$1(error))));
153
+ let timer;
154
+ const waited = new Promise((resolve) => timer = setTimeout(() => resolve(null), WAKE_ANSWER_MS));
155
+ try {
156
+ const ran = await Promise.race([running.catch(rethrow), waited]);
157
+ return ran === null ? new Response(null, { status: 202 }) : json({ ran });
158
+ } finally {
159
+ clearTimeout(timer);
160
+ }
147
161
  }
148
162
  }, {
149
163
  method: "POST",
@@ -1,4 +1,4 @@
1
- import { r as createHttp } from "./backend-http-BB0Gld6Q.mjs";
1
+ import { r as createHttp } from "./backend-http-3IxGe13a.mjs";
2
2
  import { n as connect, r as environmentProfile, t as boardUrl } from "./node-Ybi9E6bO.mjs";
3
3
  //#region src/backend-http/index.ts
4
4
  const environment = {
@@ -1,2 +1,2 @@
1
- import { t as http } from "./index.default-Boe7x-mK.mjs";
1
+ import { t as http } from "./index.default-CfAjbQrU.mjs";
2
2
  export { http };
@@ -1,2 +1,2 @@
1
- import { t as http } from "./backend-http-F0W6e36G.mjs";
1
+ import { t as http } from "./backend-http-CQWTNzym.mjs";
2
2
  export { http };
@@ -1,6 +1,6 @@
1
1
  import { t as HttpError } from "./errors-CusN4x2l.mjs";
2
2
  import { c as vercelLogin, l as vercelProjectFile, o as loginHanded, r as environmentProfile } from "./node-Ybi9E6bO.mjs";
3
- import { t as createVercel } from "./backend-vercel-CtB46vMQ.mjs";
3
+ import { t as createVercel } from "./backend-vercel-l5465vyw.mjs";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import { decodeJwt } from "jose";
6
6
  import { getVercelOidcToken } from "@vercel/oidc";
@@ -38,10 +38,15 @@ function handTeam(resolve) {
38
38
  }
39
39
  /**
40
40
  * The team: the one a CLI that runs board's hands it, `VERCEL_ORG_ID`, the one the deployment's OIDC
41
- * token names, or the linked project's (the nearest `.vercel/project.json`).
41
+ * token names, or the linked project's (the nearest `.vercel/project.json`). A handed one that
42
+ * throws fails the request with what it threw: the app's own words, not an internal error.
42
43
  */
43
44
  async function team() {
44
- if (handed) return handed();
45
+ if (handed) try {
46
+ return await handed();
47
+ } catch (error) {
48
+ throw new HttpError(502, "no_team", error instanceof Error ? error.message : String(error), { origin: "handle" });
49
+ }
45
50
  if (process.env.VERCEL_ORG_ID) return process.env.VERCEL_ORG_ID;
46
51
  if (!process.env.VERCEL_TOKEN && deployed()) try {
47
52
  const owner = decodeJwt(await getVercelOidcToken()).owner_id;
@@ -1,8 +1,8 @@
1
1
  import { _ as RemoteWatcherId } from "./schemas-Be08nyfW.mjs";
2
- import { O as RegisterBody, a as METHODS, d as VERSION, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-BfDPW95j.mjs";
3
- import { a as sha256, n as derivedId } from "./ids-C6AYo1bu.mjs";
2
+ import { O as RegisterBody, a as METHODS, d as VERSION, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-BTF_bMIN.mjs";
3
+ import { o as sha256, r as derivedId } from "./wait-until-Dw4XrIDQ.mjs";
4
4
  import { a as forbidden, o as json, s as notFound, t as HttpError } from "./errors-CusN4x2l.mjs";
5
- import { a as wakePath, i as registrant, n as callerProfile, t as PROJECTS_OWN } from "./backend-http-BB0Gld6Q.mjs";
5
+ import { a as wakePath, i as registrant, n as callerProfile, t as PROJECTS_OWN } from "./backend-http-3IxGe13a.mjs";
6
6
  //#region src/server/backend-vercel.ts
7
7
  const PROFILE = /^[A-Za-z][A-Za-z0-9-]{0,31}$/;
8
8
  const SESSION = /^[A-Za-z0-9_.:-]{1,128}$/;
@@ -1,4 +1,4 @@
1
- import { t as createVercel } from "./backend-vercel-CtB46vMQ.mjs";
1
+ import { t as createVercel } from "./backend-vercel-l5465vyw.mjs";
2
2
  //#region src/backend-vercel/index.default.ts
3
3
  /**
4
4
  * Your team's board, in Vercel's API. Outside Node there's no environment to find credentials or
@@ -1,2 +1,2 @@
1
- import { n as handTeam, r as vercel, t as credentialSource } from "./backend-vercel-DUWIcFi9.mjs";
1
+ import { n as handTeam, r as vercel, t as credentialSource } from "./backend-vercel-BPyPi8Cv.mjs";
2
2
  export { credentialSource, handTeam, vercel };
@@ -1,4 +1,4 @@
1
- import { a as commandLine, c as failureLines, i as mainWith, l as formatFailure, n as commandWord, o as exitCode, r as main, s as failureDocument, t as Failed } from "./main-BuahKR16.mjs";
1
+ import { a as commandLine, c as failureLines, i as mainWith, l as formatFailure, n as commandWord, o as exitCode, r as main, s as failureDocument, t as Failed } from "./main-DGyQ4gje.mjs";
2
2
  //#region src/cli/embedded.ts
3
3
  /**
4
4
  * Board's CLI as `appName` names it in help, usage, and errors (`vercel board`). With no board
package/dist/cli.mjs CHANGED
@@ -3,7 +3,7 @@ import { t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
3
3
  import "./schemas-Be08nyfW.mjs";
4
4
  import { a as option } from "./commands-nEG47RM_.mjs";
5
5
  import { s as projectDir } from "./node-Ybi9E6bO.mjs";
6
- import { r as main, u as who } from "./main-BuahKR16.mjs";
6
+ import { r as main, u as who } from "./main-DGyQ4gje.mjs";
7
7
  import { randomBytes, timingSafeEqual } from "node:crypto";
8
8
  import { appendFile, readFile } from "node:fs/promises";
9
9
  import { join } from "node:path";
@@ -661,7 +661,7 @@ const local = {
661
661
  if (args.length > 0) throw usage("serve takes no arguments: pass its port with --port, and its directory with --dir.");
662
662
  const port = portFlag();
663
663
  const root = projectDir();
664
- const { localHandle, serveLocal } = await import("./serve-BbHEQk_Y.mjs");
664
+ const { localHandle, serveLocal } = await import("./serve-BDLJebk7.mjs");
665
665
  const handle = flags.handle ?? process.env.BOARD_HANDLE;
666
666
  const local = await serveLocal({
667
667
  dir: flags.dir ?? join(root, ".board"),
@@ -2,11 +2,11 @@ import { a as typeOf, i as fileSize, r as IMPORT_BYTES_MAX, t as ATTACHMENT_BYTE
2
2
  import { C as toStorable, c as ChannelPath, m as MESSAGE_TEXT_MAX } from "./schemas-Be08nyfW.mjs";
3
3
  import { c as externalMessageKey, l as isThreadTarget, s as channelOf } from "./external-BV_cUncs.mjs";
4
4
  import { t as canonicalEmoji } from "./emoji-CTLpvH-A.mjs";
5
- import { n as derivedId } from "./ids-C6AYo1bu.mjs";
5
+ import { r as derivedId, t as waitUntil } from "./wait-until-Dw4XrIDQ.mjs";
6
6
  import { r as badRequest, s as notFound, t as HttpError } from "./errors-CusN4x2l.mjs";
7
7
  import { n as replaceMentions } from "./mentions-CB6ShY4R.mjs";
8
8
  import { t as DroppedError } from "./middleware-ChKM1zuu.mjs";
9
- import { n as waitUntil, t as afterRetry } from "./attempts-CLG840Oj.mjs";
9
+ import { t as afterRetry } from "./attempts-HXcskN1w.mjs";
10
10
  import { a as channelMissing, i as UnreadableError, n as ResolvedTarget, o as routesFor, t as ReceivedEvent } from "./provider-poIkXapd.mjs";
11
11
  import { a as immutable, n as SyncOverrides } from "./events-CewD4kw7.mjs";
12
12
  import { t as displayText } from "./bots-CGkO76qH.mjs";
@@ -1,8 +1,8 @@
1
1
  import { t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
2
2
  import "./schemas-Be08nyfW.mjs";
3
- import { A as SchedulesQuery, B as SyncReceiptBody, C as MatchesQuery, D as Ref, E as ReactBody, F as SyncBody, G as UploadStartBody, H as SyncUnlinkBody, I as SyncCodeBody, L as SyncCopiesQuery, M as SourceJoinBody, N as SourceReadQuery, O as RegisterBody, P as SyncAccountBody, R as SyncFindQuery, S as LinkedQuery, T as PostBody, U as ThreadsQuery, V as SyncRootsQuery, W as TypingBody, _ as InboxAckBody, a as METHODS, b as InboxQuery, c as queryObject, d as VERSION, f as SYNC, g as IdentityUnlinkBody, h as EventsQuery, j as SignInQuery, k as ScheduleBody, l as readCapped, m as EditBody, o as createRouter, p as AckBody, s as openapi, u as readJson, v as InboxNextQuery, w as MessagesQuery, x as LabelBody, y as InboxPushBody, z as SyncImportBody } from "./watchers-hash-BfDPW95j.mjs";
3
+ import { A as SchedulesQuery, B as SyncReceiptBody, C as MatchesQuery, D as Ref, E as ReactBody, F as SyncBody, G as UploadStartBody, H as SyncUnlinkBody, I as SyncCodeBody, L as SyncCopiesQuery, M as SourceJoinBody, N as SourceReadQuery, O as RegisterBody, P as SyncAccountBody, R as SyncFindQuery, S as LinkedQuery, T as PostBody, U as ThreadsQuery, V as SyncRootsQuery, W as TypingBody, _ as InboxAckBody, a as METHODS, b as InboxQuery, c as queryObject, d as VERSION, f as SYNC, g as IdentityUnlinkBody, h as EventsQuery, j as SignInQuery, k as ScheduleBody, l as readCapped, m as EditBody, o as createRouter, p as AckBody, s as openapi, u as readJson, v as InboxNextQuery, w as MessagesQuery, x as LabelBody, y as InboxPushBody, z as SyncImportBody } from "./watchers-hash-BTF_bMIN.mjs";
4
4
  import { n as createBoardClient, t as BoardError } from "./client-D0Px7KzF.mjs";
5
- import { n as derivedId } from "./ids-C6AYo1bu.mjs";
5
+ import { r as derivedId } from "./wait-until-Dw4XrIDQ.mjs";
6
6
  import { a as forbidden, c as toErrorResponse, l as unauthorized, n as RejectedError, o as json, r as badRequest, s as notFound, t as HttpError } from "./errors-CusN4x2l.mjs";
7
7
  import { d as issuersOf, g as verifiesTokens, l as hostPrincipal, o as createAuthority, s as fromTokens } from "./auth-lTkOgvcE.mjs";
8
8
  import { i as resolveActor, r as claimsOf, t as KNOWN_AGENTS } from "./actors-BLXVp4oZ.mjs";
@@ -1,4 +1,4 @@
1
- import { r as createHttp } from "./backend-http-BB0Gld6Q.mjs";
1
+ import { r as createHttp } from "./backend-http-3IxGe13a.mjs";
2
2
  //#region src/backend-http/index.default.ts
3
3
  /**
4
4
  * The board at `url`, which keeps the log. Outside Node there's no environment to find it or a
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { r as duration, t as BoardError } from "./client-D0Px7KzF.mjs";
2
2
  import { t as HttpError } from "./errors-CusN4x2l.mjs";
3
- import { t as http } from "./index.default-Boe7x-mK.mjs";
4
- import { t as createBoard } from "./exports-NFjBgIT2.mjs";
3
+ import { t as http } from "./index.default-CfAjbQrU.mjs";
4
+ import { t as createBoard } from "./exports-B-AeCbYw.mjs";
5
5
  import { t as DroppedError } from "./middleware-ChKM1zuu.mjs";
6
6
  //#region src/server/index.default.ts
7
7
  /**
@@ -11,7 +11,7 @@ import { t as DroppedError } from "./middleware-ChKM1zuu.mjs";
11
11
  function board(options = {}) {
12
12
  return createBoard(options, {
13
13
  http: () => http(),
14
- sync: () => import("./engine-ROa7-IQY.mjs"),
14
+ sync: () => import("./engine-Bfe6pcXb.mjs"),
15
15
  serving: null
16
16
  });
17
17
  }
@@ -1,5 +1,5 @@
1
1
  import { r as duration, t as BoardError } from "./client-D0Px7KzF.mjs";
2
2
  import { t as HttpError } from "./errors-CusN4x2l.mjs";
3
3
  import { t as DroppedError } from "./middleware-ChKM1zuu.mjs";
4
- import { t as board } from "./server-Bphio_82.mjs";
4
+ import { t as board } from "./server-BSXTDTOp.mjs";
5
5
  export { BoardError, DroppedError, HttpError, board, duration };