@sanity/sdk-react 2.12.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -41,6 +41,7 @@ import {QueryOptions} from '@sanity/sdk'
41
41
  import {default as React_2} from 'react'
42
42
  import {ReactElement} from 'react'
43
43
  import {ReactNode} from 'react'
44
+ import {ReleaseAction} from '@sanity/sdk'
44
45
  import {ReleaseDocument} from '@sanity/sdk'
45
46
  import {SanityClient} from '@sanity/client'
46
47
  import {SanityConfig} from '@sanity/sdk'
@@ -1594,6 +1595,82 @@ declare interface UseApplyDocumentActions {
1594
1595
  */
1595
1596
  export declare const useApplyDocumentActions: UseApplyDocumentActions
1596
1597
 
1598
+ /**
1599
+ * @public
1600
+ */
1601
+ declare interface UseApplyReleaseActions {
1602
+ (): (action: ReleaseAction | ReleaseAction[], options?: ResourceHandle) => Promise<ActionsResult>
1603
+ }
1604
+
1605
+ /**
1606
+ * @public
1607
+ *
1608
+ * Provides a stable callback function for applying one or more release actions.
1609
+ *
1610
+ * This hook wraps the core `applyDocumentActions` functionality from `@sanity/sdk`,
1611
+ * integrating it with the React component lifecycle and {@link SanityInstance}.
1612
+ * It accepts release-lifecycle actions generated by {@link createRelease},
1613
+ * {@link editRelease}, {@link publishRelease}, {@link scheduleRelease},
1614
+ * {@link unscheduleRelease}, {@link archiveRelease}, {@link unarchiveRelease},
1615
+ * and {@link deleteRelease}.
1616
+ *
1617
+ * Note that actions submitted via this hook will cascade to the documents in the release.
1618
+ * For example, if you create a release and then publish it, the documents in the release will be published.
1619
+ * If you delete a published release, the version documents will be deleted.
1620
+ *
1621
+ * Features:
1622
+ * - Applies one or multiple `ReleaseAction` objects.
1623
+ * - Supports optimistic updates for create/edit/delete: local release state
1624
+ * reflects changes immediately while in-flight.
1625
+ * - Handles batching: multiple actions passed together are submitted as a
1626
+ * single atomic transaction.
1627
+ *
1628
+ * Release actions cannot be combined with `liveEdit` document actions in the
1629
+ * same transaction. Submit them as separate transactions if you need both.
1630
+ *
1631
+ * @category Releases
1632
+ * @returns A stable callback. When called with a single `ReleaseAction` or an
1633
+ * array of `ReleaseAction`s, it returns a promise that resolves to an
1634
+ * {@link ActionsResult}.
1635
+ *
1636
+ * @example Create and schedule a release
1637
+ * ```tsx
1638
+ * import {
1639
+ * createRelease,
1640
+ * scheduleRelease,
1641
+ * useApplyReleaseActions,
1642
+ * type ReleaseHandle,
1643
+ * } from '@sanity/sdk-react'
1644
+ *
1645
+ * function ScheduleReleaseButton({release}: {release: ReleaseHandle}) {
1646
+ * const applyRelease = useApplyReleaseActions()
1647
+ *
1648
+ * const handleSchedule = () =>
1649
+ * applyRelease([
1650
+ * createRelease(release, {title: 'Summer drop', releaseType: 'asap'}),
1651
+ * scheduleRelease(release, '2026-06-01T00:00:00Z'),
1652
+ * ])
1653
+ *
1654
+ * return <button onClick={handleSchedule}>Schedule</button>
1655
+ * }
1656
+ * ```
1657
+ *
1658
+ * @example Publish a release
1659
+ * ```tsx
1660
+ * import {publishRelease, useApplyReleaseActions} from '@sanity/sdk-react'
1661
+ *
1662
+ * function PublishButton({releaseId}: {releaseId: string}) {
1663
+ * const applyRelease = useApplyReleaseActions()
1664
+ * return (
1665
+ * <button onClick={() => applyRelease(publishRelease({releaseId}))}>
1666
+ * Publish all documents in the release
1667
+ * </button>
1668
+ * )
1669
+ * }
1670
+ * ```
1671
+ */
1672
+ export declare const useApplyReleaseActions: UseApplyReleaseActions
1673
+
1597
1674
  /**
1598
1675
  * @internal
1599
1676
  * A React hook that subscribes to authentication state changes.
package/dist/index.js CHANGED
@@ -53,7 +53,7 @@ function useWindowConnection(t0) {
53
53
  node
54
54
  } = useNodeState(t1);
55
55
  let t2;
56
- $[3] === Symbol.for("react.memo_cache_sentinel") ? (t2 = [], $[3] = t2) : t2 = $[3];
56
+ $[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = [], $[3] = t2) : t2 = $[3];
57
57
  const messageUnsubscribers = useRef(t2), instance = useSanityInstance();
58
58
  let t3;
59
59
  $[4] !== node || $[5] !== onMessage ? (t3 = () => (onMessage && Object.entries(onMessage).forEach((t42) => {
@@ -87,12 +87,12 @@ function DashboardTokenRefresh(t0) {
87
87
  children
88
88
  } = t0, instance = useSanityInstance(), isTokenRefreshInProgress = useRef(!1), timeoutRef = useRef(null), processed401ErrorRef = useRef(null), authState = useAuthState();
89
89
  let t1;
90
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => {
90
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = () => {
91
91
  timeoutRef.current && (clearTimeout(timeoutRef.current), timeoutRef.current = null);
92
92
  }, $[0] = t1) : t1 = $[0];
93
93
  const clearRefreshTimeout = t1;
94
94
  let t2;
95
- $[1] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
95
+ $[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = {
96
96
  name: SDK_NODE_NAME,
97
97
  connectTo: SDK_CHANNEL_NAME
98
98
  }, $[1] = t2) : t2 = $[1];
@@ -118,7 +118,7 @@ function DashboardTokenRefresh(t0) {
118
118
  }, $[2] = instance, $[3] = windowConnection, $[4] = t3) : t3 = $[4];
119
119
  const requestNewToken = t3;
120
120
  let t4, t5;
121
- $[5] === Symbol.for("react.memo_cache_sentinel") ? (t4 = () => () => {
121
+ $[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t4 = () => () => {
122
122
  clearRefreshTimeout();
123
123
  }, t5 = [clearRefreshTimeout], $[5] = t4, $[6] = t5) : (t4 = $[5], t5 = $[6]), useEffect(t4, t5);
124
124
  let t6;
@@ -256,15 +256,15 @@ function reload() {
256
256
  function ChunkLoadError(_props) {
257
257
  const $ = c(4);
258
258
  let t0;
259
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = readChunkReloadFlag(), $[0] = t0) : t0 = $[0];
259
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = readChunkReloadFlag(), $[0] = t0) : t0 = $[0];
260
260
  const alreadyAttempted = t0;
261
261
  let t1, t2;
262
- if ($[1] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => {
262
+ if ($[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = () => {
263
263
  alreadyAttempted || (setChunkReloadFlag(), reload());
264
264
  }, t2 = [alreadyAttempted], $[1] = t1, $[2] = t2) : (t1 = $[1], t2 = $[2]), useEffect(t1, t2), !alreadyAttempted)
265
265
  return null;
266
266
  let t3;
267
- return $[3] === Symbol.for("react.memo_cache_sentinel") ? (t3 = /* @__PURE__ */ jsx(Error$1, { heading: "A new version is available", description: "The page tried to load an asset that no longer exists. Reload to continue with the latest version.", cta: {
267
+ return $[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t3 = /* @__PURE__ */ jsx(Error$1, { heading: "A new version is available", description: "The page tried to load an asset that no longer exists. Reload to continue with the latest version.", cta: {
268
268
  text: "Reload page",
269
269
  onClick: _temp$6
270
270
  } }), $[3] = t3) : t3 = $[3], t3;
@@ -342,7 +342,7 @@ function DashboardAccessRequest(t0) {
342
342
  projectId
343
343
  } = t0;
344
344
  let t1;
345
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = {
345
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = {
346
346
  name: SDK_NODE_NAME,
347
347
  connectTo: SDK_CHANNEL_NAME
348
348
  }, $[0] = t1) : t1 = $[0];
@@ -557,7 +557,7 @@ const ResourcesContext = createContext({});
557
557
  function ResetChunkReloadFlagOnMount() {
558
558
  const $ = c(1);
559
559
  let t0;
560
- return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = [], $[0] = t0) : t0 = $[0], useEffect(_temp$4, t0), null;
560
+ return $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = [], $[0] = t0) : t0 = $[0], useEffect(_temp$4, t0), null;
561
561
  }
562
562
  function _temp$4() {
563
563
  clearChunkReloadFlag();
@@ -599,7 +599,7 @@ function SDKProvider(t0) {
599
599
  }
600
600
  const resourcesValue = t3;
601
601
  let t4;
602
- $[17] === Symbol.for("react.memo_cache_sentinel") ? (t4 = /* @__PURE__ */ jsx(ResetChunkReloadFlagOnMount, {}), $[17] = t4) : t4 = $[17];
602
+ $[17] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t4 = /* @__PURE__ */ jsx(ResetChunkReloadFlagOnMount, {}), $[17] = t4) : t4 = $[17];
603
603
  let t5;
604
604
  $[18] !== children || $[19] !== resourcesValue ? (t5 = /* @__PURE__ */ jsx(ResourcesContext.Provider, { value: resourcesValue, children }), $[18] = children, $[19] = resourcesValue, $[20] = t5) : t5 = $[20];
605
605
  let t6;
@@ -659,7 +659,7 @@ function SanityApp(t0) {
659
659
  break bb0;
660
660
  }
661
661
  let t22;
662
- $[7] === Symbol.for("react.memo_cache_sentinel") ? (t22 = [], $[7] = t22) : t22 = $[7], t1 = t22;
662
+ $[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t22 = [], $[7] = t22) : t22 = $[7], t1 = t22;
663
663
  }
664
664
  const resolvedConfig = t1;
665
665
  let t2, t3;
@@ -804,7 +804,7 @@ function useAgentResourceContext(options) {
804
804
  documentId
805
805
  } = options;
806
806
  let t0;
807
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
807
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = {
808
808
  name: SDK_NODE_NAME,
809
809
  connectTo: SDK_CHANNEL_NAME
810
810
  }, $[0] = t0) : t0 = $[0];
