@oeave/bakery3 0.1.0 → 0.3.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 (77) hide show
  1. package/README.md +10 -10
  2. package/dist/bake/index.d.ts +3 -3
  3. package/dist/bake/index.js +4 -4
  4. package/dist/{bake-DaOlenyx.d.ts → bake-DZ-CJR6f.d.ts} +8 -1
  5. package/dist/catalog/index.d.ts +5 -5
  6. package/dist/catalog/index.js +3 -3
  7. package/dist/{chunk-TGFNQBKC.js → chunk-3T3FJOSD.js} +5 -5
  8. package/dist/chunk-3T3FJOSD.js.map +1 -0
  9. package/dist/{chunk-V3QINEEG.js → chunk-62M6XXNX.js} +58 -3
  10. package/dist/chunk-62M6XXNX.js.map +1 -0
  11. package/dist/{chunk-ARMTTZXZ.js → chunk-6FAMQZXB.js} +8 -8
  12. package/dist/chunk-6FAMQZXB.js.map +1 -0
  13. package/dist/{chunk-54WJDN5R.js → chunk-CSSJRP5W.js} +9 -6
  14. package/dist/chunk-CSSJRP5W.js.map +1 -0
  15. package/dist/{chunk-W6WQ5UP7.js → chunk-EN4ROBYQ.js} +32 -5
  16. package/dist/chunk-EN4ROBYQ.js.map +1 -0
  17. package/dist/chunk-KZLVTSBI.js +191 -0
  18. package/dist/chunk-KZLVTSBI.js.map +1 -0
  19. package/dist/{chunk-MD2U6S4N.js → chunk-LAKXC4WR.js} +218 -142
  20. package/dist/chunk-LAKXC4WR.js.map +1 -0
  21. package/dist/{chunk-HQTUFVMM.js → chunk-NEK5TBEH.js} +3 -3
  22. package/dist/chunk-NEK5TBEH.js.map +1 -0
  23. package/dist/chunk-OPM2L63B.js +253 -0
  24. package/dist/chunk-OPM2L63B.js.map +1 -0
  25. package/dist/{chunk-APBOWWSV.js → chunk-R5IUPOWI.js} +3 -3
  26. package/dist/chunk-R5IUPOWI.js.map +1 -0
  27. package/dist/{chunk-6YVQANMW.js → chunk-STRK4SZN.js} +262 -16
  28. package/dist/chunk-STRK4SZN.js.map +1 -0
  29. package/dist/{chunk-CX4WTVGH.js → chunk-WLEFNUOH.js} +411 -371
  30. package/dist/chunk-WLEFNUOH.js.map +1 -0
  31. package/dist/{chunk-25ZXSVQ3.js → chunk-X6GW43EX.js} +3 -3
  32. package/dist/{chunk-25ZXSVQ3.js.map → chunk-X6GW43EX.js.map} +1 -1
  33. package/dist/{chunk-WBIAFIHV.js → chunk-XK35ANPJ.js} +3 -3
  34. package/dist/{chunk-WBIAFIHV.js.map → chunk-XK35ANPJ.js.map} +1 -1
  35. package/dist/devtools/index.d.ts +3 -3
  36. package/dist/devtools/index.js +10 -9
  37. package/dist/hotspots/index.d.ts +237 -31
  38. package/dist/hotspots/index.js +1013 -118
  39. package/dist/hotspots/index.js.map +1 -1
  40. package/dist/index.d.ts +39 -8
  41. package/dist/index.js +11 -10
  42. package/dist/node/index.cjs +266 -141
  43. package/dist/node/index.cjs.map +1 -1
  44. package/dist/node/index.d.cts +152 -87
  45. package/dist/node/index.d.ts +27 -6
  46. package/dist/node/index.js +52 -3
  47. package/dist/node/index.js.map +1 -1
  48. package/dist/{prepare-C5qVvaw4.d.ts → prepare-BtjY4G3q.d.ts} +1 -1
  49. package/dist/presets/index.d.ts +37 -1
  50. package/dist/presets/index.js +4 -4
  51. package/dist/presets/index.js.map +1 -1
  52. package/dist/r3f/index.d.ts +4 -4
  53. package/dist/r3f/index.js +13 -12
  54. package/dist/r3f/index.js.map +1 -1
  55. package/dist/{room-S5TLCK4F.js → room-BM7Z7NKG.js} +6 -6
  56. package/dist/{room-S5TLCK4F.js.map → room-BM7Z7NKG.js.map} +1 -1
  57. package/dist/{rooms.gen-vhj6sFW5.d.ts → rooms.gen-DItzBR9k.d.ts} +112 -84
  58. package/dist/session-NPVBESWA.js +9 -0
  59. package/dist/{session-YCQS4MRH.js.map → session-NPVBESWA.js.map} +1 -1
  60. package/dist/{testRun-BIPXaVPb.d.ts → testRun-20OARnQr.d.ts} +12 -3
  61. package/dist/tsl/index.d.ts +14 -1
  62. package/dist/tsl/index.js +8 -2
  63. package/dist/tsl/index.js.map +1 -1
  64. package/package.json +1 -1
  65. package/dist/chunk-54WJDN5R.js.map +0 -1
  66. package/dist/chunk-6YVQANMW.js.map +0 -1
  67. package/dist/chunk-AF5BIELI.js +0 -70
  68. package/dist/chunk-AF5BIELI.js.map +0 -1
  69. package/dist/chunk-APBOWWSV.js.map +0 -1
  70. package/dist/chunk-ARMTTZXZ.js.map +0 -1
  71. package/dist/chunk-CX4WTVGH.js.map +0 -1
  72. package/dist/chunk-HQTUFVMM.js.map +0 -1
  73. package/dist/chunk-MD2U6S4N.js.map +0 -1
  74. package/dist/chunk-TGFNQBKC.js.map +0 -1
  75. package/dist/chunk-V3QINEEG.js.map +0 -1
  76. package/dist/chunk-W6WQ5UP7.js.map +0 -1
  77. package/dist/session-YCQS4MRH.js +0 -9
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/protocol/job.ts","../src/job.ts","../src/capture/exported.ts","../src/bake/job.ts","../src/upload.ts","../src/index.ts"],"names":["record","document","POLL_SCHEDULE","call","options"],"mappings":"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","file":"chunk-ARMTTZXZ.js","sourcesContent":["/**\n * Render job states and the events that carry them.\n *\n * Every transition is timestamped, idempotent and observable. Idempotent is\n * the load-bearing word: a worker that retries a stage must not bill twice\n * and must not emit `render.completed` twice, so the control plane treats a\n * transition to a state it is already in as a no-op rather than an error.\n */\n\nexport const RENDER_STATES = [\n 'created',\n 'uploading',\n 'validating',\n 'queued',\n 'starting',\n 'preparing',\n 'rendering_preview',\n 'rendering',\n 'encoding',\n 'uploading_result',\n 'completed',\n 'failed',\n 'cancelled',\n 'expired',\n] as const;\n\nexport type RenderState = (typeof RENDER_STATES)[number];\n\n/** Nothing will move a render out of these; polling can stop. */\nexport const TERMINAL_STATES: RenderState[] = [\n 'completed',\n 'failed',\n 'cancelled',\n 'expired',\n];\n\nexport function isTerminal(state: RenderState): boolean {\n return TERMINAL_STATES.includes(state);\n}\n\n/**\n * Roughly how far along a state is, for a progress bar that does not lie.\n *\n * Coarse on purpose. Real percentages exist only inside `rendering` (the\n * renderer reports its own), and pretending to know how long `preparing`\n * will take is how a progress bar ends up sitting at 90% for a minute.\n */\n// A video is the exception: while it renders, `progress` moves from this\n// state's number towards the next with the frames traced (`RenderRecord.frames`).\nexport const STATE_PROGRESS: Record<RenderState, number> = {\n created: 0,\n uploading: 0.05,\n validating: 0.1,\n queued: 0.12,\n starting: 0.15,\n preparing: 0.25,\n rendering_preview: 0.35,\n rendering: 0.5,\n encoding: 0.9,\n uploading_result: 0.95,\n completed: 1,\n failed: 1,\n cancelled: 1,\n expired: 1,\n};\n\nexport type RenderResult = {\n /**\n * Signed, private, and only good until `expiresAt` (24 hours). Copy the\n * bytes into your own storage if you keep them; `getRender(id)` hands out\n * fresh URLs until the project's retention deletes the files.\n */\n url: string;\n /**\n * Millisecond epoch at which `url` (and `previewUrl`) stop working. The\n * URLs are signed when the render is read, so reading it again with\n * `getRender(id)` returns fresh ones. Absent from an API that predates it.\n */\n expiresAt?: number;\n width: number;\n height: number;\n format: string;\n bytes: number;\n /** What was actually charged, in USD. Not the estimate. */\n cost: number;\n /** Everything needed to reproduce this exact image later. */\n versions: {\n protocol: string;\n sdk: string;\n translator: string;\n qualityPreset: string;\n };\n};\n\n/**\n * Which queue a render waits in inside its account.\n *\n * `interactive` is a person waiting: every browser-token render, and the\n * SDK's `render()` by default. `normal` is the API default. `batch` is an\n * item of a batch. A lane above always dispatches before a lane below, so a\n * configurator's visitor never waits behind an overnight catalog.\n */\nexport const RENDER_LANES = ['interactive', 'normal', 'batch'] as const;\nexport type RenderLane = (typeof RENDER_LANES)[number];\n\n/**\n * A nudge inside the lane: `high` goes before the account's other work in\n * the same lane. It never crosses a lane.\n */\nexport type RenderPriority = 'normal' | 'high';\n\nexport type RenderRecord = {\n id: string;\n state: RenderState;\n progress: number;\n /**\n * A video's frames traced so far and in all, while it renders. Updated\n * every ten seconds or so; absent for a still and once the render ends.\n */\n frames?: { done: number; total: number };\n /** Which of the account's queues it waits in. */\n lane?: RenderLane;\n /**\n * How many times a worker has been handed this render. 1 is the normal\n * case; more means an infrastructure failure was retried for you.\n */\n attempts?: number;\n /** The batch this render belongs to, and its key within it. */\n batchId?: string;\n batchKey?: string;\n /** A low-sample image, available long before the final one. */\n previewUrl?: string;\n result?: RenderResult;\n error?: RenderError;\n estimate?: CostEstimate;\n createdAt: number;\n updatedAt: number;\n metadata?: Record<string, unknown>;\n};\n\n/**\n * A finished bake, as `GET /v1/bakes/:id` answers it.\n *\n * The bundle's uv arrays are behind `bundleUrl`, not here: a dense room's\n * are megabytes, and the SDK reads them once from storage. `files` is every\n * name the bundle uses, resolved to a signed URL, so a loader can take\n * `bundle.objects[i].lightmap.uri` and look it up without knowing where the\n * files live. All of them expire together, at `expiresAt`.\n */\nexport type BakeResult = {\n /** Signed GET for bundle.json: the BakeBundle, uv arrays and all. */\n bundleUrl: string;\n /** Every file the bundle names, by that name, as a signed GET. */\n files: Record<string, string>;\n /** Millisecond epoch at which the URLs stop working. */\n expiresAt: number;\n /**\n * The bundle without its uv arrays: what a panel shows before it fetches\n * anything.\n */\n summary: import('./bake.js').BakeBundleSummary;\n /** Every file's size together, in bytes. */\n bytes: number;\n cost: number;\n versions: Record<string, string | number>;\n};\n\nexport type BakeRecord = {\n id: string;\n state: RenderState;\n progress: number;\n result?: BakeResult;\n error?: RenderError;\n estimate?: CostEstimate;\n createdAt: number;\n updatedAt: number;\n metadata?: Record<string, unknown>;\n};\n\n/**\n * Cost, before anything expensive happens.\n *\n * `maximum` is what `maxCost` is compared against, so a developer who sets\n * a ceiling gets a refusal rather than a bill somewhere between the two\n * numbers.\n */\nexport type CostEstimate = {\n estimatedCost: number;\n maximumCost: number;\n estimatedSeconds: number;\n compatibilityScore: number;\n};\n\n/**\n * A failure a developer can act on.\n *\n * `code` is stable and machine-readable; `message`, `why` and `fix` are for\n * the developer. A traceback is never any of them.\n */\nexport type RenderError = {\n code: RenderErrorCode;\n message: string;\n why?: string;\n fix?: string;\n docs?: string;\n /** Where in the scene, when the failure has a location. */\n path?: string;\n /** Whether resubmitting unchanged could plausibly work. */\n retryable: boolean;\n /**\n * The control plane tried this render again and gave up: every attempt\n * failed the same retryable way. We have been told, and\n * `POST /v1/renders/:id/retry` tries once more on request.\n */\n attemptsExhausted?: boolean;\n};\n\nexport const RENDER_ERROR_CODES = [\n 'RenderBudgetExceeded',\n 'UnsupportedMaterial',\n 'SceneTooLarge',\n 'TextureTooLarge',\n 'AssetNotFound',\n 'AssetUploadIncomplete',\n 'ProtocolVersionUnsupported',\n 'RoomPresetUnknown',\n 'RoomPresetBuildMismatch',\n 'CompatibilityPreflightFailed',\n 'OutOfVideoMemory',\n 'RenderTimeout',\n 'WorkerFailure',\n /**\n * The worker stopped answering: its lease expired, its host died, or the\n * job sat unclaimed for too long. Retried.\n */\n 'WorkerLost',\n /**\n * The renderer process died (a signal, a driver fault). Retried once on\n * another worker; twice on two hosts is the scene.\n */\n 'RendererCrashed',\n /** The result never reached storage. Retried. */\n 'UploadFailed',\n 'ResultLost',\n /**\n * No worker could take the job right now. Never an attempt: the render\n * stays queued and dispatch backs off.\n */\n 'CapacityUnavailable',\n 'QueueFull',\n 'QueueTimeout',\n /**\n * A page of batch items would take the batch's maximum past its own\n * `maxCost`. Refused whole; nothing in it was admitted.\n */\n 'BatchBudgetExceeded',\n /** Items added to a batch that is sealed, cancelled or completed. */\n 'BatchClosed',\n /**\n * `POST /v1/assets/import` will not fetch this URL: not https, not public,\n * credentials in it. A verdict on the URL; nothing was requested.\n */\n 'ImportRefused',\n /**\n * The URL was fetched and what came back cannot be used: a 404, a\n * timeout, a file that is not a GLB, one over the size limit.\n */\n 'ImportFailed',\n /** The call is on a plan the account is not on. Nothing was done. */\n 'PlanRequired',\n 'InsufficientBalance',\n 'QuotaExceeded',\n 'ConcurrencyLimitReached',\n /**\n * Too many requests from this key, browser token or address in the last\n * minute (429). The SDK waits and sends the request again on its own; this\n * reaches the developer only once its retries are spent.\n */\n 'RateLimited',\n 'Unauthorized',\n 'TokenExpired',\n 'OriginNotAllowed',\n 'InvalidRequest',\n] as const;\n\nexport type RenderErrorCode = (typeof RENDER_ERROR_CODES)[number];\n\n/** Webhook event names. */\nexport const WEBHOOK_EVENTS = [\n 'render.created',\n 'render.started',\n 'render.preview',\n 'render.completed',\n 'render.failed',\n 'render.cancelled',\n /**\n * An attempt failed for an infrastructure reason and the render was\n * queued again. Informational: the render is still yours to wait on.\n */\n 'render.retrying',\n 'video.started',\n 'video.frame.completed',\n 'video.completed',\n 'bake.created',\n 'bake.started',\n 'bake.completed',\n 'bake.failed',\n 'bake.cancelled',\n 'bake.retrying',\n /** At most one per thirty seconds per batch while it moves. */\n 'batch.progress',\n /** Sealed, and every item terminal. Once. */\n 'batch.completed',\n /** The refusal breaker tripped, or the customer paused it. */\n 'batch.paused',\n] as const;\n\nexport type WebhookEvent = (typeof WEBHOOK_EVENTS)[number];\n\n/**\n * What a webhook carries. A `render.*` event has `render`; a `bake.*` event\n * has `bake`. Never both: a receiver switches on `event` and reads the one\n * record the event is about.\n */\nexport type WebhookPayload = {\n event: WebhookEvent;\n /** Millisecond epoch. Signed together with the body; see the docs. */\n sentAt: number;\n render?: RenderRecord;\n bake?: BakeRecord;\n /** A `batch.*` event carries the batch's ledger instead. */\n batch?: import('./batch.js').BatchRecord;\n};\n","/**\n * A render in flight.\n *\n * Nobody is left looking at \"Rendering…\" for ten seconds. A job emits as it\n * goes:\n *\n * 0s submitted\n * 1s preparing\n * 2s low-sample preview -> job.on('preview')\n * 4s denoised intermediate -> job.on('progress')\n * 8s final -> await job.result()\n *\n * `await job.result()` is the whole API for someone who does not care, and\n * the events are there for someone who does. Neither is more supported than\n * the other: either one starts the polling, and a listener added late still\n * hears the latest preview, the latest progress and how the job ended.\n */\n\nimport type {\n RenderError,\n RenderRecord,\n RenderResult,\n RenderState,\n} from './protocol/index.js';\nimport { isTerminal } from './protocol/index.js';\nimport type { Bakery3Client } from './client.js';\nimport { Bakery3Error } from './errors.js';\nimport { PollFailures } from './pollFailures.js';\n\nexport type JobEvents = {\n queued: { render: RenderRecord };\n preparing: { render: RenderRecord };\n preview: { url: string; render: RenderRecord };\n progress: { percent: number; state: RenderState; render: RenderRecord };\n complete: { result: RenderResult; render: RenderRecord };\n failed: { error: Bakery3Error; render: RenderRecord };\n cancelled: { render: RenderRecord };\n};\n\n/** How long to wait for a job, and when to stop waiting. */\nexport type JobResultOptions = {\n /**\n * Stops this wait: the promise rejects with the signal's reason. The job\n * keeps polling while anything else still waits on it or listens to it,\n * and the render itself is not cancelled.\n */\n signal?: AbortSignal;\n};\n\n/**\n * Polling intervals, in ms, walked in order and then held at the last.\n *\n * Tight at the start because a preview lands in about two seconds and should\n * show the moment it exists; slack afterwards because a 4K ultra render takes\n * minutes and polling it every 400 ms is just noise.\n */\nconst POLL_SCHEDULE = [400, 400, 600, 800, 1000, 1500, 2000, 3000];\n\n/** What every job's record has: a render's and a bake's alike. */\ntype JobRecord = {\n id: string;\n state: RenderState;\n progress: number;\n result?: unknown;\n error?: RenderError;\n};\n\ntype Entry = { fn: (payload: never) => void; heard: boolean };\n\ntype Deferred<T> = {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (error: unknown) => void;\n};\n\n/**\n * The polling, the events and the waiting that a render job and a bake job\n * share. Not public API: `RenderJob` and `BakeJob` are.\n *\n * Polling starts on the first `on()` or `result()`, and stops when the job\n * ends, when `stop()` is called, or when nothing is waiting on it or\n * listening to it any more (a later `on()` or `result()` picks it up again).\n */\nexport abstract class PolledJob<\n R extends JobRecord,\n Out,\n E extends { failed: unknown; cancelled: unknown },\n> {\n readonly id: string;\n\n protected record: R;\n protected readonly client: Bakery3Client;\n\n private readonly subscribers = new Map<keyof E, Set<Entry>>();\n /** The last payload of each replayed event, for a listener added late. */\n private readonly lastPayloads = new Map<keyof E, unknown>();\n private pending: Deferred<Out> | null = null;\n /** `result()` calls still waiting. */\n private waiting = 0;\n /** The running poll loop's switch, or null when no loop runs. */\n private poller: AbortController | null = null;\n /** Set once the job has settled, for good: a terminal state or a verdict. */\n private hasEnded = false;\n\n /** \"render\" or \"bake\", for messages. */\n protected abstract readonly jobNoun: 'render' | 'bake';\n protected abstract readonly pollSchedule: readonly number[];\n /** Events a late listener is handed the latest of. */\n protected abstract readonly replayedEvents: ReadonlyArray<keyof E>;\n /** One poll. */\n protected abstract readRecord(signal: AbortSignal): Promise<R>;\n /** The events a new record raises before any terminal handling. */\n protected abstract observeRecord(record: R): void;\n /** A completed record into its output; emits `complete`. May throw. */\n protected abstract completeRecord(record: R): Promise<Out>;\n /** The record under the payload's own name: `{ render }` or `{ bake }`. */\n protected abstract recordPayload(record: R): object;\n\n constructor(client: Bakery3Client, record: R) {\n this.client = client;\n this.record = record;\n this.id = record.id;\n }\n\n get status(): RenderState {\n return this.record.state;\n }\n\n get progress(): number {\n return this.record.progress;\n }\n\n /**\n * Listen for an event. Starts polling if nothing has yet.\n *\n * A listener added after an event already fired is called with the latest\n * one, on the next microtask: the latest `preview` and `progress`, and\n * `complete`, `failed` or `cancelled` once the job has ended. Returns the\n * unsubscribe function, so a React effect can clean up without a second\n * API.\n */\n on<K extends keyof E>(\n event: K,\n listener: (payload: E[K]) => void,\n ): () => void {\n const set = this.subscribers.get(event) ?? new Set<Entry>();\n this.subscribers.set(event, set);\n const entry: Entry = {\n fn: listener as (payload: never) => void,\n heard: false,\n };\n set.add(entry);\n\n if (this.lastPayloads.has(event)) {\n queueMicrotask(() => {\n if (!set.has(entry) || entry.heard) return;\n entry.heard = true;\n call(event, entry, this.lastPayloads.get(event));\n });\n }\n this.startPolling();\n return () => {\n set.delete(entry);\n };\n }\n\n /**\n * The finished output. Starts polling if nothing has yet.\n *\n * Several callers may await the same job (a component, a devtools panel,\n * an analytics hook) and share one polling loop. Rejects with a\n * `Bakery3Error` when the job fails (after `failed` is emitted), with code\n * `Cancelled` when it was cancelled, and with an `AbortError` when the wait\n * was stopped by `stop()` or by `signal`.\n */\n result(options: JobResultOptions = {}): Promise<Out> {\n const outcome = this.pendingOutcome();\n if (this.hasEnded) return outcome.promise;\n const { signal } = options;\n if (signal?.aborted) return Promise.reject(signal.reason);\n\n this.waiting++;\n this.startPolling();\n return new Promise<Out>((resolve, reject) => {\n let waiting = true;\n const done = () => {\n if (!waiting) return false;\n waiting = false;\n this.waiting--;\n signal?.removeEventListener('abort', onAbort);\n return true;\n };\n const onAbort = () => {\n if (done()) reject(signal!.reason);\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n outcome.promise.then(\n (value) => {\n if (done()) resolve(value);\n },\n (error) => {\n if (done()) reject(error);\n },\n );\n });\n }\n\n /**\n * Stop polling, here, now. The job is NOT cancelled on the server: it\n * keeps running and is still charged, and `getRender(id)` or `getBake(id)`\n * reads it later. A pending `result()` rejects with an `AbortError`, and a\n * later `on()` or `result()` starts polling again.\n *\n * `cancel()` is the other one: it asks the server to stop the job, which\n * then ends as `cancelled`.\n */\n stop(): void {\n this.poller?.abort();\n this.poller = null;\n if (this.hasEnded || !this.pending) return;\n const stopped = this.pending;\n this.pending = null;\n stopped.reject(\n abortError(\n `Stopped watching ${this.jobNoun} ${this.id}. It still runs on the server.`,\n ),\n );\n }\n\n /** Apply a record read from the API, and settle if it is the last one. */\n protected applyRecord(record: R): void {\n this.record = record;\n this.observeRecord(record);\n if (isTerminal(record.state)) void this.settleEnd();\n }\n\n protected emitEvent<K extends keyof E>(event: K, payload: E[K]): void {\n if (this.replayedEvents.includes(event))\n this.lastPayloads.set(event, payload);\n for (const entry of this.subscribers.get(event) ?? []) {\n entry.heard = true;\n call(event, entry, payload);\n }\n }\n\n private pendingOutcome(): Deferred<Out> {\n if (this.pending) return this.pending;\n let resolve!: (value: Out) => void;\n let reject!: (error: unknown) => void;\n const promise = new Promise<Out>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n // Nobody may be waiting: a job watched only through `on()` must not\n // turn its failure into an unhandled rejection.\n promise.catch(() => {});\n this.pending = { promise, resolve, reject };\n return this.pending;\n }\n\n private isWatched(): boolean {\n if (this.waiting > 0) return true;\n for (const set of this.subscribers.values()) if (set.size > 0) return true;\n return false;\n }\n\n private startPolling(): void {\n if (this.poller || this.hasEnded) return;\n const loop = new AbortController();\n this.poller = loop;\n // On a microtask, so a listener is never called from inside the `on()`\n // that registered it, even for a job that has already ended.\n queueMicrotask(() => void this.pollLoop(loop));\n }\n\n private async pollLoop(loop: AbortController): Promise<void> {\n const { signal } = loop;\n const failures = new PollFailures();\n try {\n for (let step = 0; ; step++) {\n if (signal.aborted || this.hasEnded) return;\n if (isTerminal(this.record.state)) return void (await this.settleEnd());\n if (!this.isWatched()) return;\n\n const wait =\n this.pollSchedule[Math.min(step, this.pollSchedule.length - 1)]!;\n if (!(await pause(wait, signal))) return;\n\n try {\n const record = await this.readRecord(signal);\n if (signal.aborted) return;\n this.applyRecord(record);\n failures.succeeded();\n } catch (error) {\n if (signal.aborted) return;\n // A transient network fault must not lose a job that is still\n // running: keep polling, and only give up on an error the server\n // has declared final, or on a fault that has outlasted every poll\n // for minutes.\n if (error instanceof Bakery3Error && !error.retryable)\n return this.settleFailure(error);\n if (failures.exhausted()) return this.settleFailure(error);\n }\n }\n } finally {\n if (this.poller === loop) this.poller = null;\n }\n }\n\n /** Settle on the record's terminal state. Once. */\n private async settleEnd(): Promise<void> {\n if (this.hasEnded) return;\n this.hasEnded = true;\n this.poller?.abort();\n this.poller = null;\n const record = this.record;\n const outcome = this.pendingOutcome();\n\n if (record.state === 'cancelled') {\n this.emitEvent('cancelled', this.recordPayload(record) as E['cancelled']);\n outcome.reject(\n new Bakery3Error({\n code: 'Cancelled',\n message: `${capitalize(this.jobNoun)} ${this.id} was cancelled.`,\n retryable: false,\n }),\n );\n return;\n }\n\n if (record.state === 'completed' && record.result) {\n try {\n outcome.resolve(await this.completeRecord(record));\n } catch (error) {\n this.settleFailure(error);\n }\n return;\n }\n\n if (record.state === 'expired')\n return this.settleFailure(this.expiredError());\n\n this.settleFailure(\n record.error\n ? Bakery3Error.from(record.error)\n : new Bakery3Error({\n code: 'WorkerFailure',\n message: `${capitalize(this.jobNoun)} ended in state \"${record.state}\" with no result.`,\n retryable: true,\n }),\n );\n }\n\n /** Emit `failed`, then reject. Every failure goes through here. */\n private settleFailure(cause: unknown): void {\n this.hasEnded = true;\n this.poller?.abort();\n this.poller = null;\n const error =\n cause instanceof Bakery3Error\n ? cause\n : new Bakery3Error({\n code: 'NetworkError',\n message: `Could not read ${this.jobNoun} ${this.id}: ${\n cause instanceof Error ? cause.message : String(cause)\n }`,\n retryable: true,\n });\n this.emitEvent('failed', {\n error,\n ...this.recordPayload(this.record),\n } as E['failed']);\n this.pendingOutcome().reject(error);\n }\n\n private expiredError(): Bakery3Error {\n const files = this.jobNoun === 'bake' ? 'lightmaps' : 'image';\n return new Bakery3Error({\n code: 'Expired',\n message: `${capitalize(this.jobNoun)} ${this.id} has expired, so its ${files} can no longer be downloaded.`,\n why: `A ${this.jobNoun} expires when the project's retention ends or someone deletes it. The record stays, with its cost, but the files are gone.`,\n fix: `${this.jobNoun === 'bake' ? 'Bake' : 'Render'} again. To keep a result, copy its files into your own storage when the ${this.jobNoun} completes.`,\n docs: 'https://bakery3.com/docs/limits#retention',\n retryable: false,\n });\n }\n}\n\nexport class RenderJob extends PolledJob<\n RenderRecord,\n RenderResult,\n JobEvents\n> {\n protected readonly jobNoun = 'render';\n protected readonly pollSchedule = POLL_SCHEDULE;\n protected readonly replayedEvents: ReadonlyArray<keyof JobEvents> = [\n 'preview',\n 'progress',\n 'complete',\n 'failed',\n 'cancelled',\n ];\n\n private previewSeen = false;\n private lastState: RenderState | null = null;\n\n constructor(client: Bakery3Client, record: RenderRecord) {\n super(client, record);\n }\n\n get previewUrl(): string | undefined {\n return this.record.previewUrl;\n }\n\n /** The estimate this render was accepted under. */\n get estimate() {\n return this.record.estimate;\n }\n\n /**\n * Ask the server to stop the render. It ends as `cancelled`: `cancelled`\n * is emitted and `result()` rejects with code `Cancelled`. To stop\n * watching without stopping the render, call `stop()`.\n */\n async cancel(): Promise<void> {\n this.applyRecord(await this.client.cancelRender(this.id));\n }\n\n protected readRecord(signal: AbortSignal): Promise<RenderRecord> {\n return this.client.getRender(this.id, { signal });\n }\n\n protected observeRecord(record: RenderRecord): void {\n // Fires once. A preview URL stays on the record for the rest of the job's\n // life, so re-emitting it on every poll would make an `on('preview')`\n // handler that sets state re-render every second for nothing.\n if (record.previewUrl && !this.previewSeen) {\n this.previewSeen = true;\n this.emitEvent('preview', { url: record.previewUrl, render: record });\n }\n\n if (record.state !== this.lastState) {\n this.lastState = record.state;\n if (record.state === 'queued')\n this.emitEvent('queued', { render: record });\n if (record.state === 'preparing')\n this.emitEvent('preparing', { render: record });\n }\n\n this.emitEvent('progress', {\n percent: Math.round(record.progress * 100),\n state: record.state,\n render: record,\n });\n }\n\n protected async completeRecord(record: RenderRecord): Promise<RenderResult> {\n const result = record.result!;\n this.emitEvent('complete', { result, render: record });\n return result;\n }\n\n protected recordPayload(record: RenderRecord): { render: RenderRecord } {\n return { render: record };\n }\n}\n\nfunction call(event: PropertyKey, entry: Entry, payload: unknown): void {\n try {\n (entry.fn as (payload: unknown) => void)(payload);\n } catch (error) {\n // A throwing listener is the developer's bug, not a reason to fail\n // their render, which is already paid for by the time this runs.\n console.error(`[bakery3] listener for \"${String(event)}\" threw:`, error);\n }\n}\n\n/** Resolves true after `ms`, or false the moment `signal` aborts. */\nfunction pause(ms: number, signal: AbortSignal): Promise<boolean> {\n return new Promise((resolve) => {\n if (signal.aborted) return resolve(false);\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort);\n resolve(true);\n }, ms);\n function onAbort() {\n clearTimeout(timer);\n resolve(false);\n }\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\n/** The standard error for a wait that was called off. */\nfunction abortError(message: string): Error {\n if (typeof DOMException === 'function')\n return new DOMException(message, 'AbortError');\n const error = new Error(message);\n error.name = 'AbortError';\n return error;\n}\n\nfunction capitalize(word: string): string {\n return word.charAt(0).toUpperCase() + word.slice(1);\n}\n","/**\n * Which ids actually made it into the GLB.\n *\n * Every other check in the SDK predicts what the exporter will emit. Each\n * prediction is right until three's exporter grows one more reason to skip a\n * node, and then the developer learns about it from the renderer, after an\n * upload, in a message that can only quote an id because by then the object\n * is gone.\n *\n * This reads the ids out of the bytes that are about to be uploaded, so it\n * cannot drift from what the renderer sees: the renderer builds the same\n * index from the same `extras.bakery3Id` after it imports the same file.\n */\n\nimport { Bakery3Error } from '../errors.js';\nimport type { AnimationSpec, SceneManifest } from '../protocol/index.js';\n\nconst GLB_MAGIC = 0x46546c67; // 'glTF'\nconst CHUNK_JSON = 0x4e4f534a; // 'JSON'\n\n/**\n * The `bakery3Id` of every node in a binary glTF.\n *\n * Only the JSON chunk is decoded. The binary chunk holding the vertex data is\n * never touched, so this is cheap on a scene whose geometry is tens of\n * megabytes.\n */\nexport function exportedObjectIds(glb: ArrayBuffer): Set<string> {\n const ids = new Set<string>();\n const view = new DataView(glb);\n if (view.byteLength < 20 || view.getUint32(0, true) !== GLB_MAGIC) return ids;\n\n // Header: magic, version, length. Then chunks: length, type, data.\n let offset = 12;\n while (offset + 8 <= view.byteLength) {\n const length = view.getUint32(offset, true);\n const type = view.getUint32(offset + 4, true);\n const start = offset + 8;\n if (type === CHUNK_JSON) {\n const text = new TextDecoder().decode(new Uint8Array(glb, start, length));\n let document: { nodes?: Array<{ extras?: Record<string, unknown> }> };\n try {\n document = JSON.parse(text);\n } catch {\n // A GLB whose JSON does not parse is a problem for the exporter to\n // report, not for this function to guess at.\n return ids;\n }\n for (const node of document.nodes ?? []) {\n const id = node.extras?.bakery3Id;\n if (typeof id === 'string' && id) ids.add(id);\n }\n return ids;\n }\n offset = start + length + ((4 - (length % 4)) % 4);\n }\n return ids;\n}\n\n/**\n * Every id an animation channel is allowed to name.\n *\n * The union the renderer resolves against: nodes in the GLB, plus the lights\n * in the manifest. A lamp is described in the manifest rather than exported\n * as a glTF node, so it is addressable without appearing in the file.\n */\nexport function addressableIds(\n manifest: SceneManifest,\n glb: ArrayBuffer,\n): Set<string> {\n const ids = exportedObjectIds(glb);\n for (const light of manifest.lights ?? []) ids.add(light.objectId);\n return ids;\n}\n\n/**\n * Refuse an animation whose channels name something the upload does not carry.\n *\n * This is the last gate before the bytes leave. Failing here costs nothing;\n * failing at the renderer costs an upload, a queue slot, and a message that\n * cannot name the object.\n */\nexport function assertAnimationTargets(\n animation: AnimationSpec,\n manifest: SceneManifest,\n glb: ArrayBuffer,\n names?: Map<string, string>,\n): void {\n const addressable = addressableIds(manifest, glb);\n // An empty set means the GLB carried no stamps at all (a patched exporter,\n // or a scene of nothing). Refusing every channel on that basis would turn a\n // capture problem into a confusing animation problem.\n if (addressable.size === 0) return;\n\n for (const channel of animation.channels) {\n if (channel.target.type !== 'object') continue;\n const id = channel.target.objectId;\n if (addressable.has(id)) continue;\n const name = names?.get(id);\n throw new Bakery3Error({\n code: 'InvalidRequest',\n message: `The timeline animates \"${channel.property}\" on ${\n name ? `\"${name}\"` : `an object (${id.slice(0, 8)}…)`\n }, which did not make it into the exported scene.`,\n why: 'The channel would arrive at the renderer with an id that matches nothing in the GLB, and the render would refuse after the upload rather than here.',\n fix: `Check that the object is still in the scene and is exportable: it must not be a helper, a gizmo, or marked userData.bakery3.exclude. Otherwise drop the track with timeline.removeTrack().`,\n docs: 'https://bakery3.com/docs/animation',\n });\n }\n}\n","/**\n * A bake in flight: the same shape as a render job, with a bundle at the end\n * instead of an image.\n *\n * const job = await raytrace.bake({ settings: { textureSize: 1024 } });\n * const { bundle } = await job.result();\n * await session.apply(session.addGeneration(bundle));\n *\n * `result()` does one thing a render's does not: it reads bundle.json from\n * storage and rewrites every uri in it to the signed URL the control plane\n * issued for that file. The bundle you get is therefore self-contained:\n * `createBakeSession` loads it with no `baseUrl`, and nothing on the SDK side\n * knows where the storage is.\n */\n\nimport type {\n BakeBundle,\n BakeRecord,\n BakeResult,\n RenderState,\n} from '../protocol/index.js';\nimport type { Bakery3Client } from '../client.js';\nimport { Bakery3Error } from '../errors.js';\nimport { PolledJob } from '../job.js';\n\n/** What `await job.result()` gives back. */\nexport type BakeOutput = Omit<BakeResult, 'summary'> & {\n /** The full bundle, uv arrays included, with every uri already a URL. */\n bundle: BakeBundle;\n};\n\nexport type BakeJobEvents = {\n queued: { bake: BakeRecord };\n progress: { percent: number; state: RenderState; bake: BakeRecord };\n complete: { output: BakeOutput; bake: BakeRecord };\n failed: { error: Bakery3Error; bake: BakeRecord };\n cancelled: { bake: BakeRecord };\n};\n\n/** A bake is seconds to minutes and has no preview to catch early, so the\n * schedule starts slacker than a render's and settles at the same pace. */\nconst POLL_SCHEDULE = [800, 800, 1000, 1500, 2000, 3000];\n\n/**\n * Polling starts on the first `on()` or `result()`; a listener added late\n * hears the latest `progress` and how the bake ended. `stop()` stops watching\n * and `cancel()` stops the bake, as for a render (see `RenderJob`).\n */\nexport class BakeJob extends PolledJob<BakeRecord, BakeOutput, BakeJobEvents> {\n protected readonly jobNoun = 'bake';\n protected readonly pollSchedule = POLL_SCHEDULE;\n protected readonly replayedEvents: ReadonlyArray<keyof BakeJobEvents> = [\n 'progress',\n 'complete',\n 'failed',\n 'cancelled',\n ];\n\n private readonly fetchImpl: typeof fetch;\n private lastState: RenderState | null = null;\n\n constructor(\n client: Bakery3Client,\n record: BakeRecord,\n fetchImpl?: typeof fetch,\n ) {\n super(client, record);\n // The client's own fetch unless one is named, so a bundle is read the\n // way every other request is.\n this.fetchImpl =\n fetchImpl ??\n (client as { fetch?: typeof fetch }).fetch ??\n globalThis.fetch.bind(globalThis);\n }\n\n /** The estimate this bake was accepted under. */\n get estimate() {\n return this.record.estimate;\n }\n\n /**\n * Ask the server to stop the bake. It ends as `cancelled`: `cancelled` is\n * emitted and `result()` rejects with code `Cancelled`. To stop watching\n * without stopping the bake, call `stop()`.\n */\n async cancel(): Promise<void> {\n this.applyRecord(await this.client.cancelBake(this.id));\n }\n\n protected readRecord(signal: AbortSignal): Promise<BakeRecord> {\n return this.client.getBake(this.id, { signal });\n }\n\n protected observeRecord(record: BakeRecord): void {\n if (record.state !== this.lastState) {\n this.lastState = record.state;\n if (record.state === 'queued') this.emitEvent('queued', { bake: record });\n }\n this.emitEvent('progress', {\n percent: Math.round(record.progress * 100),\n state: record.state,\n bake: record,\n });\n }\n\n protected async completeRecord(record: BakeRecord): Promise<BakeOutput> {\n const output = await this.resolve(record.result!);\n this.emitEvent('complete', { output, bake: record });\n return output;\n }\n\n protected recordPayload(record: BakeRecord): { bake: BakeRecord } {\n return { bake: record };\n }\n\n /**\n * bundle.json from storage, every uri replaced by its signed URL.\n *\n * A name the bundle uses that the control plane signed nothing for is a\n * refusal here, with the name: never a bundle that quietly points at a\n * texture the browser will 403 on ten seconds later.\n */\n private async resolve(result: BakeResult): Promise<BakeOutput> {\n const response = await this.fetchImpl(result.bundleUrl).catch(\n (cause: Error) => {\n throw new Bakery3Error({\n code: 'NetworkError',\n message: `Could not fetch the bake bundle: ${cause.message}`,\n retryable: true,\n });\n },\n );\n if (!response.ok) {\n throw new Bakery3Error({\n code: 'WorkerFailure',\n message: `The bake bundle could not be read from storage (${response.status}).`,\n why: 'The signed URL was refused. These expire after 24 hours.',\n fix: 'Fetch the bake again with bakery3.getBake(id) for fresh URLs.',\n docs: 'https://bakery3.com/docs/bake',\n retryable: true,\n });\n }\n const bundle = (await response.json()) as BakeBundle;\n\n const url = (uri: string, what: string): string => {\n const signed = result.files[uri];\n if (!signed) {\n throw new Bakery3Error({\n code: 'WorkerFailure',\n message: `The bake bundle names ${what} \"${uri}\" that storage has no signed URL for.`,\n why: 'The render worker wrote a file the control plane did not sign, or the upload of that file failed.',\n fix: 'Bake again. If it repeats, this is a bug on our side: write to hello@bakery3.com with the bake id.',\n docs: 'https://bakery3.com/docs/bake',\n retryable: true,\n });\n }\n return signed;\n };\n\n const resolved: BakeBundle = {\n ...bundle,\n objects: bundle.objects.map((object) => ({\n ...object,\n lightmap: {\n ...object.lightmap,\n uri: url(object.lightmap.uri, 'a lightmap'),\n },\n ...(object.preview\n ? { preview: { uri: url(object.preview.uri, 'a preview') } }\n : {}),\n })),\n ...(bundle.atlas\n ? {\n atlas: {\n ...bundle.atlas,\n uri: url(bundle.atlas.uri, 'the atlas'),\n ...(bundle.atlas.preview\n ? {\n preview: {\n uri: url(bundle.atlas.preview.uri, 'the atlas preview'),\n },\n }\n : {}),\n },\n }\n : {}),\n ...(bundle.proxies\n ? {\n proxies: bundle.proxies.map((proxy) =>\n proxy.kind === 'billboard'\n ? {\n ...proxy,\n map: {\n ...proxy.map,\n uri: url(proxy.map.uri, 'a billboard'),\n },\n }\n : proxy.kind === 'decimated'\n ? {\n ...proxy,\n lightmap: {\n ...proxy.lightmap,\n uri: url(\n proxy.lightmap.uri,\n \"a decimated object's lightmap\",\n ),\n },\n }\n : {\n ...proxy,\n color: {\n uri: url(proxy.color.uri, \"a stand-in's color map\"),\n },\n normal: {\n uri: url(proxy.normal.uri, \"a stand-in's normal map\"),\n },\n lightmap: {\n ...proxy.lightmap,\n uri: url(proxy.lightmap.uri, \"a stand-in's lightmap\"),\n },\n },\n ),\n }\n : {}),\n ...(bundle.shadow\n ? {\n shadow: {\n ...bundle.shadow,\n uri: url(bundle.shadow.uri, 'the shadow plane'),\n },\n }\n : {}),\n ...(bundle.glb ? { glb: { uri: url(bundle.glb.uri, 'the GLB') } } : {}),\n ...(bundle.probe\n ? {\n probe: {\n ...bundle.probe,\n uri: url(bundle.probe.uri, 'the reflection probe'),\n ...(bundle.probe.preview\n ? {\n preview: {\n ...bundle.probe.preview,\n uri: url(bundle.probe.preview.uri, 'the probe preview'),\n },\n }\n : {}),\n },\n }\n : {}),\n };\n\n const { summary: _summary, ...rest } = result;\n return { ...rest, bundle: resolved };\n }\n}\n","/**\n * Upload only what the service does not already have.\n *\n * The whole flow, and the reason a second render feels instant:\n *\n * hash locally -> which of these exist? -> PUT only the misses\n *\n * First render Uploaded: 148 MB\n * Camera moves Uploaded: 2 KB\n * Texture change Uploaded: 6 MB\n *\n * Bytes go from the browser to object storage directly, on a presigned PUT.\n * The control plane never touches them, so the upload runs as fast as the\n * developer's connection allows.\n */\n\nimport type { AssetCheckResponse, AssetDescriptor } from './protocol/index.js';\nimport type { Bakery3Client } from './client.js';\nimport { Bakery3Error } from './errors.js';\n\nexport type UploadProgress = {\n /** Assets that were already in storage: the cache hit. */\n cached: number;\n /** Assets uploaded this time. */\n uploaded: number;\n bytesUploaded: number;\n bytesTotal: number;\n};\n\nexport type CapturedAsset = AssetDescriptor & { data: ArrayBuffer };\n\n/** More than this in flight at once and a large scene starves the main thread\n * of network without finishing any single asset sooner. */\nconst CONCURRENCY = 4;\nconst ATTEMPTS = 3;\n\nexport async function uploadMissingAssets(\n client: Bakery3Client,\n assets: CapturedAsset[],\n onProgress?: (progress: UploadProgress) => void,\n): Promise<UploadProgress> {\n const check: AssetCheckResponse = await client.checkAssets({\n assets: assets.map(({ data: _data, ...descriptor }) => descriptor),\n });\n\n // The client's own fetch, so a test, a proxy or a runtime with its own\n // fetch sees the uploads too, not only the API calls.\n const fetchImpl =\n (client as { fetch?: typeof fetch }).fetch ??\n globalThis.fetch.bind(globalThis);\n const targets = new Map(check.uploads.map((upload) => [upload.hash, upload]));\n const missing = assets.filter((asset) => targets.has(asset.hash));\n\n const progress: UploadProgress = {\n cached: assets.length - missing.length,\n uploaded: 0,\n bytesUploaded: 0,\n bytesTotal: missing.reduce((sum, asset) => sum + asset.bytes, 0),\n };\n onProgress?.(progress);\n\n // A fixed pool rather than Promise.all over everything: a 500 MB scene is\n // dozens of assets, and firing them all at once makes the browser queue\n // them anyway while making progress reporting useless.\n const queue = [...missing];\n const workers = Array.from(\n { length: Math.min(CONCURRENCY, queue.length) },\n async () => {\n for (;;) {\n const asset = queue.shift();\n if (!asset) return;\n const target = targets.get(asset.hash)!;\n await put(asset, target, fetchImpl);\n progress.uploaded++;\n progress.bytesUploaded += asset.bytes;\n onProgress?.({ ...progress });\n }\n },\n );\n await Promise.all(workers);\n\n return progress;\n}\n\nasync function put(\n asset: CapturedAsset,\n target: AssetCheckResponse['uploads'][number],\n fetchImpl: typeof fetch,\n): Promise<void> {\n let last = '';\n for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {\n try {\n const response = await fetchImpl(target.url, {\n method: 'PUT',\n // Verbatim. A presigned PUT is signed over an exact header set, so an\n // extra or missing header is a 403 that reads like an auth bug.\n headers: { ...target.headers },\n body: asset.data,\n });\n if (response.ok) return;\n last = `${response.status} ${response.statusText}`;\n // A 4xx is a verdict on this request: an expired URL or a header the\n // signature does not cover will say the same thing next time.\n if (response.status < 500 && response.status !== 429) break;\n } catch (error) {\n last = error instanceof Error ? error.message : String(error);\n }\n if (attempt < ATTEMPTS) {\n await new Promise((resolve) => setTimeout(resolve, attempt * 500));\n }\n }\n\n throw new Bakery3Error({\n code: 'AssetUploadIncomplete',\n message: `Could not upload ${asset.name ?? asset.kind} (${formatBytes(asset.bytes)}): ${last}`,\n why: 'The presigned upload URL was rejected. These expire, and they are signed over an exact set of headers.',\n fix: 'Retry the render. If it keeps failing, check for a service worker or proxy that rewrites request headers.',\n docs: 'https://bakery3.com/docs/uploads',\n retryable: true,\n });\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / 1024 / 1024).toFixed(1)} MB`;\n}\n","/**\n * @oeave/bakery3: ray trace the Three.js scene you're already rendering.\n *\n * import { createBakery3 } from '@oeave/bakery3';\n *\n * const bakery3 = createBakery3({\n * token: () => fetch('/api/bakery3-token', { method: 'POST' }).then(r => r.json()),\n * });\n *\n * const job = await bakery3.render({ scene, camera, quality: 'studio' });\n * const image = await job.result();\n *\n * Everything else in this package exists to make those five lines true from\n * inside a real application: no manual GLB export, no 3D suite, no dashboard\n * upload, no re-creating configurator state.\n *\n * While you are still finding out whether this works at all, there is a\n * shorter version that needs no server:\n *\n * const bakery3 = createBakery3({ apiKey: 'bk_sk_…' });\n *\n * It renders, and it prints a console warning telling you to move the key\n * behind a token endpoint before you ship: from a browser, `apiKey` is\n * readable by every visitor.\n */\n\nimport type { Camera, Scene } from 'three';\nimport type {\n BatchOpenRequest,\n CompatibilityReport,\n CostEstimate,\n OutputSpec,\n QualityPreset,\n RenderSpec,\n SceneManifest,\n} from './protocol/index.js';\nimport { protocolVersionFor } from './protocol/index.js';\nimport {\n createTimeline,\n Timeline,\n type TimelineOptions,\n} from './timeline/index.js';\nimport { bindTimelineContext } from './timeline/timeline.js';\nimport {\n Bakery3Client,\n type ClientOptions,\n type EstimateRequest,\n} from './client.js';\nimport { RenderJob } from './job.js';\nimport { Batch } from './batch.js';\nimport {\n RenderSet,\n RenderSetRefused,\n defaultVariantId,\n record as recordPictures,\n type Recording,\n type VariantCleanup,\n type VariantProgress,\n type VariantsQuote,\n type ViewCamera,\n} from './renderSet.js';\nimport type { CatalogFinish } from './variant.js';\nimport {\n quoteKey,\n sampleOf,\n testSettings,\n type TestRunOptions,\n} from './testRun.js';\nimport {\n captureScene,\n type CaptureOptions,\n type CapturedScene,\n} from './capture/capture.js';\nimport { assertAnimationTargets } from './capture/exported.js';\nimport { idOf } from './capture/ids.js';\nimport { shouldExclude } from './capture/scene.js';\nimport { rememberEnvironmentSource } from './capture/environmentSource.js';\nimport { analyzeScene } from './compat/analyze.js';\nimport { captureFog } from './capture/scene.js';\nimport { sceneComplexity } from './capture/complexity.js';\nimport { resolveOutput } from './capture/output.js';\nimport { tracedTriangles } from './capture/stats.js';\nimport { findPresetRooms } from './presets/roomState.js';\nimport { BakeJob } from './bake/job.js';\nimport {\n bakeQuoteOf,\n prepareBake,\n quoteBake,\n type PrepareBakeSettings,\n} from './bake/prepare.js';\nimport { uploadMissingAssets, type UploadProgress } from './upload.js';\nimport {\n Bakery3Error,\n BatchPageRefused,\n RenderBudgetExceeded,\n} from './errors.js';\nimport { SDK_VERSION } from './version.js';\n\nexport type Bakery3Options = ClientOptions & {\n /**\n * Defaults folded into every `render()`, `renderVideo()`, `estimate()` and\n * variants run. Set once at the provider so a render button stays one\n * line. A size given to a call replaces the default size as a whole.\n */\n defaults?: {\n quality?: QualityPreset;\n output?: Partial<OutputSpec>;\n maxCost?: number;\n };\n};\n\nexport type RenderOptions = Partial<CaptureOptions> & {\n scene?: Scene;\n camera?: Camera;\n quality?: QualityPreset;\n /**\n * Leave both out for the preset's long edge in the camera's shape (a 16:9\n * viewport renders 16:9). Give one and the other follows the camera's\n * aspect; give both for exactly that size.\n */\n width?: number;\n height?: number;\n format?: OutputSpec['format'];\n /** JPEG/WebP only, 1–100. */\n imageQuality?: number;\n /** Refuse the render rather than exceed this, in USD. */\n maxCost?: number;\n /** Ask for a low-sample preview. Defaults to the quality preset's own answer. */\n preview?: boolean;\n advanced?: RenderSpec['advanced'];\n metadata?: Record<string, unknown>;\n /** A resubmit with the same key returns the existing render, never a second\n * charge, which is what makes your own retry button safe. */\n idempotencyKey?: string;\n /**\n * `high` puts this render ahead of the account's other waiting work in\n * the same lane: the hero shot before the rest. It never jumps a lane, so\n * a person waiting in a configurator still goes first.\n */\n priority?: RenderSpec['priority'];\n /** Called while assets upload. Most renders after the first report 0 bytes. */\n onUpload?: (progress: UploadProgress) => void;\n};\n\n/**\n * `render()` from several cameras at once: one capture, one upload, one\n * picture per camera. Everything else means what it means for one render,\n * except `maxCost`, which is the ceiling for the whole set, and\n * `idempotencyKey`, which names the set: a resubmit under the same key\n * returns the same pictures and never a second charge.\n */\nexport type RenderCamerasOptions = Omit<\n RenderOptions,\n 'camera' | 'priority'\n> & {\n /** Names of cameras in the scene, Camera objects, or `{ id, position, target, fov }`. */\n cameras: ViewCamera[];\n};\n\n/** How every picture of a variants run is traced: the same settings `render()` takes. */\ntype PictureOptions = Pick<\n RenderOptions,\n | 'scene'\n | 'quality'\n | 'width'\n | 'height'\n | 'format'\n | 'imageQuality'\n | 'preview'\n | 'advanced'\n | 'renderer'\n | 'environment'\n | 'productState'\n | 'background'\n>;\n\n/**\n * Every variant, from every camera.\n *\n * A variant is whatever your configurator calls one: a row from the product\n * database, a SKU, a `{ model, color }`. `apply` puts your scene in that\n * state, exactly as a customer clicking would, and the SDK photographs it.\n * One variant is resident at a time, and `variants` may be a generator or an\n * async cursor, so neither the scene nor the list has to fit in memory.\n */\nexport type RenderVariantsOptions<V> = PictureOptions & {\n /**\n * Names the run. Stable across re-runs: the same key re-opens the same\n * run while it is unfinished, so a recorder that died at variant 140 is\n * resumed by calling this again.\n */\n key: string;\n name?: string;\n /** An array, a generator, an async cursor. Pulled one at a time, never collected. */\n variants: Iterable<V> | AsyncIterable<V>;\n /**\n * Put the scene in this variant's state. Return a function to undo it\n * (remove the model, dispose what it held); it runs before the next\n * variant is applied. Leave `apply` out when the variants differ only by\n * `finishes`.\n */\n apply?: (\n variant: V,\n ) => void | VariantCleanup | Promise<void | VariantCleanup>;\n /** Default: `variant.id`, `.sku` or `.key`, or the variant itself when it is a string. */\n id?: (variant: V, index: number) => string;\n /**\n * Finishes that are all inside the model already, told apart by which\n * objects show. Each becomes its own picture from the variant's one\n * capture: no second export, no second upload.\n */\n finishes?: (variant: V) => CatalogFinish[] | undefined;\n /** Default: the live camera. */\n cameras?: ViewCamera[];\n /** Echoed on every picture, its webhooks and the ledger, beside `variant`, `finish` and `camera`. */\n metadata?: (variant: V) => Record<string, unknown>;\n /**\n * Appended to every picture's key as `@version`. A picture is adopted, at\n * no cost, when its key already rendered, so bump this when the pictures\n * must be traced again: a new room, a new look.\n */\n version?: string;\n /** The ceiling for the whole run, in dollars. `quoteVariants()` gives the number to set it from. */\n maxCost: number;\n /** A ceiling for each picture, under the run's. One over it is refused alone. */\n maxCostPerImage?: number;\n /** `batch` (the default) never runs ahead of a person in a configurator. */\n lane?: 'batch' | 'normal';\n /** Fewer pictures at once than the plan allows. */\n maxParallel?: number;\n /** After every variant is recorded. For progress while they render, `run.wait({ onProgress })`. */\n onProgress?: (progress: VariantProgress) => void;\n /** Stops between variants. What was recorded stays admitted; call again to go on. */\n signal?: AbortSignal;\n};\n\n/**\n * What `capture()` returns: the manifest and the blobs it names, plus the\n * ids the manifest uses, by object name, so a caller can build variants of\n * one capture (hide these, look from there) without a second export.\n */\nexport type Capture = CapturedScene & {\n /**\n * Object name → the id the manifest addresses it by (`hiddenObjectIds`,\n * `transforms`, lights). Unnamed objects are absent; when two objects\n * share a name the first in traversal order wins, so name what you mean\n * to address.\n */\n objects: Record<string, string>;\n /** What `uploadAssets()` uploaded, once it has run. */\n upload?: UploadProgress;\n};\n\n/** The batch half of the SDK. */\nexport type BatchesApi = {\n /**\n * Open a batch, or re-open it: the same `key` returns the same batch\n * while it is not terminal, and items already completed under their keys\n * are adopted rather than rendered again.\n */\n open(request: BatchOpenRequest): Promise<Batch>;\n /** A batch by id, with its latest counts. */\n get(id: string): Promise<Batch>;\n};\n\nexport type EstimateOptions = {\n scene?: Scene;\n /**\n * The camera the render would use. An interior is priced as one from\n * where the camera stands (how much of it is walled in), so the default is\n * the client's own camera.\n */\n camera?: Camera;\n quality?: QualityPreset;\n /** The same rule as `render()`: the camera's shape when left out. */\n width?: number;\n height?: number;\n advanced?: RenderSpec['advanced'];\n /** Quote a clip: how many frames. A frame in a clip costs less than a still. */\n frames?: number;\n /**\n * Quote a bake instead of a render: the same `settings` `bake()` takes.\n * The scene is read the way the bake reads it (the include list, a preset\n * room, stand-ins from `simplify` and from `userData.bakery3.simplify`),\n * so the quote is the one the bake is accepted under.\n */\n bake?: PrepareBakeSettings;\n};\n\n/**\n * What `bake()` takes: the capture, plus what to bake and how well.\n *\n * `settings` is the same object `estimate({ bake })` takes, so a quote and\n * the bake it prices cover the same objects. By default: every object that\n * can hold a lightmap, at 1024², `standard` quality, seams hidden from the\n * camera you pass.\n */\nexport type BakeOptions = Partial<CaptureOptions> & {\n scene?: Scene;\n camera?: Camera;\n settings?: PrepareBakeSettings;\n /** Refuse the bake rather than exceed this, in USD. */\n maxCost?: number;\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n onUpload?: (progress: UploadProgress) => void;\n};\n\n/** Everything `render()` takes, plus the move. */\nexport type RenderVideoOptions = RenderOptions & {\n /** The motion to trace. Baked into the manifest at submit time. */\n timeline: Timeline;\n /** Overrides the timeline's own rate for this render only. */\n fps?: number;\n /**\n * Default `'mp4'`. `'mp4'` and `'webm'` are opaque: no codec here carries\n * alpha, and supporting it in one container only would mean the same\n * manifest producing two visibly different videos.\n *\n * `'png-sequence'` keeps the alpha: every frame is the PNG a still of it\n * would be (transparent background, the shadow in alpha), all of them in\n * one uncompressed tar with `frames.json` first, for compositing the\n * product between layers of your own. The result's `url` is the tar.\n */\n format?: 'mp4' | 'webm' | 'png-sequence';\n /**\n * `'png-sequence'` only: bits per channel, 16 (the default, as a still's\n * PNG is) or 8, whose frames are less than half the size.\n */\n bitDepth?: 8 | 16;\n};\n\nexport type Bakery3 = {\n /**\n * Capture the current scene, upload what is missing, start the render.\n *\n * With `cameras`, the same capture photographed from each of them: one\n * export, one upload, a `RenderSet` of pictures back.\n *\n * const shots = await bakery3.render({ cameras: ['hero', 'front', 'detail'] });\n * const [hero, front, detail] = await shots.result();\n *\n * `result()` gives one picture per camera, in order, or rejects: with\n * `RenderSetRefused` (its `refusals` name the cameras and the reasons)\n * when a picture was turned down at submission, so a destructured array\n * never shifts. Every picture is one size, in the first camera's shape.\n */\n render(options: RenderCamerasOptions): Promise<RenderSet>;\n render(options?: RenderOptions): Promise<RenderJob>;\n /**\n * Every variant, from every camera, however many there are.\n *\n * const run = await bakery3.renderVariants({\n * key: 'fall-2026',\n * variants: products,\n * apply: (product) => configurator.show(product),\n * cameras: ['hero', 'front', 'detail'],\n * maxCost: 600,\n * });\n * await run.wait();\n * for await (const image of run.images()) save(image);\n *\n * Resolves once every variant is recorded and the run is sealed; the\n * pictures render on from there whether or not the page stays open.\n * Calling it again with the same `key` resumes a recording that stopped\n * and adopts every picture that already rendered.\n */\n renderVariants<V>(options: RenderVariantsOptions<V>): Promise<RenderSet>;\n /**\n * What `renderVariants()` would cost, to the picture: the same walk, with\n * nothing uploaded, admitted or reserved.\n *\n * The pages are priced on a batch of their own, keyed `${key}:quote` and\n * cancelled once the quote is in, never on the run's: the run's batch is\n * opened by `renderVariants()`, with its `maxCost`, and nothing else.\n * Pictures that already rendered under their keys are quoted as adopted,\n * at nothing, so this is the price of a re-run too.\n */\n quoteVariants<V>(\n options: Omit<RenderVariantsOptions<V>, 'maxCost'> & { maxCost?: number },\n ): Promise<VariantsQuote>;\n /**\n * Look before paying: three variants (the first, the middle and the last\n * of an array; the first three of anything else) from every camera and in\n * every finish, at preview quality and a small size, in the ordinary lane\n * so they come back in a minute. Same options as `renderVariants()`. The\n * test has its own keys, so the real run never adopts these previews.\n *\n * const test = await bakery3.testVariants(options);\n * for (const image of await test.result()) show(image.variant, image.camera, image.url);\n */\n testVariants<V>(\n options: Omit<RenderVariantsOptions<V>, 'maxCost'> & { maxCost?: number },\n test?: TestRunOptions,\n ): Promise<RenderSet>;\n /** A set by id: after a reload, in another tab, from a webhook. */\n getRenderSet(id: string): Promise<RenderSet>;\n /**\n * A timeline bound to the attached scene and camera.\n *\n * const tl = bakery3.timeline({ duration: 4 });\n * tl.push({ object: 'camera', orbitY: 90 });\n * const job = await bakery3.renderVideo({ timeline: tl });\n *\n * The scene and camera are read from `attach()` when the timeline needs\n * them, so one made before the attachment still drives the camera\n * attached later. A camera move with no camera by then is refused.\n */\n timeline(options?: TimelineOptions): Timeline;\n /**\n * The same capture as `render()`, plus the baked timeline, as a video.\n *\n * A clip is priced by its frame count: one start-up floor, then every\n * frame at a fraction of a still, because one session traces them all.\n * `estimate({ frames })` gives the same quote the clip is accepted under,\n * and `maxCost` is checked against it before anything uploads.\n */\n renderVideo(options: RenderVideoOptions): Promise<RenderJob>;\n /**\n * Path-traced lighting for the scene you are already rendering.\n *\n * const job = await bakery3.bake();\n * const { bundle } = await job.result();\n * const session = createBakeSession({ scene }); // @oeave/bakery3/bake\n * await session.apply(session.addGeneration(bundle));\n *\n * The same capture as `render()`, the same asset upload, and a bundle of\n * lightmaps back (one per object, or one atlas) with its textures on\n * signed URLs the session loads directly.\n */\n bake(options?: BakeOptions): Promise<BakeJob>;\n /** A bake by id, for fresh URLs after the old ones expired. */\n getBake(id: string): Promise<BakeJob>;\n /**\n * A render by id: after a reload, in another tab, from a webhook. Its\n * `result()` signs fresh URLs when the old ones have expired.\n */\n getRender(id: string): Promise<RenderJob>;\n /** What this would cost, before anything expensive happens. */\n estimate(options?: EstimateOptions): Promise<CostEstimate>;\n /**\n * Local, free, offline: what would and would not translate.\n *\n * No account needed and no bytes leave the browser, so \"will my scene\n * work?\" can be answered before signing up.\n */\n check(scene?: Scene): CompatibilityReport;\n /** The captured manifest, without rendering. For debugging, and for seeing exactly what leaves the browser. */\n inspect(options?: RenderOptions): Promise<SceneManifest>;\n /**\n * The same capture `render()` starts from, handed back instead of\n * submitted: the manifest, its assets, and the object ids by name. What a\n * catalog recorder builds its variants from: one export per product,\n * a few KB of manifest per still.\n */\n capture(options?: RenderOptions): Promise<Capture>;\n /**\n * Upload a capture's assets that storage does not already have. Once per\n * capture; every manifest derived from it then names bytes that exist.\n */\n uploadAssets(\n capture: Pick<Capture, 'assets'>,\n onProgress?: (progress: UploadProgress) => void,\n ): Promise<UploadProgress>;\n /** Batches: a declared body of work, admitted in pages, one poll for all of it. */\n readonly batches: BatchesApi;\n /** Point the SDK at the app's live scene and camera once, at mount. */\n attach(context: {\n scene: Scene;\n camera: Camera;\n renderer?: CaptureOptions['renderer'];\n }): void;\n readonly version: string;\n};\n\nexport function createBakery3(options: Bakery3Options = {}): Bakery3 {\n const client = new Bakery3Client(options);\n const defaults = options.defaults ?? {};\n /** The developer's fetch, for reading a bake bundle the way the client reads everything else. */\n const clientFetch = options.fetch;\n\n /**\n * The live scene, camera and renderer, set by `attach`.\n *\n * This is what lets an R3F developer write `render()` with no arguments:\n * the provider attaches once at mount, and the render button does not have\n * to thread `scene` and `camera` down through the component tree. Passing\n * them explicitly always wins.\n */\n let attached: {\n scene: Scene;\n camera: Camera;\n renderer?: CaptureOptions['renderer'];\n } | null = null;\n\n function resolveScene(explicit: Scene | undefined, method: Method): Scene {\n const scene = explicit ?? attached?.scene;\n if (!scene) throw missingContext(method, 'scene');\n return scene;\n }\n\n function resolveCamera(explicit: Camera | undefined, method: Method): Camera {\n const camera = explicit ?? attached?.camera;\n if (!camera) throw missingContext(method, 'camera');\n return camera;\n }\n\n /** Once per client: the warning is about a setup, not about a render. */\n let warnedRenderer = false;\n\n /**\n * The renderer whose color settings a capture reads. Without one, three's\n * defaults are assumed (no tone mapping, exposure 1), which is right\n * headless and usually wrong in a page whose viewport tone maps: the render\n * then looks darker or flatter than what the developer sees. Said once.\n */\n function rendererFor(\n explicit: CaptureOptions['renderer'] | undefined,\n ): CaptureOptions['renderer'] | undefined {\n const renderer = explicit ?? attached?.renderer;\n if (!renderer && !warnedRenderer && inBrowser()) {\n warnedRenderer = true;\n console.warn(\n 'Bakery3: no renderer was given, so this render uses no tone mapping and an exposure of 1, and can look darker or flatter than your viewport. Pass renderer to render(), or call bakery3.attach({ scene, camera, renderer }) once. https://bakery3.com/docs/troubleshooting#the-render-is-darker-or-flatter-than-my-viewport',\n );\n }\n return renderer;\n }\n\n /**\n * The size a call renders at, by the one rule (`capture/output.ts`): the\n * preset's long edge in the camera's shape unless a size was given, every\n * field of `defaults.output` honored.\n */\n function outputFor(\n call: Pick<RenderOptions, 'width' | 'height' | 'format' | 'imageQuality'>,\n quality: QualityPreset,\n camera: Camera | undefined,\n renderer: unknown,\n even = false,\n ): OutputSpec {\n return resolveOutput(call, defaults.output, {\n quality,\n camera: camera ?? null,\n renderer,\n even,\n });\n }\n\n /**\n * The quote request for a still or a clip. `estimate()` and the `maxCost`\n * checks of `render()` and `renderVideo()` all send this, so a quote is\n * the one the render is accepted under.\n */\n function renderQuote(input: {\n quality: QualityPreset;\n output: OutputSpec;\n advanced: RenderSpec['advanced'] | undefined;\n scene: Scene;\n camera: Camera;\n frames?: number;\n }): EstimateRequest {\n return {\n quality: input.quality,\n // Only the size is priced. The format is left out of the quote so that\n // `estimate({ frames })` and the clip it precedes send the same body.\n output: {\n width: input.output.width,\n height: input.output.height,\n format: 'png',\n },\n ...(input.advanced ? { advanced: input.advanced } : {}),\n scene: estimateScene(input.scene, input.camera),\n ...(input.frames ? { frames: input.frames } : {}),\n };\n }\n\n async function capture(options: RenderOptions, method: Method) {\n return captureScene({\n scene: resolveScene(options.scene, method),\n camera: resolveCamera(options.camera, method),\n renderer: rendererFor(options.renderer),\n environment: options.environment,\n productState: options.productState,\n background: options.background,\n });\n }\n\n /** What a recording needs of this client: a capture with its ids by name, and the uploader. */\n function recorderHost(\n options: PictureOptions,\n method: Method,\n ): Recording<unknown>['host'] {\n return {\n async capture({ scene, camera }) {\n const captured = await capture({ ...options, scene, camera }, method);\n return { ...captured, objects: objectIdsByName(scene) };\n },\n uploadAssets: (captured, onProgress) =>\n uploadMissingAssets(client, captured.assets, onProgress),\n };\n }\n\n /**\n * The size every picture of a set is traced at. One size for the set, so a\n * catalog grid lines up, in the shape of the first camera of the list that\n * is a camera (an object, or a name in the scene now), else the live one.\n */\n function setOutput(\n options: PictureOptions,\n cameras: ViewCamera[] | undefined,\n scene: Scene,\n ): OutputSpec {\n const quality = options.quality ?? defaults.quality ?? 'studio';\n return outputFor(\n options,\n quality,\n firstCamera(cameras, scene) ?? attached?.camera,\n options.renderer ?? attached?.renderer,\n );\n }\n\n /** The part of a recording that is the same for cameras and for variants: how a picture is traced. */\n function pictures(\n options: PictureOptions,\n cameras: ViewCamera[] | undefined,\n method: Method,\n ) {\n const quality = options.quality ?? defaults.quality ?? 'studio';\n const scene = resolveScene(options.scene, method);\n const output = setOutput(options, cameras, scene);\n return {\n host: recorderHost(options, method),\n scene,\n output,\n spec: (manifest: SceneManifest): RenderSpec => ({\n manifest,\n quality,\n output,\n ...(options.advanced ? { advanced: options.advanced } : {}),\n ...(options.preview !== undefined ? { preview: options.preview } : {}),\n }),\n };\n }\n\n async function renderCameras(\n options: RenderCamerasOptions,\n ): Promise<RenderSet> {\n const maxCost = options.maxCost ?? defaults.maxCost;\n const key = options.idempotencyKey ?? `set_${randomId()}`;\n const plan = pictures(options, options.cameras, 'render');\n // `normal`, not `batch`: somebody asked for these and is waiting.\n const batch = new Batch(\n client,\n await client.openBatch({\n key,\n lane: 'normal',\n ...(maxCost !== undefined ? { maxCost } : {}),\n }),\n );\n const keys: string[] = [];\n const recorded = await recordPictures({\n ...plan,\n batch,\n variants: [key],\n idOf: () => key,\n cameras: options.cameras,\n metadataOf: (_set, ids) => ({ ...options.metadata, camera: ids.camera }),\n keys,\n onVariant: ({ upload }) => upload && options.onUpload?.(upload),\n });\n await batch.close();\n return new RenderSet(batch, recorded).ordered(keys);\n }\n\n function variantsRecording<V>(\n options: Omit<RenderVariantsOptions<V>, 'maxCost'>,\n batch: Batch,\n method: Method,\n ): Recording<V> {\n const cameras = options.cameras ?? [resolveCamera(undefined, method)];\n return {\n ...pictures(options, cameras, method),\n batch,\n variants: options.variants,\n idOf: options.id ?? defaultVariantId,\n ...(options.apply ? { apply: options.apply } : {}),\n ...(options.finishes ? { finishesOf: options.finishes } : {}),\n cameras,\n metadataOf: (variant, ids) => ({\n ...options.metadata?.(variant),\n ...ids,\n }),\n ...(options.version ? { version: options.version } : {}),\n ...(options.maxCostPerImage !== undefined\n ? { maxCostPerImage: options.maxCostPerImage }\n : {}),\n ...(options.signal ? { signal: options.signal } : {}),\n ...(options.onProgress ? { onVariant: options.onProgress } : {}),\n };\n }\n\n function openVariants(\n options: {\n key: string;\n name?: string;\n maxCost?: number;\n lane?: 'batch' | 'normal';\n maxParallel?: number;\n },\n method: Method,\n ) {\n requireRunKey(options.key, method);\n return client.openBatch({\n key: options.key,\n ...(options.name ? { name: options.name } : {}),\n ...(options.maxCost !== undefined ? { maxCost: options.maxCost } : {}),\n lane: options.lane ?? 'batch',\n ...(options.maxParallel !== undefined\n ? { maxParallel: options.maxParallel }\n : {}),\n });\n }\n\n async function renderVariants<V>(\n options: RenderVariantsOptions<V>,\n ): Promise<RenderSet> {\n if (!(options.maxCost > 0)) {\n throw new Bakery3Error({\n code: 'InvalidRequest',\n message: 'renderVariants() needs a maxCost.',\n why: 'A run is as many renders as the variants multiply out to, and a ceiling is what makes that number safe to be wrong about: a page that would cross it is refused, never charged.',\n fix: 'Call quoteVariants() with the same options for the real number, then set `maxCost` a little above its `maximum`.',\n docs: 'https://bakery3.com/docs/batches#estimating-the-whole-catalog',\n });\n }\n const batch = new Batch(\n client,\n await openVariants(options, 'renderVariants'),\n );\n const recorded = await recordPictures(\n variantsRecording(options, batch, 'renderVariants'),\n );\n // Sealed only once every variant is through. A recording that threw\n // leaves the run open, which is what lets the same call go on with it.\n await batch.close();\n return new RenderSet(batch, recorded);\n }\n\n return {\n version: SDK_VERSION,\n\n attach(context) {\n attached = context;\n },\n\n check(scene) {\n const { score, issues, counts } = analyzeScene(\n resolveScene(scene, 'check'),\n );\n return { score, issues, counts };\n },\n\n async inspect(options = {}) {\n return (await capture(options, 'inspect')).manifest;\n },\n\n async capture(options = {}) {\n const captured = await capture(options, 'capture');\n return {\n ...captured,\n objects: objectIdsByName(resolveScene(options.scene, 'capture')),\n };\n },\n\n uploadAssets(captured, onProgress) {\n return uploadMissingAssets(client, captured.assets, onProgress);\n },\n\n batches: {\n async open(request) {\n return new Batch(client, await client.openBatch(request));\n },\n async get(id) {\n return new Batch(client, await client.getBatch(id));\n },\n },\n\n async estimate(options = {}) {\n // Does not export the scene, on purpose. An estimate that costs a\n // 200 MB GLB export is not an estimate, it is a render with no picture,\n // and the devtools panel wants to show a price the moment it opens.\n const scene = resolveScene(options.scene, 'estimate');\n if (options.bake) {\n // The plan `bake()` makes (include list, preset room, stand-ins) and\n // the triangles its capture would count, so this quote and the one\n // the bake is accepted under are one request. An id that cannot take\n // a lightmap refuses here, before anything is exported.\n return client.estimate(\n quoteBake(scene, options.camera ?? attached?.camera, options.bake),\n );\n }\n const camera = resolveCamera(options.camera, 'estimate');\n const quality = options.quality ?? defaults.quality ?? 'studio';\n return client.estimate(\n renderQuote({\n quality,\n // A clip's derived side is even, as `renderVideo()` rounds it.\n output: outputFor(\n options,\n quality,\n camera,\n attached?.renderer,\n Boolean(options.frames),\n ),\n advanced: options.advanced,\n scene,\n camera,\n ...(options.frames ? { frames: options.frames } : {}),\n }),\n );\n },\n\n renderVariants,\n\n async testVariants(options, test = {}) {\n const scene = resolveScene(options.scene, 'testVariants');\n const output = setOutput(\n options,\n options.cameras ?? [resolveCamera(undefined, 'testVariants')],\n scene,\n );\n return renderVariants({\n ...options,\n ...testSettings(\n { key: options.key, width: output.width, height: output.height },\n test,\n ),\n name: `${options.name ?? options.key} (test)`,\n variants: sampleOf(options.variants, test.products),\n });\n },\n\n async quoteVariants(options) {\n // The route that prices a page belongs to a batch, and a batch is\n // opened under a key. Never the run's own: that batch is the one\n // `renderVariants()` opens with its `maxCost`, and one opened here\n // without a ceiling would be the batch the run then re-opens. A batch\n // of its own, priced and then cancelled, holds nothing and keeps the\n // run's key free.\n requireRunKey(options.key, 'quoteVariants');\n const batch = new Batch(\n client,\n await openVariants(\n {\n key: quoteKey(options.key),\n name: `${options.name ?? options.key} (quote)`,\n lane: options.lane ?? 'batch',\n },\n 'quoteVariants',\n ),\n );\n try {\n return await recordPictures({\n ...variantsRecording(options, batch, 'quoteVariants'),\n dryRun: true,\n });\n } finally {\n // Best effort: a quote batch left open holds nothing either.\n await batch.cancel().catch(() => {});\n }\n },\n\n async getRenderSet(id) {\n return new RenderSet(new Batch(client, await client.getBatch(id)));\n },\n\n async getRender(id) {\n return new RenderJob(client, await client.getRender(id));\n },\n\n render: (async (options: RenderOptions | RenderCamerasOptions = {}) => {\n if (hasCameras(options)) return renderCameras(options);\n const scene = resolveScene(options.scene, 'render');\n const camera = resolveCamera(options.camera, 'render');\n const renderer = rendererFor(options.renderer);\n const quality = options.quality ?? defaults.quality ?? 'studio';\n const output = outputFor(options, quality, camera, renderer);\n const maxCost = options.maxCost ?? defaults.maxCost;\n\n const { manifest, assets } = await captureScene({\n scene,\n camera,\n renderer,\n environment: options.environment,\n productState: options.productState,\n background: options.background,\n });\n\n // Budget check before the upload, not just before the render. Pushing\n // 200 MB and then being told the render is too expensive is a bad enough\n // experience to be worth one extra round trip.\n if (maxCost !== undefined) {\n const estimate = await client.estimate(\n renderQuote({\n quality,\n output,\n advanced: options.advanced,\n scene,\n camera,\n }),\n );\n if (estimate.maximumCost > maxCost) {\n throw new RenderBudgetExceeded(maxCost, estimate, 'render');\n }\n }\n\n await uploadMissingAssets(client, assets, options.onUpload);\n\n const created = await client.createRender({\n manifest,\n quality,\n output,\n ...(options.advanced ? { advanced: options.advanced } : {}),\n ...(maxCost !== undefined ? { maxCost } : {}),\n ...(options.preview !== undefined ? { preview: options.preview } : {}),\n ...(options.metadata ? { metadata: options.metadata } : {}),\n ...(options.idempotencyKey\n ? { idempotencyKey: options.idempotencyKey }\n : {}),\n ...(options.priority ? { priority: options.priority } : {}),\n });\n\n return new RenderJob(client, created);\n }) as Bakery3['render'],\n\n async bake(options = {}) {\n const scene = resolveScene(options.scene, 'bake');\n const camera = resolveCamera(options.camera, 'bake');\n const maxCost = options.maxCost ?? defaults.maxCost;\n\n const { spec, assets } = await prepareBake({\n scene,\n camera,\n renderer: rendererFor(options.renderer),\n environment: options.environment,\n productState: options.productState,\n background: options.background,\n ...(options.settings ? { settings: options.settings } : {}),\n ...(maxCost !== undefined ? { maxCost } : {}),\n ...(options.metadata ? { metadata: options.metadata } : {}),\n ...(options.idempotencyKey\n ? { idempotencyKey: options.idempotencyKey }\n : {}),\n });\n\n // Budget check before the upload, as for a render. The quote is built\n // from the prepared spec by the same function `estimate({ bake })`\n // uses, and from the same facts the control plane prices the spec by\n // (stand-ins, the shadow plane, a room around it, the triangles traced\n // and unwrapped), so a refusal here is the refusal the server would\n // give, and costs no bytes.\n if (maxCost !== undefined) {\n const quote = await client.estimate(bakeQuoteOf(spec));\n if (quote.maximumCost > maxCost) {\n throw new RenderBudgetExceeded(maxCost, quote, 'bake');\n }\n }\n\n await uploadMissingAssets(client, assets, options.onUpload);\n\n const record = await client.createBake(spec);\n return new BakeJob(client, record, clientFetch);\n },\n\n async getBake(id) {\n return new BakeJob(client, await client.getBake(id), clientFetch);\n },\n\n timeline(options = {}) {\n // Bound, not copied: the scene and camera are read from `attach()` when\n // the timeline needs them, so a timeline made at mount, before R3F has\n // attached anything, still drives the camera attached later.\n return bindTimelineContext(createTimeline(options), () => attached);\n },\n\n async renderVideo(options) {\n const scene = resolveScene(options.scene, 'renderVideo');\n const camera = resolveCamera(options.camera, 'renderVideo');\n const renderer = rendererFor(options.renderer);\n const quality = options.quality ?? defaults.quality ?? 'studio';\n // A default format counts when it is a clip format; a still's `png`\n // default does not make a clip a PNG.\n const preferred = defaults.output?.format;\n const format: NonNullable<RenderVideoOptions['format']> =\n options.format ??\n (preferred === 'mp4' ||\n preferred === 'webm' ||\n preferred === 'png-sequence'\n ? preferred\n : 'mp4');\n const sequence = format === 'png-sequence';\n // Even sides for a video: H.264 cannot encode an odd one. The image\n // quality of a JPEG or WebP default means nothing to a clip, so it\n // stays behind.\n const { quality: _imageQuality, ...size } = outputFor(\n { ...options, format },\n quality,\n camera,\n renderer,\n !sequence,\n );\n const output: OutputSpec = {\n ...size,\n format,\n ...(sequence && options.bitDepth !== undefined\n ? { bitDepth: options.bitDepth }\n : {}),\n };\n const maxCost = options.maxCost ?? defaults.maxCost;\n\n // Baked before the capture, so a timeline that refers to an object which\n // is not in the scene (the one mistake that would otherwise produce a\n // video silently missing a motion) is refused before a 148 MB GLB is\n // exported, let alone uploaded.\n const animation = options.timeline.bake({\n scene,\n ...(options.fps !== undefined ? { fps: options.fps } : {}),\n });\n\n const { manifest, assets } = await captureScene({\n scene,\n camera,\n renderer,\n environment: options.environment,\n productState: options.productState,\n background: options.background,\n });\n const animated: SceneManifest = { ...manifest, animation };\n animated.protocolVersion = protocolVersionFor(animated);\n\n // The last gate, and the only one that cannot be wrong: the ids are read\n // back out of the GLB that is about to be uploaded. Everything earlier\n // predicts what the exporter will emit; this reads what it emitted.\n assertAnimationTargets(\n animation,\n animated,\n assets[0]!.data,\n namesByObjectId(options.timeline),\n );\n\n if (maxCost !== undefined) {\n // The control plane prices a clip per frame (a floor, then every\n // frame at a fraction of a still), so the quote here is the same one\n // the render will be accepted under. Checked before the upload: being\n // told a video is unaffordable after pushing a GLB is the wrong order.\n const quote = await client.estimate(\n renderQuote({\n quality,\n output,\n advanced: options.advanced,\n scene,\n camera,\n frames: animation.frameCount,\n }),\n );\n if (quote.maximumCost > maxCost) {\n throw new RenderBudgetExceeded(maxCost, quote, 'video');\n }\n }\n\n await uploadMissingAssets(client, assets, options.onUpload);\n\n const record = await client.createRender({\n manifest: animated,\n quality,\n output,\n ...(options.advanced ? { advanced: options.advanced } : {}),\n ...(maxCost !== undefined ? { maxCost } : {}),\n // No mid-render preview for a video: a low-sample still of frame one\n // answers none of the questions somebody waiting on a clip is asking.\n preview: false,\n ...(options.metadata ? { metadata: options.metadata } : {}),\n ...(options.idempotencyKey\n ? { idempotencyKey: options.idempotencyKey }\n : {}),\n ...(options.priority ? { priority: options.priority } : {}),\n });\n\n return new RenderJob(client, record);\n },\n };\n}\n\n/**\n * What the estimator is told about a scene: its weight, whether it has fog\n * the render will trace, whether it stands in a preset room the renderer\n * builds around it, and how enclosed and how full it is from the camera. The\n * control plane reads the same facts off the manifest when it accepts the\n * render, so the quotes agree.\n */\nfunction estimateScene(\n scene: Scene,\n camera: Camera,\n): {\n triangles: number;\n fog?: boolean;\n room?: boolean;\n enclosure: number;\n objects: number;\n} {\n return {\n // Every triangle traced, a preset room's published count included, as\n // `manifest.stats.triangles` counts them for the price it is accepted at.\n triangles: tracedTriangles(scene),\n ...(captureFog(scene).fog ? { fog: true } : {}),\n ...(findPresetRooms(scene).length ? { room: true } : {}),\n ...sceneComplexity(scene, camera),\n };\n}\n\nfunction hasCameras(\n options: RenderOptions | RenderCamerasOptions,\n): options is RenderCamerasOptions {\n return Array.isArray((options as RenderCamerasOptions).cameras);\n}\n\n/** Names a set nobody named. Not a secret: uniqueness is all it is for. */\nfunction randomId(): string {\n const bytes = new Uint8Array(9);\n globalThis.crypto.getRandomValues(bytes);\n return Array.from(bytes, (byte) => byte.toString(36).padStart(2, '0')).join(\n '',\n );\n}\n\n/**\n * name -> the id the manifest uses, for every named object the export would\n * carry. The same answer the exporter writes into the GLB: a declared\n * `userData.bakery3Id` when there is one, the uuid otherwise, so this can be\n * read before or after a capture and agree with it either way.\n */\nfunction objectIdsByName(scene: Scene): Record<string, string> {\n const ids: Record<string, string> = {};\n scene.traverse((object) => {\n if (!object.name || object.name in ids || shouldExclude(object)) return;\n ids[object.name] = idOf(object);\n });\n return ids;\n}\n\n/**\n * objectId -> the name the developer would recognize.\n *\n * The animation on the wire carries ids and nothing else, by design. The\n * timeline still holds the live objects, so a refusal about a channel can name\n * \"pedestal\" instead of a uuid the developer has never seen.\n */\nfunction namesByObjectId(timeline: Timeline): Map<string, string> {\n const names = new Map<string, string>();\n for (const track of timeline.tracks) {\n if (track.target === 'camera') continue;\n names.set(idOf(track.target), track.target.name || track.target.type);\n }\n return names;\n}\n\n/** The calls that read the scene and camera, by the name a developer typed. */\ntype Method =\n | 'render'\n | 'renderVideo'\n | 'renderVariants'\n | 'quoteVariants'\n | 'testVariants'\n | 'estimate'\n | 'check'\n | 'inspect'\n | 'capture'\n | 'bake';\n\nfunction missingContext(\n method: Method,\n what: 'scene' | 'camera',\n): Bakery3Error {\n const pass =\n method === 'check'\n ? 'pass your scene to check(scene)'\n : `pass { scene, camera } to ${method}()`;\n return new Bakery3Error({\n code: 'InvalidRequest',\n message: `No ${what} for ${method}().`,\n why: `${method}() was called with no ${what}, and none has been attached.`,\n fix: `In plain three.js, ${pass}, or call bakery3.attach({ scene, camera, renderer }) once. In React Three Fiber, use useBakery3() inside or beside <Canvas>.`,\n docs: 'https://bakery3.com/docs/troubleshooting#no-scene-to-render',\n });\n}\n\nfunction requireRunKey(key: string | undefined, method: Method): void {\n if (key) return;\n throw new Bakery3Error({\n code: 'InvalidRequest',\n message: `${method}() needs a key.`,\n why: 'The key names the run. It is what lets the same call resume a recording that stopped, instead of starting a second one.',\n fix: \"Give it something stable that names this body of work: `key: 'fall-2026'`.\",\n docs: 'https://bakery3.com/docs/batches',\n });\n}\n\n/**\n * The camera a set of pictures takes its shape from: the first in the list\n * that is a camera, as an object or as a name in the scene now. A declared\n * `{ id, position, target, fov }` has no shape of its own: it takes the\n * output's.\n */\nfunction firstCamera(\n cameras: ViewCamera[] | undefined,\n scene: Scene,\n): Camera | undefined {\n for (const camera of cameras ?? []) {\n if (typeof camera === 'string') {\n let found: Camera | undefined;\n scene.traverse((object) => {\n if (!found && (object as Camera).isCamera && object.name === camera)\n found = object as Camera;\n });\n if (found) return found;\n } else if ((camera as Camera).isCamera) {\n return camera as Camera;\n }\n }\n return undefined;\n}\n\n/** A page, as opposed to Node, Bun or a worker: where a missing renderer is worth a warning. */\nfunction inBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport {\n RenderJob,\n BakeJob,\n Batch,\n Bakery3Error,\n BatchPageRefused,\n RenderBudgetExceeded,\n RenderSetRefused,\n analyzeScene,\n rememberEnvironmentSource,\n SDK_VERSION,\n};\n// The shader extractor, for anyone who wants to see exactly what their node\n// material becomes before it travels. The bakery-only nodes live in\n// '@oeave/bakery3/tsl', behind their own entry point, because they need\n// three r170+.\nexport type { BakeJobEvents, BakeOutput } from './bake/job.js';\nexport { extractMaterialShader, isNodeMaterial } from './shader/extract.js';\nexport type { ExtractedShader, ShaderTextureRef } from './shader/extract.js';\n// The timeline system. Exported from the root rather than behind its own\n// entry point because it has no dependency three does not already have, and\n// because \"render a video of this\" should not be a second thing to install.\nexport {\n createTimeline,\n Timeline,\n timelineFromGsap,\n timelineFromTheatre,\n} from './timeline/index.js';\nexport type {\n AdapterOptions,\n AuthoredValue,\n Easing,\n Keyframe,\n OrbitOptions,\n PushSpec,\n SampledTrack,\n SegmentOptions,\n TimelineEvent,\n TimelineJSON,\n TimelineOptions,\n Track,\n TrackTarget,\n} from './timeline/index.js';\nexport type {\n BatchAction,\n BatchItemRecord,\n BatchItemsPage,\n ClientAuth,\n ClientOptions,\n MintedToken,\n RetryPolicy,\n TokenProvider,\n} from './client.js';\nexport { RenderSet } from './renderSet.js';\nexport type {\n Recorded,\n RenderSetFailure,\n RenderSetImage,\n RenderSetRefusal,\n VariantCleanup,\n VariantProgress,\n VariantsQuote,\n ViewCamera,\n} from './renderSet.js';\nexport type { CatalogCamera, CatalogFinish } from './variant.js';\nexport type { TestRunOptions } from './testRun.js';\nexport type { BatchProgress, FlushOptions, WaitOptions } from './batch.js';\nexport type {\n Bakery3ErrorCode,\n BudgetedKind,\n RenderBudgetInit,\n} from './errors.js';\nexport type { UploadProgress } from './upload.js';\nexport type { JobEvents, JobResultOptions } from './job.js';\nexport type { CaptureOptions, CapturedScene } from './capture/capture.js';\n// What `bake({ settings })` and `estimate({ bake })` take.\nexport type { BakeSimplifyInput, PrepareBakeSettings } from './bake/prepare.js';\n// The bake engine itself lives behind './bake' (it pulls an HDR decoder in),\n// but its wire types belong next to the rest of the protocol: naming a\n// `BakeBundle` should not require a second import path.\nexport type {\n BakeBundle,\n BakeQuality,\n BakeSettings,\n BakeSkip,\n BakeSpec,\n BakeTextureSize,\n BakeUv,\n BakedObject,\n} from './protocol/index.js';\n/** The exporter's own skip predicate (helpers, gizmos, userData.bakery3.exclude),\n * public so a host building an object picker offers only what can render. */\nexport { shouldExclude } from './capture/scene.js';\nexport type {\n AnimationChannel,\n AnimationSpec,\n AnimationTarget,\n BatchAddRequest,\n BatchAddResponse,\n BatchCost,\n BatchCounts,\n BatchExportLine,\n BatchItemOutcome,\n BatchItemRequest,\n BatchOpenRequest,\n BatchRecord,\n BatchState,\n CompatibilityIssue,\n CompatibilityReport,\n CostEstimate,\n MaterialShaderSpec,\n FrameSequenceIndex,\n OutputFormat,\n OutputSpec,\n QualityPreset,\n RenderRecord,\n RenderResult,\n RenderState,\n SceneManifest,\n ShaderGraph,\n ShaderGraphNode,\n ShaderSlot,\n} from './protocol/index.js';\n"]}