@civitai/blocks-react 0.42.0 → 0.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +59 -4
  2. package/dist/hooks/useBuzzPurchase.d.ts +6 -0
  3. package/dist/hooks/useBuzzPurchase.d.ts.map +1 -1
  4. package/dist/hooks/useBuzzPurchase.js +8 -1
  5. package/dist/hooks/useBuzzPurchase.js.map +1 -1
  6. package/dist/hooks/useBuzzWorkflow.d.ts +169 -1
  7. package/dist/hooks/useBuzzWorkflow.d.ts.map +1 -1
  8. package/dist/hooks/useBuzzWorkflow.js +201 -1
  9. package/dist/hooks/useBuzzWorkflow.js.map +1 -1
  10. package/dist/hooks/useCheckpointPicker.d.ts +0 -7
  11. package/dist/hooks/useCheckpointPicker.d.ts.map +1 -1
  12. package/dist/hooks/useCheckpointPicker.js +2 -8
  13. package/dist/hooks/useCheckpointPicker.js.map +1 -1
  14. package/dist/hooks/useImageUpload.d.ts +1 -1
  15. package/dist/hooks/useImageUpload.d.ts.map +1 -1
  16. package/dist/hooks/useImageUpload.js +11 -4
  17. package/dist/hooks/useImageUpload.js.map +1 -1
  18. package/dist/hooks/usePublishGenerationOutputs.d.ts +11 -3
  19. package/dist/hooks/usePublishGenerationOutputs.d.ts.map +1 -1
  20. package/dist/hooks/usePublishGenerationOutputs.js +13 -2
  21. package/dist/hooks/usePublishGenerationOutputs.js.map +1 -1
  22. package/dist/hooks/useResourcePicker.js +2 -2
  23. package/dist/hooks/useResourcePicker.js.map +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/internal/iframeTransport.js +1 -1
  29. package/dist/internal/iframeTransport.js.map +1 -1
  30. package/dist/internal/mockHost.d.ts +31 -0
  31. package/dist/internal/mockHost.d.ts.map +1 -1
  32. package/dist/internal/mockHost.js +31 -0
  33. package/dist/internal/mockHost.js.map +1 -1
  34. package/dist/internal/requestTimeouts.d.ts +62 -0
  35. package/dist/internal/requestTimeouts.d.ts.map +1 -0
  36. package/dist/internal/requestTimeouts.js +168 -0
  37. package/dist/internal/requestTimeouts.js.map +1 -0
  38. package/package.json +5 -5
package/README.md CHANGED
@@ -216,9 +216,30 @@ const body: WorkflowBody = {
216
216
  modelVersionId,
217
217
  params: { prompt: userPrompt },
218
218
  };
