@sanity/sdk-react 2.5.0 → 2.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.
Files changed (30) hide show
  1. package/README.md +164 -19
  2. package/dist/index.d.ts +571 -26
  3. package/dist/index.js +149 -78
  4. package/dist/index.js.map +1 -1
  5. package/package.json +7 -7
  6. package/src/_exports/sdk-react.ts +2 -0
  7. package/src/components/SDKProvider.tsx +8 -3
  8. package/src/components/SanityApp.test.tsx +72 -2
  9. package/src/components/SanityApp.tsx +53 -10
  10. package/src/components/auth/AuthBoundary.tsx +5 -5
  11. package/src/context/ComlinkTokenRefresh.test.tsx +2 -2
  12. package/src/context/ComlinkTokenRefresh.tsx +3 -2
  13. package/src/context/SDKStudioContext.test.tsx +126 -0
  14. package/src/context/SDKStudioContext.ts +65 -0
  15. package/src/context/SourcesContext.tsx +7 -0
  16. package/src/context/renderSanityApp.test.tsx +355 -0
  17. package/src/context/renderSanityApp.tsx +48 -0
  18. package/src/hooks/agent/agentActions.ts +436 -21
  19. package/src/hooks/dashboard/useDispatchIntent.test.ts +26 -20
  20. package/src/hooks/dashboard/useDispatchIntent.ts +10 -11
  21. package/src/hooks/dashboard/utils/{getResourceIdFromDocumentHandle.test.ts → useResourceIdFromDocumentHandle.test.ts} +33 -60
  22. package/src/hooks/dashboard/utils/useResourceIdFromDocumentHandle.ts +46 -0
  23. package/src/hooks/document/useEditDocument.ts +3 -0
  24. package/src/hooks/documents/useDocuments.ts +3 -2
  25. package/src/hooks/helpers/useNormalizedSourceOptions.ts +85 -0
  26. package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +1 -0
  27. package/src/hooks/projection/useDocumentProjection.ts +15 -4
  28. package/src/hooks/query/useQuery.ts +30 -11
  29. package/src/hooks/dashboard/types.ts +0 -12
  30. package/src/hooks/dashboard/utils/getResourceIdFromDocumentHandle.ts +0 -53
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { c } from "react-compiler-runtime";
3
3
  import { ClientError, CorsOriginError } from "@sanity/client";
4
- import { getAuthState, getNodeState, getIsInDashboardState, setAuthToken, AuthStateType, getLoginUrlState, observeOrganizationVerificationState, handleAuthCallback, logout, isProjectUserNotFoundClientError, getClientErrorApiDescription, getClientErrorApiBody, getCorsErrorProjectId, createSanityInstance, agentGenerate, agentTransform, agentTranslate, agentPrompt, agentPatch, getTokenState, getCurrentUserState, getDashboardOrganizationId, getClientState, getOrCreateController, getOrCreateChannel, releaseChannel, getFavoritesState, resolveFavoritesState, resolveDatasets, getDatasetsState, applyDocumentActions, resolveDocument, getDocumentState, subscribeDocumentEvents, getPermissionsState, getDocumentSyncStatus, editDocument, getQueryKey, parseQueryKey, getQueryState, resolveQuery, createGroqSearchFilter, getPresence, getPreviewState, resolvePreview, getProjectionState, resolveProjection, resolveProject, getProjectState, resolveProjects, getProjectsState, getActiveReleasesState, getPerspectiveState, getUsersKey, parseUsersKey, getUsersState, resolveUsers, loadMoreUsers } from "@sanity/sdk";
4
+ import { getAuthState, getNodeState, getIsInDashboardState, isStudioConfig, setAuthToken, AuthStateType, getLoginUrlState, observeOrganizationVerificationState, handleAuthCallback, logout, isProjectUserNotFoundClientError, getClientErrorApiDescription, getClientErrorApiBody, getCorsErrorProjectId, createSanityInstance, agentGenerate, agentTransform, agentTranslate, agentPrompt, agentPatch, getTokenState, getCurrentUserState, getDashboardOrganizationId, getClientState, getOrCreateController, getOrCreateChannel, releaseChannel, isDatasetSource, isMediaLibrarySource, isCanvasSource, getFavoritesState, resolveFavoritesState, resolveDatasets, getDatasetsState, applyDocumentActions, resolveDocument, getDocumentState, subscribeDocumentEvents, getPermissionsState, getDocumentSyncStatus, editDocument, getQueryKey, parseQueryKey, getQueryState, resolveQuery, createGroqSearchFilter, getPresence, getPreviewState, resolvePreview, getProjectionState, resolveProjection, resolveProject, getProjectState, resolveProjects, getProjectsState, getActiveReleasesState, getPerspectiveState, getUsersKey, parseUsersKey, getUsersState, resolveUsers, loadMoreUsers } from "@sanity/sdk";
5
5
  export * from "@sanity/sdk";
