@sanity/sdk-react 2.7.0 → 2.9.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 (38) hide show
  1. package/dist/index.d.ts +144 -25
  2. package/dist/index.js +248 -139
  3. package/dist/index.js.map +1 -1
  4. package/package.json +5 -5
  5. package/src/_exports/sdk-react.ts +1 -0
  6. package/src/components/SanityApp.tsx +1 -0
  7. package/src/components/auth/AuthBoundary.test.tsx +3 -0
  8. package/src/components/auth/LoginError.test.tsx +5 -0
  9. package/src/components/auth/LoginError.tsx +22 -1
  10. package/src/context/ResourceProvider.test.tsx +7 -1
  11. package/src/context/ResourceProvider.tsx +6 -0
  12. package/src/context/SDKStudioContext.ts +6 -0
  13. package/src/hooks/dashboard/useDispatchIntent.test.ts +2 -0
  14. package/src/hooks/dashboard/useWindowTitle.test.ts +213 -0
  15. package/src/hooks/dashboard/useWindowTitle.ts +112 -0
  16. package/src/hooks/document/useApplyDocumentActions.test.ts +113 -10
  17. package/src/hooks/document/useApplyDocumentActions.ts +99 -3
  18. package/src/hooks/document/useDocument.ts +22 -6
  19. package/src/hooks/document/useDocumentEvent.test.tsx +3 -3
  20. package/src/hooks/document/useDocumentEvent.ts +10 -3
  21. package/src/hooks/document/useDocumentPermissions.test.tsx +86 -2
  22. package/src/hooks/document/useDocumentPermissions.ts +22 -0
  23. package/src/hooks/document/useDocumentSyncStatus.test.ts +13 -2
  24. package/src/hooks/document/useDocumentSyncStatus.ts +14 -5
  25. package/src/hooks/document/useEditDocument.ts +34 -8
  26. package/src/hooks/documents/useDocuments.ts +2 -0
  27. package/src/hooks/helpers/useNormalizedSourceOptions.ts +50 -28
  28. package/src/hooks/helpers/useTrackHookUsage.ts +37 -0
  29. package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +2 -0
  30. package/src/hooks/presence/usePresence.ts +2 -0
  31. package/src/hooks/preview/useDocumentPreview.test.tsx +84 -193
  32. package/src/hooks/preview/useDocumentPreview.tsx +39 -55
  33. package/src/hooks/projection/useDocumentProjection.ts +2 -0
  34. package/src/hooks/query/useQuery.ts +2 -0
  35. package/src/hooks/releases/useActiveReleases.ts +32 -13
  36. package/src/hooks/releases/usePerspective.ts +26 -14
  37. package/src/hooks/users/useUser.ts +2 -0
  38. package/src/hooks/users/useUsers.ts +2 -0
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, 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";
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, getProjectionState, resolveProjection, transformProjectionToPreview, PREVIEW_PROJECTION, 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, StrictMode, useCallback, useMemo, useInsertionEffect, useTransition } from "react";
6
+ import { createContext, useContext, useSyncExternalStore, useRef, useEffect, useState, useMemo, Suspense, StrictMode, useCallback, 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 { initTelemetry, trackHookMounted } from "@sanity/sdk/_internal";
10
11
  import { createRoot } from "react-dom/client";
11
12
  import { pick } from "lodash-es";
12
13
  const SanityInstanceContext = createContext(null), useSanityInstance = (config) => {
@@ -298,25 +299,40 @@ function _temp$6(replacementLocation) {
298
299
  }
299
300
  const useLogOut = createCallbackHook(logout);
300
301
  function LoginError(t0) {
301
- const $ = c(18), {
302
+ const $ = c(23), {
302
303
  error,
303
304
  resetErrorBoundary
304
305
  } = t0;
305
306
  if (!(error instanceof AuthError || error instanceof ConfigurationError || error instanceof ClientError))
306
307
  throw error;
307
- const logout2 = useLogOut(), authState = useAuthState(), [authErrorMessage, setAuthErrorMessage] = useState("Please try again or contact support if the problem persists."), [showRetryCta, setShowRetryCta] = useState(!0);
308
- let t1;
309
- $[0] !== logout2 || $[1] !== resetErrorBoundary ? (t1 = async () => {
310
- await logout2(), resetErrorBoundary();
311
- }, $[0] = logout2, $[1] = resetErrorBoundary, $[2] = t1) : t1 = $[2];
312
- const handleRetry = t1;
308
+ const logout2 = useLogOut(), authState = useAuthState(), {
309
+ config: t1
310
+ } = useSanityInstance(), {
311
+ projectId
312
+ } = t1, [authErrorMessage, setAuthErrorMessage] = useState("Please try again or contact support if the problem persists."), [showRetryCta, setShowRetryCta] = useState(!0);
313
313
  let t2;
314
- $[3] !== authState.type || $[4] !== error || $[5] !== handleRetry ? (t2 = () => {
314
+ $[0] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
315
+ name: SDK_NODE_NAME,
316
+ connectTo: SDK_CHANNEL_NAME
317
+ }, $[0] = t2) : t2 = $[0];
318
+ const {
319
+ fetch
320
+ } = useWindowConnection(t2);
321
+ let t3;
322
+ $[1] !== logout2 || $[2] !== resetErrorBoundary ? (t3 = async () => {
323
+ await logout2(), resetErrorBoundary();
324
+ }, $[1] = logout2, $[2] = resetErrorBoundary, $[3] = t3) : t3 = $[3];
325
+ const handleRetry = t3;
326
+ let t4;
327
+ $[4] !== authState.type || $[5] !== error || $[6] !== fetch || $[7] !== handleRetry || $[8] !== projectId ? (t4 = () => {
315
328
  if (error instanceof ClientError) {
316
329
  if (error.statusCode === 401)
317
330
  if (isProjectUserNotFoundClientError(error)) {
318
331
  const description = getClientErrorApiDescription(error);
319
- description && setAuthErrorMessage(description), setShowRetryCta(!1);
332
+ description && setAuthErrorMessage(description), setShowRetryCta(!1), fetch("dashboard/v1/auth/access/request", {
333
+ resourceType: "project",
334
+ resourceId: projectId
335
+ });
320
336
  } else
321
337
  setShowRetryCta(!0), handleRetry();
322
338
  else if (error.statusCode === 404) {
@@ -325,17 +341,17 @@ function LoginError(t0) {
325
341
  }
326
342
  }
327
343
  authState.type !== AuthStateType.ERROR && error instanceof ConfigurationError && (setAuthErrorMessage(error.message), setShowRetryCta(!0));
328
- }, $[3] = authState.type, $[4] = error, $[5] = handleRetry, $[6] = t2) : t2 = $[6];
329
- let t3;
330
- $[7] !== authState || $[8] !== error || $[9] !== handleRetry ? (t3 = [authState, handleRetry, error], $[7] = authState, $[8] = error, $[9] = handleRetry, $[10] = t3) : t3 = $[10], useEffect(t2, t3);
331
- const t4 = error instanceof AuthError ? "Authentication Error" : "Configuration Error";
344
+ }, $[4] = authState.type, $[5] = error, $[6] = fetch, $[7] = handleRetry, $[8] = projectId, $[9] = t4) : t4 = $[9];
332
345
  let t5;
333
- $[11] !== handleRetry || $[12] !== showRetryCta ? (t5 = showRetryCta ? {
346
+ $[10] !== authState || $[11] !== error || $[12] !== fetch || $[13] !== handleRetry || $[14] !== projectId ? (t5 = [authState, handleRetry, error, fetch, projectId], $[10] = authState, $[11] = error, $[12] = fetch, $[13] = handleRetry, $[14] = projectId, $[15] = t5) : t5 = $[15], useEffect(t4, t5);
347
+ const t6 = error instanceof AuthError ? "Authentication Error" : "Configuration Error";
348
+ let t7;
349
+ $[16] !== handleRetry || $[17] !== showRetryCta ? (t7 = showRetryCta ? {
334
350
  text: "Retry",
335
351
  onClick: handleRetry
336
- } : void 0, $[11] = handleRetry, $[12] = showRetryCta, $[13] = t5) : t5 = $[13];
337
- let t6;
338
- return $[14] !== authErrorMessage || $[15] !== t4 || $[16] !== t5 ? (t6 = /* @__PURE__ */ jsx(Error$1, { heading: t4, description: authErrorMessage, cta: t5 }), $[14] = authErrorMessage, $[15] = t4, $[16] = t5, $[17] = t6) : t6 = $[17], t6;
352
+ } : void 0, $[16] = handleRetry, $[17] = showRetryCta, $[18] = t7) : t7 = $[18];
353
+ let t8;
354
+ return $[19] !== authErrorMessage || $[20] !== t6 || $[21] !== t7 ? (t8 = /* @__PURE__ */ jsx(Error$1, { heading: t6, description: authErrorMessage, cta: t7 }), $[19] = authErrorMessage, $[20] = t6, $[21] = t7, $[22] = t8) : t8 = $[22], t8;
339
355
  }
340
356
  if (isInIframe() && !document.querySelector("[data-sanity-core]")) {
341
357
  const parsedUrl = new URL(window.location.href), mode = new URLSearchParams(parsedUrl.hash.slice(1)).get("mode"), script = document.createElement("script");
@@ -398,32 +414,24 @@ function AuthSwitch(t0) {
398
414
  const SDKStudioContext = createContext(null);
399
415
  SDKStudioContext.displayName = "SDKStudioContext";
400
416
  const DEFAULT_FALLBACK = /* @__PURE__ */ jsx(Fragment, { children: "Warning: No fallback provided. Please supply a fallback prop to ensure proper Suspense handling." });
401
- function ResourceProvider(t0) {
402
- const $ = c(16);
403
- let children, config, fallback;
404
- $[0] !== t0 ? ({
405
- children,
406
- fallback,
407
- ...config
408
- } = t0, $[0] = t0, $[1] = children, $[2] = config, $[3] = fallback) : (children = $[1], config = $[2], fallback = $[3]);
409
- const parent = useContext(SanityInstanceContext);
410
- let t1, t2;
411
- $[4] !== config || $[5] !== parent ? (t2 = parent ? parent.createChild(config) : createSanityInstance(config), $[4] = config, $[5] = parent, $[6] = t2) : t2 = $[6], t1 = t2;
412
- const instance = t1, disposal = useRef(null);
413
- let t3, t4;
414
- $[7] !== instance ? (t3 = () => (disposal.current !== null && instance === disposal.current.instance && (clearTimeout(disposal.current.timeoutId), disposal.current = null), () => {
417
+ function ResourceProvider({
418
+ children,
419
+ fallback,
420
+ ...config
421
+ }) {
422
+ const parent = useContext(SanityInstanceContext), instance = useMemo(() => parent ? parent.createChild(config) : createSanityInstance(config), [config, parent]), projectId = config.projectId ?? "";
423
+ useMemo(() => {
424
+ projectId && !parent && initTelemetry(instance, projectId);
425
+ }, [instance, projectId, parent]);
426
+ const disposal = useRef(null);
427
+ return useEffect(() => (disposal.current !== null && instance === disposal.current.instance && (clearTimeout(disposal.current.timeoutId), disposal.current = null), () => {
415
428
  disposal.current = {
416
429
  instance,
417
430
  timeoutId: setTimeout(() => {
418
431
  instance.isDisposed() || instance.dispose();
419
432
  }, 0)
420
433
  };
421
- }), t4 = [instance], $[7] = instance, $[8] = t3, $[9] = t4) : (t3 = $[8], t4 = $[9]), useEffect(t3, t4);
422
- const t5 = fallback ?? DEFAULT_FALLBACK;
423
- let t6;
424
- $[10] !== children || $[11] !== t5 ? (t6 = /* @__PURE__ */ jsx(Suspense, { fallback: t5, children }), $[10] = children, $[11] = t5, $[12] = t6) : t6 = $[12];
425
- let t7;
426
- return $[13] !== instance || $[14] !== t6 ? (t7 = /* @__PURE__ */ jsx(SanityInstanceContext.Provider, { value: instance, children: t6 }), $[13] = instance, $[14] = t6, $[15] = t7) : t7 = $[15], t7;
434
+ }), [instance]), /* @__PURE__ */ jsx(SanityInstanceContext.Provider, { value: instance, children: /* @__PURE__ */ jsx(Suspense, { fallback: fallback ?? DEFAULT_FALLBACK, children }) });
427
435
  }
428
436
  const SourcesContext = createContext({});
429
437
  function SDKProvider(t0) {
@@ -463,6 +471,7 @@ function deriveConfigFromWorkspace(workspace) {
463
471
  projectId: workspace.projectId,
464
472
  dataset: workspace.dataset,
465
473
  studio: {
474
+ authenticated: workspace.authenticated,
466
475
  auth: workspace.auth.token ? {
467
476
  token: workspace.auth.token
468
477
  } : void 0
@@ -649,24 +658,27 @@ function useDashboardNavigate(navigateFn) {
649
658
  }
650
659
  }, $[0] = navigateFn, $[1] = t0) : t0 = $[1], useWindowConnection(t0);
651
660
  }
652
- function useNormalizedSourceOptions(options) {
653
- const $ = c(6);
654
- let rest, sourceName;
655
- if ($[0] !== options ? ({
661
+ function normalizeSourceOptions(options, sources) {
662
+ const {
656
663
  sourceName,
657
664
  ...rest
658
- } = options, $[0] = options, $[1] = rest, $[2] = sourceName) : (rest = $[1], sourceName = $[2]), sourceName && Object.hasOwn(options, "source"))
665
+ } = options;
666
+ if (!sourceName && !options.source)
667
+ return options;
668
+ if (sourceName && Object.hasOwn(options, "source"))
659
669
  throw new Error(`Source name ${JSON.stringify(sourceName)} and source ${JSON.stringify(options.source)} cannot be used together.`);
660
- const sources = useContext(SourcesContext);
661
670
  let resolvedSource;
662
671
  if (options.source && (resolvedSource = options.source), sourceName && !Object.hasOwn(sources, sourceName))
663
672
  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 = {
673
+ return sourceName && sources[sourceName] && (resolvedSource = sources[sourceName]), {
667
674
  ...rest,
668
675
  source: resolvedSource
669
- }, $[3] = resolvedSource, $[4] = rest, $[5] = t0) : t0 = $[5], t0;
676
+ };
677
+ }
678
+ function useNormalizedSourceOptions(options) {
679
+ const $ = c(3), sources = useContext(SourcesContext);
680
+ let t0;
681
+ return $[0] !== options || $[1] !== sources ? (t0 = normalizeSourceOptions(options, sources), $[0] = options, $[1] = sources, $[2] = t0) : t0 = $[2], t0;
670
682
  }
671
683
  function useResourceIdFromDocumentHandle(documentHandle) {
672
684
  const $ = c(3), options = useNormalizedSourceOptions(documentHandle), {
@@ -936,6 +948,50 @@ function useRecordDocumentHistoryEvent(t0) {
936
948
  recordEvent
937
949
  }, $[8] = recordEvent, $[9] = t3) : t3 = $[9], t3;
938
950
  }
951
+ function resolveAppTitle(resource) {
952
+ return resource.manifest?.title ?? resource.activeDeployment?.manifest?.title ?? resource.title;
953
+ }
954
+ function useWindowTitle(viewTitle) {
955
+ const $ = c(8), [appTitle, setAppTitle] = useState(null);
956
+ let t0;
957
+ $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
958
+ name: SDK_NODE_NAME,
959
+ connectTo: SDK_CHANNEL_NAME
960
+ }, $[0] = t0) : t0 = $[0];
961
+ const {
962
+ fetch
963
+ } = useWindowConnection(t0);
964
+ let t1, t2;
965
+ $[1] !== fetch ? (t1 = () => {
966
+ if (!fetch)
967
+ return;
968
+ const controller = new AbortController();
969
+ return (async function(signal) {
970
+ try {
971
+ const data = await fetch("dashboard/v1/context", void 0, {
972
+ signal
973
+ }), title = resolveAppTitle(data.context.resource);
974
+ title && setAppTitle(title);
975
+ } catch (t32) {
976
+ const err = t32;
977
+ if (err instanceof Error && err.name === "AbortError")
978
+ return;
979
+ console.error("Failed to fetch app title from dashboard context:", err);
980
+ }
981
+ })(controller.signal), () => {
982
+ controller.abort();
983
+ };
984
+ }, t2 = [fetch], $[1] = fetch, $[2] = t1, $[3] = t2) : (t1 = $[2], t2 = $[3]), useEffect(t1, t2);
985
+ let t3, t4;
986
+ $[4] !== appTitle || $[5] !== viewTitle ? (t3 = () => {
987
+ if (!appTitle)
988
+ return;
989
+ const previous = document.title;
990
+ return document.title = viewTitle ? `${viewTitle} | ${appTitle}` : appTitle, () => {
991
+ document.title = previous;
992
+ };
993
+ }, t4 = [viewTitle, appTitle], $[4] = appTitle, $[5] = viewTitle, $[6] = t3, $[7] = t4) : (t3 = $[6], t4 = $[7]), useEffect(t3, t4);
994
+ }
939
995
  const useDatasets = createStateSourceHook({
940
996
  getState: getDatasetsState,
941
997
  shouldSuspend: (instance, projectHandle) => (
@@ -945,18 +1001,27 @@ const useDatasets = createStateSourceHook({
945
1001
  suspender: resolveDatasets,
946
1002
  getConfig: identity
947
1003
  }), useApplyDocumentActions = () => {
948
- const $ = c(2), instance = useSanityInstance();
1004
+ const $ = c(3), instance = useSanityInstance(), sources = useContext(SourcesContext);
949
1005
  let t0;
950
- return $[0] !== instance ? (t0 = (actionOrActions, options) => {
951
- const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions];
952
- let projectId, dataset;
953
- for (const action of actions)
1006
+ return $[0] !== instance || $[1] !== sources ? (t0 = (actionOrActions, options) => {
1007
+ const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions], normalizedOptions = options ? normalizeSourceOptions(options, sources) : void 0;
1008
+ let projectId, dataset, source;
1009
+ for (const action of actions) {
954
1010
  if (action.projectId) {
1011
+ if (source)
1012
+ throw new Error(`Mismatches between projectId/dataset options and source in actions. Found projectId "${action.projectId}" and dataset "${action.dataset}" but expected source "${source}".`);
955
1013
  if (projectId || (projectId = action.projectId), action.projectId !== projectId)
956
1014
  throw new Error(`Mismatched project IDs found in actions. All actions must belong to the same project. Found "${action.projectId}" but expected "${projectId}".`);
957
1015
  if (action.dataset && (dataset || (dataset = action.dataset), action.dataset !== dataset))
958
1016
  throw new Error(`Mismatched datasets found in actions. All actions must belong to the same dataset. Found "${action.dataset}" but expected "${dataset}".`);
959
1017
  }
1018
+ if (action.source) {
1019
+ if (source || (source = action.source), action.source !== source)
1020
+ throw new Error(`Mismatched sources found in actions. All actions must belong to the same source. Found "${action.source}" but expected "${source}".`);
1021
+ if (projectId || dataset)
1022
+ throw new Error(`Mismatches between projectId/dataset options and source in actions. Found "${action.source}" but expected project "${projectId}" and dataset "${dataset}".`);
1023
+ }
1024
+ }
960
1025
  if (projectId || dataset) {
961
1026
  const actualInstance = instance.match({
962
1027
  projectId,
@@ -970,15 +1035,25 @@ const useDatasets = createStateSourceHook({
970
1035
  Please ensure there is a ResourceProvider component with a matching configuration in the component hierarchy.`);
971
1036
  return applyDocumentActions(actualInstance, {
972
1037
  actions,
973
- ...options
1038
+ source,
1039
+ ...normalizedOptions
974
1040
  });
975
1041
  }
976
1042
  return applyDocumentActions(instance, {
977
1043
  actions,
978
- ...options
1044
+ source,
1045
+ ...normalizedOptions
979
1046
  });
980
- }, $[0] = instance, $[1] = t0) : t0 = $[1], t0;
981
- }, useDocumentValue = createStateSourceHook({
1047
+ }, $[0] = instance, $[1] = sources, $[2] = t0) : t0 = $[2], t0;
1048
+ };
1049
+ function useTrackHookUsage(hookName) {
1050
+ const instance = useSanityInstance(), tracked = useRef(!1);
1051
+ tracked.current || (tracked.current = !0, trackHookMounted(instance, hookName));
1052
+ }
1053
+ function trackHookUsage(instance, hookName) {
1054
+ trackHookMounted(instance, hookName);
1055
+ }
1056
+ const useDocumentValue = createStateSourceHook({
982
1057
  // Pass options directly to getDocumentState
983
1058
  getState: (instance, options) => getDocumentState(instance, options),
984
1059
  // Pass options directly to getDocumentState for checking current value
@@ -996,14 +1071,20 @@ const useDatasets = createStateSourceHook({
996
1071
  };
997
1072
  }
998
1073
  return useHook;
999
- }, useDocument = wrapHookWithData(useDocumentValue);
1074
+ }, useDocument = wrapHookWithData((options) => {
1075
+ useTrackHookUsage("useDocument");
1076
+ const normalizedOptions = useNormalizedSourceOptions(options);
1077
+ return useDocumentValue(normalizedOptions);
1078
+ });
1000
1079
  function useDocumentEvent(options) {
1001
- const $ = c(9);
1080
+ const $ = c(10);
1081
+ useTrackHookUsage("useDocumentEvent");
1082
+ const normalizedOptions = useNormalizedSourceOptions(options);
1002
1083
  let datasetHandle, onEvent;
1003
- $[0] !== options ? ({
1084
+ $[0] !== normalizedOptions ? ({
1004
1085
  onEvent,
1005
1086
  ...datasetHandle
1006
- } = options, $[0] = options, $[1] = datasetHandle, $[2] = onEvent) : (datasetHandle = $[1], onEvent = $[2]);
1087
+ } = normalizedOptions, $[0] = normalizedOptions, $[1] = datasetHandle, $[2] = onEvent) : (datasetHandle = $[1], onEvent = $[2]);
1007
1088
  const ref = useRef(onEvent);
1008
1089
  let t0;
1009
1090
  $[3] !== onEvent ? (t0 = () => {
@@ -1013,41 +1094,53 @@ function useDocumentEvent(options) {
1013
1094
  $[5] === Symbol.for("react.memo_cache_sentinel") ? (t1 = (documentEvent) => ref.current(documentEvent), $[5] = t1) : t1 = $[5];
1014
1095
  const stableHandler = t1, instance = useSanityInstance(datasetHandle);
1015
1096
  let t2, t3;
1016
- $[6] !== instance ? (t2 = () => subscribeDocumentEvents(instance, stableHandler), t3 = [instance, stableHandler], $[6] = instance, $[7] = t2, $[8] = t3) : (t2 = $[7], t3 = $[8]), useEffect(t2, t3);
1097
+ $[6] !== datasetHandle.source || $[7] !== instance ? (t2 = () => subscribeDocumentEvents(instance, {
1098
+ eventHandler: stableHandler,
1099
+ source: datasetHandle.source
1100
+ }), t3 = [instance, datasetHandle.source, stableHandler], $[6] = datasetHandle.source, $[7] = instance, $[8] = t2, $[9] = t3) : (t2 = $[8], t3 = $[9]), useEffect(t2, t3);
1017
1101
  }
1018
1102
  function useDocumentPermissions(actionOrActions) {
1019
- const $ = c(13);
1103
+ const $ = c(15);
1020
1104
  let t0, t1;
1021
1105
  $[0] !== actionOrActions ? (t1 = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions], $[0] = actionOrActions, $[1] = t1) : t1 = $[1], t0 = t1;
1022
1106
  const actions = t0;
1023
- let projectId, dataset;
1024
- if ($[2] !== actions || $[3] !== dataset || $[4] !== projectId) {
1025
- for (const action of actions)
1107
+ let projectId, dataset, source;
1108
+ if ($[2] !== actions || $[3] !== dataset || $[4] !== projectId || $[5] !== source) {
1109
+ for (const action of actions) {
1026
1110
  if (action.projectId) {
1111
+ if (source)
1112
+ throw new Error(`Mismatches between projectId/dataset options and source in actions. Found projectId "${action.projectId}" and dataset "${action.dataset}" but expected source "${source}".`);
1027
1113
  if (projectId || (projectId = action.projectId), action.projectId !== projectId)
1028
1114
  throw new Error(`Mismatched project IDs found in actions. All actions must belong to the same project. Found "${action.projectId}" but expected "${projectId}".`);
1029
1115
  if (action.dataset && (dataset || (dataset = action.dataset), action.dataset !== dataset))
1030
1116
  throw new Error(`Mismatched datasets found in actions. All actions must belong to the same dataset. Found "${action.dataset}" but expected "${dataset}".`);
1031
1117
  }
1032
- $[2] = actions, $[3] = dataset, $[4] = projectId, $[5] = projectId, $[6] = dataset;
1118
+ if (action.source) {
1119
+ if (source || (source = action.source), action.source !== source)
1120
+ throw new Error(`Mismatched sources found in actions. All actions must belong to the same source. Found "${action.source}" but expected "${source}".`);
1121
+ if (projectId || dataset)
1122
+ throw new Error(`Mismatches between projectId/dataset options and source in actions. Found "${action.source}" but expected project "${projectId}" and dataset "${dataset}".`);
1123
+ }
1124
+ }
1125
+ $[2] = actions, $[3] = dataset, $[4] = projectId, $[5] = source, $[6] = projectId, $[7] = dataset, $[8] = source;
1033
1126
  } else
1034
- projectId = $[5], dataset = $[6];
1127
+ projectId = $[6], dataset = $[7], source = $[8];
1035
1128
  let t2;
1036
- $[7] !== dataset || $[8] !== projectId ? (t2 = {
1129
+ $[9] !== dataset || $[10] !== projectId ? (t2 = {
1037
1130
  projectId,
1038
1131
  dataset
1039
- }, $[7] = dataset, $[8] = projectId, $[9] = t2) : t2 = $[9];
1132
+ }, $[9] = dataset, $[10] = projectId, $[11] = t2) : t2 = $[11];
1040
1133
  const instance = useSanityInstance(t2);
1041
- if (getPermissionsState(instance, {
1134
+ if (trackHookUsage(instance, "useDocumentPermissions"), getPermissionsState(instance, {
1042
1135
  actions
1043
1136
  }).getCurrent() === void 0)
1044
1137
  throw firstValueFrom(getPermissionsState(instance, {
1045
1138
  actions
1046
1139
  }).observable.pipe(filter(_temp$2)));
1047
1140
  let t3, t4;
1048
- $[10] !== actions || $[11] !== instance ? (t4 = getPermissionsState(instance, {
1141
+ $[12] !== actions || $[13] !== instance ? (t4 = getPermissionsState(instance, {
1049
1142
  actions
1050
- }), $[10] = actions, $[11] = instance, $[12] = t4) : t4 = $[12], t3 = t4;
1143
+ }), $[12] = actions, $[13] = instance, $[14] = t4) : t4 = $[14], t3 = t4;
1051
1144
  const {
1052
1145
  subscribe,
1053
1146
  getCurrent
@@ -1057,12 +1150,15 @@ function useDocumentPermissions(actionOrActions) {
1057
1150
  function _temp$2(result) {
1058
1151
  return result !== void 0;
1059
1152
  }
1060
- const useDocumentSyncStatus = createStateSourceHook({
1153
+ const useDocumentSyncStatusValue = createStateSourceHook({
1061
1154
  getState: getDocumentSyncStatus,
1062
1155
  shouldSuspend: (instance, doc) => getDocumentSyncStatus(instance, doc).getCurrent() === void 0,
1063
1156
  suspender: (instance, doc) => resolveDocument(instance, doc),
1064
1157
  getConfig: identity
1065
- }), ignoredKeys = ["_id", "_type", "_createdAt", "_updatedAt", "_rev"];
1158
+ }), useDocumentSyncStatus = (options) => {
1159
+ const normalizedOptions = useNormalizedSourceOptions(options);
1160
+ return useDocumentSyncStatusValue(normalizedOptions);
1161
+ }, ignoredKeys = ["_id", "_type", "_createdAt", "_updatedAt", "_rev"];
1066
1162
  function useEditDocument(t0) {
1067
1163
  const $ = c(8);
1068
1164
  let doc, path;
@@ -1070,25 +1166,27 @@ function useEditDocument(t0) {
1070
1166
  path,
1071
1167
  ...doc
1072
1168
  } = t0, $[0] = t0, $[1] = doc, $[2] = path) : (doc = $[1], path = $[2]);
1073
- const instance = useSanityInstance(doc), apply = useApplyDocumentActions();
1074
- if (getDocumentState(instance, doc).getCurrent() === void 0)
1075
- throw resolveDocument(instance, doc);
1169
+ const instance = useSanityInstance(doc);
1170
+ trackHookUsage(instance, "useEditDocument");
1171
+ const normalizedDoc = useNormalizedSourceOptions(doc), apply = useApplyDocumentActions();
1172
+ if (getDocumentState(instance, normalizedDoc).getCurrent() === void 0)
1173
+ throw resolveDocument(instance, normalizedDoc);
1076
1174
  let t1;
1077
- return $[3] !== apply || $[4] !== doc || $[5] !== instance || $[6] !== path ? (t1 = (updater) => {
1175
+ return $[3] !== apply || $[4] !== instance || $[5] !== normalizedDoc || $[6] !== path ? (t1 = (updater) => {
1078
1176
  const currentPath = path;
1079
1177
  if (currentPath) {
1080
1178
  const currentValue = getDocumentState(instance, {
1081
- ...doc,
1179
+ ...normalizedDoc,
1082
1180
  path
1083
1181
  }).getCurrent(), nextValue = typeof updater == "function" ? updater(currentValue) : updater;
1084
- return apply(editDocument(doc, {
1182
+ return apply(editDocument(normalizedDoc, {
1085
1183
  set: {
1086
1184
  [currentPath]: nextValue
1087
1185
  }
1088
1186
  }));
1089
1187
  }
1090
1188
  const current = getDocumentState(instance, {
1091
- ...doc,
1189
+ ...normalizedDoc,
1092
1190
  path
1093
1191
  }).getCurrent(), nextValue_0 = typeof updater == "function" ? updater(current) : updater;
1094
1192
  if (typeof nextValue_0 != "object" || !nextValue_0)
@@ -1096,21 +1194,23 @@ function useEditDocument(t0) {
1096
1194
  const editActions = Object.keys({
1097
1195
  ...current,
1098
1196
  ...nextValue_0
1099
- }).filter(_temp$1).filter((key_0) => current?.[key_0] !== nextValue_0[key_0]).map((key_1) => key_1 in nextValue_0 ? editDocument(doc, {
1197
+ }).filter(_temp$1).filter((key_0) => current?.[key_0] !== nextValue_0[key_0]).map((key_1) => key_1 in nextValue_0 ? editDocument(normalizedDoc, {
1100
1198
  set: {
1101
1199
  [key_1]: nextValue_0[key_1]
1102
1200
  }
1103
- }) : editDocument(doc, {
1201
+ }) : editDocument(normalizedDoc, {
1104
1202
  unset: [key_1]
1105
1203
  }));
1106
1204
  return apply(editActions);
1107
- }, $[3] = apply, $[4] = doc, $[5] = instance, $[6] = path, $[7] = t1) : t1 = $[7], t1;
1205
+ }, $[3] = apply, $[4] = instance, $[5] = normalizedDoc, $[6] = path, $[7] = t1) : t1 = $[7], t1;
1108
1206
  }
1109
1207
  function _temp$1(key) {
1110
1208
  return !ignoredKeys.includes(key);
1111
1209
  }
1112
1210
  function useQuery(options) {
1113
- const instance = useSanityInstance(options), normalized = useNormalizedSourceOptions(options), [isPending, startTransition] = useTransition(), queryKey = getQueryKey(normalized), [deferredQueryKey, setDeferredQueryKey] = useState(queryKey), ref = useRef(new AbortController());
1211
+ const instance = useSanityInstance(options);
1212
+ trackHookUsage(instance, "useQuery");
1213
+ const normalized = useNormalizedSourceOptions(options), [isPending, startTransition] = useTransition(), queryKey = getQueryKey(normalized), [deferredQueryKey, setDeferredQueryKey] = useState(queryKey), ref = useRef(new AbortController());
1114
1214
  useEffect(() => {
1115
1215
  queryKey !== deferredQueryKey && startTransition(() => {
1116
1216
  ref && !ref.current.signal.aborted && (ref.current.abort(), ref.current = new AbortController()), setDeferredQueryKey(queryKey);
@@ -1146,6 +1246,7 @@ function useDocuments({
1146
1246
  documentType,
1147
1247
  ...options
1148
1248
  }) {
1249
+ useTrackHookUsage("useDocuments");
1149
1250
  const instance = useSanityInstance(options), [limit, setLimit] = useState(batchSize), documentTypes = useMemo(() => (Array.isArray(documentType) ? documentType : [documentType]).filter((i) => typeof i == "string"), [documentType]), key = JSON.stringify({
1150
1251
  filter: filter2,
1151
1252
  search,
@@ -1208,7 +1309,9 @@ function usePaginatedDocuments(t0) {
1208
1309
  const filter2 = t1 === void 0 ? "" : t1, pageSize = t2 === void 0 ? 25 : t2;
1209
1310
  let t4;
1210
1311
  $[8] !== t3 ? (t4 = t3 === void 0 ? {} : t3, $[8] = t3, $[9] = t4) : t4 = $[9];
1211
- const params = t4, instance = useSanityInstance(options), [pageIndex, setPageIndex] = useState(0);
1312
+ const params = t4;
1313
+ useTrackHookUsage("usePaginatedDocuments");
1314
+ const instance = useSanityInstance(options), [pageIndex, setPageIndex] = useState(0);
1212
1315
  let t5;
1213
1316
  $[10] !== filter2 || $[11] !== orderings || $[12] !== pageSize || $[13] !== params || $[14] !== search ? (t5 = JSON.stringify({
1214
1317
  filter: filter2,
@@ -1318,6 +1421,7 @@ function _temp(i) {
1318
1421
  }
1319
1422
  function usePresence() {
1320
1423
  const $ = c(11), sanityInstance = useSanityInstance();
1424
+ trackHookUsage(sanityInstance, "usePresence");
1321
1425
  let t0, t1;
1322
1426
  $[0] !== sanityInstance ? (t1 = getPresence(sanityInstance), $[0] = sanityInstance, $[1] = t1) : t1 = $[1], t0 = t1;
1323
1427
  const source = t0;
@@ -1334,52 +1438,14 @@ function usePresence() {
1334
1438
  locations: t5
1335
1439
  }, $[9] = t5, $[10] = t6) : t6 = $[10], t6;
1336
1440
  }
1337
- function useDocumentPreview(t0) {
1338
- const $ = c(13);
1339
- let docHandle, ref;
1340
- $[0] !== t0 ? ({
1341
- ref,
1342
- ...docHandle
1343
- } = t0, $[0] = t0, $[1] = docHandle, $[2] = ref) : (docHandle = $[1], ref = $[2]);
1344
- const instance = useSanityInstance(docHandle);
1345
- let t1;
1346
- $[3] !== docHandle || $[4] !== instance ? (t1 = getPreviewState(instance, docHandle), $[3] = docHandle, $[4] = instance, $[5] = t1) : t1 = $[5];
1347
- const stateSource = t1;
1348
- let t2;
1349
- $[6] !== ref || $[7] !== stateSource ? (t2 = (onStoreChanged) => {
1350
- const subscription = new Observable((observer) => {
1351
- if (typeof IntersectionObserver > "u" || typeof HTMLElement > "u") {
1352
- observer.next(!0);
1353
- return;
1354
- }
1355
- const intersectionObserver = new IntersectionObserver((t32) => {
1356
- const [entry] = t32;
1357
- return observer.next(entry.isIntersecting);
1358
- }, {
1359
- rootMargin: "0px",
1360
- threshold: 0
1361
- });
1362
- return ref?.current && ref.current instanceof HTMLElement ? intersectionObserver.observe(ref.current) : observer.next(!0), () => intersectionObserver.disconnect();
1363
- }).pipe(startWith(!1), distinctUntilChanged(), switchMap((isVisible) => isVisible ? new Observable((obs) => stateSource.subscribe(() => obs.next())) : EMPTY)).subscribe({
1364
- next: onStoreChanged
1365
- });
1366
- return () => subscription.unsubscribe();
1367
- }, $[6] = ref, $[7] = stateSource, $[8] = t2) : t2 = $[8];
1368
- const subscribe = t2;
1369
- let t3;
1370
- return $[9] !== docHandle || $[10] !== instance || $[11] !== stateSource ? (t3 = () => {
1371
- const currentState = stateSource.getCurrent();
1372
- if (currentState.data === null)
1373
- throw resolvePreview(instance, docHandle);
1374
- return currentState;
1375
- }, $[9] = docHandle, $[10] = instance, $[11] = stateSource, $[12] = t3) : t3 = $[12], useSyncExternalStore(subscribe, t3);
1376
- }
1377
1441
  function useDocumentProjection({
1378
1442
  ref,
1379
1443
  projection,
1380
1444
  ...docHandle
1381
1445
  }) {
1382
- const instance = useSanityInstance(docHandle), normalizedProjection = useMemo(() => projection.trim(), [projection]), normalizedDocHandle = useNormalizedSourceOptions(docHandle), stateSource = useMemo(() => getProjectionState(instance, {
1446
+ const instance = useSanityInstance(docHandle);
1447
+ trackHookUsage(instance, "useDocumentProjection");
1448
+ const normalizedProjection = useMemo(() => projection.trim(), [projection]), normalizedDocHandle = useNormalizedSourceOptions(docHandle), stateSource = useMemo(() => getProjectionState(instance, {
1383
1449
  ...normalizedDocHandle,
1384
1450
  projection: normalizedProjection
1385
1451
  }), [instance, normalizedDocHandle, normalizedProjection]);
@@ -1406,6 +1472,32 @@ function useDocumentProjection({
1406
1472
  }, [stateSource, ref]);
1407
1473
  return useSyncExternalStore(subscribe, stateSource.getCurrent);
1408
1474
  }
1475
+ function useDocumentPreview(t0) {
1476
+ const $ = c(13);
1477
+ let docHandle, ref;
1478
+ $[0] !== t0 ? ({
1479
+ ref,
1480
+ ...docHandle
1481
+ } = t0, $[0] = t0, $[1] = docHandle, $[2] = ref) : (docHandle = $[1], ref = $[2]);
1482
+ const instance = useSanityInstance(docHandle);
1483
+ trackHookUsage(instance, "useDocumentPreview");
1484
+ const normalizedDocHandle = useNormalizedSourceOptions(docHandle);
1485
+ let t1;
1486
+ $[3] !== normalizedDocHandle || $[4] !== ref ? (t1 = {
1487
+ ...normalizedDocHandle,
1488
+ projection: PREVIEW_PROJECTION,
1489
+ ref
1490
+ }, $[3] = normalizedDocHandle, $[4] = ref, $[5] = t1) : t1 = $[5];
1491
+ const projectionResult = useDocumentProjection(t1);
1492
+ let t2, t3;
1493
+ $[6] !== instance || $[7] !== normalizedDocHandle.source || $[8] !== projectionResult.data ? (t3 = transformProjectionToPreview(instance, projectionResult.data, normalizedDocHandle.source), $[6] = instance, $[7] = normalizedDocHandle.source, $[8] = projectionResult.data, $[9] = t3) : t3 = $[9], t2 = t3;
1494
+ const previewValue = t2;
1495
+ let t4;
1496
+ return $[10] !== previewValue || $[11] !== projectionResult.isPending ? (t4 = {
1497
+ data: previewValue,
1498
+ isPending: projectionResult.isPending
1499
+ }, $[10] = previewValue, $[11] = projectionResult.isPending, $[12] = t4) : t4 = $[12], t4;
1500
+ }
1409
1501
  const useProject = createStateSourceHook({
1410
1502
  // remove `undefined` since we're suspending when that is the case
1411
1503
  getState: getProjectState,
@@ -1416,17 +1508,31 @@ const useProject = createStateSourceHook({
1416
1508
  getState: getProjectsState,
1417
1509
  shouldSuspend: (instance, options) => getProjectsState(instance, options).getCurrent() === void 0,
1418
1510
  suspender: resolveProjects
1419
- }), useActiveReleases = createStateSourceHook({
1511
+ }), useActiveReleasesValue = createStateSourceHook({
1420
1512
  getState: getActiveReleasesState,
1421
- shouldSuspend: (instance) => getActiveReleasesState(instance).getCurrent() === void 0,
1422
- suspender: (instance) => firstValueFrom(getActiveReleasesState(instance).observable.pipe(filter(Boolean)))
1423
- }), usePerspective = createStateSourceHook({
1513
+ shouldSuspend: (instance, options) => getActiveReleasesState(instance, options ?? {}).getCurrent() === void 0,
1514
+ suspender: (instance, options) => firstValueFrom(getActiveReleasesState(instance, options ?? {}).observable.pipe(filter(Boolean)))
1515
+ }), useActiveReleases = (options) => {
1516
+ const $ = c(2);
1517
+ let t0;
1518
+ $[0] !== options ? (t0 = options ?? {}, $[0] = options, $[1] = t0) : t0 = $[1];
1519
+ const normalizedOptions = useNormalizedSourceOptions(t0);
1520
+ return useActiveReleasesValue(normalizedOptions);
1521
+ }, usePerspectiveValue = createStateSourceHook({
1424
1522
  getState: getPerspectiveState,
1425
1523
  shouldSuspend: (instance, options) => getPerspectiveState(instance, options).getCurrent() === void 0,
1426
- suspender: (instance, _options) => firstValueFrom(getActiveReleasesState(instance).observable.pipe(filter(Boolean)))
1427
- });
1524
+ suspender: (instance, _options) => firstValueFrom(getPerspectiveState(instance, _options ?? {}).observable.pipe(filter(Boolean)))
1525
+ }), usePerspective = (options) => {
1526
+ const $ = c(2);
1527
+ let t0;
1528
+ $[0] !== options ? (t0 = options ?? {}, $[0] = options, $[1] = t0) : t0 = $[1];
1529
+ const normalizedOptions = useNormalizedSourceOptions(t0);
1530
+ return usePerspectiveValue(normalizedOptions);
1531
+ };
1428
1532
  function useUser(options) {
1429
- const instance = useSanityInstance(options), [isPending, startTransition] = useTransition(), key = getUsersKey(instance, options), [deferredKey, setDeferredKey] = useState(key), deferred = useMemo(() => parseUsersKey(deferredKey), [deferredKey]), [ref, setRef] = useState(new AbortController());
1533
+ const instance = useSanityInstance(options);
1534
+ trackHookUsage(instance, "useUser");
1535
+ const [isPending, startTransition] = useTransition(), key = getUsersKey(instance, options), [deferredKey, setDeferredKey] = useState(key), deferred = useMemo(() => parseUsersKey(deferredKey), [deferredKey]), [ref, setRef] = useState(new AbortController());
1430
1536
  useEffect(() => {
1431
1537
  key !== deferredKey && startTransition(() => {
1432
1538
  ref.signal.aborted || (ref.abort(), setRef(new AbortController())), setDeferredKey(key);
@@ -1447,7 +1553,9 @@ function useUser(options) {
1447
1553
  };
1448
1554
  }
1449
1555
  function useUsers(options) {
1450
- const instance = useSanityInstance(options), [isPending, startTransition] = useTransition(), key = getUsersKey(instance, options), [deferredKey, setDeferredKey] = useState(key), deferred = useMemo(() => parseUsersKey(deferredKey), [deferredKey]), [ref, setRef] = useState(new AbortController());
1556
+ const instance = useSanityInstance(options);
1557
+ trackHookUsage(instance, "useUsers");
1558
+ const [isPending, startTransition] = useTransition(), key = getUsersKey(instance, options), [deferredKey, setDeferredKey] = useState(key), deferred = useMemo(() => parseUsersKey(deferredKey), [deferredKey]), [ref, setRef] = useState(new AbortController());
1451
1559
  useEffect(() => {
1452
1560
  key !== deferredKey && startTransition(() => {
1453
1561
  ref.signal.aborted || (ref.abort(), setRef(new AbortController())), setDeferredKey(key);
@@ -1475,7 +1583,7 @@ function useUsers(options) {
1475
1583
  loadMore
1476
1584
  };
1477
1585
  }
1478
- var version = "2.7.0";
1586
+ var version = "2.9.0";
1479
1587
  function getEnv(key) {
1480
1588
  if (typeof import.meta < "u" && import.meta.env)
1481
1589
  return import.meta.env[key];
@@ -1536,6 +1644,7 @@ export {
1536
1644
  useUser,
1537
1645
  useUsers,
1538
1646
  useVerifyOrgProjects,
1539
- useWindowConnection
1647
+ useWindowConnection,
1648
+ useWindowTitle
1540
1649
  };
1541
1650
  //# sourceMappingURL=index.js.map