sanity 5.13.0 → 5.13.1-next.1

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.
@@ -1414,6 +1414,7 @@ interface DocumentStoreExtraOptions {
1414
1414
  */
1415
1415
  onSyncErrorRecovery?(error: OutOfSyncError): void;
1416
1416
  onReportLatency?: (event: LatencyReportEvent) => void;
1417
+ onSlowCommit?: () => void;
1417
1418
  }
1418
1419
  /** @internal */
1419
1420
  type ListenerEvent = MutationEvent | ReconnectEvent | InitialSnapshotEvent | PendingMutationsEvent | WelcomeEvent;
@@ -2392,7 +2393,9 @@ declare const studioLocaleStrings: {
2392
2393
  'document-status.not-published': string; /** Label to show in the document footer indicating the published date of the document */
2393
2394
  'document-status.published': string; /** Label to show in the document footer indicating the revision from date of the document */
2394
2395
  'document-status.revision-from': string; /** Label to show in the document footer indicating that the revision was not found */
2395
- 'document-status.revision-not-found': string; /** Label to indicate that a document type was not found */
2396
+ 'document-status.revision-not-found': string; /** Toast description shown when saving changes is taking longer than expected */
2397
+ 'document-store.slow-commit.description': string; /** Toast title shown when saving changes is taking longer than expected */
2398
+ 'document-store.slow-commit.title': string; /** Label to indicate that a document type was not found */
2396
2399
  'document.type.not-found': string; /** Error message shown when an action cannot be performed */
2397
2400
  'errors.unable-to-perform-action': string; /** The value of the <code>_key</code> property must be a unique string. */
2398
2401
  'form.error.duplicate-keys-alert.details.additional-description': string; /** This usually happens when items are created using an API client, and the <code>_key</code> property of each elements has been generated non-uniquely. */
@@ -1,4 +1,4 @@
1
- var version = "5.13.0", peerDependencies = {
1
+ var version = "5.13.1-next.1+60a971880c", peerDependencies = {
2
2
  "styled-components": "^6.1.15"
3
3
  };
4
4
  export {
@@ -7,7 +7,7 @@ try {
7
7
  try {
8
8
  buildVersion = buildVersion || // This is replaced by `@sanity/pkg-utils` at build time
9
9
  // and must always be references by its full static name, e.g. no optional chaining, no `if (process && process.env)` etc.
10
- "5.13.0";
10
+ "5.13.1-next.1+60a971880c";
11
11
  } catch {
12
12
  }
13
13
  const SANITY_VERSION = buildVersion || `${version}-dev`;
package/lib/index.js CHANGED
@@ -6,7 +6,7 @@ import React, { forwardRef, useRef, useState, useId, useCallback, useMemo, useIm
6
6
  import deepEquals from "react-fast-compare";
7
7
  import { WorkspacesContext, LocaleContext, MediaLibraryIdsContext, PerspectiveContext, UserColorManagerContext, ResourceCacheContext, EventsContext, WorkspaceContext, DocumentChangeContext, ReviewChangesContext, DiffContext, PresenceContext, FormBuilderContext, PortableTextMemberSchemaTypesContext, SelectedAnnotationsContext, ValidationContext, PortableTextMarkersContext, PortableTextMemberItemsContext, ChangeIndicatorTrackerContextStore, ChangeIndicatorTrackerContextGetSnapshot, FormCallbacksContext, ReferenceInputOptionsContext, DocumentIdContext, HoveredFieldContext, FieldActionsContext, FormValueContext, ReferenceItemRefContext, GetFormValueContext, EnhancedObjectDialogContext, DocumentFieldActionsContext, ArrayValidationContext, SortableItemIdContext, SourceContext, VirtualizerScrollInstanceContext, PortableTextMemberItemElementRefsContext, ScrollContext, FullscreenPTEContext, AssetLimitUpsellContext, DialogStackContext, ReleasesUpsellContext, ReleasesMetadataContext, TableContext, SearchContext, SingleDocReleaseEnabledContext, SingleDocReleaseUpsellContext, SingleDocReleaseContext, PresenceTrackerContextStore, PresenceTrackerContextGetSnapshot, FormFieldPresenceContext, ActiveWorkspaceMatcherContext, CalendarContext, AppIdCacheContext, CommentsAuthoringPathContext, CommentsIntentContext, CommentInputContext, CommentsContext, CommentsEnabledContext, CommentsOnboardingContext, CommentsSelectedPathContext, CommentsUpsellContext, AddonDatasetContext, SanityCreateConfigContext, ScheduledPublishingEnabledContext, SchedulesContext, SchedulePublishUpsellContext, DocumentActionPropsContext, TasksEnabledContext, IsLastPaneContext, MentionUserContext, TasksNavigationContext, TasksContext, TasksUpsellContext, RouterHistoryContext, ColorSchemeSetValueContext, ColorSchemeValueContext, DocumentLimitUpsellContext, NavbarContext, FreeTrialContext, LiveUserApplicationContext, PackageVersionInfoContext, StudioAnnouncementContext, CopyPasteContext, UserApplicationCacheContext, PreviewCardContext, ZIndexContext, zIndexContextDefaults } from "sanity/_singletons";
8
8
  import { SchedulesContext as SchedulesContext2 } from "sanity/_singletons";
9
- import { Badge, Grid, Box, Stack, rem, Text as Text$1, Layer, Card, Spinner, Flex, Dialog, useTheme, Button as Button$1, Skeleton, Heading, Avatar, AvatarStack, Inline, Breadcrumbs, useClickOutsideEvent, Code, MenuDivider, Menu, useElementRect, Autocomplete, useToast, useMediaIndex, useGlobalKeyDown, Checkbox as Checkbox$1, Switch as Switch$1, TextInput as TextInput$1, Select, LayerProvider, useLayer, ElementQuery, TabList, rgba, MenuItem as MenuItem$1, useBoundaryElement, BoundaryElementProvider, usePortal, PortalProvider, Portal, _responsive, useRootTheme, useArrayProp, TextArea, TextSkeleton, useElementSize, isHTMLElement, Radio, TabPanel, Container as Container$2, studioTheme, Label, AvatarCounter, ThemeColorProvider, DialogProvider, focusLastDescendant, focusFirstDescendant, VirtualList as VirtualList$1, usePrefersDark, ThemeProvider, ToastProvider } from "@sanity/ui";
9
+ import { Badge, Grid, Box, Stack, rem, Text as Text$1, Layer, Card, Spinner, Flex, Dialog, useTheme, Button as Button$1, Skeleton, Heading, useToast, Avatar, AvatarStack, Inline, Breadcrumbs, useClickOutsideEvent, Code, MenuDivider, Menu, useElementRect, Autocomplete, useMediaIndex, useGlobalKeyDown, Checkbox as Checkbox$1, Switch as Switch$1, TextInput as TextInput$1, Select, LayerProvider, useLayer, ElementQuery, TabList, rgba, MenuItem as MenuItem$1, useBoundaryElement, BoundaryElementProvider, usePortal, PortalProvider, Portal, _responsive, useRootTheme, useArrayProp, TextArea, TextSkeleton, useElementSize, isHTMLElement, Radio, TabPanel, Container as Container$2, studioTheme, Label, AvatarCounter, ThemeColorProvider, DialogProvider, focusLastDescendant, focusFirstDescendant, VirtualList as VirtualList$1, usePrefersDark, ThemeProvider, ToastProvider } from "@sanity/ui";
10
10
  import { useVirtualizer, defaultRangeExtractor, elementScroll } from "@tanstack/react-virtual";
11
11
  import throttle from "lodash-es/throttle.js";
12
12
  import { styled, css, keyframes, useTheme as useTheme$1, createGlobalStyle } from "styled-components";
@@ -1228,6 +1228,10 @@ const studioLocaleNamespace = "studio", validationLocaleNamespace = "validation"
1228
1228
  "document-status.revision-from": "Revision from <em>{{date}}</em>",
1229
1229
  /** Label to show in the document footer indicating that the revision was not found */
1230
1230
  "document-status.revision-not-found": "Revision not found",
1231
+ /** Toast description shown when saving changes is taking longer than expected */
1232
+ "document-store.slow-commit.description": "Your changes are still being saved.",
1233
+ /** Toast title shown when saving changes is taking longer than expected */
1234
+ "document-store.slow-commit.title": "Saving is taking longer than expected",
1231
1235
  /** Label to indicate that a document type was not found */
1232
1236
  "document.type.not-found": 'Document type "{{type}}" not found',
1233
1237
  /** Error message shown when an action cannot be performed */
@@ -5507,7 +5511,7 @@ function actionsApiClient(client, idPair) {
5507
5511
  function operationsApiClient(client, idPair) {
5508
5512
  return idPair.versionId ? client.withConfig(RELEASES_STUDIO_CLIENT_OPTIONS) : client;
5509
5513
  }
5510
- const FETCH_SHARD_TIMEOUT = 2e4, isMutationEventForDocId = (id2) => (event) => (event.type === "snapshot" || event.type === "mutation") && event.documentId === id2;
5514
+ const FETCH_SHARD_TIMEOUT = 2e4, SLOW_COMMIT_TIMEOUT_MS = 5e4, isMutationEventForDocId = (id2) => (event) => (event.type === "snapshot" || event.type === "mutation") && event.documentId === id2;
5511
5515
  function setVersion(version2) {
5512
5516
  return (ev) => ({
5513
5517
  ...ev,
@@ -5595,16 +5599,17 @@ function checkoutPair(client, idPair, serverActionsEnabled, options = {}) {
5595
5599
  } = idPair, {
5596
5600
  onReportLatency,
5597
5601
  onSyncErrorRecovery,
5602
+ onSlowCommit,
5598
5603
  tag
5599
5604
  } = options, listenerEvents$ = getPairListener(client, idPair, {
5600
5605
  onSyncErrorRecovery,
5601
5606
  tag
5602
- }).pipe(share()), connectionChangeEvents$ = listenerEvents$.pipe(filter((ev) => ev.type === "reconnect" || ev.type === "welcome")), draft = createBufferedDocument(draftId, listenerEvents$.pipe(filter(isMutationEventForDocId(draftId)))), version2 = typeof versionId > "u" ? void 0 : createBufferedDocument(versionId, listenerEvents$.pipe(filter(isMutationEventForDocId(versionId)))), published = createBufferedDocument(publishedId, listenerEvents$.pipe(filter(isMutationEventForDocId(publishedId)))), transactionsPendingEvents$ = listenerEvents$.pipe(filter((ev) => ev.type === "pending")), commits$ = merge(draft.commitRequest$, published.commitRequest$, version2 ? version2.commitRequest$ : EMPTY$5).pipe(mergeMap((commitRequest) => serverActionsEnabled.pipe(take$1(1), mergeMap((canUseServerActions) => submitCommitRequest(client, idPair, commitRequest, canUseServerActions))))), combinedEvents = defer(() => onReportLatency ? reportLatency({
5607
+ }).pipe(share()), connectionChangeEvents$ = listenerEvents$.pipe(filter((ev) => ev.type === "reconnect" || ev.type === "welcome")), draft = createBufferedDocument(draftId, listenerEvents$.pipe(filter(isMutationEventForDocId(draftId)))), version2 = typeof versionId > "u" ? void 0 : createBufferedDocument(versionId, listenerEvents$.pipe(filter(isMutationEventForDocId(versionId)))), published = createBufferedDocument(publishedId, listenerEvents$.pipe(filter(isMutationEventForDocId(publishedId)))), transactionsPendingEvents$ = listenerEvents$.pipe(filter((ev) => ev.type === "pending")), commitRequests$ = merge(draft.commitRequest$, published.commitRequest$, version2 ? version2.commitRequest$ : EMPTY$5).pipe(share()), commits$ = commitRequests$.pipe(mergeMap((commitRequest) => serverActionsEnabled.pipe(take$1(1), mergeMap((canUseServerActions) => submitCommitRequest(client, idPair, commitRequest, canUseServerActions)))), share()), pendingEnd$ = transactionsPendingEvents$.pipe(filter((ev) => ev.phase === "end")), commitResolved$ = merge(pendingEnd$, commits$), slowCommitWarning$ = onSlowCommit ? commitRequests$.pipe(switchMap(() => timer(SLOW_COMMIT_TIMEOUT_MS).pipe(takeUntil(commitResolved$))), tap(() => onSlowCommit())) : EMPTY$5, combinedEvents = defer(() => merge(onReportLatency ? reportLatency({
5603
5608
  commits$,
5604
5609
  listenerEvents$,
5605
5610
  client,
5606
5611
  onReportLatency
5607
- }) : merge(commits$, listenerEvents$)).pipe(mergeMap(() => EMPTY$5), share());
5612
+ }) : merge(commits$, listenerEvents$), slowCommitWarning$)).pipe(mergeMap(() => EMPTY$5), share());
5608
5613
  return {
5609
5614
  transactionsPendingEvents$,
5610
5615
  draft: {
@@ -7716,7 +7721,8 @@ function createDocumentStore({
7716
7721
  }) {
7717
7722
  const observeDocumentPairAvailability = documentPreviewStore.unstable_observeDocumentPairAvailability, client = getClient2(DEFAULT_STUDIO_CLIENT_OPTIONS), {
7718
7723
  onSyncErrorRecovery,
7719
- onReportLatency
7724
+ onReportLatency,
7725
+ onSlowCommit
7720
7726
  } = extraOptions, ctx = {
7721
7727
  client,
7722
7728
  getClient: getClient2,
@@ -7732,7 +7738,8 @@ function createDocumentStore({
7732
7738
  checkoutPair(idPair) {
7733
7739
  return checkoutPair(client, idPair, serverActionsEnabled, {
7734
7740
  onSyncErrorRecovery,
7735
- onReportLatency
7741
+ onReportLatency,
7742
+ onSlowCommit
7736
7743
  });
7737
7744
  },
7738
7745
  initialValue(opts, context) {
@@ -9758,7 +9765,9 @@ function createUserStore({
9758
9765
  getUsers: async (userIds) => (await userLoader.loadMany(userIds)).filter((result) => isRecord$4(result) && typeof result.id == "string")
9759
9766
  };
9760
9767
  }
9761
- const IGNORE_LATENCY_BELOW_MS = 1e3;
9768
+ const IGNORE_LATENCY_BELOW_MS = 1e3, SLOW_COMMIT_TOAST_COOLDOWN_MS = 3e4, slowCommitCooldown = {
9769
+ lastToastAt: 0
9770
+ };
9762
9771
  function useUserStore() {
9763
9772
  const $ = c(6), {
9764
9773
  getClient: getClient2,
@@ -9829,13 +9838,15 @@ function useDocumentPreviewStore() {
9829
9838
  }), $[0] = client, $[1] = resourceCache, $[2] = documentPreviewStore) : documentPreviewStore = $[2], documentPreviewStore;
9830
9839
  }
9831
9840
  function useDocumentStore() {
9832
- const $ = c(18), {
9841
+ const $ = c(22), {
9833
9842
  getClient: getClient2,
9834
9843
  i18n
9835
9844
  } = useSource(), schema2 = useSchema(), templates = useTemplates(), resourceCache = useResourceCache(), historyStore = useHistoryStore(), documentPreviewStore = useDocumentPreviewStore(), workspace = useWorkspace(), configFlag = workspace.__internal_serverDocumentActions?.enabled;
9836
9845
  let t0;
9837
9846
  $[0] !== configFlag ? (t0 = typeof configFlag == "boolean" ? of(configFlag) : of(!0), $[0] = configFlag, $[1] = t0) : t0 = $[1];
9838
- const serverActionsEnabled = t0, telemetry = useTelemetry();
9847
+ const serverActionsEnabled = t0, telemetry = useTelemetry(), toast = useToast(), {
9848
+ t
9849
+ } = useTranslation();
9839
9850
  let t1;
9840
9851
  $[2] !== telemetry ? (t1 = (error) => {
9841
9852
  telemetry.log(DocumentDesynced, {
@@ -9852,8 +9863,18 @@ function useDocumentStore() {
9852
9863
  });
9853
9864
  }, $[4] = telemetry, $[5] = t2) : t2 = $[5];
9854
9865
  const handleReportLatency = t2;
9866
+ let t3;
9867
+ $[6] !== t || $[7] !== toast ? (t3 = () => {
9868
+ const now = Date.now();
9869
+ now - slowCommitCooldown.lastToastAt < SLOW_COMMIT_TOAST_COOLDOWN_MS || (slowCommitCooldown.lastToastAt = now, toast.push({
9870
+ title: t("document-store.slow-commit.title"),
9871
+ description: t("document-store.slow-commit.description"),
9872
+ status: "warning"
9873
+ }));
9874
+ }, $[6] = t, $[7] = toast, $[8] = t3) : t3 = $[8];
9875
+ const handleSlowCommit = t3;
9855
9876
  let documentStore;
9856
- return $[6] !== documentPreviewStore || $[7] !== getClient2 || $[8] !== handleReportLatency || $[9] !== handleSyncErrorRecovery || $[10] !== historyStore || $[11] !== i18n || $[12] !== resourceCache || $[13] !== schema2 || $[14] !== serverActionsEnabled || $[15] !== templates || $[16] !== workspace ? (documentStore = resourceCache.get({
9877
+ return $[9] !== documentPreviewStore || $[10] !== getClient2 || $[11] !== handleReportLatency || $[12] !== handleSlowCommit || $[13] !== handleSyncErrorRecovery || $[14] !== historyStore || $[15] !== i18n || $[16] !== resourceCache || $[17] !== schema2 || $[18] !== serverActionsEnabled || $[19] !== templates || $[20] !== workspace ? (documentStore = resourceCache.get({
9857
9878
  namespace: "documentStore",
9858
9879
  dependencies: [getClient2, documentPreviewStore, historyStore, schema2, i18n, workspace]
9859
9880
  }) || createDocumentStore({
@@ -9866,13 +9887,14 @@ function useDocumentStore() {
9866
9887
  serverActionsEnabled,
9867
9888
  extraOptions: {
9868
9889
  onReportLatency: handleReportLatency,
9869
- onSyncErrorRecovery: handleSyncErrorRecovery
9890
+ onSyncErrorRecovery: handleSyncErrorRecovery,
9891
+ onSlowCommit: handleSlowCommit
9870
9892
  }
9871
9893
  }), resourceCache.set({
9872
9894
  namespace: "documentStore",
9873
9895
  dependencies: [getClient2, documentPreviewStore, historyStore, schema2, i18n, workspace],
9874
9896
  value: documentStore
9875
- }), $[6] = documentPreviewStore, $[7] = getClient2, $[8] = handleReportLatency, $[9] = handleSyncErrorRecovery, $[10] = historyStore, $[11] = i18n, $[12] = resourceCache, $[13] = schema2, $[14] = serverActionsEnabled, $[15] = templates, $[16] = workspace, $[17] = documentStore) : documentStore = $[17], documentStore;
9897
+ }), $[9] = documentPreviewStore, $[10] = getClient2, $[11] = handleReportLatency, $[12] = handleSlowCommit, $[13] = handleSyncErrorRecovery, $[14] = historyStore, $[15] = i18n, $[16] = resourceCache, $[17] = schema2, $[18] = serverActionsEnabled, $[19] = templates, $[20] = workspace, $[21] = documentStore) : documentStore = $[21], documentStore;
9876
9898
  }
9877
9899
  function useConnectionStatusStore() {
9878
9900
  const $ = c(3), {