@civitai/blocks-react 0.43.1 → 0.44.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.
- package/README.md +87 -6
- package/dist/hooks/useAppStorage.d.ts.map +1 -1
- package/dist/hooks/useAppStorage.js +17 -11
- package/dist/hooks/useAppStorage.js.map +1 -1
- package/dist/hooks/useBuzzWorkflow.d.ts +260 -20
- package/dist/hooks/useBuzzWorkflow.d.ts.map +1 -1
- package/dist/hooks/useBuzzWorkflow.js +302 -20
- package/dist/hooks/useBuzzWorkflow.js.map +1 -1
- package/dist/hooks/useCheckpointPicker.d.ts.map +1 -1
- package/dist/hooks/useCheckpointPicker.js +5 -4
- package/dist/hooks/useCheckpointPicker.js.map +1 -1
- package/dist/hooks/useSaveImage.d.ts.map +1 -1
- package/dist/hooks/useSaveImage.js +2 -3
- package/dist/hooks/useSaveImage.js.map +1 -1
- package/dist/hooks/useSharedStorage.d.ts.map +1 -1
- package/dist/hooks/useSharedStorage.js +18 -22
- 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/replyError.d.ts +87 -0
- package/dist/internal/replyError.d.ts.map +1 -0
- package/dist/internal/replyError.js +90 -0
- package/dist/internal/replyError.js.map +1 -0
- package/dist/internal/validate.d.ts +68 -16
- package/dist/internal/validate.d.ts.map +1 -1
- package/dist/internal/validate.js +91 -27
- package/dist/internal/validate.js.map +1 -1
- package/package.json +2 -2
|
@@ -144,20 +144,13 @@ function sleep(ms, signal) {
|
|
|
144
144
|
* off a third party's default-printed surface. `test/useBuzzWorkflow.test.tsx`
|
|
145
145
|
* pins it with a realistic `Unique constraint failed: Key (email)=(…)` fixture.
|
|
146
146
|
*
|
|
147
|
-
* 🔴
|
|
148
|
-
* `WORKFLOW_SUBMITTED`
|
|
149
|
-
* `status
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
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.
|
|
147
|
+
* 🔴 `submit` HAS ITS OWN CLASS — {@link WorkflowSubmitError} — BECAUSE ITS
|
|
148
|
+
* DISCRIMINATOR IS DIFFERENT. On `WORKFLOW_SUBMITTED` both producers report
|
|
149
|
+
* `status:'failed'`, so `status` separates nothing there and `cost` presence is
|
|
150
|
+
* what does. Do not merge the two classes or reuse this one for submit: the
|
|
151
|
+
* question each answers is different ("was a usable price returned?" vs "was a
|
|
152
|
+
* workflow actually queued?") and so is the arm that must keep resolving.
|
|
153
|
+
* (civitai/civitai-app-starters#251, the `submit` half of civitai/civitai#4159.)
|
|
161
154
|
*/
|
|
162
155
|
export class WorkflowEstimateError extends Error {
|
|
163
156
|
/**
|
|
@@ -219,14 +212,234 @@ export class WorkflowEstimateError extends Error {
|
|
|
219
212
|
this.snapshot = snapshot;
|
|
220
213
|
}
|
|
221
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* The `workflowId` the host stamps on a snapshot it SYNTHESISED itself, rather
|
|
217
|
+
* than one derived from a real orchestrator workflow.
|
|
218
|
+
*
|
|
219
|
+
* 🔴 THIS IS A REAL WIRE INVARIANT, NOT A HEURISTIC. Every reply the host builds
|
|
220
|
+
* itself goes through `failureSnapshot()` (civitai
|
|
221
|
+
* `src/components/AppBlocks/failureSnapshot.ts`), which hardcodes this exact
|
|
222
|
+
* literal — from its `catch` arms AND from non-catch short-circuits such as the
|
|
223
|
+
* moderator-review nack. The server's `snapshotFromWorkflow` instead returns
|
|
224
|
+
* `workflow.id ?? 'whatif'`.
|
|
225
|
+
*
|
|
226
|
+
* 🔴 COMPARE IT WITH `===` — EXACT AND CASE-SENSITIVE. Every looser comparison
|
|
227
|
+
* quietly reclassifies a reply the host did NOT synthesise into the reassuring
|
|
228
|
+
* "nothing to report" arm, and each direction has to be pinned separately:
|
|
229
|
+
* `.startsWith()` accepts `failed-x`, `.endsWith()` accepts `x-failed`, and a
|
|
230
|
+
* case-folding compare accepts `FAILED`. All three are WIDENINGS, which a
|
|
231
|
+
* delete-only mutation sweep cannot see. Pinned by three near-miss fixtures in
|
|
232
|
+
* `test/useBuzzWorkflow.test.tsx`; an earlier version of this comment said only
|
|
233
|
+
* "never a prefix test" while the tests pinned only that one direction — a
|
|
234
|
+
* description wider than its coverage.
|
|
235
|
+
*
|
|
236
|
+
* 🔴 THE FAIL-SAFETY IS ONE-DIRECTIONAL, AND SAYING OTHERWISE WAS A BUG IN AN
|
|
237
|
+
* EARLIER REVISION OF THIS COMMENT. An id that is NOT this literal is treated as
|
|
238
|
+
* possibly-charged, so an unrecognised id never buys the reassuring reading —
|
|
239
|
+
* that direction holds. The converse does NOT: this sentinel is also what the
|
|
240
|
+
* host stamps when a submit threw for reasons that may still have created and
|
|
241
|
+
* charged a workflow (a lost response, an in-progress idempotency conflict). So
|
|
242
|
+
* the sentinel arm means "the host had no workflow to report", never "nothing
|
|
243
|
+
* happened". See {@link WorkflowSubmitError.code}.
|
|
244
|
+
*/
|
|
245
|
+
const HOST_SYNTHESISED_WORKFLOW_ID = 'failed';
|
|
246
|
+
/**
|
|
247
|
+
* Thrown by {@link UseBuzzWorkflowReturn.submit} when the host's reply carries no
|
|
248
|
+
* usable workflow outcome — either the submit ERRORED before anything was queued,
|
|
249
|
+
* or a workflow-shaped reply came back already failed with no price.
|
|
250
|
+
*
|
|
251
|
+
* 🔴 READ {@link WorkflowSubmitError.code} BEFORE SAYING ANYTHING ABOUT MONEY.
|
|
252
|
+
* The two codes differ on exactly that, and getting it wrong is expensive in both
|
|
253
|
+
* directions — see the per-code notes below.
|
|
254
|
+
*
|
|
255
|
+
* 🔴 WHY THIS EXISTS — civitai/civitai-app-starters#251, the `submit` half of
|
|
256
|
+
* civitai/civitai#4159. A server-side `blocks.submitWorkflow` throw cannot reach
|
|
257
|
+
* the block as a rejection; the reply crosses `postMessage`. The host instead
|
|
258
|
+
* posts a well-formed `WORKFLOW_SUBMITTED` carrying its `failureSnapshot(err)` —
|
|
259
|
+
* `{ workflowId: 'failed', status: 'failed', error: '<server message>' }`, with
|
|
260
|
+
* **no `cost`**. That snapshot is perfectly legal, so `submit()` resolved it and
|
|
261
|
+
* moved the hook to `'done'`, handing the caller a "workflow" that does not
|
|
262
|
+
* exist.
|
|
263
|
+
*
|
|
264
|
+
* 🔴 TWO PRODUCERS, ONE `status` — AND HERE `status` DISCRIMINATES NOTHING. This
|
|
265
|
+
* is what makes submit's version of the defect different from estimate's, and
|
|
266
|
+
* why {@link WorkflowEstimateError}'s guard could not simply be copied:
|
|
267
|
+
*
|
|
268
|
+
* - **budget / spend-cap REJECTION** — a legitimate OUTCOME. The server quotes
|
|
269
|
+
* the price it refused to charge, so the snapshot carries a numeric
|
|
270
|
+
* `cost.total`. Blocks recover from it (open a top-up flow), so it MUST keep
|
|
271
|
+
* RESOLVING. Every such exit on the server attaches a cost: the per-call
|
|
272
|
+
* `buzzBudget` gate, the per-user daily Buzz cap, the per-app aggregate and
|
|
273
|
+
* velocity caps, and the dev-tunnel session cap — on all three body kinds.
|
|
274
|
+
* - **caught server EXCEPTION** — `failureSnapshot(err)`, no `cost`, and the
|
|
275
|
+
* `'failed'` sentinel id. The host had no workflow to report — usually
|
|
276
|
+
* nothing was queued, but a lost response or an in-progress idempotency
|
|
277
|
+
* conflict lands here too. Rejects as `'exception'`.
|
|
278
|
+
* - **a reply that came back failed and unpriced with a NON-sentinel id** —
|
|
279
|
+
* normally a genuine orchestrator id, no `cost` (the server's
|
|
280
|
+
* `snapshotFromWorkflow` omits the key whenever `workflow.cost?.total` is not
|
|
281
|
+
* numeric). Rejects as `'workflow-failed'`, and **money may already be
|
|
282
|
+
* committed** — see that code's note.
|
|
283
|
+
*
|
|
284
|
+
* So the rule is `cost` presence, and ONLY among failure-shaped replies: an
|
|
285
|
+
* ordinary in-flight submit (`{ workflowId:'wf_…', status:'pending' }`) is
|
|
286
|
+
* cost-less too and must keep resolving, which is why the guard is not keyed on
|
|
287
|
+
* `cost` alone either. Both clauses are load-bearing; each has its own control
|
|
288
|
+
* in `test/useBuzzWorkflow.test.tsx`.
|
|
289
|
+
*
|
|
290
|
+
* 🔴 THE GUARD IS DELIBERATELY NOT WIDENED TO ALL TERMINAL STATUSES. A cost-less
|
|
291
|
+
* `succeeded` / `canceled` / `expired` reply is a legitimate outcome and must
|
|
292
|
+
* RESOLVE; only `'failed'` is unusable. Swapping the clause for
|
|
293
|
+
* `TERMINAL_STATUSES.has(...)` is a silent WIDENING that a delete-only mutation
|
|
294
|
+
* sweep cannot see — `test/useBuzzWorkflow.test.tsx` pins each of those three
|
|
295
|
+
* statuses explicitly for exactly that reason.
|
|
296
|
+
*
|
|
297
|
+
* 🔴 THREE FIELDS, THREE AUDIENCES — AND **NONE OF THEM IS VIEWER-FACING COPY**,
|
|
298
|
+
* exactly as on {@link WorkflowEstimateError}. Two apps migrating to `0.43.0`
|
|
299
|
+
* piped that class's `err.message` straight into rendered UI
|
|
300
|
+
* (civitai/civitai-app-starters#253); the same split applies here so the same
|
|
301
|
+
* mistake is not re-enabled on the submit path.
|
|
302
|
+
*
|
|
303
|
+
* - {@link WorkflowSubmitError.snapshot}`.error` — **the DIAGNOSTIC read.** The
|
|
304
|
+
* server's own words, verbatim. **Server-authored and UNSANITISED**:
|
|
305
|
+
* civitai's `errorHandling.ts` documents that raw upstream text —
|
|
306
|
+
* Prisma/`pg` column and constraint names among it — can reach this field.
|
|
307
|
+
* Log it, or show it in a developer-facing error surface. **NEVER render it
|
|
308
|
+
* verbatim into markup**, and think before shipping it to a third-party
|
|
309
|
+
* error tracker.
|
|
310
|
+
* - {@link WorkflowSubmitError.message} — **DEVELOPER-FACING.** A CONSTANT
|
|
311
|
+
* template with only `code` interpolated. It contains no server text, so it
|
|
312
|
+
* is safe to LOG and safe to let a stack trace print — deliberate, because
|
|
313
|
+
* `message` is what an uncaught rejection prints and what a third-party
|
|
314
|
+
* block's error reporter ships upstream by default. **It is NOT intended for
|
|
315
|
+
* display to viewers** and **its exact wording is NOT a contract.**
|
|
316
|
+
* - {@link WorkflowSubmitError.code} — **the BRANCH TARGET**, and the only
|
|
317
|
+
* stable one.
|
|
318
|
+
*
|
|
319
|
+
* 🔴 DO NOT "SIMPLIFY" THIS BY PUTTING `snapshot.error` BACK ON `message`, and do
|
|
320
|
+
* not widen the guard to reject a budget rejection. The first re-opens #253; the
|
|
321
|
+
* second breaks the top-up recovery flow, which is the one thing #251 says must
|
|
322
|
+
* not break.
|
|
323
|
+
*/
|
|
324
|
+
export class WorkflowSubmitError extends Error {
|
|
325
|
+
/**
|
|
326
|
+
* WHICH PRODUCER this was, structurally — so a caller branches on an enum
|
|
327
|
+
* rather than on prose. It is the ONLY stable branch target here:
|
|
328
|
+
* `snapshot.error` is server-authored and can change without notice, and
|
|
329
|
+
* {@link WorkflowSubmitError.message} is a generic developer-facing summary
|
|
330
|
+
* whose exact wording is not a contract either.
|
|
331
|
+
*
|
|
332
|
+
* 🔴 THE TWO CODES DIFFER ON WHETHER MONEY MOVED. Do not collapse them, and do
|
|
333
|
+
* not write recovery copy that ignores the distinction.
|
|
334
|
+
*
|
|
335
|
+
* - `'exception'` — the host built this reply itself
|
|
336
|
+
* (`failureSnapshot(err)`, id {@link HOST_SYNTHESISED_WORKFLOW_ID}), from a
|
|
337
|
+
* `catch` OR from a non-catch short-circuit such as the moderator-review
|
|
338
|
+
* nack. **It means the host had no workflow to report — NOT that nothing
|
|
339
|
+
* happened.**
|
|
340
|
+
*
|
|
341
|
+
* 🔴 USUALLY nothing was queued and nothing was charged, and a retry is the
|
|
342
|
+
* sensible recovery. But the same shape is reachable when a workflow MAY have
|
|
343
|
+
* been created and charged, because the failure happened after the request
|
|
344
|
+
* left the block:
|
|
345
|
+
* - a **lost response** — the server's own catch concedes that "the
|
|
346
|
+
* orchestrator externalId dedupe still protects a retry that DID create a
|
|
347
|
+
* workflow server-side despite a lost response". What that path refunds
|
|
348
|
+
* is its own reservation and cap counters; the Buzz debit happens inside
|
|
349
|
+
* the orchestrator's submit.
|
|
350
|
+
* - an **in-progress idempotency CONFLICT** — a concurrent first attempt is
|
|
351
|
+
* still in flight and may be committing right now. Retrying blind is the
|
|
352
|
+
* worst option there.
|
|
353
|
+
* - a **transient transport failure** (5xx / 408 / 429 / 401), which the
|
|
354
|
+
* `dev:live` host collapses into this same shape.
|
|
355
|
+
*
|
|
356
|
+
* So prefer **reusing the same {@link SubmitWorkflowOptions.idempotencyKey}**
|
|
357
|
+
* on retry rather than letting a fresh one be minted, and do not render
|
|
358
|
+
* "nothing was charged" to a viewer as a certainty. There is no workflow id
|
|
359
|
+
* on this arm to poll.
|
|
360
|
+
*
|
|
361
|
+
* - `'workflow-failed'` — the id was NOT the host's sentinel, so the reply came
|
|
362
|
+
* from the server's `snapshotFromWorkflow`: normally a real orchestrator id,
|
|
363
|
+
* already `'failed'` and with no price.
|
|
364
|
+
*
|
|
365
|
+
* 🔴 **DO NOT TELL THE VIEWER NOTHING WAS CHARGED, AND DO NOT BLIND-RETRY.**
|
|
366
|
+
* Server-side, `blocks.submitWorkflow` treats *any resolved* submit as
|
|
367
|
+
* money-COMMITTED: its own comment is "A resolved submit is money-COMMITTED
|
|
368
|
+
* (the reservation is kept regardless of snapshot status)… we do NOT refund
|
|
369
|
+
* on a non-throwing failed snapshot", and `finalizeGenIdempotency` runs on
|
|
370
|
+
* that path. So Buzz may already be spent for this call.
|
|
371
|
+
*
|
|
372
|
+
* A retry is a SECOND reservation unless you reuse the same
|
|
373
|
+
* {@link SubmitWorkflowOptions.idempotencyKey} — `submit()` mints a fresh key
|
|
374
|
+
* per call by default, so an automatic retry double-reserves.
|
|
375
|
+
*
|
|
376
|
+
* 🔴 `err.snapshot.workflowId` IS USUALLY POLLABLE, BUT CHECK IT FIRST — this
|
|
377
|
+
* arm is defined by what the id is NOT. The server emits `workflow.id ??
|
|
378
|
+
* 'whatif'`, and it treats **both** `'failed'` and `'whatif'` as non-workflow
|
|
379
|
+
* sentinels (it skips its own persistence and settle steps on either). So
|
|
380
|
+
* `'whatif'` lands here — correctly, because the cautious money reading still
|
|
381
|
+
* applies — but there is nothing to poll. Guard with
|
|
382
|
+
* `err.snapshot.workflowId !== 'whatif'` before calling
|
|
383
|
+
* {@link UseBuzzWorkflowReturn.watch} / {@link UseBuzzWorkflowReturn.poll} to
|
|
384
|
+
* learn the workflow's actual fate before spending again.
|
|
385
|
+
*
|
|
386
|
+
* A union rather than a boolean so a future producer gets its own code without
|
|
387
|
+
* breaking a caller's `switch`.
|
|
388
|
+
*
|
|
389
|
+
* 🔴 A BUDGET REJECTION NEVER ARRIVES HERE. It resolves, and is read off the
|
|
390
|
+
* returned snapshot as `status === 'failed'` with a numeric `cost.total`.
|
|
391
|
+
*/
|
|
392
|
+
code;
|
|
393
|
+
/**
|
|
394
|
+
* The snapshot the host replied with, VERBATIM — including `snapshot.error`,
|
|
395
|
+
* the server's own words, when there are any.
|
|
396
|
+
*
|
|
397
|
+
* 🔴 `snapshot.error` IS SERVER-AUTHORED AND UNSANITISED. It is where the
|
|
398
|
+
* reason lives, but raw upstream text — Prisma/`pg` column and constraint
|
|
399
|
+
* names among it — can reach that field. Log it, show it in a developer-facing
|
|
400
|
+
* error surface, **NEVER render it verbatim into markup**.
|
|
401
|
+
*/
|
|
402
|
+
snapshot;
|
|
403
|
+
constructor(snapshot, code) {
|
|
404
|
+
// 🔴 GENERIC, AND DELIBERATELY NOT `snapshot.error` — see the class docs and
|
|
405
|
+
// civitai/civitai-app-starters#253. `message` is the field an uncaught
|
|
406
|
+
// rejection PRINTS and the field a third-party block's error reporter ships
|
|
407
|
+
// upstream by default, so putting the raw server string here would put
|
|
408
|
+
// database internals on the default-printed surface of somebody else's code.
|
|
409
|
+
// Exposure to the block is identical either way (`snapshot.error` was always
|
|
410
|
+
// on the wire); only the DISPOSITION changes. `code` is carried IN the
|
|
411
|
+
// message so an uncaught rejection is still self-describing.
|
|
412
|
+
//
|
|
413
|
+
// 🔴 IT MAKES NO CLAIM ABOUT MONEY, AND THAT IS THE POINT. An earlier draft
|
|
414
|
+
// read "submit did not queue a workflow", which is FALSE for
|
|
415
|
+
// `'workflow-failed'` — that arm has a workflow-shaped reply and
|
|
416
|
+
// possibly-committed
|
|
417
|
+
// spend. A single template that is true for BOTH codes cannot mislead a
|
|
418
|
+
// developer reading a stack trace; the money semantics live on `code`.
|
|
419
|
+
super(`submit did not return a usable workflow (${code}) — reason on .snapshot.error`);
|
|
420
|
+
this.name = 'WorkflowSubmitError';
|
|
421
|
+
this.code = code;
|
|
422
|
+
this.snapshot = snapshot;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
222
425
|
/**
|
|
223
426
|
* Orchestrates the estimate → confirm → submit → poll dance through the
|
|
224
427
|
* host-mediated `postMessage` path.
|
|
225
428
|
*
|
|
226
|
-
* The host enforces budget rules (`cost_estimate <= token.buzzBudget`)
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
429
|
+
* The host enforces budget rules (`cost_estimate <= token.buzzBudget`) before
|
|
430
|
+
* forwarding to the orchestrator.
|
|
431
|
+
*
|
|
432
|
+
* 🔴 A BUDGET REFUSAL DOES **NOT** REJECT — IT RESOLVES. It comes back as a
|
|
433
|
+
* snapshot with `status: 'failed'`, an `error` string and the `cost` the server
|
|
434
|
+
* declined to charge, and THAT resolved shape is the cue to call
|
|
435
|
+
* `useBuzzPurchase().openPurchaseModal()`. What DOES reject is a submit with no
|
|
436
|
+
* usable outcome — see {@link WorkflowSubmitError}. Routing a rejection into a
|
|
437
|
+
* top-up sells Buzz for a failure Buzz cannot fix.
|
|
438
|
+
*
|
|
439
|
+
* 🔴 NOR IS EVERY RESOLVED `'failed'` AN AFFORDABILITY PROBLEM. The per-app
|
|
440
|
+
* velocity limit, the per-app aggregate daily cap, a fail-closed "temporarily
|
|
441
|
+
* unavailable" deny and a missing price quote are all priced, resolving outcomes
|
|
442
|
+
* too. Branch on the message/your own policy before offering to sell anything.
|
|
230
443
|
*
|
|
231
444
|
* AFTER `submit` FLIPS `status` TO `'polling'`, USE `watch(workflowId)`. It owns
|
|
232
445
|
* the loop, resolves on the terminal snapshot, and pushes every intermediate
|
|
@@ -288,8 +501,39 @@ export class WorkflowEstimateError extends Error {
|
|
|
288
501
|
* logForDebugging(err.message, err.snapshot.error); // developer-facing: LOG only
|
|
289
502
|
* showError(estimateFailureMessage(err)); // viewer-facing: app-owned
|
|
290
503
|
* }
|
|
291
|
-
*
|
|
292
|
-
*
|
|
504
|
+
* // 🔴 submit() REJECTS when the reply carries no usable workflow outcome, so it
|
|
505
|
+
* // needs a catch too — and the two codes differ on whether MONEY MOVED.
|
|
506
|
+
* try {
|
|
507
|
+
* const snap = await submit(body); // status 'submitting' → 'polling'
|
|
508
|
+
* if (snap.status === 'failed') {
|
|
509
|
+
* // RESOLVED + priced = a server outcome (affordability, a cap, a velocity
|
|
510
|
+
* // limit, a transient deny). Only some of those are fixable by buying Buzz.
|
|
511
|
+
* showError(submitOutcomeMessage(snap));
|
|
512
|
+
* } else {
|
|
513
|
+
* const done = await watch(snap.workflowId, { onUpdate: render }); // → terminal
|
|
514
|
+
* if (done.status === 'succeeded') setImages(done.imageUrls ?? []);
|
|
515
|
+
* }
|
|
516
|
+
* } catch (err) {
|
|
517
|
+
* if (!(err instanceof WorkflowSubmitError)) throw err;
|
|
518
|
+
* logForDebugging(err.message, err.snapshot.error); // developer-facing: LOG only
|
|
519
|
+
* // 🔴 TWO SEPARATE QUESTIONS: `code` decides what you may say about MONEY,
|
|
520
|
+
* // the id decides only whether there is anything to POLL. Conjoining them
|
|
521
|
+
* // sends a 'whatif' id into the reassuring arm.
|
|
522
|
+
* if (err.code === 'workflow-failed') {
|
|
523
|
+
* // Spend may already be committed. Do NOT retry blindly (that mints a new
|
|
524
|
+
* // idempotency key = a second reservation) and do NOT claim nothing was
|
|
525
|
+
* // charged.
|
|
526
|
+
* showError('The generation may have started but did not complete.');
|
|
527
|
+
* // 'whatif' is a non-workflow sentinel — nothing behind it to poll.
|
|
528
|
+
* if (err.snapshot.workflowId !== 'whatif') {
|
|
529
|
+
* await watch(err.snapshot.workflowId, { onUpdate: render });
|
|
530
|
+
* }
|
|
531
|
+
* } else {
|
|
532
|
+
* // 'exception' — usually nothing was queued. Retry, but reuse the SAME
|
|
533
|
+
* // idempotencyKey: a lost response can also land here.
|
|
534
|
+
* showError('Could not start the generation. Please try again.');
|
|
535
|
+
* }
|
|
536
|
+
* }
|
|
293
537
|
*/
|
|
294
538
|
export function useBuzzWorkflow() {
|
|
295
539
|
const [status, setStatus] = useState('idle');
|
|
@@ -353,7 +597,45 @@ export function useBuzzWorkflow() {
|
|
|
353
597
|
const idempotencyKey = options?.idempotencyKey ?? generateIdempotencyKey();
|
|
354
598
|
try {
|
|
355
599
|
const { snapshot } = await sendTypedRequest(getTransport(), { type: 'SUBMIT_WORKFLOW', payload: { body, idempotencyKey } }, 'WORKFLOW_SUBMITTED', { timeoutMs: WORKFLOW_REQUEST_TIMEOUT_MS });
|
|
600
|
+
// 🔴 PUBLISH THE SNAPSHOT BEFORE THE REJECTION BELOW, for the same reason
|
|
601
|
+
// `estimate` does: a block may render from `result` rather than from the
|
|
602
|
+
// returned value, and jumping over this line would leave the PREVIOUS
|
|
603
|
+
// submit's snapshot in place — a live control pointing at a workflow THIS
|
|
604
|
+
// submit did not queue.
|
|
356
605
|
setResult(snapshot);
|
|
606
|
+
// 🔴 AN ERRORED SUBMIT MUST REJECT (civitai/civitai-app-starters#251, the
|
|
607
|
+
// `submit` half of civitai/civitai#4159). Two producers report
|
|
608
|
+
// `status:'failed'` and `status` separates neither:
|
|
609
|
+
//
|
|
610
|
+
// - a budget / spend-cap REJECTION is an OUTCOME the block recovers from
|
|
611
|
+
// (open a top-up flow). The server quotes the price it refused to
|
|
612
|
+
// charge, so `cost.total` is present. It RESOLVES — turning this arm
|
|
613
|
+
// into a throw is the one change that would break the recovery path.
|
|
614
|
+
// - a failure-shaped reply with NO `cost` is not a usable outcome. It
|
|
615
|
+
// REJECTS — and the `code` says which kind, because they differ on
|
|
616
|
+
// whether money moved (see WorkflowSubmitError.code).
|
|
617
|
+
//
|
|
618
|
+
// BOTH clauses are load-bearing. Dropping `status === 'failed'` would
|
|
619
|
+
// reject every ordinary in-flight reply (`{status:'pending'}` is cost-less
|
|
620
|
+
// too); dropping the cost test would reject the budget rejection. And the
|
|
621
|
+
// test is `typeof … !== 'number'`, never `!snapshot.cost?.total`: `0` is a
|
|
622
|
+
// real price and falsy.
|
|
623
|
+
//
|
|
624
|
+
// 🔴 `status === 'failed'`, NOT `TERMINAL_STATUSES.has(status)`. Widening it
|
|
625
|
+
// would reject cost-less `succeeded`/`canceled`/`expired` replies, which are
|
|
626
|
+
// legitimate outcomes the server really does emit without a price
|
|
627
|
+
// (`snapshotFromWorkflow` omits `cost` on any non-numeric total). That
|
|
628
|
+
// WIDENING is invisible to a mutation sweep that only deletes clauses, so
|
|
629
|
+
// all three statuses are pinned by their own fixtures in the test file.
|
|
630
|
+
if (snapshot.status === 'failed' && typeof snapshot.cost?.total !== 'number') {
|
|
631
|
+
// 🔴 WHICH ARM: the host stamps its own synthesised failures with the
|
|
632
|
+
// `'failed'` sentinel, while a server-built reply carries `workflow.id`
|
|
633
|
+
// (or the `'whatif'` sentinel).
|
|
634
|
+
// Anything unrecognised falls to `'workflow-failed'`, the arm that assumes
|
|
635
|
+
// money MAY be committed — an unknown id must never buy the reassuring
|
|
636
|
+
// "nothing was charged" reading.
|
|
637
|
+
throw new WorkflowSubmitError(snapshot, snapshot.workflowId === HOST_SYNTHESISED_WORKFLOW_ID ? 'exception' : 'workflow-failed');
|
|
638
|
+
}
|
|
357
639
|
setStatus(TERMINAL_STATUSES.has(snapshot.status) ? 'done' : 'polling');
|
|
358
640
|
return snapshot;
|
|
359
641
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBuzzWorkflow.js","sourceRoot":"","sources":["../../src/hooks/useBuzzWorkflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAI9C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEpF;;;;GAIG;AACH,MAAM,iBAAiB,GAAiD,IAAI,GAAG,CAAC;IAC9E,WAAW;IACX,QAAQ;IACR,UAAU;IACV,SAAS;CACV,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,MAAM,2BAA2B,GAAG,OAAO,CAAC;AAE5C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAE7C,qFAAqF;AACrF,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAExC,6EAA6E;AAC7E,MAAM,wBAAwB,GAAG,EAAE,GAAG,MAAM,CAAC;AAE7C,gFAAgF;AAChF,MAAM,yBAAyB,GAAG,CAAC,CAAC;AAwDpC;;;;;;;;;GASG;AACH,SAAS,KAAK,CAAC,EAAU,EAAE,MAAoB;IAC7C,IAAI,MAAM,EAAE,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC9C,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC3C,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"useBuzzWorkflow.js","sourceRoot":"","sources":["../../src/hooks/useBuzzWorkflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"useCheckpointPicker.d.ts","sourceRoot":"","sources":["../../src/hooks/useCheckpointPicker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAOnE;;;;;;;;;;;;;;;;;;;;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,5 +1,6 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
2
|
import { HUMAN_INTERACTION_TIMEOUT_MS } from '../internal/requestTimeouts.js';
|
|
3
|
+
import { throwOnFailedReply } from '../internal/replyError.js';
|
|
3
4
|
import { getTransport } from '../internal/singleton.js';
|
|
4
5
|
import { sendTypedRequest } from '../internal/transport.js';
|
|
5
6
|
/**
|
|
@@ -37,10 +38,10 @@ export function useCheckpointPicker() {
|
|
|
37
38
|
return { selected };
|
|
38
39
|
}, []);
|
|
39
40
|
const persist = useCallback(async (versionId) => {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
const reply = await sendTypedRequest(getTransport(), { type: 'SET_USER_CHECKPOINT', payload: { versionId } }, 'USER_CHECKPOINT_SET');
|
|
42
|
+
// This site tested `!ok` ALONE before PR #273, so the `error` clause is
|
|
43
|
+
// new here, not merely retyped.
|
|
44
|
+
throwOnFailedReply(reply, 'failed to persist checkpoint');
|
|
44
45
|
}, []);
|
|
45
46
|
return { open, persist };
|
|
46
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCheckpointPicker.js","sourceRoot":"","sources":["../../src/hooks/useCheckpointPicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAIpC,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,mBAAmB;IAcjC,MAAM,IAAI,GAAG,WAAW,CACtB,KAAK,EAAE,IAA2D,EAAE,EAAE;QACpE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,gBAAgB,CACzC,YAAY,EAAE,EACd;YACE,IAAI,EAAE,wBAAwB;YAC9B,OAAO,EAAE;gBACP,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,IAAI;oBAC/B,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE;oBAC7C,CAAC,CAAC,EAAE,CAAC;aACR;SACF,EACD,0BAA0B,EAC1B,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAC5C,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,CAAC;IACtB,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,SAAwB,EAAE,EAAE;QAC7D,MAAM,
|
|
1
|
+
{"version":3,"file":"useCheckpointPicker.js","sourceRoot":"","sources":["../../src/hooks/useCheckpointPicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAIpC,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,mBAAmB;IAcjC,MAAM,IAAI,GAAG,WAAW,CACtB,KAAK,EAAE,IAA2D,EAAE,EAAE;QACpE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,gBAAgB,CACzC,YAAY,EAAE,EACd;YACE,IAAI,EAAE,wBAAwB;YAC9B,OAAO,EAAE;gBACP,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,IAAI;oBAC/B,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE;oBAC7C,CAAC,CAAC,EAAE,CAAC;aACR;SACF,EACD,0BAA0B,EAC1B,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAC5C,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,CAAC;IACtB,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,SAAwB,EAAE,EAAE;QAC7D,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAClC,YAAY,EAAE,EACd,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,EACvD,qBAAqB,CACtB,CAAC;QACF,wEAAwE;QACxE,gCAAgC;QAChC,kBAAkB,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;IAC5D,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSaveImage.d.ts","sourceRoot":"","sources":["../../src/hooks/useSaveImage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useSaveImage.d.ts","sourceRoot":"","sources":["../../src/hooks/useSaveImage.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;OASG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,IAAI,YAAY,CAe3C"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
2
|
import { getTransport } from '../internal/singleton.js';
|
|
3
|
+
import { throwOnFailedReply } from '../internal/replyError.js';
|
|
3
4
|
import { sendTypedRequest } from '../internal/transport.js';
|
|
4
5
|
/**
|
|
5
6
|
* Download an image via the host-mediated `SAVE_IMAGE` → `SAVE_IMAGE_RESULT`
|
|
@@ -18,9 +19,7 @@ export function useSaveImage() {
|
|
|
18
19
|
? { url: input.url, filename: input.filename }
|
|
19
20
|
: { imageId: input.imageId, filename: input.filename };
|
|
20
21
|
const reply = await sendTypedRequest(getTransport(), { type: 'SAVE_IMAGE', payload }, 'SAVE_IMAGE_RESULT');
|
|
21
|
-
|
|
22
|
-
throw new Error(reply.error ?? 'failed to save image');
|
|
23
|
-
}
|
|
22
|
+
throwOnFailedReply(reply, 'failed to save image');
|
|
24
23
|
}, []);
|
|
25
24
|
return { saveImage };
|
|
26
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSaveImage.js","sourceRoot":"","sources":["../../src/hooks/useSaveImage.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;AAgC5D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,EAAE,KAAqB,EAAiB,EAAE;QAC3E,MAAM,OAAO,GACX,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;YACvC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;YAC9C,CAAC,CAAC,EAAE,OAAO,EAAG,KAA6B,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QACpF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAClC,YAAY,EAAE,EACd,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,EAC/B,mBAAmB,CACpB,CAAC;QACF,
|
|
1
|
+
{"version":3,"file":"useSaveImage.js","sourceRoot":"","sources":["../../src/hooks/useSaveImage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAgC5D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,EAAE,KAAqB,EAAiB,EAAE;QAC3E,MAAM,OAAO,GACX,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;YACvC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;YAC9C,CAAC,CAAC,EAAE,OAAO,EAAG,KAA6B,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QACpF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAClC,YAAY,EAAE,EACd,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,EAC/B,mBAAmB,CACpB,CAAC;QACF,kBAAkB,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;IACpD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,SAAS,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSharedStorage.d.ts","sourceRoot":"","sources":["../../src/hooks/useSharedStorage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAyB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"useSharedStorage.d.ts","sourceRoot":"","sources":["../../src/hooks/useSharedStorage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAyB,MAAM,yBAAyB,CAAC;AAMzF;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB;;;;;;OAMG;IACH,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;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,gBAAgB,CAAC,CAAC;IAC9B;;;;;;;OAOG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACjD;;;;;;;OAOG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC;;;OAGG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D;;;;;;;;;OASG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D;;;OAGG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACnE;AA8CD,wBAAgB,gBAAgB,IAAI,gBAAgB,CAgHnD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import { getTransport } from '../internal/singleton.js';
|
|
3
|
+
import { throwOnFailedReply, throwOnReplyError } from '../internal/replyError.js';
|
|
3
4
|
import { sendTypedRequest } from '../internal/transport.js';
|
|
4
5
|
/**
|
|
5
6
|
* App-scoped, append-only, community-votable SHARED datastore. Sibling of
|
|
@@ -57,8 +58,7 @@ export function useSharedStorage() {
|
|
|
57
58
|
cursor: opts?.cursor,
|
|
58
59
|
},
|
|
59
60
|
}, 'SHARED_LIST_RESULT');
|
|
60
|
-
|
|
61
|
-
throw new Error(result.error);
|
|
61
|
+
throwOnReplyError(result, 'shared list failed');
|
|
62
62
|
return {
|
|
63
63
|
items: result.items.map(rehydrateSharedItem),
|
|
64
64
|
nextCursor: result.nextCursor,
|
|
@@ -66,56 +66,52 @@ export function useSharedStorage() {
|
|
|
66
66
|
},
|
|
67
67
|
async get(key) {
|
|
68
68
|
const result = await sendTypedRequest(transport, { type: 'SHARED_GET', payload: { key } }, 'SHARED_GET_RESULT');
|
|
69
|
-
|
|
70
|
-
throw new Error(result.error);
|
|
69
|
+
throwOnReplyError(result, 'shared get failed');
|
|
71
70
|
return result.item ? rehydrateSharedItem(result.item) : null;
|
|
72
71
|
},
|
|
73
72
|
async report(key, reason) {
|
|
74
73
|
const result = await sendTypedRequest(transport, { type: 'SHARED_REPORT', payload: { key, reason } }, 'SHARED_REPORT_RESULT');
|
|
75
|
-
|
|
76
|
-
throw new Error(result.error ?? 'shared report failed');
|
|
77
|
-
}
|
|
74
|
+
throwOnFailedReply(result, 'shared report failed');
|
|
78
75
|
},
|
|
79
76
|
async getCount(key) {
|
|
80
77
|
const result = await sendTypedRequest(transport, { type: 'SHARED_GET_COUNT', payload: { key } }, 'SHARED_GET_COUNT_RESULT');
|
|
81
|
-
|
|
82
|
-
throw new Error(result.error);
|
|
78
|
+
throwOnReplyError(result, 'shared getCount failed');
|
|
83
79
|
return result.count;
|
|
84
80
|
},
|
|
85
81
|
async getCounts(keys) {
|
|
86
82
|
const result = await sendTypedRequest(transport, { type: 'SHARED_GET_COUNTS', payload: { keys } }, 'SHARED_GET_COUNTS_RESULT');
|
|
87
|
-
|
|
88
|
-
throw new Error(result.error);
|
|
83
|
+
throwOnReplyError(result, 'shared getCounts failed');
|
|
89
84
|
return result.counts;
|
|
90
85
|
},
|
|
91
86
|
async append(value) {
|
|
92
87
|
const result = await sendTypedRequest(transport, { type: 'SHARED_APPEND', payload: { value } }, 'SHARED_APPEND_RESULT');
|
|
93
|
-
|
|
94
|
-
throw new Error(result.error);
|
|
88
|
+
throwOnReplyError(result, 'shared append failed');
|
|
95
89
|
return { key: result.key };
|
|
96
90
|
},
|
|
97
91
|
async update(key, value) {
|
|
98
92
|
const result = await sendTypedRequest(transport, { type: 'SHARED_UPDATE', payload: { key, value } }, 'SHARED_UPDATE_RESULT');
|
|
99
|
-
|
|
100
|
-
throw new Error(result.error ?? 'shared update failed');
|
|
101
|
-
}
|
|
93
|
+
throwOnFailedReply(result, 'shared update failed');
|
|
102
94
|
},
|
|
103
95
|
async vote(key) {
|
|
104
96
|
const result = await sendTypedRequest(transport, { type: 'SHARED_VOTE', payload: { key } }, 'SHARED_VOTE_RESULT');
|
|
105
|
-
|
|
106
|
-
throw new Error(result.error);
|
|
97
|
+
throwOnReplyError(result, 'shared vote failed');
|
|
107
98
|
return result.count;
|
|
108
99
|
},
|
|
109
100
|
async unvote(key) {
|
|
110
101
|
const result = await sendTypedRequest(transport, { type: 'SHARED_UNVOTE', payload: { key } }, 'SHARED_UNVOTE_RESULT');
|
|
111
|
-
|
|
112
|
-
throw new Error(result.error);
|
|
102
|
+
throwOnReplyError(result, 'shared unvote failed');
|
|
113
103
|
return result.count;
|
|
114
104
|
},
|
|
115
105
|
async withdraw(key) {
|
|
116
106
|
const result = await sendTypedRequest(transport, { type: 'SHARED_WITHDRAW', payload: { key } }, 'SHARED_WITHDRAW_RESULT');
|
|
117
|
-
|
|
118
|
-
|
|
107
|
+
throwOnFailedReply(result, 'shared withdraw failed');
|
|
108
|
+
// `deleted` is optional on the wire type because an error reply omits
|
|
109
|
+
// it. On the success path the validator requires a boolean, so this is
|
|
110
|
+
// defence in depth rather than a reachable branch through the real
|
|
111
|
+
// transport — but it is what makes the `boolean` we return honest,
|
|
112
|
+
// instead of a cast asserting a guarantee this function cannot see.
|
|
113
|
+
if (typeof result.deleted !== 'boolean') {
|
|
114
|
+
throw new Error('shared withdraw failed: reply carried no `deleted` flag');
|
|
119
115
|
}
|
|
120
116
|
return { ok: true, deleted: result.deleted };
|
|
121
117
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSharedStorage.js","sourceRoot":"","sources":["../../src/hooks/useSharedStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAIhC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AA+G5D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,IAA2B;IACtD,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACnC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACnC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,KAAK;KACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,OAAO,CAAmB,GAAG,EAAE;QACpC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QACjC,OAAO;YACL,KAAK,CAAC,IAAI,CAAC,IAAI;gBACb,MAAM,MAAM,GAAG,MAAM,gBAAgB,CACnC,SAAS,EACT;oBACE,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE;wBACP,MAAM,EAAE,IAAI,EAAE,MAAM;wBACpB,KAAK,EAAE,IAAI,EAAE,KAAK;wBAClB,MAAM,EAAE,IAAI,EAAE,MAAM;qBACrB;iBACF,EACD,oBAAoB,CACrB,CAAC;gBACF,
|
|
1
|
+
{"version":3,"file":"useSharedStorage.js","sourceRoot":"","sources":["../../src/hooks/useSharedStorage.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,8 +19,8 @@ export { useBlockTheme } from './hooks/useBlockTheme.js';
|
|
|
19
19
|
export { useBlockSettings } from './hooks/useBlockSettings.js';
|
|
20
20
|
export { useBlockToken } from './hooks/useBlockToken.js';
|
|
21
21
|
export { useHostOrigin } from './hooks/useHostOrigin.js';
|
|
22
|
-
export { DEFAULT_WATCH_WAIT_SECONDS, useBuzzWorkflow, WorkflowEstimateError, } from './hooks/useBuzzWorkflow.js';
|
|
23
|
-
export type { SubmitWorkflowOptions, WatchWorkflowOptions } from './hooks/useBuzzWorkflow.js';
|
|
22
|
+
export { DEFAULT_WATCH_WAIT_SECONDS, useBuzzWorkflow, WorkflowEstimateError, WorkflowSubmitError, } from './hooks/useBuzzWorkflow.js';
|
|
23
|
+
export type { SubmitWorkflowOptions, WatchWorkflowOptions, WorkflowSubmitErrorCode, } from './hooks/useBuzzWorkflow.js';
|
|
24
24
|
export { useTip } from './hooks/useTip.js';
|
|
25
25
|
export type { TipParams, TipOptions, TipResult, UseTip } from './hooks/useTip.js';
|
|
26
26
|
export { useTipAllowance } from './hooks/useTipAllowance.js';
|