@civitai/blocks-react 0.71.0 → 0.72.2

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 (71) hide show
  1. package/README.md +308 -15
  2. package/dist/hooks/useAppStorage.js +2 -0
  3. package/dist/hooks/useAppWorkflows.js +2 -0
  4. package/dist/hooks/useBatchEstimate.d.ts +4 -0
  5. package/dist/hooks/useBatchEstimate.js +6 -0
  6. package/dist/hooks/useBlockAnalytics.js +2 -0
  7. package/dist/hooks/useBlockBreakpoint.js +2 -0
  8. package/dist/hooks/useBlockContext.js +2 -0
  9. package/dist/hooks/useBlockResize.js +2 -0
  10. package/dist/hooks/useBlockSettings.js +2 -0
  11. package/dist/hooks/useBlockTheme.js +2 -0
  12. package/dist/hooks/useBlockToken.js +2 -0
  13. package/dist/hooks/useBuzzAccounts.js +2 -0
  14. package/dist/hooks/useBuzzBalance.js +2 -0
  15. package/dist/hooks/useBuzzPurchase.js +2 -0
  16. package/dist/hooks/useBuzzTransactions.js +2 -0
  17. package/dist/hooks/useBuzzWorkflow.d.ts +35 -3
  18. package/dist/hooks/useBuzzWorkflow.js +32 -3
  19. package/dist/hooks/useCheckpointPicker.d.ts +2 -0
  20. package/dist/hooks/useCheckpointPicker.js +4 -0
  21. package/dist/hooks/useCivitaiNavigate.js +2 -0
  22. package/dist/hooks/useCivitaiRoute.js +2 -0
  23. package/dist/hooks/useCollectionFollow.js +2 -0
  24. package/dist/hooks/useConsentUnavailable.js +2 -0
  25. package/dist/hooks/useCreatePostFromApp.js +2 -0
  26. package/dist/hooks/useDailyCompensation.js +2 -0
  27. package/dist/hooks/useDirectLoad.js +2 -0
  28. package/dist/hooks/useDomainMaturity.js +2 -0
  29. package/dist/hooks/useEntitlements.js +2 -0
  30. package/dist/hooks/useGatedImages.js +2 -0
  31. package/dist/hooks/useGenerationResources.js +2 -0
  32. package/dist/hooks/useGoodPurchase.js +2 -0
  33. package/dist/hooks/useHostOrigin.js +2 -0
  34. package/dist/hooks/useImageUpload.js +2 -0
  35. package/dist/hooks/useNestedDocument.js +2 -0
  36. package/dist/hooks/usePrepareTrainingDataset.js +2 -0
  37. package/dist/hooks/usePublishGenerationOutputs.js +2 -0
  38. package/dist/hooks/useRequestConsent.js +2 -0
  39. package/dist/hooks/useRequestSignIn.js +2 -0
  40. package/dist/hooks/useResourcePicker.js +2 -0
  41. package/dist/hooks/useRunConfirmedStep.d.ts +209 -0
  42. package/dist/hooks/useRunConfirmedStep.js +289 -0
  43. package/dist/hooks/useRunTraining.js +2 -0
  44. package/dist/hooks/useSaveImage.js +2 -0
  45. package/dist/hooks/useSharedStorage.js +2 -0
  46. package/dist/hooks/useTip.js +2 -0
  47. package/dist/hooks/useTipAllowance.js +2 -0
  48. package/dist/hooks/useTransportConnection.d.ts +43 -0
  49. package/dist/hooks/useTransportConnection.js +59 -0
  50. package/dist/hooks/useUploadImageBytes.js +2 -0
  51. package/dist/hooks/useViewer.js +2 -0
  52. package/dist/hooks/useWildcardPack.js +2 -0
  53. package/dist/hooks/useWorkflowBatch.js +2 -0
  54. package/dist/index.d.ts +2 -0
  55. package/dist/index.js +1 -0
  56. package/dist/internal/hostSurface.d.ts +37 -0
  57. package/dist/internal/hostSurface.js +38 -0
  58. package/dist/internal/liveHost.d.ts +15 -6
  59. package/dist/internal/liveHost.js +151 -69
  60. package/dist/internal/mockHost.d.ts +123 -10
  61. package/dist/internal/mockHost.js +377 -14
  62. package/dist/internal/mockWorkflowGraph.d.ts +23 -10
  63. package/dist/internal/mockWorkflowGraph.js +34 -11
  64. package/dist/testing.d.ts +1 -1
  65. package/dist/transport/iframeTransport.js +13 -0
  66. package/dist/transport/requestTimeouts.js +6 -0
  67. package/dist/transport/singleton.d.ts +6 -0
  68. package/dist/transport/singleton.js +20 -0
  69. package/dist/transport/validate.d.ts +13 -0
  70. package/dist/transport/validate.js +76 -0
  71. package/package.json +4 -4