6
- import { createContext, useContext, useSyncExternalStore, useRef, useEffect, useState, Suspense, useCallback, useMemo, useInsertionEffect, useTransition } from "react";
6
+ import { createContext, useContext, useSyncExternalStore, useRef, useEffect, useState, Suspense, StrictMode, useCallback, useMemo, useInsertionEffect, useTransition } from "react";
7
7
  import { ErrorBoundary } from "react-error-boundary";
8
8
  import { SDK_CHANNEL_NAME, SDK_NODE_NAME } from "@sanity/message-protocol";
9
9
  import { firstValueFrom, filter, identity, Observable, startWith, distinctUntilChanged, switchMap, EMPTY } from "rxjs";
10
+ import { createRoot } from "react-dom/client";
10
11
  import { pick } from "lodash-es";
11
12
  const SanityInstanceContext = createContext(null), useSanityInstance = (config) => {
12
13
  const $ = c(3), instance = useContext(SanityInstanceContext);
@@ -65,7 +66,7 @@ function useWindowConnection(t0) {
65
66
  const [type, handler] = t42, messageUnsubscribe = node.on(type, handler);
66
67
  messageUnsubscribe && messageUnsubscribers.current.push(messageUnsubscribe);
67
68
  }), () => {
68
- messageUnsubscribers.current.forEach(_temp$7), messageUnsubscribers.current = [];
69
+ messageUnsubscribers.current.forEach(_temp$8), messageUnsubscribers.current = [];
69
70
  }), $[4] = node, $[5] = onMessage, $[6] = t3) : t3 = $[6];
70
71
  let t4;
71
72
  $[7] !== instance || $[8] !== name || $[9] !== node || $[10] !== onMessage ? (t4 = [instance, name, onMessage, node], $[7] = instance, $[8] = name, $[9] = node, $[10] = onMessage, $[11] = t4) : t4 = $[11], useEffect(t3, t4);
@@ -83,7 +84,7 @@ function useWindowConnection(t0) {
83
84
  fetch
84
85
  }, $[16] = fetch, $[17] = sendMessage, $[18] = t7) : t7 = $[18], t7;
85
86
  }
