@giveitsmaller/sdk 0.19.0 → 0.21.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/LICENSE +202 -0
- package/README.md +8 -15
- package/dist/_audit.js +14 -4
- package/dist/builder.d.ts +5 -4
- package/dist/builder.js +16 -16
- package/dist/client.d.ts +17 -7
- package/dist/client.js +116 -62
- package/dist/ergonomic/image_output_routes.d.ts +30 -0
- package/dist/ergonomic/image_output_routes.js +82 -11
- package/dist/ergonomic/option_types.d.ts +34 -1
- package/dist/ergonomic/option_types.js +5 -1
- package/dist/ergonomic/option_validation.d.ts +19 -1
- package/dist/ergonomic/option_validation.js +34 -1
- package/dist/ergonomic/preset_resolver.d.ts +2 -2
- package/dist/ergonomic/preset_resolver.js +6 -10
- package/dist/ergonomic/presets/index.d.ts +9 -8
- package/dist/ergonomic/presets/index.js +1 -9
- package/dist/errors.d.ts +105 -3
- package/dist/errors.js +136 -2
- package/dist/file-first.d.ts +234 -16
- package/dist/file-first.js +692 -175
- package/dist/generated/sdk_spec/enums.d.ts +0 -26
- package/dist/generated/sdk_spec/enums.js +0 -16
- package/dist/generated/sdk_spec/errors.d.ts +1 -1
- package/dist/generated/sdk_spec/errors.js +12 -0
- package/dist/generated/sdk_spec/presets.js +0 -14
- package/dist/generated/sdk_spec/version.d.ts +2 -2
- package/dist/generated/sdk_spec/version.js +2 -2
- package/dist/gisl.d.ts +93 -5
- package/dist/gisl.js +72 -2
- package/dist/handle.d.ts +6 -1
- package/dist/handle.js +42 -13
- package/dist/index.core.d.ts +10 -8
- package/dist/index.core.js +11 -3
- package/dist/merge.d.ts +12 -0
- package/dist/merge.js +14 -2
- package/dist/retry-metadata.d.ts +37 -0
- package/dist/retry-metadata.js +86 -0
- package/dist/sse.d.ts +2 -1
- package/dist/sse.js +26 -6
- package/dist/types.d.ts +54 -4
- package/dist/types.js +1 -0
- package/package.json +3 -3
- package/dist/ergonomic/presets/document_pdf_compress.d.ts +0 -12
- package/dist/ergonomic/presets/document_pdf_compress.js +0 -33
package/dist/file-first.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { GislItemFailedError } from './errors.js';
|
|
|
13
13
|
import { type ProgressEvent } from './builder.js';
|
|
14
14
|
import type { GislClient } from './client.js';
|
|
15
15
|
import type { OperationDownload, WorkflowStatusResponse } from '@giveitsmaller/contracts/openapi';
|
|
16
|
-
import type { ConvertOptions, ThumbnailOptions, TextWatermarkOptions, WatermarkOptions, OutputOptions, OutputFit } from './ergonomic/option_types.js';
|
|
16
|
+
import type { ConvertOptions, ThumbnailOptions, TransformOptions, TextWatermarkOptions, WatermarkOptions, OutputOptions, OutputFit } from './ergonomic/option_types.js';
|
|
17
17
|
import { OptimizeFor } from './generated/sdk_spec/enums.js';
|
|
18
18
|
import type { PresetDefaults } from './ergonomic/presets/index.js';
|
|
19
19
|
import type { WorkflowCreatePayload } from './types.js';
|
|
@@ -72,6 +72,19 @@ export interface OutputFile {
|
|
|
72
72
|
* outputs.
|
|
73
73
|
*/
|
|
74
74
|
readonly targetSizeMet?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* The measured perceptual quality of an `auto_quality` encode (0-1). Projected
|
|
77
|
+
* from the generated {@link OperationDownload.measuredQuality}; undefined
|
|
78
|
+
* (omitted) when the worker reported no measurement. Pairs with
|
|
79
|
+
* {@link qualityMetric}, which names the metric it was measured on.
|
|
80
|
+
*/
|
|
81
|
+
readonly measuredQuality?: number;
|
|
82
|
+
/**
|
|
83
|
+
* The metric {@link measuredQuality} was measured on (e.g. `ssimulacra2`).
|
|
84
|
+
* Projected from the generated {@link OperationDownload.qualityMetric};
|
|
85
|
+
* undefined when no measurement was reported.
|
|
86
|
+
*/
|
|
87
|
+
readonly qualityMetric?: string;
|
|
75
88
|
}
|
|
76
89
|
/**
|
|
77
90
|
* One succeeded entry in {@link RunResult.succeeded}: a single input's
|
|
@@ -243,10 +256,43 @@ export declare function projectMultiJobToRunResult(workflowId: string, finalStat
|
|
|
243
256
|
* @internal Exported for the file-first `Handle`; not part of the public API.
|
|
244
257
|
*/
|
|
245
258
|
export declare function isFanoutStatus(finalStatus: WorkflowStatusResponse): boolean;
|
|
259
|
+
/**
|
|
260
|
+
* Job id/ref for the DOWNSTREAM job that carries post-`sole_op` steps. A
|
|
261
|
+
* `sole_op` op (image_watermark / video_watermark / merge — ADR-0025) MUST be
|
|
262
|
+
* the only op in its job, so when a caller chains `compress()` / `convert()` /
|
|
263
|
+
* `thumbnail()` / `transform()` after `watermark()` / `merge()`, those steps
|
|
264
|
+
* lower into this separate job that consumes the sole_op output via
|
|
265
|
+
* `job_output` (the server derives the DAG from the `from` reference — no
|
|
266
|
+
* explicit `workflow_edges` needed). When present it is the TERMINAL deliverable,
|
|
267
|
+
* so `run()` / the {@link Handle} project THIS job's output, and the status-shape
|
|
268
|
+
* detectors accept it alongside the sole_op + `src_{i}` refs. PIiUit28.
|
|
269
|
+
*/
|
|
270
|
+
export declare const _POST_STEP_JOB_REF = "post";
|
|
271
|
+
/**
|
|
272
|
+
* Job id/ref for the UPSTREAM job carrying any steps that PRECEDE a single-input
|
|
273
|
+
* `sole_op` op (e.g. `.compress().textWatermark()`): the pre-steps run in this
|
|
274
|
+
* job, the `sole_op` job then consumes its output via `job_output`. Distinct
|
|
275
|
+
* from the multi-input `src_{i}` fan-in refs. IQc01rj0.
|
|
276
|
+
*/
|
|
277
|
+
export declare const _PRE_STEP_JOB_REF = "pre";
|
|
278
|
+
/**
|
|
279
|
+
* Wire op types the API marks `sole_op` (ADR-0025) — the op MUST be the ONLY op
|
|
280
|
+
* in its job. Mirrors `operation-capabilities.json` `operations.<op>.sole_op`,
|
|
281
|
+
* inlined as a browser-safe const (the raw-JSON sidecar subpath is Node-only)
|
|
282
|
+
* and PINNED to that projection by `sole-op-conformance.test.ts` — a contract
|
|
283
|
+
* regen that flips an op's `sole_op` fails there. The single-input
|
|
284
|
+
* {@link Recipe.toWorkflowPayload} reads THIS set to split a chain at every
|
|
285
|
+
* sole_op boundary into a `job_output`-linked job chain (so
|
|
286
|
+
* `.textWatermark('x').compress()` lowers to a valid DAG, not a contract-invalid
|
|
287
|
+
* co-bundled job). Mirrored by PHP `Recipe::SOLE_OP_TYPES`. IQc01rj0.
|
|
288
|
+
* @internal
|
|
289
|
+
*/
|
|
290
|
+
export declare const SOLE_OP_TYPES: ReadonlySet<string>;
|
|
246
291
|
/**
|
|
247
292
|
* True when a terminal status describes a fluent `files([...]).merge(...)`
|
|
248
293
|
* combine — at least one job ref `merge` and every OTHER job ref is `src_{i}`
|
|
249
|
-
* (the ids the {@link MergedRecipe} lowering
|
|
294
|
+
* or the downstream `post` job (the ids the {@link MergedRecipe} lowering
|
|
295
|
+
* assigns; `post` carries any post-combine steps). The data-driven seam that
|
|
250
296
|
* lets {@link Handle.wait}/{@link Handle.result} project ONLY the merged output
|
|
251
297
|
* — filtering the `src_*` passthrough plumbing — even after a
|
|
252
298
|
* `client.workflow(id)` reattach (no construction-time marker), matching
|
|
@@ -269,9 +315,10 @@ export declare function isMergeStatus(finalStatus: WorkflowStatusResponse): bool
|
|
|
269
315
|
export declare function isArchiveStatus(finalStatus: WorkflowStatusResponse): boolean;
|
|
270
316
|
/**
|
|
271
317
|
* True when a terminal status describes a fluent `file(...).watermark(overlay)`
|
|
272
|
-
* — at least one job ref `watermark` and every OTHER job ref is `src_{i}`
|
|
273
|
-
* ids the {@link WatermarkedRecipe} lowering
|
|
274
|
-
* overlay
|
|
318
|
+
* — at least one job ref `watermark` and every OTHER job ref is `src_{i}` or
|
|
319
|
+
* the downstream `post` job (the ids the {@link WatermarkedRecipe} lowering
|
|
320
|
+
* assigns: `src_0` base, `src_1` overlay, `post` any post-watermark steps).
|
|
321
|
+
* Lets {@link Handle.wait}/{@link Handle.result} AND
|
|
275
322
|
* {@link WatermarkedRecipe.run} project ONLY the watermark output — filtering
|
|
276
323
|
* the `src_*` passthrough plumbing — even after a `client.workflow(id)` reattach.
|
|
277
324
|
* Mutually exclusive with {@link isFanoutStatus} / {@link isMergeStatus} /
|
|
@@ -280,6 +327,28 @@ export declare function isArchiveStatus(finalStatus: WorkflowStatusResponse): bo
|
|
|
280
327
|
* @internal Exported for the file-first `Handle`; not part of the public API.
|
|
281
328
|
*/
|
|
282
329
|
export declare function isWatermarkStatus(finalStatus: WorkflowStatusResponse): boolean;
|
|
330
|
+
/**
|
|
331
|
+
* True when a terminal status describes a SINGLE-INPUT `sole_op` chain — e.g.
|
|
332
|
+
* `.textWatermark('x').compress()` lowered to a `text_watermark` job + a
|
|
333
|
+
* downstream `post` job (and an optional upstream `pre` job for steps before the
|
|
334
|
+
* sole_op). Every job ref is a `sole_op` wire type ({@link SOLE_OP_TYPES}) or the
|
|
335
|
+
* `pre`/`post` chain refs, with NO `src_{i}` fan-in ref (which distinguishes it
|
|
336
|
+
* from the multi-input merge/watermark/archive DAGs). Lets a submitted/reattached
|
|
337
|
+
* {@link Handle} project ONLY the terminal deliverable — filtering the
|
|
338
|
+
* intermediate sole_op artifact — without builder state. IQc01rj0.
|
|
339
|
+
*
|
|
340
|
+
* @internal Exported for the file-first `Handle`; not part of the public API.
|
|
341
|
+
*/
|
|
342
|
+
export declare function isSoleOpChainStatus(finalStatus: WorkflowStatusResponse): boolean;
|
|
343
|
+
/**
|
|
344
|
+
* The terminal deliverable ref for a single-input `sole_op` chain status: the
|
|
345
|
+
* downstream `post` job when present, else the `sole_op` job itself (the ref in
|
|
346
|
+
* {@link SOLE_OP_TYPES}). Mirrors how the merge/watermark paths pick their
|
|
347
|
+
* terminal via {@link terminalOutputRef} in `handle.ts`. IQc01rj0.
|
|
348
|
+
*
|
|
349
|
+
* @internal
|
|
350
|
+
*/
|
|
351
|
+
export declare function soleOpChainDeliverableRef(finalStatus: WorkflowStatusResponse): string;
|
|
283
352
|
/**
|
|
284
353
|
* The primary file a {@link Recipe} operates on — the "subject" of the
|
|
285
354
|
* file-first surface. A discriminated union over the ways a caller names an
|
|
@@ -324,7 +393,7 @@ export declare const fileInput: {
|
|
|
324
393
|
};
|
|
325
394
|
/** One step in a {@link Recipe}'s chain — an op kind + captured ergonomic args. */
|
|
326
395
|
interface RecipeStep {
|
|
327
|
-
readonly opType: 'compress' | 'convert' | 'thumbnail' | 'text_watermark' | 'output';
|
|
396
|
+
readonly opType: 'compress' | 'convert' | 'thumbnail' | 'text_watermark' | 'output' | 'transform';
|
|
328
397
|
readonly options: Readonly<Record<string, unknown>>;
|
|
329
398
|
}
|
|
330
399
|
/**
|
|
@@ -378,6 +447,19 @@ export declare class Recipe {
|
|
|
378
447
|
* dropped from the wire options (not sent as `undefined`).
|
|
379
448
|
*/
|
|
380
449
|
thumbnail(options: ThumbnailOptions): Recipe;
|
|
450
|
+
/**
|
|
451
|
+
* Geometric transform: rotate (0/90/180/270°) and/or flip. Chainable — the
|
|
452
|
+
* canonical single-job order is `transform → convert → compress → thumbnail`,
|
|
453
|
+
* so downstream size options refer to the final (post-transform) frame.
|
|
454
|
+
*
|
|
455
|
+
* Passthrough: `rotate`/`flip` are forwarded as-is; the SDK does NOT narrow
|
|
456
|
+
* per media (a `flip` on a PDF input passes SDK validation but the server
|
|
457
|
+
* rejects it — documents rotate only). The transform op is `availability:
|
|
458
|
+
* planned` today, so workflow-create returns `feature_not_available` (422)
|
|
459
|
+
* until the per-media Lambdas ship. A no-op (`rotate:0` + `flip:none`) is
|
|
460
|
+
* rejected server-side as `invalid_options`.
|
|
461
|
+
*/
|
|
462
|
+
transform(options?: TransformOptions): Recipe;
|
|
381
463
|
/**
|
|
382
464
|
* Produce ONE transformed image: keep or change format, plus quality, resize
|
|
383
465
|
* and route-honored controls. The single user-facing image transform — the SDK
|
|
@@ -414,7 +496,8 @@ export declare class Recipe {
|
|
|
414
496
|
* (beta). Audio/document/animated-GIF/unsupported-subtype/undetectable bases
|
|
415
497
|
* throw locally BEFORE any upload (the planned-op gate). `options` carries the
|
|
416
498
|
* wire watermark options (`anchor`, `opacity`, `margin_x`, `margin_y`,
|
|
417
|
-
* `overlay_width`). Returns a
|
|
499
|
+
* `overlay_width`, or `overlays[]` for the multi-overlay stack). Returns a
|
|
500
|
+
* {@link WatermarkedRecipe} (chain post-watermark
|
|
418
501
|
* `compress`/`convert`/`thumbnail`, then `run`/`submit`). Distinct from
|
|
419
502
|
* {@link textWatermark} (single-input text overlay).
|
|
420
503
|
*/
|
|
@@ -434,6 +517,15 @@ export declare class Recipe {
|
|
|
434
517
|
* fixed id). Not part of the caller-facing fluent surface.
|
|
435
518
|
*/
|
|
436
519
|
toWorkflowPayload(fileId: string, callbackUrl?: string): WorkflowCreatePayload;
|
|
520
|
+
/**
|
|
521
|
+
* Trigger the per-step lowering purely for its validation side effects
|
|
522
|
+
* (route honoring, planned / out-of-enum values, `media_unknown`), discarding
|
|
523
|
+
* the result. Called BEFORE uploading bytes so a route-invalid recipe fails
|
|
524
|
+
* fast instead of after the upload is spent — parity with PHP
|
|
525
|
+
* `assertOperationsLowerable`. Lowering reads only `steps` + the input token,
|
|
526
|
+
* not the upload id, so this is a faithful preflight (0azjb6Rg).
|
|
527
|
+
*/
|
|
528
|
+
private assertOperationsLowerable;
|
|
437
529
|
/** The result-addressing key passed to `file()`, or undefined. */
|
|
438
530
|
key(): string | undefined;
|
|
439
531
|
/** The number of operations chained so far (introspection / tests). */
|
|
@@ -466,6 +558,8 @@ export declare class Recipe {
|
|
|
466
558
|
maxWait?: string | number;
|
|
467
559
|
onProgress?: (event: ProgressEvent) => void;
|
|
468
560
|
signal?: AbortSignal;
|
|
561
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
562
|
+
useSSE?: boolean;
|
|
469
563
|
pollIntervalMs?: number;
|
|
470
564
|
probeBeforeCreate?: boolean;
|
|
471
565
|
probeTimeoutMs?: number;
|
|
@@ -625,6 +719,8 @@ export declare class FilesRecipe {
|
|
|
625
719
|
convert(format: string, options?: ConvertOptions): FilesRecipe;
|
|
626
720
|
/** Generate a preview of every input. `width` AND `height` are required; validated via the base {@link Recipe} before any upload. */
|
|
627
721
|
thumbnail(options: ThumbnailOptions): FilesRecipe;
|
|
722
|
+
/** Apply the same geometric transform (rotate/flip) to every input. Validated via the base {@link Recipe}. */
|
|
723
|
+
transform(options?: TransformOptions): FilesRecipe;
|
|
628
724
|
/** Apply the same text watermark to every input. Option keys validated via the base {@link Recipe}. */
|
|
629
725
|
textWatermark(text: string, options?: TextWatermarkOptions): FilesRecipe;
|
|
630
726
|
/**
|
|
@@ -681,6 +777,8 @@ export declare class FilesRecipe {
|
|
|
681
777
|
maxWait?: string | number;
|
|
682
778
|
onProgress?: (event: ProgressEvent) => void;
|
|
683
779
|
signal?: AbortSignal;
|
|
780
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
781
|
+
useSSE?: boolean;
|
|
684
782
|
pollIntervalMs?: number;
|
|
685
783
|
probeBeforeCreate?: boolean;
|
|
686
784
|
probeTimeoutMs?: number;
|
|
@@ -738,9 +836,10 @@ export declare class FilesRecipe {
|
|
|
738
836
|
*
|
|
739
837
|
* **Lowering (one workflow):** each input is uploaded once and wrapped in its
|
|
740
838
|
* own single-input `passthrough` source job (`src_N`); the `merge` job consumes
|
|
741
|
-
* those via `job_output` inputs (array order = play order)
|
|
742
|
-
* op
|
|
743
|
-
* convert / thumbnail
|
|
839
|
+
* those via `job_output` inputs (array order = play order). `merge` is
|
|
840
|
+
* `sole_op` (ADR-0025), so it is the ONLY op in its job; any post-combine ops
|
|
841
|
+
* (compress / convert / thumbnail / transform) lower into a downstream `post`
|
|
842
|
+
* job that consumes the merged output via `job_output`. The
|
|
744
843
|
* merge-level wire options reuse {@link wireMergeOptions} so a fluent merge
|
|
745
844
|
* lowers identically to the operation-first `client.merge()`.
|
|
746
845
|
*
|
|
@@ -761,11 +860,13 @@ export declare class MergedRecipe {
|
|
|
761
860
|
convert(format: string, options?: ConvertOptions): MergedRecipe;
|
|
762
861
|
/** Thumbnail the merged output. `width` AND `height` are required; validated pre-upload. */
|
|
763
862
|
thumbnail(options: ThumbnailOptions): MergedRecipe;
|
|
863
|
+
/** Geometric transform (rotate/flip) of the merged output. Passthrough; see {@link Recipe.transform}. */
|
|
864
|
+
transform(options?: TransformOptions): MergedRecipe;
|
|
764
865
|
/**
|
|
765
866
|
* Lower to the merge DAG: one `passthrough` source job per input + one
|
|
766
|
-
* `merge` job whose `operations[]` is `[merge
|
|
767
|
-
*
|
|
768
|
-
*
|
|
867
|
+
* `merge` job whose `operations[]` is exactly `[merge]` (sole_op). The merge
|
|
868
|
+
* job's `inputs[]` consume the source jobs via `job_output` in input (play)
|
|
869
|
+
* order; any post-combine ops lower into a downstream `post` job.
|
|
769
870
|
*
|
|
770
871
|
* @internal Consumed by {@link run} (after uploading all inputs), {@link submit}
|
|
771
872
|
* (with a webhook), and the cross-language parity harness (with fixed ids).
|
|
@@ -788,6 +889,8 @@ export declare class MergedRecipe {
|
|
|
788
889
|
maxWait?: string | number;
|
|
789
890
|
onProgress?: (event: ProgressEvent) => void;
|
|
790
891
|
signal?: AbortSignal;
|
|
892
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
893
|
+
useSSE?: boolean;
|
|
791
894
|
pollIntervalMs?: number;
|
|
792
895
|
probeBeforeCreate?: boolean;
|
|
793
896
|
probeTimeoutMs?: number;
|
|
@@ -887,6 +990,8 @@ export declare class ArchivedRecipe {
|
|
|
887
990
|
maxWait?: string | number;
|
|
888
991
|
onProgress?: (event: ProgressEvent) => void;
|
|
889
992
|
signal?: AbortSignal;
|
|
993
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
994
|
+
useSSE?: boolean;
|
|
890
995
|
pollIntervalMs?: number;
|
|
891
996
|
probeBeforeCreate?: boolean;
|
|
892
997
|
probeTimeoutMs?: number;
|
|
@@ -925,7 +1030,8 @@ export declare class ArchivedRecipe {
|
|
|
925
1030
|
* `passthrough` source job (`src_0` base, `src_1` overlay; their own preceding
|
|
926
1031
|
* steps lower into those jobs), and the `watermark` job consumes them via
|
|
927
1032
|
* `job_output` inputs tagged `role: base` / `role: overlay`. Post-watermark
|
|
928
|
-
* `compress`/`convert`/`thumbnail`
|
|
1033
|
+
* `compress`/`convert`/`thumbnail`/`transform` steps lower into a downstream
|
|
1034
|
+
* `post` job on the watermark output (`image_watermark` is `sole_op`). Mirrors
|
|
929
1035
|
* {@link MergedRecipe}. `textWatermark` is intentionally NOT a post-verb here.
|
|
930
1036
|
*/
|
|
931
1037
|
export declare class WatermarkedRecipe {
|
|
@@ -944,11 +1050,14 @@ export declare class WatermarkedRecipe {
|
|
|
944
1050
|
convert(format: string, options?: ConvertOptions): WatermarkedRecipe;
|
|
945
1051
|
/** Thumbnail the watermarked output. `width` AND `height` are required; validated pre-upload. */
|
|
946
1052
|
thumbnail(options: ThumbnailOptions): WatermarkedRecipe;
|
|
1053
|
+
/** Geometric transform (rotate/flip) of the watermarked output. Passthrough; see {@link Recipe.transform}. */
|
|
1054
|
+
transform(options?: TransformOptions): WatermarkedRecipe;
|
|
947
1055
|
/**
|
|
948
1056
|
* Lower to the watermark DAG: a `src_0` passthrough/base-steps job + a `src_1`
|
|
949
1057
|
* passthrough/overlay-steps job + one `watermark` job whose `inputs[]` consume
|
|
950
|
-
* them via `job_output` (role base/overlay)
|
|
951
|
-
*
|
|
1058
|
+
* them via `job_output` (role base/overlay). The watermark op is `sole_op`
|
|
1059
|
+
* (ADR-0025), so `operations[]` is exactly `[image_watermark|video_watermark]`;
|
|
1060
|
+
* any post-watermark ops lower into a downstream `post` job. `fileIds` is
|
|
952
1061
|
* `[baseId, overlayId]` (upload order). Throws pre-lowering if the base media
|
|
953
1062
|
* is undetectable/unsupported (the planned-op gate).
|
|
954
1063
|
*
|
|
@@ -967,6 +1076,8 @@ export declare class WatermarkedRecipe {
|
|
|
967
1076
|
maxWait?: string | number;
|
|
968
1077
|
onProgress?: (event: ProgressEvent) => void;
|
|
969
1078
|
signal?: AbortSignal;
|
|
1079
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
1080
|
+
useSSE?: boolean;
|
|
970
1081
|
pollIntervalMs?: number;
|
|
971
1082
|
probeBeforeCreate?: boolean;
|
|
972
1083
|
probeTimeoutMs?: number;
|
|
@@ -1005,4 +1116,111 @@ export declare class WatermarkedRecipe {
|
|
|
1005
1116
|
private lowerPostSteps;
|
|
1006
1117
|
private withStep;
|
|
1007
1118
|
}
|
|
1119
|
+
/**
|
|
1120
|
+
* The keyed multi-recipe batch builder (FF7 / MFaCjL8d). `client.batch([r1, r2, …])`
|
|
1121
|
+
* runs N DISTINCT single-input keyed {@link Recipe}s as ONE workflow; the
|
|
1122
|
+
* partitioned {@link RunResult} addresses each entry's outputs by the caller key
|
|
1123
|
+
* given at `client.file(input, key)` time (`res.byKey('hero')`), and one failed
|
|
1124
|
+
* entry lands in `failed` without sinking the rest.
|
|
1125
|
+
*
|
|
1126
|
+
* **v1 scope (locked):** `.run()` only (no `submit()` / reattach — a follow-up);
|
|
1127
|
+
* single-input {@link Recipe} entries only — the multi-input builders
|
|
1128
|
+
* ({@link FilesRecipe}, {@link MergedRecipe}, {@link WatermarkedRecipe},
|
|
1129
|
+
* {@link ArchivedRecipe}) are REJECTED pre-upload. Cross-entry upload dedupe
|
|
1130
|
+
* IS applied (1LwSJcz1): two entries sourcing the SAME input (by
|
|
1131
|
+
* {@link inputIdentity}) upload ONCE and share the resulting fileId —
|
|
1132
|
+
* correctness-neutral (same bytes → same per-job output), it only elides
|
|
1133
|
+
* redundant uploads. Observable caveat: `onProgress` upload-phase events drop
|
|
1134
|
+
* to one-per-UNIQUE input rather than one-per-entry.
|
|
1135
|
+
*
|
|
1136
|
+
* **Lowering (one workflow):** for each entry `i`, lower its single job via
|
|
1137
|
+
* {@link Recipe.toWorkflowPayload} and re-id it `b{i}` — a POSITIONAL namespace
|
|
1138
|
+
* DISTINCT from the fan-out `file-{i}` / merge-archive-watermark `src_{i}` refs so
|
|
1139
|
+
* a future reattach can't misdetect the wire as a fan-out / merge. `keyByRef`
|
|
1140
|
+
* maps each `b{i}` ref to that entry's caller key, so
|
|
1141
|
+
* {@link projectMultiJobToRunResult} partitions per entry (1 job ↔ 1 key:
|
|
1142
|
+
* `completed` → `succeeded`, else → `failed` with a {@link GislItemFailedError}).
|
|
1143
|
+
*
|
|
1144
|
+
* **Immutability:** the ctor is CLIENT-ONLY (the ordered entries + the client) —
|
|
1145
|
+
* entries are already-built Recipes that captured their own preset defaults at
|
|
1146
|
+
* `client.file(...)` time, so batch never re-plumbs
|
|
1147
|
+
* presetDefaults/scopedPresetDefaults. Mirrors the PHP `BatchRecipe`.
|
|
1148
|
+
*/
|
|
1149
|
+
export declare class BatchRecipe {
|
|
1150
|
+
private readonly client?;
|
|
1151
|
+
private readonly recipes;
|
|
1152
|
+
constructor(recipes: ReadonlyArray<Recipe>, client?: GislClient | undefined);
|
|
1153
|
+
/**
|
|
1154
|
+
* Execute the batch end-to-end: validate + lowering-preflight EVERY entry
|
|
1155
|
+
* BEFORE any upload, upload each entry's input, create ONE multi-job workflow
|
|
1156
|
+
* (one `b{i}` job per entry), await a terminal state (SSE with poll fallback,
|
|
1157
|
+
* honouring `useSSE`), then partition the per-job downloads into a keyed
|
|
1158
|
+
* {@link RunResult}. `partially_failed` is a NORMAL terminal state here — the
|
|
1159
|
+
* completed entries land in `succeeded`, the rest in `failed`.
|
|
1160
|
+
*
|
|
1161
|
+
* Requires a client bound at construction time — `gisl().batch([...])` wires
|
|
1162
|
+
* it; a directly-constructed {@link BatchRecipe} (e.g. a lowering-only test)
|
|
1163
|
+
* throws {@link GislConfigError}. Mirrors the fan-out {@link FilesRecipe.run}.
|
|
1164
|
+
*/
|
|
1165
|
+
run(options?: {
|
|
1166
|
+
maxWait?: string | number;
|
|
1167
|
+
onProgress?: (event: ProgressEvent) => void;
|
|
1168
|
+
signal?: AbortSignal;
|
|
1169
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
1170
|
+
useSSE?: boolean;
|
|
1171
|
+
pollIntervalMs?: number;
|
|
1172
|
+
probeBeforeCreate?: boolean;
|
|
1173
|
+
probeTimeoutMs?: number;
|
|
1174
|
+
}): Promise<RunResult>;
|
|
1175
|
+
/**
|
|
1176
|
+
* Lower the batch to ONE multi-job workflow-create payload against a list of
|
|
1177
|
+
* resolved upload ids (one per entry, in entry order). Each entry `i` becomes
|
|
1178
|
+
* ONE job re-id'd `b{i}` carrying that entry's lowered `source` + `operations`.
|
|
1179
|
+
* Composes the single-file {@link Recipe.toWorkflowPayload} per entry so each
|
|
1180
|
+
* keeps its own media-hint + preset resolution and lowering logic is not
|
|
1181
|
+
* duplicated. `callback_url` is built in ONLY when a webhook is supplied
|
|
1182
|
+
* (batch v1 run() supplies none, so it is omitted).
|
|
1183
|
+
*
|
|
1184
|
+
* @internal Consumed by {@link run} (after uploading) and the cross-language
|
|
1185
|
+
* golden-payload lowering test (with fixed ids). Not caller-facing.
|
|
1186
|
+
*/
|
|
1187
|
+
toWorkflowPayload(fileIds: readonly string[], callbackUrl?: string): WorkflowCreatePayload;
|
|
1188
|
+
/** The number of recipe entries in this batch (introspection / tests). */
|
|
1189
|
+
get recipeCount(): number;
|
|
1190
|
+
/**
|
|
1191
|
+
* Validate the batch AND lowering-preflight every entry BEFORE any upload
|
|
1192
|
+
* fires — an invalid entry costs no bandwidth. TWO PASSES (mirrors PHP
|
|
1193
|
+
* `BatchRecipe`'s structural-loop-then-preflight-loop), throwing
|
|
1194
|
+
* {@link GislConfigError}:
|
|
1195
|
+
* 0. empty batch → `no_recipes` (checked first).
|
|
1196
|
+
* PASS 1 (structural, ALL entries in order):
|
|
1197
|
+
* - a KNOWN multi-input builder (checked FIRST — they do NOT extend
|
|
1198
|
+
* {@link Recipe}, so the not-a-Recipe catch-all would otherwise misreport
|
|
1199
|
+
* them as plain type errors) → `multi_input_recipe_unsupported`;
|
|
1200
|
+
* - a non-{@link Recipe} entry → `invalid_recipe`;
|
|
1201
|
+
* - a missing/empty key → `missing_key`;
|
|
1202
|
+
* - a duplicate key → `duplicate_key`.
|
|
1203
|
+
* PASS 2 (lowering preflight, ALL entries): lower each entry (via
|
|
1204
|
+
* {@link Recipe.toWorkflowPayload}) so an invalid lowering throws BEFORE any
|
|
1205
|
+
* upload, mirroring what {@link FilesRecipe} lowers pre-create.
|
|
1206
|
+
*
|
|
1207
|
+
* Two passes so a batch with MULTIPLE distinct violations throws the SAME
|
|
1208
|
+
* reason regardless of entry order (a structural error anywhere wins over a
|
|
1209
|
+
* lowering error elsewhere) — converging TS + PHP error reporting. The
|
|
1210
|
+
* offending key/index rides the MESSAGE (not `conflictingFields`, which is
|
|
1211
|
+
* reserved for wire FIELD names).
|
|
1212
|
+
*/
|
|
1213
|
+
private validatePreUpload;
|
|
1214
|
+
/**
|
|
1215
|
+
* Collapse the entry inputs to a first-appearance-unique list for cross-entry
|
|
1216
|
+
* upload dedupe: two entries sourcing the SAME input (by {@link inputIdentity})
|
|
1217
|
+
* upload ONCE and share the fileId. Returns the ordered `uniqueInputs` plus an
|
|
1218
|
+
* `entryToUnique` index map (length N, entry order) so {@link run} can expand
|
|
1219
|
+
* the unique fileIds back to one-per-entry before {@link toWorkflowPayload} —
|
|
1220
|
+
* keeping the b{i} refs + {@link keyByRef} N-length and correctness-neutral.
|
|
1221
|
+
*/
|
|
1222
|
+
private planUploads;
|
|
1223
|
+
/** Map each `b{i}` job ref to that entry's caller key (validated non-empty). */
|
|
1224
|
+
private keyByRef;
|
|
1225
|
+
}
|
|
1008
1226
|
export {};
|