@@ -37,7 +37,8 @@
37
37
  * called). Only the postMessage bridge round-trips are exercised. Never import
38
38
  * this from production code.
39
39
  */
40
- import { type BlockContext, type BlockResourceInfo, type BlockResourcePickerType, type BlockUploadedImageInfo, type BlockGenerationSourceImageInfo, type BuzzAccountType, type BlockBuzzTransaction, type BlockBuzzAccount, type BlockDailyCompensationResource, type BlockViewer, type BlockWildcardPack, type BlockWildcardPackErrorCode, type AppWorkflow, type BlockPublishedModel, type BlockGatedImage, type BlockCollectionFollowErrorCode, type BlockCreatePostHostError, type BlockCreatePostResult, type BlockPrepareTrainingDatasetHostError, type BlockRunTrainingHostError, type BlockTrainingRejectionReason, type ColorDomain, type SharedStorageValue, type Theme, type ViewerInfo, type WorkflowBody } from '@civitai/app-sdk/blocks';
40
+ import { type BlockContext, type BlockResourceInfo, type BlockResourcePickerType, type BlockUploadedImageInfo, type BlockGenerationSourceImageInfo, type BuzzAccountType, type BlockBuzzTransaction, type BlockBuzzAccount, type BlockDailyCompensationResource, type BlockViewer, type BlockWildcardPack, type BlockWildcardPackErrorCode, type AppWorkflow, type BlockModel3dOutput, type BlockPublishedModel, type BlockRunConfirmedStepHostError, type BlockGatedImage, type BlockCollectionFollowErrorCode, type BlockCreatePostHostError, type BlockCreatePostResult, type BlockPrepareTrainingDatasetHostError, type BlockRunTrainingHostError, type BlockTrainingRejectionReason, type ColorDomain, type SharedStorageValue, type Theme, type ViewerInfo, type WorkflowBody } from '@civitai/app-sdk/blocks';
41
+ import { type MockWorkflowQuoteFailure } from './mockWorkflowGraph.js';
41
42
  /**
42
43
  * How submits behave. `'none'` = everything succeeds; `'all'` / `'insufficient'`
43
44
  * = every submit fails as if the viewer were OUT OF BUZZ, until an
@@ -84,6 +85,7 @@ export type CostSpec = number | ((req: WorkflowBody, step?: MockWorkflowStepInfo
84
85
  * {@link MockGenerationScenario.costPerGen} once per step and sums the results.
85
86
  * `undefined` for every other kind, which is priced with one call.
86
87
  */
