sanity 3.83.1-canary.23 → 3.84.1-next.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 (63) hide show
  1. package/lib/_chunks-cjs/PostMessageSchema.js.map +1 -1
  2. package/lib/_chunks-cjs/PostMessageTelemetry.js +1 -1
  3. package/lib/_chunks-cjs/PostMessageTelemetry.js.map +1 -1
  4. package/lib/_chunks-cjs/PresentationToolGrantsCheck.js +429 -1417
  5. package/lib/_chunks-cjs/PresentationToolGrantsCheck.js.map +1 -1
  6. package/lib/_chunks-cjs/presentation.js +70 -22
  7. package/lib/_chunks-cjs/presentation.js.map +1 -1
  8. package/lib/_chunks-cjs/resources6.js +0 -8
  9. package/lib/_chunks-cjs/resources6.js.map +1 -1
  10. package/lib/_chunks-cjs/version.js +1 -1
  11. package/lib/_chunks-es/PostMessageSchema.mjs.map +1 -1
  12. package/lib/_chunks-es/PostMessageTelemetry.mjs +1 -1
  13. package/lib/_chunks-es/PostMessageTelemetry.mjs.map +1 -1
  14. package/lib/_chunks-es/PresentationToolGrantsCheck.mjs +437 -1406
  15. package/lib/_chunks-es/PresentationToolGrantsCheck.mjs.map +1 -1
  16. package/lib/_chunks-es/presentation.mjs +73 -24
  17. package/lib/_chunks-es/presentation.mjs.map +1 -1
  18. package/lib/_chunks-es/resources6.mjs +0 -8
  19. package/lib/_chunks-es/resources6.mjs.map +1 -1
  20. package/lib/_chunks-es/version.mjs +1 -1
  21. package/lib/_singletons.d.mts +61 -2889
  22. package/lib/_singletons.d.ts +61 -2889
  23. package/lib/presentation.d.mts +57 -2887
  24. package/lib/presentation.d.ts +57 -2887
  25. package/lib/presentation.js +4 -0
  26. package/lib/presentation.js.map +1 -1
  27. package/lib/presentation.mjs +5 -1
  28. package/package.json +15 -16
  29. package/src/presentation/PostMessageTelemetry.tsx +1 -1
  30. package/src/presentation/PresentationTool.tsx +76 -85
  31. package/src/presentation/PresentationToolGrantsCheck.tsx +75 -39
  32. package/src/presentation/document/LocationsBanner.tsx +13 -52
  33. package/src/presentation/i18n/resources.ts +0 -10
  34. package/src/presentation/index.ts +13 -0
  35. package/src/presentation/{util → lib}/parse.ts +1 -2
  36. package/src/presentation/overlays/schema/PostMessageSchema.tsx +0 -1
  37. package/src/presentation/panels/usePanelsStorage.ts +1 -1
  38. package/src/presentation/preview/IFrame.tsx +35 -83
  39. package/src/presentation/preview/Preview.tsx +56 -172
  40. package/src/presentation/preview/PreviewHeader.tsx +10 -43
  41. package/src/presentation/preview/PreviewLocationInput.tsx +24 -48
  42. package/src/presentation/preview/SharePreviewMenu.tsx +2 -2
  43. package/src/presentation/reducers/presentationReducer.ts +134 -0
  44. package/src/presentation/types.ts +7 -139
  45. package/src/presentation/useMainDocument.ts +12 -4
  46. package/src/presentation/useParams.ts +3 -2
  47. package/src/presentation/usePreviewUrl.ts +133 -0
  48. package/src/presentation/actors/create-preview-secret.ts +0 -19
  49. package/src/presentation/actors/read-shared-secret.ts +0 -18
  50. package/src/presentation/actors/resolve-allow-patterns.ts +0 -55
  51. package/src/presentation/actors/resolve-initial-url.ts +0 -65
  52. package/src/presentation/actors/resolve-preview-mode-url.ts +0 -72
  53. package/src/presentation/actors/resolve-preview-mode.ts +0 -66
  54. package/src/presentation/actors/resolve-url-from-preview-search-param.ts +0 -29
  55. package/src/presentation/machines/presentation-machine.ts +0 -101
  56. package/src/presentation/machines/preview-url.ts +0 -568
  57. package/src/presentation/useAllowPatterns.ts +0 -12
  58. package/src/presentation/useId.ts +0 -7
  59. package/src/presentation/usePresentationPerspective.ts +0 -14
  60. package/src/presentation/usePreviewUrlActorRef.ts +0 -96
  61. package/src/presentation/useReportInvalidPreviewSearchParam.tsx +0 -43
  62. package/src/presentation/useTargetOrigin.ts +0 -11
  63. /package/src/presentation/{util → lib}/debounce.ts +0 -0
@@ -1,18 +1,17 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { c } from "react-compiler-runtime";
3
- import { useSelector, useActorRef } from "@xstate/react";
4
- import { presentationLocaleNamespace, usePresentationTool, PresentationSpinner, API_VERSION, MAX_TIME_TO_OVERLAYS_CONNECTION, usePresentationNavigate, POPUP_CHECK_INTERVAL, EDIT_INTENT_MODE, DEFAULT_TOOL_NAME } from "./presentation.mjs";
3
+ import { urlSearchParamPreviewPerspective, fetchSharedAccessQuery, urlSearchParamVercelProtectionBypass, urlSearchParamVercelSetBypassCookie, schemaTypeSingleton, schemaIdSingleton, schemaType } from "@sanity/preview-url-secret/constants";
4
+ import { Card, Text, Stack, Inline, Box, Flex, Container as Container$1, Code, Label, TextInput, Spinner, useToast, Menu, Grid, Switch, MenuDivider, Hotkeys, usePrefersReducedMotion, BoundaryElementProvider } from "@sanity/ui";
5
+ import { uuid } from "@sanity/uuid";
6
+ import { memo, useEffect, useRef, useContext, useLayoutEffect, useState, forwardRef, Suspense, useId, lazy, useMemo, useCallback, useImperativeHandle, useSyncExternalStore, startTransition, useReducer } from "react";
7
+ import { useTranslation, useUnique, getPublishedId, useDocumentPreviewStore, usePerspective, getPreviewStateObservable, useSchema, getPreviewValueWithFallback, SanityDefaultPreview, PreviewCard, Translate, CommentsIntentProvider, useActiveWorkspace, useClient, useCurrentUser, useProjectId, useDataset, useWorkspace, COMMENTS_INSPECTOR_NAME, useGrantsStore } from "sanity";
8
+ import { presentationLocaleNamespace, usePresentationTool, PresentationSpinner, API_VERSION, ACTION_IFRAME_RELOAD, MAX_TIME_TO_OVERLAYS_CONNECTION, ACTION_IFRAME_LOADED, POPUP_CHECK_INTERVAL, presentationReducer, presentationReducerInit, ACTION_VISUAL_EDITING_OVERLAYS_TOGGLE, ACTION_IFRAME_REFRESH, EDIT_INTENT_MODE, DEFAULT_TOOL_NAME } from "./presentation.mjs";
5
9
  import { studioPath } from "@sanity/client/csm";
6
10
  import { createController, createConnectionMachine } from "@sanity/comlink";
7
11
  import { createCompatibilityActors } from "@sanity/presentation-comlink";
8
- import { urlSearchParamPreviewPerspective, fetchSharedAccessQuery, urlSearchParamVercelProtectionBypass, urlSearchParamVercelSetBypassCookie, urlSearchParamPreviewSecret, urlSearchParamPreviewPathname, schemaTypeSingleton, schemaIdSingleton, schemaType } from "@sanity/preview-url-secret/constants";
9
- import { Card, Text, Stack, Inline, Box, Flex, Container as Container$1, Code, Label, TextInput, Spinner, useToast, Menu, Grid, Switch, MenuDivider, Hotkeys, usePrefersReducedMotion, BoundaryElementProvider } from "@sanity/ui";
10
- import { memo, useEffect, useRef, useContext, useLayoutEffect, useState, forwardRef, Suspense, useId as useId$1, useImperativeHandle, lazy, useMemo, useCallback, useSyncExternalStore, useReducer } from "react";
11
- import { useTranslation, useUnique, getPublishedId, useDocumentPreviewStore, usePerspective, getPreviewStateObservable, useSchema, getPreviewValueWithFallback, SanityDefaultPreview, PreviewCard, Translate, CommentsIntentProvider, useActiveWorkspace, useClient, useCurrentUser, useProjectId, useDataset, useWorkspace, COMMENTS_INSPECTOR_NAME, useGrantsStore } from "sanity";
12
12
  import { StateLink, useRouter, decodeJsonParams } from "sanity/router";
13
- import { styled, createGlobalStyle } from "styled-components";
13
+ import { styled } from "styled-components";
14
14
  import { useEffectEvent } from "use-effect-event";
15
- import { setup, assign, fromPromise, fromObservable, log } from "xstate";
16
15
  import { PresentationSharedStateContext, PresentationPanelsContext, PresentationNavigateContext, PresentationParamsContext, PresentationContext } from "sanity/_singletons";
17
16
  import { WarningOutlineIcon, LaunchIcon, ResetIcon, CopyIcon, ShareIcon, PanelLeftIcon, MobileDeviceIcon, DesktopIcon, RefreshIcon } from "@sanity/icons";
18
17
  import { PaneRouterContext, PaneLayout, StructureToolProvider, DocumentListPane as DocumentListPane$1, DocumentPane as DocumentPane$1 } from "sanity/structure";
@@ -29,106 +28,35 @@ import { disablePreviewAccessSharing, enablePreviewAccessSharing } from "@sanity
29
28
  import { validateApiPerspective } from "@sanity/client";
30
29
  import isEqual from "fast-deep-equal";
31
30
  import { match } from "path-to-regexp";
31
+ import { pipe, string, minLength, optional, object, record, unknown } from "valibot";
32
32
  import { createPreviewSecret } from "@sanity/preview-url-secret/create-secret";
33
- import { uuid } from "@sanity/uuid";
34
- import { throwError } from "rxjs";
33
+ import { definePreviewUrl } from "@sanity/preview-url-secret/define-preview-url";
34
+ import { suspend } from "suspend-react";
35
35
  import { subcribeToVercelProtectionBypass } from "@sanity/preview-url-secret/toggle-vercel-protection-bypass";
36
36
  const PostMessageFeatures = (props) => {
37
37
  const $ = c(3), {
38
38
  comlink
39
39
  } = props;
40
40
  let t0, t1;
41
- return $[0] !== comlink ? (t0 = () => comlink.on("visual-editing/features", _temp$f), t1 = [comlink], $[0] = comlink, $[1] = t0, $[2] = t1) : (t0 = $[1], t1 = $[2]), useEffect(t0, t1), null;
41
+ return $[0] !== comlink ? (t0 = () => comlink.on("visual-editing/features", _temp$a), t1 = [comlink], $[0] = comlink, $[1] = t0, $[2] = t1) : (t0 = $[1], t1 = $[2]), useEffect(t0, t1), null;
42
42
  };
43
43
  var PostMessageFeatures$1 = memo(PostMessageFeatures);