86
- function _temp$7(unsubscribe) {
87
+ function _temp$8(unsubscribe) {
87
88
  return unsubscribe();
88
89
  }
89
90
  const DEFAULT_RESPONSE_TIMEOUT = 1e4;
@@ -113,7 +114,7 @@ function DashboardTokenRefresh(t0) {
113
114
  if (clearRefreshTimeout(), res.token) {
114
115
  setAuthToken(instance, res.token);
115
116
  const errorContainer = document.getElementById("__sanityError");
116
- errorContainer && Array.from(errorContainer.getElementsByTagName("div")).some(_temp$6) && errorContainer.remove();
117
+ errorContainer && Array.from(errorContainer.getElementsByTagName("div")).some(_temp$7) && errorContainer.remove();
117
118
  }
118
119
  isTokenRefreshInProgress.current = !1;
119
120
  } catch {
@@ -134,7 +135,7 @@ function DashboardTokenRefresh(t0) {
134
135
  let t7;
135
136
  return $[11] !== authState || $[12] !== requestNewToken ? (t7 = [authState, requestNewToken], $[11] = authState, $[12] = requestNewToken, $[13] = t7) : t7 = $[13], useEffect(t6, t7), children;
136
137
  }
137
- function _temp$6(div) {
138
+ function _temp$7(div) {
138
139
  return div.textContent?.includes("Uncaught error: Unauthorized - A valid session is required for this endpoint");
139
140
  }
140
141
  const ComlinkTokenRefreshProvider = (t0) => {
@@ -143,8 +144,8 @@ const ComlinkTokenRefreshProvider = (t0) => {
143
144
  } = t0, instance = useSanityInstance();
144
145
  let t1;
145
146
  t1 = getIsInDashboardState(instance).getCurrent();
146
- const isInDashboard = t1, studioModeEnabled = !!instance.config.studioMode?.enabled;
147
- if (isInDashboard && !studioModeEnabled) {
147
+ const isInDashboard = t1, isStudio = isStudioConfig(instance.config);
148
+ if (isInDashboard && !isStudio) {
148
149
  let t2;
149
150
  return $[0] !== children ? (t2 = /* @__PURE__ */ jsx(DashboardTokenRefresh, { children }), $[0] = children, $[1] = t2) : t2 = $[1], t2;
150
151
  }
@@ -289,10 +290,10 @@ function LoginCallback() {
289
290
  let t0, t1;
290
291
  return $[0] !== handleAuthCallback2 ? (t0 = () => {
291
292
  const url = new URL(location.href);
292
- handleAuthCallback2(url.toString()).then(_temp$5);
293
+ handleAuthCallback2(url.toString()).then(_temp$6);
293
294
  }, t1 = [handleAuthCallback2], $[0] = handleAuthCallback2, $[1] = t0, $[2] = t1) : (t0 = $[1], t1 = $[2]), useEffect(t0, t1), null;
294
295
  }
295
- function _temp$5(replacementLocation) {
296
+ function _temp$6(replacementLocation) {
296
297
  replacementLocation && history.replaceState(null, "", replacementLocation);
297
298
  }
298
299
  const useLogOut = createCallbackHook(logout);
@@ -359,7 +360,7 @@ function AuthBoundary(t0) {
359
360
  return $[7] !== FallbackComponent || $[8] !== t4 ? (t5 = /* @__PURE__ */ jsx(ComlinkTokenRefreshProvider, { children: /* @__PURE__ */ jsx(ErrorBoundary, { FallbackComponent, children: t4 }) }), $[7] = FallbackComponent, $[8] = t4, $[9] = t5) : t5 = $[9], t5;
360
361
  }
361
362
  function AuthSwitch(t0) {
362
- const $ = c(14);
363
+ const $ = c(16);
363
364
  let children, projectIds, props, t1, t2;
364
365
  $[0] !== t0 ? ({
365
366
  CallbackComponent: t1,
@@ -368,11 +369,14 @@ function AuthSwitch(t0) {
368
369
  projectIds,
369
370
  ...props
370
371
  } = t0, $[0] = t0, $[1] = children, $[2] = projectIds, $[3] = props, $[4] = t1, $[5] = t2) : (children = $[1], projectIds = $[2], props = $[3], t1 = $[4], t2 = $[5]);
371
- const CallbackComponent = t1 === void 0 ? LoginCallback : t1, verifyOrganization = t2 === void 0 ? !0 : t2, authState = useAuthState(), studioModeEnabled = useSanityInstance().config.studioMode?.enabled, disableVerifyOrg = !verifyOrganization || studioModeEnabled || authState.type !== AuthStateType.LOGGED_IN, orgError = useVerifyOrgProjects(disableVerifyOrg, projectIds), isLoggedOut = authState.type === AuthStateType.LOGGED_OUT && !authState.isDestroyingSession, loginUrl = useLoginUrl();
372
- let t3, t4;
373
- if ($[6] !== isLoggedOut || $[7] !== loginUrl || $[8] !== studioModeEnabled ? (t3 = () => {
374
- isLoggedOut && !isInIframe() && !studioModeEnabled && (window.location.href = loginUrl);
375
- }, t4 = [isLoggedOut, loginUrl, studioModeEnabled], $[6] = isLoggedOut, $[7] = loginUrl, $[8] = studioModeEnabled, $[9] = t3, $[10] = t4) : (t3 = $[9], t4 = $[10]), useEffect(t3, t4), verifyOrganization && orgError)
372
+ const CallbackComponent = t1 === void 0 ? LoginCallback : t1, verifyOrganization = t2 === void 0 ? !0 : t2, authState = useAuthState(), instance = useSanityInstance();
373
+ let t3;
374
+ $[6] !== instance.config ? (t3 = isStudioConfig(instance.config), $[6] = instance.config, $[7] = t3) : t3 = $[7];
375
+ const isStudio = t3, disableVerifyOrg = !verifyOrganization || isStudio || authState.type !== AuthStateType.LOGGED_IN, orgError = useVerifyOrgProjects(disableVerifyOrg, projectIds), isLoggedOut = authState.type === AuthStateType.LOGGED_OUT && !authState.isDestroyingSession, loginUrl = useLoginUrl();
376
+ let t4, t5;
377
+ if ($[8] !== isLoggedOut || $[9] !== isStudio || $[10] !== loginUrl ? (t4 = () => {
378
+ isLoggedOut && !isInIframe() && !isStudio && (window.location.href = loginUrl);
379
+ }, t5 = [isLoggedOut, loginUrl, isStudio], $[8] = isLoggedOut, $[9] = isStudio, $[10] = loginUrl, $[11] = t4, $[12] = t5) : (t4 = $[11], t5 = $[12]), useEffect(t4, t5), verifyOrganization && orgError)
376
380
  throw new ConfigurationError({
377
381
  message: orgError
378
382
  });
@@ -380,8 +384,8 @@ function AuthSwitch(t0) {
380
384
  case AuthStateType.ERROR:
381
385
  throw new AuthError(authState.error);
382
386
  case AuthStateType.LOGGING_IN: {
383
- let t5;
384
- return $[11] !== CallbackComponent || $[12] !== props ? (t5 = /* @__PURE__ */ jsx(CallbackComponent, { ...props }), $[11] = CallbackComponent, $[12] = props, $[13] = t5) : t5 = $[13], t5;
387
+ let t6;
388
+ return $[13] !== CallbackComponent || $[14] !== props ? (t6 = /* @__PURE__ */ jsx(CallbackComponent, { ...props }), $[13] = CallbackComponent, $[14] = props, $[15] = t6) : t6 = $[15], t6;
385
389
  }
386
390
  case AuthStateType.LOGGED_IN:
387
391
  return children;
@@ -391,6 +395,8 @@ function AuthSwitch(t0) {
391
395
  throw new Error(`Invalid auth state: ${authState.type}`);
392
396
  }
393
397
  }
398
+ const SDKStudioContext = createContext(null);
399
+ SDKStudioContext.displayName = "SDKStudioContext";
394
400
  const DEFAULT_FALLBACK = /* @__PURE__ */ jsx(Fragment, { children: "Warning: No fallback provided. Please supply a fallback prop to ensure proper Suspense handling." });
395
401
  function ResourceProvider(t0) {
396
402
  const $ = c(16);
@@ -419,40 +425,95 @@ function ResourceProvider(t0) {
419
425
  let t7;
420
426
  return $[13] !== instance || $[14] !== t6 ? (t7 = /* @__PURE__ */ jsx(SanityInstanceContext.Provider, { value: instance, children: t6 }), $[13] = instance, $[14] = t6, $[15] = t7) : t7 = $[15], t7;
421
427
  }
422
- function SDKProvider({
423
- children,
424
- config,
425
- fallback,
426
- ...props
427
- }) {
428
- const configs = (Array.isArray(config) ? config : [config]).slice().reverse(), projectIds = configs.map((c2) => c2.projectId).filter((id) => !!id), createNestedProviders = (index) => index >= configs.length ? /* @__PURE__ */ jsx(AuthBoundary, { ...props, projectIds, children }) : /* @__PURE__ */ jsx(ResourceProvider, { ...configs[index], fallback, children: createNestedProviders(index + 1) });
429
- return createNestedProviders(0);
428
+ const SourcesContext = createContext({});
429
+ function SDKProvider(t0) {
430
+ const $ = c(19);
431
+ let children, config, fallback, props;
432
+ $[0] !== t0 ? ({
433
+ children,
434
+ config,
435
+ fallback,
436
+ ...props
437
+ } = t0, $[0] = t0, $[1] = children, $[2] = config, $[3] = fallback, $[4] = props) : (children = $[1], config = $[2], fallback = $[3], props = $[4]);
438
+ let t1;
439
+ $[5] !== config ? (t1 = Array.isArray(config) ? config : [config], $[5] = config, $[6] = t1) : t1 = $[6];
440
+ let configs, t2;
441
+ $[7] !== t1 ? (configs = t1.slice().reverse(), t2 = configs.map(_temp$5).filter(_temp2$1), $[7] = t1, $[8] = configs, $[9] = t2) : (configs = $[8], t2 = $[9]);
442
+ const projectIds = t2;
443
+ let t3, t4;
444
+ $[10] !== props.sources ? (t4 = props.sources ?? {}, $[10] = props.sources, $[11] = t4) : t4 = $[11], t3 = t4;
445
+ const sourcesValue = t3;
446
+ let t5;
447
+ if ($[12] !== children || $[13] !== configs || $[14] !== fallback || $[15] !== projectIds || $[16] !== props || $[17] !== sourcesValue) {
448
+ const createNestedProviders = (index) => index >= configs.length ? /* @__PURE__ */ jsx(AuthBoundary, { ...props, projectIds, children: /* @__PURE__ */ jsx(SourcesContext.Provider, { value: sourcesValue, children }) }) : /* @__PURE__ */ jsx(ResourceProvider, { ...configs[index], fallback, children: createNestedProviders(index + 1) });
449
+ t5 = createNestedProviders(0), $[12] = children, $[13] = configs, $[14] = fallback, $[15] = projectIds, $[16] = props, $[17] = sourcesValue, $[18] = t5;
450
+ } else
451
+ t5 = $[18];
452
+ return t5;
453
+ }
454
+ function _temp2$1(id) {
455
+ return !!id;
456
+ }
457
+ function _temp$5(c2) {
458
+ return c2.projectId;
430
459
  }
431
460
  const REDIRECT_URL = "https://sanity.io/welcome";
461
+ function deriveConfigFromWorkspace(workspace) {
462
+ return {
463
+ projectId: workspace.projectId,
464
+ dataset: workspace.dataset,
465
+ studio: {
466
+ auth: workspace.auth.token ? {
467
+ token: workspace.auth.token
468
+ } : void 0
469
+ }
470
+ };
471
+ }
432
472
  function SanityApp(t0) {
433
- const $ = c(15);
434
- let children, fallback, props, t1;
473
+ const $ = c(18);
474
+ let children, configProp, fallback, props;
435
475
  $[0] !== t0 ? ({
436
476
  children,
437
477
  fallback,
438
- config: t1,
478
+ config: configProp,
439
479
  ...props
440
- } = t0, $[0] = t0, $[1] = children, $[2] = fallback, $[3] = props, $[4] = t1) : (children = $[1], fallback = $[2], props = $[3], t1 = $[4]);
441
- let t2;
442
- $[5] !== t1 ? (t2 = t1 === void 0 ? [] : t1, $[5] = t1, $[6] = t2) : t2 = $[6];
443
- const config = t2;
444
- let t3, t4;
445
- $[7] !== config ? (t3 = () => {
480
+ } = t0, $[0] = t0, $[1] = children, $[2] = configProp, $[3] = fallback, $[4] = props) : (children = $[1], configProp = $[2], fallback = $[3], props = $[4]);
481
+ const studioWorkspace = useContext(SDKStudioContext);
482
+ let t1;
483
+ bb0: {
484
+ if (configProp) {
485
+ t1 = configProp;
486
+ break bb0;
487
+ }
488
+ if (studioWorkspace) {
489
+ let t23;
490
+ $[5] !== studioWorkspace ? (t23 = deriveConfigFromWorkspace(studioWorkspace), $[5] = studioWorkspace, $[6] = t23) : t23 = $[6], t1 = t23;
491
+ break bb0;
492
+ }
493
+ let t22;
494
+ $[7] === Symbol.for("react.memo_cache_sentinel") ? (t22 = [], $[7] = t22) : t22 = $[7], t1 = t22;
495
+ }
496
+ const resolvedConfig = t1;
497
+ let t2, t3;
498
+ $[8] !== configProp || $[9] !== resolvedConfig || $[10] !== studioWorkspace ? (t2 = () => {
446
499
  let timeout;
447
- const primaryConfig = Array.isArray(config) ? config[0] : config;
448
- return !isInIframe() && !isLocalUrl(window) && !primaryConfig?.studioMode?.enabled && (timeout = setTimeout(_temp$4, 1e3)), () => clearTimeout(timeout);
449
- }, t4 = [config], $[7] = config, $[8] = t3, $[9] = t4) : (t3 = $[8], t4 = $[9]), useEffect(t3, t4);
450
- let t5;
451
- return $[10] !== children || $[11] !== config || $[12] !== fallback || $[13] !== props ? (t5 = /* @__PURE__ */ jsx(SDKProvider, { ...props, fallback, config, children }), $[10] = children, $[11] = config, $[12] = fallback, $[13] = props, $[14] = t5) : t5 = $[14], t5;
500
+ const primaryConfig = Array.isArray(resolvedConfig) ? resolvedConfig[0] : resolvedConfig, shouldRedirectWithoutConfig = configProp === void 0 && !studioWorkspace && !primaryConfig;
501
+ return !isInIframe() && !isLocalUrl(window) && (shouldRedirectWithoutConfig || primaryConfig && !isStudioConfig(primaryConfig)) && (timeout = setTimeout(_temp$4, 1e3)), () => clearTimeout(timeout);
502
+ }, t3 = [configProp, resolvedConfig, studioWorkspace], $[8] = configProp, $[9] = resolvedConfig, $[10] = studioWorkspace, $[11] = t2, $[12] = t3) : (t2 = $[11], t3 = $[12]), useEffect(t2, t3);
503
+ let t4;
504
+ return $[13] !== children || $[14] !== fallback || $[15] !== props || $[16] !== resolvedConfig ? (t4 = /* @__PURE__ */ jsx(SDKProvider, { ...props, fallback, config: resolvedConfig, children }), $[13] = children, $[14] = fallback, $[15] = props, $[16] = resolvedConfig, $[17] = t4) : t4 = $[17], t4;
452
505
  }
453
506
  function _temp$4() {
454
507
  console.warn("Redirecting to core", REDIRECT_URL), window.location.replace(REDIRECT_URL);
455
508
  }
509
+ function renderSanityApp(rootElement, namedSources, options, children) {
510
+ if (!rootElement)
511
+ throw new Error("Missing root element to mount application into");
512
+ const {
513
+ reactStrictMode = !1
514
+ } = options, root = createRoot(rootElement), config = Object.values(namedSources);
515
+ return root.render(reactStrictMode ? /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(SanityApp, { config, fallback: /* @__PURE__ */ jsx("div", { children: "Loading..." }), children }) }) : /* @__PURE__ */ jsx(SanityApp, { config, fallback: /* @__PURE__ */ jsx("div", { children: "Loading..." }), children })), () => root.unmount();
516
+ }
456
517
  const useAgentGenerate = createCallbackHook(agentGenerate), useAgentTransform = createCallbackHook(agentTransform), useAgentTranslate = createCallbackHook(agentTranslate);
457
518
  function promptAdapter(instance, options) {
458
519
  return firstValueFrom(agentPrompt(instance, options));
@@ -588,28 +649,38 @@ function useDashboardNavigate(navigateFn) {
588
649
  }
589
650
  }, $[0] = navigateFn, $[1] = t0) : t0 = $[1], useWindowConnection(t0);
590
651
  }
591
- const SOURCE_ID = "__sanity_internal_sourceId", isDocumentHandleWithSource = (documentHandle) => "source" in documentHandle;
592
- function getResourceIdFromDocumentHandle(documentHandle) {
593
- let source;
594
- const {
652
+ function useNormalizedSourceOptions(options) {
653
+ const $ = c(6);
654
+ let rest, sourceName;
655
+ if ($[0] !== options ? ({
656
+ sourceName,
657
+ ...rest
658
+ } = options, $[0] = options, $[1] = rest, $[2] = sourceName) : (rest = $[1], sourceName = $[2]), sourceName && Object.hasOwn(options, "source"))
659
+ throw new Error(`Source name ${JSON.stringify(sourceName)} and source ${JSON.stringify(options.source)} cannot be used together.`);
660
+ const sources = useContext(SourcesContext);
661
+ let resolvedSource;
662
+ if (options.source && (resolvedSource = options.source), sourceName && !Object.hasOwn(sources, sourceName))
663
+ throw new Error(`There's no source named ${JSON.stringify(sourceName)} in context. Please use <SourceProvider>.`);
664
+ sourceName && sources[sourceName] && (resolvedSource = sources[sourceName]);
665
+ let t0;
666
+ return $[3] !== resolvedSource || $[4] !== rest ? (t0 = {
667
+ ...rest,
668
+ source: resolvedSource
669
+ }, $[3] = resolvedSource, $[4] = rest, $[5] = t0) : t0 = $[5], t0;
670
+ }
671
+ function useResourceIdFromDocumentHandle(documentHandle) {
672
+ const $ = c(3), options = useNormalizedSourceOptions(documentHandle), {
595
673
  projectId,
596
- dataset
597
- } = documentHandle;
598
- isDocumentHandleWithSource(documentHandle) && (source = documentHandle.source);
599
- let resourceId = projectId + "." + dataset, resourceType;
600
- if (source) {
601
- const sourceId = source[SOURCE_ID];
602
- if (Array.isArray(sourceId))
603
- (sourceId[0] === "media-library" || sourceId[0] === "canvas") && (resourceType = sourceId[0], resourceId = sourceId[1]);
604
- else if (sourceId && typeof sourceId == "object" && "projectId" in sourceId) {
605
- const datasetSource = sourceId;
606
- resourceId = `${datasetSource.projectId}.${datasetSource.dataset}`;
607
- }
608
- }
609
- return {
674
+ dataset,
675
+ source
676
+ } = options;
677
+ let resourceId = "", resourceType;
678
+ projectId && dataset && (resourceId = `${projectId}.${dataset}`), source && (isDatasetSource(source) ? (resourceId = `${source.projectId}.${source.dataset}`, resourceType = void 0) : isMediaLibrarySource(source) ? (resourceId = source.mediaLibraryId, resourceType = "media-library") : isCanvasSource(source) && (resourceId = source.canvasId, resourceType = "canvas"));
679
+ let t0;
680
+ return $[0] !== resourceId || $[1] !== resourceType ? (t0 = {
610
681
  id: resourceId,
611
682
  type: resourceType
612
- };
683
+ }, $[0] = resourceId, $[1] = resourceType, $[2] = t0) : t0 = $[2], t0;
613
684
  }
614
685
  function useDispatchIntent(params) {
615
686
  const {
@@ -622,20 +693,15 @@ function useDispatchIntent(params) {
622
693
  } = useWindowConnection({
623
694
  name: SDK_NODE_NAME,
624
695
  connectTo: SDK_CHANNEL_NAME
625
- });
696
+ }), resource = useResourceIdFromDocumentHandle(documentHandle);
626
697
  return {
627
698
  dispatchIntent: useCallback(() => {
628
699
  try {
629
700
  if (!action && !intentId)
630
701
  throw new Error("useDispatchIntent: Either `action` or `intentId` must be provided.");
631
- const {
632
- projectId,
633
- dataset,
634
- source
635
- } = documentHandle;
636
- if (action && intentId && console.warn("useDispatchIntent: Both `action` and `intentId` were provided. Using `intentId` and ignoring `action`."), !source && (!projectId || !dataset))
637
- throw new Error("useDispatchIntent: Either `source` or both `projectId` and `dataset` must be provided in documentHandle.");
638
- const resource = getResourceIdFromDocumentHandle(documentHandle), message = {
702
+ if (action && intentId && console.warn("useDispatchIntent: Both `action` and `intentId` were provided. Using `intentId` and ignoring `action`."), !resource.id)
703
+ throw new Error("useDispatchIntent: Unable to determine resource. Either `source`, `sourceName`, or both `projectId` and `dataset` must be provided in documentHandle.");
704
+ const message = {
639
705
  type: "dashboard/v1/events/intents/dispatch-intent",
640
706
  data: {
641
707
  ...action && !intentId ? {
@@ -663,7 +729,7 @@ function useDispatchIntent(params) {
663
729
  } catch (error) {
664
730
  throw console.error("Failed to dispatch intent:", error), error;
665
731
  }
666
- }, [action, intentId, documentHandle, parameters, sendMessage])
732
+ }, [action, intentId, documentHandle, parameters, sendMessage, resource.id, resource.type])
667
733
  };
668
734
  }
669
735
  function useManageFavorite({
@@ -1044,7 +1110,7 @@ function _temp$1(key) {
1044
1110
  return !ignoredKeys.includes(key);
1045
1111
  }
1046
1112
  function useQuery(options) {
1047
- const instance = useSanityInstance(options), [isPending, startTransition] = useTransition(), queryKey = getQueryKey(options), [deferredQueryKey, setDeferredQueryKey] = useState(queryKey), deferred = useMemo(() => parseQueryKey(deferredQueryKey), [deferredQueryKey]), ref = useRef(new AbortController());
1113
+ const instance = useSanityInstance(options), normalized = useNormalizedSourceOptions(options), [isPending, startTransition] = useTransition(), queryKey = getQueryKey(normalized), [deferredQueryKey, setDeferredQueryKey] = useState(queryKey), ref = useRef(new AbortController());
1048
1114
  useEffect(() => {
1049
1115
  queryKey !== deferredQueryKey && startTransition(() => {
1050
1116
  ref && !ref.current.signal.aborted && (ref.current.abort(), ref.current = new AbortController()), setDeferredQueryKey(queryKey);
@@ -1053,11 +1119,14 @@ function useQuery(options) {
1053
1119
  const {
1054
1120
  getCurrent,
1055
1121
  subscribe
1056
- } = useMemo(() => getQueryState(instance, deferred), [instance, deferred]);
1122
+ } = useMemo(() => {
1123
+ const deferred = parseQueryKey(deferredQueryKey);
1124
+ return getQueryState(instance, deferred);
1125
+ }, [instance, deferredQueryKey]);
1057
1126
  if (getCurrent() === void 0) {
1058
- const currentSignal = ref.current.signal;
1127
+ const currentSignal = ref.current.signal, deferred_0 = parseQueryKey(deferredQueryKey);
1059
1128
  throw resolveQuery(instance, {
1060
- ...deferred,
1129
+ ...deferred_0,
1061
1130
  signal: currentSignal
1062
1131
  });
1063
1132
  }
@@ -1310,13 +1379,13 @@ function useDocumentProjection({
1310
1379
  projection,
1311
1380
  ...docHandle
1312
1381
  }) {
1313
- const instance = useSanityInstance(docHandle), normalizedProjection = useMemo(() => projection.trim(), [projection]), stateSource = useMemo(() => getProjectionState(instance, {
1314
- ...docHandle,
1382
+ const instance = useSanityInstance(docHandle), normalizedProjection = useMemo(() => projection.trim(), [projection]), normalizedDocHandle = useNormalizedSourceOptions(docHandle), stateSource = useMemo(() => getProjectionState(instance, {
1383
+ ...normalizedDocHandle,
1315
1384
  projection: normalizedProjection
1316
- }), [instance, normalizedProjection, docHandle]);
1385
+ }), [instance, normalizedDocHandle, normalizedProjection]);
1317
1386
  if (stateSource.getCurrent()?.data === null)
1318
1387
  throw resolveProjection(instance, {
1319
- ...docHandle,
1388
+ ...normalizedDocHandle,
1320
1389
  projection: normalizedProjection
1321
1390
  });
1322
1391
  const subscribe = useCallback((onStoreChanged) => {
@@ -1406,7 +1475,7 @@ function useUsers(options) {
1406
1475
  loadMore
1407
1476
  };
1408
1477
  }
1409
- var version = "2.5.0";
1478
+ var version = "2.7.0";
1410
1479
  function getEnv(key) {
1411
1480
  if (typeof import.meta < "u" && import.meta.env)
1412
1481
  return import.meta.env[key];
@@ -1422,7 +1491,9 @@ export {
1422
1491
  REACT_SDK_VERSION,
1423
1492
  ResourceProvider,
1424
1493
  SDKProvider,
1494
+ SDKStudioContext,
1425
1495
  SanityApp,
1496
+ renderSanityApp,
1426
1497
  useActiveReleases,
1427
1498
  useAgentGenerate,
1428
1499
  useAgentPatch,