@sanity/workflow-engine 0.29.0 → 0.31.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 +61 -0
- package/DATAMODEL.md +67 -22
- package/dist/_chunks-cjs/invariants.cjs +286 -87
- package/dist/_chunks-es/invariants.js +281 -88
- package/dist/define.d.cts +289 -276
- package/dist/define.d.ts +289 -276
- package/dist/index.cjs +1297 -914
- package/dist/index.d.cts +917 -1056
- package/dist/index.d.ts +917 -1056
- package/dist/index.js +1116 -749
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# @sanity/workflow-engine
|
|
2
2
|
|
|
3
|
+
## 0.31.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ff72ece: Reader-model errors and the Studio Workflows tool now link to the canonical `/docs/workflows` documentation routes.
|
|
8
|
+
|
|
9
|
+
**No upgrade action required.** Permanent redirects preserve the former `/docs/editorial-workflows` URLs.
|
|
10
|
+
|
|
11
|
+
**Docs impact:** Publish the Workflows documentation at `/docs/workflows` and retain permanent redirects from every previously published `/docs/editorial-workflows` route.
|
|
12
|
+
|
|
13
|
+
## 0.30.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- a3a8dc0: The engine gains a list-projection read for instance dashboards. `instancePreviewsQuery` compiles the same filter arms as `instancesQuery` into a `WorkflowInstancePreview` projection — the open stage alone, field lists reduced to identity, date, document-reference, and release-reference kinds, and `claimedEffects`/`failedEffects` facts in place of the unbounded audit trails — kilobytes lighter per row than the full document. `readInstancePreviewDoc` is the matching gate-then-parse funnel (`WorkflowInstancePreviewSchema`/`parseInstancePreviewDocument` underneath), and the internal identity normalizer accepts any host carrying the identity slots, rows included. `InstancesQueryFilter` adds a keyset `before` cursor (requires `limit`) for paging the newest-first order without skipping or repeating rows across pages; both list orders now break `startedAt` ties on `_id`. **No upgrade action required** — existing reads are unchanged apart from the deterministic tie order.
|
|
18
|
+
|
|
19
|
+
**Docs impact:** The engine reference's instance-query section documents `instancePreviewsQuery`, `WorkflowInstancePreview`, and the `before` cursor in this release's pass — the Workflows tool ships reading them in the same release.
|
|
20
|
+
|
|
21
|
+
- a3a8dc0: **BREAKING:** the exported `WorkflowObserver` contract (workflow-react) gains two required members, `fetchInstancePreviews` and `listenInstanceChanges` — a custom observer no longer compiles until it implements both; the shipped SDK and Studio adapters already do, so their consumers need no action.
|
|
22
|
+
|
|
23
|
+
The reactive layer gains a progressively-hydrated preview list. `useInstancePreviews` (workflow-react) drains the engine's preview projection page by page until the whole filtered set is held — `drained: true` means counts over it are totals — then keeps every row fresh from ONE shared change listener per engine tag: an event refetches the touched previews alone, so update cost is per commit, never per list size. Page size is caller-supplied. The engine adds `instanceChangesQuery` (the tag partition as a listen filter), and the `WorkflowObserver` contract adds `fetchInstancePreviews` and `listenInstanceChanges`, implemented by the SDK observer (the Studio adapter inherits them). A change-feed failure never silently freezes a list: the SDK observer reconnects with exponential backoff and then emits a `reset` event, on which `useInstancePreviews` re-drains the whole partition — gap-missed additions, edits, and deletions all land.
|
|
24
|
+
|
|
25
|
+
**Docs impact:** The reactive-core reference documents `useInstancePreviews` and the observer contract's two new required members in this release's pass — the Workflows tool ships reading them in the same release, and the custom-adapter guidance must name both members beside the BREAKING note.
|
|
26
|
+
|
|
27
|
+
- 90207dc: **BREAKING:** `assertReaderModelAcknowledgement` now requires `{requiredMinReaderModel, context?}` instead of a context string, and `ReaderModelAcknowledgementError` accepts its optional context through `{context}`. The Blueprint package's `AcknowledgedDeployment` type moves to the engine as `AcknowledgedWorkflowDeployment`; update imports and use that shared name. Assignment-valued fields can now declare a non-empty `roles` list that limits newly written assignees. Existing fields without `roles` stay unconstrained, retain reader floor 4, and continue deploying with `expectedMinReaderModel: 4`; installing this release requires no coordinated rollout or configuration change.
|
|
28
|
+
|
|
29
|
+
Before adding `roles`, upgrade every Studio, CLI, MCP server, Function, and other runtime that shares the affected workflow resource, then change that deployment's literal `expectedMinReaderModel` to `8`. MCP deployments pass the same reviewed literal as the optional `expectedMinReaderModel` tool argument. Definitions and instances carrying the facet require reader model 8. User assignees qualify through direct roles or the definition's role aliases, while collective role assignees must literally match one configured role. Studio assignment controls, including manual start, auto-start, and assignees nested in to-do rows, offer only eligible choices while retaining stale current values so editors can remove or replace them. Constrained pickers name the active eligible roles and distinguish an empty eligible set from a search with no matches. Top-level plural and composite edits retain no more occurrences of a stale assignment at each declared assignment location than the previous value contained; removal and reordering therefore work, while an added copy is a new assignment and must qualify. Direct singular replacements and every assignment present in an `updateWhere` fragment remain strict. Each engine verb uses one member-directory snapshot across retries, cascade hops, and spawned children, then the next verb reads current membership.
|
|
30
|
+
|
|
31
|
+
Malformed project-member and project-user directory responses now fail loudly instead of treating bad rows or role records as missing users, and actor resolution reports those failures as `inaccessible`, so integrations can distinguish directory failures from absent membership.
|
|
32
|
+
|
|
33
|
+
CLI `start` and `definition delete` no longer apply the definition-submission acknowledgement gate; deploy, check, dry-run, definition diff, Blueprint provision, and engine definition APIs still validate the selected definitions' required floor.
|
|
34
|
+
|
|
35
|
+
No reader-fleet rollout or deployment-literal change is required for existing definitions that do not use `roles`.
|
|
36
|
+
|
|
37
|
+
**Docs impact:** Update the assignment field reference and authoring examples for `roles`, distinguish eligibility from editability, action permission, and literal queue ownership, and add the model-8 conditional adoption sequence to the prerelease rollout guide.
|
|
38
|
+
|
|
39
|
+
- b0b1550: **BREAKING:** Product-prefixed telemetry events now use `Workflows <event>` instead of `Editorial Workflows <event>`; `EditorialWorkflowsResource` is replaced by `WorkflowsResource`; and `defineWorkflows` now generates `workflows-<deployment name>` resource names instead of `editorial-workflows-<deployment name>`. Telemetry consumers matching the previous literals stop receiving events until updated, TypeScript consumers importing the previous Blueprint interface no longer compile, and an existing Blueprint stack that relies on the generated name treats the new default as a different resource identity.
|
|
40
|
+
|
|
41
|
+
Update telemetry dashboards, schemas, alerts, and queries to match the `Workflows` prefix; event suffixes, payloads, and versions are unchanged. Replace Blueprint imports with `WorkflowsResource`. Before deploying an existing Blueprint stack, either pass its recorded resource name explicitly or plan the detach-and-create migration to the new default. Workflows request-tag families and billing classification are unchanged.
|
|
42
|
+
|
|
43
|
+
Other user-facing package copy now uses the Workflows product name. No upgrade action is required for consumers that do not match telemetry event names or use the Blueprint package.
|
|
44
|
+
|
|
45
|
+
**Docs impact:** Rename the product throughout the public documentation, move the docs section to `/docs/workflows/*` with permanent redirects from every `/docs/editorial-workflows/*` path, and document the telemetry-prefix, `WorkflowsResource`, and Blueprint resource-name migrations in the telemetry reference, Blueprint guide, and release notes.
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- 210ca63: The API documentation shipped in every package's `.d.ts` files is rewritten to be substantially terser: multi-paragraph doc comments are cut to the facts a consumer needs, and internal narration no longer appears in editor hover text. Runtime behavior, exports, and type signatures are unchanged across the whole package group.
|
|
50
|
+
|
|
51
|
+
**No upgrade action required.**
|
|
52
|
+
|
|
53
|
+
**Docs impact: None** — the published documentation site is authored separately; only in-editor `.d.ts` hover text changes.
|
|
54
|
+
|
|
55
|
+
- a3a8dc0: `readInstancePreviewDoc` now takes an untyped lake row. A preview page slot without a string `_id` fails as a shape error named `(unknown id)` instead of being assumed to have an id for the model gate.
|
|
56
|
+
|
|
57
|
+
**No upgrade action required.** Callers that already passed `{_id: string}` continue to type-check.
|
|
58
|
+
|
|
59
|
+
**Docs impact:** None. The preview-row funnel is unchanged for well-formed rows; only the untyped input is honest.
|
|
60
|
+
|
|
61
|
+
- Updated dependencies [210ca63]
|
|
62
|
+
- @sanity/groq-condition-describe@0.4.1
|
|
63
|
+
|
|
3
64
|
## 0.29.0
|
|
4
65
|
|
|
5
66
|
### Minor Changes
|
package/DATAMODEL.md
CHANGED
|
@@ -72,10 +72,12 @@ never matches the new type).
|
|
|
72
72
|
the shape, so restamping there would lie.
|
|
73
73
|
- **`minReaderModel` — the document's reader floor.** The oldest engine model
|
|
74
74
|
that can safely _interpret this particular document_. Writers derive it
|
|
75
|
-
from compatibility-bearing features present in the canonical stored tree
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
from compatibility-bearing features present in the canonical stored tree,
|
|
76
|
+
while retaining the unconditional `DATA_MODEL_MIN_READER` baseline of 4.
|
|
77
|
+
`DATA_MODEL_MAX_READER` is the maximum floor the current writer can emit.
|
|
78
|
+
A deployment acknowledges the highest reader model verified
|
|
79
|
+
for its shared runtimes, and the writer compares it with the submitted
|
|
80
|
+
definitions' required floor.
|
|
79
81
|
- **Missing stamp = model 0** (floor 0) — the document was last written
|
|
80
82
|
before the stamp existed. A `modelVersion` with no `minReaderModel` is
|
|
81
83
|
malformed foreign data and gates conservatively: the stamp is the floor.
|
|
@@ -138,13 +140,12 @@ never matches the new type).
|
|
|
138
140
|
requirement may still require it. (The failure mode this fences off is
|
|
139
141
|
documented across the industry: a rewriter that drops the compatibility
|
|
140
142
|
gate it doesn't understand silently reopens the door the floor closed.)
|
|
141
|
-
- **
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
sole enforcement point.
|
|
143
|
+
- **Persisting a floor-bearing feature is an availability decision.** Before a
|
|
144
|
+
definition using that feature deploys, every reader sharing its workflow
|
|
145
|
+
resource — customer-deployed Functions foremost — must run an engine at or
|
|
146
|
+
above the feature's floor. Increasing the writer's maximum alone requires no
|
|
147
|
+
coordinated rollout. Like every engine-side check, the floor is advisory —
|
|
148
|
+
it gates our own clients; the Content Lake stays the sole enforcement point.
|
|
148
149
|
- **The gate ships from the engine.** `assertReadableModel`, the parse
|
|
149
150
|
functions, and the error classes are exported from
|
|
150
151
|
`@sanity/workflow-engine`, so every consumer surface composes the same
|
|
@@ -224,8 +225,9 @@ floor only when its stable marker is present in the canonical stored tree. An
|
|
|
224
225
|
of its declared type when no reliable marker exists. Readers trust the
|
|
225
226
|
persisted floor; they do not recompute features they may be too old to know.
|
|
226
227
|
Every reader-floor increase is represented as a manifest feature and classified
|
|
227
|
-
this way
|
|
228
|
-
|
|
228
|
+
this way. Raising `DATA_MODEL_MAX_READER` expands what the writer may emit; a
|
|
229
|
+
detectable feature raises only documents carrying its stable marker above the
|
|
230
|
+
retained model-4 baseline.
|
|
229
231
|
|
|
230
232
|
1. **Any change to a persisted field tree is a model change** and must be
|
|
231
233
|
declared: update the model-surface snapshot, add an entry to the model
|
|
@@ -233,16 +235,16 @@ floor.
|
|
|
233
235
|
moves **and whether the reader floor moves with it**. Nothing lands
|
|
234
236
|
"incidentally".
|
|
235
237
|
2. **Additive optional fields are allowed** without machinery: bump
|
|
236
|
-
`DATA_MODEL_VERSION`, leave
|
|
238
|
+
`DATA_MODEL_VERSION`, leave the reader constants untouched, and
|
|
237
239
|
declare the tolerant read (what an absent value means on docs written
|
|
238
240
|
before the field existed) plus why the field survives an old writer's
|
|
239
241
|
round-trip.
|
|
240
242
|
3. **Renames, removals, and semantic changes are not allowed yet.** They
|
|
241
243
|
require versioned upgrade machinery (per-model normalization steps applied
|
|
242
244
|
on read) that does not exist; until it does, the model may only grow
|
|
243
|
-
additively. When such a change eventually lands, it raises
|
|
244
|
-
|
|
245
|
-
only after the fleet story is written.
|
|
245
|
+
additively. When such a change eventually lands, it raises the affected
|
|
246
|
+
documents' reader floor — through `DATA_MODEL_MIN_READER` when no reliable
|
|
247
|
+
marker exists — and ships only after the fleet story is written.
|
|
246
248
|
4. **`DATA_MODEL_VERSION` moves when compatibility reasoning changes** — when
|
|
247
249
|
a reader would need to know which shape it is looking at. A purely
|
|
248
250
|
internal refactor that provably writes an identical tree does not bump.
|
|
@@ -251,7 +253,7 @@ floor.
|
|
|
251
253
|
change the MEANING of existing fields — old readers parse it fine and
|
|
252
254
|
silently misinterpret. That judgment (would an old reader misread, not
|
|
253
255
|
just fail to parse?) is exactly what decides whether
|
|
254
|
-
|
|
256
|
+
a feature floor moves, and no snapshot can make it — each model
|
|
255
257
|
log entry states it explicitly.
|
|
256
258
|
6. **Manifest and prose move together.** Every structural model change adds a
|
|
257
259
|
manifest entry and matching model-log declaration. The ledger snapshots
|
|
@@ -619,7 +621,7 @@ older engine's project-scoped actor silently evaluates false (and the
|
|
|
619
621
|
mirror-image for legacy values under a new actor). Misinterpretation, not
|
|
620
622
|
parse failure — exactly the case the floor exists for. `minReaderModel: 4`
|
|
621
623
|
makes pre-classifier engines refuse the document loudly instead. The writer
|
|
622
|
-
|
|
624
|
+
baseline (`DATA_MODEL_MIN_READER`) rises to 4; deployment acknowledgements
|
|
623
625
|
follow the readers-first rollout (`docs/reader-model-rollout.md`).
|
|
624
626
|
|
|
625
627
|
Manifest feature: `classified-principal-ids` (instance, reader-floor,
|
|
@@ -702,7 +704,7 @@ its base `date` / `datetime`, so no older code path can write it while skipping
|
|
|
702
704
|
validation — there is no silent bypass to fence, and the kinds leave the floor
|
|
703
705
|
at 0.
|
|
704
706
|
|
|
705
|
-
### Model 6 — node semantics and field patch operations
|
|
707
|
+
### Model 6 — node semantics and field patch operations
|
|
706
708
|
|
|
707
709
|
#### Semantics at every definition level
|
|
708
710
|
|
|
@@ -751,8 +753,8 @@ execution with different semantics. Definition documents are create-only,
|
|
|
751
753
|
instance persists preserve the opaque `definitionSnapshot` string, and history
|
|
752
754
|
readers already treat `opType` as an opaque audit label, so the discriminator
|
|
753
755
|
survives an old writer's round trip. Rule 5 fences silent misinterpretation,
|
|
754
|
-
not loud refusal, therefore this detectable feature contributes floor 0 and
|
|
755
|
-
writer maximum
|
|
756
|
+
not loud refusal, therefore this detectable feature contributes floor 0 and does
|
|
757
|
+
not raise the writer maximum. The floor does not protect these definitions from
|
|
756
758
|
older runtimes: upgrade every runtime that can process shared workflow data
|
|
757
759
|
before adopting the new ops.
|
|
758
760
|
|
|
@@ -809,6 +811,49 @@ predicate” to “the synthetic User Attributes bag” with no redeploy. Likely
|
|
|
809
811
|
zero real instances; no migration. Authors who hit it rename the predicate
|
|
810
812
|
and redeploy.
|
|
811
813
|
|
|
814
|
+
### Model 8 — role-constrained assignment fields (reader floor: 8)
|
|
815
|
+
|
|
816
|
+
Assignment-valued field shapes may carry a non-empty `roles` list. The facet
|
|
817
|
+
limits newly written user assignees to project members who fulfil at least one
|
|
818
|
+
listed role, including the definition's role aliases. A collective role
|
|
819
|
+
assignee remains ownership rather than capability and is eligible only when
|
|
820
|
+
its literal role is listed. An absent facet preserves the historical
|
|
821
|
+
unconstrained meaning.
|
|
822
|
+
|
|
823
|
+
Freshly resolved values and singular replacements validate the complete
|
|
824
|
+
assignment. For plural and composite replacements, stale retention is
|
|
825
|
+
count-bounded per declared assignment location: a candidate may retain no more
|
|
826
|
+
occurrences of one assignment identity than the previous value held at that
|
|
827
|
+
location. Array indices are not part of the location, so removal and reordering
|
|
828
|
+
do not make surviving assignments new; an added copy exceeds the previous count
|
|
829
|
+
and must qualify. An `updateWhere` merge validates every assignment location
|
|
830
|
+
present in its incoming fragment strictly, so a fragment must omit rather than
|
|
831
|
+
restate a stale assignment. Each top-level engine verb uses one project-directory
|
|
832
|
+
snapshot across retries, cascade hops, and spawned children; a later verb reads
|
|
833
|
+
a fresh snapshot.
|
|
834
|
+
|
|
835
|
+
The property is valid on `assignee` and `assignees` wherever field shapes are
|
|
836
|
+
declared: scope fields, nested object/array shapes, and effect outputs. This
|
|
837
|
+
follows the definition language's existing facet vocabulary: as `types` says
|
|
838
|
+
which documents may occupy a reference slot, `roles` says which people or
|
|
839
|
+
collective roles may occupy an assignment slot. The existing vocabulary could
|
|
840
|
+
not carry this behavior because `editable` governs who may mutate a field,
|
|
841
|
+
while action `roles` governs who may act; neither describes eligible field
|
|
842
|
+
values.
|
|
843
|
+
|
|
844
|
+
Both stamped trees grow the property: definitions persist it on field shapes,
|
|
845
|
+
and instances copy it onto resolved assignment entries so later writes remain
|
|
846
|
+
self-describing. Model-6 and model-7 writers shipped without this behavior. An
|
|
847
|
+
older reader would preserve the unknown property but silently accept an
|
|
848
|
+
assignee the declaration excludes, so the facet is appended at model 8 rather
|
|
849
|
+
than backfilled into either shipped ledger.
|
|
850
|
+
|
|
851
|
+
Manifest feature: `role-constrained-assignment-fields` (definition + instance,
|
|
852
|
+
reader-floor, detectable, floor 8). A submitted definition set carrying the
|
|
853
|
+
facet requires acknowledgement 8; a set without it may retain acknowledgement 4. Documents without the facet retain the model-4 floor; only definitions and
|
|
854
|
+
instances whose canonical field tree carries a non-empty `roles` list stamp
|
|
855
|
+
floor 8.
|
|
856
|
+
|
|
812
857
|
## Pending governed changes
|
|
813
858
|
|
|
814
859
|
- **`temp.system.guard` → `system.guard`** — the guard doc type's `temp.`
|