@sanity/workflow-studio 0.5.0 → 0.7.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/index.cjs CHANGED
@@ -1,159 +1,260 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var workflowEngine = require("@sanity/workflow-engine"), workflowReact = require("@sanity/workflow-react"), workflowSdk = require("@sanity/workflow-sdk"), sdk = require("@sanity/sdk"), react = require("react"), sanity = require("sanity");
4
- function observableStore({
5
- observable,
6
- resolve,
7
- initial
8
- }) {
9
- let latest = initial;
10
- return {
11
- subscribe(onChange) {
12
- const subscription = observable.subscribe((value) => {
13
- latest = resolve(value), onChange();
14
- });
15
- return () => subscription.unsubscribe();
16
- },
17
- getSnapshot: () => latest
18
- };
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ });
6
+
7
+ var workflowEngine = require("@sanity/workflow-engine"), observer = require("@sanity/workflow-react/observer"), observer$1 = require("@sanity/workflow-sdk/observer"), sdk = require("@sanity/sdk"), react = require("react"), sanity = require("sanity"), workflowReact = require("@sanity/workflow-react");
8
+
9
+ const RESUBSCRIBE_DELAY_MS = 5e3;
10
+
11
+ function observableStore({observable: observable, resolve: resolve, initial: initial, name: name}) {
12
+ let latest = initial;
13
+ return {
14
+ subscribe(onChange) {
15
+ let subscription, retry, stopped = !1;
16
+ const connect = () => {
17
+ subscription = observable.subscribe({
18
+ next: value => {
19
+ latest = resolve(value), onChange();
20
+ },
21
+ error: err => {
22
+ console.error(`[workflow-studio] ${name} stream errored — resubscribing in ${RESUBSCRIBE_DELAY_MS / 1e3}s:`, err),
23
+ stopped || (retry = setTimeout(connect, RESUBSCRIBE_DELAY_MS));
24
+ }
25
+ });
26
+ };
27
+ return connect(), () => {
28
+ stopped = !0, retry !== void 0 && clearTimeout(retry), subscription?.unsubscribe();
29
+ };
30
+ },
31
+ getSnapshot: () => latest
32
+ };
19
33
  }