88
+ export type { MockWorkflowQuoteFailure };
87
89
  export interface MockWorkflowStepInfo {
88
90
  /** Zero-based position in the body's `steps`. */
89
91
  index: number;
@@ -307,17 +309,27 @@ export interface MockGenerationScenario {
307
309
  */
308
310
  failWorkflowStep?: string;
309
311
  /**
310
- * Simulate the host getting NO price quote for a `kind: 'workflow'` body. The
311
- * host then refuses, before any reservation, a workflow with a training step
312
- * (`errorCode: 'training-quote-unavailable'`) or a `repeat` step at any depth
313
- * (`'workflow_repeat_unbounded'`); any other workflow proceeds reserved at the
314
- * CEILING — {@link MockHostOptions.buzzBudget} × the number of steps — which
315
- * the estimate reports as `cost.total`, with `authorFee: 0` (no quote, no
316
- * fee base). Ignored by every other kind. Live-tunable via
312
+ * Simulate the host getting NO price quote for a `kind: 'workflow'` body, and
313
+ * say why: `'rejected'` (the orchestrator refused the body), `'unavailable'`
314
+ * (no usable answer — the one cause a retry can clear) or `'unpriced'` (an
315
+ * answer without a price). `true` means `'unavailable'`.
316
+ *
317
+ * - A workflow with a training step (`errorCode: 'training-quote-<cause>'`)
318
+ * or a `repeat` step at any depth (`'workflow_repeat_unbounded'`) is
319
+ * refused on BOTH `estimate()` and `submit()`, before any reservation.
320
+ * - Any other workflow: `estimate()` FAILS with `'workflow_quote_<cause>'`
321
+ * and no `cost`, while `submit()` still PROCEEDS, reserved at the CEILING —
322
+ * {@link MockHostOptions.buzzBudget} × the number of steps — with no author
323
+ * fee (no quote, no fee base). A failed estimate does not predict a refused
324
+ * submit.
325
+ *
326
+ * `error` is the host's sentence for the cause. The mock has no orchestrator
327
+ * reason to pass on, so `'rejected'` always reads the host's reason-less form.
328
+ * Ignored by every other kind. Live-tunable via
317
329
  * `setScenario({ generation: { workflowUnpriced } })`. Default: unset (every
318
330
  * workflow is quoted at its per-step `costPerGen`).
319
331
  */
320
- workflowUnpriced?: boolean;
332
+ workflowUnpriced?: boolean | MockWorkflowQuoteFailure;
321
333
  /**
322
334
  * A single result image url (or `(body) => url`). For a `kind: 'workflow'`
323
335
  * run this (and {@link images}) is the LAST step that did not set
@@ -371,6 +383,22 @@ export interface MockGenerationScenario {
371
383
  * `appWorkflows`.
372
384
  */
373
385
  trainingPublishedModel?: BlockPublishedModel;
386
+ /**
387
+ * The 3D models a succeeded PASS-THROUGH step reports on
388
+ * {@link BlockWorkflowSnapshot.model3dOutputs} — what a `polyGen` job returns.
389
+ * As on the real host, every labelled `url` is ALSO in the snapshot's
390
+ * `imageUrls`: when set, the mock answers with exactly these urls there, in
391
+ * this order, unless {@link images} / {@link image} say otherwise (then the
392
+ * labels are sent as given and it is on you to keep the two consistent).
393
+ *
394
+ * Applies only to a pass-through `{ kind: 'step', $type }` body — the only arm
395
+ * the host labels. Default: unset, and the field is OMITTED, as the host omits
396
+ * it for a workflow that produced no 3D model.
397
+ *
398
+ * Snapshot-only, like {@link trainedEpochs}: for the app-queue read put
399
+ * `model3dOutputs` on the rows you pass as {@link MockHostOptions.appWorkflows}.
400
+ */
401
+ model3dOutputs?: BlockModel3dOutput[];
374
402
  }
375
403
  /**
376
404
  * The training bounds the mock enforces — COPIES of `@civitai/app-sdk/blocks`'s
@@ -405,6 +433,41 @@ export declare const MOCK_TRAINING_DATASET_GONE_ERROR = "training dataset not fo
405
433
  */
406
434
  export declare const MOCK_TRAINING_NONE_ELIGIBLE_ERROR = "none of the requested images can be used for training";
407
435
  export declare const MOCK_TRAINING_NONE_IMPORTED_ERROR = "none of the requested images could be prepared for training";
436
+ /**
437
+ * The per-job ceiling of a confirmed step — a COPY of `@civitai/app-sdk/blocks`'s
438
+ * `BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB`, not value-imported for the reason
439
+ * given on {@link MOCK_TRAINING_BOUNDS}. Pinned to the SDK's value by
440
+ * `test/confirmedStepFlow.test.tsx`, which imports both.
441
+ */
442
+ export declare const MOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB = 5000;
443
+ /**
444
+ * The real server's refusal when the host reads back a step quote it does not
445
+ * hold — unknown, expired, or already used by an earlier run. This is the
446
+ * PREVIEW's message, which is the one `RUN_CONFIRMED_STEP` reaches first.
447
+ */
448
+ export declare const MOCK_STEP_QUOTE_GONE_ERROR = "step quote not found or expired";
449
+ /** The real server's refusal for a confirmed run whose body is not the quoted one. */
450
+ export declare const MOCK_STEP_BODY_MISMATCH_ERROR = "the step body differs from the one that was quoted \u2014 estimate again";
451
+ /**
452
+ * The real server's refusal for a `quoteId` body sent as a plain
453
+ * `SUBMIT_WORKFLOW`: nothing but `RUN_CONFIRMED_STEP`'s dialog records the
454
+ * viewer's confirmation.
455
+ */
456
+ export declare const MOCK_STEP_NOT_CONFIRMED_ERROR = "this step has not been confirmed by the viewer in this session";
457
+ /**
458
+ * The real server's refusal for a TRAINING `$type` (`training`,
459
+ * `imageResourceTraining`) on the confirmed-step path — at the estimate, where a
460
+ * quote would otherwise be granted, and at the confirmed submit. Training runs
461
+ * have their own kind.
462
+ */
463
+ export declare const MOCK_STEP_TRAINING_TYPE_ERROR = "a training step type cannot run as a confirmed step \u2014 use kind:'training'";
464
+ /**
465
+ * The fixed PREFIX of the real server's refusal for a confirmed-step body whose
466
+ * `input` is not plain JSON. The full message continues with the offending path
467
+ * and what was found there (`body.input.when is a Date`), which varies — match on
468
+ * this prefix.
469
+ */
470
+ export declare const MOCK_STEP_NON_JSON_INPUT_ERROR_PREFIX = "a confirmed step needs plain JSON input (objects, arrays, strings, finite numbers, booleans, null) \u2014 ";
408
471
  /**
409
472
  * BUZZ scenario controls — simulate a viewer who runs out of Buzz. The mock host
410
473
  * treats `balance` as a spendable wallet: each succeeding generation DEBITS its
@@ -968,6 +1031,51 @@ export interface MockHostOptions {
968
1031
  * `setScenario({ runTrainingCapRefusal: undefined })` clears it.
969
1032
  */
970
1033
  runTrainingCapRefusal?: string;
1034
+ /**
1035
+ * Force `RUN_CONFIRMED_STEP` to reply with an `error` instead of starting the
1036
+ * job — a {@link BlockRunConfirmedStepHostError} or any other string for a
1037
+ * server message. Absent → the viewer "confirms" and the job starts.
1038
+ *
1039
+ * - `'declined'` — the viewer dismissed the confirm. No job.
1040
+ * - `'daily-limit-exceeded'` — the job would exceed the viewer's own daily
1041
+ * Buzz limit for the app. No job; the real host explains it in its chrome.
1042
+ * - `'submission-unconfirmed'` — the job MAY exist.
1043
+ *
1044
+ * A CONFIRMED STEP IS QUOTED BY THE ESTIMATE, with no knob of its own: a
1045
+ * pass-through `{ kind: 'step', $type }` estimate carries
1046
+ * {@link BlockWorkflowSnapshot.stepQuote} whenever the mock's price for it
1047
+ * ({@link MockGenerationScenario.costPerGen}, or `cost`) is above the token's
1048
+ * per-call budget ({@link MockHostOptions.buzzBudget}, default 200) and at most
1049
+ * 5,000, for a signed-in viewer. So `generation: { costPerGen: 800 }` is all it
1050
+ * takes to reach this path. ONLY a single `ESTIMATE_WORKFLOW` quotes one: a
1051
+ * batch-estimate cell never carries `stepQuote`, as on the server. And where a
1052
+ * quote would be granted, two bodies make the estimate FAIL instead, with the
1053
+ * server's message: a training `$type` (`training`, `imageResourceTraining`,
1054
+ * in any casing), and an `input` that is not plain JSON (a `Date`, `Map`,
1055
+ * `Set`, `BigInt`, `NaN`, an empty slot in a sparse array, …).
1056
+ *
1057
+ * Whether the QUOTE survives follows the real flow: the host's own gate,
1058
+ * dialog and daily-limit codes settle before the server claims the quote, so
1059
+ * it stays runnable; `submission-unconfirmed` and any server message settle
1060
+ * after the claim, so it is used up — running it again gets the quote-gone
1061
+ * error. Live-tunable via {@link MockHost.setScenario}; `undefined` clears it.
1062
+ * URL: `?confirmedStep=declined|daily-limit|unconfirmed`.
1063
+ *
1064
+ * 🔴 Same real gap as {@link runTrainingError}: the confirm is HOST chrome, so
1065
+ * the mock settles immediately where the real host waits on a click. The mock
1066
+ * also prices every estimate as FIXED — the real host gives a variable or
1067
+ * metered price no `stepQuote` at all.
1068
+ */
1069
+ runConfirmedStepError?: BlockRunConfirmedStepHostError | string;
1070
+ /**
1071
+ * Make `RUN_CONFIRMED_STEP` resolve the server's spend-cap refusal instead of
1072
+ * a job: a snapshot `{ workflowId: 'failed', status: 'failed', cost: { total:
1073
+ * <quote> }, error: <this string> }` (refunded, no job).
1074
+ * `useRunConfirmedStep()` rejects it with `.refused`. 🔴 The quote is CONSUMED,
1075
+ * as on the server. Absent → the job starts. Live-tunable via
1076
+ * {@link MockHost.setScenario}; `undefined` clears it.
1077
+ */
1078
+ runConfirmedStepCapRefusal?: string;
971
1079
  /**
972
1080
  * Force `SAVE_IMAGE` to reply with this `error` instead of saving — any of
973
1081
  * the host's free-text refusals (`'image url is not allowed'`,
@@ -1156,6 +1264,9 @@ export interface MockHostOptions {
1156
1264
  * shape carries the field, so a context you pass WITHOUT a `theme` key still
1157
1265
  * gets the harness theme (and still follows a later `setTheme`). Only a slot
1158
1266
  * this SDK has no shape for is left alone — there is no `theme` field to set.
1267
+ *
1268
+ * The slot also decides `SET_USER_CHECKPOINT`, as in production: refused on
1269
+ * `app.page` (the default), persisted on a model slot.
1159
1270
  */
1160
1271
  context?: BlockContext;
1161
1272
  /**
@@ -1230,7 +1341,7 @@ export interface MockHostOptions {
1230
1341
  * {@link MockHost.setTheme}, which pushes a real `THEME_CHANGE` — the mock of
1231
1342
  * the viewer toggling dark mode with the block already mounted.)
1232
1343
  */
1233
- export type MockHostScenarioPatch = Pick<MockHostOptions, 'consentGrantable' | 'failMode' | 'cost' | 'pollsUntilDone' | 'cannedPicks' | 'cannedMultiPicks' | 'cannedImageUpload' | 'cannedGenerationSourceUpload' | 'cannedImageScan' | 'generation' | 'buzz' | 'storage' | 'shared' | 'buzzBalanceError' | 'viewerResult' | 'viewerError' | 'buzzTransactions' | 'buzzAccounts' | 'dailyCompensation' | 'buzzReadError' | 'wildcardPack' | 'wildcardPackError' | 'collectionFollowError' | 'createPostResult' | 'createPostError' | 'trainingDatasetRejected' | 'trainingDatasetError' | 'trainingQuoteTotal' | 'runTrainingError' | 'runTrainingCapRefusal' | 'appWorkflows' | 'appWorkflowsError' | 'publishImageIds' | 'publishError' | 'gatedImages' | 'gatedImagesError' | 'disallowedAccountTypes' | 'saveImageError' | 'uploadImageBytesResult' | 'uploadImageBytesError'>;
1344
+ export type MockHostScenarioPatch = Pick<MockHostOptions, 'consentGrantable' | 'failMode' | 'cost' | 'pollsUntilDone' | 'cannedPicks' | 'cannedMultiPicks' | 'cannedImageUpload' | 'cannedGenerationSourceUpload' | 'cannedImageScan' | 'generation' | 'buzz' | 'storage' | 'shared' | 'buzzBalanceError' | 'viewerResult' | 'viewerError' | 'buzzTransactions' | 'buzzAccounts' | 'dailyCompensation' | 'buzzReadError' | 'wildcardPack' | 'wildcardPackError' | 'collectionFollowError' | 'createPostResult' | 'createPostError' | 'trainingDatasetRejected' | 'trainingDatasetError' | 'trainingQuoteTotal' | 'runTrainingError' | 'runTrainingCapRefusal' | 'runConfirmedStepError' | 'runConfirmedStepCapRefusal' | 'appWorkflows' | 'appWorkflowsError' | 'publishImageIds' | 'publishError' | 'gatedImages' | 'gatedImagesError' | 'disallowedAccountTypes' | 'saveImageError' | 'uploadImageBytesResult' | 'uploadImageBytesError'>;
1234
1345
  /** Runtime Buzz-balance handle exposed on {@link MockHost.buzz}. */
1235
1346
  export interface MockBuzzHandle {
1236
1347
  /** Current simulated balance, or `undefined` when balance isn't simulated. */
@@ -1279,6 +1390,8 @@ export declare function disallowedAccountError(accountType: BuzzAccountType): st
1279
1390
  * map onto the new scenario groups so a dev can flip out-of-Buzz /
1280
1391
  * failures / latency without editing code. `?capRefusal=1` (or `=<text>`) sets
1281
1392
  * {@link MockGenerationScenario.submitCapRefusal}.
1393
+ * `?confirmedStep=declined|daily-limit|unconfirmed` sets
1394
+ * {@link MockHostOptions.runConfirmedStepError}.
1282
1395
  *
1283
1396
  * Returns a partial overlay applied ON TOP of explicit {@link MockHostOptions}
1284
1397
  * (URL wins — it's the interactive dev knob). No-op outside a browser.