219
- await estimate(body); // status 'estimating' → 'confirming' (cost in result.cost.total)
220
- const snap = await submit(body); // status 'submitting' → 'polling'; returns a workflowId
221
- await poll(snap.workflowId); // you loop this on a backoff until terminal
219
+ // The viewer-facing copy is a string YOUR APP owns, chosen by `err.code`.
220
+ // Nothing on the error may be rendered: `err.message` is developer-facing and
221
+ // its wording is not a contract; `err.snapshot.error` is server-authored and
222
+ // unsanitised.
223
+ const estimateFailureMessage = (err: WorkflowEstimateError) =>
224
+ err.code === 'no-cost'
225
+ ? 'We could not get a price for this configuration. Try adjusting it.'
226
+ : 'Pricing is unavailable right now. Please try again shortly.';
227
+
228
+ // 🔴 estimate() REJECTS when the reply carries no usable price. ALWAYS catch it.
229
+ let priced = false;
230
+ try {
231
+ await estimate(body); // status 'estimating' → 'confirming' (cost in result.cost.total)
232
+ priced = true;
233
+ } catch (err) {
234
+ if (!(err instanceof WorkflowEstimateError)) throw err;
235
+ // status is now 'error'. Log both for the developer; render neither.
236
+ logForDebugging(err.message, err.snapshot.error);
237
+ showError(estimateFailureMessage(err));
238
+ }
239
+ if (priced) {
240
+ const snap = await submit(body); // status 'submitting' → 'polling'; returns a workflowId
241
+ await poll(snap.workflowId); // you loop this on a backoff until terminal
242
+ }
222
243
  ```
223
244
 
224
245
  **Status semantics** (gotcha #8/#9/#10):
@@ -231,9 +252,43 @@ await poll(snap.workflowId); // you loop this on a backoff until terminal
231
252
  - The hook does **not** auto-poll. After `submit` flips status to `'polling'`,
232
253
  the **caller** runs a `useEffect` that calls `poll(workflowId)` on a backoff
233
254
  until the snapshot is terminal (`succeeded | failed | canceled | expired`).
234
- - An over-budget / rejected submit comes back as a **resolved** snapshot with
255
+ - An over-budget / rejected **submit** comes back as a **resolved** snapshot with
235
256
  `status: 'failed'` + an `error` string — the transport resolves the reply, it
236
257
  doesn't throw. Check `snap.status`, not just `try/catch`.
258
+ - **`estimate` is the exception to that rule** (`@civitai/blocks-react@0.43.0+`).
259
+ It **rejects** with a `WorkflowEstimateError` when the reply carries no usable
260
+ price, rather than resolving a snapshot with no `cost`. Two things produce
261
+ that, and `err.code` tells them apart: `'failed'` (the estimate errored
262
+ server-side) and `'no-cost'` (an otherwise-successful reply that simply has no
263
+ price).
264
+ Before that version both cases resolved, so a block that correctly gates
265
+ Confirm on `typeof cost === 'number'` rendered a dialog it could never confirm
266
+ ("Cost unavailable") and the server's reason was discarded — civitai/civitai#4159.
267
+ Note this also fires in **moderator review preview**, where the host answers
268
+ every workflow request with `'not available in review preview'`: without a
269
+ `catch`, a reviewer's first click becomes an unhandled rejection.
270
+ To exercise your `catch` locally, set the mock host's
271
+ `generation.failEstimate: 'failed' | 'no-cost'`.
272
+ - **Three fields, three audiences — and none of them is viewer-facing copy.**
273
+ The string a viewer sees is one **your app owns**; nothing on this error may
274
+ be rendered as-is.
275
+ - `err.code` (`'failed' | 'no-cost'`) — **the branch target**, and the only
276
+ stable one. Switch on it to pick your own localised message.
277
+ - `err.snapshot.error` — **the diagnostic read**, and recovering it is the
278
+ whole point of the fix. **Server-authored and unsanitised** (raw upstream
279
+ text, including database constraint names, can reach it): log it or show it
280
+ in a developer-facing surface, and **never render it verbatim into markup**.
281
+ - `err.message` — **developer-facing**. A generic constant naming only the code
282
+ (`estimate did not return a usable price (no-cost) — reason on .snapshot.error`),
283
+ because `message` is what an uncaught rejection prints and what an error
284
+ reporter ships by default. Safe to log and to let a stack trace print;
285
+ **not intended for display to viewers** — it names an internal field path,
286
+ it is not localised, and **its exact wording is not a contract**, so a UI
287
+ built on it silently rots. Two apps migrating to `0.43.0` piped it into
288
+ rendered UI and would have shipped that sentence to end users.
289
+ - A cost of **`0` is a real price**, not a missing one (the orchestrator whatif
290
+ prices a cache hit at 0). `estimate` resolves it; only a non-numeric
291
+ `cost.total` rejects.
237
292
 
238
293
  > **Estimate must mirror submit** (gotcha #59): build the params for `estimate`
239
294
  > with the *exact* same logic as `submit` — same seed decision especially. The
@@ -4,6 +4,12 @@
4
4
  * balance increased; the new balance is included if the host reports it.
5
5
  * The insufficient-budget recovery path for {@link useBuzzWorkflow}.
6
6
  *
7
+ * 🔴 HUMAN-GATED: the reply comes when the viewer closes the modal, and a
8
+ * payment flow is nowhere near a ~30s round-trip — so this passes
9
+ * {@link HUMAN_INTERACTION_TIMEOUT_MS}. On the default the promise rejected
10
+ * mid-checkout, which reads to the block as "purchase failed" for a purchase
11
+ * that may well have SUCCEEDED (same defect class as civitai/civitai#4158).
12
+ *
7
13
  * @example
8
14
  * const { openPurchaseModal } = useBuzzPurchase();
9
15
  * const { purchased, newBalance } = await openPurchaseModal(suggestedAmount);
@@ -1 +1 @@
1
- {"version":3,"file":"useBuzzPurchase.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuzzPurchase.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,IAAI;IACjC,iBAAiB,EAAE,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvG,CAUA"}
1
+ {"version":3,"file":"useBuzzPurchase.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuzzPurchase.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,IAAI;IACjC,iBAAiB,EAAE,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvG,CAWA"}
@@ -1,4 +1,5 @@
1
1
  import { useCallback } from 'react';
2
+ import { HUMAN_INTERACTION_TIMEOUT_MS } from '../internal/requestTimeouts.js';
2
3
  import { getTransport } from '../internal/singleton.js';
3
4
  import { sendTypedRequest } from '../internal/transport.js';
4
5
  /**
@@ -7,6 +8,12 @@ import { sendTypedRequest } from '../internal/transport.js';
7
8
  * balance increased; the new balance is included if the host reports it.
8
9
  * The insufficient-budget recovery path for {@link useBuzzWorkflow}.
9
10
  *
11
+ * 🔴 HUMAN-GATED: the reply comes when the viewer closes the modal, and a
12
+ * payment flow is nowhere near a ~30s round-trip — so this passes
13
+ * {@link HUMAN_INTERACTION_TIMEOUT_MS}. On the default the promise rejected
14
+ * mid-checkout, which reads to the block as "purchase failed" for a purchase
15
+ * that may well have SUCCEEDED (same defect class as civitai/civitai#4158).
16
+ *
10
17
  * @example
11
18
  * const { openPurchaseModal } = useBuzzPurchase();
12
19
  * const { purchased, newBalance } = await openPurchaseModal(suggestedAmount);
@@ -14,7 +21,7 @@ import { sendTypedRequest } from '../internal/transport.js';
14
21
  */
15
22
  export function useBuzzPurchase() {
16
23
  const openPurchaseModal = useCallback(async (suggestedAmount) => {
17
- const { purchased, newBalance } = await sendTypedRequest(getTransport(), { type: 'OPEN_BUZZ_PURCHASE', payload: { suggestedAmount } }, 'BUZZ_PURCHASE_RESULT');
24
+ const { purchased, newBalance } = await sendTypedRequest(getTransport(), { type: 'OPEN_BUZZ_PURCHASE', payload: { suggestedAmount } }, 'BUZZ_PURCHASE_RESULT', { timeoutMs: HUMAN_INTERACTION_TIMEOUT_MS });
18
25
  return { purchased, newBalance };
19
26
  }, []);
20
27
  return { openPurchaseModal };
@@ -1 +1 @@
1
- {"version":3,"file":"useBuzzPurchase.js","sourceRoot":"","sources":["../../src/hooks/useBuzzPurchase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe;IAG7B,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,EAAE,eAAwB,EAAE,EAAE;QACvE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,gBAAgB,CACtD,YAAY,EAAE,EACd,EAAE,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,EAAE,EAC5D,sBAAsB,CACvB,CAAC;QACF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IACnC,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"useBuzzPurchase.js","sourceRoot":"","sources":["../../src/hooks/useBuzzPurchase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe;IAG7B,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,EAAE,eAAwB,EAAE,EAAE;QACvE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,gBAAgB,CACtD,YAAY,EAAE,EACd,EAAE,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,EAAE,EAC5D,sBAAsB,EACtB,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAC5C,CAAC;QACF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IACnC,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC/B,CAAC"}
@@ -71,6 +71,134 @@ export interface WatchWorkflowOptions {
71
71
  */
72
72
  maxRetries?: number;
73
73
  }
74
+ /**
75
+ * Thrown by {@link UseBuzzWorkflowReturn.estimate} when the host's reply does not
76
+ * carry a usable price — either because the estimate ERRORED, or because it came
77
+ * back without a numeric `cost.total`.
78
+ *
79
+ * 🔴 WHY THIS EXISTS — civitai/civitai#4159. A host-side `blocks.estimateWorkflow`
80
+ * throw is not propagated to the block as a rejection; it CANNOT be, because the
81
+ * reply crosses `postMessage`. The host instead posts a well-formed
82
+ * `ESTIMATE_RESULT` carrying its `failureSnapshot(err)` —
83
+ * `{ workflowId: 'failed', status: 'failed', error: '<server message>' }`, with
84
+ * **no `cost`** (see the host's `failureSnapshot.ts`, whose own comment states
85
+ * the block is expected to read `status`/`error`).
86
+ *
87
+ * Until this guard, `estimate()` resolved that snapshot as a SUCCESS and moved
88
+ * the hook to `'confirming'`. A correctly fail-closed block — one that gates
89
+ * Confirm on `typeof snapshot.cost?.total === 'number'` — then rendered a
90
+ * confirm dialog reading "Cost unavailable" with Confirm permanently disabled,
91
+ * and the server's own explanation (already present on `snapshot.error`) was
92
+ * discarded on the floor. The control was dead AND undiagnosable: a caller
93
+ * could not tell "priced at 0" from "the estimate errored".
94
+ *
95
+ * 🔴 TWO PRODUCERS, ONE OBSERVABLE — which is why {@link WorkflowEstimateError.code}
96
+ * exists and why the guard is not keyed on `status` alone. The server's
97
+ * `snapshotFromWorkflow` omits `cost` from an otherwise-SUCCESSFUL snapshot
98
+ * whenever the whatIf reply has no numeric total, so a `{status:'pending'}` reply
99
+ * with no `error` at all produces the identical dead control. A `status`-only
100
+ * guard would be INERT for that half. The two are distinguishable only by
101
+ * `snapshot.error` / `workflowId === 'failed'` — exactly the fields the original
102
+ * incident discarded, which is why it is still unknown which producer caused it.
103
+ *
104
+ * So an unusable estimate now REJECTS, which is what every caller's existing
105
+ * `try/catch` around `estimate()` is already shaped for. The snapshot is carried
106
+ * on the error rather than dropped, so nothing that was reachable before is lost
107
+ * — a caller that wants the raw reply reads `err.snapshot`.
108
+ *
109
+ * 🔴 WHERE THE REASON IS — READ `.snapshot.error`, NOT `message`. Recovering that
110
+ * string is the entire point of this class, so getting this the wrong way round
111
+ * reproduces the bug one layer down: a caller who logs `message` expecting the
112
+ * server's words gets a constant and is exactly as stuck as before.
113
+ *
114
+ * 🔴 THREE FIELDS, THREE AUDIENCES — AND **NONE OF THEM IS VIEWER-FACING COPY**.
115
+ * The viewer-facing string is one the APP owns; this error carries nothing you
116
+ * may render as-is. Two apps migrating to `0.43.0` each had a `catch` that piped
117
+ * `err.message` straight into rendered UI, and each would have shipped
118
+ * `estimate did not return a usable price (failed) — reason on .snapshot.error`
119
+ * to end users; both were caught only by a test asserting that exact string.
120
+ *
121
+ * - {@link WorkflowEstimateError.snapshot}`.error` — **the DIAGNOSTIC read.**
122
+ * The server's own words, verbatim. **Server-authored and UNSANITISED**:
123
+ * civitai's `errorHandling.ts` documents that raw upstream text —
124
+ * Prisma/`pg` column and constraint names among it — can reach this field.
125
+ * Log it, or show it in a developer-facing error surface. **NEVER render it
126
+ * verbatim into markup**, and think before shipping it to a third-party
127
+ * error tracker.
128
+ * - {@link WorkflowEstimateError.message} — **DEVELOPER-FACING.** A CONSTANT
129
+ * template with only `code` interpolated. It contains no server text and
130
+ * nothing to sanitise, so it is safe to LOG and safe to let a stack trace
131
+ * print — that is deliberate, because `message` is what an uncaught
132
+ * rejection prints and what a third-party block's error reporter ships
133
+ * upstream by default, and this is a package consumed by third-party code.
134
+ * **It is NOT intended for display to viewers**: it names an internal field
135
+ * path, it is not localised, and **its exact wording is NOT a contract** —
136
+ * it can change in any release, so a UI built on it silently rots.
137
+ * - {@link WorkflowEstimateError.code} — **the BRANCH TARGET**, and the only
138
+ * stable one. Switch on it to pick a viewer-facing string YOUR APP owns
139
+ * (see the mapper in the `@example` on {@link useBuzzWorkflow}).
140
+ *
141
+ * 🔴 DO NOT "SIMPLIFY" THIS BY PUTTING `snapshot.error` BACK ON `message`. The
142
+ * two fields are split on purpose and the split is what keeps database internals
143
+ * off a third party's default-printed surface. `test/useBuzzWorkflow.test.tsx`
144
+ * pins it with a realistic `Unique constraint failed: Key (email)=(…)` fixture.
145
+ *
146
+ * 🔴 NOT APPLIED TO `submit`, and the reason is narrower than it looks. On
147
+ * `WORKFLOW_SUBMITTED` there are likewise TWO producers, indistinguishable by
148
+ * `status`: budget/cap REJECTIONS, which are a documented outcome the block
149
+ * recovers from (open a top-up flow) and which carry a `cost`; and caught server
150
+ * exceptions posted via the SAME `failureSnapshot(err)` used above, which do not.
151
+ * The `#4159` defect is therefore live on `submit` too, discriminated by `cost`
152
+ * presence rather than by `status`. Fixing it there is a separate change with its
153
+ * own blast radius on the recovery path (a fix MUST keep the budget-rejection arm
154
+ * RESOLVING, or the top-up flow breaks) and is deliberately NOT attempted here —
155
+ * so `submit` is left resolving BOTH, and the accompanying test pins only the
156
+ * budget-rejection producer, not a claim that submit is correct.
157
+ *
158
+ * 🔴 TRACKED, NOT FORGOTTEN: civitai/civitai-app-starters#251. Read it before
159
+ * touching `submit`'s failure handling.
160
+ */
161
+ export declare class WorkflowEstimateError extends Error {
162
+ /**
163
+ * WHICH PRODUCER this was, structurally — so a caller branches on an enum
164
+ * rather than on prose. It is the ONLY stable branch target here:
165
+ * `snapshot.error` is server-authored and can change without notice, and
166
+ * {@link WorkflowEstimateError.message} is a generic developer-facing summary
167
+ * whose exact wording is not a contract either.
168
+ *
169
+ * 🔴 THIS IS WHAT A VIEWER-FACING MESSAGE MUST BE DERIVED FROM. Branch on
170
+ * `code` and return a string your app owns and localises; never render
171
+ * `message` or `snapshot.error` to a viewer.
172
+ *
173
+ * - `'failed'` — the reply's `status` is `'failed'`. USUALLY that means
174
+ * `blocks.estimateWorkflow` threw server-side and the host posted its
175
+ * `failureSnapshot(err)` (so `snapshot.error` carries the server's reason and
176
+ * there is no `cost`) — but it is NOT only that: a whatIf the orchestrator
177
+ * itself reports as failed maps to `'failed'` through the server's own
178
+ * `ORCH_STATUS_MAP`, and such a reply CAN carry a numeric `cost`. Both are
179
+ * rejected: a failed estimate is not a quote you may spend against, whether
180
+ * or not a number came back with it. Do not read this code as "the host
181
+ * threw" — read it as "the estimate did not succeed".
182
+ * - `'no-cost'` — a NON-failed reply with no numeric `cost.total`. There is
183
+ * usually no `snapshot.error` to explain it, which makes it the harder of the
184
+ * two to diagnose from the block side.
185
+ */
186
+ readonly code: 'failed' | 'no-cost';
187
+ /**
188
+ * The snapshot the host replied with, VERBATIM — including `snapshot.error`,
189
+ * the server's own words, when there are any.
190
+ *
191
+ * 🔴 `snapshot.error` IS SERVER-AUTHORED AND UNSANITISED. It is where the
192
+ * reason lives (reading it is the documented way to diagnose an estimate that
193
+ * will not price — the whole point of civitai/civitai#4159), but civitai's
194
+ * `errorHandling.ts` documents that raw upstream text — Prisma/`pg` column and
195
+ * constraint names among it — can reach that field. Log it, show it in a
196
+ * developer-facing error surface, **NEVER render it verbatim into markup**,
197
+ * and do not ship it to a third-party error tracker without thinking about it.
198
+ */
199
+ readonly snapshot: BlockWorkflowSnapshot;
200
+ constructor(snapshot: BlockWorkflowSnapshot, code: 'failed' | 'no-cost');
201
+ }
74
202
  /** Optional per-submit controls. */