@@ -889,7 +889,7 @@ function useFrameConnection(options) {
889
889
  };
890
890
  }, t1 = [targetOrigin, name, connectTo, heartbeat, onMessage, instance, onStatus], $[0] = connectTo, $[1] = heartbeat, $[2] = instance, $[3] = name, $[4] = onMessage, $[5] = onStatus, $[6] = targetOrigin, $[7] = t0, $[8] = t1) : (t0 = $[7], t1 = $[8]), useEffect(t0, t1);
891
891
  let t2;
892
- $[9] === Symbol.for("react.memo_cache_sentinel") ? (t2 = (frameWindow) => {
892
+ $[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = (frameWindow) => {
893
893
  const removeTarget = controllerRef.current?.addTarget(frameWindow);
894
894
  return () => {
895
895
  removeTarget?.();
@@ -897,12 +897,12 @@ function useFrameConnection(options) {
897
897
  }, $[9] = t2) : t2 = $[9];
898
898
  const connect = t2;
899
899
  let t3;
900
- $[10] === Symbol.for("react.memo_cache_sentinel") ? (t3 = (type_0, data) => {
900
+ $[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t3 = (type_0, data) => {
901
901
  channelRef.current?.post(type_0, data);
902
902
  }, $[10] = t3) : t3 = $[10];
903
903
  const sendMessage = t3;
904
904
  let t4;
905
- return $[11] === Symbol.for("react.memo_cache_sentinel") ? (t4 = {
905
+ return $[11] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t4 = {
906
906
  connect,
907
907
  sendMessage
908
908
  }, $[11] = t4) : t4 = $[11], t4;
@@ -1047,10 +1047,10 @@ function useManageFavorite({
1047
1047
  function useStudioWorkspacesByProjectIdDataset() {
1048
1048
  const $ = c(8);
1049
1049
  let t0;
1050
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {}, $[0] = t0) : t0 = $[0];
1050
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = {}, $[0] = t0) : t0 = $[0];
1051
1051
  const [workspacesByProjectIdAndDataset, setWorkspacesByProjectIdAndDataset] = useState(t0), [error, setError] = useState(null);
1052
1052
  let t1;
1053
- $[1] === Symbol.for("react.memo_cache_sentinel") ? (t1 = {
1053
+ $[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = {
1054
1054
  name: SDK_NODE_NAME,
1055
1055
  connectTo: SDK_CHANNEL_NAME
1056
1056
  }, $[1] = t1) : t1 = $[1];
@@ -1100,7 +1100,7 @@ function useNavigateToStudioDocument(documentHandle, preferredStudioUrl) {
1100
1100
  workspacesByProjectIdAndDataset
1101
1101
  } = useStudioWorkspacesByProjectIdDataset();
1102
1102
  let t0;
1103
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
1103
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = {
1104
1104
  name: SDK_NODE_NAME,
1105
1105
  connectTo: SDK_CHANNEL_NAME
1106
1106
  }, $[0] = t0) : t0 = $[0];
@@ -1153,7 +1153,7 @@ function useRecordDocumentHistoryEvent(t0) {
1153
1153
  schemaName
1154
1154
  } = t0;
1155
1155
  let t1;
1156
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = {
1156
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = {
1157
1157
  name: SDK_NODE_NAME,
1158
1158
  connectTo: SDK_CHANNEL_NAME
1159
1159
  }, $[0] = t1) : t1 = $[0];
@@ -1198,7 +1198,7 @@ function resolveAppTitle(resource) {
1198
1198
  function useWindowTitle(viewTitle) {
1199
1199
  const $ = c(8), [appTitle, setAppTitle] = useState(null);
1200
1200
  let t0;
1201
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
1201
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = {
1202
1202
  name: SDK_NODE_NAME,
1203
1203
  connectTo: SDK_CHANNEL_NAME
1204
1204
  }, $[0] = t0) : t0 = $[0];
@@ -1244,15 +1244,18 @@ const useDatasets = createStateSourceHook({
1244
1244
  ),
1245
1245
  suspender: resolveDatasets,
1246
1246
  getConfig: identity
1247
- }), useApplyDocumentActions = () => {
1247
+ });
1248
+ function useApplyActions() {
1248
1249
  const $ = c(4), instance = useSanityInstance(), resources = useContext(ResourcesContext), effectiveContextResource = useEffectiveContextResource();
1249
1250
  let t0;
1250
1251
  return $[0] !== effectiveContextResource || $[1] !== instance || $[2] !== resources ? (t0 = (actionOrActions, options) => {
1251
1252
  const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions], optionsResource = options ? normalizeResourceOptions(options, resources, effectiveContextResource).resource : void 0, normalizedActions = actions.map((action) => normalizeResourceOptions(action, resources, effectiveContextResource));
1252
1253
  let resource;
1253
- for (const action_0 of normalizedActions)
1254
- if (!resource && action_0.resource && (resource = action_0.resource), !isDeepEqual(action_0.resource, resource))
1255
- throw new Error(`Mismatched resources found in actions. All actions must belong to the same resource. Found "${JSON.stringify(action_0.resource)}" but expected "${JSON.stringify(resource)}".`);
1254
+ for (const action_0 of normalizedActions) {
1255
+ const actionResource = action_0.resource;
1256
+ if (!resource && actionResource && (resource = actionResource), !isDeepEqual(actionResource, resource))
1257
+ throw new Error(`Mismatched resources found in actions. All actions must belong to the same resource. Found "${JSON.stringify(actionResource)}" but expected "${JSON.stringify(resource)}".`);
1258
+ }
1256
1259
  if (optionsResource && resource && !isDeepEqual(optionsResource, resource))
1257
1260
  throw new Error(`Mismatched resources found in actions. Found top-level resource "${JSON.stringify(optionsResource)}" but expected resource from action handles "${JSON.stringify(resource)}".`);
1258
1261
  const effectiveResource = resource ?? optionsResource ?? effectiveContextResource;
@@ -1263,7 +1266,8 @@ const useDatasets = createStateSourceHook({
1263
1266
  resource: effectiveResource
1264
1267
  });
1265
1268
  }, $[0] = effectiveContextResource, $[1] = instance, $[2] = resources, $[3] = t0) : t0 = $[3], t0;
1266
- };
1269
+ }
1270
+ const useApplyDocumentActions = () => useApplyActions();
1267
1271
  function useTrackHookUsage(hookName) {
1268
1272
  const instance = useSanityInstance(), tracked = useRef(null);
1269
1273
  tracked.current === null && (tracked.current = !0, trackHookMounted(instance, hookName));
@@ -1309,7 +1313,7 @@ function useDocumentEvent(options) {
1309
1313
  ref.current = onEvent;
1310
1314
  }, $[3] = onEvent, $[4] = t0) : t0 = $[4], useInsertionEffect(t0);
1311
1315
  let t1;
1312
- $[5] === Symbol.for("react.memo_cache_sentinel") ? (t1 = (documentEvent) => ref.current(documentEvent), $[5] = t1) : t1 = $[5];
1316
+ $[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = (documentEvent) => ref.current(documentEvent), $[5] = t1) : t1 = $[5];
1313
1317
  const stableHandler = t1, instance = useSanityInstance();
1314
1318
  let t2, t3;
1315
1319
  $[6] !== datasetHandle.resource || $[7] !== instance ? (t2 = () => subscribeDocumentEvents(instance, {
@@ -1580,10 +1584,10 @@ function usePaginatedDocuments(t0) {
1580
1584
  count
1581
1585
  } = t15, totalPages = Math.ceil(count / pageSize), currentPage = pageIndex + 1;
1582
1586
  let t16;
1583
- $[36] === Symbol.for("react.memo_cache_sentinel") ? (t16 = () => setPageIndex(0), $[36] = t16) : t16 = $[36];
1587
+ $[36] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t16 = () => setPageIndex(0), $[36] = t16) : t16 = $[36];
1584
1588
  const firstPage = t16;
1585
1589
  let t17;
1586
- $[37] === Symbol.for("react.memo_cache_sentinel") ? (t17 = () => setPageIndex(_temp4), $[37] = t17) : t17 = $[37];
1590
+ $[37] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t17 = () => setPageIndex(_temp4), $[37] = t17) : t17 = $[37];
1587
1591
  const previousPage = t17;
1588
1592
  let t18;
1589
1593
  $[38] !== totalPages ? (t18 = () => setPageIndex((prev_0) => Math.min(prev_0 + 1, totalPages - 1)), $[38] = totalPages, $[39] = t18) : t18 = $[39];
@@ -1681,7 +1685,7 @@ function useDocumentProjection({
1681
1685
  threshold: 0
1682
1686
  });
1683
1687
  return ref?.current && ref.current instanceof HTMLElement ? intersectionObserver.observe(ref.current) : observer.next(!0), () => intersectionObserver.disconnect();
1684
- }).pipe(startWith(!1), distinctUntilChanged(), switchMap((isVisible) => isVisible ? new Observable((obs) => stateSource.subscribe(() => obs.next())) : EMPTY)).subscribe({
1688
+ }).pipe(startWith(!1), distinctUntilChanged(), switchMap((isVisible) => isVisible ? new Observable((obs) => (obs.next(), stateSource.subscribe(() => obs.next()))) : EMPTY)).subscribe({
1685
1689
  next: onStoreChanged
1686
1690
  });
1687
1691
  return () => subscription.unsubscribe();
@@ -1747,7 +1751,7 @@ function useAllReleases(options) {
1747
1751
  const normalizedOptions = useNormalizedResourceOptions(t0);
1748
1752
  return useAllReleasesValue(normalizedOptions);
1749
1753
  }
1750
- const usePerspectiveValue = createStateSourceHook({
1754
+ const useApplyReleaseActions = () => useApplyActions(), usePerspectiveValue = createStateSourceHook({
1751
1755
  getState: getPerspectiveState,
1752
1756
  shouldSuspend: (instance, options) => getPerspectiveState(instance, options).getCurrent() === void 0,
1753
1757
  suspender: (instance, _options) => firstValueFrom(getPerspectiveState(instance, _options ?? {}).observable.pipe(filter(Boolean)))
@@ -1813,7 +1817,7 @@ function useUsers(options) {
1813
1817
  loadMore
1814
1818
  };
1815
1819
  }
1816
- var version = "2.12.0";
1820
+ var version = "2.14.0";
1817
1821
  function getEnv(key) {
1818
1822
  if (typeof import.meta < "u" && import.meta.env)
1819
1823
  return import.meta.env[key];
@@ -1842,6 +1846,7 @@ export {
1842
1846
  useAgentTranslate,
1843
1847
  useAllReleases,
1844
1848
  useApplyDocumentActions,
1849
+ useApplyReleaseActions,
1845
1850
  useAuthState,
1846
1851
  useAuthToken,
1847
1852
  useClient,