@sanity/sdk-react 2.8.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 (35) hide show
  1. package/dist/index.d.ts +144 -25
  2. package/dist/index.js +216 -122
  3. package/dist/index.js.map +1 -1
  4. package/package.json +7 -7
  5. package/src/_exports/sdk-react.ts +1 -0
  6. package/src/components/SanityApp.tsx +1 -0
  7. package/src/context/ResourceProvider.test.tsx +7 -1
  8. package/src/context/ResourceProvider.tsx +6 -0
  9. package/src/context/SDKStudioContext.ts +6 -0
  10. package/src/hooks/dashboard/useDispatchIntent.test.ts +2 -0
  11. package/src/hooks/dashboard/useWindowTitle.test.ts +213 -0
  12. package/src/hooks/dashboard/useWindowTitle.ts +112 -0
  13. package/src/hooks/document/useApplyDocumentActions.test.ts +113 -10
  14. package/src/hooks/document/useApplyDocumentActions.ts +99 -3
  15. package/src/hooks/document/useDocument.ts +22 -6
  16. package/src/hooks/document/useDocumentEvent.test.tsx +3 -3
  17. package/src/hooks/document/useDocumentEvent.ts +10 -3
  18. package/src/hooks/document/useDocumentPermissions.test.tsx +86 -2
  19. package/src/hooks/document/useDocumentPermissions.ts +22 -0
  20. package/src/hooks/document/useDocumentSyncStatus.test.ts +13 -2
  21. package/src/hooks/document/useDocumentSyncStatus.ts +14 -5
  22. package/src/hooks/document/useEditDocument.ts +34 -8
  23. package/src/hooks/documents/useDocuments.ts +2 -0
  24. package/src/hooks/helpers/useNormalizedSourceOptions.ts +50 -28
  25. package/src/hooks/helpers/useTrackHookUsage.ts +37 -0
  26. package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +2 -0
  27. package/src/hooks/presence/usePresence.ts +2 -0
  28. package/src/hooks/preview/useDocumentPreview.test.tsx +84 -193
  29. package/src/hooks/preview/useDocumentPreview.tsx +39 -55
  30. package/src/hooks/projection/useDocumentProjection.ts +2 -0
  31. package/src/hooks/query/useQuery.ts +2 -0
  32. package/src/hooks/releases/useActiveReleases.ts +32 -13
  33. package/src/hooks/releases/usePerspective.ts +26 -14
  34. package/src/hooks/users/useUser.ts +2 -0
  35. 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) => {
@@ -413,32 +414,24 @@ function AuthSwitch(t0) {
413
414
  const SDKStudioContext = createContext(null);
414
415
  SDKStudioContext.displayName = "SDKStudioContext";
415
416
  const DEFAULT_FALLBACK = /* @__PURE__ */ jsx(Fragment, { children: "Warning: No fallback provided. Please supply a fallback prop to ensure proper Suspense handling." });
416
- function ResourceProvider(t0) {
417
- const $ = c(16);
418
- let children, config, fallback;
419
- $[0] !== t0 ? ({
420
- children,
421
- fallback,
422
- ...config
423
- } = t0, $[0] = t0, $[1] = children, $[2] = config, $[3] = fallback) : (children = $[1], config = $[2], fallback = $[3]);
424
- const parent = useContext(SanityInstanceContext);
425
- let t1, t2;
426
- $[4] !== config || $[5] !== parent ? (t2 = parent ? parent.createChild(config) : createSanityInstance(config), $[4] = config, $[5] = parent, $[6] = t2) : t2 = $[6], t1 = t2;
427
- const instance = t1, disposal = useRef(null);
428
- let t3, t4;
429
- $[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), () => {
430
428
  disposal.current = {
431
429
  instance,
432
430
  timeoutId: setTimeout(() => {
433
431
  instance.isDisposed() || instance.dispose();
434
432
  }, 0)
435
433
  };
436
- }), t4 = [instance], $[7] = instance, $[8] = t3, $[9] = t4) : (t3 = $[8], t4 = $[9]), useEffect(t3, t4);
437
- const t5 = fallback ?? DEFAULT_FALLBACK;
438
- let t6;
439
- $[10] !== children || $[11] !== t5 ? (t6 = /* @__PURE__ */ jsx(Suspense, { fallback: t5, children }), $[10] = children, $[11] = t5, $[12] = t6) : t6 = $[12];
440
- let t7;
441
- 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 }) });
442
435
  }