75
203
  export interface SubmitWorkflowOptions {
76
204
  /**
@@ -83,6 +211,28 @@ export interface SubmitWorkflowOptions {
83
211
  idempotencyKey?: string;
84
212
  }
85
213
  interface UseBuzzWorkflowReturn {
214
+ /**
215
+ * Price a workflow without queueing it. Resolves ONLY with a snapshot that
216
+ * carries a numeric `cost.total`.
217
+ *
218
+ * 🔴 REJECTS with {@link WorkflowEstimateError} when the reply is unusable —
219
+ * the estimate errored server-side, or it came back with no numeric cost.
220
+ * Wrap every call in `try/catch`; see that class for why resolving such a
221
+ * reply was civitai/civitai#4159.
222
+ *
223
+ * 🔴 THIS INCLUDES MODERATOR REVIEW PREVIEW, a behaviour change worth knowing
224
+ * before you ship. While an app is under review the host short-circuits every
225
+ * workflow request with `failureSnapshot('not available in review preview')`,
226
+ * so `estimate()` now rejects there where it used to resolve. That is the
227
+ * correct reading — no estimate happened — and it is why the catch is not
228
+ * optional: a block without one turns the reviewer's first click into an
229
+ * unhandled rejection, at exactly the moment it is meant to look healthy. A
230
+ * block that catches shows the reviewer the reason instead.
231
+ *
232
+ * `result` is updated to the returned snapshot BEFORE any rejection, so a
233
+ * failed estimate can never leave a previous, differently-configured
234
+ * estimate's price sitting in `result` for a Confirm gate to read.
235
+ */
86
236
  estimate: (body: WorkflowBody) => Promise<BlockWorkflowSnapshot>;
87
237
  submit: (body: WorkflowBody, options?: SubmitWorkflowOptions) => Promise<BlockWorkflowSnapshot>;
88
238
  /**
@@ -178,7 +328,25 @@ interface UseBuzzWorkflowReturn {
178
328
  * modelVersionId,
179
329
  * params: { prompt: 'a cat' },
180
330
  * };
181
- * await estimate(body); // status 'estimating' → 'confirming' (cost in result.cost.total)
331
+ * // A viewer-facing string YOUR APP owns, chosen by `code`. Neither
332
+ * // `err.message` (developer-facing, wording not a contract) nor
333
+ * // `err.snapshot.error` (server-authored, unsanitised) may be rendered.
334
+ * const estimateFailureMessage = (err: WorkflowEstimateError) =>
335
+ * err.code === 'no-cost'
336
+ * ? 'We could not get a price for this configuration. Try adjusting it.'
337
+ * : 'Pricing is unavailable right now. Please try again shortly.';
338
+ *
339
+ * // 🔴 estimate() REJECTS when the reply carries no usable price — an errored
340
+ * // estimate, or one that came back with no numeric cost. ALWAYS catch it.
341
+ * try {
342
+ * await estimate(body); // status 'estimating' → 'confirming' (cost in result.cost.total)
343
+ * } catch (err) {
344
+ * // status is now 'error'; `result` holds the unusable snapshot, never a
345
+ * // STALE priced one. See WorkflowEstimateError for the three-audience split.
346
+ * if (!(err instanceof WorkflowEstimateError)) throw err;
347
+ * logForDebugging(err.message, err.snapshot.error); // developer-facing: LOG only
348
+ * showError(estimateFailureMessage(err)); // viewer-facing: app-owned
349
+ * }
182
350
  * const snap = await submit(body); // status 'submitting' → 'polling'; returns a workflowId
183
351
  * const done = await watch(snap.workflowId, { onUpdate: render }); // → terminal
184
352
  */
@@ -1 +1 @@
1
- {"version":3,"file":"useBuzzWorkflow.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuzzWorkflow.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AA8BnG;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAW7C,iEAAiE;AACjE,MAAM,WAAW,oBAAoB;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACrD;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAyBD,oCAAoC;AACpC,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACjE,MAAM,EAAE,CACN,IAAI,EAAE,YAAY,EAClB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACpC;;;OAGG;IACH,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC7D;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,KAAK,EAAE,CACL,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,oBAAoB,KAC3B,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACpC;;;;;;OAMG;IACH,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC/D,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,eAAe,IAAI,qBAAqB,CA+MvD"}
1
+ {"version":3,"file":"useBuzzWorkflow.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuzzWorkflow.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AA8BnG;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAW7C,iEAAiE;AACjE,MAAM,WAAW,oBAAoB;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACrD;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAyBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAEpC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;gBAE7B,QAAQ,EAAE,qBAAqB,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS;CAoBxE;AAED,oCAAoC;AACpC,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,qBAAqB;IAC7B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACjE,MAAM,EAAE,CACN,IAAI,EAAE,YAAY,EAClB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACpC;;;OAGG;IACH,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC7D;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,KAAK,EAAE,CACL,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,oBAAoB,KAC3B,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACpC;;;;;;OAMG;IACH,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC/D,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,wBAAgB,eAAe,IAAI,qBAAqB,CAkPvD"}
@@ -72,6 +72,153 @@ function sleep(ms, signal) {
72
72
  signal?.addEventListener('abort', done);
73
73
  });