34
+
20
35
  function makeStudioObserver(documentStore, options) {
21
- const { mounted, engineResource, sdk: sdk2 } = options, engineIsMounted = workflowReact.sameDataset(engineResource, mounted), editStateStore = ({
22
- id,
23
- type,
24
- release
25
- }) => observableStore({
26
- observable: documentStore.pair.editState(id, type, release),
27
- resolve: resolveEditState,
28
- initial: void 0
29
- }), requireSdk = (what) => {
30
- if (sdk2 !== void 0) return sdk2;
31
- throw new Error(
32
- `@sanity/workflow-studio: ${what} \u2014 Studio's document store is bound to ${mounted.projectId}.${mounted.dataset} and cannot observe it. Pass an App SDK instance (\`useWorkflowInstance(engine, id, {sdk})\`) to observe foreign resources.`
33
- );
34
- };
35
- return {
36
- observeInstance: (instanceId) => engineIsMounted ? editStateStore({ id: instanceId, type: workflowEngine.WORKFLOW_INSTANCE_TYPE, release: void 0 }) : workflowSdk.sdkInstanceDocStore({
37
- sdk: requireSdk(
38
- `instance "${instanceId}" lives in the engine dataset ${engineResource.projectId}.${engineResource.dataset}`
39
- ),
40
- instanceId,
41
- engineResource
42
- }),
43
- observeDocs: (documents, perspective) => workflowReact.combineDocStores(
44
- documents.map((ref) => workflowReact.classifyRef(ref, mounted) === "mounted-dataset" ? {
45
- key: ref.globalDocumentId,
46
- store: editStateStore({
47
- id: ref.documentId,
48
- type: ref.type,
49
- release: workflowEngine.contentReleaseName({ ref, perspective })
50
- })
51
- } : {
52
- key: ref.globalDocumentId,
53
- store: workflowSdk.sdkContentDocStore({
54
- sdk: requireSdk(`"${ref.globalDocumentId}" lives outside this workspace`),
55
- ref,
56
- perspective
57
- })
58
- })
59
- ),
60
- observeGuards: (instanceId, resources) => workflowReact.combineGuardStores(
61
- resources.map((resource) => {
62
- if (workflowReact.sameDataset(resource, mounted)) {
63
- const { query, params } = workflowEngine.instanceGuardQuery(instanceId);
64
- return observableStore({
65
- observable: documentStore.listenQuery(query, params, {}),
66
- resolve: (docs) => docs,
67
- initial: workflowReact.NO_GUARDS
68
- });
69
- }
70
- return workflowSdk.sdkGuardStore({
71
- sdk: requireSdk(
72
- `guards for "${instanceId}" live in ${resource.projectId}.${resource.dataset}`
73
- ),
74
- instanceId,
75
- resource
76
- });
77
- })
78
- )
79
- };
36
+ const {mounted: mounted, engineResource: engineResource, sdk: sdk2, client: client} = options, engineIsMounted = observer.sameDataset(engineResource, mounted), editStateStore = ({id: id, type: type, release: release}) => observableStore({
37
+ observable: documentStore.pair.editState(id, type, release),
38
+ resolve: resolveEditState,
39
+ initial: void 0,
40
+ name: `the edit state of "${id}"`
41
+ }), requireSdk = what => {
42
+ if (sdk2 !== void 0) return sdk2;
43
+ throw new Error(`@sanity/workflow-studio: ${what} — Studio's document store is bound to ${mounted.projectId}.${mounted.dataset} and cannot observe it. Pass an App SDK instance via the hook's \`sdk\` option (e.g. \`useWorkflowSession({engine, instanceId, sdk})\`) to observe foreign resources.`);
44
+ };
45
+ return {
46
+ observeInstance: instanceId => engineIsMounted ? editStateStore({
47
+ id: instanceId,
48
+ type: workflowEngine.WORKFLOW_INSTANCE_TYPE,
49
+ release: void 0
50
+ }) : observer$1.sdkInstanceDocStore({
51
+ sdk: requireSdk(`instance "${instanceId}" lives in the engine dataset ${engineResource.projectId}.${engineResource.dataset}`),
52
+ instanceId: instanceId,
53
+ engineResource: engineResource
54
+ }),
55
+ observeDocs: (documents, perspective) => observer.combineDocStores(documents.map(ref => observer.classifyRef(ref, mounted) === "mounted-dataset" ? {
56
+ key: ref.globalDocumentId,
57
+ store: editStateStore({
58
+ id: ref.documentId,
59
+ type: ref.type,
60
+ release: workflowEngine.contentReleaseName({
61
+ ref: ref,
62
+ perspective: perspective
63
+ })
64
+ })
65
+ } : {
66
+ key: ref.globalDocumentId,
67
+ store: observer$1.sdkContentDocStore({
68
+ sdk: requireSdk(`"${ref.globalDocumentId}" lives outside this workspace`),
69
+ ref: ref,
70
+ perspective: perspective
71
+ })
72
+ })),
73
+ observeGuards: (instanceId, resources) => observer.combineGuardStores(resources.map(resource => {
74
+ if (observer.sameDataset(resource, mounted)) {
75
+ const {query: query, params: params} = workflowEngine.instanceGuardQuery(instanceId);
76
+ return observableStore({
77
+ observable: documentStore.listenQuery(query, params, {}),
78
+ resolve: docs => docs,
79
+ initial: void 0,
80
+ name: `the guard list for "${instanceId}"`
81
+ });
82
+ }
83
+ return observer$1.sdkGuardStore({
84
+ sdk: requireSdk(`guards for "${instanceId}" live in ${resource.projectId}.${resource.dataset}`),
85
+ instanceId: instanceId,
86
+ resource: resource
87
+ });
88
+ })),
89
+ observeInstances: query => engineIsMounted ? observableStore({
90
+ observable: documentStore.listenQuery(query.query, query.params, {}),
91
+ resolve: docs => docs,
92
+ initial: void 0,
93
+ name: "the instance list"
94
+ }) : observer$1.sdkInstancesStore({
95
+ sdk: requireSdk(`the instance list lives in the engine dataset ${engineResource.projectId}.${engineResource.dataset}`),
96
+ query: query,
97
+ resource: engineResource
98
+ }),
99
+ ensureDocumentExists: args => observer.ensureDocumentExists(client, args)
100
+ };
80
101
  }
