@civitai/blocks-react 0.43.0 → 0.44.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.
- package/README.md +116 -22
- package/dist/hooks/useAppStorage.d.ts.map +1 -1
- package/dist/hooks/useAppStorage.js +17 -4
- package/dist/hooks/useAppStorage.js.map +1 -1
- package/dist/hooks/useBuzzWorkflow.d.ts +303 -39
- package/dist/hooks/useBuzzWorkflow.d.ts.map +1 -1
- package/dist/hooks/useBuzzWorkflow.js +350 -39
- package/dist/hooks/useBuzzWorkflow.js.map +1 -1
- package/dist/hooks/useCheckpointPicker.d.ts.map +1 -1
- package/dist/hooks/useCheckpointPicker.js +7 -2
- package/dist/hooks/useCheckpointPicker.js.map +1 -1
- package/dist/hooks/useSaveImage.d.ts.map +1 -1
- package/dist/hooks/useSaveImage.js +6 -2
- package/dist/hooks/useSaveImage.js.map +1 -1
- package/dist/hooks/useSharedStorage.d.ts.map +1 -1
- package/dist/hooks/useSharedStorage.js +20 -4
- package/dist/hooks/useSharedStorage.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/liveHost.d.ts.map +1 -1
- package/dist/internal/liveHost.js +17 -0
- package/dist/internal/liveHost.js.map +1 -1
- package/dist/internal/mockHost.d.ts +48 -5
- package/dist/internal/mockHost.d.ts.map +1 -1
- package/dist/internal/mockHost.js +65 -3
- package/dist/internal/mockHost.js.map +1 -1
- package/dist/internal/validate.d.ts +66 -16
- package/dist/internal/validate.d.ts.map +1 -1
- package/dist/internal/validate.js +89 -27
- package/dist/internal/validate.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -216,6 +216,15 @@ const body: WorkflowBody = {
|
|
|
216
216
|
modelVersionId,
|
|
217
217
|
params: { prompt: userPrompt },
|
|
218
218
|
};
|
|
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
|
+
|
|
219
228
|
// 🔴 estimate() REJECTS when the reply carries no usable price. ALWAYS catch it.
|
|
220
229
|
let priced = false;
|
|
221
230
|
try {
|
|
@@ -223,16 +232,49 @@ try {
|
|
|
223
232
|
priced = true;
|
|
224
233
|
} catch (err) {
|
|
225
234
|
if (!(err instanceof WorkflowEstimateError)) throw err;
|
|
226
|
-
// status is now 'error'.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
// err.message is a generic summary safe to print.
|
|
230
|
-
logForDebugging(err.snapshot.error);
|
|
231
|
-
showError('This configuration cannot be priced right now.');
|
|
235
|
+
// status is now 'error'. Log both for the developer; render neither.
|
|
236
|
+
logForDebugging(err.message, err.snapshot.error);
|
|
237
|
+
showError(estimateFailureMessage(err));
|
|
232
238
|
}
|
|
233
239
|
if (priced) {
|
|
234
|
-
|
|
235
|
-
|
|
240
|
+
// 🔴 submit() REJECTS when the reply carries no usable workflow outcome. A
|
|
241
|
+
// priced refusal is different — it RESOLVES.
|
|
242
|
+
try {
|
|
243
|
+
const snap = await submit(body); // status 'submitting' → 'polling'
|
|
244
|
+
if (snap.status === 'failed') {
|
|
245
|
+
// 🔴 A RESOLVED `failed` IS A PRICED SERVER OUTCOME — and only SOME of
|
|
246
|
+
// them are about the viewer's wallet. Affordability (per-call budget, the
|
|
247
|
+
// per-user daily Buzz cap) IS fixable by buying Buzz; the per-app velocity
|
|
248
|
+
// limit, the per-app aggregate daily cap, a fail-closed "temporarily
|
|
249
|
+
// unavailable" deny and a missing price quote are NOT. Selling Buzz for
|
|
250
|
+
// one of those takes money and fixes nothing, so branch before you offer.
|
|
251
|
+
showError(submitOutcomeMessage(snap)); // YOUR app owns this copy
|
|
252
|
+
} else {
|
|
253
|
+
await poll(snap.workflowId); // you loop this on a backoff until terminal
|
|
254
|
+
}
|
|
255
|
+
} catch (err) {
|
|
256
|
+
if (!(err instanceof WorkflowSubmitError)) throw err;
|
|
257
|
+
// Log both for the developer; render neither.
|
|
258
|
+
logForDebugging(err.message, err.snapshot.error);
|
|
259
|
+
// 🔴 TWO SEPARATE QUESTIONS — DO NOT CONJOIN THEM. `code` decides what you may
|
|
260
|
+
// say about MONEY; the id decides only whether there is something to POLL.
|
|
261
|
+
// Folding the id test into the `code` test sends a 'workflow-failed' reply
|
|
262
|
+
// whose id is 'whatif' into the reassuring arm — the exact blind-retry
|
|
263
|
+
// invitation this whole guard exists to remove.
|
|
264
|
+
if (err.code === 'workflow-failed') {
|
|
265
|
+
// 🔴 Spend MAY ALREADY BE COMMITTED. Do not tell the viewer it was free,
|
|
266
|
+
// and do not retry blindly — a retry mints a fresh idempotency key, i.e. a
|
|
267
|
+
// SECOND reservation.
|
|
268
|
+
showError('The generation may have started but did not complete. Check your history.');
|
|
269
|
+
// Only NOW ask about pollability: 'whatif' is a non-workflow sentinel.
|
|
270
|
+
if (err.snapshot.workflowId !== 'whatif') await poll(err.snapshot.workflowId);
|
|
271
|
+
} else {
|
|
272
|
+
// 🔴 'exception' means the host had no workflow to report — USUALLY nothing
|
|
273
|
+
// was queued, but a lost response or an in-progress idempotency conflict
|
|
274
|
+
// reaches this arm too. Retry with the SAME idempotencyKey, not a fresh one.
|
|
275
|
+
showError('Could not start the generation. Please try again.');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
236
278
|
}
|
|
237
279
|
```
|
|
238
280
|
|
|
@@ -246,10 +288,55 @@ if (priced) {
|
|
|
246
288
|
- The hook does **not** auto-poll. After `submit` flips status to `'polling'`,
|
|
247
289
|
the **caller** runs a `useEffect` that calls `poll(workflowId)` on a backoff
|
|
248
290
|
until the snapshot is terminal (`succeeded | failed | canceled | expired`).
|
|
249
|
-
-
|
|
250
|
-
`status: 'failed'
|
|
251
|
-
|
|
252
|
-
|
|
291
|
+
- A **priced** submit refusal comes back as a **resolved** snapshot with
|
|
292
|
+
`status: 'failed'`, an `error` string, **and a numeric `cost.total`** — the
|
|
293
|
+
price the server refused to charge. That is a workflow *outcome*, not an error.
|
|
294
|
+
Check `snap.status`, not just `try/catch`.
|
|
295
|
+
🔴 **Not all of them are affordability.** Only the per-call `buzzBudget` gate
|
|
296
|
+
and the per-user daily Buzz cap are about the wallet. The per-app **velocity**
|
|
297
|
+
limit, the per-app **aggregate daily** cap, a fail-closed **"temporarily
|
|
298
|
+
unavailable"** deny and a **missing price quote** are priced outcomes too, and
|
|
299
|
+
buying Buzz fixes none of them. Branch before you offer a top-up.
|
|
300
|
+
- **`submit` REJECTS when the reply carries no usable workflow outcome**
|
|
301
|
+
(`@civitai/blocks-react@0.44.0+`). Every failure-shaped reply reports
|
|
302
|
+
`status: 'failed'`, so `status` cannot tell them apart — **`cost` presence
|
|
303
|
+
decides resolve-vs-reject, and `workflowId` decides which rejection**:
|
|
304
|
+
- **priced refusal** → carries `cost`. **Resolves**, as above.
|
|
305
|
+
- **a reply the host built itself** (`failureSnapshot(err)`, which stamps the
|
|
306
|
+
literal `workflowId: 'failed'` — from a `catch` or a short-circuit such as
|
|
307
|
+
the moderator-review nack) → no `cost`. **Rejects** with
|
|
308
|
+
`err.code === 'exception'`, which means *the host had no workflow to report*.
|
|
309
|
+
🔴 **Not the same as "nothing happened."** Usually nothing was queued or
|
|
310
|
+
charged and a retry is fine, but a **lost response**, an **in-progress
|
|
311
|
+
idempotency conflict**, or a **transient 5xx/408/429/401** also land here,
|
|
312
|
+
and a workflow may have been created and charged. Prefer reusing the same
|
|
313
|
+
`idempotencyKey` on retry, and don't render "nothing was charged" as fact.
|
|
314
|
+
- **a failed, unpriced reply whose id is NOT that sentinel** (normally a
|
|
315
|
+
genuine orchestrator id) → no `cost`. **Rejects** with
|
|
316
|
+
`err.code === 'workflow-failed'`.
|
|
317
|
+
🔴 **Money may already be committed.** Server-side, *any* resolved submit
|
|
318
|
+
keeps its Buzz reservation "regardless of snapshot status", with no refund on
|
|
319
|
+
a non-throwing failed snapshot. So do not tell the viewer it was free, and do
|
|
320
|
+
not retry blindly — `submit()` mints a fresh `idempotencyKey` per call, so an
|
|
321
|
+
automatic retry is a second reservation. Read `err.snapshot.workflowId` (a
|
|
322
|
+
usually-pollable id) and `watch`/`poll` it to learn the workflow's actual
|
|
323
|
+
fate — guarding with `err.snapshot.workflowId !== 'whatif'` first, since the
|
|
324
|
+
server treats both `'failed'` and `'whatif'` as non-workflow sentinels.
|
|
325
|
+
|
|
326
|
+
Before that version everything resolved, so a block branching on
|
|
327
|
+
`snap.status === 'failed'` could not tell "you can't afford this" from "the
|
|
328
|
+
request failed", and one gating a money control on
|
|
329
|
+
`typeof snap.cost?.total === 'number'` saw the same dead-control shape
|
|
330
|
+
civitai/civitai#4159 describes. An ordinary in-flight reply
|
|
331
|
+
(`{ status: 'pending' }`) is cost-less too and still resolves — and so are
|
|
332
|
+
cost-less `succeeded` / `canceled` / `expired` replies. Only a *failure-shaped*
|
|
333
|
+
reply with no price rejects. `err.message` is a generic developer-facing
|
|
334
|
+
constant that makes **no claim about money** (the two codes differ on that) and
|
|
335
|
+
the server's words stay on `err.snapshot.error`, exactly as on
|
|
336
|
+
`WorkflowEstimateError` below. Note this also fires in **moderator review
|
|
337
|
+
preview**. To exercise your `catch` locally, set the mock host's
|
|
338
|
+
`generation.failSubmitException: true`.
|
|
339
|
+
- **`estimate` follows the same rule for a different question** (`@civitai/blocks-react@0.43.0+`).
|
|
253
340
|
It **rejects** with a `WorkflowEstimateError` when the reply carries no usable
|
|
254
341
|
price, rather than resolving a snapshot with no `cost`. Two things produce
|
|
255
342
|
that, and `err.code` tells them apart: `'failed'` (the estimate errored
|
|
@@ -263,16 +350,23 @@ if (priced) {
|
|
|
263
350
|
`catch`, a reviewer's first click becomes an unhandled rejection.
|
|
264
351
|
To exercise your `catch` locally, set the mock host's
|
|
265
352
|
`generation.failEstimate: 'failed' | 'no-cost'`.
|
|
266
|
-
- **
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
`err.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
`err.
|
|
353
|
+
- **Three fields, three audiences — and none of them is viewer-facing copy.**
|
|
354
|
+
The string a viewer sees is one **your app owns**; nothing on this error may
|
|
355
|
+
be rendered as-is.
|
|
356
|
+
- `err.code` (`'failed' | 'no-cost'`) — **the branch target**, and the only
|
|
357
|
+
stable one. Switch on it to pick your own localised message.
|
|
358
|
+
- `err.snapshot.error` — **the diagnostic read**, and recovering it is the
|
|
359
|
+
whole point of the fix. **Server-authored and unsanitised** (raw upstream
|
|
360
|
+
text, including database constraint names, can reach it): log it or show it
|
|
361
|
+
in a developer-facing surface, and **never render it verbatim into markup**.
|
|
362
|
+
- `err.message` — **developer-facing**. A generic constant naming only the code
|
|
363
|
+
(`estimate did not return a usable price (no-cost) — reason on .snapshot.error`),
|
|
364
|
+
because `message` is what an uncaught rejection prints and what an error
|
|
365
|
+
reporter ships by default. Safe to log and to let a stack trace print;
|
|
366
|
+
**not intended for display to viewers** — it names an internal field path,
|
|
367
|
+
it is not localised, and **its exact wording is not a contract**, so a UI
|
|
368
|
+
built on it silently rots. Two apps migrating to `0.43.0` piped it into
|
|
369
|
+
rendered UI and would have shipped that sentence to end users.
|
|
276
370
|
- A cost of **`0` is a real price**, not a missing one (the orchestrator whatif
|
|
277
371
|
prices a cache hit at 0). `estimate` resolves it; only a non-numeric
|
|
278
372
|
`cost.total` rejects.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAppStorage.d.ts","sourceRoot":"","sources":["../../src/hooks/useAppStorage.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,kBAAkB,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACjD;;;;OAIG;IACH,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnF;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC7D;;;OAGG;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAClC;;;OAGG;IACH,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CACtC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,IAAI,aAAa,
|
|
1
|
+
{"version":3,"file":"useAppStorage.d.ts","sourceRoot":"","sources":["../../src/hooks/useAppStorage.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,kBAAkB,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACjD;;;;OAIG;IACH,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnF;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC7D;;;OAGG;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAClC;;;OAGG;IACH,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CACtC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,IAAI,aAAa,CAsF7C"}
|
|
@@ -35,15 +35,28 @@ export function useAppStorage() {
|
|
|
35
35
|
},
|
|
36
36
|
async set(key, value) {
|
|
37
37
|
const result = await sendTypedRequest(transport, { type: 'APP_STORAGE_SET', payload: { key, value } }, 'APP_STORAGE_SET_RESULT');
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// A PRESENT `error` is the reject signal, not a TRUTHY one: the reply
|
|
39
|
+
// validator early-accepts anything carrying an `error` key, so
|
|
40
|
+
// `error: ''` reaches here having skipped the success-field checks.
|
|
41
|
+
// `||` (not `??`) so an empty error string still yields readable copy.
|
|
42
|
+
if (!result.ok || result.error !== undefined) {
|
|
43
|
+
throw new Error(result.error || 'storage set failed');
|
|
40
44
|
}
|
|
41
45
|
return { ok: true, sizeBytes: result.sizeBytes };
|
|
42
46
|
},
|
|
43
47
|
async delete(key) {
|
|
44
48
|
const result = await sendTypedRequest(transport, { type: 'APP_STORAGE_DELETE', payload: { key } }, 'APP_STORAGE_DELETE_RESULT');
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
// PRESENT, not truthy — see `set()` above.
|
|
50
|
+
if (!result.ok || result.error !== undefined) {
|
|
51
|
+
throw new Error(result.error || 'storage delete failed');
|
|
52
|
+
}
|
|
53
|
+
// `deleted` is optional on the wire type because an error reply omits
|
|
54
|
+
// it. On the success path the validator requires a boolean, so this is
|
|
55
|
+
// defence in depth rather than a reachable branch through the real
|
|
56
|
+
// transport — but it is what makes the `boolean` we return honest,
|
|
57
|
+
// instead of a cast asserting a guarantee this function cannot see.
|
|
58
|
+
if (typeof result.deleted !== 'boolean') {
|
|
59
|
+
throw new Error('storage delete failed: reply carried no `deleted` flag');
|
|
47
60
|
}
|
|
48
61
|
return { ok: true, deleted: result.deleted };
|
|
49
62
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAppStorage.js","sourceRoot":"","sources":["../../src/hooks/useAppStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AA6D5D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAgB,GAAG,EAAE;QACjC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QACjC,OAAO;YACL,KAAK,CAAC,GAAG,CAAc,GAAW;gBAChC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CACnC,SAAS,EACT,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,EAC7C,wBAAwB,CACzB,CAAC;gBACF,IAAI,MAAM,CAAC,KAAK;oBAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChD,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,CAAa,CAAC;YAC5C,CAAC;YACD,KAAK,CAAC,GAAG,CAAc,GAAW,EAAE,KAAQ;gBAC1C,MAAM,MAAM,GAAG,MAAM,gBAAgB,CACnC,SAAS,EACT,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EACpD,wBAAwB,CACzB,CAAC;gBACF,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"useAppStorage.js","sourceRoot":"","sources":["../../src/hooks/useAppStorage.ts"],"names":[],"mappings":"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"}
|