@sanity/workflow-engine 0.2.0 → 0.3.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/dist/_chunks-cjs/schema.cjs +431 -0
- package/dist/_chunks-cjs/schema.cjs.map +1 -0
- package/dist/_chunks-es/schema.js +416 -0
- package/dist/_chunks-es/schema.js.map +1 -0
- package/dist/define.cjs +18 -418
- package/dist/define.cjs.map +1 -1
- package/dist/define.js +6 -405
- package/dist/define.js.map +1 -1
- package/dist/index.cjs +1401 -1238
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +236 -2
- package/dist/index.d.ts +236 -2
- package/dist/index.js +1397 -1233
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -517,6 +517,24 @@ declare type Bound<
|
|
|
517
517
|
},
|
|
518
518
|
> = Omit<Args, "client" | "tags" | "workflowResource">;
|
|
519
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Build a snapshot from a set of loaded docs. Pure transform.
|
|
522
|
+
*
|
|
523
|
+
* For each `LoadedDoc { doc, resource }`:
|
|
524
|
+
* - The doc's `_id` is rewritten to `gdrFromResource(resource, _id)`.
|
|
525
|
+
* - Every nested `_ref` value (recursively, through objects and arrays)
|
|
526
|
+
* is rewritten the same way: bare ref → URI in the parent's resource.
|
|
527
|
+
* Already-qualified `_ref` URIs (containing `:`) are left alone.
|
|
528
|
+
*
|
|
529
|
+
* Plain string fields, numbers, booleans — anything that isn't an
|
|
530
|
+
* object with a `_ref` field — pass through untouched. The rewriter is
|
|
531
|
+
* structural, not schema-aware: only the `_ref` field on an object is
|
|
532
|
+
* treated as a Sanity reference. Everything else is user data.
|
|
533
|
+
*/
|
|
534
|
+
export declare function buildSnapshot(args: {
|
|
535
|
+
docs: LoadedDoc[];
|
|
536
|
+
}): HydratedSnapshot;
|
|
537
|
+
|
|
520
538
|
export declare function canonicalTag(tags: string[]): string;
|
|
521
539
|
|
|
522
540
|
/**
|
|
@@ -627,6 +645,29 @@ export declare class ConcurrentFireActionError extends Error {
|
|
|
627
645
|
});
|
|
628
646
|
}
|
|
629
647
|
|
|
648
|
+
/**
|
|
649
|
+
* The Content Release a watched doc resolves under, or `undefined` for a raw
|
|
650
|
+
* read — how a reactive adapter turns the watch-set's perspective into the
|
|
651
|
+
* per-doc release its store needs. Instance / ancestor / `system.release` docs
|
|
652
|
+
* read raw ({@link readsRaw}); a content doc resolves under the **leading**
|
|
653
|
+
* release in the stack. The engine never forms the `versions.<release>.<id>`
|
|
654
|
+
* id — the adapter does (Studio's `editState` version arg, the SDK handle
|
|
655
|
+
* `{releaseName}`). A non-array perspective (`raw`/`published`/`drafts`)
|
|
656
|
+
* carries no release, so content falls back to draft/published.
|
|
657
|
+
*
|
|
658
|
+
* Note: this resolves a **single** release — the documented `instance.perspective`
|
|
659
|
+
* shapes (`[release]` / `[release, "drafts"]`). The stores' per-doc reads take
|
|
660
|
+
* one release, so a multi-release stack can't be observed reactively here; the
|
|
661
|
+
* engine's own fetch path ({@link hydrateSnapshot}) honours the full stack via
|
|
662
|
+
* `client.fetch({perspective})`.
|
|
663
|
+
*/
|
|
664
|
+
export declare function contentReleaseName(args: {
|
|
665
|
+
ref: {
|
|
666
|
+
type: string;
|
|
667
|
+
};
|
|
668
|
+
perspective: WorkflowPerspective | undefined;
|
|
669
|
+
}): string | undefined;
|
|
670
|
+
|
|
630
671
|
/**
|
|
631
672
|
* Construct an engine bound to a workflow resource + tags. The returned
|
|
632
673
|
* object exposes the same verbs as the `workflow.*` namespace, minus
|
|
@@ -994,6 +1035,28 @@ export declare interface Engine {
|
|
|
994
1035
|
setStage: (args: Bound<SetStageArgs>) => Promise<DispatchResult>;
|
|
995
1036
|
/** Fetch a workflow instance by id. */
|
|
996
1037
|
getInstance: (args: { instanceId: string }) => Promise<WorkflowInstance>;
|
|
1038
|
+
/** The reactive {@link WatchSet} for an instance — every document whose
|
|
1039
|
+
* change should re-evaluate it (the instance, its ancestors, and the docs
|
|
1040
|
+
* named by `doc.ref`/`doc.refs`/`release.ref` slots on the workflow scope
|
|
1041
|
+
* + current stage) as exploded {@link SubscriptionDocument}s, plus the
|
|
1042
|
+
* instance's read perspective. Fetches the instance, then derives. A
|
|
1043
|
+
* reactive adapter that already holds the live instance calls the pure
|
|
1044
|
+
* `subscriptionDocumentsForInstance` directly instead, to avoid the re-fetch. */
|
|
1045
|
+
subscriptionDocumentsForInstance: (args: {
|
|
1046
|
+
instanceId: string;
|
|
1047
|
+
}) => Promise<WatchSet>;
|
|
1048
|
+
/** Opt into reactivity: bind the engine to an instance doc and get a stateful
|
|
1049
|
+
* {@link InstanceSession}. Push the docs it lists in `subscriptionDocuments`
|
|
1050
|
+
* via `update`, then `evaluate`/`tick`/`fireAction` against the held state —
|
|
1051
|
+
* pushed content is never refetched. The session never observes or ticks on
|
|
1052
|
+
* its own; the consumer drives it. */
|
|
1053
|
+
instance: (
|
|
1054
|
+
instanceDoc: WorkflowInstance,
|
|
1055
|
+
opts?: {
|
|
1056
|
+
access?: WorkflowAccessOverride;
|
|
1057
|
+
grantsFromPath?: string;
|
|
1058
|
+
},
|
|
1059
|
+
) => InstanceSession;
|
|
997
1060
|
/** Every lake mutation guard this instance registered, unioned across the
|
|
998
1061
|
* instance's own resource and the resource of each `doc.ref`/`doc.refs`
|
|
999
1062
|
* GDR it holds in state. For coherency refresh and housekeeping. */
|
|
@@ -1100,6 +1163,43 @@ export declare interface EvaluateArgs {
|
|
|
1100
1163
|
resourceClients?: (parsed: ParsedGdr) => WorkflowClient | undefined;
|
|
1101
1164
|
}
|
|
1102
1165
|
|
|
1166
|
+
/**
|
|
1167
|
+
* The pure projection at the heart of {@link evaluateInstance}: given an
|
|
1168
|
+
* instance, its definition, the resolved actor/grants, and a snapshot,
|
|
1169
|
+
* compute "what can this actor do right now, and why not the rest." No
|
|
1170
|
+
* I/O — feed it a fresh snapshot (e.g. rebuilt from a live store on
|
|
1171
|
+
* change) for reactive re-evaluation. Best-effort by design: the lake's
|
|
1172
|
+
* mutation guards + ACL are the real enforcement.
|
|
1173
|
+
*/
|
|
1174
|
+
export declare function evaluateFromSnapshot(
|
|
1175
|
+
args: EvaluateFromSnapshotArgs,
|
|
1176
|
+
): Promise<WorkflowEvaluation>;
|
|
1177
|
+
|
|
1178
|
+
export declare interface EvaluateFromSnapshotArgs {
|
|
1179
|
+
instance: WorkflowInstance;
|
|
1180
|
+
definition: WorkflowDefinition;
|
|
1181
|
+
actor: Actor;
|
|
1182
|
+
/**
|
|
1183
|
+
* Resolved grants for the actor. Omit to skip the `permission-denied`
|
|
1184
|
+
* gate (graceful degradation — the real lake write boundary still
|
|
1185
|
+
* enforces).
|
|
1186
|
+
*/
|
|
1187
|
+
grants?: Grant[];
|
|
1188
|
+
/**
|
|
1189
|
+
* The in-memory snapshot to evaluate against. The caller assembles it
|
|
1190
|
+
* from whatever source — a fetch (see {@link evaluateInstance}) or a
|
|
1191
|
+
* live store. The `_id` of every doc must be in GDR-URI form, as
|
|
1192
|
+
* {@link buildSnapshot} produces.
|
|
1193
|
+
*/
|
|
1194
|
+
snapshot: HydratedSnapshot;
|
|
1195
|
+
/**
|
|
1196
|
+
* The `$now` reading every filter in this projection shares. Omit to
|
|
1197
|
+
* use {@link wallClock}; a reactive consumer (or the bench) passes its
|
|
1198
|
+
* own clock reading for a stable/deterministic timeline.
|
|
1199
|
+
*/
|
|
1200
|
+
now?: string;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1103
1203
|
declare function evaluateInstance(
|
|
1104
1204
|
args: Clocked<EvaluateArgs>,
|
|
1105
1205
|
): Promise<WorkflowEvaluation>;
|
|
@@ -1239,7 +1339,7 @@ export declare type GdrScheme =
|
|
|
1239
1339
|
* type + runtime guarantee that no bare-string id reaches the
|
|
1240
1340
|
* snapshot, slot, or filter layer.
|
|
1241
1341
|
*/
|
|
1242
|
-
declare type GdrUri = `${GdrScheme}:${string}`;
|
|
1342
|
+
export declare type GdrUri = `${GdrScheme}:${string}`;
|
|
1243
1343
|
|
|
1244
1344
|
/** Compose a GDR URI from parts. Inverse of `parseGdr`. */
|
|
1245
1345
|
export declare function gdrUri(
|
|
@@ -1603,6 +1703,22 @@ export declare type HistoryEntry =
|
|
|
1603
1703
|
actor?: Actor;
|
|
1604
1704
|
};
|
|
1605
1705
|
|
|
1706
|
+
/**
|
|
1707
|
+
* The in-memory groq-js dataset filters evaluate against. Built once
|
|
1708
|
+
* per cascade entry (in the shell), passed through to `evaluateFilter`
|
|
1709
|
+
* (in the core) for every filter check.
|
|
1710
|
+
*/
|
|
1711
|
+
export declare interface HydratedSnapshot {
|
|
1712
|
+
/** All hydrated docs, keyed by GDR URI as `_id`. */
|
|
1713
|
+
docs: SanityDocument[];
|
|
1714
|
+
/**
|
|
1715
|
+
* The set of GDR URIs present in `docs`. Helpful for tests and shells
|
|
1716
|
+
* that want to assert "is this doc in scope?" — the core eval pipeline
|
|
1717
|
+
* itself doesn't read it.
|
|
1718
|
+
*/
|
|
1719
|
+
knownIds: Set<string>;
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1606
1722
|
/**
|
|
1607
1723
|
* Initial value for an `init`-sourced slot — what a caller supplies at
|
|
1608
1724
|
* `startInstance` (or `setStage`). Same discriminator shape as
|
|
@@ -1618,6 +1734,28 @@ export declare type InitialStateValue = {
|
|
|
1618
1734
|
};
|
|
1619
1735
|
}[Exclude<StateSlotKind, "workflow.state.query">];
|
|
1620
1736
|
|
|
1737
|
+
export declare interface InstanceSession {
|
|
1738
|
+
/** The watch-set to feed via {@link InstanceSession.update}, derived from the
|
|
1739
|
+
* held instance. Recompute after the instance changes (a new stage changes it). */
|
|
1740
|
+
readonly subscriptionDocuments: WatchSet;
|
|
1741
|
+
/** Replace the held content with the current values the consumer observed
|
|
1742
|
+
* (last-write-wins, scoped). A doc whose id is the instance itself updates
|
|
1743
|
+
* the held instance. Buffered if a commit is in flight. */
|
|
1744
|
+
update(docs: LoadedDoc[]): void;
|
|
1745
|
+
/** Best-effort projection against the held content. No network (async only
|
|
1746
|
+
* because filter evaluation runs on groq-js). */
|
|
1747
|
+
evaluate(): Promise<WorkflowEvaluation>;
|
|
1748
|
+
/** Advance the instance against the held content: cascade auto-transitions,
|
|
1749
|
+
* deploy guards, queue effects, commit with `ifRevisionId`. */
|
|
1750
|
+
tick(): Promise<DispatchResult>;
|
|
1751
|
+
/** Fire an action against a task, gated on the held content, then cascade. */
|
|
1752
|
+
fireAction(args: {
|
|
1753
|
+
taskId: string;
|
|
1754
|
+
action: string;
|
|
1755
|
+
params?: Record<string, unknown>;
|
|
1756
|
+
}): Promise<DispatchResult>;
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1621
1759
|
/**
|
|
1622
1760
|
* Compare a deployed definition document to what we'd write next. Skip
|
|
1623
1761
|
* Sanity-managed system fields (`_rev`, `_createdAt`, `_updatedAt`) —
|
|
@@ -1639,6 +1777,16 @@ export declare function lakeGuardId(args: {
|
|
|
1639
1777
|
index: number;
|
|
1640
1778
|
}): string;
|
|
1641
1779
|
|
|
1780
|
+
/**
|
|
1781
|
+
* One loaded doc plus the resource it came from. The shell builds
|
|
1782
|
+
* this list by routing reads to the right client for each doc, then
|
|
1783
|
+
* hands it to `buildSnapshot`.
|
|
1784
|
+
*/
|
|
1785
|
+
export declare interface LoadedDoc {
|
|
1786
|
+
doc: SanityDocument;
|
|
1787
|
+
resource: WorkflowResource;
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1642
1790
|
export declare type LoggerFactory = (name: string) => EngineLogger;
|
|
1643
1791
|
|
|
1644
1792
|
/**
|
|
@@ -2122,6 +2270,17 @@ declare const PredicateSchema: v.StrictObjectSchema<
|
|
|
2122
2270
|
undefined
|
|
2123
2271
|
>;
|
|
2124
2272
|
|
|
2273
|
+
/**
|
|
2274
|
+
* Whether a watched ref reads RAW — never perspective-scoped. The
|
|
2275
|
+
* instance, its ancestors (both `workflow.instance`), and `release.ref`
|
|
2276
|
+
* system docs (`system.release`) are not versioned by a release
|
|
2277
|
+
* perspective; everything else is content and resolves to its
|
|
2278
|
+
* version/draft/published form. This is the single encoding of the rule
|
|
2279
|
+
* the {@link WatchSet} `perspective` contract describes to consumers, and
|
|
2280
|
+
* the rule {@link hydrateSnapshot} applies on the fetch side.
|
|
2281
|
+
*/
|
|
2282
|
+
export declare function readsRaw(ref: { type: string }): boolean;
|
|
2283
|
+
|
|
2125
2284
|
/** Make a GDR pointer to a Canvas-resource doc. */
|
|
2126
2285
|
export declare function refCanvas(
|
|
2127
2286
|
resourceId: string,
|
|
@@ -2241,6 +2400,8 @@ declare type ResourceClientResolver = (
|
|
|
2241
2400
|
parsed: ParsedGdr,
|
|
2242
2401
|
) => WorkflowClient | undefined;
|
|
2243
2402
|
|
|
2403
|
+
export declare function resourceFromParsed(parsed: ParsedGdr): WorkflowResource;
|
|
2404
|
+
|
|
2244
2405
|
/**
|
|
2245
2406
|
* Retract every guard for a stage being exited (lift predicate to allow), but
|
|
2246
2407
|
* only once the instance has genuinely moved off that stage. Skip if it is
|
|
@@ -4404,6 +4565,36 @@ export declare function stripSystemFields(
|
|
|
4404
4565
|
doc: Record<string, unknown>,
|
|
4405
4566
|
): Record<string, unknown>;
|
|
4406
4567
|
|
|
4568
|
+
/**
|
|
4569
|
+
* A document the reactive layer should subscribe to, with its GDR
|
|
4570
|
+
* exploded so consumers never re-parse: the resource-addressing parts
|
|
4571
|
+
* (from {@link ParsedGdr}), the round-trip `globalDocumentId` URI, and
|
|
4572
|
+
* the target doc's schema `_type`. The resource parts let an adapter
|
|
4573
|
+
* detect refs pointing at a project/dataset/resource it isn't
|
|
4574
|
+
* configured for; `type` feeds per-doc handles (`useDocument` /
|
|
4575
|
+
* `editState`).
|
|
4576
|
+
*/
|
|
4577
|
+
export declare interface SubscriptionDocument extends ParsedGdr {
|
|
4578
|
+
/** Full GDR URI — resource-qualified identity, for round-trip / snapshot keying. */
|
|
4579
|
+
globalDocumentId: GdrUri;
|
|
4580
|
+
/** Target doc's schema `_type`. */
|
|
4581
|
+
type: string;
|
|
4582
|
+
}
|
|
4583
|
+
|
|
4584
|
+
export declare function subscriptionDocumentsForInstance(
|
|
4585
|
+
instance: WorkflowInstance,
|
|
4586
|
+
): WatchSet;
|
|
4587
|
+
|
|
4588
|
+
/**
|
|
4589
|
+
* The engine's read-partition invariant as a GROQ predicate: a document is
|
|
4590
|
+
* visible when its `tags[]` intersect the caller's tag set.
|
|
4591
|
+
*
|
|
4592
|
+
* @param param - GROQ parameter holding the caller's tags. Defaults to
|
|
4593
|
+
* `engineTags`, matching the `workflow.query` guard so any query built with
|
|
4594
|
+
* it stays tag-scoped.
|
|
4595
|
+
*/
|
|
4596
|
+
export declare function tagScopeFilter(param?: string): string;
|
|
4597
|
+
|
|
4407
4598
|
export declare type Task = v.InferOutput<typeof TaskSchema>;
|
|
4408
4599
|
|
|
4409
4600
|
/**
|
|
@@ -5541,6 +5732,35 @@ export declare interface VerifyDeployedDefinitionsResult {
|
|
|
5541
5732
|
/** The default clock: real wall-clock time as an ISO-8601 string. */
|
|
5542
5733
|
export declare const wallClock: Clock;
|
|
5543
5734
|
|
|
5735
|
+
/**
|
|
5736
|
+
* The reactive subscription target for an instance: the exploded,
|
|
5737
|
+
* deduped watch-set plus the instance's read {@link WorkflowPerspective}.
|
|
5738
|
+
*/
|
|
5739
|
+
export declare interface WatchSet {
|
|
5740
|
+
/**
|
|
5741
|
+
* Docs to subscribe to — instance + ancestors + the docs named by
|
|
5742
|
+
* `doc.ref`/`doc.refs`/`release.ref` slots — deduped by
|
|
5743
|
+
* `globalDocumentId`. Refs that aren't resource-qualified GDR URIs are
|
|
5744
|
+
* skipped (without a resource there's nothing to subscribe against).
|
|
5745
|
+
*/
|
|
5746
|
+
documents: SubscriptionDocument[];
|
|
5747
|
+
/**
|
|
5748
|
+
* The instance's effective read perspective (a release stack like
|
|
5749
|
+
* `[releaseName]` or `[releaseName, "drafts"]`), already resolved at
|
|
5750
|
+
* `startInstance`. `undefined` means raw/published.
|
|
5751
|
+
*
|
|
5752
|
+
* The engine does not form `versions.<release>.<id>` ids — it has no
|
|
5753
|
+
* such concept (it reads content through `client.fetch({perspective})`
|
|
5754
|
+
* for queries). A reactive consumer applies this perspective when it
|
|
5755
|
+
* subscribes: a **content** doc must be resolved to its version /
|
|
5756
|
+
* draft / published form (e.g. Studio `editState`'s version param, or
|
|
5757
|
+
* the SDK's `getVersionId`), while instance / ancestor / `system.release`
|
|
5758
|
+
* docs are always raw. The `type` on each {@link SubscriptionDocument}
|
|
5759
|
+
* tells the consumer which is which.
|
|
5760
|
+
*/
|
|
5761
|
+
perspective?: WorkflowPerspective;
|
|
5762
|
+
}
|
|
5763
|
+
|
|
5544
5764
|
/**
|
|
5545
5765
|
* The four-method workflow API.
|
|
5546
5766
|
*/
|
|
@@ -5740,6 +5960,20 @@ export declare const workflow: {
|
|
|
5740
5960
|
};
|
|
5741
5961
|
};
|
|
5742
5962
|
|
|
5963
|
+
/**
|
|
5964
|
+
* The lake document type for a deployed workflow definition. Single source of
|
|
5965
|
+
* truth — every tag-scoped lookup query and the deploy write derive their
|
|
5966
|
+
* `_type` from here, mirroring {@link WORKFLOW_INSTANCE_TYPE}.
|
|
5967
|
+
*/
|
|
5968
|
+
export declare const WORKFLOW_DEFINITION_TYPE = "workflow.definition";
|
|
5969
|
+
|
|
5970
|
+
/**
|
|
5971
|
+
* The lake document type for a workflow instance. Single source of truth — the
|
|
5972
|
+
* {@link WorkflowInstance} `_type`, every tag-scoped query, and the create
|
|
5973
|
+
* write all derive from here, mirroring {@link WORKFLOW_DEFINITION_TYPE}.
|
|
5974
|
+
*/
|
|
5975
|
+
export declare const WORKFLOW_INSTANCE_TYPE = "workflow.instance";
|
|
5976
|
+
|
|
5743
5977
|
/**
|
|
5744
5978
|
* The engine's view of "who am I, what can I do?". `actor` is who
|
|
5745
5979
|
* the engine stamps onto history / `completedBy` / `Source.actor`.
|
|
@@ -8284,7 +8518,7 @@ export declare interface WorkflowFetchOptions {
|
|
|
8284
8518
|
}
|
|
8285
8519
|
|
|
8286
8520
|
export declare interface WorkflowInstance extends SanityDocument {
|
|
8287
|
-
_type:
|
|
8521
|
+
_type: typeof WORKFLOW_INSTANCE_TYPE;
|
|
8288
8522
|
/**
|
|
8289
8523
|
* Engine-scope tags stamped on the instance at create time. Engines
|
|
8290
8524
|
* with disjoint tag sets cannot read this instance; engines sharing
|
package/dist/index.d.ts
CHANGED
|
@@ -517,6 +517,24 @@ declare type Bound<
|
|
|
517
517
|
},
|
|
518
518
|
> = Omit<Args, "client" | "tags" | "workflowResource">;
|
|
519
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Build a snapshot from a set of loaded docs. Pure transform.
|
|
522
|
+
*
|
|
523
|
+
* For each `LoadedDoc { doc, resource }`:
|
|
524
|
+
* - The doc's `_id` is rewritten to `gdrFromResource(resource, _id)`.
|
|
525
|
+
* - Every nested `_ref` value (recursively, through objects and arrays)
|
|
526
|
+
* is rewritten the same way: bare ref → URI in the parent's resource.
|
|
527
|
+
* Already-qualified `_ref` URIs (containing `:`) are left alone.
|
|
528
|
+
*
|
|
529
|
+
* Plain string fields, numbers, booleans — anything that isn't an
|
|
530
|
+
* object with a `_ref` field — pass through untouched. The rewriter is
|
|
531
|
+
* structural, not schema-aware: only the `_ref` field on an object is
|
|
532
|
+
* treated as a Sanity reference. Everything else is user data.
|
|
533
|
+
*/
|
|
534
|
+
export declare function buildSnapshot(args: {
|
|
535
|
+
docs: LoadedDoc[];
|
|
536
|
+
}): HydratedSnapshot;
|
|
537
|
+
|
|
520
538
|
export declare function canonicalTag(tags: string[]): string;
|
|
521
539
|
|
|
522
540
|
/**
|
|
@@ -627,6 +645,29 @@ export declare class ConcurrentFireActionError extends Error {
|
|
|
627
645
|
});
|
|
628
646
|
}
|
|
629
647
|
|
|
648
|
+
/**
|
|
649
|
+
* The Content Release a watched doc resolves under, or `undefined` for a raw
|
|
650
|
+
* read — how a reactive adapter turns the watch-set's perspective into the
|
|
651
|
+
* per-doc release its store needs. Instance / ancestor / `system.release` docs
|
|
652
|
+
* read raw ({@link readsRaw}); a content doc resolves under the **leading**
|
|
653
|
+
* release in the stack. The engine never forms the `versions.<release>.<id>`
|
|
654
|
+
* id — the adapter does (Studio's `editState` version arg, the SDK handle
|
|
655
|
+
* `{releaseName}`). A non-array perspective (`raw`/`published`/`drafts`)
|
|
656
|
+
* carries no release, so content falls back to draft/published.
|
|
657
|
+
*
|
|
658
|
+
* Note: this resolves a **single** release — the documented `instance.perspective`
|
|
659
|
+
* shapes (`[release]` / `[release, "drafts"]`). The stores' per-doc reads take
|
|
660
|
+
* one release, so a multi-release stack can't be observed reactively here; the
|
|
661
|
+
* engine's own fetch path ({@link hydrateSnapshot}) honours the full stack via
|
|
662
|
+
* `client.fetch({perspective})`.
|
|
663
|
+
*/
|
|
664
|
+
export declare function contentReleaseName(args: {
|
|
665
|
+
ref: {
|
|
666
|
+
type: string;
|
|
667
|
+
};
|
|
668
|
+
perspective: WorkflowPerspective | undefined;
|
|
669
|
+
}): string | undefined;
|
|
670
|
+
|
|
630
671
|
/**
|
|
631
672
|
* Construct an engine bound to a workflow resource + tags. The returned
|
|
632
673
|
* object exposes the same verbs as the `workflow.*` namespace, minus
|
|
@@ -994,6 +1035,28 @@ export declare interface Engine {
|
|
|
994
1035
|
setStage: (args: Bound<SetStageArgs>) => Promise<DispatchResult>;
|
|
995
1036
|
/** Fetch a workflow instance by id. */
|
|
996
1037
|
getInstance: (args: { instanceId: string }) => Promise<WorkflowInstance>;
|
|
1038
|
+
/** The reactive {@link WatchSet} for an instance — every document whose
|
|
1039
|
+
* change should re-evaluate it (the instance, its ancestors, and the docs
|
|
1040
|
+
* named by `doc.ref`/`doc.refs`/`release.ref` slots on the workflow scope
|
|
1041
|
+
* + current stage) as exploded {@link SubscriptionDocument}s, plus the
|
|
1042
|
+
* instance's read perspective. Fetches the instance, then derives. A
|
|
1043
|
+
* reactive adapter that already holds the live instance calls the pure
|
|
1044
|
+
* `subscriptionDocumentsForInstance` directly instead, to avoid the re-fetch. */
|
|
1045
|
+
subscriptionDocumentsForInstance: (args: {
|
|
1046
|
+
instanceId: string;
|
|
1047
|
+
}) => Promise<WatchSet>;
|
|
1048
|
+
/** Opt into reactivity: bind the engine to an instance doc and get a stateful
|
|
1049
|
+
* {@link InstanceSession}. Push the docs it lists in `subscriptionDocuments`
|
|
1050
|
+
* via `update`, then `evaluate`/`tick`/`fireAction` against the held state —
|
|
1051
|
+
* pushed content is never refetched. The session never observes or ticks on
|
|
1052
|
+
* its own; the consumer drives it. */
|
|
1053
|
+
instance: (
|
|
1054
|
+
instanceDoc: WorkflowInstance,
|
|
1055
|
+
opts?: {
|
|
1056
|
+
access?: WorkflowAccessOverride;
|
|
1057
|
+
grantsFromPath?: string;
|
|
1058
|
+
},
|
|
1059
|
+
) => InstanceSession;
|
|
997
1060
|
/** Every lake mutation guard this instance registered, unioned across the
|
|
998
1061
|
* instance's own resource and the resource of each `doc.ref`/`doc.refs`
|
|
999
1062
|
* GDR it holds in state. For coherency refresh and housekeeping. */
|
|
@@ -1100,6 +1163,43 @@ export declare interface EvaluateArgs {
|
|
|
1100
1163
|
resourceClients?: (parsed: ParsedGdr) => WorkflowClient | undefined;
|
|
1101
1164
|
}
|
|
1102
1165
|
|
|
1166
|
+
/**
|
|
1167
|
+
* The pure projection at the heart of {@link evaluateInstance}: given an
|
|
1168
|
+
* instance, its definition, the resolved actor/grants, and a snapshot,
|
|
1169
|
+
* compute "what can this actor do right now, and why not the rest." No
|
|
1170
|
+
* I/O — feed it a fresh snapshot (e.g. rebuilt from a live store on
|
|
1171
|
+
* change) for reactive re-evaluation. Best-effort by design: the lake's
|
|
1172
|
+
* mutation guards + ACL are the real enforcement.
|
|
1173
|
+
*/
|
|
1174
|
+
export declare function evaluateFromSnapshot(
|
|
1175
|
+
args: EvaluateFromSnapshotArgs,
|
|
1176
|
+
): Promise<WorkflowEvaluation>;
|
|
1177
|
+
|
|
1178
|
+
export declare interface EvaluateFromSnapshotArgs {
|
|
1179
|
+
instance: WorkflowInstance;
|
|
1180
|
+
definition: WorkflowDefinition;
|
|
1181
|
+
actor: Actor;
|
|
1182
|
+
/**
|
|
1183
|
+
* Resolved grants for the actor. Omit to skip the `permission-denied`
|
|
1184
|
+
* gate (graceful degradation — the real lake write boundary still
|
|
1185
|
+
* enforces).
|
|
1186
|
+
*/
|
|
1187
|
+
grants?: Grant[];
|
|
1188
|
+
/**
|
|
1189
|
+
* The in-memory snapshot to evaluate against. The caller assembles it
|
|
1190
|
+
* from whatever source — a fetch (see {@link evaluateInstance}) or a
|
|
1191
|
+
* live store. The `_id` of every doc must be in GDR-URI form, as
|
|
1192
|
+
* {@link buildSnapshot} produces.
|
|
1193
|
+
*/
|
|
1194
|
+
snapshot: HydratedSnapshot;
|
|
1195
|
+
/**
|
|
1196
|
+
* The `$now` reading every filter in this projection shares. Omit to
|
|
1197
|
+
* use {@link wallClock}; a reactive consumer (or the bench) passes its
|
|
1198
|
+
* own clock reading for a stable/deterministic timeline.
|
|
1199
|
+
*/
|
|
1200
|
+
now?: string;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1103
1203
|
declare function evaluateInstance(
|
|
1104
1204
|
args: Clocked<EvaluateArgs>,
|
|
1105
1205
|
): Promise<WorkflowEvaluation>;
|
|
@@ -1239,7 +1339,7 @@ export declare type GdrScheme =
|
|
|
1239
1339
|
* type + runtime guarantee that no bare-string id reaches the
|
|
1240
1340
|
* snapshot, slot, or filter layer.
|
|
1241
1341
|
*/
|
|
1242
|
-
declare type GdrUri = `${GdrScheme}:${string}`;
|
|
1342
|
+
export declare type GdrUri = `${GdrScheme}:${string}`;
|
|
1243
1343
|
|
|
1244
1344
|
/** Compose a GDR URI from parts. Inverse of `parseGdr`. */
|
|
1245
1345
|
export declare function gdrUri(
|
|
@@ -1603,6 +1703,22 @@ export declare type HistoryEntry =
|
|
|
1603
1703
|
actor?: Actor;
|
|
1604
1704
|
};
|
|
1605
1705
|
|
|
1706
|
+
/**
|
|
1707
|
+
* The in-memory groq-js dataset filters evaluate against. Built once
|
|
1708
|
+
* per cascade entry (in the shell), passed through to `evaluateFilter`
|
|
1709
|
+
* (in the core) for every filter check.
|
|
1710
|
+
*/
|
|
1711
|
+
export declare interface HydratedSnapshot {
|
|
1712
|
+
/** All hydrated docs, keyed by GDR URI as `_id`. */
|
|
1713
|
+
docs: SanityDocument[];
|
|
1714
|
+
/**
|
|
1715
|
+
* The set of GDR URIs present in `docs`. Helpful for tests and shells
|
|
1716
|
+
* that want to assert "is this doc in scope?" — the core eval pipeline
|
|
1717
|
+
* itself doesn't read it.
|
|
1718
|
+
*/
|
|
1719
|
+
knownIds: Set<string>;
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1606
1722
|
/**
|
|
1607
1723
|
* Initial value for an `init`-sourced slot — what a caller supplies at
|
|
1608
1724
|
* `startInstance` (or `setStage`). Same discriminator shape as
|
|
@@ -1618,6 +1734,28 @@ export declare type InitialStateValue = {
|
|
|
1618
1734
|
};
|
|
1619
1735
|
}[Exclude<StateSlotKind, "workflow.state.query">];
|
|
1620
1736
|
|
|
1737
|
+
export declare interface InstanceSession {
|
|
1738
|
+
/** The watch-set to feed via {@link InstanceSession.update}, derived from the
|
|
1739
|
+
* held instance. Recompute after the instance changes (a new stage changes it). */
|
|
1740
|
+
readonly subscriptionDocuments: WatchSet;
|
|
1741
|
+
/** Replace the held content with the current values the consumer observed
|
|
1742
|
+
* (last-write-wins, scoped). A doc whose id is the instance itself updates
|
|
1743
|
+
* the held instance. Buffered if a commit is in flight. */
|
|
1744
|
+
update(docs: LoadedDoc[]): void;
|
|
1745
|
+
/** Best-effort projection against the held content. No network (async only
|
|
1746
|
+
* because filter evaluation runs on groq-js). */
|
|
1747
|
+
evaluate(): Promise<WorkflowEvaluation>;
|
|
1748
|
+
/** Advance the instance against the held content: cascade auto-transitions,
|
|
1749
|
+
* deploy guards, queue effects, commit with `ifRevisionId`. */
|
|
1750
|
+
tick(): Promise<DispatchResult>;
|
|
1751
|
+
/** Fire an action against a task, gated on the held content, then cascade. */
|
|
1752
|
+
fireAction(args: {
|
|
1753
|
+
taskId: string;
|
|
1754
|
+
action: string;
|
|
1755
|
+
params?: Record<string, unknown>;
|
|
1756
|
+
}): Promise<DispatchResult>;
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1621
1759
|
/**
|
|
1622
1760
|
* Compare a deployed definition document to what we'd write next. Skip
|
|
1623
1761
|
* Sanity-managed system fields (`_rev`, `_createdAt`, `_updatedAt`) —
|
|
@@ -1639,6 +1777,16 @@ export declare function lakeGuardId(args: {
|
|
|
1639
1777
|
index: number;
|
|
1640
1778
|
}): string;
|
|
1641
1779
|
|
|
1780
|
+
/**
|
|
1781
|
+
* One loaded doc plus the resource it came from. The shell builds
|
|
1782
|
+
* this list by routing reads to the right client for each doc, then
|
|
1783
|
+
* hands it to `buildSnapshot`.
|
|
1784
|
+
*/
|
|
1785
|
+
export declare interface LoadedDoc {
|
|
1786
|
+
doc: SanityDocument;
|
|
1787
|
+
resource: WorkflowResource;
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1642
1790
|
export declare type LoggerFactory = (name: string) => EngineLogger;
|
|
1643
1791
|
|
|
1644
1792
|
/**
|
|
@@ -2122,6 +2270,17 @@ declare const PredicateSchema: v.StrictObjectSchema<
|
|
|
2122
2270
|
undefined
|
|
2123
2271
|
>;
|
|
2124
2272
|
|
|
2273
|
+
/**
|
|
2274
|
+
* Whether a watched ref reads RAW — never perspective-scoped. The
|
|
2275
|
+
* instance, its ancestors (both `workflow.instance`), and `release.ref`
|
|
2276
|
+
* system docs (`system.release`) are not versioned by a release
|
|
2277
|
+
* perspective; everything else is content and resolves to its
|
|
2278
|
+
* version/draft/published form. This is the single encoding of the rule
|
|
2279
|
+
* the {@link WatchSet} `perspective` contract describes to consumers, and
|
|
2280
|
+
* the rule {@link hydrateSnapshot} applies on the fetch side.
|
|
2281
|
+
*/
|
|
2282
|
+
export declare function readsRaw(ref: { type: string }): boolean;
|
|
2283
|
+
|
|
2125
2284
|
/** Make a GDR pointer to a Canvas-resource doc. */
|
|
2126
2285
|
export declare function refCanvas(
|
|
2127
2286
|
resourceId: string,
|
|
@@ -2241,6 +2400,8 @@ declare type ResourceClientResolver = (
|
|
|
2241
2400
|
parsed: ParsedGdr,
|
|
2242
2401
|
) => WorkflowClient | undefined;
|
|
2243
2402
|
|
|
2403
|
+
export declare function resourceFromParsed(parsed: ParsedGdr): WorkflowResource;
|
|
2404
|
+
|
|
2244
2405
|
/**
|
|
2245
2406
|
* Retract every guard for a stage being exited (lift predicate to allow), but
|
|
2246
2407
|
* only once the instance has genuinely moved off that stage. Skip if it is
|
|
@@ -4404,6 +4565,36 @@ export declare function stripSystemFields(
|
|
|
4404
4565
|
doc: Record<string, unknown>,
|
|
4405
4566
|
): Record<string, unknown>;
|
|
4406
4567
|
|
|
4568
|
+
/**
|
|
4569
|
+
* A document the reactive layer should subscribe to, with its GDR
|
|
4570
|
+
* exploded so consumers never re-parse: the resource-addressing parts
|
|
4571
|
+
* (from {@link ParsedGdr}), the round-trip `globalDocumentId` URI, and
|
|
4572
|
+
* the target doc's schema `_type`. The resource parts let an adapter
|
|
4573
|
+
* detect refs pointing at a project/dataset/resource it isn't
|
|
4574
|
+
* configured for; `type` feeds per-doc handles (`useDocument` /
|
|
4575
|
+
* `editState`).
|
|
4576
|
+
*/
|
|
4577
|
+
export declare interface SubscriptionDocument extends ParsedGdr {
|
|
4578
|
+
/** Full GDR URI — resource-qualified identity, for round-trip / snapshot keying. */
|
|
4579
|
+
globalDocumentId: GdrUri;
|
|
4580
|
+
/** Target doc's schema `_type`. */
|
|
4581
|
+
type: string;
|
|
4582
|
+
}
|
|
4583
|
+
|
|
4584
|
+
export declare function subscriptionDocumentsForInstance(
|
|
4585
|
+
instance: WorkflowInstance,
|
|
4586
|
+
): WatchSet;
|
|
4587
|
+
|
|
4588
|
+
/**
|
|
4589
|
+
* The engine's read-partition invariant as a GROQ predicate: a document is
|
|
4590
|
+
* visible when its `tags[]` intersect the caller's tag set.
|
|
4591
|
+
*
|
|
4592
|
+
* @param param - GROQ parameter holding the caller's tags. Defaults to
|
|
4593
|
+
* `engineTags`, matching the `workflow.query` guard so any query built with
|
|
4594
|
+
* it stays tag-scoped.
|
|
4595
|
+
*/
|
|
4596
|
+
export declare function tagScopeFilter(param?: string): string;
|
|
4597
|
+
|
|
4407
4598
|
export declare type Task = v.InferOutput<typeof TaskSchema>;
|
|
4408
4599
|
|
|
4409
4600
|
/**
|
|
@@ -5541,6 +5732,35 @@ export declare interface VerifyDeployedDefinitionsResult {
|
|
|
5541
5732
|
/** The default clock: real wall-clock time as an ISO-8601 string. */
|
|
5542
5733
|
export declare const wallClock: Clock;
|
|
5543
5734
|
|
|
5735
|
+
/**
|
|
5736
|
+
* The reactive subscription target for an instance: the exploded,
|
|
5737
|
+
* deduped watch-set plus the instance's read {@link WorkflowPerspective}.
|
|
5738
|
+
*/
|
|
5739
|
+
export declare interface WatchSet {
|
|
5740
|
+
/**
|
|
5741
|
+
* Docs to subscribe to — instance + ancestors + the docs named by
|
|
5742
|
+
* `doc.ref`/`doc.refs`/`release.ref` slots — deduped by
|
|
5743
|
+
* `globalDocumentId`. Refs that aren't resource-qualified GDR URIs are
|
|
5744
|
+
* skipped (without a resource there's nothing to subscribe against).
|
|
5745
|
+
*/
|
|
5746
|
+
documents: SubscriptionDocument[];
|
|
5747
|
+
/**
|
|
5748
|
+
* The instance's effective read perspective (a release stack like
|
|
5749
|
+
* `[releaseName]` or `[releaseName, "drafts"]`), already resolved at
|
|
5750
|
+
* `startInstance`. `undefined` means raw/published.
|
|
5751
|
+
*
|
|
5752
|
+
* The engine does not form `versions.<release>.<id>` ids — it has no
|
|
5753
|
+
* such concept (it reads content through `client.fetch({perspective})`
|
|
5754
|
+
* for queries). A reactive consumer applies this perspective when it
|
|
5755
|
+
* subscribes: a **content** doc must be resolved to its version /
|
|
5756
|
+
* draft / published form (e.g. Studio `editState`'s version param, or
|
|
5757
|
+
* the SDK's `getVersionId`), while instance / ancestor / `system.release`
|
|
5758
|
+
* docs are always raw. The `type` on each {@link SubscriptionDocument}
|
|
5759
|
+
* tells the consumer which is which.
|
|
5760
|
+
*/
|
|
5761
|
+
perspective?: WorkflowPerspective;
|
|
5762
|
+
}
|
|
5763
|
+
|
|
5544
5764
|
/**
|
|
5545
5765
|
* The four-method workflow API.
|
|
5546
5766
|
*/
|
|
@@ -5740,6 +5960,20 @@ export declare const workflow: {
|
|
|
5740
5960
|
};
|
|
5741
5961
|
};
|
|
5742
5962
|
|
|
5963
|
+
/**
|
|
5964
|
+
* The lake document type for a deployed workflow definition. Single source of
|
|
5965
|
+
* truth — every tag-scoped lookup query and the deploy write derive their
|
|
5966
|
+
* `_type` from here, mirroring {@link WORKFLOW_INSTANCE_TYPE}.
|
|
5967
|
+
*/
|
|
5968
|
+
export declare const WORKFLOW_DEFINITION_TYPE = "workflow.definition";
|
|
5969
|
+
|
|
5970
|
+
/**
|
|
5971
|
+
* The lake document type for a workflow instance. Single source of truth — the
|
|
5972
|
+
* {@link WorkflowInstance} `_type`, every tag-scoped query, and the create
|
|
5973
|
+
* write all derive from here, mirroring {@link WORKFLOW_DEFINITION_TYPE}.
|
|
5974
|
+
*/
|
|
5975
|
+
export declare const WORKFLOW_INSTANCE_TYPE = "workflow.instance";
|
|
5976
|
+
|
|
5743
5977
|
/**
|
|
5744
5978
|
* The engine's view of "who am I, what can I do?". `actor` is who
|
|
5745
5979
|
* the engine stamps onto history / `completedBy` / `Source.actor`.
|
|
@@ -8284,7 +8518,7 @@ export declare interface WorkflowFetchOptions {
|
|
|
8284
8518
|
}
|
|
8285
8519
|
|
|
8286
8520
|
export declare interface WorkflowInstance extends SanityDocument {
|
|
8287
|
-
_type:
|
|
8521
|
+
_type: typeof WORKFLOW_INSTANCE_TYPE;
|
|
8288
8522
|
/**
|
|
8289
8523
|
* Engine-scope tags stamped on the instance at create time. Engines
|
|
8290
8524
|
* with disjoint tag sets cannot read this instance; engines sharing
|