The store seam's one write primitive: make the document exist in the
representations the engine's field hydration reads (drafts-over-published,
or the release's version docs when releaseId is set — the matrix lives
on the shared ensureDocumentExists implementation). Resolves once the
write is committed, so a start flow can call it and then startInstance
without racing the lake. Addresses the adapter's own content dataset
(Studio: the mounted workspace; SDK: the instance's configured dataset).
One-shot page fetch for the engine's instancePreviewsQuery reads, returning
raw results; the react layer parses per row. One-shot by design: hydrated
pages are kept fresh by WorkflowObserver.listenInstanceChanges
refetches, never by re-running page queries.
Subscribe to the engine dataset's instance-change feed (the engine's
instanceChangesQuery). The adapter holds one upstream listener per
feed however many stores subscribe. A listener error never throws: the
adapter reconnects with backoff and then emits a reset event, on which
a consumer resynchronizes whatever the gap missed. Returns the
unsubscribe.
Observe every requested document under the supplied perspective. Instance,
ancestor, and system.release documents read raw.
Key each map entry by the requested document's globalDocumentId, including
its resource address. A resolved missing document has a null value;
omitting its key leaves the session waiting for synchronization.
Report pending reads as loading, and surface validation failures or read
errors. Report ready only when every requested read has resolved;
an empty request or already-resolved reads may be ready immediately.
Keep snapshots referentially stable between emissions. Use
combineDocStores to combine per-document stores.
The instance's live mutation guards (temp.system.guard docs keyed by
sourceInstanceId). A standalone stream — the engine excludes guards from
the session's SubscriptionDocument set, so the adapter watches them
separately; the hook surfaces the list and feeds it to the session
(updateGuards) so evaluation re-runs as guards are deployed / deleted. Use
the engine's instancesGuardQuery to build the per-resource query.
Follow WorkflowObserver.observeDocs for pending, ready, invalid, and error states. Do not report a pending read as an empty guard list. Use the shared NO_GUARDS identity for a resolved-empty snapshot.
Guards co-locate with the subjects they lock, so they're spread across the
resources the instance's currently-observed GDRs name; resources holds
that set (engine dataset ∪ each open-stage/workflow-scope subject dataset,
from guardResourcesFor, which is where guards that can deny right
now live). The adapter subscribes one guard stream per resource and merges
them (combineGuardStores); a dataset resource foreign to the
store's own binding is reached the same way observeDocs reaches a foreign
content ref.
sharedIds is the consolidation seam: the id-set of every co-mounted
session, handed identically to each one, so an adapter can subscribe one
set-shaped live query per resource (the engine's instancesGuardQuery)
instead of one per instance, fanning results back out per
sourceInstanceId. The returned stream still holds only this
instance's guards. The set must include instanceId — its rows could
never arrive otherwise, so adapters reject the call rather than resolve
a vacuously empty stream. Omitted, the adapter subscribes for this
instance alone.
A live instance-list read against the engine's workflow resource. The
CompiledQuery comes from the engine's instancesQuery, so the
stateless and reactive paths see the same rows. Single-resource by
definition — instances live only in the engine's own dataset. The snapshot
starts in loading ("still discovering" and
"confirmed none" must be distinguishable), then becomes the matching
ObservedInstances snapshot (readable rows in instances,
refused rows flagged per row in unreadable), an invalid result, or a
read error, and remains reactive.
Store reads and content-document creation supplied by an adapter such as
@sanity/workflow-sdkor@sanity/workflow-studio. Each store reports pending reads, resolved values, validation failures, and read errors through ObserverState.