@civitai/blocks-react 0.70.0 → 0.72.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 +408 -2
- package/dist/hooks/useBatchEstimate.d.ts +4 -0
- package/dist/hooks/useBatchEstimate.js +4 -0
- package/dist/hooks/useBuzzWorkflow.d.ts +48 -0
- package/dist/hooks/useBuzzWorkflow.js +43 -0
- package/dist/hooks/useCheckpointPicker.d.ts +2 -0
- package/dist/hooks/useCheckpointPicker.js +2 -0
- package/dist/hooks/useRunConfirmedStep.d.ts +209 -0
- package/dist/hooks/useRunConfirmedStep.js +287 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/internal/hostSurface.d.ts +37 -0
- package/dist/internal/hostSurface.js +38 -0
- package/dist/internal/liveHost.d.ts +15 -6
- package/dist/internal/liveHost.js +151 -69
- package/dist/internal/mockHost.d.ts +178 -7
- package/dist/internal/mockHost.js +549 -12
- package/dist/internal/mockWorkflowGraph.d.ts +117 -0
- package/dist/internal/mockWorkflowGraph.js +447 -0
- package/dist/testing.d.ts +1 -1
- package/dist/transport/requestTimeouts.js +6 -0
- package/dist/transport/validate.d.ts +13 -0
- package/dist/transport/validate.js +111 -0
- package/package.json +4 -4
|
@@ -334,6 +334,87 @@ export function isValidWorkflowSnapshot(s) {
|
|
|
334
334
|
return false;
|
|
335
335
|
if (s.trainingQuote !== undefined && !isValidTrainingQuote(s.trainingQuote))
|
|
336
336
|
return false;
|
|
337
|
+
if (s.stepQuote !== undefined && !isValidStepQuote(s.stepQuote))
|
|
338
|
+
return false;
|
|
339
|
+
if (s.model3dOutputs !== undefined && !isValidModel3dOutputs(s.model3dOutputs))
|
|
340
|
+
return false;
|
|
341
|
+
if (s.steps !== undefined && !isValidWorkflowSteps(s.steps))
|
|
342
|
+
return false;
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Shape check for `stepQuote` — the viewer-confirmable quote a pass-through
|
|
347
|
+
* `step` estimate returns when its fixed price is above the per-call budget. The
|
|
348
|
+
* block passes `quoteId` back verbatim, renders `total` on its confirm button
|
|
349
|
+
* and may show `stepType`, so all three are pinned to their types.
|
|
350
|
+
*
|
|
351
|
+
* `quoteId`'s `sq_…` FORMAT is deliberately not pinned HERE, for the reason
|
|
352
|
+
* given on {@link isValidTrainingQuote}: a host changing the handle's format
|
|
353
|
+
* must not turn every such estimate reply into a dropped one. The format is
|
|
354
|
+
* checked where it is an instruction rather than an observation — on the way
|
|
355
|
+
* OUT, in `useRunConfirmedStep()`.
|
|
356
|
+
*/
|
|
357
|
+
function isValidStepQuote(q) {
|
|
358
|
+
if (!isObject(q))
|
|
359
|
+
return false;
|
|
360
|
+
if (!isNonEmptyString(q.quoteId))
|
|
361
|
+
return false;
|
|
362
|
+
if (!isFiniteNumber(q.total))
|
|
363
|
+
return false;
|
|
364
|
+
if (typeof q.stepType !== 'string')
|
|
365
|
+
return false;
|
|
366
|
+
return typeof q.expiresAt === 'string';
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Shape check for `model3dOutputs` — shared by {@link isValidWorkflowSnapshot}
|
|
370
|
+
* and the `AppWorkflow` row guard, which carry the same field. A block matches
|
|
371
|
+
* an entry's `url` against its image list and loads it, and branches on
|
|
372
|
+
* `format` / `variant`, so each is pinned to a string. `format` and `variant`
|
|
373
|
+
* are OPEN sets (the orchestrator's own format names and output field paths)
|
|
374
|
+
* and are never checked against a list; `variant` may be the empty string.
|
|
375
|
+
*/
|
|
376
|
+
function isValidModel3dOutputs(outputs) {
|
|
377
|
+
if (!Array.isArray(outputs))
|
|
378
|
+
return false;
|
|
379
|
+
for (const o of outputs) {
|
|
380
|
+
if (!isObject(o) || !isNonEmptyString(o.url))
|
|
381
|
+
return false;
|
|
382
|
+
if (typeof o.format !== 'string' || typeof o.variant !== 'string')
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Shape check for `steps` — the per-step view of a `kind: 'workflow'` run.
|
|
389
|
+
* OPTIONAL like its neighbours, and a PRESENT but malformed value rejects the
|
|
390
|
+
* snapshot: the block reads `name`, `$type`, `status` and `imageUrls` off every
|
|
391
|
+
* entry.
|
|
392
|
+
*
|
|
393
|
+
* `status` is checked against the SAME closed set as the snapshot's own
|
|
394
|
+
* `status`, unlike the open string unions above: it is typed as that closed
|
|
395
|
+
* union and a block `switch`es on it, so a snapshot carrying any other value is
|
|
396
|
+
* dropped rather than handed over. `output` is `unknown` by contract and is not
|
|
397
|
+
* inspected.
|
|
398
|
+
*/
|
|
399
|
+
function isValidWorkflowSteps(steps) {
|
|
400
|
+
if (!Array.isArray(steps))
|
|
401
|
+
return false;
|
|
402
|
+
for (const step of steps) {
|
|
403
|
+
if (!isObject(step))
|
|
404
|
+
return false;
|
|
405
|
+
if (typeof step.name !== 'string' || typeof step.$type !== 'string')
|
|
406
|
+
return false;
|
|
407
|
+
if (typeof step.status !== 'string' || !WORKFLOW_STATUSES.has(step.status))
|
|
408
|
+
return false;
|
|
409
|
+
if (step.imageUrls !== undefined) {
|
|
410
|
+
if (!Array.isArray(step.imageUrls))
|
|
411
|
+
return false;
|
|
412
|
+
if (!step.imageUrls.every((u) => typeof u === 'string'))
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
if (step.error !== undefined && typeof step.error !== 'string')
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
337
418
|
return true;
|
|
338
419
|
}
|
|
339
420
|
/**
|
|
@@ -998,6 +1079,8 @@ function isValidAppWorkflow(w) {
|
|
|
998
1079
|
return false;
|
|
999
1080
|
if (w.trainedEpochs !== undefined && !isValidTrainedEpochs(w.trainedEpochs))
|
|
1000
1081
|
return false;
|
|
1082
|
+
if (w.model3dOutputs !== undefined && !isValidModel3dOutputs(w.model3dOutputs))
|
|
1083
|
+
return false;
|
|
1001
1084
|
return true;
|
|
1002
1085
|
}
|
|
1003
1086
|
/**
|
|
@@ -1400,6 +1483,31 @@ export function isValidTrainingResult(p) {
|
|
|
1400
1483
|
return false;
|
|
1401
1484
|
return true;
|
|
1402
1485
|
}
|
|
1486
|
+
/**
|
|
1487
|
+
* Reply to `RUN_CONFIRMED_STEP`. A well-formed reply carries EITHER a `snapshot`
|
|
1488
|
+
* (a valid {@link isValidWorkflowSnapshot} — the block polls its `workflowId`)
|
|
1489
|
+
* OR an `error`; one with neither is malformed and dropped.
|
|
1490
|
+
*
|
|
1491
|
+
* 🔴 `error` IS SHAPE-CHECKED ONLY, for the reason given on
|
|
1492
|
+
* {@link isValidTrainingResult}: this request carries the same TEN-MINUTE
|
|
1493
|
+
* consent bound, and the host forwards server refusals (an expired or used
|
|
1494
|
+
* quote, a changed body or price, the feature flag) in the same field as its own
|
|
1495
|
+
* codes. A membership check would drop those and leave a Run button spinning for
|
|
1496
|
+
* ten minutes.
|
|
1497
|
+
*/
|
|
1498
|
+
export function isValidConfirmedStepResult(p) {
|
|
1499
|
+
if (!isObject(p))
|
|
1500
|
+
return false;
|
|
1501
|
+
if (!isWireRequestIdShape(p.requestId))
|
|
1502
|
+
return false;
|
|
1503
|
+
if (p.error !== undefined && typeof p.error !== 'string')
|
|
1504
|
+
return false;
|
|
1505
|
+
if (p.snapshot !== undefined && !isValidWorkflowSnapshot(p.snapshot))
|
|
1506
|
+
return false;
|
|
1507
|
+
if (p.snapshot === undefined && p.error === undefined)
|
|
1508
|
+
return false;
|
|
1509
|
+
return true;
|
|
1510
|
+
}
|
|
1403
1511
|
// ============================================================
|
|
1404
1512
|
// App-storage (per-viewer KV) reply validators
|
|
1405
1513
|
// ============================================================
|
|
@@ -2009,6 +2117,9 @@ export function payloadValidatorFor(type) {
|
|
|
2009
2117
|
return isValidTrainingDatasetResult;
|
|
2010
2118
|
case 'TRAINING_RESULT':
|
|
2011
2119
|
return isValidTrainingResult;
|
|
2120
|
+
// Settles a charged job, like TRAINING_RESULT directly above.
|
|
2121
|
+
case 'CONFIRMED_STEP_RESULT':
|
|
2122
|
+
return isValidConfirmedStepResult;
|
|
2012
2123
|
case 'IMAGE_UPLOAD_RESULT':
|
|
2013
2124
|
return isValidImageUploadResult;
|
|
2014
2125
|
case 'IMAGE_SCAN_RESOLVED':
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@civitai/blocks-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.72.0",
|
|
4
4
|
"description": "React hooks and iframe transport for Civitai Apps. Pairs with @civitai/app-sdk/blocks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"node": ">=20"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@civitai/
|
|
41
|
-
"@civitai/
|
|
40
|
+
"@civitai/components": "^0.9.3",
|
|
41
|
+
"@civitai/theme": "^0.5.2"
|
|
42
42
|
},
|
|
43
43
|
"comment-peerDependencies": "This floor is DERIVED, not chosen — the lowest published app-sdk that exports every symbol this package imports. Do not edit it without reading ./PEER_FLOOR.md (in-repo, unpublished) and tests/guards/blocks-react-peer-floor.test.mjs.",
|
|
44
44
|
"peerDependencies": {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"typescript": "^5.9.2",
|
|
59
59
|
"vite": "^8.0.14",
|
|
60
60
|
"vitest": "^4.1.11",
|
|
61
|
-
"@civitai/app-sdk": "^0.
|
|
61
|
+
"@civitai/app-sdk": "^0.67.0"
|
|
62
62
|
},
|
|
63
63
|
"publishConfig": {
|
|
64
64
|
"access": "public"
|