@oeave/bakery3 0.0.0-stage → 0.2.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 (86) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +562 -2
  3. package/dist/animation-B1h0Ryvj.d.ts +97 -0
  4. package/dist/bake/index.d.ts +369 -0
  5. package/dist/bake/index.js +9 -0
  6. package/dist/bake/index.js.map +1 -0
  7. package/dist/bake-DZ-CJR6f.d.ts +1364 -0
  8. package/dist/catalog/index.d.ts +100 -0
  9. package/dist/catalog/index.js +154 -0
  10. package/dist/catalog/index.js.map +1 -0
  11. package/dist/catalog.gen-BM-aNf7n.d.ts +733 -0
  12. package/dist/chunk-3G5QL4F4.js +145 -0
  13. package/dist/chunk-3G5QL4F4.js.map +1 -0
  14. package/dist/chunk-4E5VV4QY.js +12 -0
  15. package/dist/chunk-4E5VV4QY.js.map +1 -0
  16. package/dist/chunk-62M6XXNX.js +142 -0
  17. package/dist/chunk-62M6XXNX.js.map +1 -0
  18. package/dist/chunk-6FYI6AJM.js +1157 -0
  19. package/dist/chunk-6FYI6AJM.js.map +1 -0
  20. package/dist/chunk-6NYR73Y7.js +832 -0
  21. package/dist/chunk-6NYR73Y7.js.map +1 -0
  22. package/dist/chunk-APWUCEEB.js +118 -0
  23. package/dist/chunk-APWUCEEB.js.map +1 -0
  24. package/dist/chunk-HNMSWQU7.js +1709 -0
  25. package/dist/chunk-HNMSWQU7.js.map +1 -0
  26. package/dist/chunk-JFYUDERE.js +1412 -0
  27. package/dist/chunk-JFYUDERE.js.map +1 -0
  28. package/dist/chunk-KNUAOILG.js +551 -0
  29. package/dist/chunk-KNUAOILG.js.map +1 -0
  30. package/dist/chunk-KZLVTSBI.js +191 -0
  31. package/dist/chunk-KZLVTSBI.js.map +1 -0
  32. package/dist/chunk-LAKXC4WR.js +2028 -0
  33. package/dist/chunk-LAKXC4WR.js.map +1 -0
  34. package/dist/chunk-NXBAZGNB.js +1107 -0
  35. package/dist/chunk-NXBAZGNB.js.map +1 -0
  36. package/dist/chunk-QRCT5UGZ.js +3286 -0
  37. package/dist/chunk-QRCT5UGZ.js.map +1 -0
  38. package/dist/chunk-S4AJTLLN.js +23 -0
  39. package/dist/chunk-S4AJTLLN.js.map +1 -0
  40. package/dist/chunk-UWBP7B54.js +92 -0
  41. package/dist/chunk-UWBP7B54.js.map +1 -0
  42. package/dist/chunk-XK35ANPJ.js +346 -0
  43. package/dist/chunk-XK35ANPJ.js.map +1 -0
  44. package/dist/chunk-Z7IYVH22.js +4781 -0
  45. package/dist/chunk-Z7IYVH22.js.map +1 -0
  46. package/dist/chunk-ZEBVAIJJ.js +156 -0
  47. package/dist/chunk-ZEBVAIJJ.js.map +1 -0
  48. package/dist/devtools/index.d.ts +536 -0
  49. package/dist/devtools/index.js +15 -0
  50. package/dist/devtools/index.js.map +1 -0
  51. package/dist/environments/index.d.ts +93 -0
  52. package/dist/environments/index.js +382 -0
  53. package/dist/environments/index.js.map +1 -0
  54. package/dist/hotspots/index.d.ts +111 -0
  55. package/dist/hotspots/index.js +285 -0
  56. package/dist/hotspots/index.js.map +1 -0
  57. package/dist/index.d.ts +975 -0
  58. package/dist/index.js +15 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/node/index.cjs +5240 -0
  61. package/dist/node/index.cjs.map +1 -0
  62. package/dist/node/index.d.cts +4927 -0
  63. package/dist/node/index.d.ts +597 -0
  64. package/dist/node/index.js +1328 -0
  65. package/dist/node/index.js.map +1 -0
  66. package/dist/prepare-BtjY4G3q.d.ts +112 -0
  67. package/dist/presets/index.d.ts +562 -0
  68. package/dist/presets/index.js +14 -0
  69. package/dist/presets/index.js.map +1 -0
  70. package/dist/r3f/index.d.ts +159 -0
  71. package/dist/r3f/index.js +592 -0
  72. package/dist/r3f/index.js.map +1 -0
  73. package/dist/room-FS26KAPQ.js +9 -0
  74. package/dist/room-FS26KAPQ.js.map +1 -0
  75. package/dist/rooms.gen-DItzBR9k.d.ts +1462 -0
  76. package/dist/session-VCIQEO26.js +9 -0
  77. package/dist/session-VCIQEO26.js.map +1 -0
  78. package/dist/shapes/index.d.ts +222 -0
  79. package/dist/shapes/index.js +836 -0
  80. package/dist/shapes/index.js.map +1 -0
  81. package/dist/testRun-20OARnQr.d.ts +1139 -0
  82. package/dist/timeline-ChwgD7bT.d.ts +470 -0
  83. package/dist/tsl/index.d.ts +165 -0
  84. package/dist/tsl/index.js +310 -0
  85. package/dist/tsl/index.js.map +1 -0
  86. package/package.json +170 -4
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/warn.ts","../src/client.ts","../src/protocol/batch.ts","../src/pollFailures.ts","../src/batch.ts","../src/testRun.ts"],"names":["message"],"mappings":"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","file":"chunk-NXBAZGNB.js","sourcesContent":["/**\n * The \"your API key is in the page\" warning.\n *\n * A secret key never belongs in browser JavaScript: every visitor can read\n * it from the network tab. But pasting a key into an app and pressing the\n * button is how a first render happens, so the key works, and the console\n * says exactly what is wrong with it and what to do before shipping.\n *\n * The warning fires once per key, not once per render, so a provider that\n * re-mounts on every hot reload cannot bury it.\n */\n\nconst warned = new Set<string>();\n\n/** Browser tokens are minted for a browser. Only the rest are a leak. */\nconst BROWSER_TOKEN_PREFIX = 'bk_pt_';\n\n/**\n * Is this a client someone else can read the bundle of?\n *\n * A DOM, a worker, or React Native: all three ship the key to a device the\n * developer does not control. Node, Deno and Bun are the server case this\n * warning points people back towards, so they stay quiet.\n */\nexport function isBrowserLike(scope: typeof globalThis = globalThis): boolean {\n const global = scope as {\n window?: { document?: unknown };\n document?: unknown;\n navigator?: { product?: string };\n importScripts?: unknown;\n process?: { versions?: { node?: string } };\n };\n\n // A bundler shim can define `window` in Node. The real thing has a document.\n if (typeof global.window === 'object' && global.window !== null) {\n if (global.window.document !== undefined) return true;\n }\n if (typeof global.importScripts === 'function') return true; // web worker\n if (global.navigator?.product === 'ReactNative') return true;\n return false;\n}\n\nfunction isProductionBuild(scope: typeof globalThis = globalThis): boolean {\n // Bundlers inline this. `false` only means \"cannot tell\", the common case\n // in a dev server, so it never weakens the warning.\n const env = (\n scope as { process?: { env?: Record<string, string | undefined> } }\n ).process?.env;\n return env?.NODE_ENV === 'production';\n}\n\n/**\n * Enough to recognize which key, useless as one: the first twelve characters,\n * exactly what the Keys page lists each key by (`prefix` in\n * apps/web/convex/keys.ts), so the developer can find the one to rotate. Six\n * characters of a long random secret are no head start on it.\n */\nexport function redact(key: string): string {\n const prefix = /^bk_[a-z]{2}_/.exec(key)?.[0] ?? '';\n const secret = key.slice(prefix.length);\n // A short secret would be half shown by its first six. Show none of it.\n return secret.length < 16 ? `${prefix}…` : `${key.slice(0, 12)}…`;\n}\n\nexport type KeyWarningContext = {\n /** Where the key was handed in, so the fix names the right thing. */\n source: 'apiKey' | 'node';\n scope?: typeof globalThis;\n log?: (message: string) => void;\n};\n\n/**\n * Warn if a long-lived key is being used from a client environment.\n *\n * Returns whether it warned, so a caller can check that a server stays quiet.\n */\nexport function warnIfKeyIsExposed(\n key: string,\n { source, scope = globalThis, log }: KeyWarningContext,\n): boolean {\n if (!key || key.startsWith(BROWSER_TOKEN_PREFIX)) return false;\n if (!isBrowserLike(scope)) return false;\n if (warned.has(key)) return false;\n warned.add(key);\n\n const warn =\n log ??\n (typeof console !== 'undefined' && typeof console.warn === 'function'\n ? (message: string) => console.warn(message)\n : () => {});\n\n warn(message(key, source, isProductionBuild(scope)));\n return true;\n}\n\nfunction message(\n key: string,\n source: KeyWarningContext['source'],\n production: boolean,\n): string {\n const lines = [\n production\n ? `[bakery3] A secret API key is in a PRODUCTION browser bundle: ${redact(key)}`\n : `[bakery3] Your secret API key is in browser JavaScript: ${redact(key)}`,\n '',\n 'Anyone who opens the network tab on this page can read it, and a bk_sk_ key',\n 'can start renders, read every render on the account, and reach billing. It',\n 'cannot be origin-restricted, spend-capped or revoked without replacing it.',\n '',\n production\n ? 'This build has NODE_ENV=production. Do not ship it. Mint a browser token'\n : 'Fine while you are testing. Before you deploy, mint a browser token',\n 'on your own server instead:',\n '',\n ' // app/api/bakery3-token/route.ts (server only)',\n \" import { Bakery3Server } from '@oeave/bakery3/node';\",\n ' const bakery3 = new Bakery3Server(process.env.BAKERY3_SECRET_KEY!);',\n ' export const POST = async () =>',\n ' Response.json(await bakery3.tokens.create({',\n ' expiresInSeconds: 300, maxCost: 1,',\n \" allowedOrigins: ['https://shop.example.com'],\",\n ' }));',\n '',\n ];\n\n if (source === 'apiKey') {\n lines.push(\n ' // browser: token instead of apiKey',\n ' createBakery3({',\n \" token: () => fetch('/api/bakery3-token', { method: 'POST' }).then((r) => r.json()),\",\n ' });',\n '',\n );\n } else {\n lines.push(\n '@oeave/bakery3/node is a server module. Importing it into a component that',\n 'runs in the browser puts the key in the bundle. Keep it behind a route',\n \"handler, a server action, or a file with 'use server'.\",\n '',\n );\n }\n\n lines.push('https://bakery3.com/docs/auth');\n return lines.join('\\n');\n}\n\n/** Clears the once-per-key memory. For tests. */\nexport function resetKeyWarnings(): void {\n warned.clear();\n}\n","/**\n * The HTTP client for the control plane.\n *\n * Small on purpose: a handful of endpoints, one auth header, one error shape.\n * The interesting work happens in the browser (capture, hashing) and on the\n * render workers; this is the thin part in between.\n *\n * The one piece of policy it carries is the retry: a 429 or a 503 is the\n * control plane saying \"not now\", and it is answered with a bounded, jittered\n * wait rather than an error the developer has to write a loop around. Only\n * requests that are safe to repeat are repeated (see `RequestOptions.retry`).\n *\n * In production no secret key reaches this file. The browser holds a\n * short-lived, project-scoped, origin-restricted, spend-capped token minted by\n * the developer's own server. `token` is a function rather than a string so\n * it can be fetched again when one expires, which for a five-minute token in\n * a long configurator session is routine.\n *\n * `apiKey` is the other door, and it is open on purpose: a key works from the\n * browser so the first render is one paste away, and `warnIfKeyIsExposed`\n * says once, with the replacement code, why it must not stay there.\n *\n * Neither is needed to construct a client: `check()` and `inspect()` never\n * touch the network, and a React tree whose environment variable is unset\n * must still mount. A missing credential is refused at the first request,\n * with what to pass instead.\n */\n\nimport type {\n AssetCheckRequest,\n AssetImportRequest,\n AssetImportResponse,\n AssetCheckResponse,\n BakeRecord,\n BakeSettings,\n BakeSpec,\n BatchAddRequest,\n BatchAddResponse,\n BatchExportLine,\n BatchOpenRequest,\n BatchRecord,\n CostEstimate,\n RenderRecord,\n RenderSpec,\n RenderState,\n} from './protocol/index.js';\nimport {\n Bakery3Error,\n RenderBudgetExceeded,\n type Bakery3ErrorCode,\n type BudgetedKind,\n} from './errors.js';\nimport { SDK_VERSION } from './version.js';\nimport { isBrowserLike, redact, warnIfKeyIsExposed } from './warn.js';\n\nexport const DEFAULT_BASE_URL = 'https://api.bakery3.com';\n\n/**\n * The header that names the SDK's version on every request, so the API can\n * warn about, or refuse, an SDK too old to read its answers.\n */\nexport const SDK_VERSION_HEADER = 'bakery3-sdk';\n\n/**\n * Whether a browser sends `SDK_VERSION_HEADER`. A custom header has to be on\n * the API's CORS `access-control-allow-headers` list (`cors()` in\n * apps/web/convex/http.ts), or the preflight fails and every request from a\n * page fails with it. It is on that list, so this is only the switch to turn\n * it off from if that ever changes.\n */\nconst VERSION_HEADER_IN_BROWSERS = true;\n\n/** What `/v1/estimate` prices: a still or a clip, or a bake. */\nexport type EstimateRequest =\n | (Pick<RenderSpec, 'quality' | 'output' | 'advanced'> & {\n /** Triangle count and texture footprint, so an estimate can be given\n * before anything has been uploaded. `room` says the scene stands in a\n * preset room, which the renderer builds around it; `enclosure` and\n * `objects` say how walled in and how full it is from the camera\n * (`SceneComplexity`), which is what makes an interior cost more. */\n scene?: {\n triangles?: number;\n textureBytes?: number;\n fog?: boolean;\n room?: boolean;\n enclosure?: number;\n objects?: number;\n };\n /** Frames in a clip; the control plane prices a video per frame. */\n frames?: number;\n })\n | {\n /** The settings a bake request would carry. Texels (objects × size²)\n * are what the control plane prices. */\n bake: Pick<\n BakeSettings,\n | 'quality'\n | 'textureSize'\n | 'include'\n | 'sizes'\n | 'atlas'\n | 'deliverGlb'\n | 'simplify'\n | 'shadow'\n > & {\n /** The scene is a room interior: a ray that misses keeps going,\n * which is most of what such a bake costs. */\n enclosed?: boolean;\n };\n /** Triangles in the objects the bake would cover: what the unwrap runs\n * over, and priced separately from the scene's own count. */\n bakedTriangles?: number;\n scene?: { triangles?: number; textureBytes?: number; fog?: boolean };\n };\n\n/** A browser token: the string, or the JSON `tokens.create()` answers with. */\nexport type MintedToken = string | { token: string; expiresAt?: number };\n\nexport type TokenProvider = () => MintedToken | Promise<MintedToken>;\n\n/**\n * One of the two, never both. Neither is allowed too, for a client that only\n * checks scenes; its first request is refused with what to pass.\n *\n * The `?: never` arms turn passing both into a type error at the call site\n * rather than a runtime throw later: the two are different integrations, and\n * a codebase carrying both is one that has not finished moving off the key.\n */\nexport type ClientAuth =\n | {\n /** Mints a browser token, usually from your own `/api/bakery3-token`. */\n token: TokenProvider;\n apiKey?: never;\n }\n | {\n /**\n * A `bk_sk_` key used directly, for local testing, a Node script, or a\n * server-rendered call.\n *\n * From a browser this ships the key to every visitor. The SDK allows it\n * so the first render is one paste away, warns about it in the console,\n * and expects `token` by the time you deploy.\n *\n * `undefined` (an environment variable that is not set) is accepted\n * here and refused at the first request, with that said.\n */\n apiKey: string | undefined;\n token?: never;\n }\n | { token?: undefined; apiKey?: undefined };\n\n/**\n * How a 429 or a 503 is waited out. Bounded: after `maxTries` the error is\n * the developer's. The defaults are the SDK's; a test shortens the delays.\n */\nexport type RetryPolicy = {\n /** Attempts in total, the first included. Default 5. */\n maxTries?: number;\n /** The first wait, before jitter and doubling. Default 500 ms. */\n baseDelayMs?: number;\n /** No single wait is longer than this, `Retry-After` included. Default 30 s. */\n maxDelayMs?: number;\n};\n\nexport type ClientOptions = ClientAuth & {\n baseUrl?: string;\n fetch?: typeof fetch;\n retry?: RetryPolicy;\n};\n\n/** Per-request knobs, for the client's own methods. */\nexport type RequestOptions = {\n /**\n * Whether a 429/503 may be answered by sending the request again.\n *\n * Every GET is. A POST is only when repeating it cannot do a second thing:\n * a batch page (its items carry keys), a batch action, a render that\n * carries an `idempotencyKey`. `POST /v1/renders` without one is not: a\n * second copy would be a second charge, which no amount of backoff is\n * worth.\n */\n retry?: boolean;\n /** Cuts a long-poll short. */\n signal?: AbortSignal;\n};\n\n/** `GET /v1/batches/:id/items`: the render record plus the item's key. */\nexport type BatchItemRecord = RenderRecord & { key: string };\n\nexport type BatchItemsPage = {\n items: BatchItemRecord[];\n cursor: string | null;\n};\n\nexport type BatchAction = 'close' | 'pause' | 'resume' | 'cancel' | 'retry';\n\nconst DEFAULT_RETRY: Required<RetryPolicy> = {\n maxTries: 5,\n baseDelayMs: 500,\n maxDelayMs: 30_000,\n};\n\n/** The two creates whose body may be a charge. Anything else is safe to repeat. */\nconst CHARGING_ROUTES = new Set(['/v1/renders', '/v1/bakes']);\n\n/** How many ids a client remembers the creating token of. A long session\n * forgets its oldest first; a forgotten one is read with the current token. */\nconst MAX_OWNERS = 1000;\n\nconst AUTH_DOCS = 'https://bakery3.com/docs/auth';\nconst TOKEN_ROUTE_DOCS = 'https://bakery3.com/docs/auth#the-token-endpoint';\nconst KEYS_URL = 'https://bakery3.com/keys';\n\n/** What a row was created as, for the message when it can no longer be read. */\ntype OwnedKind = 'render' | 'bake' | 'batch';\ntype Owner = `${OwnedKind}:${string}`;\n\n/** The credential a client has, decided once at construction. */\ntype Auth =\n | { kind: 'token'; provider: TokenProvider }\n | { kind: 'key'; key: string }\n /** No usable credential. Refused at the first request, not at construction. */\n | { kind: 'missing'; refusal: () => Bakery3Error };\n\ntype SendOptions = RequestOptions & {\n /** The row this request reads or acts on, whose creating token it uses. */\n owner?: Owner;\n};\n\nexport class Bakery3Client {\n private readonly baseUrl: string;\n private readonly auth: Auth;\n /**\n * The fetch this client sends with: the one passed in `options.fetch`, or\n * the global. Uploads and bundle reads use it too, so a test, a proxy or a\n * runtime with its own fetch sees every request the SDK makes.\n */\n readonly fetch: typeof fetch;\n /** Cached until it expires. Re-minting per render would add a round trip to\n * the developer's own server on the critical path of every click. */\n private cached: { token: string; expiresAt: number } | null = null;\n /** One token fetch at a time. React's StrictMode mounts twice, and two\n * renders at once both find the cache empty: they share this one. */\n private minting: Promise<string> | null = null;\n /**\n * The browser token each render, bake and batch was created with, by id.\n *\n * A token can only read the rows it created. Once it has spent its\n * allowance or expired, the API still lets it read and cancel those rows\n * (for 24 hours past expiry) but not create more, and a freshly minted\n * token cannot read them at all. So a job polls with the token that\n * started it, whatever the local cache thinks of that token's expiry.\n */\n private readonly owners = new Map<Owner, string>();\n private readonly retry: Required<RetryPolicy>;\n private readonly sendVersion: boolean;\n\n constructor(options: ClientOptions = {}) {\n const given = (options ?? {}) as { token?: unknown; apiKey?: unknown };\n const { token, apiKey } = given;\n\n if (token && apiKey) {\n throw new Bakery3Error({\n code: 'InvalidRequest',\n message: 'Pass either token or apiKey, not both.',\n why: 'They are two different integrations, and the SDK will not guess which one you meant.',\n fix: 'Keep `token` for anything you deploy; `apiKey` is for local testing only.',\n docs: AUTH_DOCS,\n });\n }\n\n this.auth = authOf(token, apiKey, 'apiKey' in given);\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n this.fetch = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.retry = { ...DEFAULT_RETRY, ...options.retry };\n this.sendVersion = VERSION_HEADER_IN_BROWSERS || !isBrowserLike();\n\n if (this.auth.kind === 'key')\n warnIfKeyIsExposed(this.auth.key, { source: 'apiKey' });\n }\n\n /**\n * Why this client cannot make a request, or null when it can. The same\n * error its first request would throw, for a panel or a status line that\n * wants to say so before anyone presses Render.\n */\n credentialError(): Bakery3Error | null {\n return this.auth.kind === 'missing' ? this.auth.refusal() : null;\n }\n\n async token(force = false): Promise<string> {\n const auth = this.auth;\n // A key handed in directly is the credential. There is nothing to cache,\n // nothing to refresh, and a 401 on one means the key is wrong.\n if (auth.kind === 'key') return auth.key;\n if (auth.kind === 'missing') throw auth.refusal();\n\n // 10s of slack: a token that expires while the request is in flight is\n // indistinguishable from a bad one at the far end.\n if (!force && this.cached && this.cached.expiresAt - 10_000 > Date.now()) {\n return this.cached.token;\n }\n this.minting ??= this.mint(auth.provider).finally(() => {\n this.minting = null;\n });\n return this.minting;\n }\n\n private async mint(provider: TokenProvider): Promise<string> {\n let result: unknown;\n try {\n result = await provider();\n } catch (cause) {\n throw providerThrew(cause);\n }\n const { token, expiresAt } = readMinted(result);\n this.cached = {\n token,\n expiresAt:\n expiresAt ??\n // Unknown expiry: hold it for a minute rather than for the session,\n // so a stale one self-heals without a failed render to prompt it.\n Date.now() + 60_000,\n };\n return token;\n }\n\n async checkAssets(body: AssetCheckRequest): Promise<AssetCheckResponse> {\n return this.post<AssetCheckResponse>('/v1/assets/check', body);\n }\n\n /**\n * `POST /v1/assets/import`: have the service fetch a public URL into the\n * project's assets. Secret key only. Safe to repeat: the same bytes are the\n * same asset, and an unchanged URL is answered without a download.\n */\n async importAsset(body: AssetImportRequest): Promise<AssetImportResponse> {\n return this.post<AssetImportResponse>('/v1/assets/import', body);\n }\n\n async estimate(body: EstimateRequest): Promise<CostEstimate> {\n return this.post<CostEstimate>('/v1/estimate', body);\n }\n\n async createRender(body: RenderSpec): Promise<RenderRecord> {\n // Retried only under a key: without one a second POST is a second render.\n const { value, credential } = await this.call<RenderRecord>(\n 'POST',\n '/v1/renders',\n body,\n { retry: Boolean(body.idempotencyKey) },\n );\n this.remember('render', value.id, credential);\n return value;\n }\n\n /**\n * A render's record, with fresh signed URLs for its result and preview.\n * Read with the token that created it, when this client created it.\n */\n async getRender(\n id: string,\n options: { signal?: AbortSignal } = {},\n ): Promise<RenderRecord> {\n return this.read<RenderRecord>('GET', `/v1/renders/${segment(id)}`, {\n owner: `render:${id}`,\n signal: options.signal,\n });\n }\n\n async cancelRender(id: string): Promise<RenderRecord> {\n return this.read<RenderRecord>(\n 'POST',\n `/v1/renders/${segment(id)}/cancel`,\n { owner: `render:${id}` },\n {},\n );\n }\n\n /**\n * `POST /v1/renders/:id/retry`: one more attempt for a dead-lettered render.\n * Answers 201 with a new render linked to the old one, or 409 when the\n * render is not dead-lettered. Not repeated on a 429/503: it creates a\n * render, and a duplicate would be a duplicate charge.\n */\n async retryRender(id: string): Promise<RenderRecord> {\n const { value, credential } = await this.call<RenderRecord>(\n 'POST',\n `/v1/renders/${segment(id)}/retry`,\n {},\n { retry: false, owner: `render:${id}` },\n );\n this.remember('render', value.id, credential);\n return value;\n }\n\n async createBake(body: BakeSpec): Promise<BakeRecord> {\n const { value, credential } = await this.call<BakeRecord>(\n 'POST',\n '/v1/bakes',\n body,\n { retry: Boolean(body.idempotencyKey) },\n );\n this.remember('bake', value.id, credential);\n return value;\n }\n\n async getBake(\n id: string,\n options: { signal?: AbortSignal } = {},\n ): Promise<BakeRecord> {\n return this.read<BakeRecord>('GET', `/v1/bakes/${segment(id)}`, {\n owner: `bake:${id}`,\n signal: options.signal,\n });\n }\n\n async cancelBake(id: string): Promise<BakeRecord> {\n return this.read<BakeRecord>(\n 'POST',\n `/v1/bakes/${segment(id)}/cancel`,\n { owner: `bake:${id}` },\n {},\n );\n }\n\n // -------------------------------------------------------------------------\n // Batches\n // -------------------------------------------------------------------------\n\n /** `POST /v1/batches`. The key is the idempotency key: the same key\n * re-opens the same batch (200) while it is not terminal. */\n async openBatch(body: BatchOpenRequest): Promise<BatchRecord> {\n const { value, credential } = await this.call<BatchRecord>(\n 'POST',\n '/v1/batches',\n body,\n {},\n );\n this.remember('batch', value.id, credential);\n return value;\n }\n\n /**\n * `GET /v1/batches/:id`. With `wait`, long-polls for up to that many\n * seconds (at most 25) until the counts change: the one poll a batch needs.\n */\n async getBatch(\n id: string,\n options: { wait?: number; signal?: AbortSignal } = {},\n ): Promise<BatchRecord> {\n const wait =\n options.wait === undefined\n ? undefined\n : Math.min(25, Math.max(0, options.wait));\n const suffix = wait ? `?wait=${wait}` : '';\n return this.read<BatchRecord>(\n 'GET',\n `/v1/batches/${segment(id)}${suffix}`,\n {\n owner: `batch:${id}`,\n signal: options.signal,\n },\n );\n }\n\n /**\n * `POST /v1/batches/:id/items`: one page, at most `BATCH_PAGE_SIZE`.\n *\n * Every item carries its own key, so the page is safe to send twice: the\n * second copy adopts what the first admitted. A refusal of the whole page\n * (402 InsufficientBalance / BatchBudgetExceeded, 409 BatchClosed) throws;\n * a problem with one item comes back inside `items[i].error` with a 200.\n */\n async addBatchItems(\n id: string,\n body: BatchAddRequest,\n ): Promise<BatchAddResponse> {\n return this.read<BatchAddResponse>(\n 'POST',\n `/v1/batches/${segment(id)}/items`,\n { owner: `batch:${id}` },\n body,\n );\n }\n\n /** `GET /v1/batches/:id/items?state=&cursor=&limit=`. */\n async listBatchItems(\n id: string,\n options: { state?: RenderState; cursor?: string; limit?: number } = {},\n ): Promise<BatchItemsPage> {\n const query = new URLSearchParams();\n if (options.state) query.set('state', options.state);\n if (options.cursor) query.set('cursor', options.cursor);\n if (options.limit) query.set('limit', String(options.limit));\n const suffix = query.toString() ? `?${query}` : '';\n return this.read<BatchItemsPage>(\n 'GET',\n `/v1/batches/${segment(id)}/items${suffix}`,\n { owner: `batch:${id}` },\n );\n }\n\n /**\n * `GET /v1/batches/:id/export`: the ledger as NDJSON, one line per item,\n * yielded as it streams so a ten-thousand-item batch is never one string.\n */\n async *exportBatch(id: string): AsyncIterable<BatchExportLine> {\n const { response } = await this.send(\n 'GET',\n `/v1/batches/${segment(id)}/export`,\n undefined,\n { retry: true, owner: `batch:${id}` },\n );\n yield* ndjson<BatchExportLine>(response);\n }\n\n /** `POST /v1/batches/:id/{close,pause,resume,cancel,retry}`. Every one is a\n * state transition the control plane treats idempotently, so all repeat. */\n async batchAction(id: string, action: BatchAction): Promise<BatchRecord> {\n return this.read<BatchRecord>(\n 'POST',\n `/v1/batches/${segment(id)}/${action}`,\n { owner: `batch:${id}` },\n {},\n );\n }\n\n private post<T>(\n path: string,\n body: unknown,\n options?: RequestOptions,\n ): Promise<T> {\n return this.request<T>('POST', path, body, options);\n }\n\n /** A request about a row this client may have created, with its token. */\n private async read<T>(\n method: string,\n path: string,\n options: SendOptions,\n body?: unknown,\n ): Promise<T> {\n return (await this.call<T>(method, path, body, options)).value;\n }\n\n /** Remember which token created a row, so the row is read with it. */\n private remember(kind: OwnedKind, id: string, credential: string): void {\n // A key reads everything in its project, so there is nothing to pin.\n if (this.auth.kind !== 'token' || !id) return;\n const owner: Owner = `${kind}:${id}`;\n this.owners.delete(owner);\n this.owners.set(owner, credential);\n if (this.owners.size > MAX_OWNERS) {\n const oldest = this.owners.keys().next().value;\n if (oldest !== undefined) this.owners.delete(oldest);\n }\n }\n\n /**\n * One authenticated JSON request, with the 401 re-mint and the 429/503\n * backoff. Public for the server SDK, which shares the transport; the\n * typed methods above are the API.\n */\n async request<T>(\n method: string,\n path: string,\n body?: unknown,\n options: RequestOptions = {},\n ): Promise<T> {\n return (await this.call<T>(method, path, body, options)).value;\n }\n\n /** A JSON request, and the credential that got the answer. */\n private async call<T>(\n method: string,\n path: string,\n body: unknown,\n options: SendOptions,\n ): Promise<{ value: T; credential: string }> {\n const { response, credential, url } = await this.send(\n method,\n path,\n body,\n options,\n );\n if (response.status === 204) return { value: undefined as T, credential };\n // Read as text and parsed here, so a 200 that is not JSON (a baseUrl\n // that points at a web app, which answers every path with its HTML)\n // says so instead of throwing \"Unexpected token '<'\".\n const text = await response.text();\n if (!text.trim()) return { value: undefined as T, credential };\n try {\n return { value: JSON.parse(text) as T, credential };\n } catch {\n throw notOurs(response.status, url, undefined, text, this.baseUrl);\n }\n }\n\n private async send(\n method: string,\n path: string,\n body: unknown,\n options: SendOptions,\n ): Promise<{ response: Response; credential: string; url: string }> {\n const retry = options.retry ?? isSafeToRepeat(method, path);\n const maxTries = retry ? this.retry.maxTries : 1;\n const url = `${this.baseUrl}${path}`;\n const pinned = options.owner ? this.owners.get(options.owner) : undefined;\n // Outside the fetch's try on purpose. A token failure is an auth error\n // with its own code, fix and docs link; inside, it would become a\n // retryable NetworkError, which a job's poll loop waits out for minutes.\n let credential = pinned ?? (await this.token());\n let reminted = false;\n let leftPin = false;\n\n for (let attempt = 1; ; attempt++) {\n const response = await this.fetchOnce(\n method,\n url,\n body,\n credential,\n options.signal,\n );\n\n if (response.ok) {\n // The current token could read it after all: read with that from now.\n if (leftPin && options.owner) {\n const [kind, ...rest] = options.owner.split(':');\n this.remember(kind as OwnedKind, rest.join(':'), credential);\n }\n return { response, credential, url };\n }\n\n // One retry with a freshly minted token. A five-minute browser token\n // expiring mid-session is the expected case, not an exception. A static\n // key has nothing to re-mint, so retrying it would only turn one clear\n // 401 into two. Does not count as an attempt.\n if (response.status === 401 && !reminted && this.auth.kind === 'token') {\n await response.body?.cancel().catch(() => {});\n reminted = true;\n leftPin = pinned !== undefined;\n // The token that created the row was refused: the current one, or a\n // new one when the current one IS the refused one.\n credential = await this.token(\n !pinned || this.cached?.token === credential,\n );\n continue;\n }\n\n // The creating token is gone and the current one is a stranger to the\n // row: a token reads only what it created, so the API says 404.\n if (leftPin && response.status === 404 && options.owner) {\n await response.body?.cancel().catch(() => {});\n throw lostOwner(options.owner);\n }\n\n if (\n response.status === 401 &&\n this.auth.kind === 'key' &&\n this.auth.key.startsWith('bk_pt_')\n ) {\n await response.body?.cancel().catch(() => {});\n throw browserTokenAsKey();\n }\n\n // \"Not now\": the account is over its rate (429) or the control plane is\n // shedding load (503). Nothing about the request is wrong, so the same\n // bytes go again after a jittered wait, for a request that is safe to\n // repeat, and only so many times. Any other 4xx is a verdict.\n if (\n (response.status === 429 || response.status === 503) &&\n attempt < maxTries\n ) {\n await response.body?.cancel().catch(() => {});\n await sleep(\n this.delayFor(attempt, response.headers.get('retry-after')),\n options.signal,\n );\n continue;\n }\n\n throw await toError(response, url, path, this.baseUrl);\n }\n }\n\n private async fetchOnce(\n method: string,\n url: string,\n body: unknown,\n credential: string,\n signal: AbortSignal | undefined,\n ): Promise<Response> {\n try {\n return await this.fetch(url, {\n method,\n headers: {\n authorization: `Bearer ${credential}`,\n ...(this.sendVersion ? { [SDK_VERSION_HEADER]: SDK_VERSION } : {}),\n ...(body === undefined ? {} : { 'content-type': 'application/json' }),\n },\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n ...(signal ? { signal } : {}),\n });\n } catch (error) {\n if (signal?.aborted) throw error;\n throw new Bakery3Error({\n code: 'NetworkError',\n message: `Could not reach the Bakery3 API: ${\n error instanceof Error ? error.message : String(error)\n }`,\n fix: 'Check the browser network tab. If you set a custom baseUrl, confirm it allows your origin.',\n retryable: true,\n });\n }\n }\n\n /**\n * Exponential with full jitter, or the server's own `Retry-After` when it\n * sent one: a server that says \"in 3 s\" knows more than a formula does.\n * Both are capped, so a header naming next Tuesday does not hang a page.\n */\n private delayFor(attempt: number, retryAfter: string | null): number {\n const { baseDelayMs, maxDelayMs } = this.retry;\n const advised = parseRetryAfter(retryAfter);\n if (advised !== null) return Math.min(maxDelayMs, advised);\n const ceiling = Math.min(maxDelayMs, baseDelayMs * 2 ** (attempt - 1));\n return Math.random() * ceiling;\n }\n}\n\n/** An id as one path segment: an id with a slash in it must not reach another route. */\nfunction segment(id: string): string {\n return encodeURIComponent(id);\n}\n\n// ---------------------------------------------------------------------------\n// Credentials\n// ---------------------------------------------------------------------------\n\n/**\n * What the constructor was given, as one of three cases. A missing, empty or\n * placeholder credential is not an error yet: a client that only checks a\n * scene never needs one.\n */\nfunction authOf(token: unknown, apiKey: unknown, keyNamed: boolean): Auth {\n if (token !== undefined && token !== null) {\n if (typeof token === 'function')\n return { kind: 'token', provider: token as TokenProvider };\n return { kind: 'missing', refusal: tokenNotAFunction };\n }\n if (typeof apiKey === 'string' && apiKey.trim()) {\n const key = apiKey.trim();\n if (isPlaceholder(key))\n return { kind: 'missing', refusal: () => placeholderKey(key) };\n return { kind: 'key', key };\n }\n if (keyNamed || apiKey !== undefined)\n return { kind: 'missing', refusal: emptyKey };\n return { kind: 'missing', refusal: noCredentials };\n}\n\n/** The `bk_sk_...` of a README, pasted as it is. */\nfunction isPlaceholder(key: string): boolean {\n return key.includes('...') || key.includes('…');\n}\n\nfunction noCredentials(): Bakery3Error {\n return new Bakery3Error({\n code: 'Unauthorized',\n message: `No API key or token. Create a key at ${KEYS_URL} (sign up there first if you have no account).`,\n why: '`apiKey` is a secret key (bk_sk_) you pass directly, for testing and for servers. `token` is a function that fetches a short-lived browser token from your own server, which is what you deploy, because it keeps the key out of the page.',\n fix: \"While testing: createBakery3({ apiKey: 'bk_sk_...' }). Before you deploy: createBakery3({ token: getToken }).\",\n docs: AUTH_DOCS,\n });\n}\n\nfunction emptyKey(): Bakery3Error {\n return new Bakery3Error({\n code: 'Unauthorized',\n message:\n 'apiKey is empty. Check that the environment variable holding your key is set.',\n why: \"createBakery3({ apiKey }) was given undefined or an empty string, which is what an environment variable that is not set reads as. In a browser bundle, only variables with your framework's public prefix (NEXT_PUBLIC_, VITE_) are set.\",\n fix: `Set the variable and restart the dev server. You can copy a key from ${KEYS_URL}.`,\n docs: AUTH_DOCS,\n });\n}\n\nfunction placeholderKey(key: string): Bakery3Error {\n return new Bakery3Error({\n code: 'Unauthorized',\n message: `Replace the placeholder with your key from ${KEYS_URL}.`,\n why: `apiKey is ${redact(key)}, which looks like the example from the docs rather than a real key.`,\n fix: `Copy a secret key (bk_sk_) from ${KEYS_URL} into apiKey while testing, and switch to token before you deploy.`,\n docs: AUTH_DOCS,\n });\n}\n\nfunction tokenNotAFunction(): Bakery3Error {\n return new Bakery3Error({\n code: 'Unauthorized',\n message:\n 'token must be a function that fetches a browser token, not the token itself.',\n why: 'Browser tokens expire after minutes, so the SDK calls your function again for a new one when it needs to.',\n fix: \"createBakery3({ token: () => fetch('/api/bakery3-token', { method: 'POST' }).then((r) => r.json()) })\",\n docs: TOKEN_ROUTE_DOCS,\n });\n}\n\nfunction browserTokenAsKey(): Bakery3Error {\n return new Bakery3Error({\n code: 'TokenExpired',\n message:\n 'apiKey holds a browser token (bk_pt_), and the API refused it. It has most likely expired.',\n why: 'Browser tokens last minutes. Passed as apiKey, the SDK has no way to fetch a new one when it runs out.',\n fix: \"Pass it as token instead, as a function that fetches a fresh one: createBakery3({ token: () => fetch('/api/bakery3-token', { method: 'POST' }).then((r) => r.json()) }).\",\n docs: TOKEN_ROUTE_DOCS,\n });\n}\n\nfunction lostOwner(owner: Owner): Bakery3Error {\n const kind = owner.slice(0, owner.indexOf(':')) as OwnedKind;\n const started = kind === 'batch' ? 'opened' : 'started';\n return new Bakery3Error({\n code: 'TokenExpired',\n message: `This ${kind} was ${started} with a browser token that can no longer read it. Mint tokens with a longer expiresInSeconds, or read the ${kind} from your server with the secret key.`,\n why: `A browser token can only read the ${kind}s it ${started}. That token was refused, and a new token cannot read a ${kind} it did not start.`,\n fix: 'Pass a longer expiresInSeconds to tokens.create() on your server, or read it there with new Bakery3Server(process.env.BAKERY3_SECRET_KEY!).',\n docs: AUTH_DOCS,\n });\n}\n\n/** The provider rejected. The developer's own endpoint, not ours. */\nfunction providerThrew(cause: unknown): Bakery3Error {\n const said = cause instanceof Error ? cause.message : String(cause);\n // `r.json()` on an HTML page: a 404 for a route that is not where the\n // fetch says, or a 500 from a route that threw. A verdict, not a blink.\n if (\n cause instanceof SyntaxError ||\n (cause as { name?: unknown } | null)?.name === 'SyntaxError'\n ) {\n return new Bakery3Error({\n code: 'Unauthorized',\n message:\n 'Your token endpoint did not return JSON. It probably answered 404 or 500 with an HTML page.',\n why: `Reading its answer as JSON failed: ${said}`,\n fix: 'Open your token route in the network tab. It must answer 200 with the JSON from tokens.create(). On a 500, check your server log: BAKERY3_SECRET_KEY may be unset.',\n docs: TOKEN_ROUTE_DOCS,\n });\n }\n // Retryable, because a token route that blinks mid-render should not lose\n // the render; named, because \"could not reach the Bakery3 API\" would point\n // at the wrong network tab entry.\n return new Bakery3Error({\n code: 'Unauthorized',\n message: `The token provider threw: ${said}`,\n why: 'createBakery3({ token }) calls your function for a browser token before each request that needs one, and it rejected.',\n fix: 'Check your /api/bakery3-token route in the network tab: it should answer 200 with the JSON from tokens.create().',\n docs: TOKEN_ROUTE_DOCS,\n retryable: true,\n });\n}\n\n/** The token out of whatever the provider resolved to, or an error that says what it was instead. */\nfunction readMinted(result: unknown): { token: string; expiresAt?: number } {\n if (isFetchResponse(result)) {\n const status = result.ok ? '' : ` (it answered ${result.status})`;\n throw new Bakery3Error({\n code: 'Unauthorized',\n message: `Your token function returned a fetch Response, not the token${status}. Add .then((r) => r.json()).`,\n why: 'createBakery3({ token }) needs the token itself: a string, or the JSON from tokens.create().',\n fix: \"token: () => fetch('/api/bakery3-token', { method: 'POST' }).then((r) => r.json())\",\n docs: TOKEN_ROUTE_DOCS,\n });\n }\n if (typeof result === 'string' && result) return { token: result };\n if (isRecord(result) && typeof result.token === 'string' && result.token) {\n return {\n token: result.token,\n ...(typeof result.expiresAt === 'number' && result.expiresAt > 0\n ? { expiresAt: result.expiresAt }\n : {}),\n };\n }\n const reported = isRecord(result) ? errorText(result) : undefined;\n if (reported) {\n throw new Bakery3Error({\n code: 'Unauthorized',\n message: `Your token endpoint answered with an error instead of a token: ${reported}`,\n why: 'createBakery3({ token }) needs { token } from your route, and the JSON it got has an error in its place.',\n fix: 'Check your server log for the request to your token route. BAKERY3_SECRET_KEY may be unset or wrong.',\n docs: TOKEN_ROUTE_DOCS,\n });\n }\n throw new Bakery3Error({\n code: 'Unauthorized',\n message: 'The token provider returned nothing.',\n why: 'createBakery3({ token }) must resolve to a string, or to { token }.',\n fix: 'Check that your /api/bakery3-token route returns the JSON from tokens.create().',\n docs: TOKEN_ROUTE_DOCS,\n });\n}\n\n/** Duck-typed, because a polyfilled or cross-realm Response fails `instanceof`. */\nfunction isFetchResponse(value: unknown): value is Response {\n if (typeof Response !== 'undefined' && value instanceof Response) return true;\n return (\n isRecord(value) &&\n typeof value.json === 'function' &&\n typeof value.status === 'number' &&\n 'headers' in value\n );\n}\n\n/** `{ error: 'text' }`, `{ error: { message } }`, or `{ message }`. */\nfunction errorText(body: Record<string, unknown>): string | undefined {\n const error = body.error;\n if (typeof error === 'string' && error) return error;\n if (isRecord(error)) {\n const message = typeof error.message === 'string' ? error.message : '';\n const code = typeof error.code === 'string' ? error.code : '';\n if (message || code)\n return code && message ? `${code}: ${message}` : message || code;\n return snippet(JSON.stringify(error));\n }\n if (typeof body.message === 'string' && body.message) return body.message;\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n// ---------------------------------------------------------------------------\n// Transport helpers\n// ---------------------------------------------------------------------------\n\n/** A request whose repeat cannot do a second thing. GETs always; a POST unless\n * it is one of the two creates that may charge (those opt in per body). */\nfunction isSafeToRepeat(method: string, path: string): boolean {\n if (method === 'GET' || method === 'HEAD') return true;\n return !CHARGING_ROUTES.has(path.split('?')[0]!);\n}\n\n/** Seconds, or an HTTP date; anything else is ignored. Never negative. */\nexport function parseRetryAfter(\n header: string | null,\n now = Date.now(),\n): number | null {\n if (!header) return null;\n const trimmed = header.trim();\n if (/^\\d+$/.test(trimmed)) return Number(trimmed) * 1000;\n const date = Date.parse(trimmed);\n if (Number.isNaN(date)) return null;\n return Math.max(0, date - now);\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) return reject(signal.reason);\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n function onAbort() {\n clearTimeout(timer);\n reject(signal!.reason);\n }\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\n/**\n * One JSON document per line, yielded as the bytes arrive. A response with\n * no stream (a test's `Response`, an old runtime) falls back to its text.\n */\nasync function* ndjson<T>(response: Response): AsyncIterable<T> {\n const decoder = new TextDecoder();\n let buffer = '';\n const emit = function* (chunk: string, flush = false) {\n buffer += chunk;\n const lines = buffer.split('\\n');\n buffer = flush ? '' : (lines.pop() ?? '');\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed) yield JSON.parse(trimmed) as T;\n }\n };\n\n if (!response.body) {\n yield* emit(await response.text(), true);\n return;\n }\n const reader = response.body.getReader();\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n yield* emit(decoder.decode(value, { stream: true }));\n }\n yield* emit(decoder.decode(), true);\n}\n\n// ---------------------------------------------------------------------------\n// Errors from a response\n// ---------------------------------------------------------------------------\n\n/**\n * A refusal, as a `Bakery3Error` with its four lines intact.\n *\n * The control plane answers with the protocol's structured error shape. A\n * proxy, a gateway or a wrong `baseUrl` does not, and that is said rather\n * than shown as a bare status. The body is read once, as text: reading it as\n * JSON first and as text after fails, because a body can only be read once.\n */\nasync function toError(\n response: Response,\n url: string,\n path: string,\n baseUrl: string,\n): Promise<Bakery3Error> {\n const text = await response.text().catch(() => '');\n let payload: unknown;\n try {\n payload = text ? JSON.parse(text) : undefined;\n } catch {\n payload = undefined;\n }\n const error = isRecord(payload)\n ? isRecord(payload.error)\n ? payload.error\n : payload\n : undefined;\n\n if (!error || typeof error.code !== 'string' || !error.code) {\n return notOurs(response.status, url, error, text, baseUrl);\n }\n\n const str = (value: unknown) =>\n typeof value === 'string' && value ? value : undefined;\n const num = (value: unknown) =>\n typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n const message =\n str(error.message) ?? `${response.status} ${response.statusText}`.trim();\n\n if (error.code === 'RenderBudgetExceeded') {\n return new RenderBudgetExceeded({\n message,\n why: str(error.why),\n fix: str(error.fix),\n docs: str(error.docs),\n maxCost: num(error.maxCost),\n estimatedCost: num(error.estimatedCost),\n maximumCost: num(error.maximumCost),\n kind: budgetedKind(error.kind, path),\n });\n }\n\n return new Bakery3Error({\n code: error.code as Bakery3ErrorCode,\n message,\n why: str(error.why),\n fix: str(error.fix),\n docs: str(error.docs),\n path: str(error.path),\n retryable: response.status >= 500 || response.status === 429,\n });\n}\n\nfunction budgetedKind(kind: unknown, path: string): BudgetedKind {\n if (kind === 'render' || kind === 'video' || kind === 'bake') return kind;\n return path.startsWith('/v1/bakes') ? 'bake' : 'render';\n}\n\n/**\n * An answer that did not come from the Bakery3 API: no error code, or not\n * JSON at all. Says who answered, where, and what to check.\n */\nfunction notOurs(\n status: number,\n url: string,\n body: Record<string, unknown> | undefined,\n text: string,\n baseUrl: string,\n): Bakery3Error {\n const where = `${status} from ${url.split('?')[0]}`;\n const said = (body && errorText(body)) || snippet(text);\n const answered = said ? ` It answered: ${said}` : '';\n if (status >= 500) {\n return new Bakery3Error({\n code: 'NetworkError',\n message: `${where}: the server failed before the Bakery3 API could answer.`,\n why: `The answer has no Bakery3 error in it, so a gateway or proxy in between answered.${answered}`,\n fix: `Try again in a moment. If it keeps happening, check that baseUrl (${baseUrl}) points at the Bakery3 API.`,\n retryable: true,\n });\n }\n return new Bakery3Error({\n code:\n status === 401 || status === 403\n ? 'Unauthorized'\n : status === 429\n ? 'RateLimited'\n : 'InvalidRequest',\n message: `${where}: not the Bakery3 API. Check baseUrl.`,\n why: `The answer has no Bakery3 error in it, so another server answered: a wrong baseUrl, a proxy, or a page of your own app.${answered}`,\n fix: `Leave baseUrl out to use ${DEFAULT_BASE_URL}, or point it at a proxy that forwards /v1/ requests unchanged.`,\n retryable: status === 429,\n });\n}\n\n/** A body as one short line: tags out, whitespace collapsed, cut at 160. */\nfunction snippet(text: string): string {\n const flat = text\n .replace(/<[^>]*>/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n return flat.length > 160 ? `${flat.slice(0, 160)}…` : flat;\n}\n","/**\n * A batch: a customer's declared body of work.\n *\n * A catalog is products x finishes x cameras, a few thousand stills. The\n * customer opens a batch, adds items in pages, closes it, and reads one\n * ledger back. On the control plane every item is a render row with a\n * `batchId`, staged behind the queue proper and fed into it a page at a\n * time, so everything that holds for a render (the claim, the reservation,\n * single billing, webhooks, retention) holds for an item because it is one.\n */\n\nimport type { RenderSpec } from './manifest.js';\nimport type { BakeSpec } from './bake.js';\nimport type { RenderError } from './job.js';\n\nexport const BATCH_STATES = [\n 'open',\n 'sealed',\n 'paused',\n 'completed',\n 'cancelled',\n] as const;\nexport type BatchState = (typeof BATCH_STATES)[number];\n\n/** A page of items is at most this many. The SDK flushes at it. */\nexport const BATCH_PAGE_SIZE = 100;\n\n/**\n * And at most this many bytes of JSON. A hundred ordinary manifests are a\n * few hundred KB; a hundred manifests that each carry extracted shader\n * graphs are not, and a page is one request and one admission decision, so\n * it has to fit in both. The SDK closes a page at whichever limit comes\n * first; the route refuses a page over it by name.\n */\nexport const BATCH_PAGE_BYTES = 4 * 1024 * 1024;\n\n/**\n * One item's spec, as JSON, is at most this. The bytes belong in assets,\n * which are content addressed and uploaded once; a manifest this large is\n * carrying something inline that should have been one.\n */\nexport const BATCH_ITEM_BYTES = 900 * 1024;\n\n/**\n * How many items are in each state. `staged` items are admitted: priced,\n * reserved, waiting behind the queue proper. `queued` are in the queue and\n * `running` hold a worker. `refused` failed for a reason a retry would not\n * change (the scene's fault, or ours to explain); `failed` ran out of\n * attempts on an infrastructure failure. `adopted` were already completed\n * under the same key when they were added and cost nothing.\n */\nexport type BatchCounts = {\n staged: number;\n queued: number;\n running: number;\n completed: number;\n failed: number;\n refused: number;\n cancelled: number;\n adopted: number;\n};\n\nexport type BatchCost = {\n /** Sum of estimatedCost over admitted items. */\n estimated: number;\n /** Sum of maximumCost over admitted items: what admission reserved. */\n maximum: number;\n /** Sum of what completed items actually cost, so far. */\n actual: number;\n};\n\nexport type BatchRecord = {\n id: string;\n key: string;\n name?: string;\n kind: 'render' | 'bake';\n state: BatchState;\n lane: 'batch' | 'normal';\n maxParallel?: number;\n /** The customer's ceiling for the whole batch. */\n maxCost?: number;\n counts: BatchCounts;\n /** Every item ever admitted, adopted included. */\n total: number;\n /** How many are terminal. `done === total` once sealed is `completed`. */\n done: number;\n cost: BatchCost;\n /** Why it is paused, when it is: the breaker names the top refusal codes. */\n pausedReason?: string;\n createdAt: number;\n sealedAt?: number;\n finishedAt?: number;\n};\n\nexport type BatchOpenRequest = {\n /**\n * Stable across re-runs: the same key re-opens the same batch while it is\n * not terminal, and items already completed under their keys are adopted\n * rather than rendered again.\n */\n key: string;\n name?: string;\n kind?: 'render' | 'bake';\n /**\n * The ceiling for the whole batch, in dollars. A page that would take the\n * batch's maximum past it is refused whole.\n */\n maxCost?: number;\n /**\n * `batch` (the default) never runs ahead of a person in a configurator;\n * `normal` is the API's ordinary lane.\n */\n lane?: 'batch' | 'normal';\n /** Fewer parallel items than the plan allows, for a gentler budget. */\n maxParallel?: number;\n};\n\nexport type BatchItemRequest = {\n /**\n * The item's idempotency key, scoped to the project like every other\n * render's. `sku/finish/camera@v3` is the shape the docs suggest.\n */\n key: string;\n spec: RenderSpec | BakeSpec;\n metadata?: Record<string, unknown>;\n /** A ceiling for this one item, under the batch's. */\n maxCost?: number;\n};\n\nexport type BatchAddRequest = {\n items: BatchItemRequest[];\n /**\n * Price everything, admit nothing: the whole catalog's numbers before a\n * dollar is reserved.\n */\n dryRun?: boolean;\n};\n\nexport type BatchItemOutcome = {\n key: string;\n /** The render's id, when it was admitted or adopted. */\n id?: string;\n estimatedCost: number;\n maximumCost: number;\n /** Already completed under this key: attached at no cost. */\n adopted?: boolean;\n /**\n * Why this item, alone, was not admitted (a bad spec, an item over its own\n * maxCost). The page's other items are unaffected.\n */\n error?: RenderError;\n};\n\nexport type BatchAddResponse = {\n batch: BatchRecord;\n items: BatchItemOutcome[];\n};\n\n/** One line of `GET /v1/batches/:id/export`: the ledger, item by item. */\nexport type BatchExportLine = {\n key: string;\n id: string;\n state: string;\n resultUrl?: string;\n error?: RenderError;\n cost?: number;\n versions?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n};\n","/**\n * How long a job keeps polling while every poll fails.\n *\n * A transient fault must not lose a render that is still running, so one\n * failed poll means nothing and a job rides out a dropped connection or a\n * laptop lid. But a fault that never clears (a token route that went away, a\n * base URL that stopped resolving) would leave `result()` pending for good,\n * with nothing on the page to say why. After this long with not one\n * successful poll, the job rejects with the last error, which names the\n * cause. The render itself is untouched and can still be read by its id.\n */\nexport const POLL_GIVE_UP_MS = 5 * 60_000;\n\nexport class PollFailures {\n private since: number | null = null;\n\n constructor(private readonly now: () => number = Date.now) {}\n\n /** A poll got through: whatever was failing has cleared. */\n succeeded(): void {\n this.since = null;\n }\n\n /** A poll failed. True once they have all been failing for the whole window. */\n exhausted(): boolean {\n this.since ??= this.now();\n return this.now() - this.since >= POLL_GIVE_UP_MS;\n }\n}\n","/**\n * A batch, from the customer's side.\n *\n * const batch = await bakery3.batches.open({ key: 'fall-2026-v3', maxCost: 600 });\n * for await (const item of source) await batch.write(item); // a full page sends itself\n * await batch.close(); // the tail is flushed, then sealed: the total is known\n * await batch.wait({ onProgress: (p) => console.log(`${p.completed}/${p.total}`) });\n * for await (const item of batch.items({ state: 'failed' })) console.error(item.key);\n *\n * Two things this class is careful about, because they are the whole reason\n * the batch exists rather than a loop over `render()`:\n *\n * - Memory. `write` buffers a few KB of manifest per item and sends a page\n * the moment one is full, by count or by bytes, so awaiting it is the\n * backpressure and nothing here ever holds the catalog. (`add` and\n * `flush` are the same two steps taken by hand.) A refused page stays\n * buffered: the caller tops up and flushes again, and the same items go,\n * under the same keys.\n * - One poll loop. `wait` long-polls the batch record; it never polls a\n * render. Items are read by state with a cursor when they are wanted.\n */\n\nimport type {\n BatchAddRequest,\n BatchCost,\n BatchCounts,\n BatchExportLine,\n BatchItemOutcome,\n BatchItemRequest,\n BatchRecord,\n BatchState,\n RenderState,\n} from './protocol/index.js';\nimport {\n BATCH_ITEM_BYTES,\n BATCH_PAGE_BYTES,\n BATCH_PAGE_SIZE,\n} from './protocol/index.js';\nimport type { BatchItemRecord, BatchItemsPage } from './client.js';\nimport { Bakery3Error, BatchPageRefused } from './errors.js';\nimport { POLL_GIVE_UP_MS, PollFailures } from './pollFailures.js';\n\n/** The slice of the client a batch drives: what a mock has to provide. */\nexport type BatchTransport = {\n getBatch(\n id: string,\n options?: { wait?: number; signal?: AbortSignal },\n ): Promise<BatchRecord>;\n addBatchItems(\n id: string,\n body: BatchAddRequest,\n ): Promise<{ batch: BatchRecord; items: BatchItemOutcome[] }>;\n listBatchItems(\n id: string,\n options?: { state?: RenderState; cursor?: string; limit?: number },\n ): Promise<BatchItemsPage>;\n exportBatch(id: string): AsyncIterable<BatchExportLine>;\n batchAction(\n id: string,\n action: 'close' | 'pause' | 'resume' | 'cancel' | 'retry',\n ): Promise<BatchRecord>;\n};\n\n/**\n * The counts, the cost and where the batch stands: what a status line\n * prints. Flat on purpose (`p.completed`, not `p.counts.completed`).\n */\nexport type BatchProgress = BatchCounts & {\n id: string;\n state: BatchState;\n /** Every item ever admitted, adopted included. Final once sealed. */\n total: number;\n /** How many are terminal. */\n done: number;\n cost: BatchCost;\n pausedReason?: string;\n};\n\nexport type FlushOptions = {\n /** Price the pages, admit nothing: the buffer stays for a real flush. */\n dryRun?: boolean;\n};\n\nexport type WaitOptions = {\n /** Called after every poll that returned, whether or not the counts moved. */\n onProgress?: (progress: BatchProgress) => void;\n signal?: AbortSignal;\n};\n\n/** How long each `GET ?wait=` is allowed to hang. The route's own ceiling. */\nconst LONG_POLL_SECONDS = 25;\n\n/**\n * The wait between polls while they are failing: doubling from one second to\n * half a minute. A long-poll that fails returns at once, so without a wait a\n * tab that went offline would request again as fast as each attempt failed.\n */\nconst WAIT_RETRY_MS = { first: 1_000, ceiling: 30_000 };\n/** Items per `GET /items` page while iterating. */\nconst LIST_PAGE_SIZE = 100;\n\nexport class Batch {\n readonly id: string;\n readonly key: string;\n\n private latest: BatchRecord;\n /** The flush in flight, or the last one, settled either way. */\n private flushing: Promise<unknown> = Promise.resolve();\n private readonly buffer: BatchItemRequest[] = [];\n /** `buffer[i]` as JSON is about `sizes[i]` bytes. Kept beside it so a\n * page can be closed on bytes without serializing anything twice. */\n private readonly sizes: number[] = [];\n private bytes = 0;\n private readonly client: BatchTransport;\n /** The clock `wait()` measures its patience with. A test turns it. */\n private clock: { now: () => number; sleep: typeof pause } = {\n now: () => Date.now(),\n sleep: pause,\n };\n\n /** @internal `bakery3.batches.open()` and `.get()` make these. */\n constructor(client: BatchTransport, record: BatchRecord) {\n this.client = client;\n this.latest = record;\n this.id = record.id;\n this.key = record.key;\n }\n\n /** Buffer an item. Nothing is sent until `flush()`. */\n add(item: BatchItemRequest): this {\n if (!item.key) {\n throw new Bakery3Error({\n code: 'InvalidRequest',\n message: 'A batch item needs a key.',\n why: 'The key is what lets a re-run adopt the item instead of rendering it twice, and what a failed item is reported under.',\n fix: 'Use something stable that names the picture: `${sku}/${finish}/${camera}`.',\n docs: 'https://bakery3.com/docs/api',\n });\n }\n const size = jsonBytes(item);\n if (size > BATCH_ITEM_BYTES) throw itemTooLarge(item.key, size);\n this.buffer.push(item);\n this.sizes.push(size);\n this.bytes += size;\n return this;\n }\n\n /**\n * `add`, and send a page when one is full. Awaiting it is the\n * backpressure: a loop over a file, a cursor or a generator of any length\n * holds one page at most.\n *\n * for await (const item of source) await batch.write(item);\n * await batch.close();\n */\n async write(item: BatchItemRequest): Promise<void> {\n this.add(item);\n if (this.buffer.length >= BATCH_PAGE_SIZE || this.bytes >= BATCH_PAGE_BYTES)\n await this.flush();\n }\n\n /** Items added and not yet sent. */\n get buffered(): number {\n return this.buffer.length;\n }\n\n /** About how many bytes of JSON those items are. */\n get bufferedBytes(): number {\n return this.bytes;\n }\n\n /**\n * Price items without buffering or admitting them: the estimate, the\n * maximum and any refusal, per item, in the order given. Paged like a\n * flush. An item already completed under its key is quoted as adopted, at\n * nothing, which makes this the price of a re-run too.\n */\n async quote(items: BatchItemRequest[]): Promise<BatchItemOutcome[]> {\n const outcomes: BatchItemOutcome[] = [];\n const sizes = items.map(jsonBytes);\n let offset = 0;\n while (offset < items.length) {\n const count = pageLength(sizes, offset);\n const response = await this.client.addBatchItems(this.id, {\n items: items.slice(offset, offset + count),\n dryRun: true,\n });\n outcomes.push(...response.items);\n offset += count;\n }\n return outcomes;\n }\n\n /**\n * Send the buffer in pages: `BATCH_PAGE_SIZE` items or `BATCH_PAGE_BYTES`\n * of JSON, whichever a page reaches first.\n *\n * Returns one outcome per item sent: admitted, adopted, or refused alone\n * (`outcome.error`). A page refused whole throws `BatchPageRefused` and\n * leaves that page and everything behind it in the buffer, so the caller\n * can top up and call `flush()` again; the error carries the outcomes of\n * the pages that did get through.\n */\n flush(options: FlushOptions = {}): Promise<BatchItemOutcome[]> {\n // One at a time. Two flushes running together would both read the first\n // page, and the second one's splice would remove a page that was never\n // sent: items gone with no error. `close()` flushes too, so a flush nobody\n // awaited followed by a close is enough to meet this.\n const run = this.flushing.then(() => this.flushNow(options));\n this.flushing = run.catch(() => {});\n return run;\n }\n\n private async flushNow(options: FlushOptions): Promise<BatchItemOutcome[]> {\n const outcomes: BatchItemOutcome[] = [];\n let offset = 0;\n while (offset < this.buffer.length) {\n const page = this.buffer.slice(\n offset,\n offset + pageLength(this.sizes, offset),\n );\n let response;\n try {\n response = await this.client.addBatchItems(this.id, {\n items: page,\n ...(options.dryRun ? { dryRun: true } : {}),\n });\n } catch (error) {\n if (error instanceof Bakery3Error)\n throw new BatchPageRefused(error, page, outcomes);\n throw error;\n }\n this.latest = response.batch;\n outcomes.push(...response.items);\n if (options.dryRun) {\n // Priced, not admitted: the items are still ours to send for real.\n offset += page.length;\n } else {\n this.buffer.splice(offset, page.length);\n for (const size of this.sizes.splice(offset, page.length))\n this.bytes -= size;\n }\n }\n return outcomes;\n }\n\n /** Seal: no more items. `completed` fires once the last one is terminal.\n * Anything still buffered is flushed first, because closing over unsent\n * items would quietly drop the tail of a catalog. */\n async close(): Promise<BatchRecord> {\n if (this.buffer.length) await this.flush();\n return this.apply(await this.client.batchAction(this.id, 'close'));\n }\n\n /** Stop feeding the queue; running items finish. */\n async pause(): Promise<BatchRecord> {\n return this.apply(await this.client.batchAction(this.id, 'pause'));\n }\n\n async resume(): Promise<BatchRecord> {\n return this.apply(await this.client.batchAction(this.id, 'resume'));\n }\n\n /** Cancel every non-terminal item. What completed stays completed: it rendered. */\n async cancel(): Promise<BatchRecord> {\n return this.apply(await this.client.batchAction(this.id, 'cancel'));\n }\n\n /** Re-queue every dead-lettered item, one new attempt each. */\n async retry(): Promise<BatchRecord> {\n return this.apply(await this.client.batchAction(this.id, 'retry'));\n }\n\n /** The latest record this batch has seen. No request. */\n record(): BatchRecord {\n return this.latest;\n }\n\n /** Fetch the record now. */\n async refresh(): Promise<BatchRecord> {\n return this.apply(await this.client.getBatch(this.id));\n }\n\n /** Counts and cost from the latest record. No request. */\n progress(): BatchProgress {\n return progressOf(this.latest);\n }\n\n /**\n * Wait for the batch to finish: one long-poll loop on the batch record\n * until it is `completed` or `cancelled` (or sealed with every item\n * terminal). Never a poll per render.\n *\n * A paused batch is waited on, not given up on (someone may resume it from\n * the console), and `onProgress` sees `pausedReason` meanwhile. Pass\n * `signal` to stop waiting; the batch itself is untouched.\n *\n * A fault that clears is ridden out. One that does not (five minutes with\n * not one poll through) rejects with an error that says so and carries the\n * last fault's code. The batch renders on regardless, and `wait()` can be\n * called again.\n */\n async wait(options: WaitOptions = {}): Promise<BatchRecord> {\n const { onProgress, signal } = options;\n const failures = new PollFailures(this.clock.now);\n let failed = 0;\n for (;;) {\n if (signal?.aborted) throw signal.reason ?? abortError();\n if (isFinished(this.latest)) return this.latest;\n try {\n this.apply(\n await this.client.getBatch(this.id, {\n wait: LONG_POLL_SECONDS,\n signal,\n }),\n );\n failed = 0;\n failures.succeeded();\n } catch (error) {\n if (signal?.aborted) throw signal.reason ?? abortError();\n // A transient fault must not lose a batch that is still rendering:\n // keep polling, and only give up on a declared verdict, or on a fault\n // that has outlasted every poll for minutes.\n if (error instanceof Bakery3Error && !error.retryable) throw error;\n if (failures.exhausted()) throw lostContact(this.id, error);\n await this.clock.sleep(\n Math.min(WAIT_RETRY_MS.ceiling, WAIT_RETRY_MS.first * 2 ** failed++),\n signal,\n );\n continue;\n }\n onProgress?.(this.progress());\n }\n }\n\n /** Every item, or every item in one state, walked with the cursor. */\n async *items(\n options: { state?: RenderState } = {},\n ): AsyncIterable<BatchItemRecord> {\n let cursor: string | undefined;\n do {\n const page = await this.client.listBatchItems(this.id, {\n ...(options.state ? { state: options.state } : {}),\n ...(cursor ? { cursor } : {}),\n limit: LIST_PAGE_SIZE,\n });\n yield* page.items;\n cursor = page.cursor ?? undefined;\n } while (cursor);\n }\n\n /** The ledger, line by line, as the server streams it. */\n export(): AsyncIterable<BatchExportLine> {\n return this.client.exportBatch(this.id);\n }\n\n private apply(record: BatchRecord): BatchRecord {\n this.latest = record;\n return record;\n }\n}\n\nexport function progressOf(record: BatchRecord): BatchProgress {\n return {\n ...record.counts,\n id: record.id,\n state: record.state,\n total: record.total,\n done: record.done,\n cost: record.cost,\n ...(record.pausedReason ? { pausedReason: record.pausedReason } : {}),\n };\n}\n\n/** Nothing more will happen to this batch. */\nexport function isFinished(record: BatchRecord): boolean {\n if (record.state === 'completed' || record.state === 'cancelled') return true;\n return record.state === 'sealed' && record.done >= record.total;\n}\n\n/** How many items from `offset` make one page: by count, and by bytes. Never zero. */\nfunction pageLength(sizes: number[], offset: number): number {\n let count = 0;\n let bytes = 0;\n while (offset + count < sizes.length && count < BATCH_PAGE_SIZE) {\n bytes += sizes[offset + count]!;\n if (count > 0 && bytes > BATCH_PAGE_BYTES) break;\n count++;\n }\n return count;\n}\n\n/** UTF-16 units, not bytes: a manifest is ASCII but for the names in it, and\n * the page limit leaves more room than that difference can use. */\nfunction jsonBytes(item: BatchItemRequest): number {\n return JSON.stringify(item).length;\n}\n\nfunction itemTooLarge(key: string, size: number): Bakery3Error {\n return new Bakery3Error({\n code: 'InvalidRequest',\n message: `Item \"${key}\" is ${(size / 1024).toFixed(0)} KB of JSON; an item holds at most ${BATCH_ITEM_BYTES / 1024} KB.`,\n why: 'An item is a manifest: cameras, lights and ids, a few KB. The heavy bytes are assets, uploaded once by hash and named from the manifest.',\n fix: 'Look for something large inline in the spec or its metadata (a data: URL, a geometry, a long array) and ship it as an asset, or leave it out of `metadata`.',\n path: key,\n docs: 'https://bakery3.com/docs/batches#errors',\n });\n}\n\n/** `wait()` gave up: every poll failed for `POLL_GIVE_UP_MS`. Keeps the last fault's code. */\nfunction lostContact(id: string, cause: unknown): Bakery3Error {\n const last = cause instanceof Error ? cause.message : String(cause);\n return new Bakery3Error({\n code: cause instanceof Bakery3Error ? cause.code : 'NetworkError',\n message: `Stopped waiting for batch ${id}: no poll has got through for ${POLL_GIVE_UP_MS / 60_000} minutes. The last error was: ${last}`,\n why: 'The batch keeps rendering on the server whether or not this page can reach it, so wait() rides out a dropped connection. A fault that lasts this long (a token route that is gone, a base URL that stopped resolving) will not clear by itself.',\n fix: 'Fix what the last error names, then call wait() again, or read the set later with getRenderSet(id). Nothing was lost.',\n docs: 'https://bakery3.com/docs/batches#errors',\n retryable: true,\n });\n}\n\n/** A wait that ends early, without throwing, when the signal fires: the loop's own check reports it. */\nfunction pause(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(done, ms);\n function done() {\n clearTimeout(timer);\n signal?.removeEventListener('abort', done);\n resolve();\n }\n signal?.addEventListener('abort', done, { once: true });\n });\n}\n\nfunction abortError(): Error {\n const error = new Error('The wait was aborted.');\n error.name = 'AbortError';\n return error;\n}\n","/**\n * The test run: a few products, every camera, small and fast.\n *\n * Before six thousand pictures are paid for, three products are worth\n * looking at: are the cameras where they were meant to be, is the room the\n * right way round, does the finish list hide what it should. A test run is\n * the real run's own options with three changes, made here so the browser\n * and the server make the same ones:\n *\n * - A sample of the products. From an array: the first, the middle and the\n * last, because a catalog is usually sorted and its ends differ most.\n * From anything else (a generator, a cursor): the first three, since a\n * list that is never collected has no middle to ask for.\n * - Preview quality at a small size, the long edge 512 unless told\n * otherwise, the aspect kept, so the framing is the real run's framing.\n * - Its own keys. A test is looked at and thrown away; if it shared the real\n * run's keys, the real run would adopt these little previews as finished\n * pictures. Every test also differs from the last one, so a test after a\n * fix shows the fix and not yesterday's frame.\n *\n * No three.js here: the server entry imports this file.\n */\n\nimport type { QualityPreset } from './protocol/index.js';\n\nexport type TestRunOptions = {\n /** How many products. Default 3. */\n products?: number;\n /** The long edge of each picture, in pixels. Default 512. */\n size?: number;\n /** The ceiling for the test, in dollars. Default 5. */\n maxCost?: number;\n};\n\nexport const TEST_DEFAULTS = { products: 3, size: 512, maxCost: 5 } as const;\n\nexport type TestSettings = {\n key: string;\n version: string;\n quality: QualityPreset;\n width: number;\n height: number;\n maxCost: number;\n lane: 'normal';\n};\n\n/** What a test changes about a run whose real pictures are `width` × `height`. */\nexport function testSettings(\n run: { key: string; width: number; height: number },\n options: TestRunOptions = {},\n now: number = Date.now(),\n): TestSettings {\n const size = Math.max(64, Math.round(options.size ?? TEST_DEFAULTS.size));\n const scale = size / Math.max(run.width, run.height);\n const stamp = now.toString(36);\n return {\n key: `${run.key}:test:${stamp}`,\n version: `test-${stamp}`,\n quality: 'preview',\n // Even, because an encoder somewhere always wants that.\n width: Math.max(2, Math.round((run.width * scale) / 2) * 2),\n height: Math.max(2, Math.round((run.height * scale) / 2) * 2),\n maxCost: options.maxCost ?? TEST_DEFAULTS.maxCost,\n lane: 'normal',\n };\n}\n\n/**\n * The key a run's quote is priced under: the run's key with `:quote` after\n * it. A quote never opens the run's own batch, because the run's batch is\n * the one opened with the run's `maxCost`, and a batch is re-opened by key.\n */\nexport function quoteKey(runKey: string): string {\n return `${runKey}:quote`;\n}\n\n/** The sample, without holding more of the list than the caller already does. */\nexport async function* sampleOf<V>(\n variants: Iterable<V> | AsyncIterable<V>,\n count: number = TEST_DEFAULTS.products,\n): AsyncIterable<V> {\n const wanted = Math.max(1, Math.floor(count));\n if (Array.isArray(variants)) {\n const length = variants.length;\n if (length <= wanted) return yield* variants as V[];\n const picked = new Set<number>();\n for (let i = 0; i < wanted; i++)\n picked.add(Math.round((i * (length - 1)) / (wanted - 1 || 1)));\n for (const index of [...picked].sort((a, b) => a - b))\n yield variants[index] as V;\n return;\n }\n let taken = 0;\n for await (const variant of variants) {\n yield variant;\n if (++taken >= wanted) return;\n }\n}\n"]}