74
74
  }
75
+ /**
76
+ * Thrown by {@link UseBuzzWorkflowReturn.estimate} when the host's reply does not
77
+ * carry a usable price — either because the estimate ERRORED, or because it came
78
+ * back without a numeric `cost.total`.
79
+ *
80
+ * 🔴 WHY THIS EXISTS — civitai/civitai#4159. A host-side `blocks.estimateWorkflow`
81
+ * throw is not propagated to the block as a rejection; it CANNOT be, because the
82
+ * reply crosses `postMessage`. The host instead posts a well-formed
83
+ * `ESTIMATE_RESULT` carrying its `failureSnapshot(err)` —
84
+ * `{ workflowId: 'failed', status: 'failed', error: '<server message>' }`, with
85
+ * **no `cost`** (see the host's `failureSnapshot.ts`, whose own comment states
86
+ * the block is expected to read `status`/`error`).
87
+ *
88
+ * Until this guard, `estimate()` resolved that snapshot as a SUCCESS and moved
89
+ * the hook to `'confirming'`. A correctly fail-closed block — one that gates
90
+ * Confirm on `typeof snapshot.cost?.total === 'number'` — then rendered a
91
+ * confirm dialog reading "Cost unavailable" with Confirm permanently disabled,
92
+ * and the server's own explanation (already present on `snapshot.error`) was
93
+ * discarded on the floor. The control was dead AND undiagnosable: a caller
94
+ * could not tell "priced at 0" from "the estimate errored".
95
+ *
96
+ * 🔴 TWO PRODUCERS, ONE OBSERVABLE — which is why {@link WorkflowEstimateError.code}
97
+ * exists and why the guard is not keyed on `status` alone. The server's
98
+ * `snapshotFromWorkflow` omits `cost` from an otherwise-SUCCESSFUL snapshot
99
+ * whenever the whatIf reply has no numeric total, so a `{status:'pending'}` reply
100
+ * with no `error` at all produces the identical dead control. A `status`-only
101
+ * guard would be INERT for that half. The two are distinguishable only by
102
+ * `snapshot.error` / `workflowId === 'failed'` — exactly the fields the original
103
+ * incident discarded, which is why it is still unknown which producer caused it.
104
+ *
105
+ * So an unusable estimate now REJECTS, which is what every caller's existing
106
+ * `try/catch` around `estimate()` is already shaped for. The snapshot is carried
107
+ * on the error rather than dropped, so nothing that was reachable before is lost
108
+ * — a caller that wants the raw reply reads `err.snapshot`.
109
+ *
110
+ * 🔴 WHERE THE REASON IS — READ `.snapshot.error`, NOT `message`. Recovering that
111
+ * string is the entire point of this class, so getting this the wrong way round
112
+ * reproduces the bug one layer down: a caller who logs `message` expecting the
113
+ * server's words gets a constant and is exactly as stuck as before.
114
+ *
115
+ * 🔴 THREE FIELDS, THREE AUDIENCES — AND **NONE OF THEM IS VIEWER-FACING COPY**.
116
+ * The viewer-facing string is one the APP owns; this error carries nothing you
117
+ * may render as-is. Two apps migrating to `0.43.0` each had a `catch` that piped
118
+ * `err.message` straight into rendered UI, and each would have shipped
119
+ * `estimate did not return a usable price (failed) — reason on .snapshot.error`
120
+ * to end users; both were caught only by a test asserting that exact string.
121
+ *
122
+ * - {@link WorkflowEstimateError.snapshot}`.error` — **the DIAGNOSTIC read.**
123
+ * The server's own words, verbatim. **Server-authored and UNSANITISED**:
124
+ * civitai's `errorHandling.ts` documents that raw upstream text —
125
+ * Prisma/`pg` column and constraint names among it — can reach this field.
126
+ * Log it, or show it in a developer-facing error surface. **NEVER render it
127
+ * verbatim into markup**, and think before shipping it to a third-party
128
+ * error tracker.
129
+ * - {@link WorkflowEstimateError.message} — **DEVELOPER-FACING.** A CONSTANT
130
+ * template with only `code` interpolated. It contains no server text and
131
+ * nothing to sanitise, so it is safe to LOG and safe to let a stack trace
132
+ * print — that is deliberate, because `message` is what an uncaught
133
+ * rejection prints and what a third-party block's error reporter ships
134
+ * upstream by default, and this is a package consumed by third-party code.
135
+ * **It is NOT intended for display to viewers**: it names an internal field
136
+ * path, it is not localised, and **its exact wording is NOT a contract** —
137
+ * it can change in any release, so a UI built on it silently rots.
138
+ * - {@link WorkflowEstimateError.code} — **the BRANCH TARGET**, and the only
139
+ * stable one. Switch on it to pick a viewer-facing string YOUR APP owns
140
+ * (see the mapper in the `@example` on {@link useBuzzWorkflow}).
141
+ *
142
+ * 🔴 DO NOT "SIMPLIFY" THIS BY PUTTING `snapshot.error` BACK ON `message`. The
143
+ * two fields are split on purpose and the split is what keeps database internals
144
+ * off a third party's default-printed surface. `test/useBuzzWorkflow.test.tsx`
145
+ * pins it with a realistic `Unique constraint failed: Key (email)=(…)` fixture.
146
+ *
147
+ * 🔴 NOT APPLIED TO `submit`, and the reason is narrower than it looks. On
148
+ * `WORKFLOW_SUBMITTED` there are likewise TWO producers, indistinguishable by
149
+ * `status`: budget/cap REJECTIONS, which are a documented outcome the block
150
+ * recovers from (open a top-up flow) and which carry a `cost`; and caught server
151
+ * exceptions posted via the SAME `failureSnapshot(err)` used above, which do not.
152
+ * The `#4159` defect is therefore live on `submit` too, discriminated by `cost`
153
+ * presence rather than by `status`. Fixing it there is a separate change with its
154
+ * own blast radius on the recovery path (a fix MUST keep the budget-rejection arm
155
+ * RESOLVING, or the top-up flow breaks) and is deliberately NOT attempted here —
156
+ * so `submit` is left resolving BOTH, and the accompanying test pins only the
157
+ * budget-rejection producer, not a claim that submit is correct.
158
+ *
159
+ * 🔴 TRACKED, NOT FORGOTTEN: civitai/civitai-app-starters#251. Read it before
160
+ * touching `submit`'s failure handling.
161
+ */
162
+ export class WorkflowEstimateError extends Error {
163
+ /**
164
+ * WHICH PRODUCER this was, structurally — so a caller branches on an enum
165
+ * rather than on prose. It is the ONLY stable branch target here:
166
+ * `snapshot.error` is server-authored and can change without notice, and
167
+ * {@link WorkflowEstimateError.message} is a generic developer-facing summary
168
+ * whose exact wording is not a contract either.
169
+ *
170
+ * 🔴 THIS IS WHAT A VIEWER-FACING MESSAGE MUST BE DERIVED FROM. Branch on
171
+ * `code` and return a string your app owns and localises; never render
172
+ * `message` or `snapshot.error` to a viewer.
173
+ *
174
+ * - `'failed'` — the reply's `status` is `'failed'`. USUALLY that means
175
+ * `blocks.estimateWorkflow` threw server-side and the host posted its
176
+ * `failureSnapshot(err)` (so `snapshot.error` carries the server's reason and
177
+ * there is no `cost`) — but it is NOT only that: a whatIf the orchestrator
178
+ * itself reports as failed maps to `'failed'` through the server's own
179
+ * `ORCH_STATUS_MAP`, and such a reply CAN carry a numeric `cost`. Both are
180
+ * rejected: a failed estimate is not a quote you may spend against, whether
181
+ * or not a number came back with it. Do not read this code as "the host
182
+ * threw" — read it as "the estimate did not succeed".
183
+ * - `'no-cost'` — a NON-failed reply with no numeric `cost.total`. There is
184
+ * usually no `snapshot.error` to explain it, which makes it the harder of the
185
+ * two to diagnose from the block side.
186
+ */
187
+ code;
188
+ /**
189
+ * The snapshot the host replied with, VERBATIM — including `snapshot.error`,
190
+ * the server's own words, when there are any.
191
+ *
192
+ * 🔴 `snapshot.error` IS SERVER-AUTHORED AND UNSANITISED. It is where the
193
+ * reason lives (reading it is the documented way to diagnose an estimate that
194
+ * will not price — the whole point of civitai/civitai#4159), but civitai's
195
+ * `errorHandling.ts` documents that raw upstream text — Prisma/`pg` column and
196
+ * constraint names among it — can reach that field. Log it, show it in a
197
+ * developer-facing error surface, **NEVER render it verbatim into markup**,
198
+ * and do not ship it to a third-party error tracker without thinking about it.
199
+ */
200
+ snapshot;
201
+ constructor(snapshot, code) {
202
+ // 🔴 GENERIC, AND DELIBERATELY NOT `snapshot.error`. `message` is the field an
203
+ // uncaught rejection PRINTS and the field a third-party block's error
204
+ // reporter ships upstream by default — so putting the raw server string here
205
+ // would put database internals (constraint names, `Key (email)=(…) already
206
+ // exists.`) on the default-printed surface of somebody else's code. Exposure
207
+ // to the block is identical either way (`snapshot.error` was always on the
208
+ // wire), so routing the raw text to `.snapshot.error` alone costs a
209
+ // deliberate debugger nothing and changes only the DISPOSITION. `code` is
210
+ // carried IN the message so an uncaught rejection is still self-describing.
211
+ //
212
+ // 🔴 IT IS DEVELOPER-FACING, NOT VIEWER-FACING — it names an internal field
213
+ // path and is not localised, so it must not reach rendered UI. Its exact
214
+ // wording is NOT a contract: it may change in any release. A viewer-facing
215
+ // string is derived from `code` by the app (see the class docs).
216
+ super(`estimate did not return a usable price (${code}) — reason on .snapshot.error`);
217
+ this.name = 'WorkflowEstimateError';
218
+ this.code = code;
219
+ this.snapshot = snapshot;
220
+ }
221
+ }
75
222
  /**
76
223
  * Orchestrates the estimate → confirm → submit → poll dance through the
77
224
  * host-mediated `postMessage` path.
@@ -122,7 +269,25 @@ function sleep(ms, signal) {
122
269
  * modelVersionId,
123
270
  * params: { prompt: 'a cat' },
124
271
  * };
125
- * await estimate(body); // status 'estimating' → 'confirming' (cost in result.cost.total)
272
+ * // A viewer-facing string YOUR APP owns, chosen by `code`. Neither
273
+ * // `err.message` (developer-facing, wording not a contract) nor
274
+ * // `err.snapshot.error` (server-authored, unsanitised) may be rendered.
275
+ * const estimateFailureMessage = (err: WorkflowEstimateError) =>
276
+ * err.code === 'no-cost'
277
+ * ? 'We could not get a price for this configuration. Try adjusting it.'
278
+ * : 'Pricing is unavailable right now. Please try again shortly.';
279
+ *
280
+ * // 🔴 estimate() REJECTS when the reply carries no usable price — an errored
281
+ * // estimate, or one that came back with no numeric cost. ALWAYS catch it.
282
+ * try {
283
+ * await estimate(body); // status 'estimating' → 'confirming' (cost in result.cost.total)
284
+ * } catch (err) {
285
+ * // status is now 'error'; `result` holds the unusable snapshot, never a
286
+ * // STALE priced one. See WorkflowEstimateError for the three-audience split.
287
+ * if (!(err instanceof WorkflowEstimateError)) throw err;
288
+ * logForDebugging(err.message, err.snapshot.error); // developer-facing: LOG only
289
+ * showError(estimateFailureMessage(err)); // viewer-facing: app-owned
290
+ * }
126
291
  * const snap = await submit(body); // status 'submitting' → 'polling'; returns a workflowId
127
292
  * const done = await watch(snap.workflowId, { onUpdate: render }); // → terminal
128
293
  */