443
436
  const SourcesContext = createContext({});
444
437
  function SDKProvider(t0) {
@@ -478,6 +471,7 @@ function deriveConfigFromWorkspace(workspace) {
478
471
  projectId: workspace.projectId,
479
472
  dataset: workspace.dataset,
480
473
  studio: {
474
+ authenticated: workspace.authenticated,
481
475
  auth: workspace.auth.token ? {
482
476
  token: workspace.auth.token
483
477
  } : void 0
@@ -664,24 +658,27 @@ function useDashboardNavigate(navigateFn) {
664
658
  }
665
659
  }, $[0] = navigateFn, $[1] = t0) : t0 = $[1], useWindowConnection(t0);
666
660
  }
667
- function useNormalizedSourceOptions(options) {
668
- const $ = c(6);
669
- let rest, sourceName;
670
- if ($[0] !== options ? ({
661
+ function normalizeSourceOptions(options, sources) {
662
+ const {
671
663
  sourceName,
672
664
  ...rest
673
- } = 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"))
674
669
  throw new Error(`Source name ${JSON.stringify(sourceName)} and source ${JSON.stringify(options.source)} cannot be used together.`);
675
- const sources = useContext(SourcesContext);
676
670
  let resolvedSource;
677
671
  if (options.source && (resolvedSource = options.source), sourceName && !Object.hasOwn(sources, sourceName))
678
672
  throw new Error(`There's no source named ${JSON.stringify(sourceName)} in context. Please use <SourceProvider>.`);
679
- sourceName && sources[sourceName] && (resolvedSource = sources[sourceName]);
680
- let t0;
681
- return $[3] !== resolvedSource || $[4] !== rest ? (t0 = {
673
+ return sourceName && sources[sourceName] && (resolvedSource = sources[sourceName]), {
682
674
  ...rest,
683
675
  source: resolvedSource
684
- }, $[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;
685
682
  }
686
683
  function useResourceIdFromDocumentHandle(documentHandle) {
687
684
  const $ = c(3), options = useNormalizedSourceOptions(documentHandle), {
@@ -951,6 +948,50 @@ function useRecordDocumentHistoryEvent(t0) {
951
948
  recordEvent
952
949
  }, $[8] = recordEvent, $[9] = t3) : t3 = $[9], t3;
953
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
+ }
954
995
  const useDatasets = createStateSourceHook({
955
996
  getState: getDatasetsState,
956
997
  shouldSuspend: (instance, projectHandle) => (
@@ -960,18 +1001,27 @@ const useDatasets = createStateSourceHook({
960
1001
  suspender: resolveDatasets,
961
1002
  getConfig: identity
962
1003
  }), useApplyDocumentActions = () => {
963
- const $ = c(2), instance = useSanityInstance();
1004
+ const $ = c(3), instance = useSanityInstance(), sources = useContext(SourcesContext);
964
1005
  let t0;
965
- return $[0] !== instance ? (t0 = (actionOrActions, options) => {
966
- const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions];
967
- let projectId, dataset;
968
- 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) {
969
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}".`);
970
1013
  if (projectId || (projectId = action.projectId), action.projectId !== projectId)
971
1014
  throw new Error(`Mismatched project IDs found in actions. All actions must belong to the same project. Found "${action.projectId}" but expected "${projectId}".`);
972
1015
  if (action.dataset && (dataset || (dataset = action.dataset), action.dataset !== dataset))
973
1016
  throw new Error(`Mismatched datasets found in actions. All actions must belong to the same dataset. Found "${action.dataset}" but expected "${dataset}".`);
974
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
+ }
975
1025
  if (projectId || dataset) {
976
1026
  const actualInstance = instance.match({
977
1027
  projectId,
@@ -985,15 +1035,25 @@ const useDatasets = createStateSourceHook({
985
1035
  Please ensure there is a ResourceProvider component with a matching configuration in the component hierarchy.`);
986
1036
  return applyDocumentActions(actualInstance, {
987
1037
  actions,
988
- ...options
1038
+ source,
1039
+ ...normalizedOptions
989
1040
  });
990
1041
  }
991
1042
  return applyDocumentActions(instance, {
992
1043
  actions,
993
- ...options
1044
+ source,
1045
+ ...normalizedOptions
994
1046
  });
995
- }, $[0] = instance, $[1] = t0) : t0 = $[1], t0;
996
- }, 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({
997
1057
  // Pass options directly to getDocumentState
998
1058
  getState: (instance, options) => getDocumentState(instance, options),
999
1059
  // Pass options directly to getDocumentState for checking current value
@@ -1011,14 +1071,20 @@ const useDatasets = createStateSourceHook({
1011
1071
  };
1012
1072
  }
1013
1073
  return useHook;
1014
- }, useDocument = wrapHookWithData(useDocumentValue);
1074
+ }, useDocument = wrapHookWithData((options) => {
1075
+ useTrackHookUsage("useDocument");
1076
+ const normalizedOptions = useNormalizedSourceOptions(options);
1077
+ return useDocumentValue(normalizedOptions);
1078
+ });
1015
1079
  function useDocumentEvent(options) {
1016
- const $ = c(9);
1080
+ const $ = c(10);
1081
+ useTrackHookUsage("useDocumentEvent");
1082
+ const normalizedOptions = useNormalizedSourceOptions(options);
1017
1083
  let datasetHandle, onEvent;
1018
- $[0] !== options ? ({
1084
+ $[0] !== normalizedOptions ? ({
1019
1085
  onEvent,
1020
1086
  ...datasetHandle
1021
- } = options, $[0] = options, $[1] = datasetHandle, $[2] = onEvent) : (datasetHandle = $[1], onEvent = $[2]);
1087
+ } = normalizedOptions, $[0] = normalizedOptions, $[1] = datasetHandle, $[2] = onEvent) : (datasetHandle = $[1], onEvent = $[2]);
1022
1088
  const ref = useRef(onEvent);
1023
1089
  let t0;
1024
1090
  $[3] !== onEvent ? (t0 = () => {
@@ -1028,41 +1094,53 @@ function useDocumentEvent(options) {
1028
1094
  $[5] === Symbol.for("react.memo_cache_sentinel") ? (t1 = (documentEvent) => ref.current(documentEvent), $[5] = t1) : t1 = $[5];
1029
1095
  const stableHandler = t1, instance = useSanityInstance(datasetHandle);
1030
1096
  let t2, t3;
1031
- $[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);
1032
1101
  }
1033
1102
  function useDocumentPermissions(actionOrActions) {
1034
- const $ = c(13);
1103
+ const $ = c(15);
1035
1104
  let t0, t1;
1036
1105
  $[0] !== actionOrActions ? (t1 = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions], $[0] = actionOrActions, $[1] = t1) : t1 = $[1], t0 = t1;
1037
1106
  const actions = t0;
1038
- let projectId, dataset;
1039
- if ($[2] !== actions || $[3] !== dataset || $[4] !== projectId) {
1040
- 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) {
1041
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}".`);
1042
1113
  if (projectId || (projectId = action.projectId), action.projectId !== projectId)
1043
1114
  throw new Error(`Mismatched project IDs found in actions. All actions must belong to the same project. Found "${action.projectId}" but expected "${projectId}".`);
1044
1115
  if (action.dataset && (dataset || (dataset = action.dataset), action.dataset !== dataset))
1045
1116
  throw new Error(`Mismatched datasets found in actions. All actions must belong to the same dataset. Found "${action.dataset}" but expected "${dataset}".`);
1046
1117
  }
1047
- $[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;
1048
1126
  } else
1049
- projectId = $[5], dataset = $[6];
1127
+ projectId = $[6], dataset = $[7], source = $[8];
1050
1128
  let t2;
1051
- $[7] !== dataset || $[8] !== projectId ? (t2 = {
1129
+ $[9] !== dataset || $[10] !== projectId ? (t2 = {
1052
1130
  projectId,
1053
1131
  dataset
1054
- }, $[7] = dataset, $[8] = projectId, $[9] = t2) : t2 = $[9];
1132
+ }, $[9] = dataset, $[10] = projectId, $[11] = t2) : t2 = $[11];
1055
1133
  const instance = useSanityInstance(t2);
1056
- if (getPermissionsState(instance, {
1134
+ if (trackHookUsage(instance, "useDocumentPermissions"), getPermissionsState(instance, {
1057
1135
  actions
1058
1136
  }).getCurrent() === void 0)
1059
1137
  throw firstValueFrom(getPermissionsState(instance, {
1060
1138
  actions
1061
1139
  }).observable.pipe(filter(_temp$2)));
1062
1140
  let t3, t4;
1063
- $[10] !== actions || $[11] !== instance ? (t4 = getPermissionsState(instance, {
1141
+ $[12] !== actions || $[13] !== instance ? (t4 = getPermissionsState(instance, {
1064
1142
  actions
1065
- }), $[10] = actions, $[11] = instance, $[12] = t4) : t4 = $[12], t3 = t4;
1143
+ }), $[12] = actions, $[13] = instance, $[14] = t4) : t4 = $[14], t3 = t4;
1066
1144
  const {
1067
1145
  subscribe,
1068
1146
  getCurrent
@@ -1072,12 +1150,15 @@ function useDocumentPermissions(actionOrActions) {
1072
1150
  function _temp$2(result) {
1073
1151
  return result !== void 0;
1074
1152
  }
1075
- const useDocumentSyncStatus = createStateSourceHook({
1153
+ const useDocumentSyncStatusValue = createStateSourceHook({
1076
1154
  getState: getDocumentSyncStatus,
1077
1155
  shouldSuspend: (instance, doc) => getDocumentSyncStatus(instance, doc).getCurrent() === void 0,
1078
1156
  suspender: (instance, doc) => resolveDocument(instance, doc),
1079
1157
  getConfig: identity
1080
- }), 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"];
1081
1162
  function useEditDocument(t0) {
1082
1163
  const $ = c(8);
1083
1164
  let doc, path;
@@ -1085,25 +1166,27 @@ function useEditDocument(t0) {
1085
1166
  path,
1086
1167
  ...doc
1087
1168
  } = t0, $[0] = t0, $[1] = doc, $[2] = path) : (doc = $[1], path = $[2]);
1088
- const instance = useSanityInstance(doc), apply = useApplyDocumentActions();
1089
- if (getDocumentState(instance, doc).getCurrent() === void 0)
1090
- 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);
1091
1174
  let t1;
1092
- return $[3] !== apply || $[4] !== doc || $[5] !== instance || $[6] !== path ? (t1 = (updater) => {
1175
+ return $[3] !== apply || $[4] !== instance || $[5] !== normalizedDoc || $[6] !== path ? (t1 = (updater) => {
1093
1176
  const currentPath = path;
1094
1177
  if (currentPath) {
1095
1178
  const currentValue = getDocumentState(instance, {
1096
- ...doc,
1179
+ ...normalizedDoc,
1097
1180
  path
1098
1181
  }).getCurrent(), nextValue = typeof updater == "function" ? updater(currentValue) : updater;
1099
- return apply(editDocument(doc, {
1182
+ return apply(editDocument(normalizedDoc, {
1100
1183
  set: {
1101
1184
  [currentPath]: nextValue
1102
1185
  }
1103
1186
  }));
1104
1187
  }
1105
1188
  const current = getDocumentState(instance, {
1106
- ...doc,
1189
+ ...normalizedDoc,
1107
1190
  path
1108
1191
  }).getCurrent(), nextValue_0 = typeof updater == "function" ? updater(current) : updater;
1109
1192
  if (typeof nextValue_0 != "object" || !nextValue_0)
@@ -1111,21 +1194,23 @@ function useEditDocument(t0) {
1111
1194
  const editActions = Object.keys({
1112
1195
  ...current,
1113
1196
  ...nextValue_0
1114
- }).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, {
1115
1198
  set: {
1116
1199
  [key_1]: nextValue_0[key_1]
1117
1200
  }
1118
- }) : editDocument(doc, {
1201
+ }) : editDocument(normalizedDoc, {
1119
1202
  unset: [key_1]
1120
1203
  }));
1121
1204
  return apply(editActions);
1122
- }, $[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;
1123
1206
  }
1124
1207
  function _temp$1(key) {
1125
1208
  return !ignoredKeys.includes(key);
1126
1209
  }
1127
1210
  function useQuery(options) {
1128
- 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());
1129
1214
  useEffect(() => {
1130
1215
  queryKey !== deferredQueryKey && startTransition(() => {
1131
1216
  ref && !ref.current.signal.aborted && (ref.current.abort(), ref.current = new AbortController()), setDeferredQueryKey(queryKey);
@@ -1161,6 +1246,7 @@ function useDocuments({
1161
1246
  documentType,
1162
1247
  ...options
1163
1248
  }) {
1249
+ useTrackHookUsage("useDocuments");
1164
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({
1165
1251
  filter: filter2,
1166
1252
  search,
@@ -1223,7 +1309,9 @@ function usePaginatedDocuments(t0) {
1223
1309
  const filter2 = t1 === void 0 ? "" : t1, pageSize = t2 === void 0 ? 25 : t2;
1224
1310
  let t4;
1225
1311
  $[8] !== t3 ? (t4 = t3 === void 0 ? {} : t3, $[8] = t3, $[9] = t4) : t4 = $[9];
1226
- 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);
1227
1315
  let t5;
1228
1316
  $[10] !== filter2 || $[11] !== orderings || $[12] !== pageSize || $[13] !== params || $[14] !== search ? (t5 = JSON.stringify({
1229
1317
  filter: filter2,
@@ -1333,6 +1421,7 @@ function _temp(i) {
1333
1421
  }
1334
1422
  function usePresence() {
1335
1423
  const $ = c(11), sanityInstance = useSanityInstance();
1424
+ trackHookUsage(sanityInstance, "usePresence");
1336
1425
  let t0, t1;
1337
1426
  $[0] !== sanityInstance ? (t1 = getPresence(sanityInstance), $[0] = sanityInstance, $[1] = t1) : t1 = $[1], t0 = t1;
1338
1427
  const source = t0;
@@ -1349,52 +1438,14 @@ function usePresence() {
1349
1438
  locations: t5
1350
1439
  }, $[9] = t5, $[10] = t6) : t6 = $[10], t6;
1351
1440
  }
1352
- function useDocumentPreview(t0) {
1353
- const $ = c(13);
1354
- let docHandle, ref;
1355
- $[0] !== t0 ? ({
1356
- ref,
1357
- ...docHandle
1358
- } = t0, $[0] = t0, $[1] = docHandle, $[2] = ref) : (docHandle = $[1], ref = $[2]);
1359
- const instance = useSanityInstance(docHandle);
1360
- let t1;
1361
- $[3] !== docHandle || $[4] !== instance ? (t1 = getPreviewState(instance, docHandle), $[3] = docHandle, $[4] = instance, $[5] = t1) : t1 = $[5];
1362
- const stateSource = t1;
1363
- let t2;
1364
- $[6] !== ref || $[7] !== stateSource ? (t2 = (onStoreChanged) => {
1365
- const subscription = new Observable((observer) => {
1366
- if (typeof IntersectionObserver > "u" || typeof HTMLElement > "u") {
1367
- observer.next(!0);
1368
- return;
1369
- }
1370
- const intersectionObserver = new IntersectionObserver((t32) => {
1371
- const [entry] = t32;
1372
- return observer.next(entry.isIntersecting);
1373
- }, {
1374
- rootMargin: "0px",
1375
- threshold: 0
1376
- });
1377
- return ref?.current && ref.current instanceof HTMLElement ? intersectionObserver.observe(ref.current) : observer.next(!0), () => intersectionObserver.disconnect();
1378
- }).pipe(startWith(!1), distinctUntilChanged(), switchMap((isVisible) => isVisible ? new Observable((obs) => stateSource.subscribe(() => obs.next())) : EMPTY)).subscribe({
1379
- next: onStoreChanged
1380
- });
1381
- return () => subscription.unsubscribe();
1382
- }, $[6] = ref, $[7] = stateSource, $[8] = t2) : t2 = $[8];
1383
- const subscribe = t2;
1384
- let t3;
1385
- return $[9] !== docHandle || $[10] !== instance || $[11] !== stateSource ? (t3 = () => {
1386
- const currentState = stateSource.getCurrent();
1387
- if (currentState.data === null)
1388
- throw resolvePreview(instance, docHandle);
1389
- return currentState;
1390
- }, $[9] = docHandle, $[10] = instance, $[11] = stateSource, $[12] = t3) : t3 = $[12], useSyncExternalStore(subscribe, t3);
1391
- }
1392
1441
  function useDocumentProjection({
1393
1442
  ref,
1394
1443
  projection,
1395
1444
  ...docHandle
1396
1445
  }) {
1397
- 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, {
1398
1449
  ...normalizedDocHandle,
1399
1450
  projection: normalizedProjection
1400
1451
  }), [instance, normalizedDocHandle, normalizedProjection]);
@@ -1421,6 +1472,32 @@ function useDocumentProjection({
1421
1472
  }, [stateSource, ref]);
1422
1473
  return useSyncExternalStore(subscribe, stateSource.getCurrent);
1423
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
+ }
1424
1501
  const useProject = createStateSourceHook({
1425
1502
  // remove `undefined` since we're suspending when that is the case
1426
1503
  getState: getProjectState,
@@ -1431,17 +1508,31 @@ const useProject = createStateSourceHook({
1431
1508
  getState: getProjectsState,
1432
1509
  shouldSuspend: (instance, options) => getProjectsState(instance, options).getCurrent() === void 0,
1433
1510
  suspender: resolveProjects
1434
- }), useActiveReleases = createStateSourceHook({
1511
+ }), useActiveReleasesValue = createStateSourceHook({
1435
1512
  getState: getActiveReleasesState,
1436
- shouldSuspend: (instance) => getActiveReleasesState(instance).getCurrent() === void 0,
1437
- suspender: (instance) => firstValueFrom(getActiveReleasesState(instance).observable.pipe(filter(Boolean)))
1438
- }), 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({
1439
1522
  getState: getPerspectiveState,
1440
1523
  shouldSuspend: (instance, options) => getPerspectiveState(instance, options).getCurrent() === void 0,
1441
- suspender: (instance, _options) => firstValueFrom(getActiveReleasesState(instance).observable.pipe(filter(Boolean)))
1442
- });
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
+ };
1443
1532
  function useUser(options) {
1444
- 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());
1445
1536
  useEffect(() => {
1446
1537
  key !== deferredKey && startTransition(() => {
1447
1538
  ref.signal.aborted || (ref.abort(), setRef(new AbortController())), setDeferredKey(key);
@@ -1462,7 +1553,9 @@ function useUser(options) {
1462
1553
  };
1463
1554
  }
1464
1555
  function useUsers(options) {
1465
- 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());
1466
1559
  useEffect(() => {
1467
1560
  key !== deferredKey && startTransition(() => {
1468
1561
  ref.signal.aborted || (ref.abort(), setRef(new AbortController())), setDeferredKey(key);
@@ -1490,7 +1583,7 @@ function useUsers(options) {
1490
1583
  loadMore
1491
1584
  };
1492
1585
  }
1493
- var version = "2.8.0";
1586
+ var version = "2.9.0";
1494
1587
  function getEnv(key) {
1495
1588
  if (typeof import.meta < "u" && import.meta.env)
1496
1589
  return import.meta.env[key];
@@ -1551,6 +1644,7 @@ export {
1551
1644
  useUser,
1552
1645
  useUsers,
1553
1646
  useVerifyOrgProjects,
1554
- useWindowConnection
1647
+ useWindowConnection,
1648
+ useWindowTitle
1555
1649
  };
1556
1650
  //# sourceMappingURL=index.js.map