@sanity/sdk 2.7.0 → 3.0.0-rc.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.
Files changed (99) hide show
  1. package/dist/index.d.ts +228 -239
  2. package/dist/index.js +287 -454
  3. package/dist/index.js.map +1 -1
  4. package/package.json +4 -4
  5. package/src/_exports/index.ts +16 -17
  6. package/src/agent/agentActions.test.ts +60 -16
  7. package/src/agent/agentActions.ts +29 -20
  8. package/src/auth/authMode.test.ts +0 -25
  9. package/src/auth/authMode.ts +3 -6
  10. package/src/auth/authStore.test.ts +129 -66
  11. package/src/auth/authStore.ts +9 -11
  12. package/src/auth/dashboardAuth.ts +2 -2
  13. package/src/auth/getOrganizationVerificationState.test.ts +10 -11
  14. package/src/auth/handleAuthCallback.test.ts +0 -12
  15. package/src/auth/handleAuthCallback.ts +9 -3
  16. package/src/auth/logout.test.ts +0 -6
  17. package/src/auth/refreshStampedToken.test.ts +121 -17
  18. package/src/auth/standaloneAuth.ts +9 -3
  19. package/src/auth/studioAuth.ts +35 -8
  20. package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +9 -3
  21. package/src/auth/subscribeToStateAndFetchCurrentUser.ts +1 -1
  22. package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +0 -2
  23. package/src/auth/subscribeToStorageEventsAndSetToken.ts +2 -2
  24. package/src/auth/utils.ts +33 -0
  25. package/src/client/clientStore.test.ts +14 -61
  26. package/src/client/clientStore.ts +52 -28
  27. package/src/comlink/controller/actions/destroyController.test.ts +1 -4
  28. package/src/comlink/controller/actions/getOrCreateChannel.test.ts +1 -4
  29. package/src/comlink/controller/actions/getOrCreateController.test.ts +1 -4
  30. package/src/comlink/controller/actions/releaseChannel.test.ts +1 -1
  31. package/src/comlink/controller/comlinkControllerStore.test.ts +1 -4
  32. package/src/comlink/node/actions/getOrCreateNode.test.ts +1 -4
  33. package/src/comlink/node/actions/releaseNode.test.ts +1 -4
  34. package/src/comlink/node/comlinkNodeStore.test.ts +2 -2
  35. package/src/comlink/node/getNodeState.test.ts +1 -1
  36. package/src/config/__tests__/handles.test.ts +12 -18
  37. package/src/config/handles.ts +7 -25
  38. package/src/config/sanityConfig.ts +99 -52
  39. package/src/datasets/datasets.test.ts +2 -2
  40. package/src/datasets/datasets.ts +4 -10
  41. package/src/document/actions.test.ts +33 -4
  42. package/src/document/actions.ts +3 -10
  43. package/src/document/applyDocumentActions.test.ts +17 -18
  44. package/src/document/applyDocumentActions.ts +9 -12
  45. package/src/document/documentStore.test.ts +303 -133
  46. package/src/document/documentStore.ts +70 -61
  47. package/src/document/permissions.test.ts +44 -8
  48. package/src/document/processActions.test.ts +77 -7
  49. package/src/document/reducers.test.ts +35 -3
  50. package/src/document/sharedListener.test.ts +13 -13
  51. package/src/document/sharedListener.ts +8 -3
  52. package/src/favorites/favorites.test.ts +10 -2
  53. package/src/presence/presenceStore.test.ts +34 -9
  54. package/src/presence/presenceStore.ts +29 -13
  55. package/src/preview/previewProjectionUtils.test.ts +192 -0
  56. package/src/preview/previewProjectionUtils.ts +88 -0
  57. package/src/preview/{previewStore.ts → types.ts} +6 -25
  58. package/src/project/project.test.ts +1 -1
  59. package/src/project/project.ts +14 -20
  60. package/src/projection/getProjectionState.test.ts +4 -2
  61. package/src/projection/getProjectionState.ts +2 -21
  62. package/src/projection/projectionQuery.ts +2 -3
  63. package/src/projection/projectionStore.test.ts +3 -3
  64. package/src/projection/resolveProjection.test.ts +2 -1
  65. package/src/projection/resolveProjection.ts +2 -18
  66. package/src/projection/subscribeToStateAndFetchBatches.test.ts +2 -2
  67. package/src/projection/subscribeToStateAndFetchBatches.ts +23 -36
  68. package/src/projection/types.ts +1 -9
  69. package/src/projects/projects.test.ts +1 -1
  70. package/src/query/queryStore.test.ts +86 -28
  71. package/src/query/queryStore.ts +23 -38
  72. package/src/releases/getPerspectiveState.test.ts +14 -13
  73. package/src/releases/getPerspectiveState.ts +6 -6
  74. package/src/releases/releasesStore.test.ts +21 -6
  75. package/src/releases/releasesStore.ts +18 -8
  76. package/src/store/createActionBinder.test.ts +114 -111
  77. package/src/store/createActionBinder.ts +52 -101
  78. package/src/store/createSanityInstance.test.ts +13 -83
  79. package/src/store/createSanityInstance.ts +2 -78
  80. package/src/store/createStateSourceAction.test.ts +2 -2
  81. package/src/store/createStateSourceAction.ts +5 -5
  82. package/src/store/createStoreInstance.test.ts +2 -4
  83. package/src/users/reducers.test.ts +1 -6
  84. package/src/users/reducers.ts +2 -2
  85. package/src/users/types.ts +4 -4
  86. package/src/users/usersStore.test.ts +12 -15
  87. package/src/utils/createFetcherStore.test.ts +1 -1
  88. package/src/utils/logger.test.ts +0 -12
  89. package/src/utils/logger.ts +3 -8
  90. package/src/preview/getPreviewState.test.ts +0 -120
  91. package/src/preview/getPreviewState.ts +0 -91
  92. package/src/preview/previewQuery.test.ts +0 -236
  93. package/src/preview/previewQuery.ts +0 -153
  94. package/src/preview/previewStore.test.ts +0 -36
  95. package/src/preview/resolvePreview.test.ts +0 -47
  96. package/src/preview/resolvePreview.ts +0 -20
  97. package/src/preview/subscribeToStateAndFetchBatches.test.ts +0 -221
  98. package/src/preview/subscribeToStateAndFetchBatches.ts +0 -112
  99. package/src/preview/util.ts +0 -13
package/dist/index.js CHANGED
@@ -17,15 +17,17 @@ import { isKeySegment, isKeyedObject } from "@sanity/types";
17
17
  import { createDocumentLoaderFromClient } from "@sanity/mutate/_unstable_store";
18
18
  import { SDK_CHANNEL_NAME, SDK_NODE_NAME } from "@sanity/message-protocol";
19
19
  import { fromUrl } from "@sanity/bifur-client";
20
+ import { createImageUrlBuilder } from "@sanity/image-url";
20
21
  import { DocumentId, getPublishedId as getPublishedId$2, getDraftId as getDraftId$1, getVersionId, isDraftId, isVersionId, isPublishedId } from "@sanity/id-utils";
