@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.d.ts 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 {};
package/dist/index.js CHANGED
@@ -1,164 +1,254 @@
1
- import { instanceGuardQuery, contentReleaseName, WORKFLOW_INSTANCE_TYPE } from "@sanity/workflow-engine";
2
- import { sameDataset, combineGuardStores, combineDocStores, classifyRef, NO_GUARDS, datasetResourceId, useWorkflowSession } from "@sanity/workflow-react";
3
- import { sdkGuardStore, sdkContentDocStore, sdkInstanceDocStore } from "@sanity/workflow-sdk";
1
+ import { instanceGuardQuery, contentReleaseName, WORKFLOW_INSTANCE_TYPE, ENGINE_API_VERSION, createEngine, EXECUTION_KINDS } from "@sanity/workflow-engine";
2
+
3
+ import { sameDataset, ensureDocumentExists, combineGuardStores, combineDocStores, classifyRef, datasetResourceId, useKeyed } from "@sanity/workflow-react/observer";
4
+
5
+ import { sdkInstancesStore, sdkGuardStore, sdkContentDocStore, sdkInstanceDocStore } from "@sanity/workflow-sdk/observer";
6
+
4
7
  import { createSanityInstance } from "@sanity/sdk";
8
+
5
9
  import { useMemo, useRef, useEffect } from "react";