@@ -135,7 +300,42 @@ export function useBuzzWorkflow() {
135
300
  setStatus('estimating');
136
301
  try {
137
302
  const { snapshot } = await sendTypedRequest(getTransport(), { type: 'ESTIMATE_WORKFLOW', payload: { body } }, 'ESTIMATE_RESULT', { timeoutMs: WORKFLOW_REQUEST_TIMEOUT_MS });
303
+ // 🔴 PUBLISH THE SNAPSHOT BEFORE ANY REJECTION BELOW. `result` is what the
304
+ // README documents as where the cost lives, so a block may gate its Confirm
305
+ // on `typeof result.cost?.total === 'number'` rather than on the returned
306
+ // value. If the throw jumped over this line, a FAILED estimate would leave
307
+ // the PREVIOUS estimate's snapshot in place and that gate would read the
308
+ // OLD config's price — a live control quoting the wrong number on a money
309
+ // path, which is strictly worse than the dead control this PR exists to
310
+ // fix. Assigning first preserves the pre-fix fail-CLOSED property (the
311
+ // cost-less snapshot overwrites the priced one) and merely adds the
312
+ // rejection on top.
138
313
  setResult(snapshot);
314
+ // 🔴 AN UNUSABLE ESTIMATE MUST REJECT — and there are TWO producers of the
315
+ // identical observable "resolved, but no `cost.total`", distinguishable
316
+ // only by fields the incident in civitai/civitai#4159 discarded:
317
+ //
318
+ // (a) status:'failed' — `blocks.estimateWorkflow` threw server-side. The
319
+ // host cannot reject across postMessage, so it posts
320
+ // `failureSnapshot(err)`: a VALID snapshot with `status:'failed'`,
321
+ // an `error` string, and no `cost`.
322
+ // (b) no numeric cost on an otherwise-successful snapshot — the server's
323
+ // `snapshotFromWorkflow` OMITS `cost` entirely when the whatIf reply
324
+ // has no numeric total (`...(typeof total === 'number' ? … : {})`),
325
+ // which yields e.g. `{status:'pending'}` with no `error` at all.
326
+ //
327
+ // Keying on `status` ALONE would leave (b) resolving — the same dead
328
+ // "Cost unavailable" control, still undiagnosable. So the rule is the one
329
+ // the caller actually needs: an estimate that did not yield a usable price
330
+ // does not resolve. `canceled`/`expired` are covered by the same clause
331
+ // (they carry no cost), which is why they need no arm of their own.
332
+ const usableCost = typeof snapshot.cost?.total === 'number';
333
+ if (snapshot.status === 'failed') {
334
+ throw new WorkflowEstimateError(snapshot, 'failed');
335
+ }
336
+ if (!usableCost) {
337
+ throw new WorkflowEstimateError(snapshot, 'no-cost');
338
+ }
139
339
  setStatus('confirming');
140
340
  return snapshot;
141
341
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useBuzzWorkflow.js","sourceRoot":"","sources":["../../src/hooks/useBuzzWorkflow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useBuzzWorkflow.js","sourceRoot":"","sources":["../../src/hooks/useBuzzWorkflow.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,4 @@
1
1
  import type { BlockCheckpointInfo } from '@civitai/app-sdk/blocks';
2
- /**
3
- * A resource picker is HUMAN-interactive — the user browses the catalog and may
4
- * take a while to choose. The default request timeout (~30s) is for fast
5
- * protocol round-trips and would reject a slow browse mid-pick. Use a generous
6
- * bound instead; the host still resolves earlier on pick/dismiss/close.
7
- */
8
- export declare const PICKER_REQUEST_TIMEOUT_MS: number;
9
2
  /**
10
3
  * Drives the platform-side Checkpoint picker and the persist-override flow.
11
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"useCheckpointPicker.d.ts","sourceRoot":"","sources":["../../src/hooks/useCheckpointPicker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAKnE;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,QAAc,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,IAAI;IACrC,IAAI,EAAE,CAAC,IAAI,EAAE;QACX;;;;;WAKG;QACH,cAAc,EAAE,MAAM,CAAC;QACvB,uEAAuE;QACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,KAAK,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,mBAAmB,CAAA;KAAE,CAAC,CAAC;IAClD,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD,CAkCA"}
1
+ {"version":3,"file":"useCheckpointPicker.d.ts","sourceRoot":"","sources":["../../src/hooks/useCheckpointPicker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAMnE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,IAAI;IACrC,IAAI,EAAE,CAAC,IAAI,EAAE;QACX;;;;;WAKG;QACH,cAAc,EAAE,MAAM,CAAC;QACvB,uEAAuE;QACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,KAAK,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,mBAAmB,CAAA;KAAE,CAAC,CAAC;IAClD,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD,CAkCA"}
@@ -1,13 +1,7 @@
1
1
  import { useCallback } from 'react';
2
+ import { HUMAN_INTERACTION_TIMEOUT_MS } from '../internal/requestTimeouts.js';
2
3
  import { getTransport } from '../internal/singleton.js';
3
4
  import { sendTypedRequest } from '../internal/transport.js';
4
- /**
5
- * A resource picker is HUMAN-interactive — the user browses the catalog and may
6
- * take a while to choose. The default request timeout (~30s) is for fast
7
- * protocol round-trips and would reject a slow browse mid-pick. Use a generous
8
- * bound instead; the host still resolves earlier on pick/dismiss/close.
9
- */
10
- export const PICKER_REQUEST_TIMEOUT_MS = 10 * 60_000;
11
5
  /**
12
6
  * Drives the platform-side Checkpoint picker and the persist-override flow.
13
7
  *
@@ -39,7 +33,7 @@ export function useCheckpointPicker() {
39
33
  ? { currentVersionId: opts.currentVersionId }
40
34
  : {}),
41
35
  },
42
- }, 'CHECKPOINT_PICKER_RESULT', { timeoutMs: PICKER_REQUEST_TIMEOUT_MS });
36
+ }, 'CHECKPOINT_PICKER_RESULT', { timeoutMs: HUMAN_INTERACTION_TIMEOUT_MS });
43
37
  return { selected };
44
38
  }, []);
45
39
  const persist = useCallback(async (versionId) => {