21
- function isDatasetSource(source) {
22
- return "projectId" in source && "dataset" in source;
22
+ const DEFAULT_RESOURCE_NAME = "default";
23
+ function isDatasetResource(resource) {
24
+ return "projectId" in resource && "dataset" in resource;
23
25
  }
24
- function isMediaLibrarySource(source) {
25
- return "mediaLibraryId" in source;
26
+ function isMediaLibraryResource(resource) {
27
+ return "mediaLibraryId" in resource;
26
28
  }
27
- function isCanvasSource(source) {
28
- return "canvasId" in source;
29
+ function isCanvasResource(resource) {
30
+ return "canvasId" in resource;
29
31
  }
30
32
  const isReleasePerspective = (perspective) => typeof perspective == "object" && perspective !== null && "releaseName" in perspective;
31
33
  function getPublishedId(id) {
@@ -154,27 +156,19 @@ function createLogger(namespace, baseContext) {
154
156
  };
155
157
  }
156
158
  function createSanityInstance(config = {}) {
157
- const instanceId = crypto.randomUUID(), disposeListeners = /* @__PURE__ */ new Map(), disposed = { current: !1 }, instanceContext = {
158
- instanceId,
159
- projectId: config.projectId,
160
- dataset: config.dataset
161
- }, logger = createLogger("sdk", { instanceContext });
162
- logger.info("Sanity instance created", {
163
- hasProjectId: !!config.projectId,
164
- hasDataset: !!config.dataset,
159
+ const instanceId = crypto.randomUUID(), disposeListeners = /* @__PURE__ */ new Map(), disposed = { current: !1 }, logger = createLogger("sdk", { instanceContext: {
160
+ instanceId
161
+ } });
162
+ return logger.info("Sanity instance created", {
165
163
  hasAuth: !!config.auth,
166
164
  hasPerspective: !!config.perspective
167
165
  }), logger.debug("Instance configuration", {
168
- projectId: config.projectId,
169
- dataset: config.dataset,
170
166
  perspective: config.perspective,
171
167
  hasStudioConfig: !!config.studio,
172
168
  hasStudioTokenSource: !!config.studio?.auth?.token,
173
- legacyStudioMode: config.studioMode?.enabled,
174
169
  hasAuthProviders: !!config.auth?.providers,
175
170
  hasAuthToken: !!config.auth?.token
176
- });
177
- const instance = {
171
+ }), {
178
172
  instanceId,
179
173
  config,
180
174
  isDisposed: () => disposed.current,
@@ -193,39 +187,8 @@ function createSanityInstance(config = {}) {
193
187
  return disposeListeners.set(listenerId, cb), () => {
194
188
  disposeListeners.delete(listenerId);
195
189
  };
196
- },
197
- getParent: () => {
198
- },
199
- createChild: (next) => {
200
- logger.debug("Creating child instance", {
201
- parentInstanceId: instanceId.slice(0, 8),
202
- overridingProjectId: !!next.projectId,
203
- overridingDataset: !!next.dataset,
204
- overridingAuth: !!next.auth
205
- });
206
- const child = Object.assign(
207
- createSanityInstance({
208
- ...config,
209
- ...next,
210
- ...config.auth === next.auth ? config.auth : config.auth && next.auth && { auth: { ...config.auth, ...next.auth } }
211
- }),
212
- { getParent: () => instance }
213
- );
214
- return logger.trace("Child instance created", {
215
- internal: !0,
216
- childInstanceId: child.instanceId.slice(0, 8)
217
- }), child;
218
- },
219
- match: (targetConfig) => {
220
- if (Object.entries(pick(targetConfig, "auth", "projectId", "dataset")).every(
221
- ([key, value]) => config[key] === value
222
- ))
223
- return instance;
224
- const parent = instance.getParent();
225
- if (parent) return parent.match(targetConfig);
226
190
  }
227
191
  };
228
- return instance;
229
192
  }
230
193
  function getEnv(key) {
231
194
  if (typeof import.meta < "u" && import.meta.env)
@@ -278,36 +241,35 @@ function createActionBinder(keyFn) {
278
241
  };
279
242
  };
280
243
  }
281
- const bindActionByDataset = createActionBinder((instance, options) => {
282
- const projectId = options?.projectId ?? instance.config.projectId, dataset = options?.dataset ?? instance.config.dataset;
283
- if (!projectId || !dataset)
284
- throw new Error("This API requires a project ID and dataset configured.");
285
- return { name: `${projectId}.${dataset}`, projectId, dataset };
286
- }), createSourceKey = (instance, source) => {
287
- let name, sourceForKey;
288
- if (source) {
289
- if (sourceForKey = source, isDatasetSource(source))
290
- name = `${source.projectId}.${source.dataset}`;
291
- else if (isMediaLibrarySource(source))
292
- name = `media-library:${source.mediaLibraryId}`;
293
- else if (isCanvasSource(source))
294
- name = `canvas:${source.canvasId}`;
295
- else
296
- throw new Error(`Received invalid source: ${JSON.stringify(source)}`);
297
- return { name, source: sourceForKey };
298
- }
299
- const { projectId, dataset } = instance.config;
300
- if (!projectId || !dataset)
301
- throw new Error("This API requires a project ID and dataset configured.");
302
- return { name: `${projectId}.${dataset}`, source: { projectId, dataset } };
303
- }, bindActionBySource = createActionBinder((instance, { source }) => createSourceKey(instance, source)), bindActionBySourceAndPerspective = createActionBinder((instance, options) => {
304
- const { source, perspective } = options, utilizedPerspective = perspective ?? instance.config.perspective ?? "drafts";
244
+ const resourceKeyName = (resource) => {
245
+ if (isDatasetResource(resource)) return `${resource.projectId}.${resource.dataset}`;
246
+ if (isMediaLibraryResource(resource)) return `media-library:${resource.mediaLibraryId}`;
247
+ if (isCanvasResource(resource)) return `canvas:${resource.canvasId}`;
248
+ throw new Error(`Received invalid resource: ${JSON.stringify(resource)}`);
249
+ }, createResourceKey = (instance, resource) => {
250
+ if (resource)
251
+ return { name: resourceKeyName(resource), resource };
252
+ const defaultResource = instance.config.defaultResource;
253
+ if (!defaultResource)
254
+ throw new Error(
255
+ 'No resource provided and no default resource configured. Provide a "default" resource in your resources map, or pass an explicit resource.'
256
+ );
257
+ return { name: resourceKeyName(defaultResource), resource: defaultResource };
258
+ }, bindActionByResource = createActionBinder((instance, { resource }) => createResourceKey(instance, resource)), bindActionByResourceAndPerspective = createActionBinder((instance, options) => {
259
+ const { resource, perspective } = options, utilizedPerspective = perspective ?? instance.config.perspective ?? "drafts";
305
260
  let perspectiveKey;
306
- isReleasePerspective(utilizedPerspective) ? perspectiveKey = utilizedPerspective.releaseName : typeof utilizedPerspective == "string" ? perspectiveKey = utilizedPerspective : perspectiveKey = JSON.stringify(utilizedPerspective);
307
- const sourceKey = createSourceKey(instance, source);
261
+ if (isReleasePerspective(utilizedPerspective))
262
+ perspectiveKey = utilizedPerspective.releaseName;
263
+ else if (typeof utilizedPerspective == "string")
264
+ perspectiveKey = utilizedPerspective;
265
+ else
266
+ throw new Error(
267
+ `Stackable perspectives are not supported. Received perspective: ${JSON.stringify(utilizedPerspective)}`
268
+ );
269
+ const resourceKey = createResourceKey(instance, resource);
308
270
  return {
309
- name: `${sourceKey.name}:${perspectiveKey}`,
310
- source: sourceKey.source,
271
+ name: `${resourceKey.name}:${perspectiveKey}`,
272
+ resource: resourceKey.resource,
311
273
  perspective: utilizedPerspective
312
274
  };
313
275
  }), bindActionGlobally = createActionBinder((..._rest) => ({ name: "global" }));
@@ -363,7 +325,7 @@ function resolveAuthMode(config, locationHref) {
363
325
  return isStudioConfig(config) ? "studio" : detectDashboardContext(locationHref) ? "dashboard" : "standalone";
364
326
  }
365
327
  function isStudioConfig(config) {
366
- return !!config.studio || !!config.studioMode?.enabled;
328
+ return !!config.studio;
367
329
  }
368
330
  function detectDashboardContext(locationHref) {
369
331
  try {
@@ -540,7 +502,7 @@ const refreshStampedToken = ({ state }) => {
540
502
  }
541
503
  });
542
504
  }, subscribeToStateAndFetchCurrentUser = ({ state, instance }, fetchOptions) => {
543
- const { clientFactory, apiHost } = state.get().options, useProjectHostname = fetchOptions?.useProjectHostname ?? isStudioConfig(instance.config), projectId = instance.config.projectId;
505
+ const { clientFactory, apiHost } = state.get().options, useProjectHostname = fetchOptions?.useProjectHostname ?? isStudioConfig(instance.config), projectId = instance.config.studio?.projectId;
544
506
  return state.observable.pipe(
545
507
  map(({ authState, options: storeOptions }) => ({
546
508
  authState,
@@ -581,6 +543,15 @@ const refreshStampedToken = ({ state }) => {
581
543
  }
582
544
  });
583
545
  };
546
+ function createLoggedInAuthState(token, currentUser, existingLastTokenRefresh) {
547
+ const isStampedToken = token.includes("-st"), lastTokenRefresh = existingLastTokenRefresh ?? (isStampedToken ? Date.now() : void 0);
548
+ return {
549
+ type: AuthStateType.LOGGED_IN,
550
+ token,
551
+ currentUser,
552
+ ...lastTokenRefresh !== void 0 && { lastTokenRefresh }
553
+ };
554
+ }
584
555
  function getAuthCode(callbackUrl, locationHref) {
585
556
  const loc = new URL(locationHref, DEFAULT_BASE), callbackLocation = callbackUrl ? new URL(callbackUrl, DEFAULT_BASE) : void 0, callbackLocationMatches = callbackLocation ? loc.pathname.toLowerCase().startsWith(callbackLocation.pathname.toLowerCase()) : !0;
586
557
  let authCode = new URLSearchParams(loc.hash.slice(1)).get(AUTH_CODE_PARAM) || new URLSearchParams(loc.search).get(AUTH_CODE_PARAM);
@@ -670,7 +641,7 @@ function parseDashboardContext(locationHref) {
670
641
  function getDashboardInitialState(options) {
671
642
  const { authConfig, initialLocationHref } = options, providedToken = authConfig.token, callbackUrl = authConfig.callbackUrl, storageKey = "__sanity_auth_token", dashboardContext = parseDashboardContext(initialLocationHref), storageArea = void 0;
672
643
  return providedToken ? {
673
- authState: { type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null },
644
+ authState: createLoggedInAuthState(providedToken, null),
674
645
  storageKey,
675
646
  storageArea,
676
647
  authMethod: void 0,
@@ -712,7 +683,7 @@ const subscribeToStorageEventsAndSetToken = ({
712
683
  distinctUntilChanged()
713
684
  ).subscribe((token) => {
714
685
  state.set("updateTokenFromStorageEvent", {
715
- authState: token ? { type: AuthStateType.LOGGED_IN, token, currentUser: null } : { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
686
+ authState: token ? createLoggedInAuthState(token, null) : { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
716
687
  });
717
688
  });
718
689
  };
@@ -720,7 +691,7 @@ function getStandaloneInitialState(options) {
720
691
  const { authConfig, initialLocationHref } = options, providedToken = authConfig.token, callbackUrl = authConfig.callbackUrl, storageKey = "__sanity_auth_token", storageArea = authConfig.storageArea ?? getDefaultStorage();
721
692
  if (providedToken)
722
693
  return {
723
- authState: { type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null },
694
+ authState: createLoggedInAuthState(providedToken, null),
724
695
  storageKey,
725
696
  storageArea,
726
697
  authMethod: void 0,
@@ -736,7 +707,7 @@ function getStandaloneInitialState(options) {
736
707
  };
737
708
  const token = getTokenFromStorage(storageArea, storageKey);
738
709
  return token ? {
739
- authState: { type: AuthStateType.LOGGED_IN, token, currentUser: null },
710
+ authState: createLoggedInAuthState(token, null),
740
711
  storageKey,
741
712
  storageArea,
742
713
  authMethod: "localstorage",
@@ -796,13 +767,13 @@ function getStudioInitialState(options) {
796
767
  let authMethod;
797
768
  const token = getStudioTokenFromLocalStorage(storageArea, studioStorageKey);
798
769
  return token && (authMethod = "localstorage"), providedToken ? {
799
- authState: { type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null },
770
+ authState: createLoggedInAuthState(providedToken, null),
800
771
  storageKey: studioStorageKey,
801
772
  storageArea,
802
773
  authMethod,
803
774
  dashboardContext: {}
804
775
  } : token ? {
805
- authState: { type: AuthStateType.LOGGED_IN, token, currentUser: null },
776
+ authState: createLoggedInAuthState(token, null),
806
777
  storageKey: studioStorageKey,
807
778
  storageArea,
808
779
  authMethod: "localstorage",
@@ -820,14 +791,17 @@ function initializeStudioAuth(context, tokenRefresherRunning2) {
820
791
  return tokenSource ? initializeWithTokenSource(context, tokenSource) : initializeWithFallback(context, tokenRefresherRunning2);
821
792
  }
822
793
  function initializeWithTokenSource(context, tokenSource) {
823
- const subscriptions = [];
794
+ const subscriptions = [], studioAuthenticated = context.instance.config.studio?.authenticated === !0;
824
795
  subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !0 }));
825
796
  const tokenSub = tokenSource.subscribe({
826
797
  next: (token) => {
827
798
  const { state } = context;
828
799
  token ? state.set("studioTokenSource", (prev) => ({
829
800
  options: { ...prev.options, authMethod: void 0 },
830
- authState: { type: AuthStateType.LOGGED_IN, token, currentUser: null }
801
+ authState: createLoggedInAuthState(token, null)
802
+ })) : studioAuthenticated ? state.set("studioTokenSourceCookieAuth", (prev) => ({
803
+ options: { ...prev.options, authMethod: "cookie" },
804
+ authState: prev.authState.type === AuthStateType.LOGGED_IN ? prev.authState : createLoggedInAuthState("", null)
831
805
  })) : state.set("studioTokenSourceLoggedOut", (prev) => ({
832
806
  options: { ...prev.options, authMethod: void 0 },
833
807
  authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
@@ -851,11 +825,11 @@ function initializeWithFallback(context, tokenRefresherRunning2) {
851
825
  try {
852
826
  const { instance, state } = context;
853
827
  if (!(state.get().authState?.type === AuthStateType.LOGGED_IN && state.get().authState.token)) {
854
- const projectIdValue = instance.config.projectId, clientFactory = state.get().options.clientFactory;
828
+ const projectIdValue = instance.config.studio?.projectId, clientFactory = state.get().options.clientFactory;
855
829
  checkForCookieAuth(projectIdValue, clientFactory).then((isCookieAuthEnabled) => {
856
830
  isCookieAuthEnabled && state.set("enableCookieAuth", (prev) => ({
857
831
  options: { ...prev.options, authMethod: "cookie" },
858
- authState: prev.authState.type === AuthStateType.LOGGED_IN ? prev.authState : { type: AuthStateType.LOGGED_IN, token: "", currentUser: null }
832
+ authState: prev.authState.type === AuthStateType.LOGGED_IN ? prev.authState : createLoggedInAuthState("", null)
859
833
  }));
860
834
  });
861
835
  }
@@ -890,7 +864,7 @@ const authStore = {
890
864
  loginUrl.searchParams.set("origin", getCleanedUrl(initialLocationHref)), loginUrl.searchParams.set("type", "stampedToken"), loginUrl.searchParams.set("withSid", "true");
891
865
  const mode = resolveAuthMode(instance.config, initialLocationHref), strategyOptions = {
892
866
  authConfig,
893
- projectId: instance.config.projectId,
867
+ projectId: instance.config.studio?.projectId,
894
868
  initialLocationHref,
895
869
  tokenSource: instance.config.studio?.auth?.token
896
870
  };
@@ -971,17 +945,17 @@ const authStore = {
971
945
  )
972
946
  ), setAuthToken = bindActionGlobally(authStore, ({ state }, token) => {
973
947
  const currentAuthState = state.get().authState;
974
- token ? (currentAuthState.type !== AuthStateType.LOGGED_IN || currentAuthState.token !== token) && state.set("setToken", {
975
- authState: {
976
- type: AuthStateType.LOGGED_IN,
977
- token,
978
- // Keep existing user or set to null? Setting to null forces refetch.
979
- // Keep existing user to avoid unnecessary refetches if user data is still valid.
980
- currentUser: currentAuthState.type === AuthStateType.LOGGED_IN ? currentAuthState.currentUser : null
948
+ if (token) {
949
+ if (currentAuthState.type !== AuthStateType.LOGGED_IN || currentAuthState.token !== token) {
950
+ const currentUser = currentAuthState.type === AuthStateType.LOGGED_IN ? currentAuthState.currentUser : null, preservedLastTokenRefresh = currentAuthState.type === AuthStateType.LOGGED_IN ? currentAuthState.lastTokenRefresh : void 0;
951
+ state.set("setToken", {
952
+ authState: createLoggedInAuthState(token, currentUser, preservedLastTokenRefresh)
953
+ });
981
954
  }
982
- }) : currentAuthState.type !== AuthStateType.LOGGED_OUT && state.set("setToken", {
983
- authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
984
- });
955
+ } else
956
+ currentAuthState.type !== AuthStateType.LOGGED_OUT && state.set("setToken", {
957
+ authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
958
+ });
985
959
  }), DEFAULT_API_VERSION = "2024-11-12", DEFAULT_REQUEST_TAG_PREFIX = "sanity.sdk", allowedKeys = Object.keys({
986
960
  apiHost: null,
987
961
  useCdn: null,
@@ -998,7 +972,7 @@ const authStore = {
998
972
  requestTagPrefix: null,
999
973
  useProjectHostname: null,
1000
974
  "~experimental_resource": null,
1001
- source: null
975
+ resource: null
1002
976
  }), DEFAULT_CLIENT_CONFIG = {
1003
977
  apiVersion: DEFAULT_API_VERSION,
1004
978
  useCdn: !1,
@@ -1036,9 +1010,9 @@ const authStore = {
1036
1010
  );
1037
1011
  }
1038
1012
  const tokenFromState = state.get().token, { clients, authMethod } = state.get();
1039
- let resource;
1040
- options.source && (isDatasetSource(options.source) ? resource = { type: "dataset", id: `${options.source.projectId}.${options.source.dataset}` } : isMediaLibrarySource(options.source) ? resource = { type: "media-library", id: options.source.mediaLibraryId } : isCanvasSource(options.source) && (resource = { type: "canvas", id: options.source.canvasId }));
1041
- const projectId = options.projectId ?? instance.config.projectId, dataset = options.dataset ?? instance.config.dataset, apiHost = options.apiHost ?? instance.config.auth?.apiHost, effectiveOptions = {
1013
+ let resource, projectId = options.projectId, dataset = options.dataset;
1014
+ options.resource && (isMediaLibraryResource(options.resource) ? resource = { type: "media-library", id: options.resource.mediaLibraryId } : isCanvasResource(options.resource) ? resource = { type: "canvas", id: options.resource.canvasId } : isDatasetResource(options.resource) && (projectId = options.resource.projectId, dataset = options.resource.dataset));
1015
+ const apiHost = options.apiHost ?? instance.config.auth?.apiHost, effectiveOptions = {
1042
1016
  ...DEFAULT_CLIENT_CONFIG,
1043
1017
  ...(options.scope === "global" || !projectId || resource) && { useProjectHostname: !1 },
1044
1018
  token: authMethod === "cookie" ? void 0 : tokenFromState ?? void 0,
@@ -1048,52 +1022,52 @@ const authStore = {
1048
1022
  ...apiHost && { apiHost },
1049
1023
  ...resource && { "~experimental_resource": resource }
1050
1024
  };
1051
- resource && ((options.projectId || options.dataset) && console.warn(
1052
- "Both source and explicit projectId/dataset are provided. The source will be used and projectId/dataset will be ignored."
1053
- ), delete effectiveOptions.projectId, delete effectiveOptions.dataset), effectiveOptions.token === null || typeof effectiveOptions.token > "u" ? (delete effectiveOptions.token, authMethod === "cookie" && (effectiveOptions.withCredentials = !0)) : delete effectiveOptions.withCredentials;
1054
- const key = getClientConfigKey(effectiveOptions);
1025
+ options.resource && ((options.projectId || options.dataset) && console.warn(
1026
+ "Both resource and explicit projectId/dataset are provided. The resource will be used and projectId/dataset will be ignored."
1027
+ ), resource && (delete effectiveOptions.projectId, delete effectiveOptions.dataset)), effectiveOptions.token === null || typeof effectiveOptions.token > "u" ? (delete effectiveOptions.token, authMethod === "cookie" && (effectiveOptions.withCredentials = !0)) : delete effectiveOptions.withCredentials;
1028
+ const { resource: _omitResource, ...clientConfig } = effectiveOptions, key = getClientConfigKey(effectiveOptions);
1055
1029
  if (clients[key]) return clients[key];
1056
- const client = createClient(effectiveOptions);
1030
+ const client = createClient(clientConfig);
1057
1031
  return state.set("addClient", (prev) => ({ clients: { ...prev.clients, [key]: client } })), client;
1058
1032
  }
1059
1033
  ), getClientState = bindActionGlobally(
1060
1034
  clientStore,
1061
1035
  createStateSourceAction(({ instance }, options) => getClient(instance, options))
1062
- ), API_VERSION$6 = "vX";
1036
+ ), API_VERSION$7 = "vX";
1063
1037
  function agentGenerate(instance, options) {
1038
+ const { resource, ...agentOptions } = options;
1064
1039
  return getClientState(instance, {
1065
- apiVersion: API_VERSION$6,
1066
- projectId: instance.config.projectId,
1067
- dataset: instance.config.dataset
1068
- }).observable.pipe(switchMap((client) => client.observable.agent.action.generate(options)));
1040
+ apiVersion: API_VERSION$7,
1041
+ resource
1042
+ }).observable.pipe(switchMap((client) => client.observable.agent.action.generate(agentOptions)));
1069
1043
  }
1070
1044
  function agentTransform(instance, options) {
1045
+ const { resource, ...agentOptions } = options;
1071
1046
  return getClientState(instance, {
1072
- apiVersion: API_VERSION$6,
1073
- projectId: instance.config.projectId,
1074
- dataset: instance.config.dataset
1075
- }).observable.pipe(switchMap((client) => client.observable.agent.action.transform(options)));
1047
+ apiVersion: API_VERSION$7,
1048
+ resource
1049
+ }).observable.pipe(switchMap((client) => client.observable.agent.action.transform(agentOptions)));
1076
1050
  }
1077
1051
  function agentTranslate(instance, options) {
1052
+ const { resource, ...agentOptions } = options;
1078
1053
  return getClientState(instance, {
1079
- apiVersion: API_VERSION$6,
1080
- projectId: instance.config.projectId,
1081
- dataset: instance.config.dataset
1082
- }).observable.pipe(switchMap((client) => client.observable.agent.action.translate(options)));
1054
+ apiVersion: API_VERSION$7,
1055
+ resource
1056
+ }).observable.pipe(switchMap((client) => client.observable.agent.action.translate(agentOptions)));
1083
1057
  }
1084
1058
  function agentPrompt(instance, options) {
1059
+ const { resource, ...agentOptions } = options;
1085
1060
  return getClientState(instance, {
1086
- apiVersion: API_VERSION$6,
1087
- projectId: instance.config.projectId,
1088
- dataset: instance.config.dataset
1089
- }).observable.pipe(switchMap((client) => from(client.agent.action.prompt(options))));
1061
+ apiVersion: API_VERSION$7,
1062
+ resource
1063
+ }).observable.pipe(switchMap((client) => from(client.agent.action.prompt(agentOptions))));
1090
1064
  }
1091
1065
  function agentPatch(instance, options) {
1066
+ const { resource, ...agentOptions } = options;
1092
1067
  return getClientState(instance, {
1093
- apiVersion: API_VERSION$6,
1094
- projectId: instance.config.projectId,
1095
- dataset: instance.config.dataset
1096
- }).observable.pipe(switchMap((client) => from(client.agent.action.patch(options))));
1068
+ apiVersion: API_VERSION$7,
1069
+ resource
1070
+ }).observable.pipe(switchMap((client) => from(client.agent.action.patch(agentOptions))));
1097
1071
  }
1098
1072
  function compareProjectOrganization(projectId, projectOrganizationId, currentDashboardOrgId) {
1099
1073
  return projectOrganizationId !== currentDashboardOrgId ? {
@@ -1233,28 +1207,21 @@ function createFetcherStore({
1233
1207
  );
1234
1208
  return { getState, resolveState };
1235
1209
  }
1236
- const API_VERSION$5 = "v2025-02-19", project = createFetcherStore({
1210
+ const API_VERSION$6 = "v2025-02-19", project = createFetcherStore({
1237
1211
  name: "Project",
1238
- getKey: (instance, options) => {
1239
- const projectId = options?.projectId ?? instance.config.projectId;
1212
+ getKey: (_instance, options) => {
1213
+ const projectId = options?.projectId;
1240
1214
  if (!projectId)
1241
1215
  throw new Error("A projectId is required to use the project API.");
1242
1216
  return projectId;
1243
1217
  },
1244
- fetcher: (instance) => (options = {}) => {
1245
- const projectId = options.projectId ?? instance.config.projectId;
1218
+ fetcher: (instance) => (options) => {
1219
+ const projectId = options.projectId;
1246
1220
  return getClientState(instance, {
1247
- apiVersion: API_VERSION$5,
1221
+ apiVersion: API_VERSION$6,
1248
1222
  scope: "global",
1249
1223
  projectId
1250
- }).observable.pipe(
1251
- switchMap(
1252
- (client) => client.observable.projects.getById(
1253
- // non-null assertion is fine with the above throwing
1254
- projectId ?? instance.config.projectId
1255
- )
1256
- )
1257
- );
1224
+ }).observable.pipe(switchMap((client) => client.observable.projects.getById(projectId)));
1258
1225
  }
1259
1226
  }), getProjectState = project.getState, resolveProject = project.resolveState, getDashboardOrganizationId = bindActionGlobally(
1260
1227
  authStore,
@@ -1299,7 +1266,7 @@ const handleAuthCallback = bindActionGlobally(
1299
1266
  const cleanedUrl = getCleanedUrl(locationHref), tokenFromUrl = getTokenFromLocation(locationHref);
1300
1267
  if (tokenFromUrl)
1301
1268
  return state.set("setTokenFromUrl", {
1302
- authState: { type: AuthStateType.LOGGED_IN, token: tokenFromUrl, currentUser: null }
1269
+ authState: createLoggedInAuthState(tokenFromUrl, null)
1303
1270
  }), cleanedUrl;
1304
1271
  const authCode = getAuthCode(callbackUrl, locationHref);
1305
1272
  if (!authCode) return !1;
@@ -1331,7 +1298,7 @@ const handleAuthCallback = bindActionGlobally(
1331
1298
  query: { sid: authCode },
1332
1299
  tag: "fetch-token"
1333
1300
  });
1334
- return storageArea?.setItem(storageKey, JSON.stringify({ token })), state.set("setToken", { authState: { type: AuthStateType.LOGGED_IN, token, currentUser: null } }), cleanedUrl;
1301
+ return storageArea?.setItem(storageKey, JSON.stringify({ token })), state.set("setToken", { authState: createLoggedInAuthState(token, null) }), cleanedUrl;
1335
1302
  } catch (error) {
1336
1303
  return state.set("exchangeSessionForTokenError", { authState: { type: AuthStateType.ERROR, error } }), cleanedUrl;
1337
1304
  }
@@ -1500,10 +1467,7 @@ function createDocumentHandle(handle) {
1500
1467
  function createDocumentTypeHandle(handle) {
1501
1468
  return handle;
1502
1469
  }
1503
- function createProjectHandle(handle) {
1504
- return handle;
1505
- }
1506
- function createDatasetHandle(handle) {
1470
+ function createResourceHandle(handle) {
1507
1471
  return handle;
1508
1472
  }
1509
1473
  function configureLogging(config) {
@@ -1521,18 +1485,12 @@ function configureLogging(config) {
1521
1485
  source: "programmatic"
1522
1486
  });
1523
1487
  }
1524
- const API_VERSION$4 = "v2025-02-19", datasets = createFetcherStore({
1488
+ const API_VERSION$5 = "v2025-02-19", datasets = createFetcherStore({
1525
1489
  name: "Datasets",
1526
- getKey: (instance, options) => {
1527
- const projectId = options?.projectId ?? instance.config.projectId;
1528
- if (!projectId)
1529
- throw new Error("A projectId is required to use the project API.");
1530
- return projectId;
1531
- },
1490
+ getKey: (_instance, options) => options.projectId,
1532
1491
  fetcher: (instance) => (options) => getClientState(instance, {
1533
- apiVersion: API_VERSION$4,
1534
- // non-null assertion is fine because we check above
1535
- projectId: options?.projectId ?? instance.config.projectId,
1492
+ apiVersion: API_VERSION$5,
1493
+ projectId: options.projectId,
1536
1494
  useProjectHostname: !0
1537
1495
  }).observable.pipe(switchMap((client) => client.observable.datasets.list()))
1538
1496
  }), getDatasetsState = datasets.getState, resolveDatasets = datasets.resolveState, isSanityMutatePatch = (value) => !(typeof value != "object" || !value || !("type" in value) || typeof value.type != "string" || value.type !== "patch" || !("id" in value) || typeof value.id != "string" || !("patches" in value) || !Array.isArray(value.patches));
@@ -1598,7 +1556,7 @@ function discardDocument(doc) {
1598
1556
  documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId)
1599
1557
  };
1600
1558
  }
1601
- const DOCUMENT_STATE_CLEAR_DELAY = 1e3, INITIAL_OUTGOING_THROTTLE_TIME = 1e3, API_VERSION$3 = "v2025-05-06";
1559
+ const DOCUMENT_STATE_CLEAR_DELAY = 1e3, INITIAL_OUTGOING_THROTTLE_TIME = 1e3, API_VERSION$4 = "v2025-05-06";
1602
1560
  function generateArrayKey(length = 12) {
1603
1561
  const numBytes = Math.ceil(length / 2), bytes = crypto.getRandomValues(new Uint8Array(numBytes));
1604
1562
  return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, length);
@@ -2923,10 +2881,11 @@ function getDocumentEvents(outgoing) {
2923
2881
  )
2924
2882
  );
2925
2883
  }
2926
- const API_VERSION$2 = "v2025-05-06";
2927
- function createSharedListener(instance) {
2884
+ const API_VERSION$3 = "v2025-05-06";
2885
+ function createSharedListener(instance, resource) {
2928
2886
  const dispose$ = new Subject(), events$ = getClientState(instance, {
2929
- apiVersion: API_VERSION$2
2887
+ apiVersion: API_VERSION$3,
2888
+ ...resource ? { resource } : {}
2930
2889
  }).observable.pipe(
2931
2890
  switchMap(
2932
2891
  (client) => (
@@ -2960,9 +2919,9 @@ function createSharedListener(instance) {
2960
2919
  dispose: () => dispose$.next()
2961
2920
  };
2962
2921
  }
2963
- function createFetchDocument(instance) {
2922
+ function createFetchDocument(instance, resource) {
2964
2923
  return function(documentId) {
2965
- return getClientState(instance, { apiVersion: API_VERSION$2 }).observable.pipe(
2924
+ return getClientState(instance, { apiVersion: API_VERSION$3, resource }).observable.pipe(
2966
2925
  switchMap((client) => createDocumentLoaderFromClient(client)(documentId)),
2967
2926
  map((result) => {
2968
2927
  if (!result.accessible) {
@@ -2977,13 +2936,13 @@ function createFetchDocument(instance) {
2977
2936
  }
2978
2937
  const documentStore = {
2979
2938
  name: "Document",
2980
- getInitialState: (instance) => ({
2939
+ getInitialState: (instance, { resource }) => ({
2981
2940
  documentStates: {},
2982
2941
  // these can be emptied on refetch
2983
2942
  queued: [],
2984
2943
  applied: [],
2985
- sharedListener: createSharedListener(instance),
2986
- fetchDocument: createFetchDocument(instance),
2944
+ sharedListener: createSharedListener(instance, resource),
2945
+ fetchDocument: createFetchDocument(instance, resource),
2987
2946
  events: new Subject()
2988
2947
  }),
2989
2948
  initialize(context) {
@@ -3001,7 +2960,7 @@ const documentStore = {
3001
2960
  function getDocumentState(...args) {
3002
2961
  return _getDocumentState(...args);
3003
2962
  }
3004
- const _getDocumentState = bindActionByDataset(
2963
+ const _getDocumentState = bindActionByResource(
3005
2964
  documentStore,
3006
2965
  createStateSourceAction({
3007
2966
  selector: ({ state: { error, documentStates } }, options) => {
@@ -3031,7 +2990,7 @@ const _getDocumentState = bindActionByDataset(
3031
2990
  function resolveDocument(...args) {
3032
2991
  return _resolveDocument(...args);
3033
2992
  }
3034
- const _resolveDocument = bindActionByDataset(
2993
+ const _resolveDocument = bindActionByResource(
3035
2994
  documentStore,
3036
2995
  ({ instance }, docHandle) => firstValueFrom(
3037
2996
  getDocumentState(instance, {
@@ -3039,7 +2998,7 @@ const _resolveDocument = bindActionByDataset(
3039
2998
  path: void 0
3040
2999
  }).observable.pipe(filter((i) => i !== void 0))
3041
3000
  )
3042
- ), getDocumentSyncStatus = bindActionByDataset(
3001
+ ), getDocumentSyncStatus = bindActionByResource(
3043
3002
  documentStore,
3044
3003
  createStateSourceAction({
3045
3004
  selector: ({ state: { error, documentStates: documents, outgoing, applied, queued } }, doc) => {
@@ -3053,24 +3012,26 @@ const _resolveDocument = bindActionByDataset(
3053
3012
  },
3054
3013
  onSubscribe: (context, doc) => manageSubscriberIds(context, doc.documentId)
3055
3014
  })
3056
- ), getPermissionsState = bindActionByDataset(
3015
+ ), getPermissionsState = bindActionByResource(
3057
3016
  documentStore,
3058
3017
  createStateSourceAction({
3059
3018
  selector: calculatePermissions,
3060
3019
  onSubscribe: (context, { actions }) => manageSubscriberIds(context, getDocumentIdsFromActions(actions))
3061
3020
  })
3062
- ), resolvePermissions = bindActionByDataset(
3021
+ ), resolvePermissions = bindActionByResource(
3063
3022
  documentStore,
3064
3023
  ({ instance }, options) => firstValueFrom(
3065
3024
  getPermissionsState(instance, options).observable.pipe(filter((i) => i !== void 0))
3066
3025
  )
3067
- ), subscribeDocumentEvents = bindActionByDataset(
3026
+ ), subscribeDocumentEvents = bindActionByResource(
3068
3027
  documentStore,
3069
- ({ state }, eventHandler) => {
3070
- const { events } = state.get(), subscription = events.subscribe(eventHandler);
3028
+ ({ state }, options) => {
3029
+ const { events } = state.get(), subscription = events.subscribe(options.eventHandler);
3071
3030
  return () => subscription.unsubscribe();
3072
3031
  }
3073
- ), subscribeToQueuedAndApplyNextTransaction = ({ state }) => {
3032
+ ), subscribeToQueuedAndApplyNextTransaction = ({
3033
+ state
3034
+ }) => {
3074
3035
  const { events } = state.get();
3075
3036
  return state.observable.pipe(
3076
3037
  map(applyFirstQueuedTransaction),
@@ -3093,7 +3054,8 @@ const _resolveDocument = bindActionByDataset(
3093
3054
  ).subscribe({ error: (error) => state.set("setError", { error }) });
3094
3055
  }, subscribeToAppliedAndSubmitNextTransaction = ({
3095
3056
  state,
3096
- instance
3057
+ instance,
3058
+ key: { resource }
3097
3059
  }) => {
3098
3060
  const { events } = state.get();
3099
3061
  return state.observable.pipe(
@@ -3113,7 +3075,12 @@ const _resolveDocument = bindActionByDataset(
3113
3075
  tap$1((next) => state.set("transitionAppliedTransactionsToOutgoing", next)),
3114
3076
  map((s) => s.outgoing),
3115
3077
  distinctUntilChanged(),
3116
- withLatestFrom(getClientState(instance, { apiVersion: API_VERSION$3 }).observable),
3078
+ withLatestFrom(
3079
+ getClientState(instance, {
3080
+ apiVersion: API_VERSION$4,
3081
+ ...resource ? { resource } : {}
3082
+ }).observable
3083
+ ),
3117
3084
  concatMap(([outgoing, client]) => outgoing ? client.observable.action(outgoing.outgoingActions, {
3118
3085
  transactionId: outgoing.transactionId,
3119
3086
  skipCrossDatasetReferenceValidation: !0
@@ -3169,23 +3136,36 @@ const _resolveDocument = bindActionByDataset(
3169
3136
  }, subscribeToClientAndFetchDatasetAcl = ({
3170
3137
  instance,
3171
3138
  state,
3172
- key: { projectId, dataset }
3173
- }) => getClientState(instance, { apiVersion: API_VERSION$3 }).observable.pipe(
3174
- switchMap(
3175
- (client) => client.observable.request({
3176
- uri: `/projects/${projectId}/datasets/${dataset}/acl`,
3177
- tag: "acl.get",
3178
- withCredentials: !0
3179
- })
3180
- ),
3181
- tap$1((datasetAcl) => state.set("setGrants", { grants: createGrantsLookup(datasetAcl) }))
3182
- ).subscribe({
3183
- error: (error) => state.set("setError", { error })
3184
- });
3139
+ key: { resource }
3140
+ }) => {
3141
+ const clientOptions = { apiVersion: API_VERSION$4 };
3142
+ resource && (clientOptions.resource = resource);
3143
+ let uri;
3144
+ if (resource && isDatasetResource(resource))
3145
+ uri = `/projects/${resource.projectId}/datasets/${resource.dataset}/acl`;
3146
+ else if (resource && isMediaLibraryResource(resource))
3147
+ uri = `/media-libraries/${resource.mediaLibraryId}/acl`;
3148
+ else if (resource && isCanvasResource(resource))
3149
+ uri = `/canvases/${resource.canvasId}/acl`;
3150
+ else
3151
+ throw new Error(`Received invalid resource: ${JSON.stringify(resource)}`);
3152
+ return getClientState(instance, clientOptions).observable.pipe(
3153
+ switchMap(
3154
+ (client) => client.observable.request({
3155
+ uri,
3156
+ tag: "acl.get",
3157
+ withCredentials: !0
3158
+ })
3159
+ ),
3160
+ tap$1((datasetAcl) => state.set("setGrants", { grants: createGrantsLookup(datasetAcl) }))
3161
+ ).subscribe({
3162
+ error: (error) => state.set("setError", { error })
3163
+ });
3164
+ };
3185
3165
  function applyDocumentActions(...args) {
3186
3166
  return boundApplyDocumentActions(...args);
3187
3167
  }
3188
- const boundApplyDocumentActions = bindActionByDataset(documentStore, _applyDocumentActions);
3168
+ const boundApplyDocumentActions = bindActionByResource(documentStore, _applyDocumentActions);
3189
3169
  async function _applyDocumentActions({ state }, { actions, transactionId = crypto.randomUUID(), disableBatching }) {
3190
3170
  const { events } = state.get(), transaction = {
3191
3171
  transactionId,
@@ -3280,11 +3260,11 @@ const favorites = createFetcherStore({
3280
3260
  })
3281
3261
  );
3282
3262
  }
3283
- }), getFavoritesState = favorites.getState, resolveFavoritesState = favorites.resolveState, API_VERSION$1 = "vX", PROJECT_API_VERSION = "2025-07-18", USERS_STATE_CLEAR_DELAY = 5e3, DEFAULT_USERS_BATCH_SIZE = 100, getUsersKey = (instance, {
3263
+ }), getFavoritesState = favorites.getState, resolveFavoritesState = favorites.resolveState, API_VERSION$2 = "vX", PROJECT_API_VERSION = "2025-07-18", USERS_STATE_CLEAR_DELAY = 5e3, DEFAULT_USERS_BATCH_SIZE = 100, getUsersKey = (_instance, {
3284
3264
  resourceType,
3285
3265
  organizationId,
3286
3266
  batchSize = DEFAULT_USERS_BATCH_SIZE,
3287
- projectId = instance.config.projectId,
3267
+ projectId,
3288
3268
  userId
3289
3269
  } = {}) => JSON.stringify({
3290
3270
  resourceType,
@@ -3379,7 +3359,7 @@ const favorites = createFetcherStore({
3379
3359
  );
3380
3360
  const scope = userId.startsWith("g") ? "global" : void 0, client = getClient(instance, {
3381
3361
  scope,
3382
- apiVersion: API_VERSION$1
3362
+ apiVersion: API_VERSION$2
3383
3363
  }), resourceType2 = options.resourceType || "project", resourceId = resourceType2 === "organization" ? options.organizationId : options.projectId;
3384
3364
  return resourceId ? client.observable.request({
3385
3365
  method: "GET",
@@ -3398,7 +3378,7 @@ const favorites = createFetcherStore({
3398
3378
  filter((i) => typeof i == "string")
3399
3379
  ), resource$ = resourceType === "project" ? projectId ? of({ type: "project", id: projectId }) : throwError(() => new Error("Project ID required for this API.")) : organizationId$.pipe(map((id) => ({ type: "organization", id }))), client$ = getClientState(instance, {
3400
3380
  scope: "global",
3401
- apiVersion: API_VERSION$1
3381
+ apiVersion: API_VERSION$2
3402
3382
  }).observable, loadMore$ = state.observable.pipe(
3403
3383
  map((s) => s.users[group$.key]?.lastLoadMoreRequest),
3404
3384
  distinctUntilChanged()
@@ -3557,11 +3537,19 @@ const handleIncomingMessage = (event) => {
3557
3537
  const {
3558
3538
  instance,
3559
3539
  state,
3560
- key: { projectId, dataset }
3561
- } = context, sessionId = crypto.randomUUID(), client = getClient(instance, {
3540
+ key: { resource }
3541
+ } = context;
3542
+ if (isMediaLibraryResource(resource))
3543
+ throw new Error(
3544
+ "Presence is not supported for media library resources. Presence tracking requires a dataset resource with a projectId."
3545
+ );
3546
+ if (isCanvasResource(resource))
3547
+ throw new Error(
3548
+ "Presence is not supported for canvas resources. Presence tracking requires a dataset resource with a projectId."
3549
+ );
3550
+ const sessionId = crypto.randomUUID(), client = getClient(instance, {
3562
3551
  apiVersion: "2022-06-30",
3563
- projectId,
3564
- dataset
3552
+ resource
3565
3553
  }), token$ = getTokenState(instance).observable.pipe(distinctUntilChanged()), [incomingEvents$, dispatch] = createBifurTransport({
3566
3554
  client,
3567
3555
  token$,
@@ -3600,11 +3588,11 @@ const handleIncomingMessage = (event) => {
3600
3588
  sessionId,
3601
3589
  locations: locs
3602
3590
  }))
3603
- ), getPresence = bindActionByDataset(
3591
+ ), getPresence = bindActionByResource(
3604
3592
  presenceStore,
3605
3593
  createStateSourceAction({
3606
- selector: (context, _) => selectPresence(context.state),
3607
- onSubscribe: (context, _) => {
3594
+ selector: (context) => selectPresence(context.state),
3595
+ onSubscribe: (context) => {
3608
3596
  const subscription = context.state.observable.pipe(
3609
3597
  map(
3610
3598
  (state) => Array.from(state.locations.values()).map((l) => l.userId).filter((id) => !!id)
@@ -3618,7 +3606,7 @@ const handleIncomingMessage = (event) => {
3618
3606
  (userId) => getUserState(context.instance, {
3619
3607
  userId,
3620
3608
  resourceType: "project",
3621
- projectId: context.key.projectId
3609
+ projectId: context.key.resource && isDatasetResource(context.key.resource) ? context.key.resource.projectId : void 0
3622
3610
  }).pipe(filter((v) => !!v))
3623
3611
  );
3624
3612
  return combineLatest(userObservables);
@@ -3635,7 +3623,64 @@ const handleIncomingMessage = (event) => {
3635
3623
  return () => subscription.unsubscribe();
3636
3624
  }
3637
3625
  })
3638
- );
3626
+ ), TITLE_CANDIDATES = ["title", "name", "label", "heading", "header", "caption"], SUBTITLE_CANDIDATES = ["description", "subtitle", ...TITLE_CANDIDATES], PREVIEW_PROJECTION = `{
3627
+ // Get all potential title fields
3628
+ "titleCandidates": {
3629
+ ${TITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
3630
+ `)}
3631
+ },
3632
+ // Get all potential subtitle fields
3633
+ "subtitleCandidates": {
3634
+ ${SUBTITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
3635
+ `)}
3636
+ },
3637
+ "media": coalesce(
3638
+ select(
3639
+ defined(asset) => {"type": "image-asset", "_ref": asset._ref},
3640
+ defined(image.asset) => {"type": "image-asset", "_ref": image.asset._ref},
3641
+ defined(mainImage.asset) => {"type": "image-asset", "_ref": mainImage.asset._ref},
3642
+ null
3643
+ )
3644
+ ),
3645
+ _type,
3646
+ _id,
3647
+ _updatedAt
3648
+ }`, API_VERSION$1 = "v2025-05-06";
3649
+ function hasImageRef(value) {
3650
+ return isObject(value) && "_ref" in value && typeof value._ref == "string";
3651
+ }
3652
+ function normalizeMedia(media, client) {
3653
+ if (!media || !hasImageRef(media)) return null;
3654
+ const url = createImageUrlBuilder(client).image({ _ref: media._ref }).url();
3655
+ return {
3656
+ type: "image-asset",
3657
+ _ref: media._ref,
3658
+ url
3659
+ };
3660
+ }
3661
+ function findFirstDefined(fieldsToSearch, candidates, exclude) {
3662
+ if (candidates)
3663
+ for (const field of fieldsToSearch) {
3664
+ const value = candidates[field];
3665
+ if (typeof value == "string" && value.trim() !== "" && value !== exclude)
3666
+ return value;
3667
+ }
3668
+ }
3669
+ function transformProjectionToPreview(instance, resource, projectionResult) {
3670
+ const title = findFirstDefined(TITLE_CANDIDATES, projectionResult.titleCandidates), subtitle = findFirstDefined(SUBTITLE_CANDIDATES, projectionResult.subtitleCandidates, title), client = getClient(instance, { apiVersion: API_VERSION$1, resource });
3671
+ return {
3672
+ title: String(title || `${projectionResult._type}: ${projectionResult._id}`),
3673
+ subtitle: subtitle || void 0,
3674
+ media: normalizeMedia(projectionResult.media, client),
3675
+ ...projectionResult._status && { _status: projectionResult._status }
3676
+ };
3677
+ }
3678
+ function hashString(str) {
3679
+ let hash = 0;
3680
+ for (let i = 0; i < str.length; i++)
3681
+ hash = (hash * 31 + str.charCodeAt(i)) % 2147483647;
3682
+ return Math.abs(hash).toString(16).padStart(8, "0");
3683
+ }
3639
3684
  function sortReleases(releases = []) {
3640
3685
  return [...releases].sort((a, b) => {
3641
3686
  if (a.metadata.releaseType === "undecided" && b.metadata.releaseType !== "undecided")
@@ -3663,21 +3708,20 @@ const ARCHIVED_RELEASE_STATES = ["archived", "published"], STABLE_EMPTY_RELEASES
3663
3708
  const subscription = subscribeToReleases(context);
3664
3709
  return () => subscription.unsubscribe();
3665
3710
  }
3666
- }, getActiveReleasesState = bindActionByDataset(
3711
+ }, _getActiveReleasesState = bindActionByResource(
3667
3712
  releasesStore,
3668
3713
  createStateSourceAction({
3669
3714
  selector: ({ state }, _) => state.activeReleases
3670
3715
  })
3671
- ), RELEASES_QUERY = "releases::all()", subscribeToReleases = ({
3716
+ ), getActiveReleasesState = (instance, options) => _getActiveReleasesState(instance, options), RELEASES_QUERY = "releases::all()", subscribeToReleases = ({
3672
3717
  instance,
3673
3718
  state,
3674
- key: { projectId, dataset }
3719
+ key: { resource }
3675
3720
  }) => {
3676
3721
  const { observable: releases$ } = getQueryState(instance, {
3677
3722
  query: RELEASES_QUERY,
3678
3723
  perspective: "raw",
3679
- projectId,
3680
- dataset,
3724
+ resource,
3681
3725
  tag: "releases"
3682
3726
  });
3683
3727
  return releases$.pipe(
@@ -3713,10 +3757,10 @@ const ARCHIVED_RELEASE_STATES = ["archived", "published"], STABLE_EMPTY_RELEASES
3713
3757
  )
3714
3758
  });
3715
3759
  let _boundGetPerspectiveState;
3716
- const getPerspectiveState = (...args) => (_boundGetPerspectiveState || (_boundGetPerspectiveState = bindActionByDataset(
3760
+ const getPerspectiveState = (instance, ...rest) => (_boundGetPerspectiveState || (_boundGetPerspectiveState = bindActionByResource(
3717
3761
  releasesStore,
3718
3762
  _getPerspectiveStateSelector
3719
- )), _boundGetPerspectiveState(...args)), QUERY_STATE_CLEAR_DELAY = 1e3, QUERY_STORE_API_VERSION = "v2025-05-06", QUERY_STORE_DEFAULT_PERSPECTIVE = "drafts", setQueryError = (key, error) => (prev) => {
3763
+ )), _boundGetPerspectiveState(instance, ...rest)), QUERY_STATE_CLEAR_DELAY = 1e3, QUERY_STORE_API_VERSION = "v2025-05-06", QUERY_STORE_DEFAULT_PERSPECTIVE = "drafts", setQueryError = (key, error) => (prev) => {
3720
3764
  const prevQuery = prev.queries[key];
3721
3765
  return prevQuery ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, error } } } : prev;
3722
3766
  }, setQueryData = (key, result, syncTags) => (prev) => {
@@ -3761,7 +3805,11 @@ const queryStore = {
3761
3805
  subscription.unsubscribe();
3762
3806
  };
3763
3807
  }
3764
- }, errorHandler = (state) => (error) => state.set("setError", { error }), listenForNewSubscribersAndFetch = ({ state, instance }) => state.observable.pipe(
3808
+ }, errorHandler = (state) => (error) => state.set("setError", { error }), listenForNewSubscribersAndFetch = ({
3809
+ state,
3810
+ instance,
3811
+ key: { resource: boundResource }
3812
+ }) => state.observable.pipe(
3765
3813
  map((s) => new Set(Object.keys(s.queries))),
3766
3814
  distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i) => curr.has(i))),
3767
3815
  startWith$1(/* @__PURE__ */ new Set()),
@@ -3784,19 +3832,16 @@ const queryStore = {
3784
3832
  ), {
3785
3833
  query,
3786
3834
  params,
3787
- projectId,
3788
- dataset,
3789
3835
  tag,
3790
- source,
3836
+ resource,
3791
3837
  perspective: perspectiveFromOptions,
3792
3838
  ...restOptions
3793
3839
  } = parseQueryKey(group$.key), perspective$ = isReleasePerspective(perspectiveFromOptions) ? getPerspectiveState(instance, {
3794
- perspective: perspectiveFromOptions
3840
+ perspective: perspectiveFromOptions,
3841
+ resource: resource ?? boundResource
3795
3842
  }).observable.pipe(filter(Boolean)) : of(perspectiveFromOptions ?? QUERY_STORE_DEFAULT_PERSPECTIVE), client$ = getClientState(instance, {
3796
3843
  apiVersion: QUERY_STORE_API_VERSION,
3797
- projectId,
3798
- dataset,
3799
- source
3844
+ resource: resource ?? boundResource
3800
3845
  }).observable;
3801
3846
  return combineLatest({
3802
3847
  lastLiveEventId: lastLiveEventId$,
@@ -3824,12 +3869,11 @@ const queryStore = {
3824
3869
  ).subscribe({ error: errorHandler(state) }), listenToLiveClientAndSetLastLiveEventIds = ({
3825
3870
  state,
3826
3871
  instance,
3827
- key: { source }
3872
+ key: { resource }
3828
3873
  }) => {
3829
3874
  const liveMessages$ = getClientState(instance, {
3830
3875
  apiVersion: QUERY_STORE_API_VERSION,
3831
- // temporary guard here until we're ready for everything to be queried via global api
3832
- ...source && !isDatasetSource(source) ? { source } : {}
3876
+ resource
3833
3877
  }).observable.pipe(
3834
3878
  switchMap(
3835
3879
  (client) => defer(
@@ -3866,7 +3910,7 @@ const queryStore = {
3866
3910
  function getQueryState(...args) {
3867
3911
  return _getQueryState(...args);
3868
3912
  }
3869
- const _getQueryState = bindActionBySource(
3913
+ const _getQueryState = bindActionByResource(
3870
3914
  queryStore,
3871
3915
  createStateSourceAction({
3872
3916
  selector: ({ state, instance }, options) => {
@@ -3889,7 +3933,7 @@ const _getQueryState = bindActionBySource(
3889
3933
  function resolveQuery(...args) {
3890
3934
  return _resolveQuery(...args);
3891
3935
  }
3892
- const _resolveQuery = bindActionBySource(
3936
+ const _resolveQuery = bindActionByResource(
3893
3937
  queryStore,
3894
3938
  ({ state, instance }, { signal, ...options }) => {
3895
3939
  const normalized = normalizeOptionsWithPerspective(instance, options), { getCurrent } = getQueryState(instance, normalized), key = getQueryKey(normalized), aborted$ = signal ? new Observable((observer) => {
@@ -3911,213 +3955,6 @@ const _resolveQuery = bindActionBySource(
3911
3955
  );
3912
3956
  return firstValueFrom(race([resolved$, aborted$]));
3913
3957
  }
3914
- );
3915
- function hashString(str) {
3916
- let hash = 0;
3917
- for (let i = 0; i < str.length; i++)
3918
- hash = (hash * 31 + str.charCodeAt(i)) % 2147483647;
3919
- return Math.abs(hash).toString(16).padStart(8, "0");
3920
- }
3921
- const TITLE_CANDIDATES = ["title", "name", "label", "heading", "header", "caption"], SUBTITLE_CANDIDATES = ["description", "subtitle", ...TITLE_CANDIDATES], PREVIEW_PROJECTION = `{
3922
- // Get all potential title fields
3923
- "titleCandidates": {
3924
- ${TITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
3925
- `)}
3926
- },
3927
- // Get all potential subtitle fields
3928
- "subtitleCandidates": {
3929
- ${SUBTITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
3930
- `)}
3931
- },
3932
- "media": coalesce(
3933
- select(
3934
- defined(asset) => {"type": "image-asset", "_ref": asset._ref},
3935
- defined(image.asset) => {"type": "image-asset", "_ref": image.asset._ref},
3936
- defined(mainImage.asset) => {"type": "image-asset", "_ref": mainImage.asset._ref},
3937
- null
3938
- )
3939
- ),
3940
- _type,
3941
- _id,
3942
- _updatedAt
3943
- }`, PREVIEW_TAG = "preview", PREVIEW_PERSPECTIVE = "raw", STABLE_EMPTY_PREVIEW = { data: null, isPending: !1 }, STABLE_ERROR_PREVIEW = {
3944
- data: {
3945
- title: "Preview Error",
3946
- ...!!getEnv("DEV") && { subtitle: "Check the console for more details" }
3947
- },
3948
- isPending: !1
3949
- };
3950
- function assetIdToUrl(assetId, projectId, dataset) {
3951
- const pattern = /^image-(?<assetName>[A-Za-z0-9]+)-(?<dimensions>\d+x\d+)-(?<format>[a-z]+)$/, match = assetId.match(pattern);
3952
- if (!match?.groups)
3953
- throw new Error(
3954
- `Invalid asset ID \`${assetId}\`. Expected: image-{assetName}-{width}x{height}-{format}`
3955
- );
3956
- const { assetName, dimensions, format } = match.groups;
3957
- return `https://cdn.sanity.io/images/${projectId}/${dataset}/${assetName}-${dimensions}.${format}`;
3958
- }
3959
- function hasImageRef(value) {
3960
- return isObject(value) && "_ref" in value && typeof value._ref == "string";
3961
- }
3962
- function normalizeMedia(media, projectId, dataset) {
3963
- return !media || !hasImageRef(media) ? null : {
3964
- type: "image-asset",
3965
- _ref: media._ref,
3966
- url: assetIdToUrl(media._ref, projectId, dataset)
3967
- };
3968
- }
3969
- function findFirstDefined(fieldsToSearch, candidates, exclude) {
3970
- if (candidates)
3971
- for (const field of fieldsToSearch) {
3972
- const value = candidates[field];
3973
- if (typeof value == "string" && value.trim() !== "" && value !== exclude)
3974
- return value;
3975
- }
3976
- }
3977
- function processPreviewQuery({
3978
- projectId,
3979
- dataset,
3980
- ids,
3981
- results
3982
- }) {
3983
- const resultMap = results.reduce((acc, next) => (acc[next._id] = next, acc), {});
3984
- return Object.fromEntries(
3985
- Array.from(ids).map((id) => {
3986
- const publishedId = getPublishedId(id), draftId = getDraftId(id), draftResult = resultMap[draftId], publishedResult = resultMap[publishedId];
3987
- if (!draftResult && !publishedResult) return [id, STABLE_EMPTY_PREVIEW];
3988
- try {
3989
- const result = draftResult || publishedResult;
3990
- if (!result) return [id, STABLE_EMPTY_PREVIEW];
3991
- const title = findFirstDefined(TITLE_CANDIDATES, result.titleCandidates), subtitle = findFirstDefined(SUBTITLE_CANDIDATES, result.subtitleCandidates, title), preview = {
3992
- title: String(title || `${result._type}: ${result._id}`),
3993
- subtitle: subtitle || void 0,
3994
- media: normalizeMedia(result.media, projectId, dataset)
3995
- }, _status = {
3996
- ...draftResult?._updatedAt && { lastEditedDraftAt: draftResult._updatedAt },
3997
- ...publishedResult?._updatedAt && { lastEditedPublishedAt: publishedResult._updatedAt }
3998
- };
3999
- return [id, { data: { ...preview, _status }, isPending: !1 }];
4000
- } catch (e) {
4001
- return console.warn(e), [id, STABLE_ERROR_PREVIEW];
4002
- }
4003
- })
4004
- );
4005
- }
4006
- function createPreviewQuery(documentIds) {
4007
- const allIds = Array.from(documentIds).flatMap((id) => [getPublishedId(id), getDraftId(id)]), queryHash = hashString(PREVIEW_PROJECTION);
4008
- return {
4009
- query: `*[_id in $__ids_${queryHash}]${PREVIEW_PROJECTION}`,
4010
- params: {
4011
- [`__ids_${queryHash}`]: allIds
4012
- }
4013
- };
4014
- }
4015
- const BATCH_DEBOUNCE_TIME$1 = 50, isSetEqual$1 = (a, b) => a.size === b.size && Array.from(a).every((i) => b.has(i)), subscribeToStateAndFetchBatches$1 = ({
4016
- state,
4017
- instance,
4018
- key: { projectId, dataset }
4019
- }) => state.observable.pipe(
4020
- map(({ subscriptions }) => new Set(Object.keys(subscriptions))),
4021
- distinctUntilChanged(isSetEqual$1),
4022
- debounceTime(BATCH_DEBOUNCE_TIME$1),
4023
- startWith$1(/* @__PURE__ */ new Set()),
4024
- pairwise$1(),
4025
- tap$1(([prevIds, currIds]) => {
4026
- const newIds = [...currIds].filter((element) => !prevIds.has(element));
4027
- state.set("updatingPending", (prev) => {
4028
- const pendingValues = newIds.reduce((acc, id) => {
4029
- const prevValue = prev.values[id], value = prevValue?.data ? prevValue.data : null;
4030
- return acc[id] = { data: value, isPending: !0 }, acc;
4031
- }, {});
4032
- return { values: { ...prev.values, ...pendingValues } };
4033
- });
4034
- }),
4035
- map(([, ids]) => ids),
4036
- distinctUntilChanged(isSetEqual$1)
4037
- ).pipe(
4038
- switchMap((ids) => {
4039
- if (!ids.size) return EMPTY;
4040
- const { query, params } = createPreviewQuery(ids), controller = new AbortController();
4041
- return new Observable((observer) => {
4042
- const { getCurrent, observable } = getQueryState(instance, {
4043
- query,
4044
- params,
4045
- tag: PREVIEW_TAG,
4046
- perspective: PREVIEW_PERSPECTIVE,
4047
- projectId,
4048
- dataset
4049
- }), subscription = defer(() => getCurrent() === void 0 ? from(
4050
- resolveQuery(instance, {
4051
- query,
4052
- params,
4053
- tag: PREVIEW_TAG,
4054
- perspective: PREVIEW_PERSPECTIVE,
4055
- signal: controller.signal,
4056
- projectId,
4057
- dataset
4058
- })
4059
- ).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
4060
- return () => {
4061
- controller.signal.aborted || controller.abort(), subscription.unsubscribe();
4062
- };
4063
- }).pipe(map((data) => ({ data, ids })));
4064
- }),
4065
- map(({ ids, data }) => ({
4066
- values: processPreviewQuery({
4067
- projectId,
4068
- dataset,
4069
- ids,
4070
- results: data
4071
- })
4072
- }))
4073
- ).subscribe({
4074
- next: ({ values }) => {
4075
- state.set("updateResult", (prev) => ({ values: { ...prev.values, ...values } }));
4076
- }
4077
- }), previewStore = {
4078
- name: "Preview",
4079
- getInitialState() {
4080
- return {
4081
- subscriptions: {},
4082
- values: {}
4083
- };
4084
- },
4085
- initialize: (context) => {
4086
- const subscription = subscribeToStateAndFetchBatches$1(context);
4087
- return () => subscription.unsubscribe;
4088
- }
4089
- };
4090
- function getPreviewState(...args) {
4091
- return _getPreviewState(...args);
4092
- }
4093
- const _getPreviewState = bindActionByDataset(
4094
- previewStore,
4095
- createStateSourceAction({
4096
- selector: ({ state }, docHandle) => state.values[docHandle.documentId] ?? STABLE_EMPTY_PREVIEW,
4097
- onSubscribe: ({ state }, docHandle) => {
4098
- const subscriptionId = insecureRandomId(), documentId = getPublishedId(docHandle.documentId);
4099
- return state.set("addSubscription", (prev) => ({
4100
- subscriptions: {
4101
- ...prev.subscriptions,
4102
- [documentId]: {
4103
- ...prev.subscriptions[documentId],
4104
- [subscriptionId]: !0
4105
- }
4106
- }
4107
- })), () => {
4108
- state.set("removeSubscription", (prev) => {
4109
- const documentSubscriptions = omit(prev.subscriptions[documentId], subscriptionId), hasSubscribers = !!Object.keys(documentSubscriptions).length, prevValue = prev.values[documentId], previewValue = prevValue?.data ? prevValue.data : null;
4110
- return {
4111
- subscriptions: hasSubscribers ? { ...prev.subscriptions, [documentId]: documentSubscriptions } : omit(prev.subscriptions, documentId),
4112
- values: hasSubscribers ? prev.values : { ...prev.values, [documentId]: { data: previewValue, isPending: !1 } }
4113
- };
4114
- });
4115
- };
4116
- }
4117
- })
4118
- ), resolvePreview = bindActionByDataset(
4119
- previewStore,
4120
- ({ instance }, docHandle) => firstValueFrom(getPreviewState(instance, docHandle).observable.pipe(filter((i) => !!i.data)))
4121
3958
  ), PROJECTION_TAG = "projection", PROJECTION_STATE_CLEAR_DELAY = 1e3, STABLE_EMPTY_PROJECTION = {
4122
3959
  data: null,
4123
3960
  isPending: !1
@@ -4197,7 +4034,7 @@ function processStatusQueryResults(results) {
4197
4034
  const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Array.from(a).every((i) => b.has(i)), subscribeToStateAndFetchBatches = ({
4198
4035
  state,
4199
4036
  instance,
4200
- key: { source, perspective }
4037
+ key: { resource, perspective }
4201
4038
  }) => {
4202
4039
  const documentProjections$ = state.observable.pipe(
4203
4040
  map((s) => s.documentProjections),
@@ -4241,8 +4078,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
4241
4078
  params,
4242
4079
  tag: PROJECTION_TAG,
4243
4080
  perspective,
4244
- // temporary guard here until we're ready for everything to be queried via global API
4245
- ...source && !isDatasetSource(source) ? { source } : {}
4081
+ resource
4246
4082
  }), subscription = defer(() => getCurrent() === void 0 ? from(
4247
4083
  resolveQuery(instance, {
4248
4084
  query,
@@ -4250,8 +4086,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
4250
4086
  tag: PROJECTION_TAG,
4251
4087
  signal: controller.signal,
4252
4088
  perspective,
4253
- // temporary guard here until we're ready for everything to be queried via global API in v3
4254
- ...source && !isDatasetSource(source) ? { source } : {}
4089
+ resource
4255
4090
  })
4256
4091
  ).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
4257
4092
  return () => {
@@ -4263,8 +4098,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
4263
4098
  params: statusParams,
4264
4099
  tag: PROJECTION_TAG,
4265
4100
  perspective: "raw",
4266
- // temporary guard here until we're ready for everything to be queried via global API
4267
- ...source && !isDatasetSource(source) ? { source } : {}
4101
+ resource
4268
4102
  }), subscription = defer(() => getCurrent() === void 0 ? from(
4269
4103
  resolveQuery(instance, {
4270
4104
  query: statusQuery,
@@ -4272,8 +4106,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
4272
4106
  tag: PROJECTION_TAG,
4273
4107
  signal: controller.signal,
4274
4108
  perspective: "raw",
4275
- // temporary guard here until we're ready for everything to be queried via global API
4276
- ...source && !isDatasetSource(source) ? { source } : {}
4109
+ resource
4277
4110
  })
4278
4111
  ).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
4279
4112
  return () => {
@@ -4343,7 +4176,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
4343
4176
  function getProjectionState(...args) {
4344
4177
  return _getProjectionState(...args);
4345
4178
  }
4346
- const _getProjectionState = bindActionBySourceAndPerspective(
4179
+ const _getProjectionState = bindActionByResourceAndPerspective(
4347
4180
  projectionStore,
4348
4181
  createStateSourceAction({
4349
4182
  selector: ({ state }, options) => {
@@ -4403,7 +4236,7 @@ const _getProjectionState = bindActionBySourceAndPerspective(
4403
4236
  function resolveProjection(...args) {
4404
4237
  return _resolveProjection(...args);
4405
4238
  }
4406
- const _resolveProjection = bindActionBySourceAndPerspective(
4239
+ const _resolveProjection = bindActionByResourceAndPerspective(
4407
4240
  projectionStore,
4408
4241
  ({ instance }, options) => firstValueFrom(
4409
4242
  getProjectionState(instance, options).observable.pipe(
@@ -4511,11 +4344,13 @@ function getCorsErrorProjectId(error) {
4511
4344
  const projMatch = (error.message || "").match(/manage\/project\/([^/?#]+)/);
4512
4345
  return projMatch ? projMatch[1] : null;
4513
4346
  }
4514
- var version = "2.7.0";
4347
+ var version = "3.0.0-rc.0";
4515
4348
  const CORE_SDK_VERSION = getEnv("PKG_VERSION") || `${version}-development`;
4516
4349
  export {
4517
4350
  AuthStateType,
4518
4351
  CORE_SDK_VERSION,
4352
+ DEFAULT_RESOURCE_NAME,
4353
+ PREVIEW_PROJECTION,
4519
4354
  agentGenerate,
4520
4355
  agentPatch,
4521
4356
  agentPrompt,
@@ -4523,12 +4358,11 @@ export {
4523
4358
  agentTranslate,
4524
4359
  applyDocumentActions,
4525
4360
  configureLogging,
4526
- createDatasetHandle,
4527
4361
  createDocument,
4528
4362
  createDocumentHandle,
4529
4363
  createDocumentTypeHandle,
4530
4364
  createGroqSearchFilter,
4531
- createProjectHandle,
4365
+ createResourceHandle,
4532
4366
  createSanityInstance,
4533
4367
  defineIntent,
4534
4368
  deleteDocument,
@@ -4560,7 +4394,6 @@ export {
4560
4394
  getPermissionsState,
4561
4395
  getPerspectiveState,
4562
4396
  getPresence,
4563
- getPreviewState,
4564
4397
  getProjectState,
4565
4398
  getProjectionState,
4566
4399
  getProjectsState,
@@ -4571,9 +4404,9 @@ export {
4571
4404
  getUsersKey,
4572
4405
  getUsersState,
4573
4406
  handleAuthCallback,
4574
- isCanvasSource,
4575
- isDatasetSource,
4576
- isMediaLibrarySource,
4407
+ isCanvasResource,
4408
+ isDatasetResource,
4409
+ isMediaLibraryResource,
4577
4410
  isProjectUserNotFoundClientError,
4578
4411
  isStudioConfig,
4579
4412
  joinPaths,
@@ -4590,7 +4423,6 @@ export {
4590
4423
  resolveDocument,
4591
4424
  resolveFavoritesState,
4592
4425
  resolvePermissions,
4593
- resolvePreview,
4594
4426
  resolveProject,
4595
4427
  resolveProjection,
4596
4428
  resolveProjects,
@@ -4601,6 +4433,7 @@ export {
4601
4433
  slicePath2 as slicePath,
4602
4434
  stringifyPath2 as stringifyPath,
4603
4435
  subscribeDocumentEvents,
4436
+ transformProjectionToPreview,
4604
4437
  unpublishDocument
4605
4438
  };
4606
4439
  //# sourceMappingURL=index.js.map