44
- function _temp$f() {
44
+ function _temp$a() {
45
45
  return {
46
46
  features: {
47
47
  optimistic: !0
48
48
  }
49
49
  };
50
50
  }
51
- const presentationMachine = setup({
52
- types: {},
53
- actions: {
54
- //
55
- },
56
- actors: {
57
- //
58
- },
59
- guards: {
60
- //
61
- }
62
- }).createMachine({
63
- // eslint-disable-next-line tsdoc/syntax
64
- /** @xstate-layout N4IgpgJg5mDOIC5QAUBOcwDsAuBDbAlgPaYAEAKkUQDYDEBAZqrgLZinrVG4QDaADAF1EoAA5FYBQiREgAHogAsAJgA0IAJ6IAHAEYAdIoCcJowFY9R-vzPLlAX3vq0GHPmJlKNfVx4FMUPRMrOy+EJACwkgg4pLSmLIKCLoAbIr6Zoop2tqKAMxpJnnF6loIZkbK+uZ5umapKXmK-Cm6js7osFh48RRU1D7c4RC02ERQUNTsAG4EsACuuNSkkFL+UKRE02Co1LgasJGysWsy0UnaZinVyrpGAOx1Rim2efeliPe3hma1Zvy6XT8W4OJwgFxdNy9LwDMKQILMNgcMBMOAACyO0RO8USiAK930LWU-3uiiB9yaKXemkQjW01V+txS-GKqUe7XBnW67hIfW8cJGjER7E4Q0xYgkpwS5zxVMJKWJ-FJ5Mp1LKFn4Pz+DSaLTaYIh3Oh-UGPEg+nQqNgaPWCJCpAF4pikpxMoQKWZ+gp+TSZLy1hSH3deXpNSZLNqVP1HVcPQ8fNhQ3Nor8ATtSMdQmOLo8uPdnu9BUUfoDQY1WrqOuarUcYMwRHC8Gihqh8Zh2biubdAFpAzSEL2OS247yYfodqgiKgO1K8yog7ptATFL9dFljMDrHkh1zW6OTWF1jPXaAkmY1YgKnktfxtC9dPd+Io9DvYzzPAekxBj13T3i7vKirKkqqpBsYVQ1HUFjFs0t6KK+kIjh+-JfvoBAQFMP5nH+CDaMo16KjYyjMvUNh5GWOT6MoLL8A8ygrk0dQIUabafmaEAWiinQ2gEWHSjhjJUYuj73Pcd63noQaNEYFb-Dk2S0cxe7IYm7GcYevFYjm2HyJeeQQb8tFkikVjGNoFGajUt73o+z61vYQA */
65
- id: "Presentation Tool",
66
- context: {
67
- url: null,
68
- error: null,
69
- visualEditingOverlaysEnabled: !1
70
- },
71
- on: {
72
- "iframe reload": {
73
- actions: assign({
74
- url: null
75
- }),
76
- target: ".loading"
77
- }
78
- },
79
- states: {
80
- error: {
81
- description: "Failed to load, either because of a misconfiguration, a network error, or an unexpected error",
82
- tags: ["error"]
83
- },
84
- loading: {
85
- on: {
86
- "iframe loaded": {
87
- target: "loaded"
88
- }
89
- },
90
- tags: ["busy"]
91
- },
92
- loaded: {
93
- on: {
94
- "toggle visual editing overlays": {
95
- actions: assign({
96
- visualEditingOverlaysEnabled: ({
97
- event
98
- }) => event.enabled
99
- })
100
- },
101
- "iframe refresh": {
102
- target: ".refreshing"
103
- },
104
- "iframe reload": {
105
- target: ".reloading"
106
- }
107
- },
108
- states: {
109
- idle: {},
110
- refreshing: {
111
- on: {
112
- "iframe loaded": {
113
- target: "idle"
114
- }
115
- },
116
- tags: ["busy"]
117
- },
118
- reloading: {
119
- on: {
120
- "iframe loaded": {
121
- target: "idle"
122
- }
123
- },
124
- tags: ["busy"]
125
- }
126
- },
127
- initial: "idle"
128
- }
129
- },
130
- initial: "loading"
131
- }), SharedStateProvider = function(props) {
51
+ function debounce(fn, timeout) {
52
+ let timer;
53
+ return (...args) => {
54
+ clearTimeout(timer), timer = setTimeout(() => {
55
+ fn.apply(fn, args);
56
+ }, timeout);
57
+ };
58
+ }
59
+ const SharedStateProvider = function(props) {
132
60
  const $ = c(14), {
133
61
  comlink,
134
62
  children
@@ -199,22 +127,13 @@ const presentationMachine = setup({
199
127
  }), t5 = [id, defaultSize, order, maxWidth, minWidth, registerElement, unregisterElement], $[3] = defaultSize, $[4] = id, $[5] = maxWidth, $[6] = minWidth, $[7] = order, $[8] = registerElement, $[9] = unregisterElement, $[10] = t4, $[11] = t5) : (t4 = $[10], t5 = $[11]), useLayoutEffect(t4, t5);
200
128
  let t6;
201
129
  return $[12] !== children || $[13] !== style ? (t6 = /* @__PURE__ */ jsx(Root$1, { style, children }), $[12] = children, $[13] = style, $[14] = t6) : t6 = $[14], t6;
202
- };
203
- function debounce(fn, timeout) {
204
- let timer;
205
- return (...args) => {
206
- clearTimeout(timer), timer = setTimeout(() => {
207
- fn.apply(fn, args);
208
- }, timeout);
209
- };
210
- }
211
- const itemKey = "presentation/panels", getStoredItem = () => JSON.parse(localStorage.getItem(itemKey) || "{}"), setStoredItem = (data) => {
130
+ }, itemKey = "presentation/panels", getStoredItem = () => JSON.parse(localStorage.getItem(itemKey) || "{}"), setStoredItem = (data) => {
212
131
  localStorage.setItem(itemKey, JSON.stringify(data));
213
132
  }, getKeyForPanels = (panels) => panels.map((panel) => [panel.id, panel.order].join(":")).join(",");
214
133
  function usePanelsStorage() {
215
134
  const $ = c(1);
216
135
  let t0;
217
- const get = _temp2$8, set = _temp3$4;
136
+ const get = _temp2$5, set = _temp3$2;
218
137
  let t1;
219
138
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
220
139
  const setDebounced = debounce(set, 100);
@@ -227,18 +146,18 @@ function usePanelsStorage() {
227
146
  t1 = $[0];
228
147
  return t0 = t1, t0;
229
148
  }
230
- function _temp3$4(panels_0, widths) {
149
+ function _temp3$2(panels_0, widths) {
231
150
  const stored_0 = getStoredItem(), key_0 = getKeyForPanels(panels_0), data = {
232
151
  ...stored_0,
233
152
  [key_0]: widths
234
153
  };
235
154
  setStoredItem(data);
236
155
  }
237
- function _temp2$8(panels) {
156
+ function _temp2$5(panels) {
238
157
  const stored = getStoredItem(), key = getKeyForPanels(panels);
239
- return Array.isArray(stored[key]) && stored[key].some(_temp$e) ? void 0 : stored[key];
158
+ return Array.isArray(stored[key]) && stored[key].some(_temp$9) ? void 0 : stored[key];
240
159
  }
241
- function _temp$e(val) {
160
+ function _temp$9(val) {
242
161
  return val === null;
243
162
  }
244
163
  function getNextWidth(panel, nextWidth, containerWidth) {
@@ -659,13 +578,13 @@ function PresentationPaneRouterProvider(props) {
659
578
  ChildLink: t6,
660
579
  BackLink: t7,
661
580
  ReferenceChildLink: t8,
662
- ParameterizedLink: _temp$d,
663
- closeCurrentAndAfter: _temp2$7,
664
- handleEditReference: _temp3$3,
665
- replaceCurrent: _temp4$2,
666
- closeCurrent: _temp5$2,
667
- duplicateCurrent: _temp6$1,
668
- setView: _temp7$1,
581
+ ParameterizedLink: _temp$8,
582
+ closeCurrentAndAfter: _temp2$4,
583
+ handleEditReference: _temp3$1,
584
+ replaceCurrent: _temp4,
585
+ closeCurrent: _temp5,
586
+ duplicateCurrent: _temp6,
587
+ setView: _temp7,
669
588
  setParams: t9,
670
589
  setPayload: _temp8,
671
590
  navigateIntent: _temp9,
@@ -681,25 +600,25 @@ function _temp9(intentName, intentParams, options_0) {
681
600
  function _temp8(payload) {
682
601
  console.warn("setPayload", payload);
683
602
  }
684
- function _temp7$1(viewId) {
603
+ function _temp7(viewId) {
685
604
  console.warn("setView", viewId);
686
605
  }
687
- function _temp6$1(pane_0) {
606
+ function _temp6(pane_0) {
688
607
  console.warn("duplicateCurrent", pane_0);
689
608
  }
690
- function _temp5$2() {
609
+ function _temp5() {
691
610
  console.warn("closeCurrent");
692
611
  }
693
- function _temp4$2(pane) {
612
+ function _temp4(pane) {
694
613
  console.warn("replaceCurrent", pane);
695
614
  }
696
- function _temp3$3(options) {
615
+ function _temp3$1(options) {
697
616
  console.warn("handleEditReference", options);
698
617
  }
699
- function _temp2$7() {
618
+ function _temp2$4() {
700
619
  console.warn("closeCurrentAndAfter");
701
620
  }
702
- function _temp$d() {
621
+ function _temp$8() {
703
622
  throw new Error("ParameterizedLink not implemented");
704
623
  }
705
624
  const RootLayout = styled(PaneLayout)`
@@ -726,7 +645,7 @@ function DocumentListPane(props) {
726
645
  let t0, t1;
727
646
  if ($[0] !== mainDocumentState?.document?._id || $[1] !== refs) {
728
647
  let t22;
729
- $[3] !== mainDocumentState?.document?._id ? (t22 = (r) => getPublishedId(r._id) !== mainDocumentState?.document?._id, $[3] = mainDocumentState?.document?._id, $[4] = t22) : t22 = $[4], t1 = refs.filter(t22).map(_temp$c), $[0] = mainDocumentState?.document?._id, $[1] = refs, $[2] = t1;
648
+ $[3] !== mainDocumentState?.document?._id ? (t22 = (r) => getPublishedId(r._id) !== mainDocumentState?.document?._id, $[3] = mainDocumentState?.document?._id, $[4] = t22) : t22 = $[4], t1 = refs.filter(t22).map(_temp$7), $[0] = mainDocumentState?.document?._id, $[1] = refs, $[2] = t1;
730
649
  } else
731
650
  t1 = $[2];
732
651
  t0 = t1;
@@ -751,7 +670,7 @@ function DocumentListPane(props) {
751
670
  const pane = t2, [errorParams, setErrorParams] = useState(null);
752
671
  let t6;
753
672
  $[12] === Symbol.for("react.memo_cache_sentinel") ? (t6 = () => setErrorParams(null), $[12] = t6) : t6 = $[12];
754
- const handleRetry = t6, [structureParams] = useState(_temp2$6);
673
+ const handleRetry = t6, [structureParams] = useState(_temp2$3);
755
674
  let t7;
756
675
  $[13] === Symbol.for("react.memo_cache_sentinel") ? (t7 = () => setErrorParams(null), $[13] = t7) : t7 = $[13];
757
676
  let t8;
@@ -771,10 +690,10 @@ function DocumentListPane(props) {
771
690
  let t10;
772
691
  return $[27] !== onStructureParams || $[28] !== refs || $[29] !== searchParams || $[30] !== structureParams || $[31] !== t9 ? (t10 = /* @__PURE__ */ jsx(ErrorBoundary, { onCatch: setErrorParams, children: /* @__PURE__ */ jsx(RootLayout, { children: /* @__PURE__ */ jsx(StructureToolProvider, { children: /* @__PURE__ */ jsx(PresentationPaneRouterProvider, { onStructureParams, structureParams, searchParams, refs, children: t9 }) }) }) }), $[27] = onStructureParams, $[28] = refs, $[29] = searchParams, $[30] = structureParams, $[31] = t9, $[32] = t10) : t10 = $[32], t10;
773
692
  }
774
- function _temp2$6() {
693
+ function _temp2$3() {
775
694
  return {};
776
695
  }
777
- function _temp$c(r_0) {
696
+ function _temp$7(r_0) {
778
697
  return getPublishedId(r_0._id);
779
698
  }
780
699
  const WrappedCode = styled(Code)`
@@ -1129,7 +1048,7 @@ function usePresentationNavigator(props) {
1129
1048
  break bb0;
1130
1049
  }
1131
1050
  let t12;
1132
- $[0] !== setNavigatorEnabled ? (t12 = () => setNavigatorEnabled(_temp$b), $[0] = setNavigatorEnabled, $[1] = t12) : t12 = $[1], t0 = t12;
1051
+ $[0] !== setNavigatorEnabled ? (t12 = () => setNavigatorEnabled(_temp$6), $[0] = setNavigatorEnabled, $[1] = t12) : t12 = $[1], t0 = t12;
1133
1052
  }
1134
1053
  const toggleNavigator = t0;
1135
1054
  let t1;
@@ -1145,7 +1064,7 @@ function usePresentationNavigator(props) {
1145
1064
  let t3;
1146
1065
  return $[8] !== Component || $[9] !== t2 ? (t3 = [t2, Component], $[8] = Component, $[9] = t2, $[10] = t3) : t3 = $[10], t3;
1147
1066
  }
1148
- function _temp$b(enabled) {
1067
+ function _temp$6(enabled) {
1149
1068
  return !enabled;
1150
1069
  }
1151
1070
  function NavigatorComponent(props) {
@@ -1199,68 +1118,10 @@ const Navigator = memo(NavigatorComponent), PresentationParamsProvider = functio
1199
1118
  let t2;
1200
1119
  return $[7] !== children || $[8] !== context ? (t2 = /* @__PURE__ */ jsx(PresentationContext.Provider, { value: context, children }), $[7] = children, $[8] = context, $[9] = t2) : t2 = $[9], t2;
1201
1120
  };
1202
- function useAllowPatterns(previewUrlRef) {
1203
- const allowPatterns = useSelector(previewUrlRef, _temp$a);
1204
- if (!Array.isArray(allowPatterns))
1205
- throw new TypeError("allowPatterns must be an array");
1206
- return allowPatterns;
1207
- }
1208
- function _temp$a(state) {
1209
- return state.context.allowOrigins;
1210
- }
1211
1121
  function encodeStudioPerspective(studioPerspective) {
1212
1122
  return Array.isArray(studioPerspective) ? studioPerspective.join(",") : studioPerspective;
1213
1123
  }
1214
- function useId() {
1215
- const $ = c(2), id = useId$1();
1216
- let t0;
1217
- return $[0] !== id ? (t0 = id.startsWith(":") ? id.replace(/^:(.+):$/, "\xAB$1\xBB") : id, $[0] = id, $[1] = t0) : t0 = $[1], t0;
1218
- }
1219
- const IFrame = forwardRef(function(props, forwardedRef) {
1220
- const $ = c(19), {
1221
- animate,
1222
- initial,
1223
- onLoad,
1224
- preventClick,
1225
- src,
1226
- variants,
1227
- style
1228
- } = props, ref = useRef(null);
1229
- let t0;
1230
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => ref.current, $[0] = t0) : t0 = $[0], useImperativeHandle(forwardedRef, t0);
1231
- let t1, t2;
1232
- $[1] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => {
1233
- if (!ref.current)
1234
- return;
1235
- const instance = ref.current, handleBlur = function() {
1236
- instance === document.activeElement && instance.dispatchEvent(new MouseEvent("mousedown", {
1237
- bubbles: !0,
1238
- cancelable: !0
1239
- }));
1240
- };
1241
- return window.addEventListener("blur", handleBlur), () => {
1242
- window.removeEventListener("blur", handleBlur);
1243
- };
1244
- }, t2 = [], $[1] = t1, $[2] = t2) : (t1 = $[1], t2 = $[2]), useEffect(t1, t2);
1245
- const viewTransitionName = useId();
1246
- let t3;
1247
- $[3] !== style || $[4] !== viewTransitionName ? (t3 = {
1248
- ...style,
1249
- viewTransitionName
1250
- }, $[3] = style, $[4] = viewTransitionName, $[5] = t3) : t3 = $[5];
1251
- let t4;
1252
- $[6] !== animate || $[7] !== initial || $[8] !== onLoad || $[9] !== src || $[10] !== t3 || $[11] !== variants ? (t4 = /* @__PURE__ */ jsx(IFrameElement, { style: t3, animate, initial, onLoad, ref, src, variants }), $[6] = animate, $[7] = initial, $[8] = onLoad, $[9] = src, $[10] = t3, $[11] = variants, $[12] = t4) : t4 = $[12];
1253
- let t5;
1254
- $[13] !== preventClick ? (t5 = preventClick && /* @__PURE__ */ jsx(IFrameOverlay, {}), $[13] = preventClick, $[14] = t5) : t5 = $[14];
1255
- let t6;
1256
- $[15] === Symbol.for("react.memo_cache_sentinel") ? (t6 = /* @__PURE__ */ jsx(GlobalViewTransition, {}), $[15] = t6) : t6 = $[15];
1257
- let t7;
1258
- return $[16] !== t4 || $[17] !== t5 ? (t7 = /* @__PURE__ */ jsxs(Fragment, { children: [
1259
- t4,
1260
- t5,
1261
- t6
1262
- ] }), $[16] = t4, $[17] = t5, $[18] = t7) : t7 = $[18], t7;
1263
- }), IFrameElement = motion.create(styled.iframe`
1124
+ const IFrameElement = motion.create(styled.iframe`
1264
1125
  box-shadow: 0 0 0 1px var(--card-border-color);
1265
1126
  border: 0;
1266
1127
  max-height: 100%;
@@ -1270,20 +1131,31 @@ const IFrame = forwardRef(function(props, forwardedRef) {
1270
1131
  position: absolute;
1271
1132
  inset: 0;
1272
1133
  background: transparent;
1273
- `, GlobalViewTransition = createGlobalStyle`
1274
- html:active-view-transition-type(sanity-iframe-viewport) {
1275
- view-transition-name: none;
1276
- &::view-transition {
1277
- pointer-events: none;
1278
- }
1279
- /* &::view-transition-old(root) {
1280
- display: none;
1281
- }
1282
- &::view-transition-new(root) {
1283
- animation: none;
1284
- } */
1285
- }
1286
- `;
1134
+ `, IFrame = forwardRef(function(props, ref) {
1135
+ const $ = c(16), {
1136
+ animate,
1137
+ initial,
1138
+ onLoad,
1139
+ preventClick,
1140
+ src,
1141
+ variants,
1142
+ style
1143
+ } = props, t0 = `presentation-tool-iframe-${useId().replace(/[^a-zA-Z0-9-_]/g, "_")}`;
1144
+ let t1;
1145
+ $[0] !== style || $[1] !== t0 ? (t1 = {
1146
+ ...style,
1147
+ viewTransitionName: t0
1148
+ }, $[0] = style, $[1] = t0, $[2] = t1) : t1 = $[2];
1149
+ let t2;
1150
+ $[3] !== animate || $[4] !== initial || $[5] !== onLoad || $[6] !== ref || $[7] !== src || $[8] !== t1 || $[9] !== variants ? (t2 = /* @__PURE__ */ jsx(IFrameElement, { style: t1, animate, initial, onLoad, ref, src, variants }), $[3] = animate, $[4] = initial, $[5] = onLoad, $[6] = ref, $[7] = src, $[8] = t1, $[9] = variants, $[10] = t2) : t2 = $[10];
1151
+ let t3;
1152
+ $[11] !== preventClick ? (t3 = preventClick && /* @__PURE__ */ jsx(IFrameOverlay, {}), $[11] = preventClick, $[12] = t3) : t3 = $[12];
1153
+ let t4;
1154
+ return $[13] !== t2 || $[14] !== t3 ? (t4 = /* @__PURE__ */ jsxs(Fragment, { children: [
1155
+ t2,
1156
+ t3
1157
+ ] }), $[13] = t2, $[14] = t3, $[15] = t4) : t4 = $[15], t4;
1158
+ });
1287
1159
  function OpenPreviewButton(props) {
1288
1160
  const $ = c(16), {
1289
1161
  openPopup,
@@ -1321,25 +1193,16 @@ function OpenPreviewButton(props) {
1321
1193
  let t7;
1322
1194
  return $[13] !== t3 || $[14] !== t6 ? (t7 = /* @__PURE__ */ jsx(Tooltip, { animate: !0, content: t3, fallbackPlacements: t4, placement: "bottom", portal: !0, children: t6 }), $[13] = t3, $[14] = t6, $[15] = t7) : t7 = $[15], t7;
1323
1195
  }
1324
- function useTargetOrigin(previewUrlRef) {
1325
- const targetOrigin = useSelector(previewUrlRef, _temp$9);
1326
- if (!targetOrigin)
1327
- throw new TypeError("targetOrigin is required");
1328
- return targetOrigin;
1329
- }
1330
- function _temp$9(state) {
1331
- return state.context.previewUrl?.origin;
1332
- }
1333
- function PreviewLocationInput(props) {
1334
- const $ = c(32), {
1196
+ const PreviewLocationInput = function(props) {
1197
+ const $ = c(27), {
1335
1198
  fontSize: t0,
1336
1199
  onChange,
1200
+ origin,
1337
1201
  padding: t1,
1338
1202
  prefix,
1339
1203
  suffix,
1340
- value,
1341
- previewUrlRef
1342
- } = props, fontSize = t0 === void 0 ? 1 : t0, padding = t1 === void 0 ? 3 : t1, allowOrigins = useAllowPatterns(previewUrlRef), targetOrigin = useTargetOrigin(previewUrlRef), {
1204
+ value
1205
+ } = props, fontSize = t0 === void 0 ? 1 : t0, padding = t1 === void 0 ? 3 : t1, {
1343
1206
  t
1344
1207
  } = useTranslation(presentationLocaleNamespace), {
1345
1208
  basePath: t2
@@ -1350,74 +1213,59 @@ function PreviewLocationInput(props) {
1350
1213
  }, $[0] = t3) : t3 = $[0];
1351
1214
  const handleChange = t3;
1352
1215
  let t4;
1353
- $[1] !== allowOrigins || $[2] !== basePath || $[3] !== onChange || $[4] !== sessionValue || $[5] !== t || $[6] !== targetOrigin ? (t4 = (event_0) => {
1216
+ $[1] !== basePath || $[2] !== onChange || $[3] !== origin || $[4] !== sessionValue || $[5] !== t ? (t4 = (event_0) => {
1354
1217
  if (event_0.key === "Enter") {
1355
1218
  if (sessionValue === void 0)
1356
1219
  return;
1357
- let absoluteValue;
1358
- absoluteValue = sessionValue;
1359
- try {
1360
- absoluteValue = new URL(sessionValue, targetOrigin).toString();
1361
- } catch {
1220
+ const absoluteValue = sessionValue.startsWith("/") || sessionValue === "" ? `${origin}${sessionValue}` : sessionValue;
1221
+ if (!absoluteValue.startsWith(`${origin}/`) && absoluteValue !== origin) {
1222
+ setCustomValidity(t("preview-location-input.error", {
1223
+ origin,
1224
+ context: "missing-origin"
1225
+ }));
1226
+ return;
1362
1227
  }
1363
- if (Array.isArray(allowOrigins)) {
1364
- if (!allowOrigins.some((pattern) => pattern.test(absoluteValue))) {
1365
- setCustomValidity(t("preview-location-input.error", {
1366
- origin: targetOrigin,
1367
- context: "origin-not-allowed"
1368
- })), event_0.currentTarget.reportValidity();
1369
- return;
1370
- }
1371
- } else if (!targetOrigin && (absoluteValue.startsWith(`${basePath}/`) || absoluteValue === basePath)) {
1228
+ if (!origin && (absoluteValue.startsWith(`${basePath}/`) || absoluteValue === basePath)) {
1372
1229
  setCustomValidity(t("preview-location-input.error", {
1373
1230
  basePath,
1374
1231
  context: "same-base-path"
1375
1232
  }));
1376
1233
  return;
1377
1234
  }
1378
- const nextValue = absoluteValue === targetOrigin ? `${targetOrigin}/` : absoluteValue;
1379
- setCustomValidity(void 0), setSessionValue(void 0), onChange(nextValue), inputRef.current?.blur();
1235
+ const nextValue = absoluteValue === origin ? `${origin}/` : absoluteValue;
1236
+ setCustomValidity(void 0), setSessionValue(void 0), onChange(nextValue.slice(origin.length)), inputRef.current?.blur();
1380
1237
  }
1381
1238
  event_0.key === "Escape" && (setCustomValidity(void 0), setSessionValue(void 0));
1382
- }, $[1] = allowOrigins, $[2] = basePath, $[3] = onChange, $[4] = sessionValue, $[5] = t, $[6] = targetOrigin, $[7] = t4) : t4 = $[7];
1239
+ }, $[1] = basePath, $[2] = onChange, $[3] = origin, $[4] = sessionValue, $[5] = t, $[6] = t4) : t4 = $[6];
1383
1240
  const handleKeyDown = t4;
1384
1241
  let t5;
1385
- $[8] === Symbol.for("react.memo_cache_sentinel") ? (t5 = () => {
1242
+ $[7] === Symbol.for("react.memo_cache_sentinel") ? (t5 = () => {
1386
1243
  setCustomValidity(void 0), setSessionValue(void 0);
1387
- }, $[8] = t5) : t5 = $[8];
1244
+ }, $[7] = t5) : t5 = $[7];
1388
1245
  const handleBlur = t5;
1389
1246
  let t6;
1390
- $[9] !== targetOrigin || $[10] !== value ? (t6 = () => {
1391
- setCustomValidity(void 0);
1392
- let nextValue_0 = value;
1393
- try {
1394
- nextValue_0 = new URL(value, targetOrigin).toString();
1395
- } catch {
1396
- }
1397
- setSessionValue(nextValue_0);
1398
- }, $[9] = targetOrigin, $[10] = value, $[11] = t6) : t6 = $[11];
1399
- const handleClear = t6;
1400
- let t7;
1401
- $[12] === Symbol.for("react.memo_cache_sentinel") ? (t7 = () => {
1247
+ $[8] === Symbol.for("react.memo_cache_sentinel") ? (t6 = () => {
1402
1248
  setCustomValidity(void 0), setSessionValue(void 0);
1403
- }, $[12] = t7) : t7 = $[12];
1404
- let t8;
1405
- $[13] !== targetOrigin || $[14] !== value ? (t8 = [targetOrigin, value], $[13] = targetOrigin, $[14] = value, $[15] = t8) : t8 = $[15], useEffect(t7, t8);
1406
- let t9, t10;
1407
- $[16] === Symbol.for("react.memo_cache_sentinel") ? (t10 = {
1249
+ }, $[8] = t6) : t6 = $[8];
1250
+ let t7;
1251
+ $[9] !== origin || $[10] !== value ? (t7 = [origin, value], $[9] = origin, $[10] = value, $[11] = t7) : t7 = $[11], useEffect(t6, t7);
1252
+ let t8, t9;
1253
+ $[12] === Symbol.for("react.memo_cache_sentinel") ? (t9 = {
1408
1254
  icon: ResetIcon
1409
- }, $[16] = t10) : t10 = $[16], t9 = t10;
1410
- const t11 = customValidity ? t9 : void 0;
1255
+ }, $[12] = t9) : t9 = $[12], t8 = t9;
1256
+ const t10 = customValidity ? t8 : void 0;
1257
+ let t11;
1258
+ $[13] !== origin || $[14] !== value ? (t11 = () => {
1259
+ setCustomValidity(void 0), setSessionValue(origin + value);
1260
+ }, $[13] = origin, $[14] = value, $[15] = t11) : t11 = $[15];
1411
1261
  let t12;
1412
- $[17] === Symbol.for("react.memo_cache_sentinel") ? (t12 = {
1262
+ $[16] === Symbol.for("react.memo_cache_sentinel") ? (t12 = {
1413
1263
  zIndex: 1
1414
- }, $[17] = t12) : t12 = $[17];
1415
- let t13;
1416
- $[18] !== sessionValue || $[19] !== targetOrigin || $[20] !== value ? (t13 = sessionValue === void 0 ? new URL(value, targetOrigin).toString() : sessionValue, $[18] = sessionValue, $[19] = targetOrigin, $[20] = value, $[21] = t13) : t13 = $[21];
1264
+ }, $[16] = t12) : t12 = $[16];
1265
+ const t13 = sessionValue === void 0 ? `${origin}${value}` : sessionValue;
1417
1266
  let t14;
1418
- return $[22] !== customValidity || $[23] !== fontSize || $[24] !== handleClear || $[25] !== handleKeyDown || $[26] !== padding || $[27] !== prefix || $[28] !== suffix || $[29] !== t11 || $[30] !== t13 ? (t14 = /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(TextInput, { clearButton: t11, customValidity, fontSize, onBlur: handleBlur, onClear: handleClear, onChange: handleChange, onKeyDownCapture: handleKeyDown, padding, prefix, style: t12, radius: 2, ref: inputRef, space: padding, suffix, value: t13 }) }), $[22] = customValidity, $[23] = fontSize, $[24] = handleClear, $[25] = handleKeyDown, $[26] = padding, $[27] = prefix, $[28] = suffix, $[29] = t11, $[30] = t13, $[31] = t14) : t14 = $[31], t14;
1419
- }
1420
- const QRCodeSVG = lazy(() => import("./QRCodeSVG.mjs")), QrCodeLogoSize = 24, QrCodeLogoPadding = 16, QrSize = 224, StyledSanityMonogram = styled(SanityMonogram)`
1267
+ return $[17] !== customValidity || $[18] !== fontSize || $[19] !== handleKeyDown || $[20] !== padding || $[21] !== prefix || $[22] !== suffix || $[23] !== t10 || $[24] !== t11 || $[25] !== t13 ? (t14 = /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(TextInput, { clearButton: t10, customValidity, fontSize, onBlur: handleBlur, onClear: t11, onChange: handleChange, onKeyDownCapture: handleKeyDown, padding, prefix, style: t12, radius: 2, ref: inputRef, space: padding, suffix, value: t13 }) }), $[17] = customValidity, $[18] = fontSize, $[19] = handleKeyDown, $[20] = padding, $[21] = prefix, $[22] = suffix, $[23] = t10, $[24] = t11, $[25] = t13, $[26] = t14) : t14 = $[26], t14;
1268
+ }, QRCodeSVG = lazy(() => import("./QRCodeSVG.mjs")), QrCodeLogoSize = 24, QrCodeLogoPadding = 16, QrSize = 224, StyledSanityMonogram = styled(SanityMonogram)`
1421
1269
  position: absolute;
1422
1270
  top: 50%;
1423
1271
  left: 50%;
@@ -1450,7 +1298,7 @@ const QRCodeSVG = lazy(() => import("./QRCodeSVG.mjs")), QrCodeLogoSize = 24, Qr
1450
1298
  });
1451
1299
  }, [pushToast, t]), handleDisableSharing = useCallback(async () => {
1452
1300
  try {
1453
- setDisabling(!0), await disablePreviewAccessSharing(client, "sanity/presentation", typeof window > "u" ? "" : location.href, currentUser?.id), setSecret(null);
1301
+ setDisabling(!0), await disablePreviewAccessSharing(client, "@sanity/presentation", typeof window > "u" ? "" : location.href, currentUser?.id), setSecret(null);
1454
1302
  } catch (error_0) {
1455
1303
  setError(error_0);
1456
1304
  } finally {
@@ -1459,7 +1307,7 @@ const QRCodeSVG = lazy(() => import("./QRCodeSVG.mjs")), QrCodeLogoSize = 24, Qr
1459
1307
  }, [client, currentUser?.id]), handleEnableSharing = useCallback(async () => {
1460
1308
  try {
1461
1309
  setEnabling(!0);
1462
- const previewUrlSecret = await enablePreviewAccessSharing(client, "sanity/presentation", typeof window > "u" ? "" : location.href, currentUser?.id);
1310
+ const previewUrlSecret = await enablePreviewAccessSharing(client, "@sanity/presentation", typeof window > "u" ? "" : location.href, currentUser?.id);
1463
1311
  setSecret(previewUrlSecret.secret);
1464
1312
  } catch (error_1) {
1465
1313
  setError(error_1);
@@ -1576,10 +1424,12 @@ const QRCodeSVG = lazy(() => import("./QRCodeSVG.mjs")), QrCodeLogoSize = 24, Qr
1576
1424
  });
1577
1425
  SharePreviewMenu.displayName = "Memo(SharePreviewMenu)";
1578
1426
  const PreviewHeaderDefault = (props) => {
1579
- const $ = c(107), {
1427
+ const $ = c(100), {
1580
1428
  canSharePreviewAccess,
1581
1429
  canToggleSharePreviewAccess,
1582
1430
  canUseSharedPreviewAccess,
1431
+ dispatch,
1432
+ iframe,
1583
1433
  iframeRef,
1584
1434
  initialUrl,
1585
1435
  navigatorEnabled,
@@ -1587,7 +1437,6 @@ const PreviewHeaderDefault = (props) => {
1587
1437
  onRefresh,
1588
1438
  openPopup,
1589
1439
  overlaysConnection,
1590
- presentationRef,
1591
1440
  perspective,
1592
1441
  previewUrl,
1593
1442
  setViewport,
@@ -1595,147 +1444,145 @@ const PreviewHeaderDefault = (props) => {
1595
1444
  toggleNavigator,
1596
1445
  toggleOverlay,
1597
1446
  viewport,
1598
- previewUrlRef
1447
+ visualEditing: t0
1599
1448
  } = props, {
1449
+ overlaysEnabled
1450
+ } = t0, {
1600
1451
  t
1601
1452
  } = useTranslation(presentationLocaleNamespace);
1602
- let t0;
1603
- $[0] !== setViewport || $[1] !== viewport ? (t0 = () => setViewport(viewport === "desktop" ? "mobile" : "desktop"), $[0] = setViewport, $[1] = viewport, $[2] = t0) : t0 = $[2];
1604
- const toggleViewportSize = t0;
1605
1453
  let t1;
1606
- t1 = targetOrigin === location.origin ? "" : targetOrigin;
1607
- const previewLocationOrigin = t1;
1454
+ $[0] !== setViewport || $[1] !== viewport ? (t1 = () => setViewport(viewport === "desktop" ? "mobile" : "desktop"), $[0] = setViewport, $[1] = viewport, $[2] = t1) : t1 = $[2];
1455
+ const toggleViewportSize = t1;
1608
1456
  let t2;
1609
- $[3] !== iframeRef || $[4] !== onRefresh || $[5] !== presentationRef || $[6] !== previewUrl || $[7] !== targetOrigin ? (t2 = () => {
1457
+ t2 = targetOrigin === location.origin ? "" : targetOrigin;
1458
+ const previewLocationOrigin = t2;
1459
+ let t3;
1460
+ $[3] !== dispatch || $[4] !== iframeRef || $[5] !== onRefresh || $[6] !== previewUrl || $[7] !== targetOrigin ? (t3 = () => {
1610
1461
  onRefresh(() => {
1611
- iframeRef.current && (presentationRef.send({
1612
- type: "iframe reload"
1462
+ iframeRef.current && (dispatch({
1463
+ type: ACTION_IFRAME_RELOAD
1613
1464
  }), Object.assign(iframeRef.current, {
1614
1465
  src: `${targetOrigin}${previewUrl || "/"}`
1615
1466
  }));
1616
1467
  });
1617
- }, $[3] = iframeRef, $[4] = onRefresh, $[5] = presentationRef, $[6] = previewUrl, $[7] = targetOrigin, $[8] = t2) : t2 = $[8];
1618
- const handleRefresh = t2, isLoading = useSelector(presentationRef, _temp$8), isLoaded = useSelector(presentationRef, _temp2$5), isRefreshing = useSelector(presentationRef, _temp3$2), isReloading = useSelector(presentationRef, _temp4$1), overlaysEnabled = useSelector(presentationRef, _temp5$1);
1619
- let t3;
1468
+ }, $[3] = dispatch, $[4] = iframeRef, $[5] = onRefresh, $[6] = previewUrl, $[7] = targetOrigin, $[8] = t3) : t3 = $[8];
1469
+ const handleRefresh = t3;
1470
+ let t4;
1620
1471
  const previewURL = new URL(previewUrl || "/", targetOrigin), {
1621
1472
  pathname,
1622
1473
  search
1623
1474
  } = withoutSecretSearchParams(previewURL);
1624
- t3 = `${pathname}${search}`;
1625
- const previewLocationRoute = t3, perspectiveToggleTooltipId = useId(), previewUrlBusy = useSelector(previewUrlRef, _temp6);
1626
- let t4;
1627
- $[9] === Symbol.for("react.memo_cache_sentinel") ? (t4 = {
1628
- width: "100%"
1629
- }, $[9] = t4) : t4 = $[9];
1475
+ t4 = `${pathname}${search}`;
1476
+ const previewLocationRoute = t4;
1630
1477
  let t5;
1631
- $[10] !== navigatorEnabled || $[11] !== t || $[12] !== toggleNavigator ? (t5 = toggleNavigator && /* @__PURE__ */ jsx(Button, { "aria-label": t("preview-frame.navigator.toggle-button.aria-label"), icon: PanelLeftIcon, mode: "bleed", onClick: toggleNavigator, selected: navigatorEnabled, tooltipProps: {
1478
+ $[9] === Symbol.for("react.memo_cache_sentinel") ? (t5 = {
1479
+ width: "100%"
1480
+ }, $[9] = t5) : t5 = $[9];
1481
+ let t6;
1482
+ $[10] !== navigatorEnabled || $[11] !== t || $[12] !== toggleNavigator ? (t6 = toggleNavigator && /* @__PURE__ */ jsx(Button, { "aria-label": t("preview-frame.navigator.toggle-button.aria-label"), icon: PanelLeftIcon, mode: "bleed", onClick: toggleNavigator, selected: navigatorEnabled, tooltipProps: {
1632
1483
  content: /* @__PURE__ */ jsx(Text, { size: 1, children: t("preview-frame.navigator.toggle-button.tooltip") }),
1633
1484
  fallbackPlacements: ["bottom-start"],
1634
1485
  placement: "bottom"
1635
- } }), $[10] = navigatorEnabled, $[11] = t, $[12] = toggleNavigator, $[13] = t5) : t5 = $[13];
1636
- let t6;
1637
- $[14] === Symbol.for("react.memo_cache_sentinel") ? (t6 = {
1486
+ } }), $[10] = navigatorEnabled, $[11] = t, $[12] = toggleNavigator, $[13] = t6) : t6 = $[13];
1487
+ let t7;
1488
+ $[14] === Symbol.for("react.memo_cache_sentinel") ? (t7 = {
1638
1489
  whiteSpace: "nowrap"
1639
- }, $[14] = t6) : t6 = $[14];
1640
- const t7 = overlaysEnabled ? "disable" : "enable";
1641
- let t8;
1642
- $[15] !== t || $[16] !== t7 ? (t8 = t("preview-frame.overlay.toggle-button.tooltip", {
1643
- context: t7
1644
- }), $[15] = t, $[16] = t7, $[17] = t8) : t8 = $[17];
1490
+ }, $[14] = t7) : t7 = $[14];
1491
+ const t8 = overlaysEnabled ? "disable" : "enable";
1645
1492
  let t9;
1646
- $[18] !== t8 ? (t9 = /* @__PURE__ */ jsx(Box, { padding: 1, children: /* @__PURE__ */ jsx(Text, { size: 1, children: t8 }) }), $[18] = t8, $[19] = t9) : t9 = $[19];
1493
+ $[15] !== t || $[16] !== t8 ? (t9 = t("preview-frame.overlay.toggle-button.tooltip", {
1494
+ context: t8
1495
+ }), $[15] = t, $[16] = t8, $[17] = t9) : t9 = $[17];
1647
1496
  let t10;
1648
- $[20] === Symbol.for("react.memo_cache_sentinel") ? (t10 = /* @__PURE__ */ jsx(Box, { paddingY: 1, children: /* @__PURE__ */ jsx(Hotkeys, { keys: ["Alt"], style: {
1497
+ $[18] !== t9 ? (t10 = /* @__PURE__ */ jsx(Box, { padding: 1, children: /* @__PURE__ */ jsx(Text, { size: 1, children: t9 }) }), $[18] = t9, $[19] = t10) : t10 = $[19];
1498
+ let t11;
1499
+ $[20] === Symbol.for("react.memo_cache_sentinel") ? (t11 = /* @__PURE__ */ jsx(Box, { paddingY: 1, children: /* @__PURE__ */ jsx(Hotkeys, { keys: ["Alt"], style: {
1649
1500
  marginTop: -4,
1650
1501
  marginBottom: -4
1651
- } }) }), $[20] = t10) : t10 = $[20];
1652
- let t11;
1653
- $[21] !== t9 ? (t11 = /* @__PURE__ */ jsxs(Flex, { align: "center", style: t6, children: [
1654
- t9,
1655
- t10
1656
- ] }), $[21] = t9, $[22] = t11) : t11 = $[22];
1502
+ } }) }), $[20] = t11) : t11 = $[20];
1657
1503
  let t12;
1658
- $[23] === Symbol.for("react.memo_cache_sentinel") ? (t12 = ["bottom-start"], $[23] = t12) : t12 = $[23];
1504
+ $[21] !== t10 ? (t12 = /* @__PURE__ */ jsxs(Flex, { align: "center", style: t7, children: [
1505
+ t10,
1506
+ t11
1507
+ ] }), $[21] = t10, $[22] = t12) : t12 = $[22];
1659
1508
  let t13;
1660
- $[24] === Symbol.for("react.memo_cache_sentinel") ? (t13 = {
1509
+ $[23] === Symbol.for("react.memo_cache_sentinel") ? (t13 = ["bottom-start"], $[23] = t13) : t13 = $[23];
1510
+ let t14;
1511
+ $[24] === Symbol.for("react.memo_cache_sentinel") ? (t14 = {
1661
1512
  lineHeight: 0,
1662
1513
  borderRadius: 999,
1663
1514
  userSelect: "none"
1664
- }, $[24] = t13) : t13 = $[24];
1665
- const t14 = overlaysEnabled ? "transparent" : void 0;
1666
- let t15;
1667
- $[25] === Symbol.for("react.memo_cache_sentinel") ? (t15 = {
1515
+ }, $[24] = t14) : t14 = $[24];
1516
+ const t15 = overlaysEnabled ? "transparent" : void 0;
1517
+ let t16;
1518
+ $[25] === Symbol.for("react.memo_cache_sentinel") ? (t16 = {
1668
1519
  margin: -4
1669
- }, $[25] = t15) : t15 = $[25];
1670
- const t16 = !isLoaded, t17 = isLoading || overlaysConnection !== "connected";
1520
+ }, $[25] = t16) : t16 = $[25];
1521
+ const t17 = iframe.status === "loading" || overlaysConnection !== "connected";
1671
1522
  let t18;
1672
- $[26] !== overlaysEnabled || $[27] !== t16 || $[28] !== t17 || $[29] !== toggleOverlay ? (t18 = /* @__PURE__ */ jsx("div", { style: t15, children: /* @__PURE__ */ jsx(Switch, { indeterminate: t16, checked: overlaysEnabled, onChange: toggleOverlay, disabled: t17 }) }), $[26] = overlaysEnabled, $[27] = t16, $[28] = t17, $[29] = toggleOverlay, $[30] = t18) : t18 = $[30];
1523
+ $[26] !== overlaysEnabled || $[27] !== t17 || $[28] !== toggleOverlay ? (t18 = /* @__PURE__ */ jsx("div", { style: t16, children: /* @__PURE__ */ jsx(Switch, { checked: overlaysEnabled, onChange: toggleOverlay, disabled: t17 }) }), $[26] = overlaysEnabled, $[27] = t17, $[28] = toggleOverlay, $[29] = t18) : t18 = $[29];
1673
1524
  const t19 = !overlaysEnabled;
1674
1525
  let t20;
1675
- $[31] !== t ? (t20 = t("preview-frame.overlay.toggle-button.text"), $[31] = t, $[32] = t20) : t20 = $[32];
1526
+ $[30] !== t ? (t20 = t("preview-frame.overlay.toggle-button.text"), $[30] = t, $[31] = t20) : t20 = $[31];
1676
1527
  let t21;
1677
- $[33] !== t19 || $[34] !== t20 ? (t21 = /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { muted: t19, size: 1, weight: "medium", children: t20 }) }), $[33] = t19, $[34] = t20, $[35] = t21) : t21 = $[35];
1528
+ $[32] !== t19 || $[33] !== t20 ? (t21 = /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { muted: t19, size: 1, weight: "medium", children: t20 }) }), $[32] = t19, $[33] = t20, $[34] = t21) : t21 = $[34];
1678
1529
  let t22;
1679
- $[36] !== t18 || $[37] !== t21 ? (t22 = /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 3, children: [
1530
+ $[35] !== t18 || $[36] !== t21 ? (t22 = /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 3, children: [
1680
1531
  t18,
1681
1532
  t21
1682
- ] }), $[36] = t18, $[37] = t21, $[38] = t22) : t22 = $[38];
1533
+ ] }), $[35] = t18, $[36] = t21, $[37] = t22) : t22 = $[37];
1683
1534
  let t23;
1684
- $[39] !== t14 || $[40] !== t22 ? (t23 = /* @__PURE__ */ jsx(Card, { as: "label", flex: "none", padding: 3, marginX: 1, style: t13, tone: t14, children: t22 }), $[39] = t14, $[40] = t22, $[41] = t23) : t23 = $[41];
1535
+ $[38] !== t15 || $[39] !== t22 ? (t23 = /* @__PURE__ */ jsx(Card, { as: "label", flex: "none", padding: 3, marginX: 1, style: t14, tone: t15, children: t22 }), $[38] = t15, $[39] = t22, $[40] = t23) : t23 = $[40];
1685
1536
  let t24;
1686
- $[42] !== t11 || $[43] !== t23 ? (t24 = /* @__PURE__ */ jsx(Tooltip, { animate: !0, content: t11, fallbackPlacements: t12, placement: "bottom", portal: !0, children: t23 }), $[42] = t11, $[43] = t23, $[44] = t24) : t24 = $[44];
1537
+ $[41] !== t12 || $[42] !== t23 ? (t24 = /* @__PURE__ */ jsx(Tooltip, { animate: !0, content: t12, fallbackPlacements: t13, placement: "bottom", portal: !0, children: t23 }), $[41] = t12, $[42] = t23, $[43] = t24) : t24 = $[43];
1687
1538
  let t25;
1688
- $[45] !== isLoaded || $[46] !== isLoading || $[47] !== isRefreshing || $[48] !== isReloading || $[49] !== t ? (t25 = isLoaded ? t("preview-frame.refresh-button.tooltip") : t("preview-frame.status", {
1689
- context: isLoading ? "loading" : isRefreshing ? "refreshing" : isReloading ? "reloading" : "unknown"
1690
- }), $[45] = isLoaded, $[46] = isLoading, $[47] = isRefreshing, $[48] = isReloading, $[49] = t, $[50] = t25) : t25 = $[50];
1539
+ $[44] !== iframe.status || $[45] !== t ? (t25 = iframe.status === "loaded" ? t("preview-frame.refresh-button.tooltip") : t("preview-frame.status", {
1540
+ context: iframe.status
1541
+ }), $[44] = iframe.status, $[45] = t, $[46] = t25) : t25 = $[46];
1691
1542
  let t26;
1692
- $[51] !== t25 ? (t26 = /* @__PURE__ */ jsx(Text, { size: 1, children: t25 }), $[51] = t25, $[52] = t26) : t26 = $[52];
1543
+ $[47] !== t25 ? (t26 = /* @__PURE__ */ jsx(Text, { size: 1, children: t25 }), $[47] = t25, $[48] = t26) : t26 = $[48];
1693
1544
  let t27;
1694
- $[53] === Symbol.for("react.memo_cache_sentinel") ? (t27 = ["bottom-end"], $[53] = t27) : t27 = $[53];
1545
+ $[49] === Symbol.for("react.memo_cache_sentinel") ? (t27 = ["bottom-end"], $[49] = t27) : t27 = $[49];
1695
1546
  let t28;
1696
- $[54] !== t ? (t28 = t("preview-frame.refresh-button.aria-label"), $[54] = t, $[55] = t28) : t28 = $[55];
1697
- const t29 = isReloading || isRefreshing || previewUrlBusy;
1547
+ $[50] !== t ? (t28 = t("preview-frame.refresh-button.aria-label"), $[50] = t, $[51] = t28) : t28 = $[51];
1548
+ const t29 = iframe.status === "reloading" || iframe.status === "refreshing";
1698
1549
  let t30;
1699
- $[56] !== handleRefresh || $[57] !== t28 || $[58] !== t29 ? (t30 = /* @__PURE__ */ jsx(Button, { "aria-label": t28, icon: RefreshIcon, mode: "bleed", loading: t29, onClick: handleRefresh, tooltipProps: null }), $[56] = handleRefresh, $[57] = t28, $[58] = t29, $[59] = t30) : t30 = $[59];
1550
+ $[52] !== handleRefresh || $[53] !== t28 || $[54] !== t29 ? (t30 = /* @__PURE__ */ jsx(Button, { "aria-label": t28, icon: RefreshIcon, mode: "bleed", loading: t29, onClick: handleRefresh, tooltipProps: null }), $[52] = handleRefresh, $[53] = t28, $[54] = t29, $[55] = t30) : t30 = $[55];
1700
1551
  let t31;
1701
- $[60] !== t26 || $[61] !== t30 ? (t31 = /* @__PURE__ */ jsx(Box, { padding: 1, children: /* @__PURE__ */ jsx(Tooltip, { animate: !0, content: t26, fallbackPlacements: t27, placement: "bottom", portal: !0, children: t30 }) }), $[60] = t26, $[61] = t30, $[62] = t31) : t31 = $[62];
1552
+ $[56] !== t26 || $[57] !== t30 ? (t31 = /* @__PURE__ */ jsx(Box, { padding: 1, children: /* @__PURE__ */ jsx(Tooltip, { animate: !0, content: t26, fallbackPlacements: t27, placement: "bottom", portal: !0, children: t30 }) }), $[56] = t26, $[57] = t30, $[58] = t31) : t31 = $[58];
1702
1553
  let t32;
1703
- $[63] !== openPopup || $[64] !== perspective || $[65] !== previewLocationOrigin || $[66] !== previewLocationRoute || $[67] !== targetOrigin ? (t32 = /* @__PURE__ */ jsx(Box, { padding: 1, children: /* @__PURE__ */ jsx(OpenPreviewButton, { openPopup, previewLocationOrigin, previewLocationRoute, perspective, targetOrigin }) }), $[63] = openPopup, $[64] = perspective, $[65] = previewLocationOrigin, $[66] = previewLocationRoute, $[67] = targetOrigin, $[68] = t32) : t32 = $[68];
1554
+ $[59] !== openPopup || $[60] !== perspective || $[61] !== previewLocationOrigin || $[62] !== previewLocationRoute || $[63] !== targetOrigin ? (t32 = /* @__PURE__ */ jsx(Box, { padding: 1, children: /* @__PURE__ */ jsx(OpenPreviewButton, { openPopup, previewLocationOrigin, previewLocationRoute, perspective, targetOrigin }) }), $[59] = openPopup, $[60] = perspective, $[61] = previewLocationOrigin, $[62] = previewLocationRoute, $[63] = targetOrigin, $[64] = t32) : t32 = $[64];
1704
1555
  let t33;
1705
- $[69] !== onPathChange || $[70] !== previewLocationRoute || $[71] !== previewUrlRef || $[72] !== t31 || $[73] !== t32 ? (t33 = /* @__PURE__ */ jsx(Box, { flex: 1, children: /* @__PURE__ */ jsx(PreviewLocationInput, { previewUrlRef, prefix: t31, onChange: onPathChange, suffix: t32, value: previewLocationRoute }) }), $[69] = onPathChange, $[70] = previewLocationRoute, $[71] = previewUrlRef, $[72] = t31, $[73] = t32, $[74] = t33) : t33 = $[74];
1706
- let t34;
1707
- $[75] !== perspectiveToggleTooltipId ? (t34 = (node) => {
1708
- node?.style.setProperty("view-transition-name", perspectiveToggleTooltipId);
1709
- }, $[75] = perspectiveToggleTooltipId, $[76] = t34) : t34 = $[76];
1710
- const t35 = viewport === "desktop" ? "narrow" : "full";
1556
+ $[65] !== onPathChange || $[66] !== previewLocationOrigin || $[67] !== previewLocationRoute || $[68] !== t31 || $[69] !== t32 ? (t33 = /* @__PURE__ */ jsx(Box, { flex: 1, children: /* @__PURE__ */ jsx(PreviewLocationInput, { prefix: t31, onChange: onPathChange, origin: previewLocationOrigin, suffix: t32, value: previewLocationRoute }) }), $[65] = onPathChange, $[66] = previewLocationOrigin, $[67] = previewLocationRoute, $[68] = t31, $[69] = t32, $[70] = t33) : t33 = $[70];
1557
+ const t34 = viewport === "desktop" ? "narrow" : "full";
1558
+ let t35;
1559
+ $[71] !== t || $[72] !== t34 ? (t35 = t("preview-frame.viewport-button.tooltip", {
1560
+ context: t34
1561
+ }), $[71] = t, $[72] = t34, $[73] = t35) : t35 = $[73];
1711
1562
  let t36;
1712
- $[77] !== t || $[78] !== t35 ? (t36 = t("preview-frame.viewport-button.tooltip", {
1713
- context: t35
1714
- }), $[77] = t, $[78] = t35, $[79] = t36) : t36 = $[79];
1563
+ $[74] !== t35 ? (t36 = /* @__PURE__ */ jsx(Text, { size: 1, children: t35 }), $[74] = t35, $[75] = t36) : t36 = $[75];
1715
1564
  let t37;
1716
- $[80] !== t36 ? (t37 = /* @__PURE__ */ jsx(Text, { size: 1, children: t36 }), $[80] = t36, $[81] = t37) : t37 = $[81];
1565
+ $[76] === Symbol.for("react.memo_cache_sentinel") ? (t37 = ["bottom-start"], $[76] = t37) : t37 = $[76];
1717
1566
  let t38;
1718
- $[82] === Symbol.for("react.memo_cache_sentinel") ? (t38 = ["bottom-start"], $[82] = t38) : t38 = $[82];
1719
- let t39;
1720
- $[83] !== t ? (t39 = t("preview-frame.viewport-button.aria-label"), $[83] = t, $[84] = t39) : t39 = $[84];
1721
- const t40 = viewport === "desktop" ? MobileDeviceIcon : DesktopIcon;
1567
+ $[77] !== t ? (t38 = t("preview-frame.viewport-button.aria-label"), $[77] = t, $[78] = t38) : t38 = $[78];
1568
+ const t39 = viewport === "desktop" ? MobileDeviceIcon : DesktopIcon;
1569
+ let t40;
1570
+ $[79] !== t38 || $[80] !== t39 || $[81] !== toggleViewportSize || $[82] !== viewport ? (t40 = /* @__PURE__ */ jsx(Button, { "data-testid": "preview-viewport-toggle", "data-viewport": viewport, "aria-label": t38, icon: t39, mode: "bleed", onClick: toggleViewportSize, tooltipProps: null }), $[79] = t38, $[80] = t39, $[81] = toggleViewportSize, $[82] = viewport, $[83] = t40) : t40 = $[83];
1722
1571
  let t41;
1723
- $[85] !== t39 || $[86] !== t40 || $[87] !== toggleViewportSize || $[88] !== viewport ? (t41 = /* @__PURE__ */ jsx(Button, { "data-testid": "preview-viewport-toggle", "data-viewport": viewport, "aria-label": t39, icon: t40, mode: "bleed", onClick: toggleViewportSize, tooltipProps: null }), $[85] = t39, $[86] = t40, $[87] = toggleViewportSize, $[88] = viewport, $[89] = t41) : t41 = $[89];
1572
+ $[84] !== t36 || $[85] !== t40 ? (t41 = /* @__PURE__ */ jsx(Flex, { align: "center", flex: "none", gap: 1, children: /* @__PURE__ */ jsx(Tooltip, { animate: !0, content: t36, fallbackPlacements: t37, placement: "bottom", portal: !0, children: t40 }) }), $[84] = t36, $[85] = t40, $[86] = t41) : t41 = $[86];
1724
1573
  let t42;
1725
- $[90] !== t34 || $[91] !== t37 || $[92] !== t41 ? (t42 = /* @__PURE__ */ jsx(Flex, { align: "center", flex: "none", gap: 1, children: /* @__PURE__ */ jsx(Tooltip, { animate: !0, ref: t34, content: t37, fallbackPlacements: t38, placement: "bottom", portal: !0, children: t41 }) }), $[90] = t34, $[91] = t37, $[92] = t41, $[93] = t42) : t42 = $[93];
1574
+ $[87] !== canSharePreviewAccess || $[88] !== canToggleSharePreviewAccess || $[89] !== canUseSharedPreviewAccess || $[90] !== initialUrl || $[91] !== perspective || $[92] !== previewLocationRoute ? (t42 = canSharePreviewAccess && /* @__PURE__ */ jsx(Flex, { align: "center", flex: "none", gap: 1, children: /* @__PURE__ */ jsx(SharePreviewMenu, { canToggleSharePreviewAccess, canUseSharedPreviewAccess, previewLocationRoute, initialUrl, perspective }) }), $[87] = canSharePreviewAccess, $[88] = canToggleSharePreviewAccess, $[89] = canUseSharedPreviewAccess, $[90] = initialUrl, $[91] = perspective, $[92] = previewLocationRoute, $[93] = t42) : t42 = $[93];
1726
1575
  let t43;
1727
- $[94] !== canSharePreviewAccess || $[95] !== canToggleSharePreviewAccess || $[96] !== canUseSharedPreviewAccess || $[97] !== initialUrl || $[98] !== perspective || $[99] !== previewLocationRoute ? (t43 = canSharePreviewAccess && /* @__PURE__ */ jsx(Flex, { align: "center", flex: "none", gap: 1, children: /* @__PURE__ */ jsx(SharePreviewMenu, { canToggleSharePreviewAccess, canUseSharedPreviewAccess, previewLocationRoute, initialUrl, perspective }) }), $[94] = canSharePreviewAccess, $[95] = canToggleSharePreviewAccess, $[96] = canUseSharedPreviewAccess, $[97] = initialUrl, $[98] = perspective, $[99] = previewLocationRoute, $[100] = t43) : t43 = $[100];
1728
- let t44;
1729
- return $[101] !== t24 || $[102] !== t33 || $[103] !== t42 || $[104] !== t43 || $[105] !== t5 ? (t44 = /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 1, paddingX: 1, style: t4, children: [
1730
- t5,
1576
+ return $[94] !== t24 || $[95] !== t33 || $[96] !== t41 || $[97] !== t42 || $[98] !== t6 ? (t43 = /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 1, paddingX: 1, style: t5, children: [
1577
+ t6,
1731
1578
  t24,
1732
1579
  t33,
1733
- t42,
1734
- t43
1735
- ] }), $[101] = t24, $[102] = t33, $[103] = t42, $[104] = t43, $[105] = t5, $[106] = t44) : t44 = $[106], t44;
1580
+ t41,
1581
+ t42
1582
+ ] }), $[94] = t24, $[95] = t33, $[96] = t41, $[97] = t42, $[98] = t6, $[99] = t43) : t43 = $[99], t43;
1736
1583
  };
1737
1584
  function PreviewHeader(props) {
1738
- const $ = c(7), renderDefault = _temp7, HeaderComponent = props.options?.component;
1585
+ const $ = c(7), renderDefault = _temp$5, HeaderComponent = props.options?.component;
1739
1586
  let t0;
1740
1587
  $[0] !== HeaderComponent || $[1] !== props ? (t0 = HeaderComponent ? /* @__PURE__ */ jsx(HeaderComponent, { ...props, renderDefault }) : renderDefault(props), $[0] = HeaderComponent, $[1] = props, $[2] = t0) : t0 = $[2];
1741
1588
  const header = t0;
@@ -1750,42 +1597,20 @@ function PreviewHeader(props) {
1750
1597
  let t3;
1751
1598
  return $[5] !== header ? (t3 = /* @__PURE__ */ jsx(Card, { flex: "none", padding: 2, borderBottom: !0, style: t1, children: /* @__PURE__ */ jsx(Flex, { align: "center", style: t2, children: header }) }), $[5] = header, $[6] = t3) : t3 = $[6], t3;
1752
1599
  }
1753
- function _temp7(props_0) {
1600
+ function _temp$5(props_0) {
1754
1601
  return /* @__PURE__ */ jsx(PreviewHeaderDefault, { ...props_0 });
1755
1602
  }
1756
- function _temp$8(state) {
1757
- return state.matches("loading");
1758
- }
1759
- function _temp2$5(state_0) {
1760
- return state_0.matches("loaded");
1761
- }
1762
- function _temp3$2(state_1) {
1763
- return state_1.matches({
1764
- loaded: "refreshing"
1765
- });
1766
- }
1767
- function _temp4$1(state_2) {
1768
- return state_2.matches({
1769
- loaded: "reloading"
1770
- });
1771
- }
1772
- function _temp5$1(state_3) {
1773
- return state_3.context.visualEditingOverlaysEnabled;
1774
- }
1775
- function _temp6(state_4) {
1776
- return state_4.hasTag("busy");
1777
- }
1778
1603
  const MotionFlex = motion.create(Flex), Preview = memo(forwardRef(function(props, forwardedRef) {
1779
1604
  const {
1605
+ dispatch,
1606
+ iframe,
1780
1607
  header,
1781
1608
  initialUrl,
1782
1609
  loadersConnection,
1783
1610
  overlaysConnection,
1784
1611
  perspective,
1785
1612
  viewport,
1786
- vercelProtectionBypass,
1787
- presentationRef,
1788
- previewUrlRef
1613
+ vercelProtectionBypass
1789
1614
  } = props, [stablePerspective, setStablePerspective] = useState(null), urlPerspective = encodeStudioPerspective(stablePerspective === null ? perspective : stablePerspective), previewUrl = useMemo(() => {
1790
1615
  const url = new URL(initialUrl);
1791
1616
  return url.searchParams.get(urlSearchParamPreviewPerspective) || url.searchParams.set(urlSearchParamPreviewPerspective, urlPerspective), (vercelProtectionBypass || url.searchParams.get(urlSearchParamVercelProtectionBypass)) && url.searchParams.set(urlSearchParamVercelSetBypassCookie, "samesitenone"), vercelProtectionBypass && !url.searchParams.get(urlSearchParamVercelProtectionBypass) && url.searchParams.set(urlSearchParamVercelProtectionBypass, vercelProtectionBypass), url;
@@ -1799,26 +1624,22 @@ const MotionFlex = motion.create(Flex), Preview = memo(forwardRef(function(props
1799
1624
  devMode
1800
1625
  } = usePresentationTool(), prefersReducedMotion = usePrefersReducedMotion(), ref = useRef(null), previewHeader = /* @__PURE__ */ jsx(PreviewHeader, { ...props, iframeRef: ref, options: header });
1801
1626
  useImperativeHandle(forwardedRef, () => ref.current);
1802
- const isLoading = useSelector(presentationRef, (state) => state.matches("loading") || state.matches({
1803
- loaded: "reloading"
1804
- })), [timedOut, setTimedOut] = useState(!1), isRefreshing = useSelector(presentationRef, (state_0) => state_0.matches({
1805
- loaded: "refreshing"
1806
- })), [somethingIsWrong, setSomethingIsWrong] = useState(!1), iframeIsBusy = isLoading || isRefreshing || overlaysConnection === "connecting", handleRetry = useCallback(() => {
1807
- ref.current && (ref.current.src = previewUrl.toString(), presentationRef.send({
1808
- type: "iframe reload"
1627
+ const loading = iframe.status === "loading" || iframe.status === "reloading", [timedOut, setTimedOut] = useState(!1), refreshing = iframe.status === "refreshing", [somethingIsWrong, setSomethingIsWrong] = useState(!1), iframeIsBusy = loading || refreshing || overlaysConnection === "connecting", handleRetry = useCallback(() => {
1628
+ ref.current && (ref.current.src = previewUrl.toString(), dispatch({
1629
+ type: ACTION_IFRAME_RELOAD
1809
1630
  }));
1810
- }, [presentationRef, previewUrl]), handleContinueAnyway = useCallback(() => {
1631
+ }, [dispatch, previewUrl]), handleContinueAnyway = useCallback(() => {
1811
1632
  setContinueAnyway(!0);
1812
1633
  }, []), [continueAnyway, setContinueAnyway] = useState(!1), [showOverlaysConnectionStatus, setShowOverlaysConnectionState] = useState(!1);
1813
1634
  useEffect(() => {
1814
- if (!(isLoading || isRefreshing) && (overlaysConnection === "connecting" || overlaysConnection === "reconnecting")) {
1635
+ if (!(loading || refreshing) && (overlaysConnection === "connecting" || overlaysConnection === "reconnecting")) {
1815
1636
  const timeout = setTimeout(() => {
1816
1637
  setShowOverlaysConnectionState(!0);
1817
1638
  }, 5e3);
1818
1639
  return () => clearTimeout(timeout);
1819
1640
  }
1820
- }, [overlaysConnection, isLoading, isRefreshing]), useEffect(() => {
1821
- if (!(isLoading || isRefreshing || !showOverlaysConnectionStatus)) {
1641
+ }, [overlaysConnection, loading, refreshing]), useEffect(() => {
1642
+ if (!(loading || refreshing || !showOverlaysConnectionStatus)) {
1822
1643
  if (overlaysConnection === "connected" && (setSomethingIsWrong(!1), setShowOverlaysConnectionState(!1), setTimedOut(!1), setContinueAnyway(!1)), overlaysConnection === "connecting") {
1823
1644
  const timeout_0 = setTimeout(() => {
1824
1645
  setTimedOut(!0), console.error("Unable to connect to visual editing. Make sure you've setup '@sanity/visual-editing' correctly");
@@ -1832,110 +1653,46 @@ const MotionFlex = motion.create(Flex), Preview = memo(forwardRef(function(props
1832
1653
  return () => clearTimeout(timeout_1);
1833
1654
  }
1834
1655
  }
1835
- }, [isLoading, overlaysConnection, isRefreshing, showOverlaysConnectionStatus]);
1656
+ }, [loading, overlaysConnection, refreshing, showOverlaysConnectionStatus]);
1836
1657
  const onIFrameLoad = useCallback(() => {
1837
- presentationRef.send({
1838
- type: "iframe loaded"
1658
+ dispatch({
1659
+ type: ACTION_IFRAME_LOADED
1839
1660
  });
1840
- }, [presentationRef]), preventIframeInteraction = useMemo(() => (isLoading || overlaysConnection === "connecting" && !isRefreshing) && !continueAnyway, [continueAnyway, isLoading, isRefreshing, overlaysConnection]), canUseViewTransition = useSyncExternalStore(
1661
+ }, [dispatch]);
1662
+ useEffect(() => {
1663
+ if (!ref.current)
1664
+ return;
1665
+ const instance = ref.current;
1666
+ function handleBlur() {
1667
+ instance === document.activeElement && instance.dispatchEvent(new MouseEvent("mousedown", {
1668
+ bubbles: !0,
1669
+ cancelable: !0
1670
+ }));
1671
+ }
1672
+ return window.addEventListener("blur", handleBlur), () => {
1673
+ window.removeEventListener("blur", handleBlur);
1674
+ };
1675
+ }, []);
1676
+ const preventIframeInteraction = useMemo(() => (loading || overlaysConnection === "connecting" && iframe.status !== "refreshing") && !continueAnyway, [continueAnyway, iframe.status, loading, overlaysConnection]), canUseViewTransition = useSyncExternalStore(
1841
1677
  // eslint-disable-next-line no-empty-function
1842
1678
  useCallback(() => () => {
1843
1679
  }, []),
1844
1680
  () => CSS.supports("(view-transition-name: test)")
1845
1681
  ), iframeAnimations = useMemo(() => [
1846
1682
  preventIframeInteraction ? "background" : "active",
1847
- isLoading ? "reloading" : "idle",
1683
+ loading ? "reloading" : "idle",
1848
1684
  // If CSS View Transitions are supported, then transition iframe viewport dimensions with that instead of Motion
1849
1685
  canUseViewTransition ? "" : viewport,
1850
1686
  showOverlaysConnectionStatus && !continueAnyway ? "timedOut" : ""
1851
- ], [canUseViewTransition, continueAnyway, isLoading, preventIframeInteraction, showOverlaysConnectionStatus, viewport]), [currentViewport, setCurrentViewport] = useState(viewport), [iframeStyle, setIframeStyle] = useState(iframeVariants[viewport]);
1852
- useEffect(() => {
1687
+ ], [canUseViewTransition, continueAnyway, loading, preventIframeInteraction, showOverlaysConnectionStatus, viewport]), [currentViewport, setCurrentViewport] = useState(viewport), [iframeStyle, setIframeStyle] = useState(iframeVariants[viewport]);
1688
+ return useEffect(() => {
1853
1689
  if (canUseViewTransition && viewport !== currentViewport) {
1854
1690
  const update = () => {
1855
1691
  setCurrentViewport(viewport), setIframeStyle(iframeVariants[viewport]);
1856
1692
  };
1857
- !prefersReducedMotion && "startViewTransition" in document && typeof document.startViewTransition == "function" ? document.startViewTransition({
1858
- // @ts-expect-error - fix typings
1859
- update: () => flushSync(() => update()),
1860
- types: ["sanity-iframe-viewport"]
1861
- }) : update();
1693
+ !prefersReducedMotion && "startViewTransition" in document && typeof document.startViewTransition == "function" ? document.startViewTransition(() => flushSync(() => update())) : update();
1862
1694
  }
1863
- }, [canUseViewTransition, prefersReducedMotion, currentViewport, viewport]);
1864
- const toast = useToast(), allowOrigins = useAllowPatterns(previewUrlRef), [checkOrigin, setCheckOrigin] = useState(!1), [reportedMismatches] = useState(/* @__PURE__ */ new Set()), reportMismatchingOrigin = useEffectEvent((reportedOrigin) => {
1865
- if (allowOrigins.some((allow) => allow.test(reportedOrigin))) {
1866
- setCheckOrigin(reportedOrigin);
1867
- return;
1868
- }
1869
- reportedMismatches.has(reportedOrigin) || (reportedMismatches.add(reportedOrigin), console.warn("Visual Editing is here but misconfigured", {
1870
- reportedOrigin
1871
- }), toast.push({
1872
- closable: !0,
1873
- id: `presentation-iframe-origin-mismatch-${reportedOrigin}`,
1874
- status: "error",
1875
- duration: 1 / 0,
1876
- title: t("preview-frame.configuration.error.title"),
1877
- description: /* @__PURE__ */ jsx(Translate, { t, i18nKey: "preview-frame.configuration.error.description", components: {
1878
- Code: "code"
1879
- }, values: {
1880
- targetOrigin: previewUrl.origin,
1881
- reportedOrigin
1882
- } })
1883
- }));
1884
- }), navigate = usePresentationNavigate(), navigateEvent = useEffectEvent((url_0) => {
1885
- if (!checkOrigin) return;
1886
- const nextUrl = new URL(url_0, checkOrigin);
1887
- navigate(`${checkOrigin}${nextUrl.pathname}${nextUrl.search}${nextUrl.hash}`);
1888
- });
1889
- return useEffect(() => {
1890
- if (!checkOrigin)
1891
- return;
1892
- const target = ref.current?.contentWindow;
1893
- if (!target)
1894
- return;
1895
- const controller = createController({
1896
- targetOrigin: checkOrigin
1897
- });
1898
- controller.addTarget(target);
1899
- const comlink = controller.createChannel({
1900
- name: "presentation",
1901
- heartbeat: !0,
1902
- connectTo: "visual-editing"
1903
- }, createConnectionMachine().provide({
1904
- actors: createCompatibilityActors()
1905
- }));
1906
- comlink.on("visual-editing/navigate", (data) => {
1907
- navigateEvent(data.url);
1908
- });
1909
- const stop = comlink.start();
1910
- return () => {
1911
- stop(), controller.destroy();
1912
- };
1913
- }, [checkOrigin]), useEffect(() => {
1914
- if (overlaysConnection === "connecting" || overlaysConnection === "reconnecting") {
1915
- const interval = setInterval(() => {
1916
- ref.current?.contentWindow?.postMessage(
1917
- {
1918
- domain: "sanity/channels",
1919
- from: "presentation",
1920
- type: "presentation/status"
1921
- },
1922
- /**
1923
- * The targetOrigin is set to '*' intentionally here, as we need to find out if the iframe is misconfigured and has the wrong origin
1924
- */
1925
- "*"
1926
- );
1927
- }, 1e3), controller_0 = new AbortController();
1928
- return window.addEventListener("message", ({
1929
- data: data_0
1930
- }) => {
1931
- data_0 && typeof data_0 == "object" && "domain" in data_0 && data_0.domain === "sanity/channels" && "type" in data_0 && data_0.type === "visual-editing/status" && "data" in data_0 && typeof data_0.data == "object" && data_0.data && "origin" in data_0.data && typeof data_0.data.origin == "string" && reportMismatchingOrigin(data_0.data.origin);
1932
- }, {
1933
- signal: controller_0.signal
1934
- }), () => {
1935
- controller_0.abort(), clearInterval(interval);
1936
- };
1937
- }
1938
- }, [overlaysConnection, timedOut]), /* @__PURE__ */ jsx(MotionConfig, { transition: prefersReducedMotion ? {
1695
+ }, [canUseViewTransition, prefersReducedMotion, currentViewport, viewport]), /* @__PURE__ */ jsx(MotionConfig, { transition: prefersReducedMotion ? {
1939
1696
  duration: 0
1940
1697
  } : void 0, children: /* @__PURE__ */ jsxs(TooltipDelayGroupProvider, { children: [
1941
1698
  previewHeader,
@@ -1943,7 +1700,7 @@ const MotionFlex = motion.create(Flex), Preview = memo(forwardRef(function(props
1943
1700
  position: "relative",
1944
1701
  cursor: iframeIsBusy ? "wait" : void 0
1945
1702
  }, children: [
1946
- /* @__PURE__ */ jsx(AnimatePresence, { children: !somethingIsWrong && !isLoading && !isRefreshing && // viewport, // using CSS View Transitions instead of framer motion to drive this
1703
+ /* @__PURE__ */ jsx(AnimatePresence, { children: !somethingIsWrong && !loading && !refreshing && // viewport, // using CSS View Transitions instead of framer motion to drive this
1947
1704
  showOverlaysConnectionStatus && !continueAnyway ? /* @__PURE__ */ jsx(MotionFlex, { initial: "initial", animate: "animate", exit: "exit", variants: spinnerVariants, justify: "center", align: "center", style: {
1948
1705
  inset: "0",
1949
1706
  position: "absolute",
@@ -1975,7 +1732,7 @@ const MotionFlex = motion.create(Flex), Preview = memo(forwardRef(function(props
1975
1732
  text: t("preview-frame.continue-button.text")
1976
1733
  }
1977
1734
  )
1978
- ] }) }) : (isLoading || overlaysConnection === "connecting" && !isRefreshing) && !continueAnyway ? /* @__PURE__ */ jsx(MotionFlex, { initial: "initial", animate: "animate", exit: "exit", variants: spinnerVariants, justify: "center", align: "center", style: {
1735
+ ] }) }) : (loading || overlaysConnection === "connecting" && iframe.status !== "refreshing") && !continueAnyway ? /* @__PURE__ */ jsx(MotionFlex, { initial: "initial", animate: "animate", exit: "exit", variants: spinnerVariants, justify: "center", align: "center", style: {
1979
1736
  inset: "0",
1980
1737
  position: "absolute"
1981
1738
  // boxShadow: '0 0 0 1px var(--card-shadow-outline-color)',
@@ -2083,7 +1840,7 @@ function useDocumentsOnPage(perspective, frameStateRef) {
2083
1840
  const [previewDrafts, setPreviewDrafts] = useState(t1), urlRef = useRef("");
2084
1841
  let t2;
2085
1842
  $[2] !== frameStateRef ? (t2 = (key, perspective_0, t32) => {
2086
- const documents = (t32 === void 0 ? [] : t32).filter(_temp$7);
1843
+ const documents = (t32 === void 0 ? [] : t32).filter(_temp$4);
2087
1844
  (perspective_0 === "published" ? setPublished : setPreviewDrafts)((cache) => {
2088
1845
  const next = {};
2089
1846
  for (const document2 of documents)
@@ -2104,7 +1861,7 @@ function useDocumentsOnPage(perspective, frameStateRef) {
2104
1861
  const keyedCache = perspective === "published" ? published : previewDrafts;
2105
1862
  let t4;
2106
1863
  if ($[4] !== keyedCache) {
2107
- const uniqueDocuments = Object.values(keyedCache).reduce(_temp2$4, {});
1864
+ const uniqueDocuments = Object.values(keyedCache).reduce(_temp2$2, {});
2108
1865
  t4 = Object.values(uniqueDocuments), $[4] = keyedCache, $[5] = t4;
2109
1866
  } else
2110
1867
  t4 = $[5];
@@ -2113,12 +1870,12 @@ function useDocumentsOnPage(perspective, frameStateRef) {
2113
1870
  let t5;
2114
1871
  return $[6] !== documentsOnPage || $[7] !== setDocumentsOnPage ? (t5 = [documentsOnPage, setDocumentsOnPage], $[6] = documentsOnPage, $[7] = setDocumentsOnPage, $[8] = t5) : t5 = $[8], t5;
2115
1872
  }
2116
- function _temp2$4(acc, cache_0) {
1873
+ function _temp2$2(acc, cache_0) {
2117
1874
  return Object.values(cache_0).forEach((doc) => {
2118
1875
  acc[doc._id] = doc;
2119
1876
  }), acc;
2120
1877
  }
2121
- function _temp$7(sourceDocument) {
1878
+ function _temp$4(sourceDocument) {
2122
1879
  return "_projectId" in sourceDocument && sourceDocument._projectId ? (warnOnceAboutCrossDatasetReference("Cross dataset references are not supported yet, ignoring source document", sourceDocument), !1) : sourceDocument;
2123
1880
  }
2124
1881
  function fnOrObj(arg, context) {
@@ -2140,14 +1897,14 @@ function getParamsFromResult(resolver, context) {
2140
1897
  function getRouteContext(route, url) {
2141
1898
  const routes = Array.isArray(route) ? route : [route];
2142
1899
  for (route of routes) {
2143
- let origin2, path = route;
1900
+ let origin, path = route;
2144
1901
  if (typeof route == "string")
2145
1902
  try {
2146
1903
  const absolute = new URL(route);
2147
- origin2 = absolute.origin, path = absolute.pathname;
1904
+ origin = absolute.origin, path = absolute.pathname;
2148
1905
  } catch {
2149
1906
  }
2150
- if (!(origin2 && url.origin !== origin2))
1907
+ if (!(origin && url.origin !== origin))
2151
1908
  try {
2152
1909
  const result = match(path, {
2153
1910
  decode: decodeURIComponent
@@ -2158,7 +1915,7 @@ function getRouteContext(route, url) {
2158
1915
  path: path2
2159
1916
  } = result;
2160
1917
  return {
2161
- origin: origin2,
1918
+ origin,
2162
1919
  params,
2163
1920
  path: path2
2164
1921
  };
@@ -2173,7 +1930,7 @@ function useMainDocument(props) {
2173
1930
  navigate,
2174
1931
  navigationHistory,
2175
1932
  path,
2176
- targetOrigin,
1933
+ previewUrl,
2177
1934
  resolvers: t0
2178
1935
  } = props;
2179
1936
  let t1;
@@ -2189,7 +1946,7 @@ function useMainDocument(props) {
2189
1946
  }, $[2] = t2) : t2 = $[2];
2190
1947
  const client = useClient(t2);
2191
1948
  let t3;
2192
- $[3] !== path || $[4] !== routerState ? (t3 = path || routerState._searchParams?.find(_temp$6)?.[1] || "", $[3] = path, $[4] = routerState, $[5] = t3) : t3 = $[5];
1949
+ $[3] !== path || $[4] !== routerState ? (t3 = path || routerState._searchParams?.find(_temp$3)?.[1] || "", $[3] = path, $[4] = routerState, $[5] = t3) : t3 = $[5];
2193
1950
  const relativeUrl = t3, [mainDocumentState, setMainDocumentState] = useState(void 0), mainDocumentIdRef = useRef(void 0);
2194
1951
  let t4;
2195
1952
  $[6] !== navigate || $[7] !== navigationHistory ? (t4 = (doc, url) => {
@@ -2203,8 +1960,8 @@ function useMainDocument(props) {
2203
1960
  }, $[6] = navigate, $[7] = navigationHistory, $[8] = t4) : t4 = $[8];
2204
1961
  const handleResponse = useEffectEvent(t4);
2205
1962
  let t5;
2206
- $[9] !== client || $[10] !== handleResponse || $[11] !== perspectiveStack || $[12] !== relativeUrl || $[13] !== resolvers || $[14] !== targetOrigin ? (t5 = () => {
2207
- const url_0 = new URL(relativeUrl, targetOrigin);
1963
+ $[9] !== client || $[10] !== handleResponse || $[11] !== perspectiveStack || $[12] !== previewUrl || $[13] !== relativeUrl || $[14] !== resolvers ? (t5 = () => {
1964
+ const base = typeof previewUrl == "string" ? previewUrl : typeof previewUrl == "object" && previewUrl?.origin || location.origin, url_0 = new URL(relativeUrl, base);
2208
1965
  if (resolvers.length) {
2209
1966
  let result;
2210
1967
  for (const resolver of resolvers) {
@@ -2237,14 +1994,25 @@ function useMainDocument(props) {
2237
1994
  }
2238
1995
  }
2239
1996
  setMainDocumentState(void 0), mainDocumentIdRef.current = void 0;
2240
- }, $[9] = client, $[10] = handleResponse, $[11] = perspectiveStack, $[12] = relativeUrl, $[13] = resolvers, $[14] = targetOrigin, $[15] = t5) : t5 = $[15];
1997
+ }, $[9] = client, $[10] = handleResponse, $[11] = perspectiveStack, $[12] = previewUrl, $[13] = relativeUrl, $[14] = resolvers, $[15] = t5) : t5 = $[15];
2241
1998
  let t6;
2242
- return $[16] !== client || $[17] !== perspectiveStack || $[18] !== relativeUrl || $[19] !== resolvers || $[20] !== targetOrigin ? (t6 = [client, perspectiveStack, relativeUrl, resolvers, targetOrigin], $[16] = client, $[17] = perspectiveStack, $[18] = relativeUrl, $[19] = resolvers, $[20] = targetOrigin, $[21] = t6) : t6 = $[21], useEffect(t5, t6), mainDocumentState;
1999
+ return $[16] !== client || $[17] !== perspectiveStack || $[18] !== previewUrl || $[19] !== relativeUrl || $[20] !== resolvers ? (t6 = [client, previewUrl, relativeUrl, resolvers, perspectiveStack], $[16] = client, $[17] = perspectiveStack, $[18] = previewUrl, $[19] = relativeUrl, $[20] = resolvers, $[21] = t6) : t6 = $[21], useEffect(t5, t6), mainDocumentState;
2243
2000
  }
2244
- function _temp$6(t0) {
2001
+ function _temp$3(t0) {
2245
2002
  const [key] = t0;
2246
2003
  return key === "preview";
2247
2004
  }
2005
+ const lengthyStr$1 = pipe(string(), minLength(1)), optionalLengthyStr = optional(lengthyStr$1);
2006
+ object({
2007
+ baseUrl: lengthyStr$1,
2008
+ dataset: optionalLengthyStr,
2009
+ id: lengthyStr$1,
2010
+ path: lengthyStr$1,
2011
+ projectId: optionalLengthyStr,
2012
+ tool: optionalLengthyStr,
2013
+ type: optionalLengthyStr,
2014
+ workspace: optionalLengthyStr
2015
+ });
2248
2016
  const RE_SEGMENT_WITH_INDEX = /^([\w-]+):(0|[1-9][0-9]*)$/, RE_SEGMENT_WITH_TUPLE = /^([\w-]+):([0-9]+),([0-9]+)$/, RE_SEGMENT_WITH_KEY = /^([\w-]+):([\w-]+)$/;
2249
2017
  function urlStringToPath(str) {
2250
2018
  const path = [];
@@ -2270,6 +2038,12 @@ function urlStringToPath(str) {
2270
2038
  }
2271
2039
  return path;
2272
2040
  }
2041
+ const lengthyStr = pipe(string(), minLength(1));
2042
+ object({
2043
+ origin: lengthyStr,
2044
+ href: lengthyStr,
2045
+ data: optional(record(string(), unknown()))
2046
+ });
2273
2047
  function parseId(rawId) {
2274
2048
  if (rawId === void 0)
2275
2049
  return;
@@ -2307,7 +2081,7 @@ function useParams({
2307
2081
  id,
2308
2082
  type,
2309
2083
  path,
2310
- preview: routerSearchParams.preview || initialPreviewUrl.toString(),
2084
+ preview: routerSearchParams.preview || `${initialPreviewUrl.pathname}${initialPreviewUrl.search}`,
2311
2085
  perspective: routerSearchParams.perspective,
2312
2086
  viewport: routerSearchParams.viewport,
2313
2087
  inspect: routerSearchParams.inspect,
@@ -2372,7 +2146,7 @@ function useParams({
2372
2146
  };
2373
2147
  }
2374
2148
  const usePopups = (controller) => {
2375
- const $ = c(10), [popups, setPopups] = useState(_temp$5);
2149
+ const $ = c(10), [popups, setPopups] = useState(_temp$2);
2376
2150
  let t0;
2377
2151
  $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = (url) => {
2378
2152
  const source = window.open(url, "_blank");
@@ -2386,7 +2160,7 @@ const usePopups = (controller) => {
2386
2160
  for (const source_0 of popups)
2387
2161
  source_0 && "closed" in source_0 && !source_0.closed && unsubs.push(controller.addTarget(source_0));
2388
2162
  return () => {
2389
- unsubs.forEach(_temp2$3);
2163
+ unsubs.forEach(_temp2$1);
2390
2164
  };
2391
2165
  }, t2 = [controller, popups], $[1] = controller, $[2] = popups, $[3] = t1, $[4] = t2) : (t1 = $[3], t2 = $[4]), useEffect(t1, t2);
2392
2166
  let t3, t4;
@@ -2414,19 +2188,85 @@ const usePopups = (controller) => {
2414
2188
  open
2415
2189
  }, $[8] = popups, $[9] = t5) : t5 = $[9], t5;
2416
2190
  };
2417
- function _temp$5() {
2191
+ function _temp$2() {
2418
2192
  return /* @__PURE__ */ new Set();
2419
2193
  }
2420
- function _temp2$3(unsub) {
2194
+ function _temp2$1(unsub) {
2421
2195
  return unsub();
2422
2196
  }
2423
- function usePresentationPerspective() {
2424
- const {
2425
- perspectiveStack,
2426
- selectedPerspectiveName: t0,
2427
- selectedReleaseId
2428
- } = usePerspective();
2429
- return selectedReleaseId ? perspectiveStack : t0 === void 0 ? "drafts" : t0;
2197
+ function usePreviewUrl(previewUrl, toolName, studioPreviewPerspective, previewSearchParam, canCreateUrlPreviewSecrets) {
2198
+ const $ = c(12);
2199
+ let t0;
2200
+ $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
2201
+ apiVersion: API_VERSION
2202
+ }, $[0] = t0) : t0 = $[0];
2203
+ const client = useClient(t0), workspace = useActiveWorkspace(), basePath = workspace?.activeWorkspace?.basePath || "/", workspaceName = workspace?.activeWorkspace?.name || "default", deps = useSuspendCacheKeys(toolName, basePath, workspaceName, previewSearchParam), previewUrlSecret = usePreviewUrlSecret(canCreateUrlPreviewSecrets && typeof previewUrl == "object" || typeof previewUrl == "function", deps);
2204
+ let t1;
2205
+ $[1] !== basePath || $[2] !== client || $[3] !== previewSearchParam || $[4] !== previewUrl || $[5] !== previewUrlSecret || $[6] !== studioPreviewPerspective ? (t1 = async () => {
2206
+ if (typeof previewUrl == "string") {
2207
+ const resolvedUrl = new URL(previewUrl, location.origin);
2208
+ let resultUrl = resolvedUrl;
2209
+ try {
2210
+ if (previewSearchParam) {
2211
+ const restoredUrl = new URL(previewSearchParam, resolvedUrl);
2212
+ restoredUrl.origin === resolvedUrl.origin && (resultUrl = restoredUrl);
2213
+ }
2214
+ } catch {
2215
+ }
2216
+ return location.origin === resultUrl.origin && (resultUrl.pathname.startsWith(`${basePath}/`) || resultUrl.pathname === basePath) ? resolvedUrl : resultUrl;
2217
+ }
2218
+ const resolvedUrl_0 = await (typeof previewUrl == "object" ? definePreviewUrl(previewUrl) : previewUrl)({
2219
+ client,
2220
+ previewUrlSecret,
2221
+ studioPreviewPerspective: encodeStudioPerspective(studioPreviewPerspective),
2222
+ previewSearchParam,
2223
+ studioBasePath: basePath
2224
+ });
2225
+ return new URL(resolvedUrl_0, location.origin);
2226
+ }, $[1] = basePath, $[2] = client, $[3] = previewSearchParam, $[4] = previewUrl, $[5] = previewUrlSecret, $[6] = studioPreviewPerspective, $[7] = t1) : t1 = $[7];
2227
+ let t2;
2228
+ return $[8] !== deps || $[9] !== previewUrlSecret || $[10] !== t1 ? (t2 = suspend(t1, [...deps, previewUrlSecret]), $[8] = deps, $[9] = previewUrlSecret, $[10] = t1, $[11] = t2) : t2 = $[11], t2;
2229
+ }
2230
+ const resolveUUID = Symbol("sanity/presentation/resolveUUID");
2231
+ function useSuspendCacheKeys(toolName, basePath, workspaceName, previewSearchParam) {
2232
+ const $ = c(12);
2233
+ let t0;
2234
+ $[0] !== previewSearchParam ? (t0 = () => previewSearchParam || "", $[0] = previewSearchParam, $[1] = t0) : t0 = $[1];
2235
+ const [cachedPreviewSearchParam, setCachedPreviewSearchParam] = useState(t0), timeoutRef = useRef(0);
2236
+ let t1, t2;
2237
+ $[2] !== cachedPreviewSearchParam || $[3] !== previewSearchParam ? (t1 = () => {
2238
+ if (cachedPreviewSearchParam && previewSearchParam)
2239
+ return window.clearTimeout(timeoutRef.current), () => {
2240
+ timeoutRef.current = window.setTimeout(() => {
2241
+ setCachedPreviewSearchParam("");
2242
+ }, 100);
2243
+ };
2244
+ }, t2 = [cachedPreviewSearchParam, previewSearchParam], $[2] = cachedPreviewSearchParam, $[3] = previewSearchParam, $[4] = t1, $[5] = t2) : (t1 = $[4], t2 = $[5]), useEffect(t1, t2);
2245
+ const currentUser = useCurrentUser();
2246
+ let t3;
2247
+ const t4 = currentUser?.id;
2248
+ let t5;
2249
+ return $[6] !== basePath || $[7] !== cachedPreviewSearchParam || $[8] !== t4 || $[9] !== toolName || $[10] !== workspaceName ? (t5 = ["sanity/presentation", basePath, workspaceName, toolName, t4, resolveUUID, cachedPreviewSearchParam], $[6] = basePath, $[7] = cachedPreviewSearchParam, $[8] = t4, $[9] = toolName, $[10] = workspaceName, $[11] = t5) : t5 = $[11], t3 = t5, t3;
2250
+ }
2251
+ function usePreviewUrlSecret(enabled, deps) {
2252
+ const $ = c(10);
2253
+ let t0;
2254
+ $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
2255
+ apiVersion: API_VERSION
2256
+ }, $[0] = t0) : t0 = $[0];
2257
+ const client = useClient(t0), currentUser = useCurrentUser(), [secretLastExpiredAt, setSecretLastExpiredAt] = useState("");
2258
+ let t1;
2259
+ $[1] !== client || $[2] !== currentUser?.id || $[3] !== deps || $[4] !== enabled || $[5] !== secretLastExpiredAt ? (t1 = enabled ? suspend(async () => await createPreviewSecret(client, "@sanity/presentation", typeof window > "u" ? "" : location.href, currentUser?.id), [...deps, secretLastExpiredAt]) : null, $[1] = client, $[2] = currentUser?.id, $[3] = deps, $[4] = enabled, $[5] = secretLastExpiredAt, $[6] = t1) : t1 = $[6];
2260
+ const previewUrlSecret = t1;
2261
+ let t2, t3;
2262
+ return $[7] !== previewUrlSecret ? (t2 = () => {
2263
+ if (!previewUrlSecret)
2264
+ return;
2265
+ const timeout = setTimeout(() => {
2266
+ startTransition(() => setSecretLastExpiredAt(previewUrlSecret.expiresAt.toString()));
2267
+ }, previewUrlSecret.expiresAt.getTime() - Date.now());
2268
+ return () => clearTimeout(timeout);
2269
+ }, t3 = [previewUrlSecret], $[7] = previewUrlSecret, $[8] = t2, $[9] = t3) : (t2 = $[8], t3 = $[9]), useEffect(t2, t3), previewUrlSecret?.secret || null;
2430
2270
  }
2431
2271
  function useStatus() {
2432
2272
  const $ = c(4);
@@ -2436,13 +2276,13 @@ function useStatus() {
2436
2276
  let t1;
2437
2277
  bb0: {
2438
2278
  const values = Array.from(statusMap.values());
2439
- if (values.find(_temp$4)) {
2279
+ if (values.find(_temp$1)) {
2440
2280
  t1 = "connected";
2441
2281
  break bb0;
2442
2282
  }
2443
- const handshaking = values.filter(_temp2$2);
2283
+ const handshaking = values.filter(_temp2);
2444
2284
  if (handshaking.length) {
2445
- t1 = handshaking.some(_temp3$1) ? "connecting" : "reconnecting";
2285
+ t1 = handshaking.some(_temp3) ? "connecting" : "reconnecting";
2446
2286
  break bb0;
2447
2287
  }
2448
2288
  t1 = "idle";
@@ -2468,19 +2308,19 @@ function useStatus() {
2468
2308
  let t3;
2469
2309
  return $[2] !== memoStatus ? (t3 = [memoStatus, setStatusFromEvent], $[2] = memoStatus, $[3] = t3) : t3 = $[3], t3;
2470
2310
  }
2471
- function _temp3$1(t0) {
2311
+ function _temp3(t0) {
2472
2312
  const {
2473
2313
  hasConnected
2474
2314
  } = t0;
2475
2315
  return !hasConnected;
2476
2316
  }
2477
- function _temp2$2(t0) {
2317
+ function _temp2(t0) {
2478
2318
  const {
2479
2319
  status: status_0
2480
2320
  } = t0;
2481
2321
  return status_0 === "connecting";
2482
2322
  }
2483
- function _temp$4(t0) {
2323
+ function _temp$1(t0) {
2484
2324
  const {
2485
2325
  status
2486
2326
  } = t0;
@@ -2491,22 +2331,25 @@ const LiveQueries = lazy(() => import("./LiveQueries.mjs")), PostMessageDocument
2491
2331
  `;
2492
2332
  function PresentationTool(props) {
2493
2333
  const {
2334
+ canCreateUrlPreviewSecrets,
2494
2335
  canToggleSharePreviewAccess,
2495
2336
  canUseSharedPreviewAccess,
2496
2337
  tool,
2497
- vercelProtectionBypass,
2498
- initialPreviewUrl,
2499
- previewUrlRef
2500
- } = props, allowOrigins = useAllowPatterns(previewUrlRef), targetOrigin = useTargetOrigin(previewUrlRef), components = tool.options?.components, name = tool.name || DEFAULT_TOOL_NAME, {
2338
+ vercelProtectionBypass
2339
+ } = props, components = tool.options?.components, _previewUrl = tool.options?.previewUrl, name = tool.name || DEFAULT_TOOL_NAME, {
2501
2340
  unstable_navigator,
2502
2341
  unstable_header
2503
2342
  } = components || {}, {
2504
2343
  navigate: routerNavigate,
2505
2344
  state: routerState
2506
- } = useRouter(), routerSearchParams = useUnique(Object.fromEntries(routerState._searchParams || [])), perspective = usePresentationPerspective(), canSharePreviewAccess = useSelector(previewUrlRef, (state) => state.context.previewMode?.shareAccess !== !1), [devMode] = useState(() => {
2345
+ } = useRouter(), routerSearchParams = useUnique(Object.fromEntries(routerState._searchParams || [])), {
2346
+ perspectiveStack,
2347
+ selectedPerspectiveName = "drafts",
2348
+ selectedReleaseId
2349
+ } = usePerspective(), perspective = selectedReleaseId ? perspectiveStack : selectedPerspectiveName, initialPreviewUrl = usePreviewUrl(_previewUrl || "/", name, perspective, routerSearchParams.preview || null, canCreateUrlPreviewSecrets), canSharePreviewAccess = useMemo(() => _previewUrl && typeof _previewUrl == "object" && "draftMode" in _previewUrl && _previewUrl.draftMode ? (console.warn("previewUrl.draftMode is deprecated, use previewUrl.previewMode instead"), _previewUrl.draftMode.shareAccess !== !1) : _previewUrl && typeof _previewUrl == "object" && "previewMode" in _previewUrl && _previewUrl.previewMode ? _previewUrl.previewMode.shareAccess !== !1 : !1, [_previewUrl]), [devMode] = useState(() => {
2507
2350
  const option = tool.options?.devMode;
2508
2351
  return typeof option == "function" ? option() : typeof option == "boolean" ? option : typeof window < "u" && window.location.hostname === "localhost";
2509
- }), iframeRef = useRef(null), [controller, setController] = useState(), [visualEditingComlink, setVisualEditingComlink] = useState(null), frameStateRef = useRef({
2352
+ }), targetOrigin = useMemo(() => initialPreviewUrl.origin, [initialPreviewUrl.origin]), iframeRef = useRef(null), [controller, setController] = useState(), [visualEditingComlink, setVisualEditingComlink] = useState(null), frameStateRef = useRef({
2510
2353
  title: void 0,
2511
2354
  url: void 0
2512
2355
  }), {
@@ -2521,16 +2364,16 @@ function PresentationTool(props) {
2521
2364
  routerState,
2522
2365
  routerSearchParams,
2523
2366
  frameStateRef
2524
- }), navigate = useMemo(() => debounce(_navigate, 50), [_navigate]), presentationRef = useActorRef(presentationMachine), viewport = useMemo(() => params.viewport ? "mobile" : "desktop", [params.viewport]), [documentsOnPage, setDocumentsOnPage] = useDocumentsOnPage(perspective, frameStateRef), projectId = useProjectId(), dataset = useDataset(), mainDocumentState = useMainDocument({
2367
+ }), navigate = useMemo(() => debounce(_navigate, 50), [_navigate]), [state, dispatch] = useReducer(presentationReducer, {}, presentationReducerInit), viewport = useMemo(() => params.viewport ? "mobile" : "desktop", [params.viewport]), [documentsOnPage, setDocumentsOnPage] = useDocumentsOnPage(perspective, frameStateRef), projectId = useProjectId(), dataset = useDataset(), mainDocumentState = useMainDocument({
2525
2368
  // Prevent flash of content by using immediate navigation
2526
2369
  navigate: _navigate,
2527
2370
  navigationHistory,
2528
2371
  path: params.preview,
2529
- targetOrigin,
2372
+ previewUrl: tool.options?.previewUrl,
2530
2373
  resolvers: tool.options?.resolve?.mainDocuments
2531
2374
  }), [overlaysConnection, setOverlaysConnection] = useStatus(), [loadersConnection, setLoadersConnection] = useStatus(), [previewKitConnection, setPreviewKitConnection] = useStatus(), {
2532
2375
  open: handleOpenPopup
2533
- } = usePopups(controller), isLoading = useSelector(presentationRef, (state_0) => state_0.matches("loading"));
2376
+ } = usePopups(controller), isLoading = state.iframe.status === "loading";
2534
2377
  useEffect(() => {
2535
2378
  const target = iframeRef.current?.contentWindow;
2536
2379
  if (!target || isLoading) return;
@@ -2559,14 +2402,9 @@ function PresentationTool(props) {
2559
2402
  });
2560
2403
  }), comlink.on("visual-editing/navigate", (data_0) => {
2561
2404
  const {
2562
- title
2405
+ title,
2406
+ url
2563
2407
  } = data_0;
2564
- let url = data_0.url;
2565
- if (!url.startsWith("http"))
2566
- try {
2567
- url = new URL(url, targetOrigin).toString();
2568
- } catch {
2569
- }
2570
2408
  if (frameStateRef.current.url !== url)
2571
2409
  try {
2572
2410
  const [urlWithoutSearch, search] = url.split("?"), searchParams_0 = new URLSearchParams(search);
@@ -2585,8 +2423,8 @@ function PresentationTool(props) {
2585
2423
  }), comlink.on("visual-editing/meta", (data_1) => {
2586
2424
  frameStateRef.current.title = data_1.title;
2587
2425
  }), comlink.on("visual-editing/toggle", (data_2) => {
2588
- presentationRef.send({
2589
- type: "toggle visual editing overlays",
2426
+ dispatch({
2427
+ type: ACTION_VISUAL_EDITING_OVERLAYS_TOGGLE,
2590
2428
  enabled: data_2.enabled
2591
2429
  });
2592
2430
  }), comlink.on("visual-editing/documents", (data_3) => {
@@ -2597,19 +2435,19 @@ function PresentationTool(props) {
2597
2435
  data_3.documents
2598
2436
  );
2599
2437
  }), comlink.on("visual-editing/refreshing", (data_4) => {
2600
- data_4.source === "manual" ? clearTimeout(refreshRef.current) : data_4.source === "mutation" && presentationRef.send({
2601
- type: "iframe refresh"
2438
+ data_4.source === "manual" ? clearTimeout(refreshRef.current) : data_4.source === "mutation" && dispatch({
2439
+ type: ACTION_IFRAME_REFRESH
2602
2440
  });
2603
2441
  }), comlink.on("visual-editing/refreshed", () => {
2604
- presentationRef.send({
2605
- type: "iframe loaded"
2442
+ dispatch({
2443
+ type: ACTION_IFRAME_LOADED
2606
2444
  });
2607
2445
  }), comlink.onStatus(setOverlaysConnection);
2608
2446
  const stop = comlink.start();
2609
2447
  return setVisualEditingComlink(comlink), () => {
2610
2448
  stop(), setVisualEditingComlink(null);
2611
2449
  };
2612
- }, [controller, presentationRef, setDocumentsOnPage, setOverlaysConnection, targetOrigin]), useEffect(() => {
2450
+ }, [controller, setDocumentsOnPage, setOverlaysConnection, targetOrigin]), useEffect(() => {
2613
2451
  if (!controller) return;
2614
2452
  const comlink_0 = controller.createChannel({
2615
2453
  name: "presentation",
@@ -2632,13 +2470,11 @@ function PresentationTool(props) {
2632
2470
  path: studioPath.toString(nextPath)
2633
2471
  }, {}, !0);
2634
2472
  }, [navigate]), handlePreviewPath = useCallback((nextPath_0) => {
2635
- const url_0 = new URL(nextPath_0, targetOrigin), preview = url_0.toString();
2636
- params.preview !== preview && (Array.isArray(allowOrigins) ? allowOrigins.some((pattern) => pattern.test(preview)) && navigate({}, {
2473
+ const url_0 = new URL(nextPath_0, initialPreviewUrl.origin), preview = url_0.pathname + url_0.search;
2474
+ url_0.origin === initialPreviewUrl.origin && preview !== params.preview && navigate({}, {
2637
2475
  preview
2638
- }) : url_0.origin === targetOrigin && navigate({}, {
2639
- preview
2640
- }));
2641
- }, [targetOrigin, params.preview, allowOrigins, navigate]), handleStructureParams = useCallback((structureParams_0) => {
2476
+ });
2477
+ }, [initialPreviewUrl, params, navigate]), handleStructureParams = useCallback((structureParams_0) => {
2642
2478
  navigate({}, structureParams_0);
2643
2479
  }, [navigate]);
2644
2480
  useEffect(() => {
@@ -2647,27 +2483,10 @@ function PresentationTool(props) {
2647
2483
  path: params.path
2648
2484
  }) : visualEditingComlink?.post("presentation/blur");
2649
2485
  }, [params.id, params.path, visualEditingComlink]), useEffect(() => {
2650
- if (frameStateRef.current.url && params.preview && frameStateRef.current.url !== params.preview) {
2651
- try {
2652
- const frameOrigin = new URL(frameStateRef.current.url, targetOrigin).origin, previewOrigin = new URL(params.preview, targetOrigin).origin;
2653
- if (frameOrigin !== previewOrigin)
2654
- return;
2655
- } catch {
2656
- }
2657
- if (frameStateRef.current.url = params.preview, overlaysConnection === "connected") {
2658
- let url_1 = params.preview;
2659
- if (url_1.startsWith("http"))
2660
- try {
2661
- const newUrl = new URL(params.preview, targetOrigin);
2662
- url_1 = newUrl.pathname + newUrl.search + newUrl.hash;
2663
- } catch {
2664
- }
2665
- visualEditingComlink?.post("presentation/navigate", {
2666
- url: url_1,
2667
- type: "replace"
2668
- });
2669
- }
2670
- }
2486
+ frameStateRef.current.url && params.preview && frameStateRef.current.url !== params.preview && (frameStateRef.current.url = params.preview, overlaysConnection !== "connected" && iframeRef.current ? iframeRef.current.src = `${targetOrigin}${params.preview}` : visualEditingComlink?.post("presentation/navigate", {
2487
+ url: params.preview,
2488
+ type: "replace"
2489
+ }));
2671
2490
  }, [overlaysConnection, targetOrigin, params.preview, visualEditingComlink]);
2672
2491
  const toggleOverlay = useCallback(() => visualEditingComlink?.post("presentation/toggle-overlay"), [visualEditingComlink]), [displayedDocument, setDisplayedDocument] = useState(null);
2673
2492
  useEffect(() => {
@@ -2686,8 +2505,8 @@ function PresentationTool(props) {
2686
2505
  }, PresentationNavigator] = usePresentationNavigator({
2687
2506
  unstable_navigator
2688
2507
  }), refreshRef = useRef(void 0), handleRefresh = useCallback((fallback) => {
2689
- if (presentationRef.send({
2690
- type: "iframe refresh"
2508
+ if (dispatch({
2509
+ type: ACTION_IFRAME_REFRESH
2691
2510
  }), visualEditingComlink) {
2692
2511
  refreshRef.current = window.setTimeout(fallback, 300), visualEditingComlink.post("presentation/refresh", {
2693
2512
  source: "manual",
@@ -2696,7 +2515,7 @@ function PresentationTool(props) {
2696
2515
  return;
2697
2516
  }
2698
2517
  fallback();
2699
- }, [loadersConnection, presentationRef, previewKitConnection, visualEditingComlink]), workspace = useWorkspace(), getCommentIntent = useCallback(({
2518
+ }, [loadersConnection, previewKitConnection, visualEditingComlink]), workspace = useWorkspace(), getCommentIntent = useCallback(({
2700
2519
  id,
2701
2520
  type,
2702
2521
  path
@@ -2729,7 +2548,9 @@ function PresentationTool(props) {
2729
2548
  canSharePreviewAccess,
2730
2549
  canToggleSharePreviewAccess,
2731
2550
  canUseSharedPreviewAccess,
2551
+ dispatch,
2732
2552
  header: unstable_header,
2553
+ iframe: state.iframe,
2733
2554
  initialUrl: initialPreviewUrl,
2734
2555
  loadersConnection,
2735
2556
  navigatorEnabled,
@@ -2745,9 +2566,8 @@ function PresentationTool(props) {
2745
2566
  toggleNavigator,
2746
2567
  toggleOverlay,
2747
2568
  viewport,
2748
- vercelProtectionBypass,
2749
- presentationRef,
2750
- previewUrlRef
2569
+ visualEditing: state.visualEditing,
2570
+ vercelProtectionBypass
2751
2571
  },
2752
2572
  targetOrigin
2753
2573
  ) }) }) }),
@@ -2777,824 +2597,13 @@ const IS_MAC = typeof window < "u" && /Mac|iPod|iPhone|iPad/.test(window.navigat
2777
2597
  function isHotkey(keys, event) {
2778
2598
  return keys.every((key) => MODIFIERS[key] ? event[MODIFIERS[key]] : event.key === key.toUpperCase());
2779
2599
  }
2780
- function defineCreatePreviewSecretActor({
2781
- client,
2782
- currentUserId
2783
- }) {
2784
- return fromPromise(async () => await createPreviewSecret(client, "sanity/presentation", location.href, currentUserId));
2785
- }
2786
- function defineReadSharedSecretActor({
2787
- client
2788
- }) {
2789
- return fromPromise(async () => client.fetch(fetchSharedAccessQuery, {}, {
2790
- tag: "presentation.fallback-to-shared-access-secret"
2791
- }));
2792
- }
2793
- function defineResolveAllowPatternsActor({
2794
- client,
2795
- allowOption
2796
- }) {
2797
- return fromPromise(async ({
2798
- input
2799
- }) => {
2800
- const {
2801
- initialUrl
2802
- } = input;
2803
- if (typeof URLPattern > "u" && await import("urlpattern-polyfill"), !allowOption)
2804
- return [new URLPattern(initialUrl.origin)];
2805
- const maybePatterns = typeof allowOption == "function" ? await allowOption({
2806
- client,
2807
- origin,
2808
- initialUrl
2809
- }) : allowOption, urlPatterns = (Array.isArray(maybePatterns) ? maybePatterns : [maybePatterns]).map((value) => {
2810
- const urlPattern = new URLPattern(value);
2811
- if (urlPattern.hostname === "*")
2812
- throw new Error("It's insecure to allow any hostname, it could disclose data to a malicious site");
2813
- return urlPattern;
2814
- });
2815
- return urlPatterns.some((pattern) => pattern.test(initialUrl.origin)) ? urlPatterns : [...urlPatterns, new URLPattern(initialUrl.origin)];
2816
- });
2817
- }
2818
- function defineResolveInitialUrlActor({
2819
- client,
2820
- studioBasePath,
2821
- previewUrlOption,
2822
- perspective
2823
- }) {
2824
- return fromPromise(async ({
2825
- input
2826
- }) => {
2827
- const {
2828
- origin: origin2
2829
- } = location;
2830
- if (typeof previewUrlOption == "function") {
2831
- const initial = await previewUrlOption({
2832
- client,
2833
- studioBasePath,
2834
- // @TODO handle checking permissions here, and then generating a secret
2835
- previewUrlSecret: "",
2836
- studioPreviewPerspective: encodeStudioPerspective(perspective),
2837
- previewSearchParam: input.previewSearchParam
2838
- });
2839
- return new URL(initial, origin2);
2840
- }
2841
- if (!previewUrlOption)
2842
- return new URL("/", origin2);
2843
- if (typeof previewUrlOption == "string")
2844
- return new URL(previewUrlOption, origin2);
2845
- if (typeof previewUrlOption.initial == "function") {
2846
- const initial = await previewUrlOption.initial({
2847
- client,
2848
- origin: origin2
2849
- });
2850
- return new URL(initial, origin2);
2851
- }
2852
- return typeof previewUrlOption.initial == "string" ? new URL(previewUrlOption.initial, origin2) : new URL(previewUrlOption.preview || "/", previewUrlOption.origin || origin2);
2853
- });
2854
- }
2855
- function defineResolvePreviewModeActor({
2856
- client,
2857
- previewUrlOption
2858
- }) {
2859
- return fromPromise(async ({
2860
- input
2861
- }) => {
2862
- const {
2863
- targetOrigin
2864
- } = input;
2865
- if (typeof previewUrlOption == "object" && previewUrlOption?.draftMode)
2866
- return {
2867
- enable: previewUrlOption.draftMode.enable,
2868
- shareAccess: previewUrlOption.draftMode.shareAccess ?? !0
2869
- };
2870
- if (!previewUrlOption || typeof previewUrlOption == "string" || typeof previewUrlOption == "function" || !previewUrlOption.previewMode)
2871
- return !1;
2872
- const previewMode = typeof previewUrlOption.previewMode == "function" ? await previewUrlOption.previewMode({
2873
- client,
2874
- origin,
2875
- targetOrigin
2876
- }) : previewUrlOption.previewMode;
2877
- return previewMode === !1 ? !1 : {
2878
- enable: previewMode.enable,
2879
- shareAccess: previewMode.shareAccess ?? !0
2880
- };
2881
- });
2882
- }
2883
- function defineResolvePreviewModeUrlActor({
2884
- client,
2885
- studioBasePath,
2886
- previewUrlOption,
2887
- perspective
2888
- }) {
2889
- return fromPromise(async ({
2890
- input
2891
- }) => {
2892
- const {
2893
- previewUrlSecret,
2894
- resolvedPreviewMode,
2895
- initialUrl
2896
- } = input;
2897
- if (typeof previewUrlOption == "function") {
2898
- const initial = await previewUrlOption({
2899
- client,
2900
- studioBasePath,
2901
- previewUrlSecret,
2902
- studioPreviewPerspective: encodeStudioPerspective(perspective),
2903
- previewSearchParam: initialUrl.toString()
2904
- });
2905
- return new URL(initial, initialUrl);
2906
- }
2907
- if (!resolvedPreviewMode)
2908
- throw new Error("Resolved preview mode is false");
2909
- const url = new URL(resolvedPreviewMode.enable, initialUrl);
2910
- return url.searchParams.set(urlSearchParamPreviewSecret, previewUrlSecret), url.searchParams.set(urlSearchParamPreviewPerspective, encodeStudioPerspective(perspective)), initialUrl.pathname !== url.pathname && url.searchParams.set(urlSearchParamPreviewPathname, `${initialUrl.pathname}${initialUrl.search}${initialUrl.hash}`), url;
2911
- });
2912
- }
2913
- const resolveUrlFromPreviewSearchParamActor = fromPromise(async ({
2914
- input
2915
- }) => {
2916
- const {
2917
- previewSearchParam,
2918
- initialUrl,
2919
- allowOrigins
2920
- } = input;
2921
- if (!previewSearchParam)
2922
- return initialUrl;
2923
- try {
2924
- const previewSearchParamUrl = new URL(previewSearchParam, initialUrl.origin);
2925
- return allowOrigins.some((pattern) => pattern.test(previewSearchParamUrl.origin)) ? previewSearchParamUrl : initialUrl;
2926
- } catch {
2927
- return initialUrl;
2928
- }
2929
- }), shareAccessSingletonDocument = {
2930
- _id: schemaIdSingleton,
2931
- _type: schemaTypeSingleton
2932
- }, previewUrlSecretDocument = {
2933
- _id: `drafts.${uuid()}`,
2934
- _type: schemaType
2935
- }, previewUrlMachine = setup({
2936
- types: {},
2937
- actions: {
2938
- "notify preview will likely fail": log("Missing permissions to create preview secret, or read shared preview secret. Preview will likely fail loading."),
2939
- "assign preview search param": assign({
2940
- previewSearchParam: (_, params) => params.previewSearchParam
2941
- }),
2942
- "assign error": assign({
2943
- error: (_, params) => params.error instanceof Error ? params.error : new Error(params.message, {
2944
- cause: params.error
2945
- })
2946
- })
2947
- },
2948
- actors: {
2949
- "check permission": fromObservable(() => throwError(() => new Error("The 'check permission' actor is not implemented. Add it to previewUrlMachine.provide({actors: {'check permission': fromObservable(({input}: {input: CheckPermissionInput}) => ...)}})"))),
2950
- "resolve initial url": fromPromise(() => Promise.reject(new Error("The 'resolve initial url' actor is not implemented. Add it to previewUrlMachine.provide({actors: {'resolve initial url': fromPromise(...)}})"))),
2951
- "resolve allow patterns": fromPromise(() => Promise.reject(new Error("The 'resolve allow patterns' actor is not implemented. Add it to previewUrlMachine.provide({actors: {'resolve allow pattern': fromPromise(...)}})"))),
2952
- "resolve url from preview search param": resolveUrlFromPreviewSearchParamActor,
2953
- "resolve preview mode": fromPromise(() => Promise.reject(new Error("The 'resolve preview mode' actor is not implemented. Add it to previewUrlMachine.provide({actors: {'resolve preview mode': fromPromise(...)}})"))),
2954
- "create preview secret": fromPromise(async () => Promise.reject(new Error("The 'create preview secret' actor is not implemented. Add it to previewUrlMachine.provide({actors: {'create preview secret': fromPromise(...)}})"))),
2955
- "read shared preview secret": fromPromise(async () => Promise.reject(new Error("The 'read shared preview secret' actor is not implemented. Add it to previewUrlMachine.provide({actors: {'read shared preview secret': fromPromise(...)}})"))),
2956
- "resolve preview mode url": fromPromise(() => Promise.reject(new Error("The 'resolve preview mode url' actor is not implemented. Add it to previewUrlMachine.provide({actors: {'resolve preview mode url': fromPromise(...)}})")))
2957
- },
2958
- guards: {
2959
- "has checked permissions": ({
2960
- context
2961
- }) => !!(context.previewAccessSharingCreatePermission && context.previewAccessSharingReadPermission && context.previewAccessSharingUpdatePermission && context.previewUrlSecretPermission),
2962
- "search param has new origin": ({
2963
- context,
2964
- event
2965
- }) => {
2966
- if (!context.previewUrl || !event.previewSearchParam)
2967
- return !1;
2968
- try {
2969
- const previewSearchParamUrl = new URL(event.previewSearchParam, context.previewUrl);
2970
- return context.previewUrl.origin !== previewSearchParamUrl.origin;
2971
- } catch {
2972
- return !1;
2973
- }
2974
- },
2975
- "can create preview secret": ({
2976
- context
2977
- }) => context.previewUrlSecretPermission?.granted === !0,
2978
- "has preview mode with created secret": ({
2979
- context
2980
- }, params) => params === !1 ? !1 : context.previewUrlSecretPermission?.granted === !0,
2981
- "has preview mode with share access": ({
2982
- context
2983
- }, params) => params === !1 ? !1 : context.previewAccessSharingReadPermission?.granted === !0,
2984
- "has preview mode without permissions": ({
2985
- context
2986
- }, params) => params === !1 ? !1 : context.previewAccessSharingReadPermission?.granted === !1 && context.previewUrlSecretPermission?.granted === !1
2987
- },
2988
- delays: {
2989
- expiredSecret: ({
2990
- context
2991
- }) => {
2992
- if (!context.previewUrlSecret?.expiresAt)
2993
- return 0;
2994
- const now = Date.now(), expiresAt = context.previewUrlSecret.expiresAt.getTime();
2995
- return Math.max(expiresAt - now, 0);
2996
- }
2997
- }
2998
- }).createMachine({
2999
- // eslint-disable-next-line tsdoc/syntax
3000
- /** @xstate-layout N4IgpgJg5mDOIC5QAUBOYBuBLMB3ABAKoBKAMgMRiqoD2qAdAA4A2AhgC4BmdAtvWphwESpBFgB2GGgGMOWGuIDaABgC6K1YlCMasLO3nitIAB6IArAA56AZgCcAdkcBGS8vMAmO+YBszgDQgAJ6Izs4+9M7KACzKztGWHg4OPubmAL7pgQLYeERklNR0TGxcvPzoucJkYpIycgqKzupqxjp6BgrGZggAtM520ZHRdjZjNjFe7oEhCGERUbHxicmpGVkgOUL5FFS0DCwc3Kh8W3kitVKynUoeLZpIIO36ht2IvV62Hl7elmE2lh83xmoXCkRicQSSRS5gSmWylW2IkK+xKR3KZ2qogkVwaShs9zauheXUePV6gPo3jSUyi-xBczBi0hKxh5mc8M2iPOBVgYHY+EY3IIfNYqGkAAtBWLWDwNESOq8yaCbM56A4bB5fGllHYvD4fAz4h56CNfG5LKqHMpLdFOZidvRJWBpABrCRQZBUHhYWB6BSwcjyx7PG5vPrs5TqjWqyyjTXRDwMjwxei68J2ZQ2nyWXN2jYOkT0dCwGjMbDiKAASXEL1YzEIqGY5AgCjA9BxNFd7cLZGLcDLFertYM9cbzEu9RuGmD2mJYeVfRGdipyh86Yc0XiE3MDK3JssIwcrmtPjGSXzCMEPNI-dL5Y9NbrDabKOKhzKJwq16xd8Hj5HLAxybSdrkMGdWhDeclVAclN3odlzBsKwBjSSxjwcZM7DVeJ1w8P4xmidk7HtYVHRLf9KwAQWYZgaFwZAOHYKhxEDVtxHbTtu2-KpyIHB9qNo+jGPYZjUFY0C8Qgh450VUlYPedkHHoHwnDSZDVOiGwfGiBlUhXXwwjsQYtKSYzSJ-Pj7yHGi6IYpiWMDPZ31KY5TjIosKIEqBbOEhzxNgSTpzUWcnmg+TTHePV6Hw3MYgzaItJ0hlYRNTNkLiHxBl1GILN4zz+KHccADFaB4TEAGUwDFSVGNQWUWzbDs6m43tby8oqm1KmhyuFKqaolOrZSC8CQsg2SSSMRdel8ZSNUTdlcw8M07AZQZrDXdaDRtUZnHWK98r7DqPRKsrKuq8VBplHg3wOVyMQ8o7CpOrqzr6i7auukbGjGmSwrkqaFL6MJlLiWFlC1EGty0hknAiXVVPMRx12UJwOQLR72ueytMQAWRoCAwEajjmqkVrMb-by8YJsBvqUX6FUm8Nem2+hbWPUZErGTcjS8NUJg8AE9T1ZwHHwvKkSe6yPWpwnic4lqewp46ceFfHCbpmdmkZhcgZmyxzFsDmTPcXUUiNRKDy3ZQJlVLSkYlm9KaHWWifYhWyaVyyCul1Wf3V2nOzAn71DuHWYMivovGsBxPCy74beWaJDWCUJzBSFTrUcQYdMzIFHd-FXPTVmn5dJrsvcOrHfeL-2ac1kKCXDiLyWcNKJiiHM-BtONwgtnMEM1DVNwhhI7B8AurMo2uqgD260U-dzval6fXYbwkoIB5moijLLkm5tvYRBo1nGQtND11ZaIdzEiMeX6vV5LuW+QFIVLNFS7pXquVxv+pnF1FtYP4OY7AG3QohJMqcEDeGUq4NwYQBhLEnkWWAABXaQ0g4CBhfoKMiH9JRf1lKFUMEceiizVPA0+7gtQQy8LzXU6obaJTFtEJwHhXDIL7G-WepccHcO2PgqUjBrrEPCoDSOFI3C2AGHtQ8sIiJJGTILZS7JRaeGSKw7CnDbz8LwAHJ06AOBgHOtIdA7Ay5cUrpLHRT92ymOqsxExZj16iK3gAqI6oaQ6QtE4YylhkynzmkCBGNgNR7VvgdaxTBbEGIccY969jzHOTuuiL8bVol10JrEoxTj+QuN-iQlu7xwjKX1P8bSTC0hGhcKaBIOZAQGkBKE7RGSeFZMMRACqEoxRgCohgrBFjFY8Sibo3A+iOldJ6X0zBfp8l-UKeIshjgqTGTiPYPaGotS7igd8QWtgsp6iQnFOEd8q6tKEOM6qnTunoGmQM5JC83LDKdqMy5rBrlTP6bMoOUkGab3-kDU+ERVEpnsEjDRVSdljBXKeQY3h5gOBaa8mmzt4k-nHIMz2zzfzIvaYVNFVRxxzObosxAfg1Q2jSOERIh5kIBNGKaNZ2lvjhFhEimJHUCVCAxQ8j8Tz0m4vbJyzERKfnBQ3hNXWkdyWeJsCMVhqNsK6mTO4Q2Q9DysLCEhDw7LMntjQV8wMJhYDsCMfQVgnAxIAAowAmEYFgdAnSXRmIAJTkAFTEg1MzYCuIBZHKYKlUiqWwrCMJkDZgDAYceRMfwUisPYZYTIGxxA03gI8NqJLmZ6msKqENcjErqIZL0cethvDGXLew9hiYWnOjdDLb0vp-SsUzdNcwEMEJ7WTohDMfgU4RpTCpUJnhYrHghuEFpRcnyjhfMwFtet2Q2FNOwsWZarBan8TsuMkRvhIzPJGDwmkWnJLnf6g0aZl0mQTURDdsxYiGwwsRIEgwEwTuxj5IS9lRKORPeSJCOF4XgrUZqbZsxwZszcJtbC4RUg2FfTXU6PVzoDSGjwH9ik-gxRGG4NtxkkZblhgyxIhFQG5lSPEODj89VoYjKqGKURkij0zImXSUCwiozZuDLUCQQY6tOVEr1WDqMsxNCkP4RFPBZj+I4I0qoRMODjIlceBzkK6raWAIT7DDZlNPhUuVkKI0pEXbHBISF1yAiIqpi5KL7E5ISWYoTna2b6Qg+DcFN7EAphLdpdOWVoPJ0RXxl5HKrmTNuYahzaQviaQPVERa8mlGeBUnnQyDStSwcCzi4L1kuV4HHNR4DCFdRaVVFSzcZ4VVIVsDEVhZ5QnWlYZZvRKLj3-KlT0FIKjVRZghkCXwqkjQGzVFxvOMisoWYy46QV9ABN+mo3mFZZ427lp032jzVa2bJGtCUtciak1AA */
3001
- id: "Preview URL",
3002
- context: ({
3003
- input
3004
- }) => ({
3005
- initialUrl: null,
3006
- previewUrl: null,
3007
- error: null,
3008
- allowOrigins: null,
3009
- previewSearchParam: input.previewSearchParam,
3010
- previewUrlSecret: null,
3011
- previewAccessSharingCreatePermission: null,
3012
- previewAccessSharingReadPermission: null,
3013
- previewAccessSharingUpdatePermission: null,
3014
- previewUrlSecretPermission: null,
3015
- previewMode: null
3016
- }),
3017
- invoke: [{
3018
- src: "check permission",
3019
- input: () => ({
3020
- checkPermissionName: "read",
3021
- document: shareAccessSingletonDocument
3022
- }),
3023
- onError: {
3024
- target: ".error",
3025
- actions: {
3026
- type: "assign error",
3027
- params: ({
3028
- event
3029
- }) => ({
3030
- message: "Failed to check permission",
3031
- error: event.error
3032
- })
3033
- }
3034
- },
3035
- onSnapshot: {
3036
- actions: assign({
3037
- previewAccessSharingReadPermission: ({
3038
- event
3039
- }) => event.snapshot.context ?? null
3040
- })
3041
- }
3042
- }, {
3043
- src: "check permission",
3044
- input: () => ({
3045
- checkPermissionName: "create",
3046
- document: shareAccessSingletonDocument
3047
- }),
3048
- onError: {
3049
- target: ".error",
3050
- actions: {
3051
- type: "assign error",
3052
- params: ({
3053
- event
3054
- }) => ({
3055
- message: "Failed to check permission",
3056
- error: event.error
3057
- })
3058
- }
3059
- },
3060
- onSnapshot: {
3061
- actions: assign({
3062
- previewAccessSharingCreatePermission: ({
3063
- event
3064
- }) => event.snapshot.context ?? null
3065
- })
3066
- }
3067
- }, {
3068
- src: "check permission",
3069
- input: () => ({
3070
- checkPermissionName: "update",
3071
- document: shareAccessSingletonDocument
3072
- }),
3073
- onError: {
3074
- target: ".error",
3075
- actions: {
3076
- type: "assign error",
3077
- params: ({
3078
- event
3079
- }) => ({
3080
- message: "Failed to check permission",
3081
- error: event.error
3082
- })
3083
- }
3084
- },
3085
- onSnapshot: {
3086
- actions: assign({
3087
- previewAccessSharingUpdatePermission: ({
3088
- event
3089
- }) => event.snapshot.context ?? null
3090
- })
3091
- }
3092
- }, {
3093
- src: "check permission",
3094
- input: () => ({
3095
- checkPermissionName: "create",
3096
- document: previewUrlSecretDocument
3097
- }),
3098
- onError: {
3099
- target: ".error",
3100
- actions: {
3101
- type: "assign error",
3102
- params: ({
3103
- event
3104
- }) => ({
3105
- message: "Failed to check permission",
3106
- error: event.error
3107
- })
3108
- }
3109
- },
3110
- onSnapshot: {
3111
- actions: assign({
3112
- previewUrlSecretPermission: ({
3113
- event
3114
- }) => event.snapshot.context ?? null
3115
- })
3116
- }
3117
- }],
3118
- on: {
3119
- "set preview search param": {
3120
- actions: {
3121
- type: "assign preview search param",
3122
- params: ({
3123
- event
3124
- }) => ({
3125
- previewSearchParam: event.previewSearchParam
3126
- })
3127
- }
3128
- }
3129
- },
3130
- states: {
3131
- checkingPermissions: {
3132
- always: {
3133
- guard: "has checked permissions",
3134
- target: "resolvingInitialUrl"
3135
- },
3136
- tags: "busy"
3137
- },
3138
- resolvingInitialUrl: {
3139
- invoke: {
3140
- src: "resolve initial url",
3141
- input: ({
3142
- context
3143
- }) => ({
3144
- previewSearchParam: context.previewSearchParam
3145
- }),
3146
- onError: {
3147
- target: "error",
3148
- actions: {
3149
- type: "assign error",
3150
- params: ({
3151
- event
3152
- }) => ({
3153
- message: "Failed to resolve initial url",
3154
- error: event.error
3155
- })
3156
- }
3157
- },
3158
- onDone: {
3159
- target: "resolvingAllowPatterns",
3160
- actions: assign({
3161
- initialUrl: ({
3162
- event
3163
- }) => event.output
3164
- })
3165
- }
3166
- },
3167
- tags: "busy"
3168
- },
3169
- error: {
3170
- type: "final",
3171
- tags: "error"
3172
- },
3173
- resolvingAllowPatterns: {
3174
- invoke: {
3175
- src: "resolve allow patterns",
3176
- input: ({
3177
- context
3178
- }) => ({
3179
- initialUrl: context.initialUrl
3180
- }),
3181
- onError: {
3182
- target: "error",
3183
- actions: {
3184
- type: "assign error",
3185
- params: ({
3186
- event
3187
- }) => ({
3188
- message: "Failed to resolve preview url allow patterns",
3189
- error: event.error
3190
- })
3191
- }
3192
- },
3193
- onDone: {
3194
- target: "resolvingUrlFromPreviewSearchParam",
3195
- actions: assign({
3196
- allowOrigins: ({
3197
- event
3198
- }) => event.output
3199
- })
3200
- }
3201
- },
3202
- tags: ["busy"]
3203
- },
3204
- resolvingUrlFromPreviewSearchParam: {
3205
- id: "loop",
3206
- invoke: {
3207
- src: "resolve url from preview search param",
3208
- input: ({
3209
- context
3210
- }) => ({
3211
- initialUrl: context.initialUrl,
3212
- allowOrigins: context.allowOrigins,
3213
- previewSearchParam: context.previewSearchParam
3214
- }),
3215
- onError: {
3216
- target: "error",
3217
- actions: {
3218
- type: "assign error",
3219
- params: ({
3220
- event
3221
- }) => ({
3222
- message: "Failed to resolve preview url from search param",
3223
- error: event.error
3224
- })
3225
- }
3226
- },
3227
- onDone: {
3228
- target: "resolvingPreviewMode",
3229
- actions: assign({
3230
- initialUrl: ({
3231
- event
3232
- }) => event.output
3233
- })
3234
- }
3235
- },
3236
- tags: ["busy"]
3237
- },
3238
- resolvingPreviewMode: {
3239
- on: {
3240
- "set preview search param": {
3241
- guard: "search param has new origin",
3242
- actions: {
3243
- type: "assign preview search param",
3244
- params: ({
3245
- event
3246
- }) => ({
3247
- previewSearchParam: event.previewSearchParam
3248
- })
3249
- },
3250
- target: "#loop",
3251
- reenter: !0
3252
- }
3253
- },
3254
- invoke: {
3255
- src: "resolve preview mode",
3256
- input: ({
3257
- context
3258
- }) => ({
3259
- targetOrigin: context.initialUrl.origin
3260
- }),
3261
- onError: {
3262
- target: "error",
3263
- actions: {
3264
- type: "assign error",
3265
- params: ({
3266
- event
3267
- }) => ({
3268
- message: "Failed to resolve preview url allow patterns",
3269
- error: event.error
3270
- })
3271
- }
3272
- },
3273
- onDone: [{
3274
- guard: {
3275
- type: "has preview mode with created secret",
3276
- params: ({
3277
- event
3278
- }) => event.output
3279
- },
3280
- actions: assign({
3281
- previewMode: ({
3282
- event
3283
- }) => event.output
3284
- }),
3285
- target: "previewMode.createPreviewSecret"
3286
- }, {
3287
- guard: {
3288
- type: "has preview mode with share access",
3289
- params: ({
3290
- event
3291
- }) => event.output
3292
- },
3293
- actions: assign({
3294
- previewMode: ({
3295
- event
3296
- }) => event.output
3297
- }),
3298
- target: "previewMode.readShareAccess"
3299
- }, {
3300
- guard: {
3301
- type: "has preview mode without permissions",
3302
- params: ({
3303
- event
3304
- }) => event.output
3305
- },
3306
- actions: [assign({
3307
- previewUrl: ({
3308
- context
3309
- }) => context.initialUrl
3310
- }), "notify preview will likely fail"],
3311
- target: "success"
3312
- }, {
3313
- actions: assign({
3314
- previewUrl: ({
3315
- context
3316
- }) => context.initialUrl
3317
- }),
3318
- target: "success"
3319
- }]
3320
- },
3321
- tags: ["busy"]
3322
- },
3323
- success: {
3324
- on: {
3325
- "set preview search param": {
3326
- guard: "search param has new origin",
3327
- actions: {
3328
- type: "assign preview search param",
3329
- params: ({
3330
- event
3331
- }) => ({
3332
- previewSearchParam: event.previewSearchParam
3333
- })
3334
- },
3335
- target: "#loop",
3336
- reenter: !0
3337
- }
3338
- }
3339
- },
3340
- previewMode: {
3341
- on: {
3342
- "set preview search param": {
3343
- guard: "search param has new origin",
3344
- actions: {
3345
- type: "assign preview search param",
3346
- params: ({
3347
- event
3348
- }) => ({
3349
- previewSearchParam: event.previewSearchParam
3350
- })
3351
- },
3352
- target: "#loop",
3353
- reenter: !0
3354
- }
3355
- },
3356
- states: {
3357
- createPreviewSecret: {
3358
- invoke: {
3359
- src: "create preview secret",
3360
- onError: {
3361
- target: "error",
3362
- actions: {
3363
- type: "assign error",
3364
- params: ({
3365
- event
3366
- }) => ({
3367
- message: "Failed to create preview secret",
3368
- error: event.error
3369
- })
3370
- }
3371
- },
3372
- onDone: {
3373
- target: "resolvePreviewUrl",
3374
- actions: assign({
3375
- previewUrlSecret: ({
3376
- event
3377
- }) => event.output
3378
- })
3379
- }
3380
- },
3381
- tags: ["busy"]
3382
- },
3383
- readShareAccess: {
3384
- invoke: {
3385
- src: "read shared preview secret",
3386
- onError: {
3387
- target: "error",
3388
- actions: {
3389
- type: "assign error",
3390
- params: ({
3391
- event
3392
- }) => ({
3393
- message: "Failed to read shared preview secret",
3394
- error: event.error
3395
- })
3396
- }
3397
- },
3398
- onDone: {
3399
- target: "resolvePreviewUrl",
3400
- actions: assign({
3401
- previewUrlSecret: ({
3402
- event
3403
- }) => ({
3404
- secret: event.output,
3405
- expiresAt: new Date(Date.now() + 1e3 * 60 * 60 * 60 * 24)
3406
- })
3407
- })
3408
- }
3409
- },
3410
- tags: ["busy"]
3411
- },
3412
- resolvePreviewUrl: {
3413
- invoke: {
3414
- src: "resolve preview mode url",
3415
- input: ({
3416
- context
3417
- }) => ({
3418
- initialUrl: context.initialUrl,
3419
- resolvedPreviewMode: context.previewMode,
3420
- previewUrlSecret: context.previewUrlSecret.secret
3421
- }),
3422
- onError: {
3423
- target: "error",
3424
- actions: {
3425
- type: "assign error",
3426
- params: ({
3427
- event
3428
- }) => ({
3429
- message: "Failed to resolve preview url",
3430
- error: event.error
3431
- })
3432
- }
3433
- },
3434
- onDone: {
3435
- target: "success",
3436
- actions: assign({
3437
- previewUrl: ({
3438
- event
3439
- }) => event.output
3440
- })
3441
- }
3442
- },
3443
- tags: ["busy"]
3444
- },
3445
- error: {
3446
- type: "final",
3447
- tags: ["error"]
3448
- },
3449
- success: {
3450
- after: {
3451
- expiredSecret: {
3452
- guard: "can create preview secret",
3453
- actions: assign({
3454
- previewUrlSecret: null
3455
- }),
3456
- target: "createPreviewSecret",
3457
- reenter: !0
3458
- }
3459
- }
3460
- }
3461
- },
3462
- initial: "readShareAccess"
3463
- }
3464
- },
3465
- initial: "checkingPermissions"
3466
- });
3467
- function usePreviewUrlActorRef(previewUrlOption, allowOption) {
3468
- const $ = c(24), grantsStore = useGrantsStore();
3469
- let t0;
3470
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
3471
- apiVersion: API_VERSION
3472
- }, $[0] = t0) : t0 = $[0];
3473
- const client = useClient(t0), currentUserId = useCurrentUser()?.id, studioBasePath = useActiveWorkspace()?.activeWorkspace?.basePath || "/", router = useRouter();
3474
- let t1;
3475
- $[1] !== router.state._searchParams ? (t1 = new URLSearchParams(router.state._searchParams).get("preview"), $[1] = router.state._searchParams, $[2] = t1) : t1 = $[2];
3476
- const previewSearchParam = t1, {
3477
- push: pushToast
3478
- } = useToast(), {
3479
- t
3480
- } = useTranslation(presentationLocaleNamespace), perspective = usePresentationPerspective();
3481
- let t2;
3482
- if ($[3] !== allowOption || $[4] !== client || $[5] !== currentUserId || $[6] !== grantsStore || $[7] !== perspective || $[8] !== previewUrlOption || $[9] !== pushToast || $[10] !== studioBasePath || $[11] !== t) {
3483
- let t32;
3484
- $[13] !== pushToast || $[14] !== t ? (t32 = () => pushToast({
3485
- id: "preview-url-secret.missing-grants",
3486
- closable: !0,
3487
- status: "error",
3488
- duration: 1 / 0,
3489
- title: t("preview-url-secret.missing-grants")
3490
- }), $[13] = pushToast, $[14] = t, $[15] = t32) : t32 = $[15];
3491
- let t42;
3492
- $[16] !== grantsStore ? (t42 = (t52) => {
3493
- const {
3494
- input
3495
- } = t52;
3496
- return grantsStore.checkDocumentPermission(input.checkPermissionName, input.document);
3497
- }, $[16] = grantsStore, $[17] = t42) : t42 = $[17], t2 = previewUrlMachine.provide({
3498
- actions: {
3499
- "notify preview will likely fail": t32
3500
- },
3501
- actors: {
3502
- "create preview secret": defineCreatePreviewSecretActor({
3503
- client,
3504
- currentUserId
3505
- }),
3506
- "read shared preview secret": defineReadSharedSecretActor({
3507
- client
3508
- }),
3509
- "resolve allow patterns": defineResolveAllowPatternsActor({
3510
- client,
3511
- allowOption
3512
- }),
3513
- "resolve initial url": defineResolveInitialUrlActor({
3514
- client,
3515
- studioBasePath,
3516
- previewUrlOption,
3517
- perspective
3518
- }),
3519
- "resolve preview mode": defineResolvePreviewModeActor({
3520
- client,
3521
- previewUrlOption
3522
- }),
3523
- "resolve preview mode url": defineResolvePreviewModeUrlActor({
3524
- client,
3525
- studioBasePath,
3526
- previewUrlOption,
3527
- perspective
3528
- }),
3529
- "check permission": fromObservable(t42)
3530
- }
3531
- }), $[3] = allowOption, $[4] = client, $[5] = currentUserId, $[6] = grantsStore, $[7] = perspective, $[8] = previewUrlOption, $[9] = pushToast, $[10] = studioBasePath, $[11] = t, $[12] = t2;
3532
- } else
3533
- t2 = $[12];
3534
- let t3;
3535
- $[18] !== previewSearchParam ? (t3 = {
3536
- input: {
3537
- previewSearchParam
3538
- }
3539
- }, $[18] = previewSearchParam, $[19] = t3) : t3 = $[19];
3540
- const actorRef = useActorRef(t2, t3);
3541
- let t4, t5;
3542
- $[20] !== actorRef || $[21] !== previewSearchParam ? (t4 = () => {
3543
- actorRef.send({
3544
- type: "set preview search param",
3545
- previewSearchParam
3546
- });
3547
- }, t5 = [actorRef, previewSearchParam], $[20] = actorRef, $[21] = previewSearchParam, $[22] = t4, $[23] = t5) : (t4 = $[22], t5 = $[23]), useEffect(t4, t5);
3548
- const error = useSelector(actorRef, _temp$3);
3549
- if (error)
3550
- throw error;
3551
- return actorRef;
3552
- }
3553
- function _temp$3(state) {
3554
- return state.status === "error" ? state.error : state.hasTag("error") ? state.context.error : null;
3555
- }
3556
- function useReportInvalidPreviewSearchParam(previewUrlRef) {
3557
- const $ = c(9), {
3558
- t
3559
- } = useTranslation(presentationLocaleNamespace), {
3560
- push: pushToast
3561
- } = useToast(), router = useRouter();
3562
- let t0;
3563
- $[0] !== router.state._searchParams ? (t0 = new URLSearchParams(router.state._searchParams).get("preview"), $[0] = router.state._searchParams, $[1] = t0) : t0 = $[1];
3564
- const previewSearchParam = t0, allowOrigins = useSelector(previewUrlRef, _temp$2), currentOrigin = useSelector(previewUrlRef, _temp2$1);
3565
- let t1, t2;
3566
- $[2] !== allowOrigins || $[3] !== currentOrigin || $[4] !== previewSearchParam || $[5] !== pushToast || $[6] !== t ? (t1 = () => {
3567
- if (!Array.isArray(allowOrigins) || !previewSearchParam || !currentOrigin)
3568
- return;
3569
- const nextOrigin = new URL(previewSearchParam, currentOrigin).origin;
3570
- allowOrigins.some((pattern) => pattern.test(nextOrigin)) || pushToast({
3571
- closable: !0,
3572
- id: `presentation-iframe-origin-mismatch-${nextOrigin}`,
3573
- status: "error",
3574
- duration: 1 / 0,
3575
- title: t("preview-search-param.configuration.error.title"),
3576
- description: /* @__PURE__ */ jsx(Translate, { t, i18nKey: "preview-search-param.configuration.error.description", components: {
3577
- Code: "code"
3578
- }, values: {
3579
- previewSearchParam,
3580
- blockedOrigin: nextOrigin
3581
- } })
3582
- });
3583
- }, t2 = [allowOrigins, currentOrigin, previewSearchParam, pushToast, t], $[2] = allowOrigins, $[3] = currentOrigin, $[4] = previewSearchParam, $[5] = pushToast, $[6] = t, $[7] = t1, $[8] = t2) : (t1 = $[7], t2 = $[8]), useEffect(t1, t2);
3584
- }
3585
- function _temp2$1(state_0) {
3586
- return state_0.context.previewUrl?.origin;
3587
- }
3588
- function _temp$2(state) {
3589
- return state.context.allowOrigins;
3590
- }
3591
2600
  function useVercelBypassSecret() {
3592
2601
  const $ = c(7);
3593
2602
  let t0;
3594
2603
  $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
3595
2604
  apiVersion: API_VERSION
3596
2605
  }, $[0] = t0) : t0 = $[0];
3597
- const client = useClient(t0), [vercelProtectionBypassReadyState, ready] = useReducer(_temp$1, "loading"), [vercelProtectionBypassSecret, setVercelProtectionBypassSecret] = useState(null);
2606
+ const client = useClient(t0), [vercelProtectionBypassReadyState, ready] = useReducer(_temp, "loading"), [vercelProtectionBypassSecret, setVercelProtectionBypassSecret] = useState(null);
3598
2607
  let t1, t2;
3599
2608
  $[1] !== client ? (t1 = () => {
3600
2609
  const unsubscribe = subcribeToVercelProtectionBypass(client, (secret) => {
@@ -3605,37 +2614,59 @@ function useVercelBypassSecret() {
3605
2614
  let t3;
3606
2615
  return $[4] !== vercelProtectionBypassReadyState || $[5] !== vercelProtectionBypassSecret ? (t3 = [vercelProtectionBypassSecret, vercelProtectionBypassReadyState], $[4] = vercelProtectionBypassReadyState, $[5] = vercelProtectionBypassSecret, $[6] = t3) : t3 = $[6], t3;
3607
2616
  }
3608
- function _temp$1() {
2617
+ function _temp() {
3609
2618
  return "ready";
3610
2619
  }
3611
- function PresentationToolGrantsCheck(t0) {
3612
- const $ = c(8), {
3613
- tool
3614
- } = t0, previewUrlRef = usePreviewUrlActorRef(tool.options?.previewUrl, tool.options?.allowOrigins);
3615
- useReportInvalidPreviewSearchParam(previewUrlRef);
3616
- const previewAccessSharingCreatePermission = useSelector(previewUrlRef, _temp), previewAccessSharingUpdatePermission = useSelector(previewUrlRef, _temp2), previewAccessSharingReadPermission = useSelector(previewUrlRef, _temp3), previewUrlSecretPermission = useSelector(previewUrlRef, _temp4), url = useSelector(previewUrlRef, _temp5), [vercelProtectionBypass, vercelProtectionBypassReadyState] = useVercelBypassSecret();
3617
- if (!url || vercelProtectionBypassReadyState === "loading" || !previewAccessSharingCreatePermission || typeof previewAccessSharingCreatePermission.granted > "u" || !previewAccessSharingUpdatePermission || typeof previewAccessSharingUpdatePermission.granted > "u" || !previewUrlSecretPermission || !previewAccessSharingReadPermission || typeof previewAccessSharingReadPermission.granted > "u" || typeof previewUrlSecretPermission.granted > "u") {
3618
- let t12;
3619
- return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t12 = /* @__PURE__ */ jsx(PresentationSpinner, {}), $[0] = t12) : t12 = $[0], t12;
2620
+ function PresentationToolGrantsCheck(props) {
2621
+ const $ = c(17), {
2622
+ t
2623
+ } = useTranslation(presentationLocaleNamespace), {
2624
+ previewUrl
2625
+ } = props.tool.options ?? {}, {
2626
+ push: pushToast
2627
+ } = useToast(), willGeneratePreviewUrlSecret = typeof previewUrl == "object" || typeof previewUrl == "function", grantsStore = useGrantsStore(), [previewAccessSharingCreatePermission, setCreateAccessSharingPermission] = useState(null), [previewAccessSharingUpdatePermission, setUpdateAccessSharingPermission] = useState(null), [previewAccessSharingReadPermission, setReadAccessSharingPermission] = useState(null), [previewUrlSecretPermission, setPreviewUrlSecretPermission] = useState(null);
2628
+ let t0, t1;
2629
+ $[0] !== grantsStore || $[1] !== willGeneratePreviewUrlSecret ? (t0 = () => {
2630
+ if (!willGeneratePreviewUrlSecret)
2631
+ return;
2632
+ const previewCreateAccessSharingPermissionSubscription = grantsStore.checkDocumentPermission("create", {
2633
+ _id: schemaIdSingleton,
2634
+ _type: schemaTypeSingleton
2635
+ }).subscribe(setCreateAccessSharingPermission), previewUpdateAccessSharingPermissionSubscription = grantsStore.checkDocumentPermission("update", {
2636
+ _id: schemaIdSingleton,
2637
+ _type: schemaTypeSingleton
2638
+ }).subscribe(setUpdateAccessSharingPermission), previewReadAccessSharingPermissionSubscription = grantsStore.checkDocumentPermission("read", {
2639
+ _id: schemaIdSingleton,
2640
+ _type: schemaTypeSingleton
2641
+ }).subscribe(setReadAccessSharingPermission), previewUrlSecretPermissionSubscription = grantsStore.checkDocumentPermission("create", {
2642
+ _id: `drafts.${uuid()}`,
2643
+ _type: schemaType
2644
+ }).subscribe(setPreviewUrlSecretPermission);
2645
+ return () => {
2646
+ previewCreateAccessSharingPermissionSubscription.unsubscribe(), previewUpdateAccessSharingPermissionSubscription.unsubscribe(), previewReadAccessSharingPermissionSubscription.unsubscribe(), previewUrlSecretPermissionSubscription.unsubscribe();
2647
+ };
2648
+ }, t1 = [grantsStore, willGeneratePreviewUrlSecret], $[0] = grantsStore, $[1] = willGeneratePreviewUrlSecret, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), useEffect(t0, t1);
2649
+ const canCreateUrlPreviewSecrets = previewUrlSecretPermission?.granted;
2650
+ let t2, t3;
2651
+ $[4] !== canCreateUrlPreviewSecrets || $[5] !== pushToast || $[6] !== t || $[7] !== willGeneratePreviewUrlSecret ? (t2 = () => {
2652
+ if (!willGeneratePreviewUrlSecret || canCreateUrlPreviewSecrets !== !1)
2653
+ return;
2654
+ const raf = requestAnimationFrame(() => pushToast({
2655
+ closable: !0,
2656
+ status: "error",
2657
+ duration: 3e4,
2658
+ title: t("preview-url-secret.missing-grants")
2659
+ }));
2660
+ return () => cancelAnimationFrame(raf);
2661
+ }, t3 = [canCreateUrlPreviewSecrets, pushToast, t, willGeneratePreviewUrlSecret], $[4] = canCreateUrlPreviewSecrets, $[5] = pushToast, $[6] = t, $[7] = willGeneratePreviewUrlSecret, $[8] = t2, $[9] = t3) : (t2 = $[8], t3 = $[9]), useEffect(t2, t3);
2662
+ const [vercelProtectionBypass, vercelProtectionBypassReadyState] = useVercelBypassSecret();
2663
+ if (vercelProtectionBypassReadyState === "loading" || willGeneratePreviewUrlSecret && (!previewAccessSharingCreatePermission || typeof previewAccessSharingCreatePermission.granted > "u" || !previewAccessSharingUpdatePermission || typeof previewAccessSharingUpdatePermission.granted > "u" || !previewUrlSecretPermission || !previewAccessSharingReadPermission || typeof previewAccessSharingReadPermission.granted > "u" || typeof previewUrlSecretPermission.granted > "u")) {
2664
+ let t42;
2665
+ return $[10] === Symbol.for("react.memo_cache_sentinel") ? (t42 = /* @__PURE__ */ jsx(PresentationSpinner, {}), $[10] = t42) : t42 = $[10], t42;
3620
2666
  }
3621
- const t1 = previewAccessSharingCreatePermission?.granted === !0 && previewAccessSharingUpdatePermission?.granted === !0, t2 = previewAccessSharingReadPermission?.granted === !0;
3622
- let t3;
3623
- return $[1] !== previewUrlRef || $[2] !== t1 || $[3] !== t2 || $[4] !== tool || $[5] !== url || $[6] !== vercelProtectionBypass ? (t3 = /* @__PURE__ */ jsx(PresentationTool, { tool, initialPreviewUrl: url, vercelProtectionBypass, canToggleSharePreviewAccess: t1, canUseSharedPreviewAccess: t2, previewUrlRef }), $[1] = previewUrlRef, $[2] = t1, $[3] = t2, $[4] = tool, $[5] = url, $[6] = vercelProtectionBypass, $[7] = t3) : t3 = $[7], t3;
3624
- }
3625
- function _temp5(state_3) {
3626
- return state_3.context.previewUrl;
3627
- }
3628
- function _temp4(state_2) {
3629
- return state_2.context.previewUrlSecretPermission;
3630
- }
3631
- function _temp3(state_1) {
3632
- return state_1.context.previewAccessSharingReadPermission;
3633
- }
3634
- function _temp2(state_0) {
3635
- return state_0.context.previewAccessSharingUpdatePermission;
3636
- }
3637
- function _temp(state) {
3638
- return state.context.previewAccessSharingCreatePermission;
2667
+ const t4 = canCreateUrlPreviewSecrets === !0, t5 = previewAccessSharingCreatePermission?.granted === !0 && previewAccessSharingUpdatePermission?.granted === !0, t6 = previewAccessSharingReadPermission?.granted === !0;
2668
+ let t7;
2669
+ return $[11] !== props || $[12] !== t4 || $[13] !== t5 || $[14] !== t6 || $[15] !== vercelProtectionBypass ? (t7 = /* @__PURE__ */ jsx(PresentationTool, { ...props, vercelProtectionBypass, canCreateUrlPreviewSecrets: t4, canToggleSharePreviewAccess: t5, canUseSharedPreviewAccess: t6 }), $[11] = props, $[12] = t4, $[13] = t5, $[14] = t6, $[15] = vercelProtectionBypass, $[16] = t7) : t7 = $[16], t7;
3639
2670
  }
3640
2671
  export {
3641
2672
  PresentationToolGrantsCheck as default