6
- import { useDocumentStore, useSource } from "sanity";
7
- function observableStore({
8
- observable,
9
- resolve,
10
- initial
11
- }) {
12
- let latest = initial;
13
- return {
14
- subscribe(onChange) {
15
- const subscription = observable.subscribe((value) => {
16
- latest = resolve(value), onChange();
17
- });
18
- return () => subscription.unsubscribe();
19
- },
20
- getSnapshot: () => latest
21
- };
10
+
11
+ import { useDocumentStore, useSource, useClient } from "sanity";
12
+
13
+ import { useWorkflowTelemetry, useWorkflowSession as useWorkflowSession$1, useDocumentWorkflows as useDocumentWorkflows$1, useWorkflowInstances as useWorkflowInstances$1 } from "@sanity/workflow-react";
14
+
15
+ const RESUBSCRIBE_DELAY_MS = 5e3;
16
+
17
+ function observableStore({observable: observable, resolve: resolve, initial: initial, name: name}) {
18
+ let latest = initial;
19
+ return {
20
+ subscribe(onChange) {
21
+ let subscription, retry, stopped = !1;
22
+ const connect = () => {
23
+ subscription = observable.subscribe({
24
+ next: value => {
25
+ latest = resolve(value), onChange();
26
+ },
27
+ error: err => {
28
+ console.error(`[workflow-studio] ${name} stream errored — resubscribing in ${RESUBSCRIBE_DELAY_MS / 1e3}s:`, err),
29
+ stopped || (retry = setTimeout(connect, RESUBSCRIBE_DELAY_MS));
30
+ }
31
+ });
32
+ };
33
+ return connect(), () => {
34
+ stopped = !0, retry !== void 0 && clearTimeout(retry), subscription?.unsubscribe();
35
+ };
36
+ },
37
+ getSnapshot: () => latest
38
+ };
22
39
  }
40
+
23
41
  function makeStudioObserver(documentStore, options) {
24
- const { mounted, engineResource, sdk } = options, engineIsMounted = sameDataset(engineResource, mounted), editStateStore = ({
25
- id,
26
- type,
27
- release
28
- }) => observableStore({
29
- observable: documentStore.pair.editState(id, type, release),
30
- resolve: resolveEditState,
31
- initial: void 0
32
- }), requireSdk = (what) => {
33
- if (sdk !== void 0) return sdk;
34
- throw new Error(
35
- `@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.`
36
- );
37
- };
38
- return {
39
- observeInstance: (instanceId) => engineIsMounted ? editStateStore({ id: instanceId, type: WORKFLOW_INSTANCE_TYPE, release: void 0 }) : sdkInstanceDocStore({
40
- sdk: requireSdk(
41
- `instance "${instanceId}" lives in the engine dataset ${engineResource.projectId}.${engineResource.dataset}`
42
- ),
43
- instanceId,
44
- engineResource
45
- }),
46
- observeDocs: (documents, perspective) => combineDocStores(
47
- documents.map((ref) => classifyRef(ref, mounted) === "mounted-dataset" ? {
48
- key: ref.globalDocumentId,
49
- store: editStateStore({
50
- id: ref.documentId,
51
- type: ref.type,
52
- release: contentReleaseName({ ref, perspective })
53
- })
54
- } : {
55
- key: ref.globalDocumentId,
56
- store: sdkContentDocStore({
57
- sdk: requireSdk(`"${ref.globalDocumentId}" lives outside this workspace`),
58
- ref,
59
- perspective
60
- })
61
- })
62
- ),
63
- observeGuards: (instanceId, resources) => combineGuardStores(
64
- resources.map((resource) => {
65
- if (sameDataset(resource, mounted)) {
66
- const { query, params } = instanceGuardQuery(instanceId);
67
- return observableStore({
68
- observable: documentStore.listenQuery(query, params, {}),
69
- resolve: (docs) => docs,
70
- initial: NO_GUARDS
71
- });
72
- }
73
- return sdkGuardStore({
74
- sdk: requireSdk(
75
- `guards for "${instanceId}" live in ${resource.projectId}.${resource.dataset}`
76
- ),
77
- instanceId,
78
- resource
79
- });
80
- })
81
- )
82
- };
42
+ const {mounted: mounted, engineResource: engineResource, sdk: sdk, client: client} = options, engineIsMounted = sameDataset(engineResource, mounted), editStateStore = ({id: id, type: type, release: release}) => observableStore({
43
+ observable: documentStore.pair.editState(id, type, release),
44
+ resolve: resolveEditState,
45
+ initial: void 0,
46
+ name: `the edit state of "${id}"`
47
+ }), requireSdk = what => {
48
+ if (sdk !== void 0) return sdk;
49
+ 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.`);
50
+ };
51
+ return {
52
+ observeInstance: instanceId => engineIsMounted ? editStateStore({
53
+ id: instanceId,
54
+ type: WORKFLOW_INSTANCE_TYPE,
55
+ release: void 0
56
+ }) : sdkInstanceDocStore({
57
+ sdk: requireSdk(`instance "${instanceId}" lives in the engine dataset ${engineResource.projectId}.${engineResource.dataset}`),
58
+ instanceId: instanceId,
59
+ engineResource: engineResource
60
+ }),
61
+ observeDocs: (documents, perspective) => combineDocStores(documents.map(ref => classifyRef(ref, mounted) === "mounted-dataset" ? {
62
+ key: ref.globalDocumentId,
63
+ store: editStateStore({
64
+ id: ref.documentId,
65
+ type: ref.type,
66
+ release: contentReleaseName({
67
+ ref: ref,
68
+ perspective: perspective
69
+ })
70
+ })
71
+ } : {
72
+ key: ref.globalDocumentId,
73
+ store: sdkContentDocStore({
74
+ sdk: requireSdk(`"${ref.globalDocumentId}" lives outside this workspace`),
75
+ ref: ref,
76
+ perspective: perspective
77
+ })
78
+ })),
79
+ observeGuards: (instanceId, resources) => combineGuardStores(resources.map(resource => {
80
+ if (sameDataset(resource, mounted)) {
81
+ const {query: query, params: params} = instanceGuardQuery(instanceId);
82
+ return observableStore({
83
+ observable: documentStore.listenQuery(query, params, {}),
84
+ resolve: docs => docs,
85
+ initial: void 0,
86
+ name: `the guard list for "${instanceId}"`
87
+ });
88
+ }
89
+ return sdkGuardStore({
90
+ sdk: requireSdk(`guards for "${instanceId}" live in ${resource.projectId}.${resource.dataset}`),
91
+ instanceId: instanceId,
92
+ resource: resource
93
+ });
94
+ })),
95
+ observeInstances: query => engineIsMounted ? observableStore({
96
+ observable: documentStore.listenQuery(query.query, query.params, {}),
97
+ resolve: docs => docs,
98
+ initial: void 0,
99
+ name: "the instance list"
100
+ }) : sdkInstancesStore({
101
+ sdk: requireSdk(`the instance list lives in the engine dataset ${engineResource.projectId}.${engineResource.dataset}`),
102
+ query: query,
103
+ resource: engineResource
104
+ }),
105
+ ensureDocumentExists: args => ensureDocumentExists(client, args)
106
+ };
83
107
  }
108
+
84
109
  function resolveEditState(editState) {
85
- if (editState.ready)
86
- return editState.version ?? editState.draft ?? editState.published;
110
+ if (editState.ready) return editState.version ?? editState.draft ?? editState.published;
87
111
  }
88
- function useWorkflowInstance({
89
- engine,
90
- instanceId,
91
- access,
92
- grantsFromPath,
93
- sdk: suppliedSdk
94
- }) {
95
- const documentStore = useDocumentStore(), { projectId, dataset } = useSource(), mounted = useMemo(() => ({ projectId, dataset }), [projectId, dataset]), engineResource = useMemo(() => datasetResourceId(engine.workflowResource), [engine]), sdk = useEmbeddedSdk({
96
- supplied: suppliedSdk,
97
- // The engine dataset being foreign is the signal an SDK instance is
98
- // needed; foreign content refs without one still fail loud per ref.
99
- needed: !sameDataset(engineResource, mounted),
100
- mounted
101
- }), observer = useMemo(
102
- () => makeStudioObserver(documentStore, {
103
- mounted,
104
- engineResource,
105
- ...sdk !== void 0 ? { sdk } : {}
106
- }),
107
- [documentStore, mounted, engineResource, sdk]
108
- );
109
- return useWorkflowSession({ engine, instanceId, observer, opts: { access, grantsFromPath } });
112
+
113
+ const SESSION_CLIENT_OPTIONS = {
114
+ apiVersion: ENGINE_API_VERSION
115
+ };
116
+
117
+ function useStudioObserver({engine: engine, sdk: suppliedSdk}) {
118
+ const documentStore = useDocumentStore(), source = useSource(), {projectId: projectId, dataset: dataset} = source, mounted = useMemo(() => ({
119
+ projectId: projectId,
120
+ dataset: dataset
121
+ }), [ projectId, dataset ]), engineResource = useMemo(() => datasetResourceId(engine.workflowResource), [ engine ]), sdk = useEmbeddedSdk({
122
+ supplied: suppliedSdk,
123
+ needed: !sameDataset(engineResource, mounted),
124
+ mounted: mounted,
125
+ sessionToken: source.getClient(SESSION_CLIENT_OPTIONS).config().token
126
+ });
127
+ return useMemo(() => makeStudioObserver(documentStore, {
128
+ mounted: mounted,
129
+ client: source.getClient(SESSION_CLIENT_OPTIONS),
130
+ engineResource: engineResource,
131
+ ...sdk !== void 0 ? {
132
+ sdk: sdk
133
+ } : {}
134
+ }), [ documentStore, source, mounted, engineResource, sdk ]);
110
135
  }
111
- function useEmbeddedSdk({
112
- supplied,
113
- needed,
114
- mounted
115
- }) {
116
- const wanted = supplied === void 0 && needed, held = useRef(void 0), key = `${mounted.projectId}.${mounted.dataset}`;
117
- wanted && (held.current?.key !== key || held.current.instance.isDisposed()) && (held.current = { key, instance: bootstrapInstance(mounted) });
118
- const embedded = wanted ? held.current?.instance : void 0;
119
- return useDeferredDispose(embedded), supplied ?? embedded;
136
+
137
+ function useEmbeddedSdk({supplied: supplied, needed: needed, mounted: mounted, sessionToken: sessionToken}) {
138
+ const wanted = supplied === void 0 && needed, held = useRef(void 0), key = `${mounted.projectId}.${mounted.dataset}`;
139
+ wanted && (held.current?.key !== key || held.current.instance.isDisposed()) && (held.current = {
140
+ key: key,
141
+ instance: bootstrapInstance(mounted, sessionToken)
142
+ });
143
+ const embedded = wanted ? held.current?.instance : void 0;
144
+ return useDeferredDispose(embedded), supplied ?? embedded;
120
145
  }
121
- function bootstrapInstance(mounted) {
122
- return createSanityInstance({
123
- projectId: mounted.projectId,
124
- dataset: mounted.dataset,
125
- auth: { token: studioSessionToken(mounted.projectId) }
126
- });
146
+
147
+ function bootstrapInstance(mounted, sessionToken) {
148
+ 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}).");
149
+ return createSanityInstance({
150
+ projectId: mounted.projectId,
151
+ dataset: mounted.dataset,
152
+ auth: {
153
+ token: sessionToken
154
+ }
155
+ });
127
156
  }
157
+
128
158
  function useDeferredDispose(instance) {
129
- const disposal = useRef(void 0);
130
- useEffect(() => {
131
- if (instance !== void 0)
132
- return disposal.current?.instance === instance && (clearTimeout(disposal.current.timeoutId), disposal.current = void 0), () => {
133
- disposal.current = {
134
- instance,
135
- timeoutId: setTimeout(() => {
136
- instance.isDisposed() || instance.dispose();
137
- }, 0)
159
+ const disposal = useRef(void 0);
160
+ useEffect(() => {
161
+ if (instance !== void 0) return disposal.current?.instance === instance && (clearTimeout(disposal.current.timeoutId),
162
+ disposal.current = void 0), () => {
163
+ disposal.current = {
164
+ instance: instance,
165
+ timeoutId: setTimeout(() => {
166
+ instance.isDisposed() || instance.dispose();
167
+ }, 0)
168
+ };
138
169
  };
139
- };
140
- }, [instance]);
170
+ }, [ instance ]);
141
171
  }
142
- function studioSessionToken(projectId) {
143
- const token = persistedToken(projectId);
144
- if (typeof token != "string")
145
- throw new Error(
146
- "@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})."
147
- );
148
- return token;
172
+
173
+ function useWorkflowEngine({workflowResource: workflowResource, tag: tag, resourceClients: resourceClients, effectHandlers: effectHandlers, missingHandler: missingHandler}) {
174
+ const client = useClient({
175
+ apiVersion: ENGINE_API_VERSION
176
+ }), resource = useKeyed([ workflowResource.type, workflowResource.id ], () => workflowResource), telemetry = useWorkflowTelemetry();
177
+ return useMemo(() => {
178
+ const engineDataset = datasetResourceId(resource), engineClient = client.withConfig({
179
+ projectId: engineDataset.projectId,
180
+ dataset: engineDataset.dataset,
181
+ useCdn: !1,
182
+ requestTagPrefix: "sanity.workflows.studio"
183
+ });
184
+ return createEngine({
185
+ client: engineClient,
186
+ workflowResource: resource,
187
+ tag: tag,
188
+ resourceClients: resourceClients ?? studioResourceClients(client),
189
+ executionContext: {
190
+ kind: EXECUTION_KINDS.studio
191
+ },
192
+ ...effectHandlers !== void 0 ? {
193
+ effectHandlers: effectHandlers
194
+ } : {},
195
+ ...missingHandler !== void 0 ? {
196
+ missingHandler: missingHandler
197
+ } : {},
198
+ telemetry: telemetry
199
+ });
200
+ }, [ client, resource, tag, resourceClients, effectHandlers, missingHandler, telemetry ]);
149
201
  }
150
- function persistedToken(projectId) {
151
- const raw = window.localStorage.getItem(`__studio_auth_token_${projectId}`);
152
- if (raw !== null)
153
- try {
154
- const parsed = JSON.parse(raw);
155
- return typeof parsed != "object" || parsed === null ? void 0 : parsed.token;
156
- } catch {
157
- return;
158
- }
202
+
203
+ function studioResourceClients(client) {
204
+ return parsed => parsed.scheme === "dataset" && parsed.projectId !== void 0 && parsed.dataset !== void 0 ? client.withConfig({
205
+ projectId: parsed.projectId,
206
+ dataset: parsed.dataset,
207
+ useCdn: !1,
208
+ requestTagPrefix: "sanity.workflows.studio"
209
+ }) : void 0;
159
210
  }
160
- export {
161
- makeStudioObserver,
162
- useWorkflowInstance
163
- };
164
- //# sourceMappingURL=index.js.map
211
+
212
+ function useWorkflowSession({engine: engine, instanceId: instanceId, grantsFromPath: grantsFromPath, sdk: sdk}) {
213
+ const observer = useStudioObserver({
214
+ engine: engine,
215
+ sdk: sdk
216
+ });
217
+ return useWorkflowSession$1({
218
+ engine: engine,
219
+ instanceId: instanceId,
220
+ observer: observer,
221
+ host: "studio",
222
+ opts: {
223
+ grantsFromPath: grantsFromPath
224
+ }
225
+ });
226
+ }
227
+
228
+ function useWorkflowInstances({engine: engine, filter: filter, sdk: sdk}) {
229
+ const observer = useStudioObserver({
230
+ engine: engine,
231
+ sdk: sdk
232
+ });
233
+ return useWorkflowInstances$1({
234
+ engine: engine,
235
+ observer: observer,
236
+ ...filter !== void 0 ? {
237
+ filter: filter
238
+ } : {}
239
+ });
240
+ }
241
+
242
+ function useDocumentWorkflows({engine: engine, document: document, sdk: sdk}) {
243
+ const observer = useStudioObserver({
244
+ engine: engine,
245
+ sdk: sdk
246
+ });
247
+ return useDocumentWorkflows$1({
248
+ engine: engine,
249
+ observer: observer,
250
+ document: document
251
+ });
252
+ }
253
+
254
+ export { makeStudioObserver, studioResourceClients, useDocumentWorkflows, useStudioObserver, useWorkflowEngine, useWorkflowInstances, useWorkflowSession };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/workflow-studio",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "React adapter that drives the @sanity/workflow-engine reactive session from the Sanity Studio document store.",
5
5
  "keywords": [
6
6
  "sanity",
@@ -21,7 +21,8 @@
21
21
  "directory": "packages/workflow-studio"
22
22
  },
23
23
  "files": [
24
- "dist"
24
+ "dist",
25
+ "CHANGELOG.md"
25
26
  ],
26
27
  "type": "module",
27
28
  "sideEffects": false,
@@ -37,17 +38,16 @@
37
38
  "./package.json": "./package.json"
38
39
  },
39
40
  "publishConfig": {
40
- "access": "restricted"
41
+ "access": "public"
41
42
  },
42
43
  "dependencies": {
43
- "@sanity/workflow-engine": "0.13.0",
44
- "@sanity/workflow-react": "0.8.0",
45
- "@sanity/workflow-sdk": "0.5.0"
44
+ "@sanity/workflow-engine": "0.15.0",
45
+ "@sanity/workflow-react": "0.10.0",
46
+ "@sanity/workflow-sdk": "0.7.0"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@sanity/pkg-utils": "^10.5.2",
49
50
  "@sanity/sdk": "^2.12.0",
50
- "@sanity/sdk-react": "^2.12.0",
51
51
  "@testing-library/react": "^16.3.2",
52
52
  "@types/react": "^19.2.17",
53
53
  "jsdom": "^29.1.1",
@@ -58,7 +58,6 @@
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@sanity/sdk": "^2.12.0",
61
- "@sanity/sdk-react": "^2.12.0",
62
61
  "react": "^19.2.7",
63
62
  "sanity": "^5.30.0"
64
63
  },