102
+
81
103
  function resolveEditState(editState) {
82
- if (editState.ready)
83
- return editState.version ?? editState.draft ?? editState.published;
104
+ if (editState.ready) return editState.version ?? editState.draft ?? editState.published;
84
105
  }
85
- function useWorkflowInstance({
86
- engine,
87
- instanceId,
88
- access,
89
- grantsFromPath,
90
- sdk: suppliedSdk
91
- }) {
92
- const documentStore = sanity.useDocumentStore(), { projectId, dataset } = sanity.useSource(), mounted = react.useMemo(() => ({ projectId, dataset }), [projectId, dataset]), engineResource = react.useMemo(() => workflowReact.datasetResourceId(engine.workflowResource), [engine]), sdk2 = useEmbeddedSdk({
93
- supplied: suppliedSdk,
94
- // The engine dataset being foreign is the signal an SDK instance is
95
- // needed; foreign content refs without one still fail loud per ref.
96
- needed: !workflowReact.sameDataset(engineResource, mounted),
97
- mounted
98
- }), observer = react.useMemo(
99
- () => makeStudioObserver(documentStore, {
100
- mounted,
101
- engineResource,
102
- ...sdk2 !== void 0 ? { sdk: sdk2 } : {}
103
- }),
104
- [documentStore, mounted, engineResource, sdk2]
105
- );
106
- return workflowReact.useWorkflowSession({ engine, instanceId, observer, opts: { access, grantsFromPath } });
106
+
107
+ const SESSION_CLIENT_OPTIONS = {
108
+ apiVersion: workflowEngine.ENGINE_API_VERSION
109
+ };
110
+
111
+ function useStudioObserver({engine: engine, sdk: suppliedSdk}) {
112
+ const documentStore = sanity.useDocumentStore(), source = sanity.useSource(), {projectId: projectId, dataset: dataset} = source, mounted = react.useMemo(() => ({
113
+ projectId: projectId,
114
+ dataset: dataset
115
+ }), [ projectId, dataset ]), engineResource = react.useMemo(() => observer.datasetResourceId(engine.workflowResource), [ engine ]), sdk2 = useEmbeddedSdk({
116
+ supplied: suppliedSdk,
117
+ needed: !observer.sameDataset(engineResource, mounted),
118
+ mounted: mounted,
119
+ sessionToken: source.getClient(SESSION_CLIENT_OPTIONS).config().token
120
+ });
121
+ return react.useMemo(() => makeStudioObserver(documentStore, {
122
+ mounted: mounted,
123
+ client: source.getClient(SESSION_CLIENT_OPTIONS),
124
+ engineResource: engineResource,
125
+ ...sdk2 !== void 0 ? {
126
+ sdk: sdk2
127
+ } : {}
128
+ }), [ documentStore, source, mounted, engineResource, sdk2 ]);
107
129
  }
108
- function useEmbeddedSdk({
109
- supplied,
110
- needed,
111
- mounted
112
- }) {
113
- const wanted = supplied === void 0 && needed, held = react.useRef(void 0), key = `${mounted.projectId}.${mounted.dataset}`;
114
- wanted && (held.current?.key !== key || held.current.instance.isDisposed()) && (held.current = { key, instance: bootstrapInstance(mounted) });
115
- const embedded = wanted ? held.current?.instance : void 0;
116
- return useDeferredDispose(embedded), supplied ?? embedded;
130
+
131
+ function useEmbeddedSdk({supplied: supplied, needed: needed, mounted: mounted, sessionToken: sessionToken}) {
132
+ const wanted = supplied === void 0 && needed, held = react.useRef(void 0), key = `${mounted.projectId}.${mounted.dataset}`;
133
+ wanted && (held.current?.key !== key || held.current.instance.isDisposed()) && (held.current = {
134
+ key: key,
135
+ instance: bootstrapInstance(mounted, sessionToken)
136
+ });
137
+ const embedded = wanted ? held.current?.instance : void 0;
138
+ return useDeferredDispose(embedded), supplied ?? embedded;
117
139
  }
118
- function bootstrapInstance(mounted) {
119
- return sdk.createSanityInstance({
120
- projectId: mounted.projectId,
121
- dataset: mounted.dataset,
122
- auth: { token: studioSessionToken(mounted.projectId) }
123
- });
140
+
141
+ function bootstrapInstance(mounted, sessionToken) {
142
+ if (sessionToken === void 0) throw new Error("@sanity/workflow-studio: the engine's state dataset is not this workspace's dataset, and no Studio session token is readable to bootstrap an App SDK instance (cookie-authenticated studio?). Pass one explicitly via the hook's `sdk` option, e.g. useWorkflowSession({engine, instanceId, sdk}).");
143
+ return sdk.createSanityInstance({
144
+ projectId: mounted.projectId,
145
+ dataset: mounted.dataset,
146
+ auth: {
147
+ token: sessionToken
148
+ }
149
+ });
124
150
  }
151
+
125
152
  function useDeferredDispose(instance) {
126
- const disposal = react.useRef(void 0);
127
- react.useEffect(() => {
128
- if (instance !== void 0)
129
- return disposal.current?.instance === instance && (clearTimeout(disposal.current.timeoutId), disposal.current = void 0), () => {
130
- disposal.current = {
131
- instance,
132
- timeoutId: setTimeout(() => {
133
- instance.isDisposed() || instance.dispose();
134
- }, 0)
153
+ const disposal = react.useRef(void 0);
154
+ react.useEffect(() => {
155
+ if (instance !== void 0) return disposal.current?.instance === instance && (clearTimeout(disposal.current.timeoutId),
156
+ disposal.current = void 0), () => {
157
+ disposal.current = {
158
+ instance: instance,
159
+ timeoutId: setTimeout(() => {
160
+ instance.isDisposed() || instance.dispose();
161
+ }, 0)
162
+ };
135
163
  };
136
- };
137
- }, [instance]);
164
+ }, [ instance ]);
165
+ }
166
+
167
+ function useWorkflowEngine({workflowResource: workflowResource, tag: tag, resourceClients: resourceClients, effectHandlers: effectHandlers, missingHandler: missingHandler}) {
168
+ const client = sanity.useClient({
169
+ apiVersion: workflowEngine.ENGINE_API_VERSION
170
+ }), resource = observer.useKeyed([ workflowResource.type, workflowResource.id ], () => workflowResource), telemetry = workflowReact.useWorkflowTelemetry();
171
+ return react.useMemo(() => {
172
+ const engineDataset = observer.datasetResourceId(resource), engineClient = client.withConfig({
173
+ projectId: engineDataset.projectId,
174
+ dataset: engineDataset.dataset,
175
+ useCdn: !1,
176
+ requestTagPrefix: "sanity.workflows.studio"
177
+ });
178
+ return workflowEngine.createEngine({
179
+ client: engineClient,
180
+ workflowResource: resource,
181
+ tag: tag,
182
+ resourceClients: resourceClients ?? studioResourceClients(client),
183
+ executionContext: {
184
+ kind: workflowEngine.EXECUTION_KINDS.studio
185
+ },
186
+ ...effectHandlers !== void 0 ? {
187
+ effectHandlers: effectHandlers
188
+ } : {},
189
+ ...missingHandler !== void 0 ? {
190
+ missingHandler: missingHandler
191
+ } : {},
192
+ telemetry: telemetry
193
+ });
194
+ }, [ client, resource, tag, resourceClients, effectHandlers, missingHandler, telemetry ]);
195
+ }
196
+
197
+ function studioResourceClients(client) {
198
+ return parsed => parsed.scheme === "dataset" && parsed.projectId !== void 0 && parsed.dataset !== void 0 ? client.withConfig({
199
+ projectId: parsed.projectId,
200
+ dataset: parsed.dataset,
201
+ useCdn: !1,
202
+ requestTagPrefix: "sanity.workflows.studio"
203
+ }) : void 0;
204
+ }
205
+
206
+ function useWorkflowSession({engine: engine, instanceId: instanceId, grantsFromPath: grantsFromPath, sdk: sdk2}) {
207
+ const observer2 = useStudioObserver({
208
+ engine: engine,
209
+ sdk: sdk2
210
+ });
211
+ return workflowReact.useWorkflowSession({
212
+ engine: engine,
213
+ instanceId: instanceId,
214
+ observer: observer2,
215
+ host: "studio",
216
+ opts: {
217
+ grantsFromPath: grantsFromPath
218
+ }
219
+ });
138
220
  }
139
- function studioSessionToken(projectId) {
140
- const token = persistedToken(projectId);
141
- if (typeof token != "string")
142
- throw new Error(
143
- "@sanity/workflow-studio: the engine's state dataset is not this workspace's dataset, and no Studio session token is readable to bootstrap an App SDK instance (cookie-authenticated studio?). Pass one explicitly: useWorkflowInstance({engine, instanceId, sdk})."
144
- );
145
- return token;
221
+
222
+ function useWorkflowInstances({engine: engine, filter: filter, sdk: sdk2}) {
223
+ const observer2 = useStudioObserver({
224
+ engine: engine,
225
+ sdk: sdk2
226
+ });
227
+ return workflowReact.useWorkflowInstances({
228
+ engine: engine,
229
+ observer: observer2,
230
+ ...filter !== void 0 ? {
231
+ filter: filter
232
+ } : {}
233
+ });
146
234
  }
147
- function persistedToken(projectId) {
148
- const raw = window.localStorage.getItem(`__studio_auth_token_${projectId}`);
149
- if (raw !== null)
150
- try {
151
- const parsed = JSON.parse(raw);
152
- return typeof parsed != "object" || parsed === null ? void 0 : parsed.token;
153
- } catch {
154
- return;
155
- }
235
+
236
+ function useDocumentWorkflows({engine: engine, document: document, sdk: sdk2}) {
237
+ const observer2 = useStudioObserver({
238
+ engine: engine,
239
+ sdk: sdk2
240
+ });
241
+ return workflowReact.useDocumentWorkflows({
242
+ engine: engine,
243
+ observer: observer2,
244
+ document: document
245
+ });
156
246
  }
247
+
157
248
  exports.makeStudioObserver = makeStudioObserver;
158
- exports.useWorkflowInstance = useWorkflowInstance;
159
- //# sourceMappingURL=index.cjs.map
249
+
250
+ exports.studioResourceClients = studioResourceClients;
251
+
252
+ exports.useDocumentWorkflows = useDocumentWorkflows;
253
+
254
+ exports.useStudioObserver = useStudioObserver;
255
+
256
+ exports.useWorkflowEngine = useWorkflowEngine;
257
+
258
+ exports.useWorkflowInstances = useWorkflowInstances;
259
+
260
+ exports.useWorkflowSession = useWorkflowSession;
package/dist/index.d.cts CHANGED
@@ -1,11 +1,19 @@
1
- import { DatasetResourceId } from "@sanity/workflow-react";
1
+ import { DatasetResourceId } from "@sanity/workflow-react/observer";
2
2
  import type { DocumentStore } from "sanity";
3
- import type { Engine } from "@sanity/workflow-engine";
3
+ import { EffectHandler } from "@sanity/workflow-engine";
4
+ import { Engine } from "@sanity/workflow-engine";
5
+ import type { GdrUri } from "@sanity/workflow-engine";
6
+ import type { InstancesQueryFilter } from "@sanity/workflow-engine";
7
+ import { MissingHandlerPolicy } from "@sanity/workflow-engine";
4
8
  import { MutationGuardDoc } from "@sanity/workflow-react";
9
+ import { ResourceClientResolver } from "@sanity/workflow-engine";
10
+ import type { SanityClient } from "sanity";
5
11
  import { SanityInstance } from "@sanity/sdk";
6
- import type { WorkflowAccessOverride } from "@sanity/workflow-engine";
7
- import { WorkflowInstanceController } from "@sanity/workflow-react";
8
- import { WorkflowObserver } from "@sanity/workflow-react";
12
+ import { useClient } from "sanity";
13
+ import { WorkflowInstanceList } from "@sanity/workflow-react";
14
+ import { WorkflowObserver } from "@sanity/workflow-react/observer";
15
+ import { WorkflowResource } from "@sanity/workflow-engine";
16
+ import { WorkflowSession } from "@sanity/workflow-react";
9
17
 
10
18
  /**
11
19
  * A {@link WorkflowObserver} that routes every stream to the store that can
@@ -13,7 +21,8 @@ import { WorkflowObserver } from "@sanity/workflow-react";
13
21
  *
14
22
  * - Anything in the **mounted workspace dataset** → `documentStore`
15
23
  * (`pair.editState` for docs — including Studio's local uncommitted edits,
16
- * the one stream only Studio has — and `listenQuery` for guards).
24
+ * the one stream only Studio has — and `listenQuery` for guards and
25
+ * instance lists).
17
26
  * - Anything else (foreign content refs; the engine's state dataset when it
18
27
  * isn't the workspace) → the App SDK store via {@link sdkInstanceDocStore} /
19
28
  * {@link sdkContentDocStore} / {@link sdkGuardStore} when
@@ -27,10 +36,15 @@ export declare function makeStudioObserver(
27
36
 
28
37
  export { MutationGuardDoc };
29
38
 
39
+ declare type StudioClient = ReturnType<typeof useClient>;
40
+
30
41
  export declare interface StudioObserverOptions {
31
42
  /** The workspace's project + dataset — the only resource Studio's
32
43
  * `documentStore` can address. */
33
44
  mounted: DatasetResourceId;
45
+ /** A workspace-bound client — carries `ensureDocumentExists` writes, which
46
+ * address the mounted dataset (where the workspace's subject docs live). */
47
+ client: SanityClient;
34
48
  /** The engine's state dataset (`datasetResourceId(engine.workflowResource)`)
35
49
  * — where the instance doc and its verdict-relevant guards live. Routinely
36
50
  * a dedicated `workflows` dataset distinct from the workspace. */
@@ -42,6 +56,88 @@ export declare interface StudioObserverOptions {
42
56
  sdk?: SanityInstance;
43
57
  }
44
58
 
59
+ /**
60
+ * The default Studio {@link ResourceClientResolver}: any fully-addressed
61
+ * `dataset:` GDR resolves to the workspace client rebound to that
62
+ * project/dataset; other schemes (media-library, canvas) return `undefined`,
63
+ * letting the engine route them — a sibling client derived from the engine
64
+ * client's own credentials for foreign resources, its own client for the
65
+ * workflow resource. A custom resolver can delegate to this for the dataset
66
+ * arm and handle other schemes itself.
67
+ */
68
+ export declare function studioResourceClients(
69
+ client: StudioClient,
70
+ ): ResourceClientResolver;
71
+
72
+ /** Which in-flight instances reference this document (GDR URI) — live,
73
+ * observed from Sanity Studio. Same routing and `sdk` rules as
74
+ * {@link useWorkflowInstances}. */
75
+ export declare function useDocumentWorkflows({
76
+ engine,
77
+ document,
78
+ sdk,
79
+ }: {
80
+ engine: Engine;
81
+ document: GdrUri;
82
+ sdk?: SanityInstance;
83
+ }): WorkflowInstanceList;
84
+
85
+ /**
86
+ * The Studio observer for this engine — the shared wiring under every
87
+ * reactive hook in this package. Workspace-dataset streams ride
88
+ * `documentStore`; anything foreign (routinely the engine's dedicated
89
+ * `workflows` dataset) rides an App SDK instance, bootstrapped from the
90
+ * Studio session when the caller doesn't supply one. Must run inside Studio
91
+ * source context (so `useDocumentStore`/`useSource` resolve).
92
+ */
93
+ export declare function useStudioObserver({
94
+ engine,
95
+ sdk: suppliedSdk,
96
+ }: {
97
+ engine: Engine;
98
+ sdk?: SanityInstance | undefined;
99
+ }): WorkflowObserver;
100
+
101
+ /**
102
+ * Build the Studio-side engine once: the workspace client rebound to the
103
+ * engine's state dataset, plus {@link studioResourceClients} as the default
104
+ * per-resource routing — so subjects and refs across many content datasets
105
+ * resolve without call sites assembling clients. Pass `resourceClients` to
106
+ * override the routing (compose with {@link studioResourceClients} to keep
107
+ * dataset-GDR routing). `effectHandlers`/`missingHandler` feed
108
+ * {@link Engine.drainEffects} for engines that drain effects in the Studio.
109
+ * Memoized on the config's content, so inline `workflowResource` literals are
110
+ * fine; custom `resourceClients` and `effectHandlers` values should still be
111
+ * stable. Must render inside Studio source context.
112
+ */
113
+ export declare function useWorkflowEngine({
114
+ workflowResource,
115
+ tag,
116
+ resourceClients,
117
+ effectHandlers,
118
+ missingHandler,
119
+ }: {
120
+ workflowResource: WorkflowResource;
121
+ tag: string;
122
+ resourceClients?: ResourceClientResolver;
123
+ effectHandlers?: Record<string, EffectHandler>;
124
+ missingHandler?: MissingHandlerPolicy;
125
+ }): Engine;
126
+
127
+ /** A live, filterable workflow-instance list observed from Sanity Studio —
128
+ * through `documentStore.listenQuery` when the engine dataset is the
129
+ * workspace's own, else through an App SDK instance (auto-bootstrapped, or
130
+ * supply `sdk`). Must render inside Studio source context. */
131
+ export declare function useWorkflowInstances({
132
+ engine,
133
+ filter,
134
+ sdk,
135
+ }: {
136
+ engine: Engine;
137
+ filter?: InstancesQueryFilter;
138
+ sdk?: SanityInstance;
139
+ }): WorkflowInstanceList;
140
+
45
141
  /**
46
142
  * Drive a workflow instance reactively from Sanity Studio. Watched docs in the
47
143
  * workspace's own dataset observe through `documentStore.pair.editState`
@@ -51,24 +147,24 @@ export declare interface StudioObserverOptions {
51
147
  * from the workspace, an SDK instance is bootstrapped automatically from the
52
148
  * Studio session (pass `sdk` to supply your own — required for
53
149
  * cookie-authenticated studios, where no session token is readable). Returns
54
- * `{evaluation, ready, guards, tick, fireAction, editField}`; the consumer decides when
55
- * to advance. Must render inside Studio source context (so
56
- * `useDocumentStore`/`useSource` resolve).
150
+ * the full {@link WorkflowSession} (evaluation, ready, guards, and the
151
+ * tick/fireAction/editField/preview verbs); the consumer decides when to
152
+ * advance. Must render inside Studio source context.
57
153
  */
58
- export declare function useWorkflowInstance({
154
+ export declare function useWorkflowSession({
59
155
  engine,
60
156
  instanceId,
61
- access,
62
157
  grantsFromPath,
63
- sdk: suppliedSdk,
158
+ sdk,
64
159
  }: {
65
160
  engine: Engine;
66
161
  instanceId: string;
67
- access?: WorkflowAccessOverride;
68
162
  grantsFromPath?: string;
69
163
  sdk?: SanityInstance;
70
- }): WorkflowInstanceController;
164
+ }): WorkflowSession;
165
+
166
+ export { WorkflowInstanceList };
71
167
 
72
- export { WorkflowInstanceController };
168
+ export { WorkflowSession };
73
169
 
74
170
  export {};