@civitai/blocks-react 0.28.0 → 0.30.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 CHANGED
@@ -293,6 +293,36 @@ if (error instanceof WildcardPackError && error.code === 'busy') void refetch();
293
293
  if (!loading && pack) console.log(Object.keys(pack.lists));
294
294
  ```
295
295
 
296
+ ### `useAppWorkflows(params?)`
297
+
298
+ The calling app's **own** generator subqueue — the tag-scoped list of generations
299
+ **this app** produced for the viewer (newest-first), plus a fail-closed `cancel`.
300
+ The host self-binds the account off the block token and **forces** the per-app tag
301
+ filter, so a block only ever sees the queue it produced — never the viewer's
302
+ personal queue or another app's. Returns `{ workflows, cursor, loading, error,
303
+ refetch, cancel }`; each `AppWorkflow` is `{ workflowId, status, images[], cost,
304
+ createdAt }`. Pass the returned `cursor` back as `params.cursor` to page forward.
305
+ Requires `ai:write:budgeted` (same trust boundary as submit); host-mediated over
306
+ `QUERY_APP_WORKFLOWS` / `CANCEL_APP_WORKFLOW`.
307
+
308
+ `cancel(workflowId)` sends `CANCEL_APP_WORKFLOW`, resolves once the host confirms
309
+ the terminal state (which is optimistically spliced into `workflows` in place — no
310
+ refetch round-trip), and rejects with the host's error on failure.
311
+
312
+ ```tsx
313
+ const { workflows, cursor, loading, error, refetch, cancel } = useAppWorkflows({ limit: 20 });
314
+ if (!loading && !error) {
315
+ workflows.forEach((w) => console.log(w.workflowId, w.status, w.images.length, w.cost));
316
+ }
317
+ async function onCancel(id: string) {
318
+ try {
319
+ await cancel(id); // optimistically flips the row to `canceled`
320
+ } catch (err) {
321
+ console.error('cancel failed', err);
322
+ }
323
+ }
324
+ ```
325
+
296
326
  ### `useAppStorage()`
297
327
 
298
328
  Per-(block instance, viewer) KV datastore, host-mediated. 64 KB per value,
@@ -583,7 +613,8 @@ Runnable, minimal blocks — one per feature, each with its own README:
583
613
 
584
614
  | `@civitai/blocks-react` | pairs with `@civitai/app-sdk` | adds |
585
615
  |---|---|---|
586
- | `0.27.x` | `^0.23.0` | async-scan image upload; transport validators for all `SHARED_*` / `APP_STORAGE_*` / picker replies |
616
+ | `0.29.x` | `^0.24.0` | `useAppWorkflows()` — app generator subqueue read + cancel (`QUERY_APP_WORKFLOWS` / `CANCEL_APP_WORKFLOW`) |
617
+ | `0.27.x`–`0.28.x` | `^0.23.0` | async-scan image upload; transport validators for all `SHARED_*` / `APP_STORAGE_*` / picker replies |
587
618
  | `0.26.x` | `^0.22.0` | `useViewer()` (`GET_VIEWER`) |
588
619
  | `0.25.x` | `^0.21.0` | `useBuzzTransactions`, `useBuzzAccounts`, `useDailyCompensation`, `useWildcardPack` |
589
620
  | `0.5.0` | `^0.7.0` | `useBuzzWorkflow().cancel()` (real server-side cancel, gotcha #51) |
@@ -0,0 +1,54 @@
1
+ import type { AppWorkflow, AppWorkflowsParams } from '@civitai/app-sdk/blocks';
2
+ export type { AppWorkflow, AppWorkflowsParams };
3
+ /**
4
+ * What {@link useAppWorkflows} returns.
5
+ */
6
+ export interface UseAppWorkflows {
7
+ /** The current page's workflows (newest-first). `[]` until the first successful fetch. */
8
+ workflows: AppWorkflow[];
9
+ /**
10
+ * The next-page cursor, or `null` when there's no further page. Pass it back as
11
+ * `params.cursor` on a subsequent call to page forward.
12
+ */
13
+ cursor: string | null;
14
+ /** `true` while a fetch (initial or `refetch`) is in flight. */
15
+ loading: boolean;
16
+ /**
17
+ * The last fetch's failure — a host-reported error (anon viewer / missing
18
+ * `ai:write:budgeted` scope / rate-limit / host failure) or the transport
19
+ * timeout. Free-text. Cleared at the start of the next fetch. A failed
20
+ * {@link cancel} does NOT set this (it rejects its own promise instead).
21
+ */
22
+ error: Error | null;
23
+ /** Re-request the current page. */
24
+ refetch: () => void;
25
+ /**
26
+ * Cancel ONE workflow in this app's subqueue (host `CANCEL_APP_WORKFLOW`). The
27
+ * host is FAIL-CLOSED — it verifies the viewer/app own the workflow before the
28
+ * orchestrator cancel — so a block can only cancel a gen it submitted. Resolves
29
+ * once the host confirms the terminal state, which is OPTIMISTICALLY spliced
30
+ * into `workflows` in place (no refetch round-trip); rejects with the host's
31
+ * free-text error on failure (FORBIDDEN / transport). Unmount-safe.
32
+ */
33
+ cancel: (workflowId: string) => Promise<void>;
34
+ }
35
+ /**
36
+ * Read (and cancel within) the calling app's OWN generator SUBQUEUE — the
37
+ * tag-scoped list of generations THIS app produced for the viewer, newest-first —
38
+ * through the host-mediated `QUERY_APP_WORKFLOWS` → `APP_WORKFLOWS_RESULT` and
39
+ * `CANCEL_APP_WORKFLOW` → `CANCEL_APP_WORKFLOW_RESULT` bridges. Token-bound: the
40
+ * host self-binds the account off the block token and FORCES the per-app tag
41
+ * filter (scope `ai:write:budgeted`, same trust boundary as submit) — the block
42
+ * can never widen the filter or reach another user's / their personal queue.
43
+ *
44
+ * Fetches on mount and whenever `params` change (by value), and exposes `refetch`.
45
+ * A host that never answers surfaces as an `error` after the transport's request
46
+ * timeout — the hook never hangs. Late responses that arrive after unmount are
47
+ * ignored.
48
+ *
49
+ * @example
50
+ * const { workflows, cursor, loading, error, cancel } = useAppWorkflows({ limit: 20 });
51
+ * // …render each workflow's images; await cancel(w.workflowId) on a Cancel click.
52
+ */
53
+ export declare function useAppWorkflows(params?: AppWorkflowsParams): UseAppWorkflows;
54
+ //# sourceMappingURL=useAppWorkflows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAppWorkflows.d.ts","sourceRoot":"","sources":["../../src/hooks/useAppWorkflows.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAK/E,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,0FAA0F;IAC1F,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,mCAAmC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;;;OAOG;IACH,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,eAAe,CAyE5E"}
@@ -0,0 +1,82 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { getTransport } from '../internal/singleton.js';
3
+ import { sendTypedRequest } from '../internal/transport.js';
4
+ /**
5
+ * Read (and cancel within) the calling app's OWN generator SUBQUEUE — the
6
+ * tag-scoped list of generations THIS app produced for the viewer, newest-first —
7
+ * through the host-mediated `QUERY_APP_WORKFLOWS` → `APP_WORKFLOWS_RESULT` and
8
+ * `CANCEL_APP_WORKFLOW` → `CANCEL_APP_WORKFLOW_RESULT` bridges. Token-bound: the
9
+ * host self-binds the account off the block token and FORCES the per-app tag
10
+ * filter (scope `ai:write:budgeted`, same trust boundary as submit) — the block
11
+ * can never widen the filter or reach another user's / their personal queue.
12
+ *
13
+ * Fetches on mount and whenever `params` change (by value), and exposes `refetch`.
14
+ * A host that never answers surfaces as an `error` after the transport's request
15
+ * timeout — the hook never hangs. Late responses that arrive after unmount are
16
+ * ignored.
17
+ *
18
+ * @example
19
+ * const { workflows, cursor, loading, error, cancel } = useAppWorkflows({ limit: 20 });
20
+ * // …render each workflow's images; await cancel(w.workflowId) on a Cancel click.
21
+ */
22
+ export function useAppWorkflows(params) {
23
+ const [workflows, setWorkflows] = useState([]);
24
+ const [cursor, setCursor] = useState(null);
25
+ const [loading, setLoading] = useState(true);
26
+ const [error, setError] = useState(null);
27
+ const mountedRef = useRef(true);
28
+ useEffect(() => {
29
+ mountedRef.current = true;
30
+ return () => {
31
+ mountedRef.current = false;
32
+ };
33
+ }, []);
34
+ // Serialize the params to a stable key so `refetch`'s identity only changes
35
+ // when the params VALUE changes (not on every render's fresh object). The
36
+ // callback re-parses the key so it closes over NOTHING but the key.
37
+ const paramsKey = params ? JSON.stringify(params) : '';
38
+ const refetch = useCallback(() => {
39
+ setLoading(true);
40
+ setError(null);
41
+ const parsed = paramsKey ? JSON.parse(paramsKey) : undefined;
42
+ const payload = parsed ? { params: parsed } : {};
43
+ sendTypedRequest(getTransport(), { type: 'QUERY_APP_WORKFLOWS', payload }, 'APP_WORKFLOWS_RESULT')
44
+ .then((result) => {
45
+ if (!mountedRef.current)
46
+ return;
47
+ if (result.error || !result.result) {
48
+ setError(new Error(result.error ?? 'failed to fetch app workflows'));
49
+ setLoading(false);
50
+ return;
51
+ }
52
+ setWorkflows(result.result.workflows);
53
+ setCursor(result.result.cursor ?? null);
54
+ setLoading(false);
55
+ })
56
+ .catch((err) => {
57
+ if (!mountedRef.current)
58
+ return;
59
+ setError(err instanceof Error ? err : new Error(String(err)));
60
+ setLoading(false);
61
+ });
62
+ }, [paramsKey]);
63
+ useEffect(() => {
64
+ refetch();
65
+ }, [refetch]);
66
+ const cancel = useCallback(async (workflowId) => {
67
+ const reply = await sendTypedRequest(getTransport(), { type: 'CANCEL_APP_WORKFLOW', payload: { workflowId } }, 'CANCEL_APP_WORKFLOW_RESULT');
68
+ if (reply.error || !reply.result) {
69
+ throw new Error(reply.error ?? 'failed to cancel workflow');
70
+ }
71
+ const canceled = reply.result.workflow;
72
+ // Optimistically splice the terminal (canceled) projection into the current
73
+ // page in place — no refetch round-trip. Functional update so it never races
74
+ // a concurrent refetch's stale closure. Only touches the row if it's present
75
+ // (the host returns the canceled workflow regardless).
76
+ if (mountedRef.current) {
77
+ setWorkflows((prev) => prev.map((w) => (w.workflowId === canceled.workflowId ? canceled : w)));
78
+ }
79
+ }, []);
80
+ return { workflows, cursor, loading, error, refetch, cancel };
81
+ }
82
+ //# sourceMappingURL=useAppWorkflows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAppWorkflows.js","sourceRoot":"","sources":["../../src/hooks/useAppWorkflows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { BlockGatedImage } from '@civitai/app-sdk/blocks';
2
+ export type { BlockGatedImage };
3
+ /**
4
+ * What {@link useGatedImages} returns.
5
+ */
6
+ export interface UseGatedImages {
7
+ /**
8
+ * Ask the host for per-VIEWER gated display data for a list of image ids, and
9
+ * resolve with a {@link BlockGatedImage} per resolvable id.
10
+ *
11
+ * The host applies the REQUESTING VIEWER's browsing-level clamp server-side, so
12
+ * the shape a viewer receives depends on THEIR ceiling:
13
+ * - `status: 'visible'` — scanned clean + within ceiling + unflagged: the full
14
+ * moderated projection incl. `url` and `width`/`height` for grid layout.
15
+ * - `status: 'hidden'` — the image exists but is withheld from THIS viewer
16
+ * (above ceiling / not-yet-scanned / flagged): NO `url` is ever returned, so
17
+ * the block MUST render a blurred/placeholder cell for it. The block can
18
+ * never obtain an unclamped url for an image the viewer isn't allowed to see.
19
+ *
20
+ * Ids the host can't resolve to a benchmark-eligible bare `Image` row are
21
+ * OMITTED entirely (neither visible nor hidden), so the returned array MAY be
22
+ * shorter than `imageIds`. Rejects with the host's free-text error on failure,
23
+ * or the transport timeout — the hook never hangs.
24
+ */
25
+ getImages: (imageIds: number[]) => Promise<BlockGatedImage[]>;
26
+ }
27
+ /**
28
+ * Read per-viewer gated display data for a list of image ids via the
29
+ * host-mediated `GET_IMAGES_BY_IDS` → `IMAGES_RESULT` bridge — the read side of
30
+ * a cross-user image grid (e.g. ids stored via `useSharedStorage()`).
31
+ *
32
+ * The host applies the requesting viewer's browsing-level clamp server-side and
33
+ * returns each image as `visible` (moderated projection incl. url) or `hidden`
34
+ * (NO url — above ceiling / unscanned / flagged). This is the load-bearing
35
+ * cross-user moderation boundary: an unclamped edge URL never crosses to a viewer
36
+ * who can't see the image, and the block must render a placeholder for any
37
+ * `hidden` entry.
38
+ *
39
+ * @example
40
+ * const { getImages } = useGatedImages();
41
+ * const images = await getImages([101, 102, 103]);
42
+ * // …render `visible` cells with their url; `hidden` cells as a blurred placeholder.
43
+ */
44
+ export declare function useGatedImages(): UseGatedImages;
45
+ //# sourceMappingURL=useGatedImages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGatedImages.d.ts","sourceRoot":"","sources":["../../src/hooks/useGatedImages.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAK/D,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CAC/D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,IAAI,cAAc,CAc/C"}
@@ -0,0 +1,31 @@
1
+ import { useCallback } from 'react';
2
+ import { getTransport } from '../internal/singleton.js';
3
+ import { sendTypedRequest } from '../internal/transport.js';
4
+ /**
5
+ * Read per-viewer gated display data for a list of image ids via the
6
+ * host-mediated `GET_IMAGES_BY_IDS` → `IMAGES_RESULT` bridge — the read side of
7
+ * a cross-user image grid (e.g. ids stored via `useSharedStorage()`).
8
+ *
9
+ * The host applies the requesting viewer's browsing-level clamp server-side and
10
+ * returns each image as `visible` (moderated projection incl. url) or `hidden`
11
+ * (NO url — above ceiling / unscanned / flagged). This is the load-bearing
12
+ * cross-user moderation boundary: an unclamped edge URL never crosses to a viewer
13
+ * who can't see the image, and the block must render a placeholder for any
14
+ * `hidden` entry.
15
+ *
16
+ * @example
17
+ * const { getImages } = useGatedImages();
18
+ * const images = await getImages([101, 102, 103]);
19
+ * // …render `visible` cells with their url; `hidden` cells as a blurred placeholder.
20
+ */
21
+ export function useGatedImages() {
22
+ const getImages = useCallback(async (imageIds) => {
23
+ const reply = await sendTypedRequest(getTransport(), { type: 'GET_IMAGES_BY_IDS', payload: { imageIds } }, 'IMAGES_RESULT');
24
+ if (reply.error || !reply.result) {
25
+ throw new Error(reply.error ?? 'failed to fetch gated images');
26
+ }
27
+ return reply.result.images;
28
+ }, []);
29
+ return { getImages };
30
+ }
31
+ //# sourceMappingURL=useGatedImages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGatedImages.js","sourceRoot":"","sources":["../../src/hooks/useGatedImages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAIpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AA6B5D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,EAAE,QAAkB,EAA8B,EAAE;QACrF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAClC,YAAY,EAAE,EACd,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,EAAE,EACpD,eAAe,CAChB,CAAC;QACF,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,8BAA8B,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IAC7B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,SAAS,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * What {@link usePublishGenerationOutputs} returns.
3
+ */
4
+ export interface UsePublishGenerationOutputs {
5
+ /**
6
+ * Ask the host to PUBLISH selected outputs of ONE of this app's OWN workflows
7
+ * (from its generator subqueue) as bare, REAL-SCANNED public `Image` rows, and
8
+ * resolve with the created image ids (order matches the resolved outputs).
9
+ *
10
+ * The block sends the `workflowId` + optional `imageIndexes` (indexes into the
11
+ * workflow's `images` as seen via `useAppWorkflows()`) — NEVER urls. The host
12
+ * resolves the orchestrator urls server-side from the ownership-verified
13
+ * workflow, so the iframe can't inject an arbitrary blob. FAIL-CLOSED
14
+ * server-side: the host re-derives (viewer, app, workflowId) ownership before
15
+ * reading the workflow, re-uploads each selected output to civitai storage, and
16
+ * runs the FULL image-scan pipeline (no skip) — the returned ids are bare
17
+ * (post-less), scanned `Image` rows with no Post / gallery attach / rewards /
18
+ * notifications. Host-chrome shows a consent confirm before publishing. Omit
19
+ * `imageIndexes` to publish all available outputs; `title` is an optional
20
+ * advisory label the host MAY ignore.
21
+ *
22
+ * Rejects with the host's free-text error on failure (anon viewer / missing
23
+ * scope / not-owned workflow / rate-limit / upload or scan failure) or the
24
+ * transport timeout — the hook never hangs.
25
+ */
26
+ publish: (args: {
27
+ workflowId: string;
28
+ imageIndexes?: number[];
29
+ title?: string;
30
+ }) => Promise<number[]>;
31
+ }
32
+ /**
33
+ * Publish selected outputs of one of the calling app's OWN generations into bare,
34
+ * real-scanned public `Image` rows via the host-mediated
35
+ * `PUBLISH_GENERATION_OUTPUTS` → `PUBLISH_RESULT` bridge.
36
+ *
37
+ * Token-bound + fail-closed: the host self-binds the account off the block token,
38
+ * re-derives (viewer, app, workflowId) ownership before reading the workflow, and
39
+ * re-uploads + FULL-scans each selected output server-side (no url ever crosses
40
+ * from the iframe). The result is a set of bare (post-less) scanned `Image` row
41
+ * ids — no Post, no gallery attach, no rewards/notifications. Host-chrome shows a
42
+ * consent confirm before anything is published.
43
+ *
44
+ * @example
45
+ * const { publish } = usePublishGenerationOutputs();
46
+ * const imageIds = await publish({ workflowId: w.workflowId, imageIndexes: [0, 2] });
47
+ * // …store imageIds via useSharedStorage() so the grid can read them back gated.
48
+ */
49
+ export declare function usePublishGenerationOutputs(): UsePublishGenerationOutputs;
50
+ //# sourceMappingURL=usePublishGenerationOutputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePublishGenerationOutputs.d.ts","sourceRoot":"","sources":["../../src/hooks/usePublishGenerationOutputs.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACvG;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,2BAA2B,IAAI,2BAA2B,CAwBzE"}
@@ -0,0 +1,38 @@
1
+ import { useCallback } from 'react';
2
+ import { getTransport } from '../internal/singleton.js';
3
+ import { sendTypedRequest } from '../internal/transport.js';
4
+ /**
5
+ * Publish selected outputs of one of the calling app's OWN generations into bare,
6
+ * real-scanned public `Image` rows via the host-mediated
7
+ * `PUBLISH_GENERATION_OUTPUTS` → `PUBLISH_RESULT` bridge.
8
+ *
9
+ * Token-bound + fail-closed: the host self-binds the account off the block token,
10
+ * re-derives (viewer, app, workflowId) ownership before reading the workflow, and
11
+ * re-uploads + FULL-scans each selected output server-side (no url ever crosses
12
+ * from the iframe). The result is a set of bare (post-less) scanned `Image` row
13
+ * ids — no Post, no gallery attach, no rewards/notifications. Host-chrome shows a
14
+ * consent confirm before anything is published.
15
+ *
16
+ * @example
17
+ * const { publish } = usePublishGenerationOutputs();
18
+ * const imageIds = await publish({ workflowId: w.workflowId, imageIndexes: [0, 2] });
19
+ * // …store imageIds via useSharedStorage() so the grid can read them back gated.
20
+ */
21
+ export function usePublishGenerationOutputs() {
22
+ const publish = useCallback(async (args) => {
23
+ const reply = await sendTypedRequest(getTransport(), {
24
+ type: 'PUBLISH_GENERATION_OUTPUTS',
25
+ payload: {
26
+ workflowId: args.workflowId,
27
+ ...(args.imageIndexes !== undefined ? { imageIndexes: args.imageIndexes } : {}),
28
+ ...(args.title !== undefined ? { title: args.title } : {}),
29
+ },
30
+ }, 'PUBLISH_RESULT');
31
+ if (reply.error || !reply.result) {
32
+ throw new Error(reply.error ?? 'failed to publish generation outputs');
33
+ }
34
+ return reply.result.imageIds;
35
+ }, []);
36
+ return { publish };
37
+ }
38
+ //# sourceMappingURL=usePublishGenerationOutputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePublishGenerationOutputs.js","sourceRoot":"","sources":["../../src/hooks/usePublishGenerationOutputs.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;AA8B5D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,2BAA2B;IACzC,MAAM,OAAO,GAAG,WAAW,CACzB,KAAK,EAAE,IAAqE,EAAqB,EAAE;QACjG,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAClC,YAAY,EAAE,EACd;YACE,IAAI,EAAE,4BAA4B;YAClC,OAAO,EAAE;gBACP,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,GAAG,CAAC,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/E,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3D;SACF,EACD,gBAAgB,CACjB,CAAC;QACF,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,sCAAsC,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;IAC/B,CAAC,EACD,EAAE,CACH,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -32,7 +32,13 @@ export { useDailyCompensation } from './hooks/useDailyCompensation.js';
32
32
  export type { UseDailyCompensation } from './hooks/useDailyCompensation.js';
33
33
  export { useWildcardPack, WildcardPackError } from './hooks/useWildcardPack.js';
34
34
  export type { UseWildcardPack } from './hooks/useWildcardPack.js';
35
- export type { BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockWildcardPack, BlockWildcardPackErrorCode, } from '@civitai/app-sdk/blocks';
35
+ export { useAppWorkflows } from './hooks/useAppWorkflows.js';
36
+ export type { UseAppWorkflows } from './hooks/useAppWorkflows.js';
37
+ export { usePublishGenerationOutputs } from './hooks/usePublishGenerationOutputs.js';
38
+ export type { UsePublishGenerationOutputs } from './hooks/usePublishGenerationOutputs.js';
39
+ export { useGatedImages } from './hooks/useGatedImages.js';
40
+ export type { UseGatedImages } from './hooks/useGatedImages.js';
41
+ export type { BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, AppWorkflowImage, AppWorkflowsParams, BlockGatedImage, } from '@civitai/app-sdk/blocks';
36
42
  export { useCheckpointPicker } from './hooks/useCheckpointPicker.js';
37
43
  export { useResourcePicker } from './hooks/useResourcePicker.js';
38
44
  export { useImageUpload } from './hooks/useImageUpload.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -24,6 +24,9 @@ export { useBuzzTransactions } from './hooks/useBuzzTransactions.js';
24
24
  export { useBuzzAccounts } from './hooks/useBuzzAccounts.js';
25
25
  export { useDailyCompensation } from './hooks/useDailyCompensation.js';
26
26
  export { useWildcardPack, WildcardPackError } from './hooks/useWildcardPack.js';
27
+ export { useAppWorkflows } from './hooks/useAppWorkflows.js';
28
+ export { usePublishGenerationOutputs } from './hooks/usePublishGenerationOutputs.js';
29
+ export { useGatedImages } from './hooks/useGatedImages.js';
27
30
  export { useCheckpointPicker } from './hooks/useCheckpointPicker.js';
28
31
  export { useResourcePicker } from './hooks/useResourcePicker.js';
29
32
  export { useImageUpload } from './hooks/useImageUpload.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAG3F,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAO3D,QAAQ;AACR,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAShF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EACL,6BAA6B,EAC7B,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAOzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAG3F,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAO3D,QAAQ;AACR,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEhF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,wCAAwC,CAAC;AAErF,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAa3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EACL,6BAA6B,EAC7B,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAOzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"liveHost.d.ts","sourceRoot":"","sources":["../../src/internal/liveHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH,OAAO,EACL,KAAK,YAAY,EAGjB,KAAK,WAAW,EAChB,KAAK,KAAK,EACV,KAAK,UAAU,EAGhB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,QAAQ,EAAyC,MAAM,eAAe,CAAC;AACrF,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,oBAAoB,CAAC;AAK5B;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC3B,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,UAAU,CAAC;IACpC;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACvD;AAQD;;;;;GAKG;AACH,UAAU,wBAAwB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,wBAAwB,CAgB/E;AAyHD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAssCjE"}
1
+ {"version":3,"file":"liveHost.d.ts","sourceRoot":"","sources":["../../src/internal/liveHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH,OAAO,EACL,KAAK,YAAY,EAGjB,KAAK,WAAW,EAChB,KAAK,KAAK,EACV,KAAK,UAAU,EAGhB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,QAAQ,EAAyC,MAAM,eAAe,CAAC;AACrF,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,oBAAoB,CAAC;AAK5B;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC3B,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,UAAU,CAAC;IACpC;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACvD;AAQD;;;;;GAKG;AACH,UAAU,wBAAwB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,wBAAwB,CAgB/E;AAyHD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CA+yCjE"}
@@ -696,6 +696,93 @@ export function createLiveHost(options) {
696
696
  });
697
697
  return;
698
698
  }
699
+ case 'QUERY_APP_WORKFLOWS': {
700
+ // App generator SUBQUEUE read via the token-bound
701
+ // `blocks.queryAppWorkflows` MUTATION (POST). params (cursor/limit) are
702
+ // spread FIRST so the host-authoritative `blockToken` (spread LAST) can
703
+ // never be overridden — mirrors the real host; the host also forces the
704
+ // per-app tag filter server-side (the input carries no `tags`). It
705
+ // returns a plain `{ workflows, cursor }`, unwrapped with `callTrpcData`.
706
+ // FREE-TEXT error on failure. Unroutable without requestId.
707
+ if (typeof requestId !== 'string')
708
+ return;
709
+ void callTrpcData('blocks.queryAppWorkflows', { ...(typed.payload?.params ?? {}), blockToken: rawToken }, 'POST').then((r) => {
710
+ dispatchToBlock({
711
+ type: 'APP_WORKFLOWS_RESULT',
712
+ payload: r.data
713
+ ? { requestId, result: r.data }
714
+ : { requestId, error: r.error ?? 'app workflows unavailable' },
715
+ });
716
+ });
717
+ return;
718
+ }
719
+ case 'CANCEL_APP_WORKFLOW': {
720
+ // Cancel ONE subqueue workflow via the token-bound
721
+ // `blocks.cancelAppWorkflow` MUTATION (POST). FAIL-CLOSED server-side
722
+ // (ownership + app-tag guard). Returns a plain `{ workflow }` (the
723
+ // terminal projection), unwrapped with `callTrpcData`. FREE-TEXT error
724
+ // on failure (FORBIDDEN / transport). Drop a request with no requestId
725
+ // or a missing/empty workflowId (mirrors the real host).
726
+ if (typeof requestId !== 'string')
727
+ return;
728
+ const cancelId = typed.payload?.workflowId;
729
+ if (typeof cancelId !== 'string' || cancelId.length === 0)
730
+ return;
731
+ void callTrpcData('blocks.cancelAppWorkflow', { blockToken: rawToken, workflowId: cancelId }, 'POST').then((r) => {
732
+ dispatchToBlock({
733
+ type: 'CANCEL_APP_WORKFLOW_RESULT',
734
+ payload: r.data
735
+ ? { requestId, result: r.data }
736
+ : { requestId, error: r.error ?? 'cancel failed' },
737
+ });
738
+ });
739
+ return;
740
+ }
741
+ case 'PUBLISH_GENERATION_OUTPUTS': {
742
+ // Publish selected outputs of one of the app's OWN workflows as bare,
743
+ // real-scanned public Image rows via the token-bound
744
+ // `blocks.publishGenerationOutputs` MUTATION (POST). The block sends
745
+ // `workflowId` + optional `imageIndexes` (NEVER urls); the host
746
+ // re-derives ownership, re-uploads + FULL-scans server-side. Returns a
747
+ // plain `{ imageIds }`, unwrapped with `callTrpcData`. FREE-TEXT error
748
+ // on failure. Unroutable without requestId.
749
+ if (typeof requestId !== 'string')
750
+ return;
751
+ void callTrpcData('blocks.publishGenerationOutputs', {
752
+ blockToken: rawToken,
753
+ workflowId: typed.payload?.workflowId,
754
+ ...(typed.payload?.imageIndexes !== undefined
755
+ ? { imageIndexes: typed.payload.imageIndexes }
756
+ : {}),
757
+ ...(typed.payload?.title !== undefined ? { title: typed.payload.title } : {}),
758
+ }, 'POST').then((r) => {
759
+ dispatchToBlock({
760
+ type: 'PUBLISH_RESULT',
761
+ payload: r.data
762
+ ? { requestId, result: r.data }
763
+ : { requestId, error: r.error ?? 'publish unavailable' },
764
+ });
765
+ });
766
+ return;
767
+ }
768
+ case 'GET_IMAGES_BY_IDS': {
769
+ // Per-viewer gated image read via the token-bound `blocks.getImagesByIds`
770
+ // MUTATION (POST). The host applies the requesting viewer's
771
+ // browsing-level clamp server-side and returns a plain `{ images }`
772
+ // (`BlockGatedImage[]` — visible/hidden), unwrapped with `callTrpcData`.
773
+ // FREE-TEXT error on failure. Unroutable without requestId.
774
+ if (typeof requestId !== 'string')
775
+ return;
776
+ void callTrpcData('blocks.getImagesByIds', { blockToken: rawToken, imageIds: typed.payload?.imageIds ?? [] }, 'POST').then((r) => {
777
+ dispatchToBlock({
778
+ type: 'IMAGES_RESULT',
779
+ payload: r.data
780
+ ? { requestId, result: r.data }
781
+ : { requestId, error: r.error ?? 'gated images unavailable' },
782
+ });
783
+ });
784
+ return;
785
+ }
699
786
  case 'OPEN_CHECKPOINT_PICKER': {
700
787
  // Serve the picker locally: open the in-harness catalog browser
701
788
  // filtered to Checkpoints in the requested ecosystem, pre-highlight