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
@@ -0,0 +1,133 @@
1
+ import {createPreviewSecret} from '@sanity/preview-url-secret/create-secret'
2
+ import {definePreviewUrl} from '@sanity/preview-url-secret/define-preview-url'
3
+ import {startTransition, useEffect, useMemo, useRef, useState} from 'react'
4
+ import {type SanityClient, useActiveWorkspace, useClient, useCurrentUser} from 'sanity'
5
+ import {suspend} from 'suspend-react'
6
+
7
+ import {API_VERSION} from './constants'
8
+ import {type PresentationPerspective, type PreviewUrlOption} from './types'
9
+ import {encodeStudioPerspective} from './util/encodeStudioPerspective'
10
+
11
+ export function usePreviewUrl(
12
+ previewUrl: PreviewUrlOption,
13
+ toolName: string,
14
+ studioPreviewPerspective: PresentationPerspective,
15
+ previewSearchParam: string | null,
16
+ canCreateUrlPreviewSecrets: boolean,
17
+ ): URL {
18
+ const client = useClient({apiVersion: API_VERSION})
19
+ const workspace = useActiveWorkspace()
20
+ const basePath = workspace?.activeWorkspace?.basePath || '/'
21
+ const workspaceName = workspace?.activeWorkspace?.name || 'default'
22
+ const deps = useSuspendCacheKeys(toolName, basePath, workspaceName, previewSearchParam)
23
+ const previewUrlSecret = usePreviewUrlSecret(
24
+ (canCreateUrlPreviewSecrets && typeof previewUrl === 'object') ||
25
+ typeof previewUrl === 'function',
26
+ deps,
27
+ )
28
+
29
+ return suspend(async () => {
30
+ if (typeof previewUrl === 'string') {
31
+ const resolvedUrl = new URL(previewUrl, location.origin)
32
+ let resultUrl = resolvedUrl
33
+ try {
34
+ if (previewSearchParam) {
35
+ const restoredUrl = new URL(previewSearchParam, resolvedUrl)
36
+ if (restoredUrl.origin === resolvedUrl.origin) {
37
+ resultUrl = restoredUrl
38
+ }
39
+ }
40
+ } catch {
41
+ // ignore
42
+ }
43
+ // Prevent infinite recursion
44
+ if (
45
+ location.origin === resultUrl.origin &&
46
+ (resultUrl.pathname.startsWith(`${basePath}/`) || resultUrl.pathname === basePath)
47
+ ) {
48
+ return resolvedUrl
49
+ }
50
+ return resultUrl
51
+ }
52
+ const resolvePreviewUrl =
53
+ typeof previewUrl === 'object' ? definePreviewUrl<SanityClient>(previewUrl) : previewUrl
54
+ const resolvedUrl = await resolvePreviewUrl({
55
+ client,
56
+ previewUrlSecret: previewUrlSecret!,
57
+ studioPreviewPerspective: encodeStudioPerspective(studioPreviewPerspective),
58
+ previewSearchParam,
59
+ studioBasePath: basePath,
60
+ })
61
+ return new URL(resolvedUrl, location.origin)
62
+ }, [...deps, previewUrlSecret]) satisfies URL
63
+ }
64
+
65
+ // https://github.com/pmndrs/suspend-react?tab=readme-ov-file#making-cache-keys-unique
66
+ const resolveUUID = Symbol('sanity/presentation/resolveUUID')
67
+
68
+ function useSuspendCacheKeys(
69
+ toolName: string,
70
+ basePath: string,
71
+ workspaceName: string,
72
+ previewSearchParam: string | null,
73
+ ) {
74
+ // Allow busting the cache when the Presentation Tool is reloaded, without causing it to suspend on every render that changes the `preview` parameter
75
+ const [cachedPreviewSearchParam, setCachedPreviewSearchParam] = useState(
76
+ () => previewSearchParam || '',
77
+ )
78
+ const timeoutRef = useRef(0)
79
+ useEffect(() => {
80
+ if (cachedPreviewSearchParam && previewSearchParam) {
81
+ // Handle resets, like when the Presentation Tool is clicked in the navbar
82
+ window.clearTimeout(timeoutRef.current)
83
+ return () => {
84
+ timeoutRef.current = window.setTimeout(() => {
85
+ setCachedPreviewSearchParam('')
86
+ }, 100)
87
+ }
88
+ }
89
+ return undefined
90
+ }, [cachedPreviewSearchParam, previewSearchParam])
91
+
92
+ const currentUser = useCurrentUser()
93
+ return useMemo(
94
+ () => [
95
+ // Cache based on a few specific conditions
96
+ 'sanity/presentation',
97
+ basePath,
98
+ workspaceName,
99
+ toolName,
100
+ currentUser?.id,
101
+ resolveUUID,
102
+ cachedPreviewSearchParam,
103
+ ],
104
+ [basePath, currentUser?.id, toolName, workspaceName, cachedPreviewSearchParam],
105
+ )
106
+ }
107
+
108
+ function usePreviewUrlSecret(enabled: boolean, deps: (string | symbol | undefined)[]) {
109
+ const client = useClient({apiVersion: API_VERSION})
110
+ const currentUser = useCurrentUser()
111
+ const [secretLastExpiredAt, setSecretLastExpiredAt] = useState<string>('')
112
+
113
+ const previewUrlSecret = enabled
114
+ ? suspend(async () => {
115
+ return await createPreviewSecret(
116
+ client,
117
+ '@sanity/presentation',
118
+ typeof window === 'undefined' ? '' : location.href,
119
+ currentUser?.id,
120
+ )
121
+ }, [...deps, secretLastExpiredAt])
122
+ : null
123
+
124
+ useEffect(() => {
125
+ if (!previewUrlSecret) return undefined
126
+ const timeout = setTimeout(() => {
127
+ startTransition(() => setSecretLastExpiredAt(previewUrlSecret.expiresAt.toString()))
128
+ }, previewUrlSecret.expiresAt.getTime() - Date.now())
129
+ return () => clearTimeout(timeout)
130
+ }, [previewUrlSecret])
131
+
132
+ return previewUrlSecret?.secret || null
133
+ }
@@ -1,19 +0,0 @@
1
- import {createPreviewSecret} from '@sanity/preview-url-secret/create-secret'
2
- import {type SanityClient} from 'sanity'
3
- import {fromPromise, type PromiseActorLogic} from 'xstate'
4
-
5
- /** @internal */
6
- export function defineCreatePreviewSecretActor({
7
- client,
8
- currentUserId,
9
- }: {
10
- client: SanityClient
11
- currentUserId: string | undefined
12
- }): PromiseActorLogic<{
13
- secret: string
14
- expiresAt: Date
15
- }> {
16
- return fromPromise(async () => {
17
- return await createPreviewSecret(client, 'sanity/presentation', location.href, currentUserId)
18
- })
19
- }
@@ -1,18 +0,0 @@
1
- import {fetchSharedAccessQuery} from '@sanity/preview-url-secret/constants'
2
- import {type SanityClient} from 'sanity'
3
- import {fromPromise, type PromiseActorLogic} from 'xstate'
4
-
5
- /** @internal */
6
- export function defineReadSharedSecretActor({
7
- client,
8
- }: {
9
- client: SanityClient
10
- }): PromiseActorLogic<string | null> {
11
- return fromPromise(async () => {
12
- return client.fetch<string | null>(
13
- fetchSharedAccessQuery,
14
- {},
15
- {tag: 'presentation.fallback-to-shared-access-secret'},
16
- )
17
- })
18
- }
@@ -1,55 +0,0 @@
1
- import {fromPromise, type PromiseActorLogic} from 'xstate'
2
-
3
- import {type PreviewUrlAllowOption, type PreviewUrlAllowOptionContext} from '../types'
4
-
5
- interface Context extends Pick<PreviewUrlAllowOptionContext, 'client'> {
6
- allowOption: PreviewUrlAllowOption | undefined
7
- }
8
- type Input = Omit<PreviewUrlAllowOptionContext, 'client' | 'origin'>
9
-
10
- /** @internal */
11
- export function defineResolveAllowPatternsActor({
12
- client,
13
- allowOption,
14
- }: Context): PromiseActorLogic<URLPattern[], Input> {
15
- return fromPromise<URLPattern[], Input>(async ({input}) => {
16
- const {initialUrl} = input
17
-
18
- /**
19
- * Lazy load the URLPattern polyfill on-demand, if needed
20
- */
21
- if (typeof URLPattern === 'undefined') {
22
- await import('urlpattern-polyfill')
23
- }
24
-
25
- /**
26
- * If no allow option is provided, we use the initial URL to infer the pattern
27
- */
28
- if (!allowOption) {
29
- return [new URLPattern(initialUrl.origin)]
30
- }
31
-
32
- const maybePatterns =
33
- typeof allowOption === 'function'
34
- ? await allowOption({client, origin, initialUrl})
35
- : allowOption
36
- const patterns = Array.isArray(maybePatterns) ? maybePatterns : [maybePatterns]
37
- const urlPatterns = patterns.map((value) => {
38
- const urlPattern = new URLPattern(value)
39
- if (urlPattern.hostname === '*') {
40
- throw new Error(
41
- `It's insecure to allow any hostname, it could disclose data to a malicious site`,
42
- )
43
- }
44
- return urlPattern
45
- })
46
- /**
47
- * If the declared patterns don't consider the initial URL valid, we add it to the list of patterns
48
- */
49
- if (!urlPatterns.some((pattern) => pattern.test(initialUrl.origin))) {
50
- return [...urlPatterns, new URLPattern(initialUrl.origin)]
51
- }
52
-
53
- return urlPatterns
54
- })
55
- }
@@ -1,65 +0,0 @@
1
- import {type SanityClient} from 'sanity'
2
- import {fromPromise, type PromiseActorLogic} from 'xstate'
3
-
4
- import {type PresentationPerspective, type PreviewUrlOption} from '../types'
5
- import {encodeStudioPerspective} from '../util/encodeStudioPerspective'
6
-
7
- /** @internal */
8
- export function defineResolveInitialUrlActor({
9
- client,
10
- studioBasePath,
11
- previewUrlOption,
12
- perspective,
13
- }: {
14
- client: SanityClient
15
- studioBasePath: string
16
- previewUrlOption: PreviewUrlOption | undefined
17
- perspective: PresentationPerspective
18
- }): PromiseActorLogic<URL, {previewSearchParam: string | null}> {
19
- return fromPromise<URL, {previewSearchParam: string | null}>(
20
- async ({input}: {input: {previewSearchParam: string | null}}) => {
21
- const {origin} = location
22
- /**
23
- * If the previewUrlOption is a function, we need to resolve it and maintain backwards compatibility
24
- */
25
- if (typeof previewUrlOption === 'function') {
26
- const initial = await previewUrlOption({
27
- client,
28
- studioBasePath,
29
- // @TODO handle checking permissions here, and then generating a secret
30
- previewUrlSecret: '',
31
- studioPreviewPerspective: encodeStudioPerspective(perspective),
32
- previewSearchParam: input.previewSearchParam,
33
- })
34
- return new URL(initial, origin)
35
- }
36
-
37
- /**
38
- * Provide backwards compatibility for versions where `previewUrl` where optional
39
- */
40
- if (!previewUrlOption) {
41
- return new URL('/', origin)
42
- }
43
- /**
44
- * Support setting `previewUrl` as a string shorthand
45
- */
46
- if (typeof previewUrlOption === 'string') {
47
- return new URL(previewUrlOption, origin)
48
- }
49
-
50
- if (typeof previewUrlOption.initial === 'function') {
51
- const initial = await previewUrlOption.initial({
52
- client,
53
- origin,
54
- })
55
- return new URL(initial, origin)
56
- }
57
-
58
- if (typeof previewUrlOption.initial === 'string') {
59
- return new URL(previewUrlOption.initial, origin)
60
- }
61
-
62
- return new URL(previewUrlOption.preview || '/', previewUrlOption.origin || origin)
63
- },
64
- )
65
- }
@@ -1,72 +0,0 @@
1
- import {
2
- urlSearchParamPreviewPathname,
3
- urlSearchParamPreviewPerspective,
4
- urlSearchParamPreviewSecret,
5
- } from '@sanity/preview-url-secret/constants'
6
- import {type SanityClient} from 'sanity'
7
- import {fromPromise, type PromiseActorLogic} from 'xstate'
8
-
9
- import {
10
- type PresentationPerspective,
11
- type PreviewUrlOption,
12
- type PreviewUrlPreviewMode,
13
- } from '../types'
14
- import {encodeStudioPerspective} from '../util/encodeStudioPerspective'
15
-
16
- /** @internal */
17
- export interface ResolvePreviewModeUrlInput {
18
- previewUrlSecret: string
19
- resolvedPreviewMode: PreviewUrlPreviewMode
20
- initialUrl: URL
21
- }
22
-
23
- /** @internal */
24
- export function defineResolvePreviewModeUrlActor({
25
- client,
26
- studioBasePath,
27
- previewUrlOption,
28
- perspective,
29
- }: {
30
- client: SanityClient
31
- studioBasePath: string
32
- previewUrlOption: PreviewUrlOption | undefined
33
- perspective: PresentationPerspective
34
- }): PromiseActorLogic<URL, ResolvePreviewModeUrlInput> {
35
- return fromPromise<URL, ResolvePreviewModeUrlInput>(async ({input}) => {
36
- const {previewUrlSecret, resolvedPreviewMode, initialUrl} = input
37
-
38
- /**
39
- * If the previewUrlOption is a function, we need to resolve it and maintain backwards compatibility
40
- */
41
- if (typeof previewUrlOption === 'function') {
42
- const initial = await previewUrlOption({
43
- client,
44
- studioBasePath,
45
- previewUrlSecret,
46
- studioPreviewPerspective: encodeStudioPerspective(perspective),
47
- previewSearchParam: initialUrl.toString(),
48
- })
49
- return new URL(initial, initialUrl)
50
- }
51
-
52
- /**
53
- * If the resolved preview mode is false then we have an unexpected state that shouldn't be possible
54
- */
55
- if (!resolvedPreviewMode) {
56
- throw new Error('Resolved preview mode is false')
57
- }
58
-
59
- const url = new URL(resolvedPreviewMode.enable, initialUrl)
60
-
61
- url.searchParams.set(urlSearchParamPreviewSecret, previewUrlSecret)
62
- url.searchParams.set(urlSearchParamPreviewPerspective, encodeStudioPerspective(perspective))
63
- if (initialUrl.pathname !== url.pathname) {
64
- url.searchParams.set(
65
- urlSearchParamPreviewPathname,
66
- `${initialUrl.pathname}${initialUrl.search}${initialUrl.hash}`,
67
- )
68
- }
69
-
70
- return url
71
- })
72
- }
@@ -1,66 +0,0 @@
1
- import {fromPromise, type PromiseActorLogic} from 'xstate'
2
-
3
- import {
4
- type PreviewUrlOption,
5
- type PreviewUrlPreviewMode,
6
- type PreviewUrlPreviewModeOptionContext,
7
- } from '../types'
8
-
9
- type Options = Omit<PreviewUrlPreviewModeOptionContext, 'origin'>
10
-
11
- interface Context extends Pick<Options, 'client'> {
12
- previewUrlOption: PreviewUrlOption | undefined
13
- }
14
- type Input = Omit<Options, 'client'>
15
-
16
- /** @internal */
17
- export function defineResolvePreviewModeActor({
18
- client,
19
- previewUrlOption,
20
- }: Context): PromiseActorLogic<PreviewUrlPreviewMode | false, Input> {
21
- return fromPromise<PreviewUrlPreviewMode | false, Input>(async ({input}) => {
22
- const {targetOrigin} = input
23
-
24
- /**
25
- * Handle legacy draftMode options
26
- */
27
- if (typeof previewUrlOption === 'object' && previewUrlOption?.draftMode) {
28
- return {
29
- enable: previewUrlOption.draftMode.enable,
30
- shareAccess: previewUrlOption.draftMode.shareAccess ?? true,
31
- }
32
- }
33
-
34
- /**
35
- * If no preview mode option is provided, we disable preview mode
36
- */
37
- if (
38
- !previewUrlOption ||
39
- typeof previewUrlOption === 'string' ||
40
- typeof previewUrlOption === 'function' ||
41
- !previewUrlOption.previewMode
42
- ) {
43
- return false
44
- }
45
-
46
- /**
47
- * If the option is a function, we resolve it
48
- */
49
- const previewMode =
50
- typeof previewUrlOption.previewMode === 'function'
51
- ? await previewUrlOption.previewMode({client, origin, targetOrigin})
52
- : previewUrlOption.previewMode
53
-
54
- if (previewMode === false) {
55
- return false
56
- }
57
-
58
- /**
59
- * Return only supported preview mode options, filter out unknowns
60
- */
61
- return {
62
- enable: previewMode.enable,
63
- shareAccess: previewMode.shareAccess ?? true,
64
- }
65
- })
66
- }
@@ -1,29 +0,0 @@
1
- import {fromPromise} from 'xstate'
2
-
3
- /** @internal */
4
- export const resolveUrlFromPreviewSearchParamActor = fromPromise<
5
- URL,
6
- {initialUrl: URL; previewSearchParam: string | null | undefined; allowOrigins: URLPattern[]}
7
- >(async ({input}) => {
8
- const {previewSearchParam, initialUrl, allowOrigins} = input
9
-
10
- /**
11
- * If the preview search param is falsy we can skip
12
- */
13
- if (!previewSearchParam) {
14
- return initialUrl
15
- }
16
-
17
- /**
18
- * Validate the previewSearchParam
19
- */
20
- try {
21
- const previewSearchParamUrl = new URL(previewSearchParam, initialUrl.origin)
22
- if (!allowOrigins.some((pattern) => pattern.test(previewSearchParamUrl.origin))) {
23
- return initialUrl
24
- }
25
- return previewSearchParamUrl
26
- } catch (err) {
27
- return initialUrl
28
- }
29
- })
@@ -1,101 +0,0 @@
1
- import {type ActorRefFrom, assign, setup} from 'xstate'
2
-
3
- interface Context {
4
- url: URL | null
5
- error: Error | null
6
- visualEditingOverlaysEnabled: boolean
7
- }
8
-
9
- type Event =
10
- | {type: 'toggle visual editing overlays'; enabled: boolean}
11
- | {type: 'iframe loaded'}
12
- | {type: 'iframe refresh'}
13
- | {type: 'iframe reload'}
14
-
15
- export const presentationMachine = setup({
16
- types: {} as {
17
- context: Context
18
- events: Event
19
- tags: 'busy' | 'error'
20
- },
21
- actions: {
22
- //
23
- },
24
- actors: {
25
- //
26
- },
27
- guards: {
28
- //
29
- },
30
- }).createMachine({
31
- // eslint-disable-next-line tsdoc/syntax
32
- /** @xstate-layout N4IgpgJg5mDOIC5QAUBOcwDsAuBDbAlgPaYAEAKkUQDYDEBAZqrgLZinrVG4QDaADAF1EoAA5FYBQiREgAHogAsAJgA0IAJ6IAHAEYAdIoCcJowFY9R-vzPLlAX3vq0GHPmJlKNfVx4FMUPRMrOy+EJACwkgg4pLSmLIKCLoAbIr6Zoop2tqKAMxpJnnF6loIZkbK+uZ5umapKXmK-Cm6js7osFh48RRU1D7c4RC02ERQUNTsAG4EsACuuNSkkFL+UKRE02Co1LgasJGysWsy0UnaZinVyrpGAOx1Rim2efeliPe3hma1Zvy6XT8W4OJwgFxdNy9LwDMKQILMNgcMBMOAACyO0RO8USiAK930LWU-3uiiB9yaKXemkQjW01V+txS-GKqUe7XBnW67hIfW8cJGjER7E4Q0xYgkpwS5zxVMJKWJ-FJ5Mp1LKFn4Pz+DSaLTaYIh3Oh-UGPEg+nQqNgaPWCJCpAF4pikpxMoQKWZ+gp+TSZLy1hSH3deXpNSZLNqVP1HVcPQ8fNhQ3Nor8ATtSMdQmOLo8uPdnu9BUUfoDQY1WrqOuarUcYMwRHC8Gihqh8Zh2biubdAFpAzSEL2OS247yYfodqgiKgO1K8yog7ptATFL9dFljMDrHkh1zW6OTWF1jPXaAkmY1YgKnktfxtC9dPd+Io9DvYzzPAekxBj13T3i7vKirKkqqpBsYVQ1HUFjFs0t6KK+kIjh+-JfvoBAQFMP5nH+CDaMo16KjYyjMvUNh5GWOT6MoLL8A8ygrk0dQIUabafmaEAWiinQ2gEWHSjhjJUYuj73Pcd63noQaNEYFb-Dk2S0cxe7IYm7GcYevFYjm2HyJeeQQb8tFkikVjGNoFGajUt73o+z61vYQA */
33
- id: 'Presentation Tool',
34
- context: {
35
- url: null,
36
- error: null,
37
- visualEditingOverlaysEnabled: false,
38
- },
39
-
40
- on: {
41
- 'iframe reload': {
42
- actions: assign({url: null}),
43
- target: '.loading',
44
- },
45
- },
46
-
47
- states: {
48
- error: {
49
- description:
50
- 'Failed to load, either because of a misconfiguration, a network error, or an unexpected error',
51
- tags: ['error'],
52
- },
53
- loading: {
54
- on: {
55
- 'iframe loaded': {
56
- target: 'loaded',
57
- },
58
- },
59
- tags: ['busy'],
60
- },
61
- loaded: {
62
- on: {
63
- 'toggle visual editing overlays': {
64
- actions: assign({
65
- visualEditingOverlaysEnabled: ({event}) => event.enabled,
66
- }),
67
- },
68
- 'iframe refresh': {
69
- target: '.refreshing',
70
- },
71
- 'iframe reload': {
72
- target: '.reloading',
73
- },
74
- },
75
-
76
- states: {
77
- idle: {},
78
- refreshing: {
79
- on: {
80
- 'iframe loaded': {
81
- target: 'idle',
82
- },
83
- },
84
- tags: ['busy'],
85
- },
86
- reloading: {
87
- on: {
88
- 'iframe loaded': {
89
- target: 'idle',
90
- },
91
- },
92
- tags: ['busy'],
93
- },
94
- },
95
- initial: 'idle',
96
- },
97
- },
98
- initial: 'loading',
99
- })
100
-
101
- export type PresentationMachineRef = ActorRefFrom<typeof presentationMachine>