@sanity/workflow-engine 0.16.0 → 0.18.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 +87 -0
- package/DATAMODEL.md +244 -42
- package/README.md +23 -0
- package/dist/_chunks-cjs/invariants.cjs +1029 -225
- package/dist/_chunks-es/invariants.js +944 -226
- package/dist/define.cjs +6 -1
- package/dist/define.d.cts +220 -48
- package/dist/define.d.ts +220 -48
- package/dist/define.js +7 -2
- package/dist/index.cjs +4371 -2591
- package/dist/index.d.cts +1456 -302
- package/dist/index.d.ts +1456 -302
- package/dist/index.js +4162 -2477
- package/package.json +2 -2
package/dist/index.d.cts
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";
|
|
@@ -39,17 +40,15 @@ export declare function abortReason(
|
|
|
39
40
|
): string | undefined;
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
|
-
* The structured half of applicability: does
|
|
43
|
-
* ({@link isSubjectEntry} — `
|
|
44
|
-
*
|
|
45
|
-
* a
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* pinned to caller-filled `input` entries by a deploy invariant, so it alone
|
|
52
|
-
* identifies the handoff.)
|
|
43
|
+
* The structured half of applicability: does the definition's subject entry
|
|
44
|
+
* ({@link isSubjectEntry} — the `subject` kind, workflow scope, at most one
|
|
45
|
+
* by deploy invariant) accept `documentType`? The kind is the discriminator,
|
|
46
|
+
* so a definition surfaces from its SUBJECT's document picker and nowhere
|
|
47
|
+
* else; the start dialog collects the remaining required entries (their
|
|
48
|
+
* fail-hard validation backstops). A subject without `types` accepts any
|
|
49
|
+
* type; a definition with NO subject entry takes no subject and never
|
|
50
|
+
* matches. Cheap and indexable — no GROQ evaluation — so a consumer can
|
|
51
|
+
* pre-filter before loading document content.
|
|
53
52
|
*/
|
|
54
53
|
export declare function acceptsDocumentType(
|
|
55
54
|
definition: Pick<ApplicabilitySource, "fields">,
|
|
@@ -82,6 +81,11 @@ export declare type Action = ActionFields<Op, string[]> & {
|
|
|
82
81
|
roles?: string[] | undefined;
|
|
83
82
|
};
|
|
84
83
|
|
|
84
|
+
export declare const ACTION_SEMANTICS: readonly [
|
|
85
|
+
"decision.accept",
|
|
86
|
+
"decision.decline",
|
|
87
|
+
];
|
|
88
|
+
|
|
85
89
|
/**
|
|
86
90
|
* The engine's per-reason detail fragment — the same wording
|
|
87
91
|
* {@link ActionDisabledError} embeds in its message. Exported so a dev-facing
|
|
@@ -123,6 +127,8 @@ export declare type ActionDisabledReason = Exclude<
|
|
|
123
127
|
|
|
124
128
|
export declare interface ActionEvaluation {
|
|
125
129
|
action: Action;
|
|
130
|
+
/** The action's advisory workflow meaning, unchanged from its definition. */
|
|
131
|
+
semantics?: ActionSemantic[] | undefined;
|
|
126
132
|
allowed: boolean;
|
|
127
133
|
/**
|
|
128
134
|
* The action is cascade-fired (`when`): the engine fires it on truth, it
|
|
@@ -146,6 +152,7 @@ export declare interface ActionEvaluation {
|
|
|
146
152
|
* group-membership grammars. */
|
|
147
153
|
declare type ActionFields<TOp, TGroup> = {
|
|
148
154
|
name: string;
|
|
155
|
+
semantics?: ActionSemantic[] | undefined;
|
|
149
156
|
title?: string | undefined;
|
|
150
157
|
description?: string | undefined;
|
|
151
158
|
group?: TGroup | undefined;
|
|
@@ -167,36 +174,131 @@ export declare type ActionParam = v.InferOutput<typeof ActionParamSchema>;
|
|
|
167
174
|
* effects: missing required params → ActionParamsInvalidError, action
|
|
168
175
|
* does not commit. Resolved values feed `ValueExpr.param` lookups.
|
|
169
176
|
*/
|
|
170
|
-
declare const ActionParamSchema: v.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
v.
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
177
|
+
declare const ActionParamSchema: v.SchemaWithPipe<
|
|
178
|
+
readonly [
|
|
179
|
+
v.StrictObjectSchema<
|
|
180
|
+
{
|
|
181
|
+
readonly type: v.PicklistSchema<
|
|
182
|
+
readonly [
|
|
183
|
+
"string",
|
|
184
|
+
"number",
|
|
185
|
+
"boolean",
|
|
186
|
+
"url",
|
|
187
|
+
"dateTime",
|
|
188
|
+
"actor",
|
|
189
|
+
"doc.ref",
|
|
190
|
+
"doc.refs",
|
|
191
|
+
"json",
|
|
192
|
+
],
|
|
193
|
+
`Invalid option: expected one of ${string}`
|
|
194
|
+
>;
|
|
195
|
+
readonly name: v.SchemaWithPipe<
|
|
196
|
+
readonly [
|
|
197
|
+
v.StringSchema<undefined>,
|
|
198
|
+
v.MinLengthAction<string, 1, "must be a non-empty string">,
|
|
199
|
+
]
|
|
200
|
+
>;
|
|
201
|
+
readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
202
|
+
readonly description: v.OptionalSchema<
|
|
203
|
+
v.StringSchema<undefined>,
|
|
204
|
+
undefined
|
|
205
|
+
>;
|
|
206
|
+
readonly required: v.OptionalSchema<
|
|
207
|
+
v.BooleanSchema<undefined>,
|
|
208
|
+
undefined
|
|
209
|
+
>;
|
|
210
|
+
readonly options: v.OptionalSchema<
|
|
211
|
+
v.GenericSchema<ChoiceOptions>,
|
|
212
|
+
undefined
|
|
213
|
+
>;
|
|
214
|
+
readonly validation: v.OptionalSchema<
|
|
215
|
+
v.GenericSchema<ScalarValidation>,
|
|
216
|
+
undefined
|
|
217
|
+
>;
|
|
218
|
+
},
|
|
195
219
|
undefined
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
220
|
+
>,
|
|
221
|
+
v.CheckAction<
|
|
222
|
+
{
|
|
223
|
+
type:
|
|
224
|
+
| "string"
|
|
225
|
+
| "number"
|
|
226
|
+
| "boolean"
|
|
227
|
+
| "doc.ref"
|
|
228
|
+
| "doc.refs"
|
|
229
|
+
| "url"
|
|
230
|
+
| "actor"
|
|
231
|
+
| "dateTime"
|
|
232
|
+
| "json";
|
|
233
|
+
name: string;
|
|
234
|
+
title?: string | undefined;
|
|
235
|
+
description?: string | undefined;
|
|
236
|
+
required?: boolean | undefined;
|
|
237
|
+
options?: ChoiceOptions | undefined;
|
|
238
|
+
validation?: ScalarValidation | undefined;
|
|
239
|
+
},
|
|
240
|
+
(
|
|
241
|
+
issue: v.CheckIssue<{
|
|
242
|
+
type:
|
|
243
|
+
| "string"
|
|
244
|
+
| "number"
|
|
245
|
+
| "boolean"
|
|
246
|
+
| "doc.ref"
|
|
247
|
+
| "doc.refs"
|
|
248
|
+
| "url"
|
|
249
|
+
| "actor"
|
|
250
|
+
| "dateTime"
|
|
251
|
+
| "json";
|
|
252
|
+
name: string;
|
|
253
|
+
title?: string | undefined;
|
|
254
|
+
description?: string | undefined;
|
|
255
|
+
required?: boolean | undefined;
|
|
256
|
+
options?: ChoiceOptions | undefined;
|
|
257
|
+
validation?: ScalarValidation | undefined;
|
|
258
|
+
}>,
|
|
259
|
+
) => string
|
|
260
|
+
>,
|
|
261
|
+
v.CheckAction<
|
|
262
|
+
{
|
|
263
|
+
type:
|
|
264
|
+
| "string"
|
|
265
|
+
| "number"
|
|
266
|
+
| "boolean"
|
|
267
|
+
| "doc.ref"
|
|
268
|
+
| "doc.refs"
|
|
269
|
+
| "url"
|
|
270
|
+
| "actor"
|
|
271
|
+
| "dateTime"
|
|
272
|
+
| "json";
|
|
273
|
+
name: string;
|
|
274
|
+
title?: string | undefined;
|
|
275
|
+
description?: string | undefined;
|
|
276
|
+
required?: boolean | undefined;
|
|
277
|
+
options?: ChoiceOptions | undefined;
|
|
278
|
+
validation?: ScalarValidation | undefined;
|
|
279
|
+
},
|
|
280
|
+
(
|
|
281
|
+
issue: v.CheckIssue<{
|
|
282
|
+
type:
|
|
283
|
+
| "string"
|
|
284
|
+
| "number"
|
|
285
|
+
| "boolean"
|
|
286
|
+
| "doc.ref"
|
|
287
|
+
| "doc.refs"
|
|
288
|
+
| "url"
|
|
289
|
+
| "actor"
|
|
290
|
+
| "dateTime"
|
|
291
|
+
| "json";
|
|
292
|
+
name: string;
|
|
293
|
+
title?: string | undefined;
|
|
294
|
+
description?: string | undefined;
|
|
295
|
+
required?: boolean | undefined;
|
|
296
|
+
options?: ChoiceOptions | undefined;
|
|
297
|
+
validation?: ScalarValidation | undefined;
|
|
298
|
+
}>,
|
|
299
|
+
) => string
|
|
300
|
+
>,
|
|
301
|
+
]
|
|
200
302
|
>;
|
|
201
303
|
|
|
202
304
|
/**
|
|
@@ -241,6 +343,8 @@ export declare function actionRendering(action: {
|
|
|
241
343
|
| undefined;
|
|
242
344
|
}): "absent" | "automation" | "button";
|
|
243
345
|
|
|
346
|
+
export declare type ActionSemantic = (typeof ACTION_SEMANTICS)[number];
|
|
347
|
+
|
|
244
348
|
/** The fireable-action verdict for one action on an activity — its `allowed`
|
|
245
349
|
* state, structured `disabledReason`, and declared params, tagged with the
|
|
246
350
|
* owning activity. The per-action atom both projections share:
|
|
@@ -312,6 +416,13 @@ declare const ACTIVITY_STATUSES: readonly [
|
|
|
312
416
|
"failed",
|
|
313
417
|
];
|
|
314
418
|
|
|
419
|
+
/** The activity slice of a stage rollup — total by construction, like
|
|
420
|
+
* {@link stageAutonomyOf}. */
|
|
421
|
+
export declare function activityAutonomyOf(
|
|
422
|
+
stageAutonomy: StageAutonomy,
|
|
423
|
+
activityName: string,
|
|
424
|
+
): AutonomyAnswer;
|
|
425
|
+
|
|
315
426
|
/** An activity's gates, each described — absent keys mirror undeclared gates. */
|
|
316
427
|
export declare interface ActivityDescription {
|
|
317
428
|
requirements?: Record<string, ConditionDescription>;
|
|
@@ -360,11 +471,19 @@ export declare interface ActivityEvaluation {
|
|
|
360
471
|
*/
|
|
361
472
|
kind: ActivityKind;
|
|
362
473
|
/**
|
|
363
|
-
* Who, if anyone, the activity
|
|
474
|
+
* Who, if anyone, fires the activity's actions — derived from its shape
|
|
364
475
|
* alone: `autonomous` (every action cascade-fired), `interactive` (only
|
|
365
476
|
* fireAction-fired actions), `off-system` (`target` present), or `hybrid`.
|
|
366
477
|
*/
|
|
367
478
|
classification: ExecutorClassification;
|
|
479
|
+
/**
|
|
480
|
+
* The causal refinement of {@link ActivityEvaluation.classification}:
|
|
481
|
+
* whether this activity completes without a caller, derived by
|
|
482
|
+
* {@link deriveWorkflowAutonomy}'s dataflow over the definition — a
|
|
483
|
+
* mechanically `autonomous` activity whose triggers only read
|
|
484
|
+
* caller-written state still reports the caller it waits on.
|
|
485
|
+
*/
|
|
486
|
+
autonomy: AutonomyAnswer;
|
|
368
487
|
/** Whether this activity is the current actor's responsibility right now. */
|
|
369
488
|
pendingOnActor: boolean;
|
|
370
489
|
/**
|
|
@@ -443,11 +562,31 @@ export declare const ACTOR_KINDS: readonly ["person", "agent", "system"];
|
|
|
443
562
|
|
|
444
563
|
export declare type ActorKind = (typeof ACTOR_KINDS)[number];
|
|
445
564
|
|
|
565
|
+
export declare type ActorResolution<User> =
|
|
566
|
+
| {
|
|
567
|
+
readonly status: "resolved";
|
|
568
|
+
readonly actor: PersonActor;
|
|
569
|
+
readonly user: User;
|
|
570
|
+
}
|
|
571
|
+
| {
|
|
572
|
+
readonly status: "missing";
|
|
573
|
+
readonly actor: PersonActor;
|
|
574
|
+
}
|
|
575
|
+
| {
|
|
576
|
+
readonly status: "inaccessible";
|
|
577
|
+
readonly actor: PersonActor;
|
|
578
|
+
readonly cause?: unknown;
|
|
579
|
+
}
|
|
580
|
+
| {
|
|
581
|
+
readonly status: "not-person";
|
|
582
|
+
readonly actor: Actor;
|
|
583
|
+
};
|
|
584
|
+
|
|
446
585
|
export { analyzeCondition };
|
|
447
586
|
|
|
448
|
-
/** The definition surface
|
|
587
|
+
/** The definition surface the start contexts read — structural, so authored,
|
|
449
588
|
* stored, and deployed definition shapes all fit. `name` binds
|
|
450
|
-
* `$definition` and names the definition in a broken-
|
|
589
|
+
* `$definition` and names the definition in a broken-predicate error. */
|
|
451
590
|
export declare interface ApplicabilitySource {
|
|
452
591
|
name?: string | undefined;
|
|
453
592
|
lifecycle?: WorkflowLifecycle | undefined;
|
|
@@ -456,6 +595,7 @@ export declare interface ApplicabilitySource {
|
|
|
456
595
|
| {
|
|
457
596
|
kind?: StartKind | undefined;
|
|
458
597
|
filter?: string | undefined;
|
|
598
|
+
allowed?: string | undefined;
|
|
459
599
|
}
|
|
460
600
|
| undefined;
|
|
461
601
|
}
|
|
@@ -470,7 +610,7 @@ export declare function applicableDefinitions<
|
|
|
470
610
|
definitions: readonly T[];
|
|
471
611
|
document: CandidateDocument;
|
|
472
612
|
/** Caller-side filter bindings, shared by every definition's evaluation. */
|
|
473
|
-
scope?:
|
|
613
|
+
scope?: StartScope;
|
|
474
614
|
}): Promise<T[]>;
|
|
475
615
|
|
|
476
616
|
/**
|
|
@@ -491,6 +631,11 @@ export declare function assertReadableModel<
|
|
|
491
631
|
},
|
|
492
632
|
>(doc: T): T;
|
|
493
633
|
|
|
634
|
+
export declare function assertReaderModelAcknowledgement(
|
|
635
|
+
expectedMinReaderModel: unknown,
|
|
636
|
+
context?: string,
|
|
637
|
+
): asserts expectedMinReaderModel is typeof DATA_MODEL_MIN_READER;
|
|
638
|
+
|
|
494
639
|
/**
|
|
495
640
|
* One member of an `assignees`-kind entry's value — and the value of the
|
|
496
641
|
* singular `assignee` kind. The WHO-FOR spec the inbox reverse-query and the
|
|
@@ -511,6 +656,8 @@ export declare type Assignee =
|
|
|
511
656
|
|
|
512
657
|
export { AtomInsight };
|
|
513
658
|
|
|
659
|
+
export { atomReadsDataset };
|
|
660
|
+
|
|
514
661
|
export { AtomRequirement };
|
|
515
662
|
|
|
516
663
|
/**
|
|
@@ -607,6 +754,11 @@ export declare type AuthoringGuard = v.InferOutput<typeof AuthoringGuardSchema>;
|
|
|
607
754
|
|
|
608
755
|
declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
609
756
|
{
|
|
757
|
+
/**
|
|
758
|
+
* Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
|
|
759
|
+
* guard's lake `_id` derives from `(instanceId, name)` at stage entry.
|
|
760
|
+
* Unique per definition.
|
|
761
|
+
*/
|
|
610
762
|
name: v.SchemaWithPipe<
|
|
611
763
|
readonly [
|
|
612
764
|
v.StringSchema<undefined>,
|
|
@@ -768,8 +920,9 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
|
768
920
|
/**
|
|
769
921
|
* Lake GROQ predicate — a distinct eval context: delta-mode GROQ
|
|
770
922
|
* reading the `before()`/`after()` natives, `mutation`, `guard`, and
|
|
771
|
-
* `identity()`. Bare ids/fields only.
|
|
772
|
-
*
|
|
923
|
+
* `identity()`. Bare ids/fields only. Polarity: a result of strictly
|
|
924
|
+
* `true` ALLOWS the matched mutation; anything else (false, null, an
|
|
925
|
+
* evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
|
|
773
926
|
*/
|
|
774
927
|
predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
775
928
|
/**
|
|
@@ -1221,6 +1374,85 @@ export declare type AuthoringWorkflow = WorkflowFields<
|
|
|
1221
1374
|
AuthoringStartBlock
|
|
1222
1375
|
>;
|
|
1223
1376
|
|
|
1377
|
+
/** The narratable answer at one rollup level: the verdict plus what it waits
|
|
1378
|
+
* on. `waitsOn` may be non-empty on a `yes` verdict (an effect settle is a
|
|
1379
|
+
* wait the engine resolves itself) — consumers choose what to surface. */
|
|
1380
|
+
export declare interface AutonomyAnswer {
|
|
1381
|
+
completesWithoutCaller: AutonomyVerdict;
|
|
1382
|
+
waitsOn: AutonomyWait[];
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
/** The workflow-level autonomy narrative: fully self-running, or the stages
|
|
1386
|
+
* where a run is held. */
|
|
1387
|
+
export declare function autonomySummary(
|
|
1388
|
+
autonomy: WorkflowAutonomy,
|
|
1389
|
+
ctx: DescribeContext,
|
|
1390
|
+
): InsightPhrase;
|
|
1391
|
+
|
|
1392
|
+
/**
|
|
1393
|
+
* Whether a node resolves without a caller: `yes` — engine machinery alone
|
|
1394
|
+
* (the cascade plus the host's effect drain/ticker) gets it there; `no` —
|
|
1395
|
+
* someone outside the engine must act (a caller fires an action, an editor
|
|
1396
|
+
* writes a field or content); `conditional` — it may resolve either way
|
|
1397
|
+
* depending on values the analysis can't see (start-time seeds, mixed
|
|
1398
|
+
* alternative routes, unresolvable children, cyclic gates).
|
|
1399
|
+
*
|
|
1400
|
+
* `yes` still leans on the host: effects settle only if a drain runs, and
|
|
1401
|
+
* time only passes for a ticker. A cascade-fired action's `roles` pin is a
|
|
1402
|
+
* DEPENDENCY, not an assumption — the runtime leaves a pinned trigger armed
|
|
1403
|
+
* until a capable token cascades, and whether the deployment's tokens fulfil
|
|
1404
|
+
* the pin is configuration the analysis can't see, so a pinned trigger
|
|
1405
|
+
* reports `conditional` with the pin as its wait.
|
|
1406
|
+
*/
|
|
1407
|
+
export declare type AutonomyVerdict = "yes" | "no" | "conditional";
|
|
1408
|
+
|
|
1409
|
+
/** One narratable dependency a non-`yes` verdict rests on. */
|
|
1410
|
+
export declare type AutonomyWait =
|
|
1411
|
+
| {
|
|
1412
|
+
kind: "caller-action";
|
|
1413
|
+
stage: string;
|
|
1414
|
+
activity: string;
|
|
1415
|
+
action: string;
|
|
1416
|
+
roles?: string[];
|
|
1417
|
+
}
|
|
1418
|
+
| {
|
|
1419
|
+
kind: "execute-pin";
|
|
1420
|
+
stage: string;
|
|
1421
|
+
activity: string;
|
|
1422
|
+
action: string;
|
|
1423
|
+
roles: string[];
|
|
1424
|
+
}
|
|
1425
|
+
| {
|
|
1426
|
+
kind: "editor-field";
|
|
1427
|
+
field: string;
|
|
1428
|
+
}
|
|
1429
|
+
| {
|
|
1430
|
+
kind: "editor-content";
|
|
1431
|
+
condition: Condition;
|
|
1432
|
+
}
|
|
1433
|
+
| {
|
|
1434
|
+
kind: "effect";
|
|
1435
|
+
effect: string;
|
|
1436
|
+
}
|
|
1437
|
+
| {
|
|
1438
|
+
kind: "start-input";
|
|
1439
|
+
field: string;
|
|
1440
|
+
}
|
|
1441
|
+
| {
|
|
1442
|
+
kind: "context";
|
|
1443
|
+
key?: string;
|
|
1444
|
+
}
|
|
1445
|
+
| {
|
|
1446
|
+
kind: "subworkflow";
|
|
1447
|
+
definition: string;
|
|
1448
|
+
resolved: boolean;
|
|
1449
|
+
}
|
|
1450
|
+
| {
|
|
1451
|
+
kind: "unwritten-field";
|
|
1452
|
+
field: string;
|
|
1453
|
+
handlerPossible: boolean;
|
|
1454
|
+
};
|
|
1455
|
+
|
|
1224
1456
|
export declare interface AvailableAction {
|
|
1225
1457
|
activity: string;
|
|
1226
1458
|
activityStatus: ActivityStatus;
|
|
@@ -1251,10 +1483,10 @@ export declare interface AvailableActionsResult {
|
|
|
1251
1483
|
/**
|
|
1252
1484
|
* Type each caller-supplied name→value against the workflow's declared field
|
|
1253
1485
|
* entries — the engine takes typed {@link InitialFieldValue}s, and a value's
|
|
1254
|
-
* type IS its declared entry's kind. Only `input`-sourced entries read
|
|
1255
|
-
*
|
|
1256
|
-
*
|
|
1257
|
-
*
|
|
1486
|
+
* type IS its declared entry's kind. Only `input`-sourced entries read caller
|
|
1487
|
+
* values, so anything else fails here, naming the fields that ARE settable.
|
|
1488
|
+
* The engine repeats this structural validation at its contract boundary;
|
|
1489
|
+
* value validation also stays there.
|
|
1258
1490
|
*/
|
|
1259
1491
|
export declare function buildInitialFields({
|
|
1260
1492
|
declared,
|
|
@@ -1318,6 +1550,17 @@ export declare interface ChildrenArgs extends InstanceRefArgs {
|
|
|
1318
1550
|
activity?: string;
|
|
1319
1551
|
}
|
|
1320
1552
|
|
|
1553
|
+
export declare interface ChoiceOption {
|
|
1554
|
+
title: string;
|
|
1555
|
+
value: ChoiceValue;
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
export declare interface ChoiceOptions {
|
|
1559
|
+
list: ChoiceOption[];
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
export declare type ChoiceValue = string | number;
|
|
1563
|
+
|
|
1321
1564
|
/**
|
|
1322
1565
|
* The action half of the mirrored claim pair. `field` references an
|
|
1323
1566
|
* author-declared actor-valued entry (the pair's other half), resolved
|
|
@@ -1378,6 +1621,21 @@ export declare function clientConfigFromResource(res: WorkflowResource):
|
|
|
1378
1621
|
* resolves to a client, or the router throws. */
|
|
1379
1622
|
declare type ClientForGdr = (parsed: ParsedGdr) => WorkflowClient;
|
|
1380
1623
|
|
|
1624
|
+
/** Native project-user response returned by Sanity's project API. */
|
|
1625
|
+
export declare interface ClientProjectUser {
|
|
1626
|
+
readonly id: string;
|
|
1627
|
+
readonly displayName?: string;
|
|
1628
|
+
readonly email?: string;
|
|
1629
|
+
readonly imageUrl?: string | null;
|
|
1630
|
+
readonly [key: string]: unknown;
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
/** Project-user directory for CLI, MCP, and server runtimes using the engine client. */
|
|
1634
|
+
export declare function clientProjectUserDirectory(
|
|
1635
|
+
client: WorkflowClient,
|
|
1636
|
+
projectId: string,
|
|
1637
|
+
): ProjectUserDirectory<ClientProjectUser>;
|
|
1638
|
+
|
|
1381
1639
|
/**
|
|
1382
1640
|
* The engine's single source of "now".
|
|
1383
1641
|
*
|
|
@@ -1648,11 +1906,14 @@ export declare interface ConditionVar {
|
|
|
1648
1906
|
* the rest evaluate to `undefined` — and deploy rejects them at these
|
|
1649
1907
|
* sites; a cascade-fired action's per-token gate is `roles`, never its
|
|
1650
1908
|
* conditions.
|
|
1651
|
-
* 3. **The start
|
|
1652
|
-
* against a CANDIDATE (no instance exists yet):
|
|
1653
|
-
* the
|
|
1654
|
-
*
|
|
1655
|
-
*
|
|
1909
|
+
* 3. **The start contexts** — a definition's `start.filter` and
|
|
1910
|
+
* `start.allowed` evaluate against a CANDIDATE (no instance exists yet):
|
|
1911
|
+
* `*[...]` reads the WORKFLOW resource's dataset and none of the rendered
|
|
1912
|
+
* condition vars exist. The two split on what a surface can know:
|
|
1913
|
+
* `filter` is browse-time-pure (candidate document as root,
|
|
1914
|
+
* {@link START_FILTER_VARS} — no `$fields`, which cannot exist before
|
|
1915
|
+
* inputs do), `allowed` is the start-time permission predicate
|
|
1916
|
+
* ({@link START_ALLOWED_VARS} — `$fields` bound, never a root).
|
|
1656
1917
|
* 4. **Guard predicates** — NOT conditions. A lake mutation guard's
|
|
1657
1918
|
* `predicate` is groq-js **delta-mode** GROQ over a document mutation:
|
|
1658
1919
|
* `before()`/`after()`/`identity()` are dialect natives, and the wire
|
|
@@ -1666,7 +1927,7 @@ export declare interface ConditionVar {
|
|
|
1666
1927
|
* instance and its snapshot.
|
|
1667
1928
|
* - `'caller'` — rides the acting caller; without one the var is `undefined`
|
|
1668
1929
|
* (conditions referencing it fail closed). Author predicates may not read
|
|
1669
|
-
* these — they pre-evaluate
|
|
1930
|
+
* these — they pre-evaluate caller-free, per evaluation context.
|
|
1670
1931
|
* - `'spawn'` — bound only at spawn sites (the per-row `$row`).
|
|
1671
1932
|
*/
|
|
1672
1933
|
export declare type ConditionVarBinding = "always" | "caller" | "spawn";
|
|
@@ -1808,10 +2069,11 @@ export declare function contextMap(
|
|
|
1808
2069
|
|
|
1809
2070
|
/**
|
|
1810
2071
|
* A caller broke a public-API contract — a call the engine rejects
|
|
1811
|
-
*
|
|
2072
|
+
* without writing anything: an invalid `tag`, a `workflow.query` GROQ that
|
|
1812
2073
|
* never binds `$tag`, a bare id where a GDR URI is required, an action,
|
|
1813
|
-
* activity, or field the definition never declared
|
|
1814
|
-
*
|
|
2074
|
+
* activity, or field the definition never declared, or a `startInstance`
|
|
2075
|
+
* `instanceId` reused for a different start (or a discarded one). Fix the
|
|
2076
|
+
* call site; retrying cannot succeed.
|
|
1815
2077
|
*/
|
|
1816
2078
|
export declare class ContractViolationError extends WorkflowError<"contract-violation"> {
|
|
1817
2079
|
constructor(message: string);
|
|
@@ -1841,7 +2103,9 @@ export declare class ContractViolationError extends WorkflowError<"contract-viol
|
|
|
1841
2103
|
* `completeEffect` — the runtime still decides when to drain and
|
|
1842
2104
|
* reports outcomes via `completeEffect`.
|
|
1843
2105
|
*/
|
|
1844
|
-
export declare function createEngine
|
|
2106
|
+
export declare function createEngine<Client extends WorkflowClient>(
|
|
2107
|
+
args: CreateEngineArgs<Client>,
|
|
2108
|
+
): Engine;
|
|
1845
2109
|
|
|
1846
2110
|
/**
|
|
1847
2111
|
* The {@link EngineScopeArgs} scope pinned at construction, plus the
|
|
@@ -1851,8 +2115,11 @@ export declare function createEngine(args: CreateEngineArgs): Engine;
|
|
|
1851
2115
|
* partition is the only thing keeping reads and writes off the wrong
|
|
1852
2116
|
* environment.
|
|
1853
2117
|
*/
|
|
1854
|
-
export declare interface CreateEngineArgs
|
|
1855
|
-
|
|
2118
|
+
export declare interface CreateEngineArgs<
|
|
2119
|
+
Client extends WorkflowClient = WorkflowClient,
|
|
2120
|
+
> extends EngineScopeArgs {
|
|
2121
|
+
client: Client;
|
|
2122
|
+
effectHandlers?: Record<string, EffectHandler<Client>>;
|
|
1856
2123
|
missingHandler?: MissingHandlerPolicy;
|
|
1857
2124
|
loggerFactory?: LoggerFactory;
|
|
1858
2125
|
/**
|
|
@@ -1904,19 +2171,70 @@ export declare function createTelemetryIntake(args: {
|
|
|
1904
2171
|
}): TelemetryIntake;
|
|
1905
2172
|
|
|
1906
2173
|
/**
|
|
1907
|
-
* The
|
|
1908
|
-
*
|
|
1909
|
-
*
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
2174
|
+
* The append-only, machine-readable counterpart of the model log in
|
|
2175
|
+
* `DATAMODEL.md`. It records compatibility decisions; the prose log retains
|
|
2176
|
+
* the reasoning, absent-value semantics, and old-writer round-trip proof.
|
|
2177
|
+
*/
|
|
2178
|
+
export declare const DATA_MODEL_CHANGES: readonly [
|
|
2179
|
+
Readonly<{
|
|
2180
|
+
id: "governed-model-stamps";
|
|
2181
|
+
introducedInModel: 1;
|
|
2182
|
+
minReaderModel: 0;
|
|
2183
|
+
documentTypes: readonly ["definition", "instance"];
|
|
2184
|
+
compatibility: "additive";
|
|
2185
|
+
applicability: "unconditional";
|
|
2186
|
+
summary: "Definition and instance documents carry model provenance and reader-floor stamps.";
|
|
2187
|
+
}>,
|
|
2188
|
+
Readonly<{
|
|
2189
|
+
id: "subject-field-kind";
|
|
2190
|
+
introducedInModel: 2;
|
|
2191
|
+
minReaderModel: 0;
|
|
2192
|
+
documentTypes: readonly ["definition", "instance"];
|
|
2193
|
+
compatibility: "additive";
|
|
2194
|
+
applicability: "detectable";
|
|
2195
|
+
summary: "A workflow-level subject field identifies the document a workflow is about.";
|
|
2196
|
+
}>,
|
|
2197
|
+
Readonly<{
|
|
2198
|
+
id: "typed-scalar-choice-lists";
|
|
2199
|
+
introducedInModel: 2;
|
|
2200
|
+
minReaderModel: 2;
|
|
2201
|
+
documentTypes: readonly ["definition", "instance"];
|
|
2202
|
+
compatibility: "reader-floor";
|
|
2203
|
+
applicability: "detectable";
|
|
2204
|
+
summary: "Scalar fields may constrain writes to a persisted typed choice list.";
|
|
2205
|
+
}>,
|
|
2206
|
+
Readonly<{
|
|
2207
|
+
id: "action-semantics";
|
|
2208
|
+
introducedInModel: 2;
|
|
2209
|
+
minReaderModel: 0;
|
|
2210
|
+
documentTypes: readonly ["definition"];
|
|
2211
|
+
compatibility: "additive";
|
|
2212
|
+
applicability: "detectable";
|
|
2213
|
+
summary: "Ordinary actions may carry a closed bag of advisory workflow semantics.";
|
|
2214
|
+
}>,
|
|
2215
|
+
Readonly<{
|
|
2216
|
+
id: "inclusive-scalar-bounds";
|
|
2217
|
+
introducedInModel: 2;
|
|
2218
|
+
minReaderModel: 2;
|
|
2219
|
+
documentTypes: readonly ["definition", "instance"];
|
|
2220
|
+
compatibility: "reader-floor";
|
|
2221
|
+
applicability: "detectable";
|
|
2222
|
+
summary: "String, text, and number values may carry persisted inclusive bounds.";
|
|
2223
|
+
}>,
|
|
2224
|
+
];
|
|
2225
|
+
|
|
2226
|
+
/**
|
|
2227
|
+
* The maximum reader floor this writer can emit. Individual documents derive
|
|
2228
|
+
* their `minReaderModel` from the compatibility-bearing features actually
|
|
2229
|
+
* present; a document written at {@link DATA_MODEL_VERSION} may therefore
|
|
2230
|
+
* carry a lower floor. Raising this maximum is a declared, DATAMODEL.md-logged
|
|
2231
|
+
* decision that requires readers-first fleet sequencing.
|
|
1914
2232
|
*/
|
|
1915
|
-
export declare const DATA_MODEL_MIN_READER =
|
|
2233
|
+
export declare const DATA_MODEL_MIN_READER = 2;
|
|
1916
2234
|
|
|
1917
2235
|
/**
|
|
1918
2236
|
* The engine's persisted data-model version — the provenance half of
|
|
1919
|
-
*
|
|
2237
|
+
* the model stamp, written as `modelVersion` on every engine-owned
|
|
1920
2238
|
* document at its construction and persist choke-points. Conforms-to
|
|
1921
2239
|
* semantics: the stamp means "this document conforms to model N now" —
|
|
1922
2240
|
* instances are re-stamped on every full persist, so mixed-version fleets
|
|
@@ -1927,7 +2245,19 @@ export declare const DATA_MODEL_MIN_READER = 0;
|
|
|
1927
2245
|
* job. Declare every bump in `DATAMODEL.md`; the model-surface snapshot test
|
|
1928
2246
|
* keeps undeclared drift red.
|
|
1929
2247
|
*/
|
|
1930
|
-
export declare const DATA_MODEL_VERSION =
|
|
2248
|
+
export declare const DATA_MODEL_VERSION = 2;
|
|
2249
|
+
|
|
2250
|
+
export declare interface DataModelChange {
|
|
2251
|
+
readonly id: string;
|
|
2252
|
+
readonly introducedInModel: number;
|
|
2253
|
+
readonly minReaderModel: number;
|
|
2254
|
+
readonly documentTypes: readonly DataModelDocumentType[];
|
|
2255
|
+
readonly compatibility: "additive" | "reader-floor";
|
|
2256
|
+
readonly applicability: "unconditional" | "detectable";
|
|
2257
|
+
readonly summary: string;
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
export declare type DataModelDocumentType = "definition" | "instance";
|
|
1931
2261
|
|
|
1932
2262
|
/**
|
|
1933
2263
|
* Split a dataset resource id (`<projectId>.<dataset>`) into its parts — the
|
|
@@ -2103,6 +2433,10 @@ export declare interface DefinitionsForDocumentArgs {
|
|
|
2103
2433
|
* perspective the caller loaded the document with.
|
|
2104
2434
|
*/
|
|
2105
2435
|
document: CandidateDocument;
|
|
2436
|
+
/** Resource-qualified identity of `document`. Required when an applicable
|
|
2437
|
+
* definition's `start.filter` reads `$subjectHasInFlightInstance`; the
|
|
2438
|
+
* loaded value's bare `_id` cannot distinguish resources. */
|
|
2439
|
+
subject?: GdrUri;
|
|
2106
2440
|
}
|
|
2107
2441
|
|
|
2108
2442
|
/** A definition-level site address: every runtime {@link InsightSite}, plus
|
|
@@ -2227,13 +2561,17 @@ export declare interface DeployDefinitionResult {
|
|
|
2227
2561
|
export declare interface DeployDefinitionsArgs<
|
|
2228
2562
|
T extends WorkflowDefinitionInput<T> = WorkflowDefinition,
|
|
2229
2563
|
> {
|
|
2564
|
+
/** Reviewed literal acknowledging the installed writer's maximum reader-floor capability. */
|
|
2565
|
+
expectedMinReaderModel: typeof DATA_MODEL_MIN_READER;
|
|
2230
2566
|
/**
|
|
2231
2567
|
* Resource-alias bindings for this deploy (alias name → physical resource).
|
|
2232
|
-
*
|
|
2233
|
-
*
|
|
2234
|
-
*
|
|
2235
|
-
*
|
|
2236
|
-
*
|
|
2568
|
+
* A deploy-time abstraction ONLY: every `@<alias>:` reference in a
|
|
2569
|
+
* definition is expanded to its bound physical resource before the
|
|
2570
|
+
* deployed definition is fingerprinted and stored, and deploy fails closed
|
|
2571
|
+
* on an unbound alias. Aliases never exist past deploy — no stored
|
|
2572
|
+
* document carries one, the runtime never sees the map, and an
|
|
2573
|
+
* alias-shaped ref reaching a runtime boundary is rejected as malformed.
|
|
2574
|
+
* Omit for single-resource workflows (definitions referencing no aliases).
|
|
2237
2575
|
*/
|
|
2238
2576
|
resourceAliases?: ResourceAliases;
|
|
2239
2577
|
/** Authored definitions (the default — full compile-time checking) or
|
|
@@ -2282,7 +2620,7 @@ export declare type DeployedDefinition = WorkflowDefinition & {
|
|
|
2282
2620
|
*
|
|
2283
2621
|
* An aborted instance also no-ops: it parks on its stage forever, so a stale
|
|
2284
2622
|
* deploy landing after abort's retract would re-lock the subjects with no
|
|
2285
|
-
* remaining path to
|
|
2623
|
+
* remaining path to delete them. The gate is `abortedAt`, not `completedAt` —
|
|
2286
2624
|
* a normal move *into* a terminal stage stamps `completedAt` in the same
|
|
2287
2625
|
* persist and must still deploy that stage's guards.
|
|
2288
2626
|
*/
|
|
@@ -2294,6 +2632,7 @@ export declare function deployStageGuards(args: StageGuardArgs): Promise<void>;
|
|
|
2294
2632
|
* definitions themselves — carrying `resourceAliases` here is what keeps a diff
|
|
2295
2633
|
* fingerprinting the same physical content `deployDefinitions` would. */
|
|
2296
2634
|
export declare interface DeployTarget {
|
|
2635
|
+
expectedMinReaderModel: typeof DATA_MODEL_MIN_READER;
|
|
2297
2636
|
tag: string;
|
|
2298
2637
|
workflowResource: WorkflowResource;
|
|
2299
2638
|
resourceAliases?: ResourceAliases;
|
|
@@ -2308,18 +2647,37 @@ export declare interface DeployTarget {
|
|
|
2308
2647
|
*/
|
|
2309
2648
|
export declare function deriveActivityKind(activity: Activity): ActivityKind;
|
|
2310
2649
|
|
|
2650
|
+
export declare interface DeriveAutonomyOptions {
|
|
2651
|
+
/** Child definitions for `spawn` recursion, by definition `name` — the
|
|
2652
|
+
* deploy batch or previously deployed set. An unresolvable child reports
|
|
2653
|
+
* `conditional` with an unresolved wait. */
|
|
2654
|
+
children?: ReadonlyMap<string, WorkflowDefinition>;
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2311
2657
|
/**
|
|
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).
|
|
2658
|
+
* Who, if anyone, fires the activity's actions — derived ahead-of-time from
|
|
2659
|
+
* the activity's shape alone: `off-system` when `target` is present; else
|
|
2660
|
+
* `autonomous` (every action cascade-fired — no caller fires anything),
|
|
2661
|
+
* `interactive` (only fireAction-fired actions), or `hybrid` (mixed). An
|
|
2662
|
+
* actionless activity classifies `autonomous` vacuously (deploy's
|
|
2663
|
+
* terminal-reachability invariant rejects it anyway). Shape-only: whether
|
|
2664
|
+
* the activity actually RESOLVES without a caller is the causal question
|
|
2665
|
+
* `deriveWorkflowAutonomy` answers.
|
|
2318
2666
|
*/
|
|
2319
2667
|
export declare function deriveExecutorClassification(
|
|
2320
2668
|
activity: Activity,
|
|
2321
2669
|
): ExecutorClassification;
|
|
2322
2670
|
|
|
2671
|
+
/**
|
|
2672
|
+
* Derive the causal autonomy of a stored definition. Pure and instance-free;
|
|
2673
|
+
* conditions must parse (they did at define/deploy time — an unparseable one
|
|
2674
|
+
* throws groq-js's syntax error rather than guessing).
|
|
2675
|
+
*/
|
|
2676
|
+
export declare function deriveWorkflowAutonomy(
|
|
2677
|
+
definition: WorkflowDefinition,
|
|
2678
|
+
options?: DeriveAutonomyOptions,
|
|
2679
|
+
): WorkflowAutonomy;
|
|
2680
|
+
|
|
2323
2681
|
export declare type Describable =
|
|
2324
2682
|
| ConditionInsight
|
|
2325
2683
|
| FieldInsight
|
|
@@ -2337,6 +2695,12 @@ export declare function describeAtom(
|
|
|
2337
2695
|
fallback: boolean;
|
|
2338
2696
|
};
|
|
2339
2697
|
|
|
2698
|
+
/** One {@link AutonomyWait} as a phrase in the workflow vocabulary. */
|
|
2699
|
+
export declare function describeAutonomyWait(
|
|
2700
|
+
wait: AutonomyWait,
|
|
2701
|
+
ctx: DescribeContext,
|
|
2702
|
+
): InsightPhrase;
|
|
2703
|
+
|
|
2340
2704
|
/** Render one condition's insight as a checklist + frontier summary, in the
|
|
2341
2705
|
* workflow vocabulary. */
|
|
2342
2706
|
export declare function describeCondition(
|
|
@@ -2611,7 +2975,7 @@ export declare type DisabledReason =
|
|
|
2611
2975
|
/**
|
|
2612
2976
|
* The actor's grants on an involved subject's resource don't allow the
|
|
2613
2977
|
* content write the action's effects would perform there. Forecast
|
|
2614
|
-
* per-resource: each subject named by a `doc.ref`/`doc.refs`/`release.ref`
|
|
2978
|
+
* per-resource: each subject named by a `doc.ref`/`subject`/`doc.refs`/`release.ref`
|
|
2615
2979
|
* field entry outside the workflow's own resource is checked against
|
|
2616
2980
|
* THAT resource's ACL. Advisory like every engine verdict — the subject's
|
|
2617
2981
|
* lake still enforces; and it degrades open: a resource whose grants
|
|
@@ -2806,6 +3170,7 @@ export declare interface EditableFieldEvaluation {
|
|
|
2806
3170
|
name: string;
|
|
2807
3171
|
type: FieldKind;
|
|
2808
3172
|
title?: string;
|
|
3173
|
+
validation?: ScalarValidation;
|
|
2809
3174
|
/** Current resolved value; `undefined` until the field is first resolved. */
|
|
2810
3175
|
value: unknown;
|
|
2811
3176
|
/** Whether THIS actor may edit the field right now (window + predicate + guard). */
|
|
@@ -2920,6 +3285,15 @@ export declare type EditMode = "set" | "append" | "unset";
|
|
|
2920
3285
|
|
|
2921
3286
|
export declare type Effect = v.InferOutput<typeof EffectSchema>;
|
|
2922
3287
|
|
|
3288
|
+
/**
|
|
3289
|
+
* Every terminal state an effect run can record. `done` and `failed` are
|
|
3290
|
+
* reported through completion ({@link EffectCompletionStatus}); `cancelled`
|
|
3291
|
+
* is engine-stamped only — an abort cancelling the entry before dispatch.
|
|
3292
|
+
* A cancellation is not a failure: anything counting failures (dashboards,
|
|
3293
|
+
* retry tooling) must not count aborted-away effects among them.
|
|
3294
|
+
*/
|
|
3295
|
+
declare const EFFECT_RUN_STATUSES: readonly ["done", "failed", "cancelled"];
|
|
3296
|
+
|
|
2923
3297
|
/** The outcomes a completer may report through `completeEffect` — a run
|
|
2924
3298
|
* either succeeded or failed. `cancelled` is not reportable: only an abort
|
|
2925
3299
|
* stamps it, on entries that never dispatched. */
|
|
@@ -2928,6 +3302,20 @@ export declare type EffectCompletionStatus = Exclude<
|
|
|
2928
3302
|
"cancelled"
|
|
2929
3303
|
>;
|
|
2930
3304
|
|
|
3305
|
+
export declare type EffectHandler<
|
|
3306
|
+
Client extends WorkflowClient = WorkflowClient,
|
|
3307
|
+
> = {
|
|
3308
|
+
/** Bivariant so a concretely typed handler registry remains readable from
|
|
3309
|
+
* the non-generic Engine surface; only the typed drain invokes handlers. */
|
|
3310
|
+
bivarianceHack(
|
|
3311
|
+
params: Record<string, unknown>,
|
|
3312
|
+
ctx: EffectHandlerContext<Client>,
|
|
3313
|
+
): Promise<{
|
|
3314
|
+
outputs?: Record<string, unknown>;
|
|
3315
|
+
ops?: FieldOp[];
|
|
3316
|
+
} | void>;
|
|
3317
|
+
}["bivarianceHack"];
|
|
3318
|
+
|
|
2931
3319
|
/**
|
|
2932
3320
|
* External effect handler — invoked at drain time with the resolved
|
|
2933
3321
|
* `params` and a context. Returning `outputs` records them on the run's
|
|
@@ -2938,8 +3326,10 @@ export declare type EffectCompletionStatus = Exclude<
|
|
|
2938
3326
|
* applier as an action's field ops (so a created doc's ref enters `$fields`, or
|
|
2939
3327
|
* a screened outcome lands in a field the activity/stage gate reads). Effects
|
|
2940
3328
|
* report results as field state, never by flipping an activity status, so `ops`
|
|
2941
|
-
* excludes `status.set`.
|
|
2942
|
-
*
|
|
3329
|
+
* excludes `status.set`. Unlike definition-authored field ops, completion ops
|
|
3330
|
+
* have no authoring location from which to infer a target scope: every returned
|
|
3331
|
+
* op must explicitly set `target.scope` to `'workflow'` or `'stage'`. Throwing
|
|
3332
|
+
* marks the effect as failed (and returns no `ops`).
|
|
2943
3333
|
*
|
|
2944
3334
|
* **Delivery is at-least-once — a handler MAY run more than once for the
|
|
2945
3335
|
* same effect.** Two overlaps produce a double-run: the dispatching process
|
|
@@ -2957,38 +3347,38 @@ export declare type EffectCompletionStatus = Exclude<
|
|
|
2957
3347
|
* already completed; derive external-system identifiers from `ctx.effectKey`
|
|
2958
3348
|
* so the receiving system can dedupe the overlap the ledger can't see.
|
|
2959
3349
|
*/
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
}
|
|
3350
|
+
declare type EffectHandlerContext<Client extends WorkflowClient> = {
|
|
3351
|
+
/**
|
|
3352
|
+
* The exact concrete client supplied to `createEngine`, bound to the
|
|
3353
|
+
* workflow resource rather than an
|
|
3354
|
+
* engine wrapper. Its class identity, namespaces, configuration, and
|
|
3355
|
+
* credentials are preserved. Handler-owned requests are not automatically
|
|
3356
|
+
* tagged by the engine.
|
|
3357
|
+
*/
|
|
3358
|
+
client: Client;
|
|
3359
|
+
/**
|
|
3360
|
+
* Resolve the client bound to a subject doc's own resource. A handler
|
|
3361
|
+
* patches the SUBJECT (which may live in a different Sanity resource
|
|
3362
|
+
* than the instance — split-dataset GDR deploys); the drainer's
|
|
3363
|
+
* `completeEffect` writes the INSTANCE through {@link client}. One
|
|
3364
|
+
* client can't address both, so a handler that patches a foreign
|
|
3365
|
+
* subject must route its write here.
|
|
3366
|
+
*
|
|
3367
|
+
* Pass the subject's GDR — the URI a binding like `$fields.subject._id`
|
|
3368
|
+
* resolves to (the hydrated doc's `_id`), or a full
|
|
3369
|
+
* {@link GlobalDocumentReference}. Returns the `resourceClients` client
|
|
3370
|
+
* for that resource when one is mapped, {@link client} for the workflow
|
|
3371
|
+
* resource itself, and a sibling derived from {@link client}'s
|
|
3372
|
+
* credentials otherwise. Mapped clients are returned unchanged; an
|
|
3373
|
+
* unmapped foreign resource necessarily returns a configured sibling.
|
|
3374
|
+
* Throws if `ref` isn't a GDR — a bare id can't
|
|
3375
|
+
* be routed, so failing loud beats silently patching the wrong dataset.
|
|
3376
|
+
*/
|
|
3377
|
+
clientFor: (ref: GdrUri | GlobalDocumentReference) => WorkflowClient;
|
|
3378
|
+
instanceId: string;
|
|
3379
|
+
effectKey: string;
|
|
3380
|
+
log: (message: string, extra?: Record<string, unknown>) => void;
|
|
3381
|
+
};
|
|
2992
3382
|
|
|
2993
3383
|
export declare interface EffectHistoryEntry {
|
|
2994
3384
|
_key: string;
|
|
@@ -3095,14 +3485,7 @@ export declare function effectOutputsMap(
|
|
|
3095
3485
|
instance: Pick<WorkflowInstance, "effectHistory">,
|
|
3096
3486
|
): Record<string, unknown>;
|
|
3097
3487
|
|
|
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";
|
|
3488
|
+
export declare type EffectRunStatus = (typeof EFFECT_RUN_STATUSES)[number];
|
|
3106
3489
|
|
|
3107
3490
|
declare const EffectSchema: v.StrictObjectSchema<
|
|
3108
3491
|
{
|
|
@@ -3183,6 +3566,10 @@ export declare interface Engine {
|
|
|
3183
3566
|
/** The resolved telemetry logger ({@link noopTelemetry} unless injected) —
|
|
3184
3567
|
* exposed so adapters built on the engine log through the same seam. */
|
|
3185
3568
|
readonly telemetry: WorkflowTelemetryLogger;
|
|
3569
|
+
/** Resolve durable actor provenance through this engine's project client. */
|
|
3570
|
+
resolveActor: (
|
|
3571
|
+
args: ResolveClientActorArgs,
|
|
3572
|
+
) => Promise<ActorResolution<ClientProjectUser>>;
|
|
3186
3573
|
deployDefinitions: <T extends WorkflowDefinitionInput<T>>(
|
|
3187
3574
|
args: DeployDefinitionsArgs<T>,
|
|
3188
3575
|
) => Promise<DeployDefinitionsResult>;
|
|
@@ -3214,7 +3601,7 @@ export declare interface Engine {
|
|
|
3214
3601
|
getInstance: (args: InstanceRefArgs) => Promise<WorkflowInstance>;
|
|
3215
3602
|
/** The reactive {@link WatchSet} for an instance — every document whose
|
|
3216
3603
|
* change should re-evaluate it (the instance, its ancestors, and the docs
|
|
3217
|
-
* named by `doc.ref`/`doc.refs`/`release.ref` field entries on the workflow scope
|
|
3604
|
+
* named by `doc.ref`/`subject`/`doc.refs`/`release.ref` field entries on the workflow scope
|
|
3218
3605
|
* + current stage) as exploded {@link SubscriptionDocument}s, plus the
|
|
3219
3606
|
* instance's read perspective. Fetches the instance, then derives. A
|
|
3220
3607
|
* reactive adapter that already holds the live instance calls the pure
|
|
@@ -3229,8 +3616,9 @@ export declare interface Engine {
|
|
|
3229
3616
|
* its own; the consumer drives it. */
|
|
3230
3617
|
session: (args: SessionArgs) => InstanceSession;
|
|
3231
3618
|
/** Every lake mutation guard this instance registered, unioned across the
|
|
3232
|
-
* instance's own resource and the resource of each
|
|
3233
|
-
* GDR it holds in state. For coherency
|
|
3619
|
+
* instance's own resource and the resource of each
|
|
3620
|
+
* `doc.ref`/`subject`/`doc.refs` GDR it holds in state. For coherency
|
|
3621
|
+
* refresh and housekeeping. */
|
|
3234
3622
|
guardsForInstance: (args: InstanceRefArgs) => Promise<MutationGuardDoc[]>;
|
|
3235
3623
|
/** Every lake mutation guard a workflow deployed (any version), across the
|
|
3236
3624
|
* datasources its guards statically name — the workflow resource plus any
|
|
@@ -3249,26 +3637,39 @@ export declare interface Engine {
|
|
|
3249
3637
|
* in-flight instance whose watch-set includes `document` (a resource-qualified
|
|
3250
3638
|
* GDR URI). For a non-reactive, content-change-driven runtime deciding which
|
|
3251
3639
|
* instances a changed doc should `tick`. Matches the same ref set the forward
|
|
3252
|
-
* watch-set uses (self, ancestors, current-stage `doc.ref`/`doc.refs`/`release.ref`)
|
|
3640
|
+
* watch-set uses (self, ancestors, current-stage `doc.ref`/`subject`/`doc.refs`/`release.ref`)
|
|
3253
3641
|
* via the shared `collectWatchRefs`. Sorted by `startedAt` asc. */
|
|
3254
3642
|
instancesForDocument: (
|
|
3255
3643
|
args: InstancesForDocumentArgs,
|
|
3256
3644
|
) => Promise<WorkflowInstance[]>;
|
|
3257
3645
|
/** The startable half of {@link Engine.instancesForDocument}: the latest
|
|
3258
3646
|
* deployed version of every definition that applies to the LOADED candidate
|
|
3259
|
-
* document — startable,
|
|
3260
|
-
* `start.filter`
|
|
3261
|
-
* picker's filter, never
|
|
3647
|
+
* document — startable, the `subject`-kind entry accepts its `_type`, and
|
|
3648
|
+
* `start.filter` (browse-time-pure — `$fields` never binds) passes. All
|
|
3649
|
+
* matches, name ascending; advisory — a start picker's filter, never
|
|
3650
|
+
* enforcement. */
|
|
3262
3651
|
definitionsForDocument: (
|
|
3263
3652
|
args: DefinitionsForDocumentArgs,
|
|
3264
3653
|
) => Promise<DeployedDefinition[]>;
|
|
3654
|
+
/** Pre-flight `startInstance`'s gates for a definition + the
|
|
3655
|
+
* `initialFields` gathered so far: structurally invalid rows, the
|
|
3656
|
+
* `start.allowed` verdict with its insight, and still-missing required
|
|
3657
|
+
* inputs. `allowed` is the overall startability signal; `outcome` describes
|
|
3658
|
+
* only the condition. Bindability-aware — a
|
|
3659
|
+
* predicate reading a not-yet-supplied entry reports `'unevaluable'`
|
|
3660
|
+
* with the entries named in `unboundReads`, never a collapsed verdict.
|
|
3661
|
+
* Pure read; the enforcement moment is `startInstance` itself. */
|
|
3662
|
+
evaluateStart: (args: EvaluateStartArgs) => Promise<StartEvaluation>;
|
|
3265
3663
|
/** GROQ query against the engine's workflow resource. `$tag`
|
|
3266
3664
|
* is bound for tag-scoped filtering. */
|
|
3267
3665
|
query: <T = unknown>(args: QueryArgs) => Promise<T>;
|
|
3268
3666
|
/** Snapshot-aware GROQ — runs against the same in-memory view the
|
|
3269
|
-
* engine's filters see for the supplied instance. The
|
|
3270
|
-
*
|
|
3271
|
-
*
|
|
3667
|
+
* engine's filters see for the supplied instance. The caller-free
|
|
3668
|
+
* rendered scope cascade gates evaluate in is bound — the
|
|
3669
|
+
* instance-derived vars ({@link FILTER_SCOPE_VARS}) with the open
|
|
3670
|
+
* stage's overlay merged into `$fields`, `$assigned` at its caller-free
|
|
3671
|
+
* `false`, plus the author's pre-evaluated `$<predicate>` booleans —
|
|
3672
|
+
* ids in GDR URI form to match the snapshot's keying. */
|
|
3272
3673
|
queryInScope: <T = unknown>(args: QueryInScopeArgs) => Promise<T>;
|
|
3273
3674
|
/** List every pending effect on an instance. */
|
|
3274
3675
|
listPendingEffects: (args: InstanceRefArgs) => Promise<PendingEffect[]>;
|
|
@@ -3303,8 +3704,9 @@ export declare interface Engine {
|
|
|
3303
3704
|
* housekeeping exports — derives its working client onto this version via
|
|
3304
3705
|
* {@link WorkflowClient.withConfig}, and `resourceClients`-resolved clients
|
|
3305
3706
|
* are rebound the same way. A caller's configured `apiVersion` therefore
|
|
3306
|
-
* never reaches engine traffic (the caller's own client instance is
|
|
3307
|
-
* untouched).
|
|
3707
|
+
* never reaches engine-owned traffic (the caller's own client instance is
|
|
3708
|
+
* untouched). Effect handlers are host traffic and deliberately receive the
|
|
3709
|
+
* caller's configuration unchanged. The other exception is a client that lacks `withConfig` and so
|
|
3308
3710
|
* cannot be rebound — it must be built to serve this version; see
|
|
3309
3711
|
* {@link WorkflowClient.withConfig}.
|
|
3310
3712
|
*/
|
|
@@ -3347,8 +3749,9 @@ export declare interface EngineScopeArgs {
|
|
|
3347
3749
|
* docs that live in a different Sanity resource than the workflow). Called
|
|
3348
3750
|
* with a parsed GDR; return a client for that resource, or undefined to let
|
|
3349
3751
|
* the engine route it — `client` for the workflow resource itself, a
|
|
3350
|
-
* sibling derived from `client`'s credentials for anything else.
|
|
3351
|
-
*
|
|
3752
|
+
* sibling derived from `client`'s credentials for anything else. A served
|
|
3753
|
+
* resource is also part of the declared surface for runtime-supplied refs.
|
|
3754
|
+
* Engine-scope configuration — see `CreateEngineArgs`.
|
|
3352
3755
|
*/
|
|
3353
3756
|
resourceClients?: ResourceClientResolver;
|
|
3354
3757
|
/**
|
|
@@ -3368,6 +3771,16 @@ export declare interface EngineScopeArgs {
|
|
|
3368
3771
|
idempotencyTtlMs?: number;
|
|
3369
3772
|
}
|
|
3370
3773
|
|
|
3774
|
+
/**
|
|
3775
|
+
* Pull the {@link GlobalDocumentReference} values out of `doc.ref` /
|
|
3776
|
+
* `subject` / `doc.refs` (content) field entries. Content only — release
|
|
3777
|
+
* field entries come from {@link entryReleaseRefs}, so guard discovery (which
|
|
3778
|
+
* reads this via `collectEntryDocUris`) stays scoped to content docs.
|
|
3779
|
+
*/
|
|
3780
|
+
export declare function entryDocRefs(
|
|
3781
|
+
entries: unknown,
|
|
3782
|
+
): GlobalDocumentReference[];
|
|
3783
|
+
|
|
3371
3784
|
/**
|
|
3372
3785
|
* Pure error helpers — no client, no I/O. The one home for the engine's
|
|
3373
3786
|
* "coerce an unknown caught value" + "rethrow with context" idioms, so the
|
|
@@ -3465,24 +3878,45 @@ export declare function evaluateMutationGuard(args: {
|
|
|
3465
3878
|
context: MutationContext;
|
|
3466
3879
|
}): Promise<boolean>;
|
|
3467
3880
|
|
|
3881
|
+
/** Args for `evaluateStart` — the pre-flight read of `startInstance`'s gates
|
|
3882
|
+
* for a definition + the `initialFields` gathered so far (possibly none). */
|
|
3883
|
+
export declare interface EvaluateStartArgs {
|
|
3884
|
+
/** The definition's `name` — which deployed workflow would be started. */
|
|
3885
|
+
definition: string;
|
|
3886
|
+
/** Optional explicit version. Defaults to the highest deployed version. */
|
|
3887
|
+
version?: number;
|
|
3888
|
+
/**
|
|
3889
|
+
* The candidate seed, in `StartInstanceArgs.initialFields` shape. Partial
|
|
3890
|
+
* mid-form input is expected and safe: the verdict is BINDABILITY-AWARE —
|
|
3891
|
+
* when the predicate reads a declared entry these inputs don't supply,
|
|
3892
|
+
* `outcome` reports `'unevaluable'` and {@link StartEvaluation.unboundReads}
|
|
3893
|
+
* names the entries, instead of the collapsed answer GROQ equality would
|
|
3894
|
+
* otherwise produce (`null == x` is false, not null — a definitive-looking
|
|
3895
|
+
* verdict one more input could overturn, in either direction).
|
|
3896
|
+
*/
|
|
3897
|
+
initialFields?: InitialFieldValue[];
|
|
3898
|
+
}
|
|
3899
|
+
|
|
3468
3900
|
/**
|
|
3469
|
-
* Evaluate one `start.filter` in the start-filter context: `document` (may
|
|
3470
|
-
* absent — root
|
|
3471
|
-
* {@link
|
|
3472
|
-
* `analyzeCondition` says the filter reads the
|
|
3473
|
-
*
|
|
3474
|
-
*
|
|
3901
|
+
* Evaluate one `start.filter` in the start-filter context: `document` (may
|
|
3902
|
+
* be absent — a root read is then GROQ null, fail-closed or vacuous-pass by
|
|
3903
|
+
* shape) as the GROQ root, the {@link StartScope} bindings plus
|
|
3904
|
+
* `$definition`, and — when `analyzeCondition` says the filter reads the
|
|
3905
|
+
* dataset or the filter reads `$subjectHasInFlightInstance` — the scope's
|
|
3906
|
+
* fetched slice as `*`. Cheap pure evaluation otherwise: no I/O rides a
|
|
3907
|
+
* filter that needs neither. GROQ null ("can't decide") is `false` — every consumer of
|
|
3475
3908
|
* this verdict fails closed; a parse/evaluation THROW is a malformed
|
|
3476
|
-
* predicate, not an unevaluable one — rethrown loud, naming the definition
|
|
3477
|
-
*
|
|
3478
|
-
*
|
|
3909
|
+
* predicate, not an unevaluable one — rethrown loud, naming the definition,
|
|
3910
|
+
* so every read surface that evaluates the filter reports the same context.
|
|
3911
|
+
* A caller that omits the prospective subject required by the synthetic
|
|
3912
|
+
* variable also throws as a scope-contract error. A failed slice FETCH
|
|
3479
3913
|
* propagates as itself: transport trouble, never definition blame.
|
|
3480
3914
|
*/
|
|
3481
3915
|
export declare function evaluateStartFilter(args: {
|
|
3482
3916
|
filter: string;
|
|
3483
3917
|
definition: Pick<ApplicabilitySource, "name">;
|
|
3484
3918
|
document?: CandidateDocument | undefined;
|
|
3485
|
-
scope?:
|
|
3919
|
+
scope?: StartScope | undefined;
|
|
3486
3920
|
}): Promise<boolean>;
|
|
3487
3921
|
|
|
3488
3922
|
/**
|
|
@@ -3532,8 +3966,8 @@ export declare interface ExecutionContext {
|
|
|
3532
3966
|
}
|
|
3533
3967
|
|
|
3534
3968
|
/**
|
|
3535
|
-
* Executor classifications — who, if anyone, an activity
|
|
3536
|
-
* (derived; see `./activity-kind.ts`).
|
|
3969
|
+
* Executor classifications — who, if anyone, fires an activity's actions
|
|
3970
|
+
* (shape-derived; see `./activity-kind.ts`).
|
|
3537
3971
|
*/
|
|
3538
3972
|
export declare const EXECUTOR_CLASSIFICATION_DISPLAY: {
|
|
3539
3973
|
autonomous: {
|
|
@@ -3564,10 +3998,63 @@ export declare const EXECUTOR_CLASSIFICATIONS: readonly [
|
|
|
3564
3998
|
export declare type ExecutorClassification =
|
|
3565
3999
|
(typeof EXECUTOR_CLASSIFICATIONS)[number];
|
|
3566
4000
|
|
|
4001
|
+
/**
|
|
4002
|
+
* Expand every `@<alias>:` reference in a definition to the physical GDR prefix
|
|
4003
|
+
* its alias binds to, returning a definition that carries only physical
|
|
4004
|
+
* references. Fails closed — naming the definition + alias — when a referenced
|
|
4005
|
+
* alias isn't bound: the check that stops a portable definition from deploying
|
|
4006
|
+
* against the wrong (or no) resource.
|
|
4007
|
+
*
|
|
4008
|
+
* Runs at deploy (inside {@link planDefinitionDeploy}), BEFORE the content
|
|
4009
|
+
* fingerprint, so a deployed definition never carries a logical alias. The
|
|
4010
|
+
* stored references are physical, and a rebind (same source, a different alias
|
|
4011
|
+
* map) surfaces as changed content — a new version, never a silent shift in what
|
|
4012
|
+
* the workflow reads. A no-op when the definition references no aliases.
|
|
4013
|
+
*
|
|
4014
|
+
* Rewrites string VALUES only (via the shared {@link mapJsonStrings} deep-walk),
|
|
4015
|
+
* skipping the prose fields in {@link PROSE_KEYS}. A reference that stands alone
|
|
4016
|
+
* (the whole value is `@<alias>:<id>`, e.g. a literal `doc.ref`) must expand to a
|
|
4017
|
+
* well-formed GDR — a malformed one (`@content:a:b`, an empty id) is rejected
|
|
4018
|
+
* here rather than failing when an instance later reads it.
|
|
4019
|
+
*/
|
|
4020
|
+
export declare function expandResourceAliases(
|
|
4021
|
+
definition: WorkflowDefinition,
|
|
4022
|
+
resourceAliases: ResourceAliases | undefined,
|
|
4023
|
+
): WorkflowDefinition;
|
|
4024
|
+
|
|
3567
4025
|
export { explainCondition };
|
|
3568
4026
|
|
|
3569
4027
|
export { ExplainConditionArgs };
|
|
3570
4028
|
|
|
4029
|
+
/**
|
|
4030
|
+
* Explain one `start.allowed` in the start-allowed context: no root (the
|
|
4031
|
+
* subject rides `$fields.<entry>.id` — deploy rejects a root read), the
|
|
4032
|
+
* {@link StartScope} bindings plus `$definition` and the caller's `$fields`
|
|
4033
|
+
* map, and the scope's fetched slice as `*` when the predicate reads the
|
|
4034
|
+
* dataset. Returns the full {@link ConditionInsight} — `outcome` is the
|
|
4035
|
+
* verdict (`'satisfied'` allows; `'unsatisfied'`/`'unevaluable'` refuse,
|
|
4036
|
+
* fail-closed) and the atom breakdown is what lets a surface disable its
|
|
4037
|
+
* start affordance AND say why. One evaluator serves both moments:
|
|
4038
|
+
* `startInstance` enforces the outcome, the `evaluateStart` verb pre-flights
|
|
4039
|
+
* it.
|
|
4040
|
+
*
|
|
4041
|
+
* A dataset-reading predicate with no slice provider THROWS instead of
|
|
4042
|
+
* failing closed: unlike a picker that merely hides a row, this verdict
|
|
4043
|
+
* refuses starts — evaluating over an empty `*` would let a `count()`-style
|
|
4044
|
+
* rule pass vacuously, and a silent "not allowed" would misreport a caller
|
|
4045
|
+
* bug as an author verdict. Parse/evaluation throws rethrow naming the
|
|
4046
|
+
* definition, like the filter's; a failed slice FETCH propagates as itself.
|
|
4047
|
+
*/
|
|
4048
|
+
export declare function explainStartAllowed(args: {
|
|
4049
|
+
allowed: string;
|
|
4050
|
+
definition: Pick<ApplicabilitySource, "name" | "fields">;
|
|
4051
|
+
/** The caller's input entries as a `$fields` map — the engine verbs build
|
|
4052
|
+
* it with `startFieldsParam` (field resolution's projection), so the
|
|
4053
|
+
* predicate can only see values the resolution would persist. */
|
|
4054
|
+
fields: Record<string, unknown>;
|
|
4055
|
+
scope?: StartScope | undefined;
|
|
4056
|
+
}): Promise<ConditionInsight>;
|
|
4057
|
+
|
|
3571
4058
|
/**
|
|
3572
4059
|
* Extract the bare document `_id` from a GDR URI — what
|
|
3573
4060
|
* `*[_id == $docId]` in GROQ needs.
|
|
@@ -3610,6 +4097,10 @@ export declare const FIELD_KIND_DISPLAY: {
|
|
|
3610
4097
|
title: string;
|
|
3611
4098
|
description: string;
|
|
3612
4099
|
};
|
|
4100
|
+
subject: {
|
|
4101
|
+
title: string;
|
|
4102
|
+
description: string;
|
|
4103
|
+
};
|
|
3613
4104
|
"release.ref": {
|
|
3614
4105
|
title: string;
|
|
3615
4106
|
description: string;
|
|
@@ -3678,6 +4169,7 @@ declare const FIELD_SCOPES: readonly ["workflow", "stage", "activity"];
|
|
|
3678
4169
|
declare const FIELD_VALUE_KINDS: readonly [
|
|
3679
4170
|
"doc.ref",
|
|
3680
4171
|
"doc.refs",
|
|
4172
|
+
"subject",
|
|
3681
4173
|
"release.ref",
|
|
3682
4174
|
"string",
|
|
3683
4175
|
"text",
|
|
@@ -3721,6 +4213,8 @@ declare type FieldEntryFields<TEditable, TGroup> = FieldBase<
|
|
|
3721
4213
|
TGroup
|
|
3722
4214
|
> & {
|
|
3723
4215
|
type: FieldValueKind;
|
|
4216
|
+
options?: ChoiceOptions | undefined;
|
|
4217
|
+
validation?: ScalarValidation | undefined;
|
|
3724
4218
|
types?: string[] | undefined;
|
|
3725
4219
|
fields?: FieldShape[] | undefined;
|
|
3726
4220
|
of?: FieldShape[] | undefined;
|
|
@@ -3776,6 +4270,8 @@ export declare interface FieldShape {
|
|
|
3776
4270
|
name: string;
|
|
3777
4271
|
title?: string | undefined;
|
|
3778
4272
|
description?: string | undefined;
|
|
4273
|
+
options?: ChoiceOptions | undefined;
|
|
4274
|
+
validation?: ScalarValidation | undefined;
|
|
3779
4275
|
fields?: FieldShape[] | undefined;
|
|
3780
4276
|
of?: FieldShape[] | undefined;
|
|
3781
4277
|
}
|
|
@@ -3809,6 +4305,10 @@ declare type FieldValueKind = (typeof FIELD_VALUE_KINDS)[number];
|
|
|
3809
4305
|
export declare interface FieldValueMap {
|
|
3810
4306
|
"doc.ref": GlobalDocumentReference | null;
|
|
3811
4307
|
"doc.refs": GlobalDocumentReference[];
|
|
4308
|
+
/** THE document the workflow is about — same value as
|
|
4309
|
+
* {@link FieldValueMap."doc.ref"}, distinct kind so the runtime and UI
|
|
4310
|
+
* identify the subject deterministically (workflow scope, at most one). */
|
|
4311
|
+
subject: GlobalDocumentReference | null;
|
|
3812
4312
|
"release.ref": ReleaseRef | null;
|
|
3813
4313
|
string: string | null;
|
|
3814
4314
|
/** Multiline string — same value as {@link FieldValueMap.string}, distinct kind for rendering. */
|
|
@@ -3987,6 +4487,35 @@ export declare function gdrUri(
|
|
|
3987
4487
|
): GdrUri;
|
|
3988
4488
|
|
|
3989
4489
|
/**
|
|
4490
|
+
* The engine's reference value — deliberately NOT a lake reference, and
|
|
4491
|
+
* spelled differently on purpose (`id`/`type`, never `_ref`/`_id`):
|
|
4492
|
+
*
|
|
4493
|
+
* - **`id` is a URI, not a bare doc id**, because workflow references cross
|
|
4494
|
+
* resources (another dataset, a media library) and a bare `_id` is only
|
|
4495
|
+
* meaningful inside one dataset. Everything resource-aware — client
|
|
4496
|
+
* routing, spawn discovery, guard target resolution — reads the resource
|
|
4497
|
+
* out of this URI. It is stripped to a bare lake id at exactly one
|
|
4498
|
+
* boundary: `paramsForLake` (core/params.ts), when a query actually runs
|
|
4499
|
+
* against a lake.
|
|
4500
|
+
* - **`type` carries the target's schema type so consumers don't need a
|
|
4501
|
+
* fetch — as stamped by the ref's constructor, never verified against the
|
|
4502
|
+
* target.** Engine-built refs stamp it from real data (a projection row's
|
|
4503
|
+
* `_type`, the `releaseRef` constructor); a caller-supplied ref's `type`
|
|
4504
|
+
* is a trusted claim. Three advisory surfaces read it: the declared-subject-type
|
|
4505
|
+
* contract (an entry's `types: [...]` accepts/rejects incoming refs —
|
|
4506
|
+
* `refTypeIssues` at start `initialFields` and spawn `with`), start
|
|
4507
|
+
* applicability ("which definitions accept a doc of this `_type`" —
|
|
4508
|
+
* `acceptsDocumentType`), and guard `match.types` inference from resolved
|
|
4509
|
+
* targets (`resolveMatchTypes`). All must work when the target lives in a
|
|
4510
|
+
* resource the reader can't (or shouldn't) fetch from.
|
|
4511
|
+
*
|
|
4512
|
+
* In rendered GROQ this shape is what a reference-held value exposes
|
|
4513
|
+
* (`$fields.<entry>.id` / `.type`) — whereas `_id`/`_type` belong to
|
|
4514
|
+
* documents you hold (lake rows, `$row`, a dereferenced singular `doc.ref`).
|
|
4515
|
+
* The spelling is not a namespace guarantee: a content document can carry
|
|
4516
|
+
* its own `id`/`type` fields — what you're reading follows what the entry's
|
|
4517
|
+
* declared kind puts in your hand, never the key's spelling.
|
|
4518
|
+
*
|
|
3990
4519
|
* `TType` preserves the `type` literal the constructors ({@link refDataset},
|
|
3991
4520
|
* {@link gdrRef}, …) were called with, so a constructed ref satisfies
|
|
3992
4521
|
* literal-typed targets (e.g. a `release.ref` value's `"system.release"`).
|
|
@@ -4116,9 +4645,6 @@ export declare type Guard = v.InferOutput<typeof GuardSchema>;
|
|
|
4116
4645
|
*/
|
|
4117
4646
|
export declare const GUARD_DOC_TYPE = "temp.system.guard";
|
|
4118
4647
|
|
|
4119
|
-
/** Retracted predicate — unconditionally allows, lifting the guard. */
|
|
4120
|
-
export declare const GUARD_LIFTED_PREDICATE = "true";
|
|
4121
|
-
|
|
4122
4648
|
export declare const GUARD_OWNER = "robot:workflow-engine";
|
|
4123
4649
|
|
|
4124
4650
|
/**
|
|
@@ -4243,6 +4769,11 @@ declare const GuardReadSchema: v.VariantSchema<
|
|
|
4243
4769
|
/** Stored guards carry the printed string reads (the deploy resolver's input). */
|
|
4244
4770
|
declare const GuardSchema: v.StrictObjectSchema<
|
|
4245
4771
|
{
|
|
4772
|
+
/**
|
|
4773
|
+
* Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
|
|
4774
|
+
* guard's lake `_id` derives from `(instanceId, name)` at stage entry.
|
|
4775
|
+
* Unique per definition.
|
|
4776
|
+
*/
|
|
4246
4777
|
name: v.SchemaWithPipe<
|
|
4247
4778
|
readonly [
|
|
4248
4779
|
v.StringSchema<undefined>,
|
|
@@ -4314,8 +4845,9 @@ declare const GuardSchema: v.StrictObjectSchema<
|
|
|
4314
4845
|
/**
|
|
4315
4846
|
* Lake GROQ predicate — a distinct eval context: delta-mode GROQ
|
|
4316
4847
|
* reading the `before()`/`after()` natives, `mutation`, `guard`, and
|
|
4317
|
-
* `identity()`. Bare ids/fields only.
|
|
4318
|
-
*
|
|
4848
|
+
* `identity()`. Bare ids/fields only. Polarity: a result of strictly
|
|
4849
|
+
* `true` ALLOWS the matched mutation; anything else (false, null, an
|
|
4850
|
+
* evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
|
|
4319
4851
|
*/
|
|
4320
4852
|
predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
4321
4853
|
/**
|
|
@@ -4711,6 +5243,67 @@ export declare interface HydratedSnapshot {
|
|
|
4711
5243
|
*/
|
|
4712
5244
|
export declare function inFlightFilter(): string;
|
|
4713
5245
|
|
|
5246
|
+
/** Why one caller-supplied initial-field row cannot be consumed. */
|
|
5247
|
+
export declare type InitialFieldIssue = {
|
|
5248
|
+
index: number;
|
|
5249
|
+
name: string;
|
|
5250
|
+
type: FieldKind;
|
|
5251
|
+
} & (
|
|
5252
|
+
| {
|
|
5253
|
+
reason: "duplicate";
|
|
5254
|
+
duplicateIndexes: number[];
|
|
5255
|
+
}
|
|
5256
|
+
| {
|
|
5257
|
+
reason: "undeclared";
|
|
5258
|
+
}
|
|
5259
|
+
| {
|
|
5260
|
+
reason: "wrong-kind";
|
|
5261
|
+
expectedTypes: FieldKind[];
|
|
5262
|
+
}
|
|
5263
|
+
| {
|
|
5264
|
+
reason: "not-input";
|
|
5265
|
+
source:
|
|
5266
|
+
| "working-memory"
|
|
5267
|
+
| Exclude<NonNullable<FieldEntry["initialValue"]>["type"], "input">;
|
|
5268
|
+
}
|
|
5269
|
+
| ({
|
|
5270
|
+
reason: "invalid-scope";
|
|
5271
|
+
stage: string;
|
|
5272
|
+
declaredType: FieldKind;
|
|
5273
|
+
} & (
|
|
5274
|
+
| {
|
|
5275
|
+
scope: "stage";
|
|
5276
|
+
}
|
|
5277
|
+
| {
|
|
5278
|
+
scope: "activity";
|
|
5279
|
+
activity: string;
|
|
5280
|
+
}
|
|
5281
|
+
))
|
|
5282
|
+
);
|
|
5283
|
+
|
|
5284
|
+
/**
|
|
5285
|
+
* Explain every structural reason caller-supplied initial-field rows cannot
|
|
5286
|
+
* be consumed. Value-shape validation remains in the resolver because it
|
|
5287
|
+
* needs the matched declaration's complete schema.
|
|
5288
|
+
*/
|
|
5289
|
+
export declare function initialFieldIssues(
|
|
5290
|
+
args: ScopedInitialFieldDeclarations & {
|
|
5291
|
+
initialFields: readonly InitialFieldValue[];
|
|
5292
|
+
},
|
|
5293
|
+
): InitialFieldIssue[];
|
|
5294
|
+
|
|
5295
|
+
/**
|
|
5296
|
+
* Thrown before start writes when one or more caller-supplied `initialFields`
|
|
5297
|
+
* rows cannot be consumed by workflow-scope, input-sourced declarations.
|
|
5298
|
+
* `issues` is stable machine-readable remediation context; the message renders
|
|
5299
|
+
* the same complete set for logs and command-line callers.
|
|
5300
|
+
*/
|
|
5301
|
+
export declare class InitialFieldsInvalidError extends WorkflowError<"initial-fields-invalid"> {
|
|
5302
|
+
readonly definition?: string;
|
|
5303
|
+
readonly issues: InitialFieldIssue[];
|
|
5304
|
+
constructor(args: { definition?: string; issues: InitialFieldIssue[] });
|
|
5305
|
+
}
|
|
5306
|
+
|
|
4714
5307
|
/**
|
|
4715
5308
|
* Initial value for an `input`-sourced entry — what a caller supplies at
|
|
4716
5309
|
* `startInstance` (or `setStage`). Same discriminator shape as
|
|
@@ -4760,14 +5353,24 @@ export declare type InsightSite =
|
|
|
4760
5353
|
activity?: string;
|
|
4761
5354
|
};
|
|
4762
5355
|
|
|
5356
|
+
/**
|
|
5357
|
+
* Mint the Sanity document `_id` for a workflow instance — a fresh
|
|
5358
|
+
* {@link randomKey} suffix, so every instance (root or spawned child) gets a
|
|
5359
|
+
* unique doc id under its tag. Lives in the shell, not `core/`, because it
|
|
5360
|
+
* draws randomness; the deterministic {@link definitionDocId} is the pure-core
|
|
5361
|
+
* counterpart. Bare form — Sanity rejects `:` in document IDs, so this is
|
|
5362
|
+
* never a GDR URI.
|
|
5363
|
+
*/
|
|
5364
|
+
export declare function instanceDocId(tag: string): string;
|
|
5365
|
+
|
|
4763
5366
|
/**
|
|
4764
5367
|
* The per-instance guard filter — the single definition of "this instance's
|
|
4765
5368
|
* guards in one datasource". The engine's verdict load
|
|
4766
5369
|
* ({@link verdictGuardsForInstance}) fetches it once against the engine
|
|
4767
5370
|
* datasource; the reactive adapters feed the same query/params to their
|
|
4768
5371
|
* stores as a live subscription; {@link guardsForInstance} unions it across
|
|
4769
|
-
* datasources for housekeeping.
|
|
4770
|
-
*
|
|
5372
|
+
* datasources for housekeeping. Ordinary stage retraction deletes guards, so
|
|
5373
|
+
* results represent active persisted guard documents.
|
|
4771
5374
|
*/
|
|
4772
5375
|
export declare function instanceGuardQuery(instanceId: string): CompiledQuery;
|
|
4773
5376
|
|
|
@@ -4815,7 +5418,10 @@ export declare interface InstanceSession {
|
|
|
4815
5418
|
/** Replace the held content with the current values the consumer observed
|
|
4816
5419
|
* (last-write-wins, scoped). A self-doc updates the held instance only when
|
|
4817
5420
|
* its `_updatedAt` is strictly newer — an older or timestamp-equal echo is
|
|
4818
|
-
* ignored. Buffered if a commit is in flight
|
|
5421
|
+
* ignored. Buffered if a commit is in flight; a BUFFERED push that fails
|
|
5422
|
+
* validation surfaces on the NEXT `update` call (after that call's own
|
|
5423
|
+
* docs are processed), never from the commit itself — the commit's
|
|
5424
|
+
* outcome is never masked by a store echo's failure. */
|
|
4819
5425
|
update(docs: LoadedDoc[]): void;
|
|
4820
5426
|
/** Replace the held live guards (the consumer's guard stream,
|
|
4821
5427
|
* last-write-wins). Guards are a separate stream from the watch-set:
|
|
@@ -4858,10 +5464,11 @@ export declare interface InstanceSession {
|
|
|
4858
5464
|
* replace the target's staged rows (last write wins); appends accumulate.
|
|
4859
5465
|
* Tolerant where commits are loud: a target that doesn't resolve in the
|
|
4860
5466
|
* 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
|
|
5467
|
+
* (a skipped activity's field), a value that doesn't fit the field's
|
|
5468
|
+
* shape yet (a half-typed date), or a ref outside the declared resource
|
|
5469
|
+
* surface stages an INERT preview — no echo, no throw; the commit at the
|
|
5470
|
+
* semantic boundary is the loud surface. Never persisted — commit via
|
|
5471
|
+
* {@link InstanceSession.editField}. */
|
|
4865
5472
|
previewField(args: {
|
|
4866
5473
|
target: EditFieldTarget;
|
|
4867
5474
|
mode?: EditMode;
|
|
@@ -4879,8 +5486,10 @@ export declare interface InstancesForDocumentArgs {
|
|
|
4879
5486
|
|
|
4880
5487
|
/**
|
|
4881
5488
|
* The instance-list GROQ for a {@link InstancesQueryFilter}, ordered by
|
|
4882
|
-
* `startedAt` ascending
|
|
4883
|
-
*
|
|
5489
|
+
* `startedAt` ascending (descending + sliced under
|
|
5490
|
+
* {@link InstancesQueryFilter.limit}). Adapters subscribe to it;
|
|
5491
|
+
* {@link workflow.query}-style one-shot reads fetch it — both see the same
|
|
5492
|
+
* rows.
|
|
4884
5493
|
*/
|
|
4885
5494
|
export declare function instancesQuery(args: {
|
|
4886
5495
|
tag: string;
|
|
@@ -4924,6 +5533,14 @@ export declare interface InstancesQueryFilter {
|
|
|
4924
5533
|
stage?: string;
|
|
4925
5534
|
/** Include completed/aborted instances (default: in-flight only). */
|
|
4926
5535
|
includeCompleted?: boolean;
|
|
5536
|
+
/**
|
|
5537
|
+
* Cap the read to the NEWEST `limit` instances — the query flips to
|
|
5538
|
+
* `startedAt desc` and slices, so a bounded consumer (a dashboard over an
|
|
5539
|
+
* unbounded dataset) reads the most recent rows instead of the oldest.
|
|
5540
|
+
* Unlimited reads keep the ascending order adapters index by. Must be a
|
|
5541
|
+
* positive integer.
|
|
5542
|
+
*/
|
|
5543
|
+
limit?: number;
|
|
4927
5544
|
}
|
|
4928
5545
|
|
|
4929
5546
|
/**
|
|
@@ -4978,7 +5595,7 @@ export declare function isDefinitionApplicable(args: {
|
|
|
4978
5595
|
definition: ApplicabilitySource;
|
|
4979
5596
|
document: CandidateDocument;
|
|
4980
5597
|
/** Caller-side filter bindings — omit for the bare candidate-doc context. */
|
|
4981
|
-
scope?:
|
|
5598
|
+
scope?: StartScope;
|
|
4982
5599
|
}): Promise<boolean>;
|
|
4983
5600
|
|
|
4984
5601
|
/**
|
|
@@ -4997,13 +5614,14 @@ export declare function isFilterScopedOut(entry: {
|
|
|
4997
5614
|
export declare function isGdr(value: unknown): value is GlobalDocumentReference;
|
|
4998
5615
|
|
|
4999
5616
|
/**
|
|
5000
|
-
* Whether
|
|
5001
|
-
*
|
|
5002
|
-
*
|
|
5003
|
-
*
|
|
5617
|
+
* Whether an entry is caller-filled at start/spawn — the only source that
|
|
5618
|
+
* reads `initialFields`. Every other source (query/literal/fieldRead, or
|
|
5619
|
+
* working memory) resolves itself at materialisation, so a `$fields.<name>`
|
|
5620
|
+
* read of it can never bind on any read surface that evaluates a
|
|
5621
|
+
* `start.filter`. The deploy read-check keys on this.
|
|
5004
5622
|
*/
|
|
5005
|
-
export declare function
|
|
5006
|
-
|
|
5623
|
+
export declare function isInputSourced(
|
|
5624
|
+
entry: Pick<FieldEntry, "initialValue">,
|
|
5007
5625
|
): boolean;
|
|
5008
5626
|
|
|
5009
5627
|
/**
|
|
@@ -5027,6 +5645,32 @@ export declare function isNotesEntry(
|
|
|
5027
5645
|
}
|
|
5028
5646
|
>;
|
|
5029
5647
|
|
|
5648
|
+
/** Whether a project-user API failure explicitly means the user is absent. */
|
|
5649
|
+
export declare function isProjectUserNotFoundError(error: unknown): boolean;
|
|
5650
|
+
|
|
5651
|
+
/** Entry-level {@link isSingleDocRefKind}: narrows a resolved entry to the
|
|
5652
|
+
* single-GDR arms (`doc.ref` / `subject`) — the value is one GDR (or null)
|
|
5653
|
+
* and the entry may carry the accepted-target `types`. */
|
|
5654
|
+
export declare function isSingleDocRefEntry(
|
|
5655
|
+
entry: ResolvedFieldEntry,
|
|
5656
|
+
): entry is Extract<
|
|
5657
|
+
ResolvedFieldEntry,
|
|
5658
|
+
{
|
|
5659
|
+
_type: "doc.ref" | "subject";
|
|
5660
|
+
}
|
|
5661
|
+
>;
|
|
5662
|
+
|
|
5663
|
+
/**
|
|
5664
|
+
* Kinds whose value is a single content-document GDR — `doc.ref` and its
|
|
5665
|
+
* elevated alias `subject`. The one predicate behind every "this entry is one
|
|
5666
|
+
* document reference" branch (deref reads, query/spawn ref coercion, input
|
|
5667
|
+
* shape checks, watch-set collection), so the alias can't drift out of a
|
|
5668
|
+
* site.
|
|
5669
|
+
*/
|
|
5670
|
+
export declare function isSingleDocRefKind(
|
|
5671
|
+
kind: string,
|
|
5672
|
+
): kind is "doc.ref" | "subject";
|
|
5673
|
+
|
|
5030
5674
|
/**
|
|
5031
5675
|
* Whether a human may start this definition standalone (the default). A
|
|
5032
5676
|
* `lifecycle: 'child'` definition is spawn-only — instantiated by a parent via
|
|
@@ -5040,15 +5684,16 @@ export declare function isStartableDefinition(definition: {
|
|
|
5040
5684
|
}): boolean;
|
|
5041
5685
|
|
|
5042
5686
|
/**
|
|
5043
|
-
* The SUBJECT-ENTRY RULE:
|
|
5044
|
-
*
|
|
5045
|
-
* applicability's type
|
|
5046
|
-
*
|
|
5047
|
-
*
|
|
5048
|
-
* "counts as a subject" can't
|
|
5687
|
+
* The SUBJECT-ENTRY RULE: the `subject`-kind entry is what makes a definition
|
|
5688
|
+
* "about" a subject document — the kind is the discriminator, never a
|
|
5689
|
+
* heuristic over required refs. One predicate shared by applicability's type
|
|
5690
|
+
* matching (`acceptsDocumentType`), the autonomous-start deploy invariant,
|
|
5691
|
+
* and the root-read deploy check (a root-reading `start.filter` needs a
|
|
5692
|
+
* subject entry to bind a candidate root) — so "counts as a subject" can't
|
|
5693
|
+
* drift between them.
|
|
5049
5694
|
*/
|
|
5050
5695
|
export declare function isSubjectEntry(
|
|
5051
|
-
entry: Pick<FieldEntry, "
|
|
5696
|
+
entry: Pick<FieldEntry, "type">,
|
|
5052
5697
|
): boolean;
|
|
5053
5698
|
|
|
5054
5699
|
/**
|
|
@@ -5098,6 +5743,19 @@ export declare function isTodoListEntry(
|
|
|
5098
5743
|
* as null). The remaining columns stay loose (field validation owns them). */
|
|
5099
5744
|
export declare function isTodoListItem(row: unknown): row is TodoListItem;
|
|
5100
5745
|
|
|
5746
|
+
/**
|
|
5747
|
+
* True when the instance document exists but its start never finished: the
|
|
5748
|
+
* `create` committed, yet priming (stage entry, activities, guard deploy)
|
|
5749
|
+
* did not. The shape is legal and resumable — `startInstance` with the same
|
|
5750
|
+
* `instanceId` completes the outstanding commits. Readers should present it
|
|
5751
|
+
* as an incomplete start, never as a normal run sitting at its initial
|
|
5752
|
+
* stage. Terminal instances are excluded: an aborted never-primed husk
|
|
5753
|
+
* reads as aborted, not as still-resumable.
|
|
5754
|
+
*/
|
|
5755
|
+
export declare function isUnprimed(
|
|
5756
|
+
instance: Pick<WorkflowInstance, "stages" | "completedAt" | "abortedAt">,
|
|
5757
|
+
): boolean;
|
|
5758
|
+
|
|
5101
5759
|
/**
|
|
5102
5760
|
* Deterministic id so deploy/retract are query-free and idempotent. Derived
|
|
5103
5761
|
* from the guard's authored `name` — an author-controlled handle that stays
|
|
@@ -5164,6 +5822,15 @@ export declare interface LoadedDoc {
|
|
|
5164
5822
|
|
|
5165
5823
|
export declare type LoggerFactory = (name: string) => EngineLogger;
|
|
5166
5824
|
|
|
5825
|
+
/** A by-name reference to another workflow definition (an
|
|
5826
|
+
* `action.spawn.definition`). No `version` (or `'latest'`) means "the
|
|
5827
|
+
* highest deployed version at spawn time"; a numeric version pins one
|
|
5828
|
+
* deployed version permanently. */
|
|
5829
|
+
export declare interface LogicalRef {
|
|
5830
|
+
name: string;
|
|
5831
|
+
version?: number | "latest";
|
|
5832
|
+
}
|
|
5833
|
+
|
|
5167
5834
|
export declare type ManualTarget = v.InferOutput<
|
|
5168
5835
|
typeof StoredManualTargetSchema
|
|
5169
5836
|
>;
|
|
@@ -5190,7 +5857,7 @@ export { MAX_COUNTERFACTUAL_INDEX };
|
|
|
5190
5857
|
|
|
5191
5858
|
/**
|
|
5192
5859
|
* The oldest engine model that can safely read a persisted engine document.
|
|
5193
|
-
* The engine always writes the
|
|
5860
|
+
* The engine always writes the stamp pair, so a `modelVersion`
|
|
5194
5861
|
* with no `minReaderModel` is malformed foreign data — read conservatively:
|
|
5195
5862
|
* the stamp itself is the floor. A doc with neither is model 0 (floor 0).
|
|
5196
5863
|
*/
|
|
@@ -5396,6 +6063,8 @@ export declare interface MutationGuardDoc extends MutationGuardBody {
|
|
|
5396
6063
|
_updatedAt?: string;
|
|
5397
6064
|
}
|
|
5398
6065
|
|
|
6066
|
+
export declare const MutationGuardDocSchema: v.GenericSchema<MutationGuardDoc>;
|
|
6067
|
+
|
|
5399
6068
|
export declare interface MutationGuardMatch {
|
|
5400
6069
|
types?: string[];
|
|
5401
6070
|
/** Bare document ids (resource-local; both published and `drafts.` forms). */
|
|
@@ -5404,6 +6073,14 @@ export declare interface MutationGuardMatch {
|
|
|
5404
6073
|
actions: MutationGuardAction[];
|
|
5405
6074
|
}
|
|
5406
6075
|
|
|
6076
|
+
/** Every wait narrated, de-duplicated by phrase: same-named actions on
|
|
6077
|
+
* sibling activities are distinct waits that tell one story — consumers
|
|
6078
|
+
* want one line per story, not one per site. */
|
|
6079
|
+
export declare function narrateAutonomyWaits(
|
|
6080
|
+
waits: readonly AutonomyWait[],
|
|
6081
|
+
ctx: DescribeContext,
|
|
6082
|
+
): string[];
|
|
6083
|
+
|
|
5407
6084
|
/** The default logger: emit nothing. The engine's twin of `@sanity/telemetry`'s `noopLogger`. */
|
|
5408
6085
|
export declare const noopTelemetry: WorkflowTelemetryLogger;
|
|
5409
6086
|
|
|
@@ -5527,12 +6204,7 @@ export declare function parseDefinitionInput(
|
|
|
5527
6204
|
caller: string,
|
|
5528
6205
|
): WorkflowDefinition;
|
|
5529
6206
|
|
|
5530
|
-
/**
|
|
5531
|
-
* The ONE way to read an instance's frozen {@link WorkflowInstance.definitionSnapshot}
|
|
5532
|
-
* back into a {@link WorkflowDefinition} — wraps the parse so a corrupt
|
|
5533
|
-
* snapshot fails with the instance id attached instead of a bare
|
|
5534
|
-
* `SyntaxError`.
|
|
5535
|
-
*/
|
|
6207
|
+
/** Parse the frozen definition from a complete persisted instance. */
|
|
5536
6208
|
export declare function parseDefinitionSnapshot(
|
|
5537
6209
|
instance: WorkflowInstance,
|
|
5538
6210
|
): WorkflowDefinition;
|
|
@@ -5549,12 +6221,34 @@ export declare interface ParsedGdr {
|
|
|
5549
6221
|
documentId: string;
|
|
5550
6222
|
}
|
|
5551
6223
|
|
|
6224
|
+
declare type ParsedWorkflowConfig = v.InferOutput<typeof WorkflowConfigSchema>;
|
|
6225
|
+
|
|
6226
|
+
declare type ParsedWorkflowDeployment =
|
|
6227
|
+
ParsedWorkflowConfig["deployments"][number];
|
|
6228
|
+
|
|
5552
6229
|
/**
|
|
5553
6230
|
* Parse a GDR URI into its scheme + addressing parts. Throws on
|
|
5554
6231
|
* unknown scheme or malformed shape.
|
|
5555
6232
|
*/
|
|
5556
6233
|
export declare function parseGdr(uri: string): ParsedGdr;
|
|
5557
6234
|
|
|
6235
|
+
/**
|
|
6236
|
+
* Parse a fetched guard document, failing hard with a
|
|
6237
|
+
* {@link PersistedDocShapeError} naming the document and every offending
|
|
6238
|
+
* field. No model-version gate: the guard doc carries no stamp by design —
|
|
6239
|
+
* its `_type` cutover is its versioning event.
|
|
6240
|
+
*/
|
|
6241
|
+
export declare function parseGuardDocument(doc: unknown): MutationGuardDoc;
|
|
6242
|
+
|
|
6243
|
+
/**
|
|
6244
|
+
* Parse a fetched `sanity.workflow.instance` document, failing hard with a
|
|
6245
|
+
* {@link PersistedDocShapeError} naming the document and every offending
|
|
6246
|
+
* field. The caller's model-version gate (`assertReadableModel`) comes
|
|
6247
|
+
* FIRST — a doc from beyond the reader floor is a governed
|
|
6248
|
+
* `ModelVersionAheadError`, not a shape error.
|
|
6249
|
+
*/
|
|
6250
|
+
export declare function parseInstanceDocument(doc: unknown): WorkflowInstance;
|
|
6251
|
+
|
|
5558
6252
|
/**
|
|
5559
6253
|
* Parse a resource-shaped GDR (`<type>:<id>`, no document part) into the
|
|
5560
6254
|
* {@link WorkflowResource} it names. The one grammar for resource addresses —
|
|
@@ -5643,6 +6337,30 @@ export declare interface PendingEffectClaim {
|
|
|
5643
6337
|
leaseExpiresAt?: string;
|
|
5644
6338
|
}
|
|
5645
6339
|
|
|
6340
|
+
/**
|
|
6341
|
+
* A persisted engine-owned document failed its shape parse — the stored
|
|
6342
|
+
* field tree does not match what this engine's data model declares for the
|
|
6343
|
+
* doc type. Distinct from {@link ModelVersionAheadError} (a declared,
|
|
6344
|
+
* governed fence: upgrade the engine); this is UNGOVERNED corruption — a
|
|
6345
|
+
* document no conforming engine wrote — and the read fails hard instead of
|
|
6346
|
+
* letting the malformed value corrupt behavior downstream. The issues name
|
|
6347
|
+
* every offending field path.
|
|
6348
|
+
*/
|
|
6349
|
+
export declare class PersistedDocShapeError extends WorkflowError<"persisted-doc-shape"> {
|
|
6350
|
+
readonly documentId: string;
|
|
6351
|
+
readonly documentType: string;
|
|
6352
|
+
readonly issues: ValidationIssue[];
|
|
6353
|
+
constructor(args: {
|
|
6354
|
+
documentId: string;
|
|
6355
|
+
documentType: string;
|
|
6356
|
+
issues: ValidationIssue[];
|
|
6357
|
+
});
|
|
6358
|
+
}
|
|
6359
|
+
|
|
6360
|
+
export declare type PersonActor = Omit<Actor, "kind"> & {
|
|
6361
|
+
readonly kind: "person";
|
|
6362
|
+
};
|
|
6363
|
+
|
|
5646
6364
|
/**
|
|
5647
6365
|
* One row of the instance's idempotency ledger — a caller-supplied
|
|
5648
6366
|
* `idempotencyKey` a state-changing verb already committed under. Recorded in
|
|
@@ -5702,6 +6420,26 @@ export declare function projectToWatchRef(args: {
|
|
|
5702
6420
|
perspective: WorkflowPerspective | undefined;
|
|
5703
6421
|
}): SanityDocument;
|
|
5704
6422
|
|
|
6423
|
+
/** Host integration for current project-user data. */
|
|
6424
|
+
export declare interface ProjectUserDirectory<User> {
|
|
6425
|
+
/** Return `inaccessible` for lookup failures; directory methods must not reject. */
|
|
6426
|
+
readonly findById: (id: string) => Promise<ProjectUserLookup<User>>;
|
|
6427
|
+
readonly findByEmail?: (email: string) => Promise<ProjectUserLookup<User>>;
|
|
6428
|
+
}
|
|
6429
|
+
|
|
6430
|
+
export declare type ProjectUserLookup<User> =
|
|
6431
|
+
| {
|
|
6432
|
+
readonly status: "resolved";
|
|
6433
|
+
readonly user: User;
|
|
6434
|
+
}
|
|
6435
|
+
| {
|
|
6436
|
+
readonly status: "missing";
|
|
6437
|
+
}
|
|
6438
|
+
| {
|
|
6439
|
+
readonly status: "inaccessible";
|
|
6440
|
+
readonly cause?: unknown;
|
|
6441
|
+
};
|
|
6442
|
+
|
|
5705
6443
|
export declare interface QueryArgs {
|
|
5706
6444
|
groq: string;
|
|
5707
6445
|
params?: Record<string, unknown>;
|
|
@@ -5711,6 +6449,28 @@ export declare interface QueryInScopeArgs extends InstanceRefArgs, QueryArgs {}
|
|
|
5711
6449
|
|
|
5712
6450
|
export { quoted };
|
|
5713
6451
|
|
|
6452
|
+
export declare const READER_MODEL_ROLLOUT_URL =
|
|
6453
|
+
"https://github.com/sanity-io/workflows/blob/main/docs/reader-model-rollout.md";
|
|
6454
|
+
|
|
6455
|
+
/** A producer has not explicitly acknowledged this engine's writer capability. */
|
|
6456
|
+
export declare class ReaderModelAcknowledgementError extends WorkflowError<"reader-model-acknowledgement"> {
|
|
6457
|
+
readonly code = "WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
|
|
6458
|
+
readonly expectedMinReaderModel: unknown;
|
|
6459
|
+
readonly engineMinReaderModel = 2;
|
|
6460
|
+
readonly engineModelVersion = 2;
|
|
6461
|
+
readonly documentationUrl =
|
|
6462
|
+
"https://github.com/sanity-io/workflows/blob/main/docs/reader-model-rollout.md";
|
|
6463
|
+
constructor(expectedMinReaderModel: unknown, context?: string);
|
|
6464
|
+
}
|
|
6465
|
+
|
|
6466
|
+
/**
|
|
6467
|
+
* The one spelling of the instance read discipline — model gate
|
|
6468
|
+
* ({@link assertReadableModel}) first, shape parse
|
|
6469
|
+
* ({@link parseInstanceDocument}) second — shared by the point-read funnel
|
|
6470
|
+
* above and the list-read sites that fetch instance rows in bulk.
|
|
6471
|
+
*/
|
|
6472
|
+
export declare function readInstanceDoc(doc: SanityDocument): WorkflowInstance;
|
|
6473
|
+
|
|
5714
6474
|
/**
|
|
5715
6475
|
* Whether a watched ref reads RAW — never perspective-scoped. The
|
|
5716
6476
|
* instance, its ancestors, and its spawned children (all instance docs), and
|
|
@@ -5761,6 +6521,15 @@ export declare function refDataset<TType extends string = string>({
|
|
|
5761
6521
|
type: TType;
|
|
5762
6522
|
}): GlobalDocumentReference<TType>;
|
|
5763
6523
|
|
|
6524
|
+
/**
|
|
6525
|
+
* Kinds whose entries carry the accepted-target `types` facet — the
|
|
6526
|
+
* content-document reference kinds. `release.ref` is excluded: it points at a
|
|
6527
|
+
* release system doc whose type is fixed.
|
|
6528
|
+
*/
|
|
6529
|
+
export declare function refKindAcceptsTypes(
|
|
6530
|
+
kind: string,
|
|
6531
|
+
): kind is "doc.ref" | "doc.refs" | "subject";
|
|
6532
|
+
|
|
5764
6533
|
/** Make a GDR pointer to a Media-Library-resource doc. */
|
|
5765
6534
|
export declare function refMediaLibrary<TType extends string = string>({
|
|
5766
6535
|
resourceId,
|
|
@@ -5769,15 +6538,36 @@ export declare function refMediaLibrary<TType extends string = string>({
|
|
|
5769
6538
|
}: ResourceRefArgs<TType>): GlobalDocumentReference<TType>;
|
|
5770
6539
|
|
|
5771
6540
|
/**
|
|
5772
|
-
*
|
|
5773
|
-
*
|
|
5774
|
-
*
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
6541
|
+
* Thrown when a field write carries a ref to a resource outside the
|
|
6542
|
+
* declared surface. The write does not commit; the engine has not mutated
|
|
6543
|
+
* state.
|
|
6544
|
+
*/
|
|
6545
|
+
export declare class RefResourceUndeclaredError extends WorkflowError<"ref-resource-undeclared"> {
|
|
6546
|
+
readonly entryType: string;
|
|
6547
|
+
readonly entryName: string;
|
|
6548
|
+
readonly issues: string[];
|
|
6549
|
+
constructor(args: { entryName: string; entryType: string; issues: string[] });
|
|
6550
|
+
}
|
|
6551
|
+
|
|
6552
|
+
/**
|
|
6553
|
+
* Every spawn reference a definition carries, as logical
|
|
6554
|
+
* {@link LogicalRef} entries — the definition's outgoing edges in the
|
|
6555
|
+
* spawn-dependency graph. The one walk deploy ordering, delete's
|
|
6556
|
+
* referrer check, and external dependency tooling all share, so what
|
|
6557
|
+
* counts as a reference can never drift between them.
|
|
6558
|
+
*/
|
|
6559
|
+
export declare function refsOf(def: WorkflowDefinition): LogicalRef[];
|
|
6560
|
+
|
|
6561
|
+
/**
|
|
6562
|
+
* The GDR `type`s in a reference-kind ({@link refKindAcceptsTypes}) value
|
|
6563
|
+
* that the entry's declared accepted `types` reject — empty when the value
|
|
6564
|
+
* conforms, the entry declares no `types`, or the kind isn't a ref. A GDR's
|
|
6565
|
+
* `type` names the target document's schema type, so this is the
|
|
6566
|
+
* declared-target-type contract. Skips anything that isn't GDR-shaped — the
|
|
6567
|
+
* shape schemas scream about those. Boundaries that need their own error
|
|
6568
|
+
* framing (the spawn `with` projection gates its remediation hint on the
|
|
6569
|
+
* generic `"document"` type being among the rejects) read this; everything
|
|
6570
|
+
* else goes through {@link refTypeIssues} / {@link checkFieldValue}.
|
|
5781
6571
|
*/
|
|
5782
6572
|
export declare function rejectedRefTypes(args: {
|
|
5783
6573
|
entryType: string;
|
|
@@ -5865,12 +6655,18 @@ export declare class RequiredFieldNotProvidedError extends WorkflowError<"requir
|
|
|
5865
6655
|
});
|
|
5866
6656
|
}
|
|
5867
6657
|
|
|
5868
|
-
/**
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
6658
|
+
/** The known persisted-model requirements applicable to one canonical stored tree. */
|
|
6659
|
+
export declare function requiredModelFeatures(
|
|
6660
|
+
documentType: DataModelDocumentType,
|
|
6661
|
+
document: unknown,
|
|
6662
|
+
): readonly DataModelChange[];
|
|
6663
|
+
|
|
6664
|
+
/** The oldest engine model that can safely interpret one canonical stored tree. */
|
|
6665
|
+
export declare function requiredReaderModel(
|
|
6666
|
+
documentType: DataModelDocumentType,
|
|
6667
|
+
document: unknown,
|
|
6668
|
+
): number;
|
|
6669
|
+
|
|
5874
6670
|
export declare const RESERVED_CONDITION_VARS: readonly string[];
|
|
5875
6671
|
|
|
5876
6672
|
/**
|
|
@@ -5894,6 +6690,23 @@ export declare interface ResolveAccessArgs {
|
|
|
5894
6690
|
grantsFromPath?: string;
|
|
5895
6691
|
}
|
|
5896
6692
|
|
|
6693
|
+
/** Resolves person provenance without treating agent or system ids as user ids. */
|
|
6694
|
+
export declare function resolveActor<User>(
|
|
6695
|
+
directory: ProjectUserDirectory<User>,
|
|
6696
|
+
actor: Actor,
|
|
6697
|
+
): Promise<ActorResolution<User>>;
|
|
6698
|
+
|
|
6699
|
+
/** Resolve an actor through a plain engine client, without a UI adapter. */
|
|
6700
|
+
export declare function resolveClientActor(
|
|
6701
|
+
client: WorkflowClient,
|
|
6702
|
+
args: ResolveClientActorArgs,
|
|
6703
|
+
): Promise<ActorResolution<ClientProjectUser>>;
|
|
6704
|
+
|
|
6705
|
+
export declare interface ResolveClientActorArgs {
|
|
6706
|
+
readonly actor: Actor;
|
|
6707
|
+
readonly projectId: string;
|
|
6708
|
+
}
|
|
6709
|
+
|
|
5897
6710
|
/**
|
|
5898
6711
|
* A resolved field entry as the engine persists it on an instance.
|
|
5899
6712
|
* Discriminated by `_type` (bare — unique within this union); the `value`
|
|
@@ -5901,9 +6714,9 @@ export declare interface ResolveAccessArgs {
|
|
|
5901
6714
|
* `initialValue` is `{type:'query'}`, of any kind) additionally carries
|
|
5902
6715
|
* `resolvedAt` — the lake-read time — so `resolvedAt` is provenance-driven,
|
|
5903
6716
|
* not kind-specific. `object` / `array` entries carry their declared
|
|
5904
|
-
* sub-field shape (`fields` / `of`) — and
|
|
5905
|
-
* their declared accepted `types` — so the
|
|
5906
|
-
* op-time validation and rendering.
|
|
6717
|
+
* sub-field shape (`fields` / `of`) — and the reference kinds
|
|
6718
|
+
* ({@link refKindAcceptsTypes}) their declared accepted `types` — so the
|
|
6719
|
+
* instance is self-describing for op-time validation and rendering.
|
|
5907
6720
|
*/
|
|
5908
6721
|
export declare type ResolvedFieldEntry = {
|
|
5909
6722
|
[K in FieldKind]: {
|
|
@@ -5915,6 +6728,8 @@ export declare type ResolvedFieldEntry = {
|
|
|
5915
6728
|
value: FieldValueMap[K];
|
|
5916
6729
|
/** Lake-read time, present only on `query`-sourced entries. */
|
|
5917
6730
|
resolvedAt?: string;
|
|
6731
|
+
options?: ChoiceOptions;
|
|
6732
|
+
validation?: ScalarValidation;
|
|
5918
6733
|
} & (K extends "object"
|
|
5919
6734
|
? {
|
|
5920
6735
|
fields: FieldShape[];
|
|
@@ -5925,7 +6740,7 @@ export declare type ResolvedFieldEntry = {
|
|
|
5925
6740
|
of: FieldShape[];
|
|
5926
6741
|
}
|
|
5927
6742
|
: Record<never, never>) &
|
|
5928
|
-
(K extends "doc.ref" | "doc.refs"
|
|
6743
|
+
(K extends "doc.ref" | "doc.refs" | "subject"
|
|
5929
6744
|
? {
|
|
5930
6745
|
types?: string[];
|
|
5931
6746
|
}
|
|
@@ -5959,9 +6774,10 @@ export declare function resolveFieldEntry(
|
|
|
5959
6774
|
export declare type ResourceAliases = Record<string, WorkflowResource>;
|
|
5960
6775
|
|
|
5961
6776
|
/**
|
|
5962
|
-
* Collapse a deployment's `resourceAliases` bindings into the
|
|
5963
|
-
* {@link ResourceAliases} map (handle name → physical resource)
|
|
5964
|
-
*
|
|
6777
|
+
* Collapse a deployment's `resourceAliases` bindings into the
|
|
6778
|
+
* {@link ResourceAliases} map (handle name → physical resource) that
|
|
6779
|
+
* `deployDefinitions` expands `@<handle>:` references against. Deploy-time
|
|
6780
|
+
* only — the map never reaches any other verb.
|
|
5965
6781
|
*/
|
|
5966
6782
|
export declare function resourceAliasesToMap(
|
|
5967
6783
|
resourceAliases: WorkflowDeployment["resourceAliases"],
|
|
@@ -5974,10 +6790,13 @@ export declare function resourceAliasesToMap(
|
|
|
5974
6790
|
* engine route it — its own client for the workflow resource, a derived
|
|
5975
6791
|
* sibling ({@link WorkflowClient.withConfig}) for anything else.
|
|
5976
6792
|
*
|
|
5977
|
-
*
|
|
5978
|
-
*
|
|
5979
|
-
*
|
|
5980
|
-
*
|
|
6793
|
+
* Serving a resource also DECLARES it on the written-ref surface: the write
|
|
6794
|
+
* boundaries probe this resolver per ref, so narrowing a resolver rejects
|
|
6795
|
+
* refs to the resources it stops serving.
|
|
6796
|
+
*
|
|
6797
|
+
* Engine-owned verb scopes rebind resolved clients onto
|
|
6798
|
+
* `ENGINE_API_VERSION`. Effect handlers receive resolver clients unchanged
|
|
6799
|
+
* because handler traffic belongs to the host.
|
|
5981
6800
|
*/
|
|
5982
6801
|
export declare type ResourceClientResolver = (
|
|
5983
6802
|
parsed: ParsedGdr,
|
|
@@ -6008,11 +6827,18 @@ declare interface ResourceRefArgs<TType extends string> {
|
|
|
6008
6827
|
type: TType;
|
|
6009
6828
|
}
|
|
6010
6829
|
|
|
6830
|
+
export declare interface ResourceSurface {
|
|
6831
|
+
/** True when the parsed GDR targets a declared resource. */
|
|
6832
|
+
allows: (parsed: ParsedGdr) => boolean;
|
|
6833
|
+
/** Prose rendering of the declared surface, for rejection messages. */
|
|
6834
|
+
description: string;
|
|
6835
|
+
}
|
|
6836
|
+
|
|
6011
6837
|
/**
|
|
6012
|
-
* Retract every guard for a stage being exited
|
|
6838
|
+
* Retract every guard for a stage being exited by deleting it, but
|
|
6013
6839
|
* only once the instance has genuinely moved off that stage — or was aborted
|
|
6014
6840
|
* on it: an aborted instance keeps its `currentStage` (no stage move), so the
|
|
6015
|
-
* `abortedAt` stamp is what licenses
|
|
6841
|
+
* `abortedAt` stamp is what licenses retracting the stage it still occupies. The
|
|
6016
6842
|
* gate is `abortedAt`, not `completedAt` — normal completion parks the
|
|
6017
6843
|
* instance on a structurally terminal stage whose guards must stay live.
|
|
6018
6844
|
* Skip if it is still live on the stage (a concurrent loop-back re-entered
|
|
@@ -6079,8 +6905,52 @@ declare const RoleAliasesSchema: v.RecordSchema<
|
|
|
6079
6905
|
undefined
|
|
6080
6906
|
>;
|
|
6081
6907
|
|
|
6908
|
+
/** Whether two workflow resources address the same place. */
|
|
6909
|
+
export declare function sameResource(
|
|
6910
|
+
a: WorkflowResource,
|
|
6911
|
+
b: WorkflowResource,
|
|
6912
|
+
): boolean;
|
|
6913
|
+
|
|
6914
|
+
/** Inclusive scalar bounds. String/text bounds measure character length;
|
|
6915
|
+
* number bounds measure the numeric value. */
|
|
6916
|
+
export declare interface ScalarValidation {
|
|
6917
|
+
min?: number | undefined;
|
|
6918
|
+
max?: number | undefined;
|
|
6919
|
+
}
|
|
6920
|
+
|
|
6921
|
+
export declare function scalarValidationIssues(args: {
|
|
6922
|
+
entryType: string;
|
|
6923
|
+
validation: ScalarValidation | undefined;
|
|
6924
|
+
value: unknown;
|
|
6925
|
+
}): string[] | undefined;
|
|
6926
|
+
|
|
6927
|
+
/**
|
|
6928
|
+
* The DECLARED field tree of a runtime schema — every entry key (optional
|
|
6929
|
+
* keys marked `key?`), every enum vocabulary, every variant arm — walked out
|
|
6930
|
+
* of valibot's runtime shape. The declared twin of `fieldTreeShape` (which
|
|
6931
|
+
* walks a CONCRETE document): the model-surface gate pins persisted doc
|
|
6932
|
+
* types by what their schema declares, so an optional field no fixture
|
|
6933
|
+
* reaches is still ledger-visible. Recursive grammars (a field shape nesting
|
|
6934
|
+
* field shapes) close with a `'(circular)'` marker.
|
|
6935
|
+
*/
|
|
6936
|
+
export declare function schemaTreeShape(schema: v.GenericSchema): unknown;
|
|
6937
|
+
|
|
6082
6938
|
export { ScopeAssignment };
|
|
6083
6939
|
|
|
6940
|
+
export declare interface ScopedInitialFieldDeclarations {
|
|
6941
|
+
workflowFields: readonly FieldEntry[];
|
|
6942
|
+
stages?: readonly {
|
|
6943
|
+
name: string;
|
|
6944
|
+
fields?: readonly FieldEntry[] | undefined;
|
|
6945
|
+
activities?:
|
|
6946
|
+
| readonly {
|
|
6947
|
+
name: string;
|
|
6948
|
+
fields?: readonly FieldEntry[] | undefined;
|
|
6949
|
+
}[]
|
|
6950
|
+
| undefined;
|
|
6951
|
+
}[];
|
|
6952
|
+
}
|
|
6953
|
+
|
|
6084
6954
|
export { sentenceCase };
|
|
6085
6955
|
|
|
6086
6956
|
export declare interface SessionArgs {
|
|
@@ -6115,6 +6985,27 @@ export declare interface SiteConsequence {
|
|
|
6115
6985
|
after: ConditionOutcome;
|
|
6116
6986
|
}
|
|
6117
6987
|
|
|
6988
|
+
/** One statically invalid parent-to-child spawn contract found at deploy. */
|
|
6989
|
+
export declare type SpawnContractIssue =
|
|
6990
|
+
| {
|
|
6991
|
+
reason: "unresolved-definition";
|
|
6992
|
+
from: string;
|
|
6993
|
+
ref: string;
|
|
6994
|
+
}
|
|
6995
|
+
| {
|
|
6996
|
+
reason: "unconsumable-field";
|
|
6997
|
+
from: string;
|
|
6998
|
+
child: string;
|
|
6999
|
+
field: string;
|
|
7000
|
+
detail: string;
|
|
7001
|
+
};
|
|
7002
|
+
|
|
7003
|
+
/** Deploy refused one or more invalid static `spawn` contracts. */
|
|
7004
|
+
export declare class SpawnContractsInvalidError extends WorkflowError<"spawn-contracts-invalid"> {
|
|
7005
|
+
readonly issues: SpawnContractIssue[];
|
|
7006
|
+
constructor(args: { issues: SpawnContractIssue[]; message: string });
|
|
7007
|
+
}
|
|
7008
|
+
|
|
6118
7009
|
export declare type Stage = StageFields<
|
|
6119
7010
|
FieldEntry,
|
|
6120
7011
|
Activity,
|
|
@@ -6123,6 +7014,21 @@ export declare type Stage = StageFields<
|
|
|
6123
7014
|
Editable
|
|
6124
7015
|
>;
|
|
6125
7016
|
|
|
7017
|
+
/** A stage's rollup: progress through any exit transition, plus each
|
|
7018
|
+
* activity's own completion answer. */
|
|
7019
|
+
export declare interface StageAutonomy extends AutonomyAnswer {
|
|
7020
|
+
stage: string;
|
|
7021
|
+
activities: Record<string, AutonomyAnswer>;
|
|
7022
|
+
}
|
|
7023
|
+
|
|
7024
|
+
/** The stage slice of a rollup. Total by construction — the rollup derives
|
|
7025
|
+
* from the same `definition.stages` consumers iterate, so a miss is an
|
|
7026
|
+
* engine bug worth failing loud on. */
|
|
7027
|
+
export declare function stageAutonomyOf(
|
|
7028
|
+
autonomy: WorkflowAutonomy,
|
|
7029
|
+
stageName: string,
|
|
7030
|
+
): StageAutonomy;
|
|
7031
|
+
|
|
6126
7032
|
export declare interface StageEntry {
|
|
6127
7033
|
_key: string;
|
|
6128
7034
|
name: StageName;
|
|
@@ -6138,6 +7044,9 @@ export declare interface StageEvaluation {
|
|
|
6138
7044
|
stage: Stage;
|
|
6139
7045
|
activities: ActivityEvaluation[];
|
|
6140
7046
|
transitions: TransitionEvaluation[];
|
|
7047
|
+
/** The stage's causal-autonomy rollup — will it progress without a caller,
|
|
7048
|
+
* and what does it wait on. Definition-derived, identical for every actor. */
|
|
7049
|
+
autonomy: StageAutonomy;
|
|
6141
7050
|
}
|
|
6142
7051
|
|
|
6143
7052
|
/** Type-mirror of {@link stageFields}, parameterised over field/activity/transition/guard/editable. */
|
|
@@ -6170,18 +7079,35 @@ declare interface StageGuardArgs {
|
|
|
6170
7079
|
|
|
6171
7080
|
export declare type StageName = string;
|
|
6172
7081
|
|
|
7082
|
+
/**
|
|
7083
|
+
* The vars a definition's `start.allowed` reads — the start-time permission
|
|
7084
|
+
* dialect: everything the filter context binds ({@link START_FILTER_VARS})
|
|
7085
|
+
* plus `$fields`, which start time always has. No candidate root ever binds
|
|
7086
|
+
* here (the subject rides `$fields.<entry>.id`; a root read is
|
|
7087
|
+
* deploy-rejected). Pre-flights can omit not-yet-collected input bindings and
|
|
7088
|
+
* report those reads as provisional. Bound in one place: `startContextParams`
|
|
7089
|
+
* in the applicability evaluator.
|
|
7090
|
+
*/
|
|
7091
|
+
export declare const START_ALLOWED_VARS: readonly {
|
|
7092
|
+
name: string;
|
|
7093
|
+
label: string;
|
|
7094
|
+
description: string;
|
|
7095
|
+
}[];
|
|
7096
|
+
|
|
6173
7097
|
/**
|
|
6174
7098
|
* The vars a definition's `start.filter` reads — the start-filter dialect,
|
|
6175
7099
|
* not the rendered condition scope (no {@link ConditionVarBinding}: these
|
|
6176
7100
|
* bind only while the filter is evaluated on the READ side — the
|
|
6177
7101
|
* `definitionsForDocument` derivation and the Studio start control).
|
|
6178
|
-
* `startInstance` never evaluates the filter.
|
|
6179
|
-
*
|
|
6180
|
-
*
|
|
6181
|
-
*
|
|
7102
|
+
* `startInstance` never evaluates the filter. BROWSE-TIME-PURE: `$fields` is
|
|
7103
|
+
* deliberately absent — a `$fields` read is deploy-rejected with a pointer
|
|
7104
|
+
* to `start.allowed`. The synthetic subject variable requires a prospective
|
|
7105
|
+
* subject; evaluation throws when the caller omits that required scope.
|
|
7106
|
+
* Bound in one place: `startContextParams` in the applicability evaluator.
|
|
6182
7107
|
*/
|
|
6183
7108
|
export declare const START_FILTER_VARS: readonly {
|
|
6184
7109
|
name: string;
|
|
7110
|
+
label: string;
|
|
6185
7111
|
description: string;
|
|
6186
7112
|
}[];
|
|
6187
7113
|
|
|
@@ -6203,44 +7129,72 @@ export declare type StartBlock = StartFields & {
|
|
|
6203
7129
|
*/
|
|
6204
7130
|
export declare type StartContext = Record<string, unknown>;
|
|
6205
7131
|
|
|
7132
|
+
/**
|
|
7133
|
+
* What `evaluateStart` projects — the same gates `startInstance` enforces,
|
|
7134
|
+
* as renderable state. `allowed` and `missingRequired` are deliberately
|
|
7135
|
+
* orthogonal: a missing required input is a caller mistake (the verb throws
|
|
7136
|
+
* `RequiredFieldNotProvidedError` for it), never a `start.allowed` verdict.
|
|
7137
|
+
*/
|
|
7138
|
+
export declare interface StartEvaluation {
|
|
7139
|
+
/** Overall preflight startability: every supplied initial-field row is
|
|
7140
|
+
* valid and the `start.allowed` outcome is satisfied. `outcome` describes
|
|
7141
|
+
* only the condition; structurally invalid rows can therefore produce
|
|
7142
|
+
* `allowed: false` with `outcome: 'satisfied'`. */
|
|
7143
|
+
allowed: boolean;
|
|
7144
|
+
/**
|
|
7145
|
+
* Three-valued, BINDABILITY-AWARE verdict: `'unsatisfied'` is a definitive
|
|
7146
|
+
* no for these inputs (disable and explain), `'unevaluable'` means the
|
|
7147
|
+
* predicate can't be decided yet — either a null operand reached an
|
|
7148
|
+
* ordered comparison, or the predicate reads an entry `initialFields`
|
|
7149
|
+
* doesn't supply ({@link StartEvaluation.unboundReads} non-empty). Keep
|
|
7150
|
+
* the affordance enabled on `'unevaluable'`; `startInstance` still
|
|
7151
|
+
* enforces the final verdict, where absence is final rather than
|
|
7152
|
+
* provisional.
|
|
7153
|
+
*/
|
|
7154
|
+
outcome: ConditionOutcome;
|
|
7155
|
+
/** The `start.allowed` atom breakdown over the SUPPLIED inputs — what to
|
|
7156
|
+
* render next to a disabled start affordance. Present iff the definition
|
|
7157
|
+
* declares `allowed`. With `unboundReads` non-empty its own `outcome` may
|
|
7158
|
+
* be a collapsed provisional answer — the top-level `outcome` is the
|
|
7159
|
+
* trustworthy one. */
|
|
7160
|
+
insight?: ConditionInsight;
|
|
7161
|
+
/** The `$fields` entries the predicate reads that `initialFields` doesn't
|
|
7162
|
+
* supply — "fill these to decide". Non-empty forces `outcome:
|
|
7163
|
+
* 'unevaluable'`. Empty when the definition declares no `allowed`. */
|
|
7164
|
+
unboundReads: string[];
|
|
7165
|
+
/** Required input entries `initialFields` doesn't fill yet — the rows a
|
|
7166
|
+
* `startInstance` now would throw `RequiredFieldNotProvidedError` about. */
|
|
7167
|
+
missingRequired: {
|
|
7168
|
+
name: string;
|
|
7169
|
+
type: FieldEntry["type"];
|
|
7170
|
+
}[];
|
|
7171
|
+
/** Supplied rows `startInstance` would reject before writing. Empty means
|
|
7172
|
+
* every row targets a workflow-scope, input-sourced declaration exactly
|
|
7173
|
+
* once. Render these as corrections, not an authorization verdict. */
|
|
7174
|
+
invalidInitialFields: InitialFieldIssue[];
|
|
7175
|
+
}
|
|
7176
|
+
|
|
6206
7177
|
/** Type-mirror of {@link startFields}: how standalone runs of this workflow
|
|
6207
7178
|
* begin. Stored requires `kind` (desugar fills the `'interactive'` default);
|
|
6208
7179
|
* authoring may omit it — so each variant declares it. */
|
|
6209
7180
|
declare type StartFields = {
|
|
6210
7181
|
filter?: string | undefined;
|
|
7182
|
+
allowed?: string | undefined;
|
|
6211
7183
|
};
|
|
6212
7184
|
|
|
6213
7185
|
/**
|
|
6214
|
-
*
|
|
6215
|
-
*
|
|
6216
|
-
*
|
|
6217
|
-
*
|
|
6218
|
-
*
|
|
6219
|
-
*
|
|
7186
|
+
* Project caller-supplied `initialFields` into the `$fields` map the
|
|
7187
|
+
* start-allowed context binds: one key per declared `input`-sourced entry,
|
|
7188
|
+
* resolved through {@link suppliedFieldFor} — the predicate can only ever see
|
|
7189
|
+
* a value the input resolution would persist, and an undeclared supplied name
|
|
7190
|
+
* never leaks in. Unsupplied (or null-supplied) entries stay unbound, so a
|
|
7191
|
+
* read of one is GROQ null. Document references bind as their GDR envelopes
|
|
7192
|
+
* (`$fields.<entry>.id` is the GDR URI).
|
|
6220
7193
|
*/
|
|
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
|
-
}
|
|
7194
|
+
export declare function startFieldsParam(args: {
|
|
7195
|
+
entryDefs: readonly FieldEntry[];
|
|
7196
|
+
initialFields: readonly InitialFieldValue[];
|
|
7197
|
+
}): Record<string, unknown>;
|
|
6244
7198
|
|
|
6245
7199
|
export declare interface StartInstanceArgs {
|
|
6246
7200
|
/** The definition's `name` — which deployed workflow to instantiate. */
|
|
@@ -6256,10 +7210,11 @@ export declare interface StartInstanceArgs {
|
|
|
6256
7210
|
* `initialValue` resolution for query/working-memory entries).
|
|
6257
7211
|
*
|
|
6258
7212
|
* To start an instance "about" a specific document, declare a
|
|
6259
|
-
* `{ type: "
|
|
7213
|
+
* `{ type: "subject", name: "subject", initialValue: { type: "input" } }`
|
|
6260
7214
|
* entry on the workflow and pass
|
|
6261
|
-
* `{ type: "
|
|
6262
|
-
* Conditions then read it as `$fields.subject
|
|
7215
|
+
* `{ type: "subject", name: "subject", value: { id, type } }` here.
|
|
7216
|
+
* Conditions then read it as `$fields.subject`, and document pickers key
|
|
7217
|
+
* on the `subject` kind.
|
|
6263
7218
|
*/
|
|
6264
7219
|
initialFields?: InitialFieldValue[];
|
|
6265
7220
|
ancestors?: GlobalDocumentReference[];
|
|
@@ -6275,7 +7230,14 @@ export declare interface StartInstanceArgs {
|
|
|
6275
7230
|
* entry, so all forms read back the same under `$context.<name>`.
|
|
6276
7231
|
*/
|
|
6277
7232
|
context?: StartContext;
|
|
6278
|
-
/**
|
|
7233
|
+
/**
|
|
7234
|
+
* Caller-supplied id; auto-generated otherwise (mint one with
|
|
7235
|
+
* `instanceDocId`). This is start's idempotency key: a retry carrying the
|
|
7236
|
+
* same id resumes the earlier attempt's outstanding commits instead of
|
|
7237
|
+
* creating a duplicate — the per-instance request ledger can't cover the
|
|
7238
|
+
* create (it lives on the instance document), so id identity is the rail.
|
|
7239
|
+
* Inputs bind on the create only; a resume never re-reads them.
|
|
7240
|
+
*/
|
|
6279
7241
|
instanceId?: string;
|
|
6280
7242
|
/**
|
|
6281
7243
|
* URL path on the supplied client where the engine fetches the
|
|
@@ -6329,6 +7291,55 @@ export declare function startKindOf(definition: {
|
|
|
6329
7291
|
| undefined;
|
|
6330
7292
|
}): StartKind;
|
|
6331
7293
|
|
|
7294
|
+
/**
|
|
7295
|
+
* Thrown by `startInstance` when the definition's `start.allowed` predicate
|
|
7296
|
+
* is not satisfied for the supplied `initialFields` — evaluated false, or
|
|
7297
|
+
* GROQ null ("can't decide"; fail-closed, `insight.outcome` tells the two
|
|
7298
|
+
* apart). Carries the full {@link ConditionInsight} so a consumer renders
|
|
7299
|
+
* the same explanation the `evaluateStart` pre-flight would have shown.
|
|
7300
|
+
* There is no override arg — like `fireAction`, you don't bypass a verdict,
|
|
7301
|
+
* you change what produces it. Advisory under races like every engine-side
|
|
7302
|
+
* check.
|
|
7303
|
+
*/
|
|
7304
|
+
export declare class StartNotAllowedError extends WorkflowError<"start-not-allowed"> {
|
|
7305
|
+
readonly definition: string;
|
|
7306
|
+
readonly insight: ConditionInsight;
|
|
7307
|
+
constructor(args: { definition: string; insight: ConditionInsight });
|
|
7308
|
+
}
|
|
7309
|
+
|
|
7310
|
+
/**
|
|
7311
|
+
* Thrown when a start fails AFTER its create committed but BEFORE priming:
|
|
7312
|
+
* the instance document exists, unprimed (see {@link isUnprimed}) — a
|
|
7313
|
+
* genuinely failed start, but a RESUMABLE one. The error names the id so
|
|
7314
|
+
* every surface's failure message can point at the retry rail: retrying
|
|
7315
|
+
* `startInstance` with this `instanceId` finishes the start instead of
|
|
7316
|
+
* creating a duplicate; aborting the instance discards it.
|
|
7317
|
+
*/
|
|
7318
|
+
export declare class StartNotPrimedError extends WorkflowError<"start-not-primed"> {
|
|
7319
|
+
readonly instanceId: string;
|
|
7320
|
+
constructor(args: { instanceId: string; cause: unknown });
|
|
7321
|
+
}
|
|
7322
|
+
|
|
7323
|
+
/**
|
|
7324
|
+
* Thrown when a start's first cascade fails AFTER the instance was created
|
|
7325
|
+
* and primed: the run exists — stage entered, activities active, guards
|
|
7326
|
+
* deployed — it just hasn't auto-advanced to a stable stage yet. Callers
|
|
7327
|
+
* must not present this as a failed start: the workflow IS running, and a
|
|
7328
|
+
* `tick` (or retrying `startInstance` with the same `instanceId`) resumes
|
|
7329
|
+
* the settling.
|
|
7330
|
+
*/
|
|
7331
|
+
export declare class StartNotSettledError extends WorkflowError<"start-not-settled"> {
|
|
7332
|
+
readonly instanceId: string;
|
|
7333
|
+
/** The primed instance re-read after the cascade failure — absent when
|
|
7334
|
+
* that best-effort read also failed. */
|
|
7335
|
+
readonly instance?: WorkflowInstance;
|
|
7336
|
+
constructor(args: {
|
|
7337
|
+
instanceId: string;
|
|
7338
|
+
instance?: WorkflowInstance;
|
|
7339
|
+
cause: unknown;
|
|
7340
|
+
});
|
|
7341
|
+
}
|
|
7342
|
+
|
|
6332
7343
|
/**
|
|
6333
7344
|
* Why a definition can't be started standalone, or `undefined` when it can.
|
|
6334
7345
|
* Advisory — the engine itself does not refuse ({@link isStartableDefinition})
|
|
@@ -6339,6 +7350,43 @@ export declare function startRefusal(definition: {
|
|
|
6339
7350
|
lifecycle?: WorkflowLifecycle | undefined;
|
|
6340
7351
|
}): string | undefined;
|
|
6341
7352
|
|
|
7353
|
+
/**
|
|
7354
|
+
* The caller-side half of the start contexts — everything the evaluating
|
|
7355
|
+
* surface knows that the definition doesn't. Every member is optional
|
|
7356
|
+
* because the surfaces genuinely differ (a pure consumer may hold no clock):
|
|
7357
|
+
* except for the subject identity required by `$subjectHasInFlightInstance`,
|
|
7358
|
+
* an absent binding evaluates each read of it to GROQ null, and where that
|
|
7359
|
+
* null lands decides the verdict — a predicate that can't decide without
|
|
7360
|
+
* the binding fails closed, while a count-of-matches clause over values
|
|
7361
|
+
* every row stores passes vacuously (in GROQ null equals only null, so the
|
|
7362
|
+
* unbound read matches no stored value). The vars themselves are
|
|
7363
|
+
* inventoried in `START_FILTER_VARS` / `START_ALLOWED_VARS`; the caller's
|
|
7364
|
+
* `$fields` map is NOT scope — `start.filter` never binds it, and
|
|
7365
|
+
* `explainStartAllowed` takes it as its own argument.
|
|
7366
|
+
*/
|
|
7367
|
+
export declare interface StartScope {
|
|
7368
|
+
/** The engine's tag partition — binds `$tag`. */
|
|
7369
|
+
tag?: string | undefined;
|
|
7370
|
+
/** ISO clock reading — binds `$now`. */
|
|
7371
|
+
now?: string | undefined;
|
|
7372
|
+
/** Resource-qualified identity of the prospective subject. Required when
|
|
7373
|
+
* `start.filter` reads `$subjectHasInFlightInstance`; unlike a loaded
|
|
7374
|
+
* document's bare `_id`, this stays collision-free across resources. */
|
|
7375
|
+
subject?: GdrUri | undefined;
|
|
7376
|
+
/**
|
|
7377
|
+
* The WORKFLOW resource's dataset, for predicates that read it (`*[...]` or
|
|
7378
|
+
* a deref) or `$subjectHasInFlightInstance` — invoked lazily only when the
|
|
7379
|
+
* predicate needs it. A slice is fine as long as it covers what predicates
|
|
7380
|
+
* scan; the engine verbs supply EVERY instance of the tag, completed
|
|
7381
|
+
* included — `*` carries no hidden predicate, so authors qualify in-flight
|
|
7382
|
+
* themselves (`!defined(completedAt)`). Absent ⇒ a dataset-reading filter
|
|
7383
|
+
* fails closed (this surface cannot see the dataset, so it cannot decide),
|
|
7384
|
+
* while a dataset-reading `allowed` THROWS — see
|
|
7385
|
+
* {@link explainStartAllowed}.
|
|
7386
|
+
*/
|
|
7387
|
+
fetchDataset?: (() => Promise<unknown[]>) | undefined;
|
|
7388
|
+
}
|
|
7389
|
+
|
|
6342
7390
|
/**
|
|
6343
7391
|
* Declared editability of a field — the generic edit seam's gate. Default
|
|
6344
7392
|
* (absent) is NOT editable: a field is op-only engine working memory unless the
|
|
@@ -7181,6 +8229,29 @@ declare type TransitionFields = {
|
|
|
7181
8229
|
*/
|
|
7182
8230
|
export declare function tryParseGdr(uri: string): ParsedGdr | undefined;
|
|
7183
8231
|
|
|
8232
|
+
/**
|
|
8233
|
+
* The `$fields` entries a `start.allowed` predicate reads that `fields` does
|
|
8234
|
+
* not bind — the BINDABILITY rule every pre-flight surface applies before
|
|
8235
|
+
* trusting a verdict over possibly-incomplete inputs. GROQ equality against
|
|
8236
|
+
* a missing operand collapses to a definitive-looking answer (`null == x` is
|
|
8237
|
+
* false, not null), so a verdict that read an unbound entry is PROVISIONAL in
|
|
8238
|
+
* both directions: supplying the entry could overturn a refusal AND an
|
|
8239
|
+
* approval. Non-empty ⇒ report "can't decide yet" instead of the collapsed
|
|
8240
|
+
* verdict (the `evaluateStart` verb does; the Studio start control does).
|
|
8241
|
+
*
|
|
8242
|
+
* The GATE never consults this: at `startInstance` the supplied inputs are
|
|
8243
|
+
* final, so evaluating over genuine absence — including rules that WANT it,
|
|
8244
|
+
* like `!defined($fields.rush)` — is the correct semantics there.
|
|
8245
|
+
*
|
|
8246
|
+
* `fields` is a produced `$fields` map (`startFieldsParam`, or a surface's
|
|
8247
|
+
* seed map) — producers bind only own keys with real values, so key presence
|
|
8248
|
+
* IS the supplied-ness rule.
|
|
8249
|
+
*/
|
|
8250
|
+
export declare function unboundAllowedReads(
|
|
8251
|
+
allowed: string,
|
|
8252
|
+
fields: Record<string, unknown>,
|
|
8253
|
+
): string[];
|
|
8254
|
+
|
|
7184
8255
|
/**
|
|
7185
8256
|
* The diagnose idiom shared by every consumer: each unsatisfied exit
|
|
7186
8257
|
* transition with its insight summary. Consumers shape the result (the CLI
|
|
@@ -7221,27 +8292,13 @@ export declare function validateDefinition(
|
|
|
7221
8292
|
definition: WorkflowDefinition,
|
|
7222
8293
|
): void;
|
|
7223
8294
|
|
|
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
8295
|
export declare function validateTag(tag: string): void;
|
|
7244
8296
|
|
|
8297
|
+
declare interface ValidationIssue {
|
|
8298
|
+
path: ReadonlyArray<PropertyKey>;
|
|
8299
|
+
message: string;
|
|
8300
|
+
}
|
|
8301
|
+
|
|
7245
8302
|
export declare type ValueExpr = ValueExprInternal;
|
|
7246
8303
|
|
|
7247
8304
|
declare type ValueExprInternal =
|
|
@@ -7311,7 +8368,7 @@ export declare const wallClock: Clock;
|
|
|
7311
8368
|
export declare interface WatchSet {
|
|
7312
8369
|
/**
|
|
7313
8370
|
* Docs to subscribe to — instance + ancestors + the docs named by
|
|
7314
|
-
* `doc.ref`/`doc.refs`/`release.ref` field entries — deduped by
|
|
8371
|
+
* `doc.ref`/`subject`/`doc.refs`/`release.ref` field entries — deduped by
|
|
7315
8372
|
* `globalDocumentId`. Refs that aren't resource-qualified GDR URIs are
|
|
7316
8373
|
* skipped (without a resource there's nothing to subscribe against).
|
|
7317
8374
|
*/
|
|
@@ -7386,18 +8443,36 @@ export declare const workflow: {
|
|
|
7386
8443
|
/**
|
|
7387
8444
|
* Spawn a new workflow instance from a deployed definition.
|
|
7388
8445
|
*
|
|
7389
|
-
*
|
|
7390
|
-
*
|
|
7391
|
-
*
|
|
7392
|
-
*
|
|
7393
|
-
*
|
|
8446
|
+
* Two gates run before anything is written, in order: the required-input
|
|
8447
|
+
* check — a missing `required` input is a CALLER mistake
|
|
8448
|
+
* ({@link RequiredFieldNotProvidedError}) — then the definition's
|
|
8449
|
+
* `start.allowed` permission predicate, whose false/GROQ-null VERDICT
|
|
8450
|
+
* throws {@link StartNotAllowedError} (declaring the expression is the
|
|
8451
|
+
* opt-in; there is no override arg — pre-flight with `evaluateStart`).
|
|
8452
|
+
* Per-value SHAPE validation fires during field resolution, after the
|
|
8453
|
+
* verdict but still before any write. It does NOT evaluate `start.filter`:
|
|
8454
|
+
* that is a read-side visibility rule (see `definitionsForDocument`).
|
|
7394
8455
|
*
|
|
7395
8456
|
* Pins the snapshot at start-time, seeds the `context` bag, and enters
|
|
7396
8457
|
* the initial stage — fields resolve and every in-scope activity is
|
|
7397
8458
|
* born active. Then cascades until stable, so the initial stage's
|
|
7398
|
-
* `when: 'true'` triggers have fired by the time this returns.
|
|
7399
|
-
*
|
|
7400
|
-
*
|
|
8459
|
+
* `when: 'true'` triggers have fired by the time this returns.
|
|
8460
|
+
*
|
|
8461
|
+
* Start is three commits — create, prime, first cascade — and a supplied
|
|
8462
|
+
* `instanceId` is its idempotency key across them. When that id already
|
|
8463
|
+
* exists under this tag for the same start, the call RESUMES: input gates
|
|
8464
|
+
* and field resolution are skipped (those values were pinned at create)
|
|
8465
|
+
* and the outstanding commits run — the retry path for a start that
|
|
8466
|
+
* failed after its create landed (see `isUnprimed`). Reusing an id for a
|
|
8467
|
+
* DIFFERENT start (definition or explicit version mismatch) — or for an
|
|
8468
|
+
* unfinished start that was aborted (a discarded start) — throws
|
|
8469
|
+
* {@link ContractViolationError}. The mid-sequence failures are typed and
|
|
8470
|
+
* carry the retry id: a prime failure after the create committed throws
|
|
8471
|
+
* `StartNotPrimedError` (failed but resumable), and a cascade failure
|
|
8472
|
+
* after a successful prime throws `StartNotSettledError` — the run exists
|
|
8473
|
+
* by then and must not be reported as a failed start. `changed` is `true`
|
|
8474
|
+
* on a fresh start and rev-derived on a resume; `cascaded` reports how far
|
|
8475
|
+
* the instance auto-advanced.
|
|
7401
8476
|
*/
|
|
7402
8477
|
startInstance: (
|
|
7403
8478
|
rawArgs: Clocked<Telemetered<StartInstanceArgs & EngineScopeArgs>>,
|
|
@@ -7517,10 +8592,13 @@ export declare const workflow: {
|
|
|
7517
8592
|
* filters see for a given instance.
|
|
7518
8593
|
*
|
|
7519
8594
|
* Hydrates the instance's snapshot (instance + ancestors + every doc
|
|
7520
|
-
* declared by a `doc.ref` / `doc.refs` entry in scope), then
|
|
8595
|
+
* declared by a `doc.ref` / `subject` / `doc.refs` entry in scope), then
|
|
7521
8596
|
* evaluates the supplied GROQ in groq-js against that dataset. The
|
|
7522
|
-
* rendered scope
|
|
7523
|
-
*
|
|
8597
|
+
* caller-free rendered scope cascade gates evaluate in is auto-bound —
|
|
8598
|
+
* the instance-derived vars ({@link FILTER_SCOPE_VARS}) with the open
|
|
8599
|
+
* stage's overlay merged into `$fields`, `$assigned` at its caller-free
|
|
8600
|
+
* `false`, plus the author's pre-evaluated `$<predicate>` booleans —
|
|
8601
|
+
* ids in GDR URI form to match the snapshot's keying.
|
|
7524
8602
|
*
|
|
7525
8603
|
* Use when an external consumer (a UI, a debug pane, a test) wants
|
|
7526
8604
|
* to ask "what does the engine see for this workflow right now?"
|
|
@@ -7600,7 +8678,8 @@ export declare const workflow: {
|
|
|
7600
8678
|
* Inngest/durable worker, any server) that holds no instances in memory: a
|
|
7601
8679
|
* document changed; which instances should it `tick`? The watch-set covers
|
|
7602
8680
|
* the instance itself, its ancestors, and the docs named by
|
|
7603
|
-
* `doc.ref` / `doc.refs` / `release.ref` field entries on the
|
|
8681
|
+
* `doc.ref` / `subject` / `doc.refs` / `release.ref` field entries on the
|
|
8682
|
+
* workflow scope
|
|
7604
8683
|
* **and the current stage** — so a hand-rolled GROQ over `fields[]` gets it
|
|
7605
8684
|
* subtly wrong (misses stage-scope refs, `release.ref`, ancestors).
|
|
7606
8685
|
*
|
|
@@ -7629,21 +8708,44 @@ export declare const workflow: {
|
|
|
7629
8708
|
* deployed definition that APPLIES to `document` — what a start picker for
|
|
7630
8709
|
* it should offer. Loads the latest deployed version of each definition
|
|
7631
8710
|
* visible to the engine's tag and filters it through the derivation
|
|
7632
|
-
* ({@link applicableDefinitions}): startable ∧
|
|
8711
|
+
* ({@link applicableDefinitions}): startable ∧ the `subject`-kind entry
|
|
7633
8712
|
* 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
|
-
*
|
|
8713
|
+
* browse-time-pure start-filter context with `$tag`/`$definition`/`$now`
|
|
8714
|
+
* bound and the tag's instance slice (completed included) backing dataset
|
|
8715
|
+
* reads. `start.allowed` never participates — permission is a start-time
|
|
8716
|
+
* question; pre-flight it with {@link workflow.evaluateStart}.
|
|
7638
8717
|
*
|
|
7639
8718
|
* Takes the LOADED candidate document, not a ref — applicability evaluates
|
|
7640
|
-
* its content, under whatever perspective the caller read it with.
|
|
7641
|
-
*
|
|
7642
|
-
*
|
|
8719
|
+
* its content, under whatever perspective the caller read it with. A
|
|
8720
|
+
* resource-qualified `subject` accompanies it when a filter reads
|
|
8721
|
+
* `$subjectHasInFlightInstance`; a bare document id cannot identify a
|
|
8722
|
+
* cross-resource subject. Surfaces ALL matches (name ascending), no engine
|
|
8723
|
+
* ranking — presenting a picker or auto-picking is consumer policy.
|
|
8724
|
+
* Advisory like every engine-side check.
|
|
7643
8725
|
*/
|
|
7644
8726
|
definitionsForDocument: (
|
|
7645
8727
|
rawArgs: Clocked<DefinitionsForDocumentArgs & EngineScopeArgs>,
|
|
7646
8728
|
) => Promise<DeployedDefinition[]>;
|
|
8729
|
+
/**
|
|
8730
|
+
* Pre-flight the start gates for a definition + candidate `initialFields` —
|
|
8731
|
+
* the read `startInstance` enforces, as a {@link StartEvaluation} a surface
|
|
8732
|
+
* can render: `missingRequired` mirrors the input contract
|
|
8733
|
+
* ({@link RequiredFieldNotProvidedError}'s rows), and `allowed` /
|
|
8734
|
+
* `outcome` / `insight` carry the `start.allowed` verdict with its atom
|
|
8735
|
+
* breakdown — disable the start affordance on a definitive `false` and say
|
|
8736
|
+
* why. BINDABILITY-AWARE for partial mid-form inputs: when the predicate
|
|
8737
|
+
* reads an entry `initialFields` doesn't supply, `outcome` is
|
|
8738
|
+
* `'unevaluable'` and `unboundReads` names the entries ("fill these to
|
|
8739
|
+
* decide") instead of the collapsed answer GROQ equality would give —
|
|
8740
|
+
* this is the ONE deliberate divergence from the gate, where absence is
|
|
8741
|
+
* final, not provisional (a rule like `!defined($fields.rush)` genuinely
|
|
8742
|
+
* passes there when `rush` is absent). A definition with no
|
|
8743
|
+
* `start.allowed` is vacuously allowed, exactly like the verb. Pure read;
|
|
8744
|
+
* advisory under races — the enforcement moment is `startInstance` itself.
|
|
8745
|
+
*/
|
|
8746
|
+
evaluateStart: (
|
|
8747
|
+
rawArgs: Clocked<EvaluateStartArgs & EngineScopeArgs>,
|
|
8748
|
+
) => Promise<StartEvaluation>;
|
|
7647
8749
|
/**
|
|
7648
8750
|
* Permission helpers — Sanity ACL grants evaluated against documents
|
|
7649
8751
|
* via GROQ. Used by `workflow.evaluate` to soft-gate actions when the
|
|
@@ -7705,6 +8807,12 @@ export declare interface WorkflowAdminOverrideData extends InstanceScopedEventDa
|
|
|
7705
8807
|
changed: boolean;
|
|
7706
8808
|
}
|
|
7707
8809
|
|
|
8810
|
+
/** The whole-definition rollup: every stage must progress, so the workflow
|
|
8811
|
+
* verdict conjoins the stage verdicts. */
|
|
8812
|
+
export declare interface WorkflowAutonomy extends AutonomyAnswer {
|
|
8813
|
+
stages: StageAutonomy[];
|
|
8814
|
+
}
|
|
8815
|
+
|
|
7708
8816
|
export declare interface WorkflowClient {
|
|
7709
8817
|
fetch: <T = unknown>(
|
|
7710
8818
|
query: string,
|
|
@@ -7854,7 +8962,12 @@ export declare interface WorkflowCommitOptions {
|
|
|
7854
8962
|
tag?: string;
|
|
7855
8963
|
}
|
|
7856
8964
|
|
|
7857
|
-
export declare type WorkflowConfig =
|
|
8965
|
+
export declare type WorkflowConfig = Omit<
|
|
8966
|
+
ParsedWorkflowConfig,
|
|
8967
|
+
"deployments"
|
|
8968
|
+
> & {
|
|
8969
|
+
deployments: WorkflowDeployment[];
|
|
8970
|
+
};
|
|
7858
8971
|
|
|
7859
8972
|
declare const WorkflowConfigSchema: v.ObjectSchema<
|
|
7860
8973
|
{
|
|
@@ -7869,6 +8982,10 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
|
|
|
7869
8982
|
v.NonEmptyAction<string, "must not be empty">,
|
|
7870
8983
|
]
|
|
7871
8984
|
>;
|
|
8985
|
+
readonly expectedMinReaderModel: v.OptionalSchema<
|
|
8986
|
+
v.CustomSchema<2, undefined>,
|
|
8987
|
+
undefined
|
|
8988
|
+
>;
|
|
7872
8989
|
readonly tag: v.SchemaWithPipe<
|
|
7873
8990
|
readonly [
|
|
7874
8991
|
v.StringSchema<undefined>,
|
|
@@ -8130,6 +9247,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
|
|
|
8130
9247
|
v.MinLengthAction<
|
|
8131
9248
|
{
|
|
8132
9249
|
name: string;
|
|
9250
|
+
expectedMinReaderModel?: 2 | undefined;
|
|
8133
9251
|
tag: string;
|
|
8134
9252
|
workflowResource:
|
|
8135
9253
|
| {
|
|
@@ -8190,6 +9308,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
|
|
|
8190
9308
|
v.CheckAction<
|
|
8191
9309
|
{
|
|
8192
9310
|
name: string;
|
|
9311
|
+
expectedMinReaderModel?: 2 | undefined;
|
|
8193
9312
|
tag: string;
|
|
8194
9313
|
workflowResource:
|
|
8195
9314
|
| {
|
|
@@ -8351,7 +9470,12 @@ declare const WorkflowDefinitionSchema: v.GenericSchema<
|
|
|
8351
9470
|
WorkflowFields<FieldEntry, Stage, StartBlock>
|
|
8352
9471
|
>;
|
|
8353
9472
|
|
|
8354
|
-
export declare type WorkflowDeployment =
|
|
9473
|
+
export declare type WorkflowDeployment = Omit<
|
|
9474
|
+
ParsedWorkflowDeployment,
|
|
9475
|
+
"expectedMinReaderModel"
|
|
9476
|
+
> & {
|
|
9477
|
+
expectedMinReaderModel: typeof DATA_MODEL_MIN_READER;
|
|
9478
|
+
};
|
|
8355
9479
|
|
|
8356
9480
|
export declare const WorkflowEffectCompleted: WorkflowTelemetryEvent<WorkflowEffectCompletedData>;
|
|
8357
9481
|
|
|
@@ -8399,23 +9523,31 @@ export declare abstract class WorkflowError<
|
|
|
8399
9523
|
|
|
8400
9524
|
export declare type WorkflowErrorKind =
|
|
8401
9525
|
| "action-disabled"
|
|
9526
|
+
| "start-not-allowed"
|
|
8402
9527
|
| "edit-field-denied"
|
|
8403
9528
|
| "mutation-guard-denied"
|
|
8404
9529
|
| "action-params-invalid"
|
|
8405
9530
|
| "effect-ops-invalid"
|
|
8406
9531
|
| "effect-outputs-invalid"
|
|
8407
9532
|
| "required-field-not-provided"
|
|
9533
|
+
| "initial-fields-invalid"
|
|
8408
9534
|
| "workflow-state-diverged"
|
|
8409
9535
|
| "partial-guard-deploy"
|
|
9536
|
+
| "start-not-primed"
|
|
9537
|
+
| "start-not-settled"
|
|
8410
9538
|
| "concurrent-fire-action"
|
|
8411
9539
|
| "concurrent-edit-field"
|
|
8412
9540
|
| "concurrent-complete-effect"
|
|
8413
9541
|
| "cascade-limit"
|
|
8414
9542
|
| "field-value-shape"
|
|
9543
|
+
| "ref-resource-undeclared"
|
|
8415
9544
|
| "model-version-ahead"
|
|
9545
|
+
| "reader-model-acknowledgement"
|
|
9546
|
+
| "persisted-doc-shape"
|
|
8416
9547
|
| "instance-not-found"
|
|
8417
9548
|
| "definition-not-found"
|
|
8418
9549
|
| "definition-in-use"
|
|
9550
|
+
| "spawn-contracts-invalid"
|
|
8419
9551
|
| "effect-not-found"
|
|
8420
9552
|
| "missing-effect-handler"
|
|
8421
9553
|
| "contract-violation";
|
|
@@ -8443,6 +9575,14 @@ export declare interface WorkflowEvaluation {
|
|
|
8443
9575
|
* Empty when no condition reads a field.
|
|
8444
9576
|
*/
|
|
8445
9577
|
fieldInsights: FieldInsight[];
|
|
9578
|
+
/**
|
|
9579
|
+
* The whole definition's causal-autonomy rollup: per activity, per stage,
|
|
9580
|
+
* and workflow-wide — will each level resolve without a caller, and what
|
|
9581
|
+
* does it wait on. Static (no instance state), stamped here so every
|
|
9582
|
+
* consumer reads one derivation. Spawn children are not resolved at
|
|
9583
|
+
* evaluation time, so their legs report `conditional`.
|
|
9584
|
+
*/
|
|
9585
|
+
autonomy: WorkflowAutonomy;
|
|
8446
9586
|
}
|
|
8447
9587
|
|
|
8448
9588
|
export declare interface WorkflowFetchOptions {
|
|
@@ -8472,6 +9612,12 @@ export declare interface WorkflowFieldEditedData extends InstanceScopedEventData
|
|
|
8472
9612
|
|
|
8473
9613
|
/** Type-mirror of {@link workflowFields}, parameterised over field/stage/start. */
|
|
8474
9614
|
declare type WorkflowFields<TField, TStage, TStart> = {
|
|
9615
|
+
/**
|
|
9616
|
+
* Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
|
|
9617
|
+
* name interpolates into every deployed document id
|
|
9618
|
+
* (`<tag>.<name>.v<version>`). Stable identity — instances pin to it,
|
|
9619
|
+
* subworkflows resolve by it.
|
|
9620
|
+
*/
|
|
8475
9621
|
name: string;
|
|
8476
9622
|
title: string;
|
|
8477
9623
|
description?: string | undefined;
|
|
@@ -8497,9 +9643,9 @@ export declare interface WorkflowInstance extends SanityDocument {
|
|
|
8497
9643
|
modelVersion?: number;
|
|
8498
9644
|
/**
|
|
8499
9645
|
* Reader floor — the oldest engine data model that can safely interpret
|
|
8500
|
-
* this document
|
|
8501
|
-
* {@link
|
|
8502
|
-
*
|
|
9646
|
+
* this document. Derived from features actually present, bounded by
|
|
9647
|
+
* {@link DATA_MODEL_MIN_READER}, and written alongside
|
|
9648
|
+
* {@link WorkflowInstance.modelVersion}. Full persists never lower it.
|
|
8503
9649
|
*/
|
|
8504
9650
|
minReaderModel?: number;
|
|
8505
9651
|
/**
|
|
@@ -8606,6 +9752,13 @@ export declare interface WorkflowInstance extends SanityDocument {
|
|
|
8606
9752
|
|
|
8607
9753
|
export declare const WorkflowInstanceAborted: WorkflowTelemetryEvent<WorkflowAdminOverrideData>;
|
|
8608
9754
|
|
|
9755
|
+
/**
|
|
9756
|
+
* The persisted instance document, root to leaf. Reused verbatim by every
|
|
9757
|
+
* engine read boundary through {@link parseInstanceDocument}; the
|
|
9758
|
+
* model-surface gate derives its shape ledger from this schema.
|
|
9759
|
+
*/
|
|
9760
|
+
export declare const WorkflowInstanceSchema: v.GenericSchema<WorkflowInstance>;
|
|
9761
|
+
|
|
8609
9762
|
export declare const WorkflowInstanceStarted: WorkflowTelemetryEvent<WorkflowInstanceStartedData>;
|
|
8610
9763
|
|
|
8611
9764
|
export declare interface WorkflowInstanceStartedData extends InstanceScopedEventData {
|
|
@@ -8800,10 +9953,11 @@ export declare interface WorkflowTransaction {
|
|
|
8800
9953
|
/**
|
|
8801
9954
|
* Queue a document delete. Deliberately a transaction-only capability —
|
|
8802
9955
|
* the top-level client surface stays delete-free so no engine code path
|
|
8803
|
-
* can casually remove documents
|
|
8804
|
-
*
|
|
8805
|
-
*
|
|
8806
|
-
*
|
|
9956
|
+
* can casually remove documents. Engine-side consumers are guard retraction
|
|
9957
|
+
* and `deleteDefinition` housekeeping; outside the engine the CLI's `nuke`
|
|
9958
|
+
* reset deletes raw engine-owned docs through it. Both the real
|
|
9959
|
+
* `@sanity/client` Transaction and the test fake's TransactionHandle carry
|
|
9960
|
+
* this shape.
|
|
8807
9961
|
*/
|
|
8808
9962
|
delete: (id: string) => WorkflowTransaction;
|
|
8809
9963
|
/**
|