@sanity/workflow-engine 0.16.0 → 0.17.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/CHANGELOG.md +43 -0
- package/DATAMODEL.md +104 -29
- package/dist/_chunks-cjs/invariants.cjs +420 -120
- package/dist/_chunks-es/invariants.js +389 -121
- package/dist/define.d.cts +35 -12
- package/dist/define.d.ts +35 -12
- package/dist/index.cjs +4034 -2714
- package/dist/index.d.cts +737 -131
- package/dist/index.d.ts +737 -131
- package/dist/index.js +3994 -2731
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { analyzeCondition } from "@sanity/groq-condition-describe";
|
|
2
2
|
import { AtomInsight } from "@sanity/groq-condition-describe";
|
|
3
|
+
import { atomReadsDataset } from "@sanity/groq-condition-describe";
|
|
3
4
|
import { AtomRequirement } from "@sanity/groq-condition-describe";
|
|
4
5
|
import { checklistLines as checklistLines_2 } from "@sanity/groq-condition-describe";
|
|
5
6
|
import { ComparisonOp } from "@sanity/groq-condition-describe";
|
|
@@ -312,6 +313,13 @@ declare const ACTIVITY_STATUSES: readonly [
|
|
|
312
313
|
"failed",
|
|
313
314
|
];
|
|
314
315
|
|
|
316
|
+
/** The activity slice of a stage rollup — total by construction, like
|
|
317
|
+
* {@link stageAutonomyOf}. */
|
|
318
|
+
export declare function activityAutonomyOf(
|
|
319
|
+
stageAutonomy: StageAutonomy,
|
|
320
|
+
activityName: string,
|
|
321
|
+
): AutonomyAnswer;
|
|
322
|
+
|
|
315
323
|
/** An activity's gates, each described — absent keys mirror undeclared gates. */
|
|
316
324
|
export declare interface ActivityDescription {
|
|
317
325
|
requirements?: Record<string, ConditionDescription>;
|
|
@@ -360,11 +368,19 @@ export declare interface ActivityEvaluation {
|
|
|
360
368
|
*/
|
|
361
369
|
kind: ActivityKind;
|
|
362
370
|
/**
|
|
363
|
-
* Who, if anyone, the activity
|
|
371
|
+
* Who, if anyone, fires the activity's actions — derived from its shape
|
|
364
372
|
* alone: `autonomous` (every action cascade-fired), `interactive` (only
|
|
365
373
|
* fireAction-fired actions), `off-system` (`target` present), or `hybrid`.
|
|
366
374
|
*/
|
|
367
375
|
classification: ExecutorClassification;
|
|
376
|
+
/**
|
|
377
|
+
* The causal refinement of {@link ActivityEvaluation.classification}:
|
|
378
|
+
* whether this activity completes without a caller, derived by
|
|
379
|
+
* {@link deriveWorkflowAutonomy}'s dataflow over the definition — a
|
|
380
|
+
* mechanically `autonomous` activity whose triggers only read
|
|
381
|
+
* caller-written state still reports the caller it waits on.
|
|
382
|
+
*/
|
|
383
|
+
autonomy: AutonomyAnswer;
|
|
368
384
|
/** Whether this activity is the current actor's responsibility right now. */
|
|
369
385
|
pendingOnActor: boolean;
|
|
370
386
|
/**
|
|
@@ -445,9 +461,9 @@ export declare type ActorKind = (typeof ACTOR_KINDS)[number];
|
|
|
445
461
|
|
|
446
462
|
export { analyzeCondition };
|
|
447
463
|
|
|
448
|
-
/** The definition surface
|
|
464
|
+
/** The definition surface the start contexts read — structural, so authored,
|
|
449
465
|
* stored, and deployed definition shapes all fit. `name` binds
|
|
450
|
-
* `$definition` and names the definition in a broken-
|
|
466
|
+
* `$definition` and names the definition in a broken-predicate error. */
|
|
451
467
|
export declare interface ApplicabilitySource {
|
|
452
468
|
name?: string | undefined;
|
|
453
469
|
lifecycle?: WorkflowLifecycle | undefined;
|
|
@@ -456,6 +472,7 @@ export declare interface ApplicabilitySource {
|
|
|
456
472
|
| {
|
|
457
473
|
kind?: StartKind | undefined;
|
|
458
474
|
filter?: string | undefined;
|
|
475
|
+
allowed?: string | undefined;
|
|
459
476
|
}
|
|
460
477
|
| undefined;
|
|
461
478
|
}
|
|
@@ -470,7 +487,7 @@ export declare function applicableDefinitions<
|
|
|
470
487
|
definitions: readonly T[];
|
|
471
488
|
document: CandidateDocument;
|
|
472
489
|
/** Caller-side filter bindings, shared by every definition's evaluation. */
|
|
473
|
-
scope?:
|
|
490
|
+
scope?: StartScope;
|
|
474
491
|
}): Promise<T[]>;
|
|
475
492
|
|
|
476
493
|
/**
|
|
@@ -511,6 +528,8 @@ export declare type Assignee =
|
|
|
511
528
|
|
|
512
529
|
export { AtomInsight };
|
|
513
530
|
|
|
531
|
+
export { atomReadsDataset };
|
|
532
|
+
|
|
514
533
|
export { AtomRequirement };
|
|
515
534
|
|
|
516
535
|
/**
|
|
@@ -607,6 +626,11 @@ export declare type AuthoringGuard = v.InferOutput<typeof AuthoringGuardSchema>;
|
|
|
607
626
|
|
|
608
627
|
declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
609
628
|
{
|
|
629
|
+
/**
|
|
630
|
+
* Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
|
|
631
|
+
* guard's lake `_id` derives from `(instanceId, name)` at stage entry.
|
|
632
|
+
* Unique per definition.
|
|
633
|
+
*/
|
|
610
634
|
name: v.SchemaWithPipe<
|
|
611
635
|
readonly [
|
|
612
636
|
v.StringSchema<undefined>,
|
|
@@ -768,8 +792,9 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
|
768
792
|
/**
|
|
769
793
|
* Lake GROQ predicate — a distinct eval context: delta-mode GROQ
|
|
770
794
|
* reading the `before()`/`after()` natives, `mutation`, `guard`, and
|
|
771
|
-
* `identity()`. Bare ids/fields only.
|
|
772
|
-
*
|
|
795
|
+
* `identity()`. Bare ids/fields only. Polarity: a result of strictly
|
|
796
|
+
* `true` ALLOWS the matched mutation; anything else (false, null, an
|
|
797
|
+
* evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
|
|
773
798
|
*/
|
|
774
799
|
predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
775
800
|
/**
|
|
@@ -1221,6 +1246,85 @@ export declare type AuthoringWorkflow = WorkflowFields<
|
|
|
1221
1246
|
AuthoringStartBlock
|
|
1222
1247
|
>;
|
|
1223
1248
|
|
|
1249
|
+
/** The narratable answer at one rollup level: the verdict plus what it waits
|
|
1250
|
+
* on. `waitsOn` may be non-empty on a `yes` verdict (an effect settle is a
|
|
1251
|
+
* wait the engine resolves itself) — consumers choose what to surface. */
|
|
1252
|
+
export declare interface AutonomyAnswer {
|
|
1253
|
+
completesWithoutCaller: AutonomyVerdict;
|
|
1254
|
+
waitsOn: AutonomyWait[];
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
/** The workflow-level autonomy narrative: fully self-running, or the stages
|
|
1258
|
+
* where a run is held. */
|
|
1259
|
+
export declare function autonomySummary(
|
|
1260
|
+
autonomy: WorkflowAutonomy,
|
|
1261
|
+
ctx: DescribeContext,
|
|
1262
|
+
): InsightPhrase;
|
|
1263
|
+
|
|
1264
|
+
/**
|
|
1265
|
+
* Whether a node resolves without a caller: `yes` — engine machinery alone
|
|
1266
|
+
* (the cascade plus the host's effect drain/ticker) gets it there; `no` —
|
|
1267
|
+
* someone outside the engine must act (a caller fires an action, an editor
|
|
1268
|
+
* writes a field or content); `conditional` — it may resolve either way
|
|
1269
|
+
* depending on values the analysis can't see (start-time seeds, mixed
|
|
1270
|
+
* alternative routes, unresolvable children, cyclic gates).
|
|
1271
|
+
*
|
|
1272
|
+
* `yes` still leans on the host: effects settle only if a drain runs, and
|
|
1273
|
+
* time only passes for a ticker. A cascade-fired action's `roles` pin is a
|
|
1274
|
+
* DEPENDENCY, not an assumption — the runtime leaves a pinned trigger armed
|
|
1275
|
+
* until a capable token cascades, and whether the deployment's tokens fulfil
|
|
1276
|
+
* the pin is configuration the analysis can't see, so a pinned trigger
|
|
1277
|
+
* reports `conditional` with the pin as its wait.
|
|
1278
|
+
*/
|
|
1279
|
+
export declare type AutonomyVerdict = "yes" | "no" | "conditional";
|
|
1280
|
+
|
|
1281
|
+
/** One narratable dependency a non-`yes` verdict rests on. */
|
|
1282
|
+
export declare type AutonomyWait =
|
|
1283
|
+
| {
|
|
1284
|
+
kind: "caller-action";
|
|
1285
|
+
stage: string;
|
|
1286
|
+
activity: string;
|
|
1287
|
+
action: string;
|
|
1288
|
+
roles?: string[];
|
|
1289
|
+
}
|
|
1290
|
+
| {
|
|
1291
|
+
kind: "execute-pin";
|
|
1292
|
+
stage: string;
|
|
1293
|
+
activity: string;
|
|
1294
|
+
action: string;
|
|
1295
|
+
roles: string[];
|
|
1296
|
+
}
|
|
1297
|
+
| {
|
|
1298
|
+
kind: "editor-field";
|
|
1299
|
+
field: string;
|
|
1300
|
+
}
|
|
1301
|
+
| {
|
|
1302
|
+
kind: "editor-content";
|
|
1303
|
+
condition: Condition;
|
|
1304
|
+
}
|
|
1305
|
+
| {
|
|
1306
|
+
kind: "effect";
|
|
1307
|
+
effect: string;
|
|
1308
|
+
}
|
|
1309
|
+
| {
|
|
1310
|
+
kind: "start-input";
|
|
1311
|
+
field: string;
|
|
1312
|
+
}
|
|
1313
|
+
| {
|
|
1314
|
+
kind: "context";
|
|
1315
|
+
key?: string;
|
|
1316
|
+
}
|
|
1317
|
+
| {
|
|
1318
|
+
kind: "subworkflow";
|
|
1319
|
+
definition: string;
|
|
1320
|
+
resolved: boolean;
|
|
1321
|
+
}
|
|
1322
|
+
| {
|
|
1323
|
+
kind: "unwritten-field";
|
|
1324
|
+
field: string;
|
|
1325
|
+
handlerPossible: boolean;
|
|
1326
|
+
};
|
|
1327
|
+
|
|
1224
1328
|
export declare interface AvailableAction {
|
|
1225
1329
|
activity: string;
|
|
1226
1330
|
activityStatus: ActivityStatus;
|
|
@@ -1648,11 +1752,14 @@ export declare interface ConditionVar {
|
|
|
1648
1752
|
* the rest evaluate to `undefined` — and deploy rejects them at these
|
|
1649
1753
|
* sites; a cascade-fired action's per-token gate is `roles`, never its
|
|
1650
1754
|
* conditions.
|
|
1651
|
-
* 3. **The start
|
|
1652
|
-
* against a CANDIDATE (no instance exists yet):
|
|
1653
|
-
* the
|
|
1654
|
-
*
|
|
1655
|
-
*
|
|
1755
|
+
* 3. **The start contexts** — a definition's `start.filter` and
|
|
1756
|
+
* `start.allowed` evaluate against a CANDIDATE (no instance exists yet):
|
|
1757
|
+
* `*[...]` reads the WORKFLOW resource's dataset and none of the rendered
|
|
1758
|
+
* condition vars exist. The two split on what a surface can know:
|
|
1759
|
+
* `filter` is browse-time-pure (candidate document as root,
|
|
1760
|
+
* {@link START_FILTER_VARS} — no `$fields`, which cannot exist before
|
|
1761
|
+
* inputs do), `allowed` is the start-time permission predicate
|
|
1762
|
+
* ({@link START_ALLOWED_VARS} — `$fields` bound, never a root).
|
|
1656
1763
|
* 4. **Guard predicates** — NOT conditions. A lake mutation guard's
|
|
1657
1764
|
* `predicate` is groq-js **delta-mode** GROQ over a document mutation:
|
|
1658
1765
|
* `before()`/`after()`/`identity()` are dialect natives, and the wire
|
|
@@ -1666,7 +1773,7 @@ export declare interface ConditionVar {
|
|
|
1666
1773
|
* instance and its snapshot.
|
|
1667
1774
|
* - `'caller'` — rides the acting caller; without one the var is `undefined`
|
|
1668
1775
|
* (conditions referencing it fail closed). Author predicates may not read
|
|
1669
|
-
* these — they pre-evaluate
|
|
1776
|
+
* these — they pre-evaluate caller-free, per evaluation context.
|
|
1670
1777
|
* - `'spawn'` — bound only at spawn sites (the per-row `$row`).
|
|
1671
1778
|
*/
|
|
1672
1779
|
export declare type ConditionVarBinding = "always" | "caller" | "spawn";
|
|
@@ -1808,10 +1915,11 @@ export declare function contextMap(
|
|
|
1808
1915
|
|
|
1809
1916
|
/**
|
|
1810
1917
|
* A caller broke a public-API contract — a call the engine rejects
|
|
1811
|
-
*
|
|
1918
|
+
* without writing anything: an invalid `tag`, a `workflow.query` GROQ that
|
|
1812
1919
|
* never binds `$tag`, a bare id where a GDR URI is required, an action,
|
|
1813
|
-
* activity, or field the definition never declared
|
|
1814
|
-
*
|
|
1920
|
+
* activity, or field the definition never declared, or a `startInstance`
|
|
1921
|
+
* `instanceId` reused for a different start (or a discarded one). Fix the
|
|
1922
|
+
* call site; retrying cannot succeed.
|
|
1815
1923
|
*/
|
|
1816
1924
|
export declare class ContractViolationError extends WorkflowError<"contract-violation"> {
|
|
1817
1925
|
constructor(message: string);
|
|
@@ -2229,11 +2337,13 @@ export declare interface DeployDefinitionsArgs<
|
|
|
2229
2337
|
> {
|
|
2230
2338
|
/**
|
|
2231
2339
|
* Resource-alias bindings for this deploy (alias name → physical resource).
|
|
2232
|
-
*
|
|
2233
|
-
*
|
|
2234
|
-
*
|
|
2235
|
-
*
|
|
2236
|
-
*
|
|
2340
|
+
* A deploy-time abstraction ONLY: every `@<alias>:` reference in a
|
|
2341
|
+
* definition is expanded to its bound physical resource before the
|
|
2342
|
+
* deployed definition is fingerprinted and stored, and deploy fails closed
|
|
2343
|
+
* on an unbound alias. Aliases never exist past deploy — no stored
|
|
2344
|
+
* document carries one, the runtime never sees the map, and an
|
|
2345
|
+
* alias-shaped ref reaching a runtime boundary is rejected as malformed.
|
|
2346
|
+
* Omit for single-resource workflows (definitions referencing no aliases).
|
|
2237
2347
|
*/
|
|
2238
2348
|
resourceAliases?: ResourceAliases;
|
|
2239
2349
|
/** Authored definitions (the default — full compile-time checking) or
|
|
@@ -2308,18 +2418,37 @@ export declare interface DeployTarget {
|
|
|
2308
2418
|
*/
|
|
2309
2419
|
export declare function deriveActivityKind(activity: Activity): ActivityKind;
|
|
2310
2420
|
|
|
2421
|
+
export declare interface DeriveAutonomyOptions {
|
|
2422
|
+
/** Child definitions for `spawn` recursion, by definition `name` — the
|
|
2423
|
+
* deploy batch or previously deployed set. An unresolvable child reports
|
|
2424
|
+
* `conditional` with an unresolved wait. */
|
|
2425
|
+
children?: ReadonlyMap<string, WorkflowDefinition>;
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2311
2428
|
/**
|
|
2312
|
-
* Who, if anyone, the activity
|
|
2313
|
-
*
|
|
2314
|
-
* (every action cascade-fired — no caller
|
|
2315
|
-
* fireAction-fired actions), or `hybrid` (mixed). An
|
|
2316
|
-
* classifies `autonomous` vacuously
|
|
2317
|
-
* terminal-reachability invariant rejects it anyway).
|
|
2429
|
+
* Who, if anyone, fires the activity's actions — derived ahead-of-time from
|
|
2430
|
+
* the activity's shape alone: `off-system` when `target` is present; else
|
|
2431
|
+
* `autonomous` (every action cascade-fired — no caller fires anything),
|
|
2432
|
+
* `interactive` (only fireAction-fired actions), or `hybrid` (mixed). An
|
|
2433
|
+
* actionless activity classifies `autonomous` vacuously (deploy's
|
|
2434
|
+
* terminal-reachability invariant rejects it anyway). Shape-only: whether
|
|
2435
|
+
* the activity actually RESOLVES without a caller is the causal question
|
|
2436
|
+
* `deriveWorkflowAutonomy` answers.
|
|
2318
2437
|
*/
|
|
2319
2438
|
export declare function deriveExecutorClassification(
|
|
2320
2439
|
activity: Activity,
|
|
2321
2440
|
): ExecutorClassification;
|
|
2322
2441
|
|
|
2442
|
+
/**
|
|
2443
|
+
* Derive the causal autonomy of a stored definition. Pure and instance-free;
|
|
2444
|
+
* conditions must parse (they did at define/deploy time — an unparseable one
|
|
2445
|
+
* throws groq-js's syntax error rather than guessing).
|
|
2446
|
+
*/
|
|
2447
|
+
export declare function deriveWorkflowAutonomy(
|
|
2448
|
+
definition: WorkflowDefinition,
|
|
2449
|
+
options?: DeriveAutonomyOptions,
|
|
2450
|
+
): WorkflowAutonomy;
|
|
2451
|
+
|
|
2323
2452
|
export declare type Describable =
|
|
2324
2453
|
| ConditionInsight
|
|
2325
2454
|
| FieldInsight
|
|
@@ -2337,6 +2466,12 @@ export declare function describeAtom(
|
|
|
2337
2466
|
fallback: boolean;
|
|
2338
2467
|
};
|
|
2339
2468
|
|
|
2469
|
+
/** One {@link AutonomyWait} as a phrase in the workflow vocabulary. */
|
|
2470
|
+
export declare function describeAutonomyWait(
|
|
2471
|
+
wait: AutonomyWait,
|
|
2472
|
+
ctx: DescribeContext,
|
|
2473
|
+
): InsightPhrase;
|
|
2474
|
+
|
|
2340
2475
|
/** Render one condition's insight as a checklist + frontier summary, in the
|
|
2341
2476
|
* workflow vocabulary. */
|
|
2342
2477
|
export declare function describeCondition(
|
|
@@ -2920,6 +3055,15 @@ export declare type EditMode = "set" | "append" | "unset";
|
|
|
2920
3055
|
|
|
2921
3056
|
export declare type Effect = v.InferOutput<typeof EffectSchema>;
|
|
2922
3057
|
|
|
3058
|
+
/**
|
|
3059
|
+
* Every terminal state an effect run can record. `done` and `failed` are
|
|
3060
|
+
* reported through completion ({@link EffectCompletionStatus}); `cancelled`
|
|
3061
|
+
* is engine-stamped only — an abort cancelling the entry before dispatch.
|
|
3062
|
+
* A cancellation is not a failure: anything counting failures (dashboards,
|
|
3063
|
+
* retry tooling) must not count aborted-away effects among them.
|
|
3064
|
+
*/
|
|
3065
|
+
declare const EFFECT_RUN_STATUSES: readonly ["done", "failed", "cancelled"];
|
|
3066
|
+
|
|
2923
3067
|
/** The outcomes a completer may report through `completeEffect` — a run
|
|
2924
3068
|
* either succeeded or failed. `cancelled` is not reportable: only an abort
|
|
2925
3069
|
* stamps it, on entries that never dispatched. */
|
|
@@ -3095,14 +3239,7 @@ export declare function effectOutputsMap(
|
|
|
3095
3239
|
instance: Pick<WorkflowInstance, "effectHistory">,
|
|
3096
3240
|
): Record<string, unknown>;
|
|
3097
3241
|
|
|
3098
|
-
|
|
3099
|
-
* Every terminal state an effect run can record. `done` and `failed` are
|
|
3100
|
-
* reported through completion ({@link EffectCompletionStatus}); `cancelled`
|
|
3101
|
-
* is engine-stamped only — an abort cancelling the entry before dispatch.
|
|
3102
|
-
* A cancellation is not a failure: anything counting failures (dashboards,
|
|
3103
|
-
* retry tooling) must not count aborted-away effects among them.
|
|
3104
|
-
*/
|
|
3105
|
-
export declare type EffectRunStatus = "done" | "failed" | "cancelled";
|
|
3242
|
+
export declare type EffectRunStatus = (typeof EFFECT_RUN_STATUSES)[number];
|
|
3106
3243
|
|
|
3107
3244
|
declare const EffectSchema: v.StrictObjectSchema<
|
|
3108
3245
|
{
|
|
@@ -3257,18 +3394,30 @@ export declare interface Engine {
|
|
|
3257
3394
|
/** The startable half of {@link Engine.instancesForDocument}: the latest
|
|
3258
3395
|
* deployed version of every definition that applies to the LOADED candidate
|
|
3259
3396
|
* document — startable, a required subject entry accepts its `_type`, and
|
|
3260
|
-
* `start.filter`
|
|
3261
|
-
* picker's filter, never
|
|
3397
|
+
* `start.filter` (browse-time-pure — `$fields` never binds) passes. All
|
|
3398
|
+
* matches, name ascending; advisory — a start picker's filter, never
|
|
3399
|
+
* enforcement. */
|
|
3262
3400
|
definitionsForDocument: (
|
|
3263
3401
|
args: DefinitionsForDocumentArgs,
|
|
3264
3402
|
) => Promise<DeployedDefinition[]>;
|
|
3403
|
+
/** Pre-flight `startInstance`'s gates for a definition + the
|
|
3404
|
+
* `initialFields` gathered so far: the `start.allowed` verdict with its
|
|
3405
|
+
* insight (disable the start affordance on a definitive false AND say
|
|
3406
|
+
* why) plus the still-missing required inputs. Bindability-aware — a
|
|
3407
|
+
* predicate reading a not-yet-supplied entry reports `'unevaluable'`
|
|
3408
|
+
* with the entries named in `unboundReads`, never a collapsed verdict.
|
|
3409
|
+
* Pure read; the enforcement moment is `startInstance` itself. */
|
|
3410
|
+
evaluateStart: (args: EvaluateStartArgs) => Promise<StartEvaluation>;
|
|
3265
3411
|
/** GROQ query against the engine's workflow resource. `$tag`
|
|
3266
3412
|
* is bound for tag-scoped filtering. */
|
|
3267
3413
|
query: <T = unknown>(args: QueryArgs) => Promise<T>;
|
|
3268
3414
|
/** Snapshot-aware GROQ — runs against the same in-memory view the
|
|
3269
|
-
* engine's filters see for the supplied instance. The
|
|
3270
|
-
*
|
|
3271
|
-
*
|
|
3415
|
+
* engine's filters see for the supplied instance. The caller-free
|
|
3416
|
+
* rendered scope cascade gates evaluate in is bound — the
|
|
3417
|
+
* instance-derived vars ({@link FILTER_SCOPE_VARS}) with the open
|
|
3418
|
+
* stage's overlay merged into `$fields`, `$assigned` at its caller-free
|
|
3419
|
+
* `false`, plus the author's pre-evaluated `$<predicate>` booleans —
|
|
3420
|
+
* ids in GDR URI form to match the snapshot's keying. */
|
|
3272
3421
|
queryInScope: <T = unknown>(args: QueryInScopeArgs) => Promise<T>;
|
|
3273
3422
|
/** List every pending effect on an instance. */
|
|
3274
3423
|
listPendingEffects: (args: InstanceRefArgs) => Promise<PendingEffect[]>;
|
|
@@ -3347,8 +3496,9 @@ export declare interface EngineScopeArgs {
|
|
|
3347
3496
|
* docs that live in a different Sanity resource than the workflow). Called
|
|
3348
3497
|
* with a parsed GDR; return a client for that resource, or undefined to let
|
|
3349
3498
|
* the engine route it — `client` for the workflow resource itself, a
|
|
3350
|
-
* sibling derived from `client`'s credentials for anything else.
|
|
3351
|
-
*
|
|
3499
|
+
* sibling derived from `client`'s credentials for anything else. A served
|
|
3500
|
+
* resource is also part of the declared surface for runtime-supplied refs.
|
|
3501
|
+
* Engine-scope configuration — see `CreateEngineArgs`.
|
|
3352
3502
|
*/
|
|
3353
3503
|
resourceClients?: ResourceClientResolver;
|
|
3354
3504
|
/**
|
|
@@ -3368,6 +3518,16 @@ export declare interface EngineScopeArgs {
|
|
|
3368
3518
|
idempotencyTtlMs?: number;
|
|
3369
3519
|
}
|
|
3370
3520
|
|
|
3521
|
+
/**
|
|
3522
|
+
* Pull the {@link GlobalDocumentReference} values out of `doc.ref` /
|
|
3523
|
+
* `doc.refs` (content) field entries. Content only — release field entries come
|
|
3524
|
+
* from {@link entryReleaseRefs}, so guard discovery (which reads this via
|
|
3525
|
+
* `collectEntryDocUris`) stays scoped to content docs.
|
|
3526
|
+
*/
|
|
3527
|
+
export declare function entryDocRefs(
|
|
3528
|
+
entries: unknown,
|
|
3529
|
+
): GlobalDocumentReference[];
|
|
3530
|
+
|
|
3371
3531
|
/**
|
|
3372
3532
|
* Pure error helpers — no client, no I/O. The one home for the engine's
|
|
3373
3533
|
* "coerce an unknown caught value" + "rethrow with context" idioms, so the
|
|
@@ -3465,10 +3625,30 @@ export declare function evaluateMutationGuard(args: {
|
|
|
3465
3625
|
context: MutationContext;
|
|
3466
3626
|
}): Promise<boolean>;
|
|
3467
3627
|
|
|
3628
|
+
/** Args for `evaluateStart` — the pre-flight read of `startInstance`'s gates
|
|
3629
|
+
* for a definition + the `initialFields` gathered so far (possibly none). */
|
|
3630
|
+
export declare interface EvaluateStartArgs {
|
|
3631
|
+
/** The definition's `name` — which deployed workflow would be started. */
|
|
3632
|
+
definition: string;
|
|
3633
|
+
/** Optional explicit version. Defaults to the highest deployed version. */
|
|
3634
|
+
version?: number;
|
|
3635
|
+
/**
|
|
3636
|
+
* The candidate seed, in `StartInstanceArgs.initialFields` shape. Partial
|
|
3637
|
+
* mid-form input is expected and safe: the verdict is BINDABILITY-AWARE —
|
|
3638
|
+
* when the predicate reads a declared entry these inputs don't supply,
|
|
3639
|
+
* `outcome` reports `'unevaluable'` and {@link StartEvaluation.unboundReads}
|
|
3640
|
+
* names the entries, instead of the collapsed answer GROQ equality would
|
|
3641
|
+
* otherwise produce (`null == x` is false, not null — a definitive-looking
|
|
3642
|
+
* verdict one more input could overturn, in either direction).
|
|
3643
|
+
*/
|
|
3644
|
+
initialFields?: InitialFieldValue[];
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3468
3647
|
/**
|
|
3469
|
-
* Evaluate one `start.filter` in the start-filter context: `document` (may
|
|
3470
|
-
* absent — root
|
|
3471
|
-
* {@link
|
|
3648
|
+
* Evaluate one `start.filter` in the start-filter context: `document` (may
|
|
3649
|
+
* be absent — a root read is then GROQ null, fail-closed or vacuous-pass by
|
|
3650
|
+
* shape) as the GROQ root, the {@link StartScope} bindings plus
|
|
3651
|
+
* `$definition`, and — only when
|
|
3472
3652
|
* `analyzeCondition` says the filter reads the dataset — the scope's fetched
|
|
3473
3653
|
* slice as `*`. Cheap pure evaluation otherwise: no I/O rides a filter that
|
|
3474
3654
|
* never scans. GROQ null ("can't decide") is `false` — every consumer of
|
|
@@ -3482,7 +3662,7 @@ export declare function evaluateStartFilter(args: {
|
|
|
3482
3662
|
filter: string;
|
|
3483
3663
|
definition: Pick<ApplicabilitySource, "name">;
|
|
3484
3664
|
document?: CandidateDocument | undefined;
|
|
3485
|
-
scope?:
|
|
3665
|
+
scope?: StartScope | undefined;
|
|
3486
3666
|
}): Promise<boolean>;
|
|
3487
3667
|
|
|
3488
3668
|
/**
|
|
@@ -3532,8 +3712,8 @@ export declare interface ExecutionContext {
|
|
|
3532
3712
|
}
|
|
3533
3713
|
|
|
3534
3714
|
/**
|
|
3535
|
-
* Executor classifications — who, if anyone, an activity
|
|
3536
|
-
* (derived; see `./activity-kind.ts`).
|
|
3715
|
+
* Executor classifications — who, if anyone, fires an activity's actions
|
|
3716
|
+
* (shape-derived; see `./activity-kind.ts`).
|
|
3537
3717
|
*/
|
|
3538
3718
|
export declare const EXECUTOR_CLASSIFICATION_DISPLAY: {
|
|
3539
3719
|
autonomous: {
|
|
@@ -3568,6 +3748,35 @@ export { explainCondition };
|
|
|
3568
3748
|
|
|
3569
3749
|
export { ExplainConditionArgs };
|
|
3570
3750
|
|
|
3751
|
+
/**
|
|
3752
|
+
* Explain one `start.allowed` in the start-allowed context: no root (the
|
|
3753
|
+
* subject rides `$fields.<entry>.id` — deploy rejects a root read), the
|
|
3754
|
+
* {@link StartScope} bindings plus `$definition` and the caller's `$fields`
|
|
3755
|
+
* map, and the scope's fetched slice as `*` when the predicate reads the
|
|
3756
|
+
* dataset. Returns the full {@link ConditionInsight} — `outcome` is the
|
|
3757
|
+
* verdict (`'satisfied'` allows; `'unsatisfied'`/`'unevaluable'` refuse,
|
|
3758
|
+
* fail-closed) and the atom breakdown is what lets a surface disable its
|
|
3759
|
+
* start affordance AND say why. One evaluator serves both moments:
|
|
3760
|
+
* `startInstance` enforces the outcome, the `evaluateStart` verb pre-flights
|
|
3761
|
+
* it.
|
|
3762
|
+
*
|
|
3763
|
+
* A dataset-reading predicate with no slice provider THROWS instead of
|
|
3764
|
+
* failing closed: unlike a picker that merely hides a row, this verdict
|
|
3765
|
+
* refuses starts — evaluating over an empty `*` would let a `count()`-style
|
|
3766
|
+
* rule pass vacuously, and a silent "not allowed" would misreport a caller
|
|
3767
|
+
* bug as an author verdict. Parse/evaluation throws rethrow naming the
|
|
3768
|
+
* definition, like the filter's; a failed slice FETCH propagates as itself.
|
|
3769
|
+
*/
|
|
3770
|
+
export declare function explainStartAllowed(args: {
|
|
3771
|
+
allowed: string;
|
|
3772
|
+
definition: Pick<ApplicabilitySource, "name">;
|
|
3773
|
+
/** The caller's input entries as a `$fields` map — the engine verbs build
|
|
3774
|
+
* it with `startFieldsParam` (field resolution's projection), so the
|
|
3775
|
+
* predicate can only see values the resolution would persist. */
|
|
3776
|
+
fields: Record<string, unknown>;
|
|
3777
|
+
scope?: StartScope | undefined;
|
|
3778
|
+
}): Promise<ConditionInsight>;
|
|
3779
|
+
|
|
3571
3780
|
/**
|
|
3572
3781
|
* Extract the bare document `_id` from a GDR URI — what
|
|
3573
3782
|
* `*[_id == $docId]` in GROQ needs.
|
|
@@ -3987,6 +4196,35 @@ export declare function gdrUri(
|
|
|
3987
4196
|
): GdrUri;
|
|
3988
4197
|
|
|
3989
4198
|
/**
|
|
4199
|
+
* The engine's reference value — deliberately NOT a lake reference, and
|
|
4200
|
+
* spelled differently on purpose (`id`/`type`, never `_ref`/`_id`):
|
|
4201
|
+
*
|
|
4202
|
+
* - **`id` is a URI, not a bare doc id**, because workflow references cross
|
|
4203
|
+
* resources (another dataset, a media library) and a bare `_id` is only
|
|
4204
|
+
* meaningful inside one dataset. Everything resource-aware — client
|
|
4205
|
+
* routing, spawn discovery, guard target resolution — reads the resource
|
|
4206
|
+
* out of this URI. It is stripped to a bare lake id at exactly one
|
|
4207
|
+
* boundary: `paramsForLake` (core/params.ts), when a query actually runs
|
|
4208
|
+
* against a lake.
|
|
4209
|
+
* - **`type` carries the target's schema type so consumers don't need a
|
|
4210
|
+
* fetch — as stamped by the ref's constructor, never verified against the
|
|
4211
|
+
* target.** Engine-built refs stamp it from real data (a projection row's
|
|
4212
|
+
* `_type`, the `releaseRef` constructor); a caller-supplied ref's `type`
|
|
4213
|
+
* is a trusted claim. Three advisory surfaces read it: the declared-subject-type
|
|
4214
|
+
* contract (an entry's `types: [...]` accepts/rejects incoming refs —
|
|
4215
|
+
* `refTypeIssues` at start `initialFields` and spawn `with`), start
|
|
4216
|
+
* applicability ("which definitions accept a doc of this `_type`" —
|
|
4217
|
+
* `acceptsDocumentType`), and guard `match.types` inference from resolved
|
|
4218
|
+
* targets (`resolveMatchTypes`). All must work when the target lives in a
|
|
4219
|
+
* resource the reader can't (or shouldn't) fetch from.
|
|
4220
|
+
*
|
|
4221
|
+
* In rendered GROQ this shape is what a reference-held value exposes
|
|
4222
|
+
* (`$fields.<entry>.id` / `.type`) — whereas `_id`/`_type` belong to
|
|
4223
|
+
* documents you hold (lake rows, `$row`, a dereferenced singular `doc.ref`).
|
|
4224
|
+
* The spelling is not a namespace guarantee: a content document can carry
|
|
4225
|
+
* its own `id`/`type` fields — what you're reading follows what the entry's
|
|
4226
|
+
* declared kind puts in your hand, never the key's spelling.
|
|
4227
|
+
*
|
|
3990
4228
|
* `TType` preserves the `type` literal the constructors ({@link refDataset},
|
|
3991
4229
|
* {@link gdrRef}, …) were called with, so a constructed ref satisfies
|
|
3992
4230
|
* literal-typed targets (e.g. a `release.ref` value's `"system.release"`).
|
|
@@ -4243,6 +4481,11 @@ declare const GuardReadSchema: v.VariantSchema<
|
|
|
4243
4481
|
/** Stored guards carry the printed string reads (the deploy resolver's input). */
|
|
4244
4482
|
declare const GuardSchema: v.StrictObjectSchema<
|
|
4245
4483
|
{
|
|
4484
|
+
/**
|
|
4485
|
+
* Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
|
|
4486
|
+
* guard's lake `_id` derives from `(instanceId, name)` at stage entry.
|
|
4487
|
+
* Unique per definition.
|
|
4488
|
+
*/
|
|
4246
4489
|
name: v.SchemaWithPipe<
|
|
4247
4490
|
readonly [
|
|
4248
4491
|
v.StringSchema<undefined>,
|
|
@@ -4314,8 +4557,9 @@ declare const GuardSchema: v.StrictObjectSchema<
|
|
|
4314
4557
|
/**
|
|
4315
4558
|
* Lake GROQ predicate — a distinct eval context: delta-mode GROQ
|
|
4316
4559
|
* reading the `before()`/`after()` natives, `mutation`, `guard`, and
|
|
4317
|
-
* `identity()`. Bare ids/fields only.
|
|
4318
|
-
*
|
|
4560
|
+
* `identity()`. Bare ids/fields only. Polarity: a result of strictly
|
|
4561
|
+
* `true` ALLOWS the matched mutation; anything else (false, null, an
|
|
4562
|
+
* evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
|
|
4319
4563
|
*/
|
|
4320
4564
|
predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
4321
4565
|
/**
|
|
@@ -4760,6 +5004,16 @@ export declare type InsightSite =
|
|
|
4760
5004
|
activity?: string;
|
|
4761
5005
|
};
|
|
4762
5006
|
|
|
5007
|
+
/**
|
|
5008
|
+
* Mint the Sanity document `_id` for a workflow instance — a fresh
|
|
5009
|
+
* {@link randomKey} suffix, so every instance (root or spawned child) gets a
|
|
5010
|
+
* unique doc id under its tag. Lives in the shell, not `core/`, because it
|
|
5011
|
+
* draws randomness; the deterministic {@link definitionDocId} is the pure-core
|
|
5012
|
+
* counterpart. Bare form — Sanity rejects `:` in document IDs, so this is
|
|
5013
|
+
* never a GDR URI.
|
|
5014
|
+
*/
|
|
5015
|
+
export declare function instanceDocId(tag: string): string;
|
|
5016
|
+
|
|
4763
5017
|
/**
|
|
4764
5018
|
* The per-instance guard filter — the single definition of "this instance's
|
|
4765
5019
|
* guards in one datasource". The engine's verdict load
|
|
@@ -4815,7 +5069,10 @@ export declare interface InstanceSession {
|
|
|
4815
5069
|
/** Replace the held content with the current values the consumer observed
|
|
4816
5070
|
* (last-write-wins, scoped). A self-doc updates the held instance only when
|
|
4817
5071
|
* its `_updatedAt` is strictly newer — an older or timestamp-equal echo is
|
|
4818
|
-
* ignored. Buffered if a commit is in flight
|
|
5072
|
+
* ignored. Buffered if a commit is in flight; a BUFFERED push that fails
|
|
5073
|
+
* validation surfaces on the NEXT `update` call (after that call's own
|
|
5074
|
+
* docs are processed), never from the commit itself — the commit's
|
|
5075
|
+
* outcome is never masked by a store echo's failure. */
|
|
4819
5076
|
update(docs: LoadedDoc[]): void;
|
|
4820
5077
|
/** Replace the held live guards (the consumer's guard stream,
|
|
4821
5078
|
* last-write-wins). Guards are a separate stream from the watch-set:
|
|
@@ -4858,10 +5115,11 @@ export declare interface InstanceSession {
|
|
|
4858
5115
|
* replace the target's staged rows (last write wins); appends accumulate.
|
|
4859
5116
|
* Tolerant where commits are loud: a target that doesn't resolve in the
|
|
4860
5117
|
* current stage (it moved under a mounted editor), a closed edit window
|
|
4861
|
-
* (a skipped activity's field),
|
|
4862
|
-
*
|
|
4863
|
-
* no echo, no throw; the commit at the
|
|
4864
|
-
* surface. Never persisted — commit via
|
|
5118
|
+
* (a skipped activity's field), a value that doesn't fit the field's
|
|
5119
|
+
* shape yet (a half-typed date), or a ref outside the declared resource
|
|
5120
|
+
* surface stages an INERT preview — no echo, no throw; the commit at the
|
|
5121
|
+
* semantic boundary is the loud surface. Never persisted — commit via
|
|
5122
|
+
* {@link InstanceSession.editField}. */
|
|
4865
5123
|
previewField(args: {
|
|
4866
5124
|
target: EditFieldTarget;
|
|
4867
5125
|
mode?: EditMode;
|
|
@@ -4879,8 +5137,10 @@ export declare interface InstancesForDocumentArgs {
|
|
|
4879
5137
|
|
|
4880
5138
|
/**
|
|
4881
5139
|
* The instance-list GROQ for a {@link InstancesQueryFilter}, ordered by
|
|
4882
|
-
* `startedAt` ascending
|
|
4883
|
-
*
|
|
5140
|
+
* `startedAt` ascending (descending + sliced under
|
|
5141
|
+
* {@link InstancesQueryFilter.limit}). Adapters subscribe to it;
|
|
5142
|
+
* {@link workflow.query}-style one-shot reads fetch it — both see the same
|
|
5143
|
+
* rows.
|
|
4884
5144
|
*/
|
|
4885
5145
|
export declare function instancesQuery(args: {
|
|
4886
5146
|
tag: string;
|
|
@@ -4924,6 +5184,14 @@ export declare interface InstancesQueryFilter {
|
|
|
4924
5184
|
stage?: string;
|
|
4925
5185
|
/** Include completed/aborted instances (default: in-flight only). */
|
|
4926
5186
|
includeCompleted?: boolean;
|
|
5187
|
+
/**
|
|
5188
|
+
* Cap the read to the NEWEST `limit` instances — the query flips to
|
|
5189
|
+
* `startedAt desc` and slices, so a bounded consumer (a dashboard over an
|
|
5190
|
+
* unbounded dataset) reads the most recent rows instead of the oldest.
|
|
5191
|
+
* Unlimited reads keep the ascending order adapters index by. Must be a
|
|
5192
|
+
* positive integer.
|
|
5193
|
+
*/
|
|
5194
|
+
limit?: number;
|
|
4927
5195
|
}
|
|
4928
5196
|
|
|
4929
5197
|
/**
|
|
@@ -4978,7 +5246,7 @@ export declare function isDefinitionApplicable(args: {
|
|
|
4978
5246
|
definition: ApplicabilitySource;
|
|
4979
5247
|
document: CandidateDocument;
|
|
4980
5248
|
/** Caller-side filter bindings — omit for the bare candidate-doc context. */
|
|
4981
|
-
scope?:
|
|
5249
|
+
scope?: StartScope;
|
|
4982
5250
|
}): Promise<boolean>;
|
|
4983
5251
|
|
|
4984
5252
|
/**
|
|
@@ -5098,6 +5366,19 @@ export declare function isTodoListEntry(
|
|
|
5098
5366
|
* as null). The remaining columns stay loose (field validation owns them). */
|
|
5099
5367
|
export declare function isTodoListItem(row: unknown): row is TodoListItem;
|
|
5100
5368
|
|
|
5369
|
+
/**
|
|
5370
|
+
* True when the instance document exists but its start never finished: the
|
|
5371
|
+
* `create` committed, yet priming (stage entry, activities, guard deploy)
|
|
5372
|
+
* did not. The shape is legal and resumable — `startInstance` with the same
|
|
5373
|
+
* `instanceId` completes the outstanding commits. Readers should present it
|
|
5374
|
+
* as an incomplete start, never as a normal run sitting at its initial
|
|
5375
|
+
* stage. Terminal instances are excluded: an aborted never-primed husk
|
|
5376
|
+
* reads as aborted, not as still-resumable.
|
|
5377
|
+
*/
|
|
5378
|
+
export declare function isUnprimed(
|
|
5379
|
+
instance: Pick<WorkflowInstance, "stages" | "completedAt" | "abortedAt">,
|
|
5380
|
+
): boolean;
|
|
5381
|
+
|
|
5101
5382
|
/**
|
|
5102
5383
|
* Deterministic id so deploy/retract are query-free and idempotent. Derived
|
|
5103
5384
|
* from the guard's authored `name` — an author-controlled handle that stays
|
|
@@ -5396,6 +5677,8 @@ export declare interface MutationGuardDoc extends MutationGuardBody {
|
|
|
5396
5677
|
_updatedAt?: string;
|
|
5397
5678
|
}
|
|
5398
5679
|
|
|
5680
|
+
export declare const MutationGuardDocSchema: v.GenericSchema<MutationGuardDoc>;
|
|
5681
|
+
|
|
5399
5682
|
export declare interface MutationGuardMatch {
|
|
5400
5683
|
types?: string[];
|
|
5401
5684
|
/** Bare document ids (resource-local; both published and `drafts.` forms). */
|
|
@@ -5404,6 +5687,14 @@ export declare interface MutationGuardMatch {
|
|
|
5404
5687
|
actions: MutationGuardAction[];
|
|
5405
5688
|
}
|
|
5406
5689
|
|
|
5690
|
+
/** Every wait narrated, de-duplicated by phrase: same-named actions on
|
|
5691
|
+
* sibling activities are distinct waits that tell one story — consumers
|
|
5692
|
+
* want one line per story, not one per site. */
|
|
5693
|
+
export declare function narrateAutonomyWaits(
|
|
5694
|
+
waits: readonly AutonomyWait[],
|
|
5695
|
+
ctx: DescribeContext,
|
|
5696
|
+
): string[];
|
|
5697
|
+
|
|
5407
5698
|
/** The default logger: emit nothing. The engine's twin of `@sanity/telemetry`'s `noopLogger`. */
|
|
5408
5699
|
export declare const noopTelemetry: WorkflowTelemetryLogger;
|
|
5409
5700
|
|
|
@@ -5555,6 +5846,23 @@ export declare interface ParsedGdr {
|
|
|
5555
5846
|
*/
|
|
5556
5847
|
export declare function parseGdr(uri: string): ParsedGdr;
|
|
5557
5848
|
|
|
5849
|
+
/**
|
|
5850
|
+
* Parse a fetched guard document, failing hard with a
|
|
5851
|
+
* {@link PersistedDocShapeError} naming the document and every offending
|
|
5852
|
+
* field. No model-version gate: the guard doc carries no stamp by design —
|
|
5853
|
+
* its `_type` cutover is its versioning event.
|
|
5854
|
+
*/
|
|
5855
|
+
export declare function parseGuardDocument(doc: unknown): MutationGuardDoc;
|
|
5856
|
+
|
|
5857
|
+
/**
|
|
5858
|
+
* Parse a fetched `sanity.workflow.instance` document, failing hard with a
|
|
5859
|
+
* {@link PersistedDocShapeError} naming the document and every offending
|
|
5860
|
+
* field. The caller's model-version gate (`assertReadableModel`) comes
|
|
5861
|
+
* FIRST — a doc from beyond the reader floor is a governed
|
|
5862
|
+
* `ModelVersionAheadError`, not a shape error.
|
|
5863
|
+
*/
|
|
5864
|
+
export declare function parseInstanceDocument(doc: unknown): WorkflowInstance;
|
|
5865
|
+
|
|
5558
5866
|
/**
|
|
5559
5867
|
* Parse a resource-shaped GDR (`<type>:<id>`, no document part) into the
|
|
5560
5868
|
* {@link WorkflowResource} it names. The one grammar for resource addresses —
|
|
@@ -5643,6 +5951,26 @@ export declare interface PendingEffectClaim {
|
|
|
5643
5951
|
leaseExpiresAt?: string;
|
|
5644
5952
|
}
|
|
5645
5953
|
|
|
5954
|
+
/**
|
|
5955
|
+
* A persisted engine-owned document failed its shape parse — the stored
|
|
5956
|
+
* field tree does not match what this engine's data model declares for the
|
|
5957
|
+
* doc type. Distinct from {@link ModelVersionAheadError} (a declared,
|
|
5958
|
+
* governed fence: upgrade the engine); this is UNGOVERNED corruption — a
|
|
5959
|
+
* document no conforming engine wrote — and the read fails hard instead of
|
|
5960
|
+
* letting the malformed value corrupt behavior downstream. The issues name
|
|
5961
|
+
* every offending field path.
|
|
5962
|
+
*/
|
|
5963
|
+
export declare class PersistedDocShapeError extends WorkflowError<"persisted-doc-shape"> {
|
|
5964
|
+
readonly documentId: string;
|
|
5965
|
+
readonly documentType: string;
|
|
5966
|
+
readonly issues: ValidationIssue[];
|
|
5967
|
+
constructor(args: {
|
|
5968
|
+
documentId: string;
|
|
5969
|
+
documentType: string;
|
|
5970
|
+
issues: ValidationIssue[];
|
|
5971
|
+
});
|
|
5972
|
+
}
|
|
5973
|
+
|
|
5646
5974
|
/**
|
|
5647
5975
|
* One row of the instance's idempotency ledger — a caller-supplied
|
|
5648
5976
|
* `idempotencyKey` a state-changing verb already committed under. Recorded in
|
|
@@ -5711,6 +6039,14 @@ export declare interface QueryInScopeArgs extends InstanceRefArgs, QueryArgs {}
|
|
|
5711
6039
|
|
|
5712
6040
|
export { quoted };
|
|
5713
6041
|
|
|
6042
|
+
/**
|
|
6043
|
+
* The one spelling of the instance read discipline — model gate
|
|
6044
|
+
* ({@link assertReadableModel}) first, shape parse
|
|
6045
|
+
* ({@link parseInstanceDocument}) second — shared by the point-read funnel
|
|
6046
|
+
* above and the list-read sites that fetch instance rows in bulk.
|
|
6047
|
+
*/
|
|
6048
|
+
export declare function readInstanceDoc(doc: SanityDocument): WorkflowInstance;
|
|
6049
|
+
|
|
5714
6050
|
/**
|
|
5715
6051
|
* Whether a watched ref reads RAW — never perspective-scoped. The
|
|
5716
6052
|
* instance, its ancestors, and its spawned children (all instance docs), and
|
|
@@ -5768,6 +6104,18 @@ export declare function refMediaLibrary<TType extends string = string>({
|
|
|
5768
6104
|
type,
|
|
5769
6105
|
}: ResourceRefArgs<TType>): GlobalDocumentReference<TType>;
|
|
5770
6106
|
|
|
6107
|
+
/**
|
|
6108
|
+
* Thrown when a field write carries a ref to a resource outside the
|
|
6109
|
+
* declared surface. The write does not commit; the engine has not mutated
|
|
6110
|
+
* state.
|
|
6111
|
+
*/
|
|
6112
|
+
export declare class RefResourceUndeclaredError extends WorkflowError<"ref-resource-undeclared"> {
|
|
6113
|
+
readonly entryType: string;
|
|
6114
|
+
readonly entryName: string;
|
|
6115
|
+
readonly issues: string[];
|
|
6116
|
+
constructor(args: { entryName: string; entryType: string; issues: string[] });
|
|
6117
|
+
}
|
|
6118
|
+
|
|
5771
6119
|
/**
|
|
5772
6120
|
* The GDR `type`s in a `doc.ref` / `doc.refs` value that the entry's declared
|
|
5773
6121
|
* accepted `types` reject — empty when the value conforms, the entry declares
|
|
@@ -5959,9 +6307,10 @@ export declare function resolveFieldEntry(
|
|
|
5959
6307
|
export declare type ResourceAliases = Record<string, WorkflowResource>;
|
|
5960
6308
|
|
|
5961
6309
|
/**
|
|
5962
|
-
* Collapse a deployment's `resourceAliases` bindings into the
|
|
5963
|
-
* {@link ResourceAliases} map (handle name → physical resource)
|
|
5964
|
-
*
|
|
6310
|
+
* Collapse a deployment's `resourceAliases` bindings into the
|
|
6311
|
+
* {@link ResourceAliases} map (handle name → physical resource) that
|
|
6312
|
+
* `deployDefinitions` expands `@<handle>:` references against. Deploy-time
|
|
6313
|
+
* only — the map never reaches any other verb.
|
|
5965
6314
|
*/
|
|
5966
6315
|
export declare function resourceAliasesToMap(
|
|
5967
6316
|
resourceAliases: WorkflowDeployment["resourceAliases"],
|
|
@@ -5974,6 +6323,10 @@ export declare function resourceAliasesToMap(
|
|
|
5974
6323
|
* engine route it — its own client for the workflow resource, a derived
|
|
5975
6324
|
* sibling ({@link WorkflowClient.withConfig}) for anything else.
|
|
5976
6325
|
*
|
|
6326
|
+
* Serving a resource also DECLARES it on the written-ref surface: the write
|
|
6327
|
+
* boundaries probe this resolver per ref, so narrowing a resolver rejects
|
|
6328
|
+
* refs to the resources it stops serving.
|
|
6329
|
+
*
|
|
5977
6330
|
* Resolved clients ride the engine's API version like every other engine
|
|
5978
6331
|
* client: the verb scope rebinds them onto `ENGINE_API_VERSION` when they
|
|
5979
6332
|
* carry {@link WorkflowClient.withConfig} (one without it is used as
|
|
@@ -6008,6 +6361,13 @@ declare interface ResourceRefArgs<TType extends string> {
|
|
|
6008
6361
|
type: TType;
|
|
6009
6362
|
}
|
|
6010
6363
|
|
|
6364
|
+
export declare interface ResourceSurface {
|
|
6365
|
+
/** True when the parsed GDR targets a declared resource. */
|
|
6366
|
+
allows: (parsed: ParsedGdr) => boolean;
|
|
6367
|
+
/** Prose rendering of the declared surface, for rejection messages. */
|
|
6368
|
+
description: string;
|
|
6369
|
+
}
|
|
6370
|
+
|
|
6011
6371
|
/**
|
|
6012
6372
|
* Retract every guard for a stage being exited (lift predicate to allow), but
|
|
6013
6373
|
* only once the instance has genuinely moved off that stage — or was aborted
|
|
@@ -6079,6 +6439,23 @@ declare const RoleAliasesSchema: v.RecordSchema<
|
|
|
6079
6439
|
undefined
|
|
6080
6440
|
>;
|
|
6081
6441
|
|
|
6442
|
+
/** Whether two workflow resources address the same place. */
|
|
6443
|
+
export declare function sameResource(
|
|
6444
|
+
a: WorkflowResource,
|
|
6445
|
+
b: WorkflowResource,
|
|
6446
|
+
): boolean;
|
|
6447
|
+
|
|
6448
|
+
/**
|
|
6449
|
+
* The DECLARED field tree of a runtime schema — every entry key (optional
|
|
6450
|
+
* keys marked `key?`), every enum vocabulary, every variant arm — walked out
|
|
6451
|
+
* of valibot's runtime shape. The declared twin of `fieldTreeShape` (which
|
|
6452
|
+
* walks a CONCRETE document): the model-surface gate pins persisted doc
|
|
6453
|
+
* types by what their schema declares, so an optional field no fixture
|
|
6454
|
+
* reaches is still ledger-visible. Recursive grammars (a field shape nesting
|
|
6455
|
+
* field shapes) close with a `'(circular)'` marker.
|
|
6456
|
+
*/
|
|
6457
|
+
export declare function schemaTreeShape(schema: v.GenericSchema): unknown;
|
|
6458
|
+
|
|
6082
6459
|
export { ScopeAssignment };
|
|
6083
6460
|
|
|
6084
6461
|
export { sentenceCase };
|
|
@@ -6123,6 +6500,21 @@ export declare type Stage = StageFields<
|
|
|
6123
6500
|
Editable
|
|
6124
6501
|
>;
|
|
6125
6502
|
|
|
6503
|
+
/** A stage's rollup: progress through any exit transition, plus each
|
|
6504
|
+
* activity's own completion answer. */
|
|
6505
|
+
export declare interface StageAutonomy extends AutonomyAnswer {
|
|
6506
|
+
stage: string;
|
|
6507
|
+
activities: Record<string, AutonomyAnswer>;
|
|
6508
|
+
}
|
|
6509
|
+
|
|
6510
|
+
/** The stage slice of a rollup. Total by construction — the rollup derives
|
|
6511
|
+
* from the same `definition.stages` consumers iterate, so a miss is an
|
|
6512
|
+
* engine bug worth failing loud on. */
|
|
6513
|
+
export declare function stageAutonomyOf(
|
|
6514
|
+
autonomy: WorkflowAutonomy,
|
|
6515
|
+
stageName: string,
|
|
6516
|
+
): StageAutonomy;
|
|
6517
|
+
|
|
6126
6518
|
export declare interface StageEntry {
|
|
6127
6519
|
_key: string;
|
|
6128
6520
|
name: StageName;
|
|
@@ -6138,6 +6530,9 @@ export declare interface StageEvaluation {
|
|
|
6138
6530
|
stage: Stage;
|
|
6139
6531
|
activities: ActivityEvaluation[];
|
|
6140
6532
|
transitions: TransitionEvaluation[];
|
|
6533
|
+
/** The stage's causal-autonomy rollup — will it progress without a caller,
|
|
6534
|
+
* and what does it wait on. Definition-derived, identical for every actor. */
|
|
6535
|
+
autonomy: StageAutonomy;
|
|
6141
6536
|
}
|
|
6142
6537
|
|
|
6143
6538
|
/** Type-mirror of {@link stageFields}, parameterised over field/activity/transition/guard/editable. */
|
|
@@ -6170,15 +6565,33 @@ declare interface StageGuardArgs {
|
|
|
6170
6565
|
|
|
6171
6566
|
export declare type StageName = string;
|
|
6172
6567
|
|
|
6568
|
+
/**
|
|
6569
|
+
* The vars a definition's `start.allowed` reads — the start-time permission
|
|
6570
|
+
* dialect: everything the filter context binds ({@link START_FILTER_VARS})
|
|
6571
|
+
* plus `$fields`, which start time always has. No candidate root ever binds
|
|
6572
|
+
* here (the subject rides `$fields.<entry>.id`; a root read is
|
|
6573
|
+
* deploy-rejected), so a false/GROQ-null verdict is genuinely fail-closed —
|
|
6574
|
+
* there is no unbound-binding ambiguity to caveat. Bound in one place:
|
|
6575
|
+
* `startContextParams` in the applicability evaluator.
|
|
6576
|
+
*/
|
|
6577
|
+
export declare const START_ALLOWED_VARS: readonly {
|
|
6578
|
+
name: string;
|
|
6579
|
+
description: string;
|
|
6580
|
+
}[];
|
|
6581
|
+
|
|
6173
6582
|
/**
|
|
6174
6583
|
* The vars a definition's `start.filter` reads — the start-filter dialect,
|
|
6175
6584
|
* not the rendered condition scope (no {@link ConditionVarBinding}: these
|
|
6176
6585
|
* bind only while the filter is evaluated on the READ side — the
|
|
6177
6586
|
* `definitionsForDocument` derivation and the Studio start control).
|
|
6178
|
-
* `startInstance` never evaluates the filter.
|
|
6179
|
-
*
|
|
6180
|
-
*
|
|
6181
|
-
*
|
|
6587
|
+
* `startInstance` never evaluates the filter. BROWSE-TIME-PURE: every var is
|
|
6588
|
+
* knowable before any inputs exist, so `$fields` is deliberately absent — a
|
|
6589
|
+
* `$fields` read in a filter is deploy-rejected with a pointer to
|
|
6590
|
+
* `start.allowed`, the context that binds it. An absent binding evaluates to
|
|
6591
|
+
* GROQ null; the VERDICT-level coercion (null result ⇒ not applicable) is
|
|
6592
|
+
* what fails closed — what a null read does inside the expression depends on
|
|
6593
|
+
* its shape. Bound in one place: `startContextParams` in the applicability
|
|
6594
|
+
* evaluator.
|
|
6182
6595
|
*/
|
|
6183
6596
|
export declare const START_FILTER_VARS: readonly {
|
|
6184
6597
|
name: string;
|
|
@@ -6203,44 +6616,66 @@ export declare type StartBlock = StartFields & {
|
|
|
6203
6616
|
*/
|
|
6204
6617
|
export declare type StartContext = Record<string, unknown>;
|
|
6205
6618
|
|
|
6619
|
+
/**
|
|
6620
|
+
* What `evaluateStart` projects — the same gates `startInstance` enforces,
|
|
6621
|
+
* as renderable state. `allowed` and `missingRequired` are deliberately
|
|
6622
|
+
* orthogonal: a missing required input is a caller mistake (the verb throws
|
|
6623
|
+
* `RequiredFieldNotProvidedError` for it), never a `start.allowed` verdict.
|
|
6624
|
+
*/
|
|
6625
|
+
export declare interface StartEvaluation {
|
|
6626
|
+
/** The `start.allowed` verdict — `outcome === 'satisfied'`. Vacuously true
|
|
6627
|
+
* when the definition declares no `allowed`, exactly like the verb. */
|
|
6628
|
+
allowed: boolean;
|
|
6629
|
+
/**
|
|
6630
|
+
* Three-valued, BINDABILITY-AWARE verdict: `'unsatisfied'` is a definitive
|
|
6631
|
+
* no for these inputs (disable and explain), `'unevaluable'` means the
|
|
6632
|
+
* predicate can't be decided yet — either a null operand reached an
|
|
6633
|
+
* ordered comparison, or the predicate reads an entry `initialFields`
|
|
6634
|
+
* doesn't supply ({@link StartEvaluation.unboundReads} non-empty). Keep
|
|
6635
|
+
* the affordance enabled on `'unevaluable'`; `startInstance` still
|
|
6636
|
+
* enforces the final verdict, where absence is final rather than
|
|
6637
|
+
* provisional.
|
|
6638
|
+
*/
|
|
6639
|
+
outcome: ConditionOutcome;
|
|
6640
|
+
/** The `start.allowed` atom breakdown over the SUPPLIED inputs — what to
|
|
6641
|
+
* render next to a disabled start affordance. Present iff the definition
|
|
6642
|
+
* declares `allowed`. With `unboundReads` non-empty its own `outcome` may
|
|
6643
|
+
* be a collapsed provisional answer — the top-level `outcome` is the
|
|
6644
|
+
* trustworthy one. */
|
|
6645
|
+
insight?: ConditionInsight;
|
|
6646
|
+
/** The `$fields` entries the predicate reads that `initialFields` doesn't
|
|
6647
|
+
* supply — "fill these to decide". Non-empty forces `outcome:
|
|
6648
|
+
* 'unevaluable'`. Empty when the definition declares no `allowed`. */
|
|
6649
|
+
unboundReads: string[];
|
|
6650
|
+
/** Required input entries `initialFields` doesn't fill yet — the rows a
|
|
6651
|
+
* `startInstance` now would throw `RequiredFieldNotProvidedError` about. */
|
|
6652
|
+
missingRequired: {
|
|
6653
|
+
name: string;
|
|
6654
|
+
type: FieldEntry["type"];
|
|
6655
|
+
}[];
|
|
6656
|
+
}
|
|
6657
|
+
|
|
6206
6658
|
/** Type-mirror of {@link startFields}: how standalone runs of this workflow
|
|
6207
6659
|
* begin. Stored requires `kind` (desugar fills the `'interactive'` default);
|
|
6208
6660
|
* authoring may omit it — so each variant declares it. */
|
|
6209
6661
|
declare type StartFields = {
|
|
6210
6662
|
filter?: string | undefined;
|
|
6663
|
+
allowed?: string | undefined;
|
|
6211
6664
|
};
|
|
6212
6665
|
|
|
6213
6666
|
/**
|
|
6214
|
-
*
|
|
6215
|
-
*
|
|
6216
|
-
*
|
|
6217
|
-
*
|
|
6218
|
-
*
|
|
6219
|
-
*
|
|
6667
|
+
* Project caller-supplied `initialFields` into the `$fields` map the
|
|
6668
|
+
* start-allowed context binds: one key per declared `input`-sourced entry,
|
|
6669
|
+
* resolved through {@link suppliedFieldFor} — the predicate can only ever see
|
|
6670
|
+
* a value the input resolution would persist, and an undeclared supplied name
|
|
6671
|
+
* never leaks in. Unsupplied (or null-supplied) entries stay unbound, so a
|
|
6672
|
+
* read of one is GROQ null. Document references bind as their GDR envelopes
|
|
6673
|
+
* (`$fields.<entry>.id` is the GDR URI).
|
|
6220
6674
|
*/
|
|
6221
|
-
export declare
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
now?: string | undefined;
|
|
6226
|
-
/**
|
|
6227
|
-
* The candidate initialFields by entry name — binds `$fields`. Document
|
|
6228
|
-
* references bind as their GDR envelopes (`$fields.<entry>.id` is the GDR
|
|
6229
|
-
* URI). A surface that holds the caller's inputs (the Studio start control)
|
|
6230
|
-
* supplies them; a per-doc picker does not.
|
|
6231
|
-
*/
|
|
6232
|
-
fields?: Record<string, unknown> | undefined;
|
|
6233
|
-
/**
|
|
6234
|
-
* The WORKFLOW resource's dataset, for filters that read it (`*[...]` or a
|
|
6235
|
-
* deref) — invoked lazily, only when `analyzeCondition` says the filter
|
|
6236
|
-
* needs it. A slice is fine as long as it covers what filters scan;
|
|
6237
|
-
* `definitionsForDocument` supplies EVERY instance of the tag, completed
|
|
6238
|
-
* included — `*` carries no hidden predicate, so authors qualify in-flight
|
|
6239
|
-
* themselves (`!defined(completedAt)`). Absent ⇒ a dataset-reading filter
|
|
6240
|
-
* fails closed (this surface cannot see the dataset, so it cannot decide).
|
|
6241
|
-
*/
|
|
6242
|
-
fetchDataset?: (() => Promise<unknown[]>) | undefined;
|
|
6243
|
-
}
|
|
6675
|
+
export declare function startFieldsParam(args: {
|
|
6676
|
+
entryDefs: readonly FieldEntry[];
|
|
6677
|
+
initialFields: readonly InitialFieldValue[];
|
|
6678
|
+
}): Record<string, unknown>;
|
|
6244
6679
|
|
|
6245
6680
|
export declare interface StartInstanceArgs {
|
|
6246
6681
|
/** The definition's `name` — which deployed workflow to instantiate. */
|
|
@@ -6275,7 +6710,14 @@ export declare interface StartInstanceArgs {
|
|
|
6275
6710
|
* entry, so all forms read back the same under `$context.<name>`.
|
|
6276
6711
|
*/
|
|
6277
6712
|
context?: StartContext;
|
|
6278
|
-
/**
|
|
6713
|
+
/**
|
|
6714
|
+
* Caller-supplied id; auto-generated otherwise (mint one with
|
|
6715
|
+
* `instanceDocId`). This is start's idempotency key: a retry carrying the
|
|
6716
|
+
* same id resumes the earlier attempt's outstanding commits instead of
|
|
6717
|
+
* creating a duplicate — the per-instance request ledger can't cover the
|
|
6718
|
+
* create (it lives on the instance document), so id identity is the rail.
|
|
6719
|
+
* Inputs bind on the create only; a resume never re-reads them.
|
|
6720
|
+
*/
|
|
6279
6721
|
instanceId?: string;
|
|
6280
6722
|
/**
|
|
6281
6723
|
* URL path on the supplied client where the engine fetches the
|
|
@@ -6329,6 +6771,55 @@ export declare function startKindOf(definition: {
|
|
|
6329
6771
|
| undefined;
|
|
6330
6772
|
}): StartKind;
|
|
6331
6773
|
|
|
6774
|
+
/**
|
|
6775
|
+
* Thrown by `startInstance` when the definition's `start.allowed` predicate
|
|
6776
|
+
* is not satisfied for the supplied `initialFields` — evaluated false, or
|
|
6777
|
+
* GROQ null ("can't decide"; fail-closed, `insight.outcome` tells the two
|
|
6778
|
+
* apart). Carries the full {@link ConditionInsight} so a consumer renders
|
|
6779
|
+
* the same explanation the `evaluateStart` pre-flight would have shown.
|
|
6780
|
+
* There is no override arg — like `fireAction`, you don't bypass a verdict,
|
|
6781
|
+
* you change what produces it. Advisory under races like every engine-side
|
|
6782
|
+
* check.
|
|
6783
|
+
*/
|
|
6784
|
+
export declare class StartNotAllowedError extends WorkflowError<"start-not-allowed"> {
|
|
6785
|
+
readonly definition: string;
|
|
6786
|
+
readonly insight: ConditionInsight;
|
|
6787
|
+
constructor(args: { definition: string; insight: ConditionInsight });
|
|
6788
|
+
}
|
|
6789
|
+
|
|
6790
|
+
/**
|
|
6791
|
+
* Thrown when a start fails AFTER its create committed but BEFORE priming:
|
|
6792
|
+
* the instance document exists, unprimed (see {@link isUnprimed}) — a
|
|
6793
|
+
* genuinely failed start, but a RESUMABLE one. The error names the id so
|
|
6794
|
+
* every surface's failure message can point at the retry rail: retrying
|
|
6795
|
+
* `startInstance` with this `instanceId` finishes the start instead of
|
|
6796
|
+
* creating a duplicate; aborting the instance discards it.
|
|
6797
|
+
*/
|
|
6798
|
+
export declare class StartNotPrimedError extends WorkflowError<"start-not-primed"> {
|
|
6799
|
+
readonly instanceId: string;
|
|
6800
|
+
constructor(args: { instanceId: string; cause: unknown });
|
|
6801
|
+
}
|
|
6802
|
+
|
|
6803
|
+
/**
|
|
6804
|
+
* Thrown when a start's first cascade fails AFTER the instance was created
|
|
6805
|
+
* and primed: the run exists — stage entered, activities active, guards
|
|
6806
|
+
* deployed — it just hasn't auto-advanced to a stable stage yet. Callers
|
|
6807
|
+
* must not present this as a failed start: the workflow IS running, and a
|
|
6808
|
+
* `tick` (or retrying `startInstance` with the same `instanceId`) resumes
|
|
6809
|
+
* the settling.
|
|
6810
|
+
*/
|
|
6811
|
+
export declare class StartNotSettledError extends WorkflowError<"start-not-settled"> {
|
|
6812
|
+
readonly instanceId: string;
|
|
6813
|
+
/** The primed instance re-read after the cascade failure — absent when
|
|
6814
|
+
* that best-effort read also failed. */
|
|
6815
|
+
readonly instance?: WorkflowInstance;
|
|
6816
|
+
constructor(args: {
|
|
6817
|
+
instanceId: string;
|
|
6818
|
+
instance?: WorkflowInstance;
|
|
6819
|
+
cause: unknown;
|
|
6820
|
+
});
|
|
6821
|
+
}
|
|
6822
|
+
|
|
6332
6823
|
/**
|
|
6333
6824
|
* Why a definition can't be started standalone, or `undefined` when it can.
|
|
6334
6825
|
* Advisory — the engine itself does not refuse ({@link isStartableDefinition})
|
|
@@ -6339,6 +6830,38 @@ export declare function startRefusal(definition: {
|
|
|
6339
6830
|
lifecycle?: WorkflowLifecycle | undefined;
|
|
6340
6831
|
}): string | undefined;
|
|
6341
6832
|
|
|
6833
|
+
/**
|
|
6834
|
+
* The caller-side half of the start contexts — everything the evaluating
|
|
6835
|
+
* surface knows that the definition doesn't. Every member is optional
|
|
6836
|
+
* because the surfaces genuinely differ (a pure consumer may hold no clock):
|
|
6837
|
+
* an absent binding evaluates each read of it to GROQ null, and where that
|
|
6838
|
+
* null lands decides the verdict — a predicate that can't decide without
|
|
6839
|
+
* the binding fails closed, while a count-of-matches clause over values
|
|
6840
|
+
* every row stores passes vacuously (in GROQ null equals only null, so the
|
|
6841
|
+
* unbound read matches no stored value). The vars themselves are
|
|
6842
|
+
* inventoried in `START_FILTER_VARS` / `START_ALLOWED_VARS`; the caller's
|
|
6843
|
+
* `$fields` map is NOT scope — `start.filter` never binds it, and
|
|
6844
|
+
* `explainStartAllowed` takes it as its own argument.
|
|
6845
|
+
*/
|
|
6846
|
+
export declare interface StartScope {
|
|
6847
|
+
/** The engine's tag partition — binds `$tag`. */
|
|
6848
|
+
tag?: string | undefined;
|
|
6849
|
+
/** ISO clock reading — binds `$now`. */
|
|
6850
|
+
now?: string | undefined;
|
|
6851
|
+
/**
|
|
6852
|
+
* The WORKFLOW resource's dataset, for predicates that read it (`*[...]` or
|
|
6853
|
+
* a deref) — invoked lazily, only when `analyzeCondition` says the
|
|
6854
|
+
* predicate needs it. A slice is fine as long as it covers what predicates
|
|
6855
|
+
* scan; the engine verbs supply EVERY instance of the tag, completed
|
|
6856
|
+
* included — `*` carries no hidden predicate, so authors qualify in-flight
|
|
6857
|
+
* themselves (`!defined(completedAt)`). Absent ⇒ a dataset-reading filter
|
|
6858
|
+
* fails closed (this surface cannot see the dataset, so it cannot decide),
|
|
6859
|
+
* while a dataset-reading `allowed` THROWS — see
|
|
6860
|
+
* {@link explainStartAllowed}.
|
|
6861
|
+
*/
|
|
6862
|
+
fetchDataset?: (() => Promise<unknown[]>) | undefined;
|
|
6863
|
+
}
|
|
6864
|
+
|
|
6342
6865
|
/**
|
|
6343
6866
|
* Declared editability of a field — the generic edit seam's gate. Default
|
|
6344
6867
|
* (absent) is NOT editable: a field is op-only engine working memory unless the
|
|
@@ -7181,6 +7704,29 @@ declare type TransitionFields = {
|
|
|
7181
7704
|
*/
|
|
7182
7705
|
export declare function tryParseGdr(uri: string): ParsedGdr | undefined;
|
|
7183
7706
|
|
|
7707
|
+
/**
|
|
7708
|
+
* The `$fields` entries a `start.allowed` predicate reads that `fields` does
|
|
7709
|
+
* not bind — the BINDABILITY rule every pre-flight surface applies before
|
|
7710
|
+
* trusting a verdict over possibly-incomplete inputs. GROQ equality against
|
|
7711
|
+
* a missing operand collapses to a definitive-looking answer (`null == x` is
|
|
7712
|
+
* false, not null), so a verdict that read an unbound entry is PROVISIONAL in
|
|
7713
|
+
* both directions: supplying the entry could overturn a refusal AND an
|
|
7714
|
+
* approval. Non-empty ⇒ report "can't decide yet" instead of the collapsed
|
|
7715
|
+
* verdict (the `evaluateStart` verb does; the Studio start control does).
|
|
7716
|
+
*
|
|
7717
|
+
* The GATE never consults this: at `startInstance` the supplied inputs are
|
|
7718
|
+
* final, so evaluating over genuine absence — including rules that WANT it,
|
|
7719
|
+
* like `!defined($fields.rush)` — is the correct semantics there.
|
|
7720
|
+
*
|
|
7721
|
+
* `fields` is a produced `$fields` map (`startFieldsParam`, or a surface's
|
|
7722
|
+
* seed map) — producers bind only own keys with real values, so key presence
|
|
7723
|
+
* IS the supplied-ness rule.
|
|
7724
|
+
*/
|
|
7725
|
+
export declare function unboundAllowedReads(
|
|
7726
|
+
allowed: string,
|
|
7727
|
+
fields: Record<string, unknown>,
|
|
7728
|
+
): string[];
|
|
7729
|
+
|
|
7184
7730
|
/**
|
|
7185
7731
|
* The diagnose idiom shared by every consumer: each unsatisfied exit
|
|
7186
7732
|
* transition with its insight summary. Consumers shape the result (the CLI
|
|
@@ -7221,27 +7767,13 @@ export declare function validateDefinition(
|
|
|
7221
7767
|
definition: WorkflowDefinition,
|
|
7222
7768
|
): void;
|
|
7223
7769
|
|
|
7224
|
-
/**
|
|
7225
|
-
* Engine-scope tag — the environment partition primitive.
|
|
7226
|
-
*
|
|
7227
|
-
* Every engine operates against exactly one `tag` ("test", "prod", …).
|
|
7228
|
-
* The tag partitions definitions and instances within a single workflow
|
|
7229
|
-
* resource: `deploy(def, tag: "test")` and `deploy(def, tag: "prod")` are
|
|
7230
|
-
* separate deployed workflows with independent lifecycles, and every read
|
|
7231
|
-
* is scoped to one tag so test runs never surface in prod.
|
|
7232
|
-
*
|
|
7233
|
-
* The tag must be Sanity-ID-compatible since it's joined into IDs with
|
|
7234
|
-
* `.` — ASCII lowercase + digits + dashes, no leading dash, no dots. It
|
|
7235
|
-
* is also the ID prefix for every definition/instance the engine writes.
|
|
7236
|
-
*
|
|
7237
|
-
* There is no default. The tag selects which environment the engine reads
|
|
7238
|
-
* and writes, and the engine enforces nothing — so the partition is the
|
|
7239
|
-
* only thing keeping test runs out of prod. Every entry point
|
|
7240
|
-
* (`createEngine`, the CLI, the MCP server) requires it explicitly and
|
|
7241
|
-
* fails when it's absent rather than guessing an environment.
|
|
7242
|
-
*/
|
|
7243
7770
|
export declare function validateTag(tag: string): void;
|
|
7244
7771
|
|
|
7772
|
+
declare interface ValidationIssue {
|
|
7773
|
+
path: ReadonlyArray<PropertyKey>;
|
|
7774
|
+
message: string;
|
|
7775
|
+
}
|
|
7776
|
+
|
|
7245
7777
|
export declare type ValueExpr = ValueExprInternal;
|
|
7246
7778
|
|
|
7247
7779
|
declare type ValueExprInternal =
|
|
@@ -7386,18 +7918,36 @@ export declare const workflow: {
|
|
|
7386
7918
|
/**
|
|
7387
7919
|
* Spawn a new workflow instance from a deployed definition.
|
|
7388
7920
|
*
|
|
7389
|
-
*
|
|
7390
|
-
*
|
|
7391
|
-
*
|
|
7392
|
-
*
|
|
7393
|
-
*
|
|
7921
|
+
* Two gates run before anything is written, in order: the required-input
|
|
7922
|
+
* check — a missing `required` input is a CALLER mistake
|
|
7923
|
+
* ({@link RequiredFieldNotProvidedError}) — then the definition's
|
|
7924
|
+
* `start.allowed` permission predicate, whose false/GROQ-null VERDICT
|
|
7925
|
+
* throws {@link StartNotAllowedError} (declaring the expression is the
|
|
7926
|
+
* opt-in; there is no override arg — pre-flight with `evaluateStart`).
|
|
7927
|
+
* Per-value SHAPE validation fires during field resolution, after the
|
|
7928
|
+
* verdict but still before any write. It does NOT evaluate `start.filter`:
|
|
7929
|
+
* that is a read-side visibility rule (see `definitionsForDocument`).
|
|
7394
7930
|
*
|
|
7395
7931
|
* Pins the snapshot at start-time, seeds the `context` bag, and enters
|
|
7396
7932
|
* the initial stage — fields resolve and every in-scope activity is
|
|
7397
7933
|
* born active. Then cascades until stable, so the initial stage's
|
|
7398
|
-
* `when: 'true'` triggers have fired by the time this returns.
|
|
7399
|
-
*
|
|
7400
|
-
*
|
|
7934
|
+
* `when: 'true'` triggers have fired by the time this returns.
|
|
7935
|
+
*
|
|
7936
|
+
* Start is three commits — create, prime, first cascade — and a supplied
|
|
7937
|
+
* `instanceId` is its idempotency key across them. When that id already
|
|
7938
|
+
* exists under this tag for the same start, the call RESUMES: input gates
|
|
7939
|
+
* and field resolution are skipped (those values were pinned at create)
|
|
7940
|
+
* and the outstanding commits run — the retry path for a start that
|
|
7941
|
+
* failed after its create landed (see `isUnprimed`). Reusing an id for a
|
|
7942
|
+
* DIFFERENT start (definition or explicit version mismatch) — or for an
|
|
7943
|
+
* unfinished start that was aborted (a discarded start) — throws
|
|
7944
|
+
* {@link ContractViolationError}. The mid-sequence failures are typed and
|
|
7945
|
+
* carry the retry id: a prime failure after the create committed throws
|
|
7946
|
+
* `StartNotPrimedError` (failed but resumable), and a cascade failure
|
|
7947
|
+
* after a successful prime throws `StartNotSettledError` — the run exists
|
|
7948
|
+
* by then and must not be reported as a failed start. `changed` is `true`
|
|
7949
|
+
* on a fresh start and rev-derived on a resume; `cascaded` reports how far
|
|
7950
|
+
* the instance auto-advanced.
|
|
7401
7951
|
*/
|
|
7402
7952
|
startInstance: (
|
|
7403
7953
|
rawArgs: Clocked<Telemetered<StartInstanceArgs & EngineScopeArgs>>,
|
|
@@ -7519,8 +8069,11 @@ export declare const workflow: {
|
|
|
7519
8069
|
* Hydrates the instance's snapshot (instance + ancestors + every doc
|
|
7520
8070
|
* declared by a `doc.ref` / `doc.refs` entry in scope), then
|
|
7521
8071
|
* evaluates the supplied GROQ in groq-js against that dataset. The
|
|
7522
|
-
* rendered scope
|
|
7523
|
-
*
|
|
8072
|
+
* caller-free rendered scope cascade gates evaluate in is auto-bound —
|
|
8073
|
+
* the instance-derived vars ({@link FILTER_SCOPE_VARS}) with the open
|
|
8074
|
+
* stage's overlay merged into `$fields`, `$assigned` at its caller-free
|
|
8075
|
+
* `false`, plus the author's pre-evaluated `$<predicate>` booleans —
|
|
8076
|
+
* ids in GDR URI form to match the snapshot's keying.
|
|
7524
8077
|
*
|
|
7525
8078
|
* Use when an external consumer (a UI, a debug pane, a test) wants
|
|
7526
8079
|
* to ask "what does the engine see for this workflow right now?"
|
|
@@ -7631,10 +8184,10 @@ export declare const workflow: {
|
|
|
7631
8184
|
* visible to the engine's tag and filters it through the derivation
|
|
7632
8185
|
* ({@link applicableDefinitions}): startable ∧ a required subject entry
|
|
7633
8186
|
* accepts the doc's `_type` ∧ `start.filter` passes — evaluated in the
|
|
7634
|
-
* start-filter context with `$tag`/`$definition`/`$now`
|
|
7635
|
-
* tag's instance slice (completed included) backing dataset
|
|
7636
|
-
* `
|
|
7637
|
-
*
|
|
8187
|
+
* browse-time-pure start-filter context with `$tag`/`$definition`/`$now`
|
|
8188
|
+
* bound and the tag's instance slice (completed included) backing dataset
|
|
8189
|
+
* reads. `start.allowed` never participates — permission is a start-time
|
|
8190
|
+
* question; pre-flight it with {@link workflow.evaluateStart}.
|
|
7638
8191
|
*
|
|
7639
8192
|
* Takes the LOADED candidate document, not a ref — applicability evaluates
|
|
7640
8193
|
* its content, under whatever perspective the caller read it with. Surfaces
|
|
@@ -7644,6 +8197,26 @@ export declare const workflow: {
|
|
|
7644
8197
|
definitionsForDocument: (
|
|
7645
8198
|
rawArgs: Clocked<DefinitionsForDocumentArgs & EngineScopeArgs>,
|
|
7646
8199
|
) => Promise<DeployedDefinition[]>;
|
|
8200
|
+
/**
|
|
8201
|
+
* Pre-flight the start gates for a definition + candidate `initialFields` —
|
|
8202
|
+
* the read `startInstance` enforces, as a {@link StartEvaluation} a surface
|
|
8203
|
+
* can render: `missingRequired` mirrors the input contract
|
|
8204
|
+
* ({@link RequiredFieldNotProvidedError}'s rows), and `allowed` /
|
|
8205
|
+
* `outcome` / `insight` carry the `start.allowed` verdict with its atom
|
|
8206
|
+
* breakdown — disable the start affordance on a definitive `false` and say
|
|
8207
|
+
* why. BINDABILITY-AWARE for partial mid-form inputs: when the predicate
|
|
8208
|
+
* reads an entry `initialFields` doesn't supply, `outcome` is
|
|
8209
|
+
* `'unevaluable'` and `unboundReads` names the entries ("fill these to
|
|
8210
|
+
* decide") instead of the collapsed answer GROQ equality would give —
|
|
8211
|
+
* this is the ONE deliberate divergence from the gate, where absence is
|
|
8212
|
+
* final, not provisional (a rule like `!defined($fields.rush)` genuinely
|
|
8213
|
+
* passes there when `rush` is absent). A definition with no
|
|
8214
|
+
* `start.allowed` is vacuously allowed, exactly like the verb. Pure read;
|
|
8215
|
+
* advisory under races — the enforcement moment is `startInstance` itself.
|
|
8216
|
+
*/
|
|
8217
|
+
evaluateStart: (
|
|
8218
|
+
rawArgs: Clocked<EvaluateStartArgs & EngineScopeArgs>,
|
|
8219
|
+
) => Promise<StartEvaluation>;
|
|
7647
8220
|
/**
|
|
7648
8221
|
* Permission helpers — Sanity ACL grants evaluated against documents
|
|
7649
8222
|
* via GROQ. Used by `workflow.evaluate` to soft-gate actions when the
|
|
@@ -7705,6 +8278,12 @@ export declare interface WorkflowAdminOverrideData extends InstanceScopedEventDa
|
|
|
7705
8278
|
changed: boolean;
|
|
7706
8279
|
}
|
|
7707
8280
|
|
|
8281
|
+
/** The whole-definition rollup: every stage must progress, so the workflow
|
|
8282
|
+
* verdict conjoins the stage verdicts. */
|
|
8283
|
+
export declare interface WorkflowAutonomy extends AutonomyAnswer {
|
|
8284
|
+
stages: StageAutonomy[];
|
|
8285
|
+
}
|
|
8286
|
+
|
|
7708
8287
|
export declare interface WorkflowClient {
|
|
7709
8288
|
fetch: <T = unknown>(
|
|
7710
8289
|
query: string,
|
|
@@ -8399,6 +8978,7 @@ export declare abstract class WorkflowError<
|
|
|
8399
8978
|
|
|
8400
8979
|
export declare type WorkflowErrorKind =
|
|
8401
8980
|
| "action-disabled"
|
|
8981
|
+
| "start-not-allowed"
|
|
8402
8982
|
| "edit-field-denied"
|
|
8403
8983
|
| "mutation-guard-denied"
|
|
8404
8984
|
| "action-params-invalid"
|
|
@@ -8407,12 +8987,16 @@ export declare type WorkflowErrorKind =
|
|
|
8407
8987
|
| "required-field-not-provided"
|
|
8408
8988
|
| "workflow-state-diverged"
|
|
8409
8989
|
| "partial-guard-deploy"
|
|
8990
|
+
| "start-not-primed"
|
|
8991
|
+
| "start-not-settled"
|
|
8410
8992
|
| "concurrent-fire-action"
|
|
8411
8993
|
| "concurrent-edit-field"
|
|
8412
8994
|
| "concurrent-complete-effect"
|
|
8413
8995
|
| "cascade-limit"
|
|
8414
8996
|
| "field-value-shape"
|
|
8997
|
+
| "ref-resource-undeclared"
|
|
8415
8998
|
| "model-version-ahead"
|
|
8999
|
+
| "persisted-doc-shape"
|
|
8416
9000
|
| "instance-not-found"
|
|
8417
9001
|
| "definition-not-found"
|
|
8418
9002
|
| "definition-in-use"
|
|
@@ -8443,6 +9027,14 @@ export declare interface WorkflowEvaluation {
|
|
|
8443
9027
|
* Empty when no condition reads a field.
|
|
8444
9028
|
*/
|
|
8445
9029
|
fieldInsights: FieldInsight[];
|
|
9030
|
+
/**
|
|
9031
|
+
* The whole definition's causal-autonomy rollup: per activity, per stage,
|
|
9032
|
+
* and workflow-wide — will each level resolve without a caller, and what
|
|
9033
|
+
* does it wait on. Static (no instance state), stamped here so every
|
|
9034
|
+
* consumer reads one derivation. Spawn children are not resolved at
|
|
9035
|
+
* evaluation time, so their legs report `conditional`.
|
|
9036
|
+
*/
|
|
9037
|
+
autonomy: WorkflowAutonomy;
|
|
8446
9038
|
}
|
|
8447
9039
|
|
|
8448
9040
|
export declare interface WorkflowFetchOptions {
|
|
@@ -8472,6 +9064,12 @@ export declare interface WorkflowFieldEditedData extends InstanceScopedEventData
|
|
|
8472
9064
|
|
|
8473
9065
|
/** Type-mirror of {@link workflowFields}, parameterised over field/stage/start. */
|
|
8474
9066
|
declare type WorkflowFields<TField, TStage, TStart> = {
|
|
9067
|
+
/**
|
|
9068
|
+
* Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
|
|
9069
|
+
* name interpolates into every deployed document id
|
|
9070
|
+
* (`<tag>.<name>.v<version>`). Stable identity — instances pin to it,
|
|
9071
|
+
* subworkflows resolve by it.
|
|
9072
|
+
*/
|
|
8475
9073
|
name: string;
|
|
8476
9074
|
title: string;
|
|
8477
9075
|
description?: string | undefined;
|
|
@@ -8606,6 +9204,13 @@ export declare interface WorkflowInstance extends SanityDocument {
|
|
|
8606
9204
|
|
|
8607
9205
|
export declare const WorkflowInstanceAborted: WorkflowTelemetryEvent<WorkflowAdminOverrideData>;
|
|
8608
9206
|
|
|
9207
|
+
/**
|
|
9208
|
+
* The persisted instance document, root to leaf. Reused verbatim by every
|
|
9209
|
+
* engine read boundary through {@link parseInstanceDocument}; the
|
|
9210
|
+
* model-surface gate derives its shape ledger from this schema.
|
|
9211
|
+
*/
|
|
9212
|
+
export declare const WorkflowInstanceSchema: v.GenericSchema<WorkflowInstance>;
|
|
9213
|
+
|
|
8609
9214
|
export declare const WorkflowInstanceStarted: WorkflowTelemetryEvent<WorkflowInstanceStartedData>;
|
|
8610
9215
|
|
|
8611
9216
|
export declare interface WorkflowInstanceStartedData extends InstanceScopedEventData {
|
|
@@ -8800,10 +9405,11 @@ export declare interface WorkflowTransaction {
|
|
|
8800
9405
|
/**
|
|
8801
9406
|
* Queue a document delete. Deliberately a transaction-only capability —
|
|
8802
9407
|
* the top-level client surface stays delete-free so no engine code path
|
|
8803
|
-
* can casually remove documents; the sole consumer is
|
|
8804
|
-
* housekeeping (definition docs + orphaned guard docs)
|
|
8805
|
-
*
|
|
8806
|
-
*
|
|
9408
|
+
* can casually remove documents; engine-side the sole consumer is
|
|
9409
|
+
* `deleteDefinition` housekeeping (definition docs + orphaned guard docs),
|
|
9410
|
+
* and outside the engine the CLI's `nuke` reset deletes raw engine-owned
|
|
9411
|
+
* docs through it. Both the real `@sanity/client` Transaction and the test
|
|
9412
|
+
* fake's TransactionHandle carry this shape.
|
|
8807
9413
|
*/
|
|
8808
9414
|
delete: (id: string) => WorkflowTransaction;
|
|
8809
9415
|
/**
|