next-sanity 12.3.5 → 12.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PresentationComlink.js.map +1 -1
- package/dist/SanityLive.js +157 -0
- package/dist/SanityLive.js.map +1 -0
- package/dist/VisualEditing.js +17 -26
- package/dist/VisualEditing.js.map +1 -1
- package/dist/isCorsOriginError.js.map +1 -1
- package/dist/live/client-components/index.d.ts +5 -13
- package/dist/live/client-components/index.d.ts.map +1 -1
- package/dist/live/client-components/index.js +5 -154
- package/dist/live/client-components/index.js.map +1 -1
- package/dist/live/conditions/default/index.d.ts +83 -5
- package/dist/live/conditions/default/index.d.ts.map +1 -1
- package/dist/live/conditions/default/index.js +78 -0
- package/dist/live/conditions/default/index.js.map +1 -1
- package/dist/live/conditions/next-js/index.d.ts +89 -0
- package/dist/live/conditions/next-js/index.d.ts.map +1 -0
- package/dist/live/conditions/next-js/index.js +88 -0
- package/dist/live/conditions/next-js/index.js.map +1 -0
- package/dist/live/conditions/react-server/index.d.ts +88 -2
- package/dist/live/conditions/react-server/index.d.ts.map +1 -0
- package/dist/live/conditions/react-server/index.js +149 -69
- package/dist/live/conditions/react-server/index.js.map +1 -1
- package/dist/live/server-actions/{index.default.d.ts → index.d.ts} +1 -1
- package/dist/live/server-actions/index.d.ts.map +1 -0
- package/dist/live/server-actions/{index.default.js → index.js} +9 -5
- package/dist/live/server-actions/index.js.map +1 -0
- package/dist/{defineLive.d.ts → types.d.ts} +39 -26
- package/dist/types.d.ts.map +1 -0
- package/dist/visual-editing/client-component/index.d.ts +2 -2
- package/dist/visual-editing/client-component/index.d.ts.map +1 -1
- package/dist/visual-editing/client-component/index.js +3 -17
- package/dist/visual-editing/client-component/index.js.map +1 -1
- package/dist/visual-editing/index.js +2 -2
- package/dist/visual-editing/index.js.map +1 -1
- package/dist/visual-editing/server-actions/index.d.ts +6 -2
- package/dist/visual-editing/server-actions/index.d.ts.map +1 -1
- package/dist/visual-editing/server-actions/index.js +22 -7
- package/dist/visual-editing/server-actions/index.js.map +1 -1
- package/package.json +4 -5
- package/dist/defineLive.d.ts.map +0 -1
- package/dist/live/server-actions/index.default.d.ts.map +0 -1
- package/dist/live/server-actions/index.default.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PresentationComlink.js","names":[],"sources":["../src/live/client-components/PresentationComlink.tsx"],"sourcesContent":["import type {ClientPerspective} from '@sanity/client'\nimport {
|
|
1
|
+
{"version":3,"file":"PresentationComlink.js","names":[],"sources":["../src/live/client-components/PresentationComlink.tsx"],"sourcesContent":["import type {ClientPerspective} from '@sanity/client'\nimport {createNode, createNodeMachine} from '@sanity/comlink'\nimport {\n createCompatibilityActors,\n type LoaderControllerMsg,\n type LoaderNodeMsg,\n} from '@sanity/presentation-comlink'\nimport {setPerspectiveCookie} from 'next-sanity/live/server-actions'\nimport {useRouter} from 'next/navigation'\nimport {useEffect, useEffectEvent} from 'react'\n\nimport {setComlink, setComlinkClientConfig} from '../hooks/context'\n\nfunction PresentationComlink(props: {\n projectId: string\n dataset: string\n draftModeEnabled: boolean\n draftModePerspective: ClientPerspective\n}): React.JSX.Element | null {\n const {projectId, dataset, draftModeEnabled, draftModePerspective} = props\n const router = useRouter()\n\n useEffect(() => {\n setComlinkClientConfig(projectId, dataset)\n }, [dataset, projectId])\n\n const handlePerspectiveChange = useEffectEvent(\n (perspective: ClientPerspective, signal: AbortSignal) => {\n if (draftModeEnabled && perspective !== draftModePerspective) {\n setPerspectiveCookie(perspective)\n .then(() => {\n if (signal.aborted) return\n router.refresh()\n })\n .catch((reason) => console.error('Failed to set the preview perspective cookie', reason))\n }\n },\n )\n\n useEffect(() => {\n const comlink = createNode<LoaderNodeMsg, LoaderControllerMsg>(\n {\n name: 'loaders',\n connectTo: 'presentation',\n },\n createNodeMachine<LoaderNodeMsg, LoaderControllerMsg>().provide({\n actors: createCompatibilityActors<LoaderNodeMsg>(),\n }),\n )\n\n let controller: AbortController | undefined\n comlink.on('loader/perspective', (data) => {\n controller?.abort()\n controller = new AbortController()\n handlePerspectiveChange(data.perspective, controller.signal)\n })\n\n const stop = comlink.start()\n setComlink(comlink)\n return () => {\n stop()\n }\n }, [])\n\n return null\n}\nPresentationComlink.displayName = 'PresentationComlink'\n\nexport default PresentationComlink\n"],"mappings":";;;;;;AAaA,SAAS,oBAAoB,OAKA;CAC3B,MAAM,EAAC,WAAW,SAAS,kBAAkB,yBAAwB;CACrE,MAAM,SAAS,WAAW;AAE1B,iBAAgB;AACd,yBAAuB,WAAW,QAAQ;IACzC,CAAC,SAAS,UAAU,CAAC;CAExB,MAAM,0BAA0B,gBAC7B,aAAgC,WAAwB;AACvD,MAAI,oBAAoB,gBAAgB,qBACtC,sBAAqB,YAAY,CAC9B,WAAW;AACV,OAAI,OAAO,QAAS;AACpB,UAAO,SAAS;IAChB,CACD,OAAO,WAAW,QAAQ,MAAM,gDAAgD,OAAO,CAAC;GAGhG;AAED,iBAAgB;EACd,MAAM,UAAU,WACd;GACE,MAAM;GACN,WAAW;GACZ,EACD,mBAAuD,CAAC,QAAQ,EAC9D,QAAQ,2BAA0C,EACnD,CAAC,CACH;EAED,IAAI;AACJ,UAAQ,GAAG,uBAAuB,SAAS;AACzC,eAAY,OAAO;AACnB,gBAAa,IAAI,iBAAiB;AAClC,2BAAwB,KAAK,aAAa,WAAW,OAAO;IAC5D;EAEF,MAAM,OAAO,QAAQ,OAAO;AAC5B,aAAW,QAAQ;AACnB,eAAa;AACX,SAAM;;IAEP,EAAE,CAAC;AAEN,QAAO;;AAET,oBAAoB,cAAc"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { d as setEnvironment, f as setPerspective } from "./context.js";
|
|
2
|
+
import { t as isCorsOriginError } from "./isCorsOriginError.js";
|
|
3
|
+
import { useRouter } from "next/navigation";
|
|
4
|
+
import { startTransition, useEffect, useEffectEvent, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { isMaybePresentation, isMaybePreviewWindow } from "@sanity/presentation-comlink";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { createClient } from "@sanity/client";
|
|
8
|
+
import dynamic from "next/dynamic";
|
|
9
|
+
import { revalidateSyncTags } from "next-sanity/live/server-actions";
|
|
10
|
+
const PresentationComlink = dynamic(() => import("./PresentationComlink.js"));
|
|
11
|
+
const RefreshOnFocus = dynamic(() => import("./RefreshOnFocus.js"));
|
|
12
|
+
const RefreshOnMount = dynamic(() => import("./RefreshOnMount.js"));
|
|
13
|
+
const RefreshOnInterval = dynamic(() => import("./RefreshOnInterval.js"));
|
|
14
|
+
const RefreshOnReconnect = dynamic(() => import("./RefreshOnReconnect.js"));
|
|
15
|
+
function handleError(error) {
|
|
16
|
+
if (isCorsOriginError(error)) console.warn(`Sanity Live is unable to connect to the Sanity API as the current origin - ${window.origin} - is not in the list of allowed CORS origins for this Sanity Project.`, error.addOriginUrl && `Add it here:`, error.addOriginUrl?.toString());
|
|
17
|
+
else console.error(error);
|
|
18
|
+
}
|
|
19
|
+
function handleOnGoAway(event, intervalOnGoAway) {
|
|
20
|
+
if (intervalOnGoAway) console.warn("Sanity Live connection closed, switching to long polling set to a interval of", intervalOnGoAway / 1e3, "seconds and the server gave this reason:", event.reason);
|
|
21
|
+
else console.error("Sanity Live connection closed, automatic revalidation is disabled, the server gave this reason:", event.reason);
|
|
22
|
+
}
|
|
23
|
+
function SanityLive(props) {
|
|
24
|
+
const { projectId, dataset, apiHost, apiVersion, useProjectHostname, token, requestTagPrefix, draftModeEnabled, draftModePerspective, refreshOnMount = false, refreshOnFocus = draftModeEnabled ? false : typeof window === "undefined" ? true : window.self === window.top, refreshOnReconnect = true, intervalOnGoAway = 3e4, requestTag = "next-loader.live", onError = handleError, onGoAway = handleOnGoAway, revalidateSyncTags: revalidateSyncTags$1 = revalidateSyncTags, waitFor } = props;
|
|
25
|
+
const client = useMemo(() => createClient({
|
|
26
|
+
projectId,
|
|
27
|
+
dataset,
|
|
28
|
+
apiHost,
|
|
29
|
+
apiVersion,
|
|
30
|
+
useProjectHostname,
|
|
31
|
+
ignoreBrowserTokenWarning: true,
|
|
32
|
+
token,
|
|
33
|
+
useCdn: false,
|
|
34
|
+
requestTagPrefix
|
|
35
|
+
}), [
|
|
36
|
+
apiHost,
|
|
37
|
+
apiVersion,
|
|
38
|
+
dataset,
|
|
39
|
+
projectId,
|
|
40
|
+
requestTagPrefix,
|
|
41
|
+
token,
|
|
42
|
+
useProjectHostname
|
|
43
|
+
]);
|
|
44
|
+
const [refreshOnInterval, setRefreshOnInterval] = useState(false);
|
|
45
|
+
/**
|
|
46
|
+
* 1. Handle Live Events and call revalidateTag or router.refresh when needed
|
|
47
|
+
*/
|
|
48
|
+
const router = useRouter();
|
|
49
|
+
const handleLiveEvent = useEffectEvent((event) => {
|
|
50
|
+
if (process.env.NODE_ENV !== "production" && event.type === "welcome") {
|
|
51
|
+
console.info("Sanity is live with", token ? "automatic revalidation for draft content changes as well as published content" : draftModeEnabled ? "automatic revalidation for only published content. Provide a `browserToken` to `defineLive` to support draft content outside of Presentation Tool." : "automatic revalidation of published content");
|
|
52
|
+
startTransition(() => setRefreshOnInterval(false));
|
|
53
|
+
} else if (event.type === "message") if (waitFor === "function") startTransition(() => router.refresh());
|
|
54
|
+
else revalidateSyncTags$1(event.tags).then((result) => {
|
|
55
|
+
if (result === "refresh") startTransition(() => router.refresh());
|
|
56
|
+
});
|
|
57
|
+
else if (event.type === "restart" || event.type === "reconnect") {
|
|
58
|
+
startTransition(() => setRefreshOnInterval(false));
|
|
59
|
+
startTransition(() => router.refresh());
|
|
60
|
+
} else if (event.type === "goaway") {
|
|
61
|
+
onGoAway(event, intervalOnGoAway);
|
|
62
|
+
startTransition(() => setRefreshOnInterval(intervalOnGoAway));
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const subscription = client.live.events({
|
|
67
|
+
includeDrafts: !!token,
|
|
68
|
+
tag: requestTag,
|
|
69
|
+
waitFor
|
|
70
|
+
}).subscribe({
|
|
71
|
+
next: handleLiveEvent,
|
|
72
|
+
error: (err) => {
|
|
73
|
+
onError(err);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return () => subscription.unsubscribe();
|
|
77
|
+
}, [
|
|
78
|
+
client.live,
|
|
79
|
+
onError,
|
|
80
|
+
requestTag,
|
|
81
|
+
token,
|
|
82
|
+
waitFor
|
|
83
|
+
]);
|
|
84
|
+
/**
|
|
85
|
+
* 2. Notify what perspective we're in, when in Draft Mode
|
|
86
|
+
*/
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (draftModeEnabled && draftModePerspective) setPerspective(draftModePerspective);
|
|
89
|
+
else setPerspective("unknown");
|
|
90
|
+
}, [draftModeEnabled, draftModePerspective]);
|
|
91
|
+
const [loadComlink, setLoadComlink] = useState(false);
|
|
92
|
+
/**
|
|
93
|
+
* 3. Notify what environment we're in, when in Draft Mode
|
|
94
|
+
*/
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
if (isMaybePresentation()) return;
|
|
97
|
+
if (draftModeEnabled && token) {
|
|
98
|
+
setEnvironment("live");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (draftModeEnabled) {
|
|
102
|
+
setEnvironment("static");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
setEnvironment("unknown");
|
|
106
|
+
}, [draftModeEnabled, token]);
|
|
107
|
+
/**
|
|
108
|
+
* 4. If Presentation Tool is detected, load up the comlink and integrate with it
|
|
109
|
+
*/
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (!isMaybePresentation()) return;
|
|
112
|
+
const controller = new AbortController();
|
|
113
|
+
const timeout = setTimeout(() => setEnvironment("live"), 3e3);
|
|
114
|
+
window.addEventListener("message", ({ data }) => {
|
|
115
|
+
if (data && typeof data === "object" && "domain" in data && data.domain === "sanity/channels" && "from" in data && data.from === "presentation") {
|
|
116
|
+
clearTimeout(timeout);
|
|
117
|
+
setEnvironment(isMaybePreviewWindow() ? "presentation-window" : "presentation-iframe");
|
|
118
|
+
setLoadComlink(true);
|
|
119
|
+
controller.abort();
|
|
120
|
+
}
|
|
121
|
+
}, { signal: controller.signal });
|
|
122
|
+
return () => {
|
|
123
|
+
clearTimeout(timeout);
|
|
124
|
+
controller.abort();
|
|
125
|
+
};
|
|
126
|
+
}, []);
|
|
127
|
+
/**
|
|
128
|
+
* 5. Warn if draft mode is being disabled
|
|
129
|
+
* @TODO move logic into PresentationComlink, or maybe VisualEditing?
|
|
130
|
+
*/
|
|
131
|
+
const draftModeEnabledWarnRef = useRef(void 0);
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
if (!draftModeEnabled) return;
|
|
134
|
+
clearTimeout(draftModeEnabledWarnRef.current);
|
|
135
|
+
return () => {
|
|
136
|
+
draftModeEnabledWarnRef.current = setTimeout(() => {
|
|
137
|
+
console.warn("Sanity Live: Draft mode was enabled, but is now being disabled");
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
}, [draftModeEnabled]);
|
|
141
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
142
|
+
draftModeEnabled && loadComlink && /* @__PURE__ */ jsx(PresentationComlink, {
|
|
143
|
+
projectId,
|
|
144
|
+
dataset,
|
|
145
|
+
draftModeEnabled,
|
|
146
|
+
draftModePerspective
|
|
147
|
+
}),
|
|
148
|
+
!draftModeEnabled && refreshOnMount && /* @__PURE__ */ jsx(RefreshOnMount, {}),
|
|
149
|
+
refreshOnInterval && Number.isFinite(refreshOnInterval) && refreshOnInterval > 0 && /* @__PURE__ */ jsx(RefreshOnInterval, { interval: refreshOnInterval }),
|
|
150
|
+
!draftModeEnabled && refreshOnFocus && /* @__PURE__ */ jsx(RefreshOnFocus, {}),
|
|
151
|
+
!draftModeEnabled && refreshOnReconnect && /* @__PURE__ */ jsx(RefreshOnReconnect, {})
|
|
152
|
+
] });
|
|
153
|
+
}
|
|
154
|
+
SanityLive.displayName = "SanityLiveClientComponent";
|
|
155
|
+
export { SanityLive as default };
|
|
156
|
+
|
|
157
|
+
//# sourceMappingURL=SanityLive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SanityLive.js","names":["defaultRevalidateSyncTags","revalidateSyncTags"],"sources":["../src/live/client-components/SanityLive.tsx"],"sourcesContent":["import {\n createClient,\n type ClientPerspective,\n type InitializedClientConfig,\n type LiveEvent,\n type LiveEventGoAway,\n type SyncTag,\n} from '@sanity/client'\nimport {isMaybePresentation, isMaybePreviewWindow} from '@sanity/presentation-comlink'\nimport {revalidateSyncTags as defaultRevalidateSyncTags} from 'next-sanity/live/server-actions'\nimport dynamic from 'next/dynamic'\nimport {useRouter} from 'next/navigation'\nimport {useEffect, useMemo, useRef, useState, useEffectEvent, startTransition} from 'react'\n\nimport {isCorsOriginError} from '#live/isCorsOriginError'\n\nimport {setEnvironment, setPerspective} from '../hooks/context'\n\nconst PresentationComlink = dynamic(() => import('./PresentationComlink'))\nconst RefreshOnFocus = dynamic(() => import('./RefreshOnFocus'))\nconst RefreshOnMount = dynamic(() => import('./RefreshOnMount'))\nconst RefreshOnInterval = dynamic(() => import('./RefreshOnInterval'))\nconst RefreshOnReconnect = dynamic(() => import('./RefreshOnReconnect'))\n\n/**\n * @public\n */\nexport interface SanityLiveProps extends Pick<\n InitializedClientConfig,\n | 'projectId'\n | 'dataset'\n | 'apiHost'\n | 'apiVersion'\n | 'useProjectHostname'\n | 'token'\n | 'requestTagPrefix'\n> {\n draftModeEnabled: boolean\n draftModePerspective?: ClientPerspective\n refreshOnMount?: boolean\n refreshOnFocus?: boolean\n refreshOnReconnect?: boolean\n requestTag: string | undefined\n onError?: (error: unknown) => void\n intervalOnGoAway?: number | false\n onGoAway?: (event: LiveEventGoAway, intervalOnGoAway: number | false) => void\n revalidateSyncTags?: (tags: SyncTag[]) => Promise<void | 'refresh'>\n waitFor?: 'function'\n}\n\nfunction handleError(error: unknown) {\n if (isCorsOriginError(error)) {\n console.warn(\n `Sanity Live is unable to connect to the Sanity API as the current origin - ${window.origin} - is not in the list of allowed CORS origins for this Sanity Project.`,\n error.addOriginUrl && `Add it here:`,\n error.addOriginUrl?.toString(),\n )\n } else {\n console.error(error)\n }\n}\n\nfunction handleOnGoAway(event: LiveEventGoAway, intervalOnGoAway: number | false) {\n if (intervalOnGoAway) {\n console.warn(\n 'Sanity Live connection closed, switching to long polling set to a interval of',\n intervalOnGoAway / 1000,\n 'seconds and the server gave this reason:',\n event.reason,\n )\n } else {\n console.error(\n 'Sanity Live connection closed, automatic revalidation is disabled, the server gave this reason:',\n event.reason,\n )\n }\n}\n\nfunction SanityLive(props: SanityLiveProps): React.JSX.Element | null {\n const {\n projectId,\n dataset,\n apiHost,\n apiVersion,\n useProjectHostname,\n token,\n requestTagPrefix,\n draftModeEnabled,\n draftModePerspective,\n refreshOnMount = false,\n refreshOnFocus = draftModeEnabled\n ? false\n : typeof window === 'undefined'\n ? true\n : window.self === window.top,\n refreshOnReconnect = true,\n intervalOnGoAway = 30_000,\n requestTag = 'next-loader.live',\n onError = handleError,\n onGoAway = handleOnGoAway,\n revalidateSyncTags = defaultRevalidateSyncTags,\n waitFor,\n } = props\n\n const client = useMemo(\n () =>\n createClient({\n projectId,\n dataset,\n apiHost,\n apiVersion,\n useProjectHostname,\n ignoreBrowserTokenWarning: true,\n token,\n useCdn: false,\n requestTagPrefix,\n }),\n [apiHost, apiVersion, dataset, projectId, requestTagPrefix, token, useProjectHostname],\n )\n const [refreshOnInterval, setRefreshOnInterval] = useState<number | false>(false)\n\n /**\n * 1. Handle Live Events and call revalidateTag or router.refresh when needed\n */\n const router = useRouter()\n const handleLiveEvent = useEffectEvent((event: LiveEvent) => {\n if (process.env.NODE_ENV !== 'production' && event.type === 'welcome') {\n // oxlint-disable-next-line no-console\n console.info(\n 'Sanity is live with',\n token\n ? 'automatic revalidation for draft content changes as well as published content'\n : draftModeEnabled\n ? 'automatic revalidation for only published content. Provide a `browserToken` to `defineLive` to support draft content outside of Presentation Tool.'\n : 'automatic revalidation of published content',\n )\n // Disable long polling when welcome event is received, this is a no-op if long polling is already disabled\n startTransition(() => setRefreshOnInterval(false))\n } else if (event.type === 'message') {\n if (waitFor === 'function') {\n // Cache is already revalidated by the Sanity Function, just refresh the router\n startTransition(() => router.refresh())\n } else {\n void revalidateSyncTags(event.tags).then((result) => {\n if (result === 'refresh') startTransition(() => router.refresh())\n })\n }\n } else if (event.type === 'restart' || event.type === 'reconnect') {\n // Disable long polling when restart/reconnect event is received, this is a no-op if long polling is already disabled\n startTransition(() => setRefreshOnInterval(false))\n // @TODO add support for `onRestart` and `onReconnect` events so this can be customized\n startTransition(() => router.refresh())\n } else if (event.type === 'goaway') {\n onGoAway(event, intervalOnGoAway)\n startTransition(() => setRefreshOnInterval(intervalOnGoAway))\n }\n })\n useEffect(() => {\n const subscription = client.live\n .events({includeDrafts: !!token, tag: requestTag, waitFor})\n .subscribe({\n next: handleLiveEvent,\n error: (err: unknown) => {\n // console.error('What?', err)\n onError(err)\n },\n })\n return () => subscription.unsubscribe()\n }, [client.live, onError, requestTag, token, waitFor])\n\n /**\n * 2. Notify what perspective we're in, when in Draft Mode\n */\n useEffect(() => {\n if (draftModeEnabled && draftModePerspective) {\n setPerspective(draftModePerspective)\n } else {\n setPerspective('unknown')\n }\n }, [draftModeEnabled, draftModePerspective])\n\n const [loadComlink, setLoadComlink] = useState(false)\n /**\n * 3. Notify what environment we're in, when in Draft Mode\n */\n useEffect(() => {\n // If we might be in Presentation Tool, then skip detecting here as it's handled later\n if (isMaybePresentation()) return\n\n // If we're definitely not in Presentation Tool, then we can set the environment as stand-alone live preview\n // if we have both a browser token, and draft mode is enabled\n if (draftModeEnabled && token) {\n setEnvironment('live')\n return\n }\n // If we're in draft mode, but don't have a browser token, then we're in static mode\n // which means that published content is still live, but draft changes likely need manual refresh\n if (draftModeEnabled) {\n setEnvironment('static')\n return\n }\n\n // Fallback to `unknown` otherwise, as we simply don't know how it's setup\n setEnvironment('unknown')\n return\n }, [draftModeEnabled, token])\n\n /**\n * 4. If Presentation Tool is detected, load up the comlink and integrate with it\n */\n useEffect(() => {\n if (!isMaybePresentation()) return\n const controller = new AbortController()\n // Wait for a while to see if Presentation Tool is detected, before assuming the env to be stand-alone live preview\n const timeout = setTimeout(() => setEnvironment('live'), 3_000)\n window.addEventListener(\n 'message',\n ({data}: MessageEvent<unknown>) => {\n if (\n data &&\n typeof data === 'object' &&\n 'domain' in data &&\n data.domain === 'sanity/channels' &&\n 'from' in data &&\n data.from === 'presentation'\n ) {\n clearTimeout(timeout)\n setEnvironment(isMaybePreviewWindow() ? 'presentation-window' : 'presentation-iframe')\n setLoadComlink(true)\n controller.abort()\n }\n },\n {signal: controller.signal},\n )\n return () => {\n clearTimeout(timeout)\n controller.abort()\n }\n }, [])\n\n /**\n * 5. Warn if draft mode is being disabled\n * @TODO move logic into PresentationComlink, or maybe VisualEditing?\n */\n const draftModeEnabledWarnRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n useEffect(() => {\n if (!draftModeEnabled) return\n clearTimeout(draftModeEnabledWarnRef.current)\n return () => {\n draftModeEnabledWarnRef.current = setTimeout(() => {\n console.warn('Sanity Live: Draft mode was enabled, but is now being disabled')\n })\n }\n }, [draftModeEnabled])\n\n return (\n <>\n {draftModeEnabled && loadComlink && (\n <PresentationComlink\n projectId={projectId!}\n dataset={dataset!}\n draftModeEnabled={draftModeEnabled}\n draftModePerspective={draftModePerspective!}\n />\n )}\n {!draftModeEnabled && refreshOnMount && <RefreshOnMount />}\n {refreshOnInterval && Number.isFinite(refreshOnInterval) && refreshOnInterval > 0 && (\n <RefreshOnInterval interval={refreshOnInterval} />\n )}\n {!draftModeEnabled && refreshOnFocus && <RefreshOnFocus />}\n {!draftModeEnabled && refreshOnReconnect && <RefreshOnReconnect />}\n </>\n )\n}\n\nSanityLive.displayName = 'SanityLiveClientComponent'\n\nexport default SanityLive\n"],"mappings":";;;;;;;;;AAkBA,MAAM,sBAAsB,cAAc,OAAO,4BAAyB;AAC1E,MAAM,iBAAiB,cAAc,OAAO,uBAAoB;AAChE,MAAM,iBAAiB,cAAc,OAAO,uBAAoB;AAChE,MAAM,oBAAoB,cAAc,OAAO,0BAAuB;AACtE,MAAM,qBAAqB,cAAc,OAAO,2BAAwB;AA4BxE,SAAS,YAAY,OAAgB;AACnC,KAAI,kBAAkB,MAAM,CAC1B,SAAQ,KACN,8EAA8E,OAAO,OAAO,yEAC5F,MAAM,gBAAgB,gBACtB,MAAM,cAAc,UAAU,CAC/B;KAED,SAAQ,MAAM,MAAM;;AAIxB,SAAS,eAAe,OAAwB,kBAAkC;AAChF,KAAI,iBACF,SAAQ,KACN,iFACA,mBAAmB,KACnB,4CACA,MAAM,OACP;KAED,SAAQ,MACN,mGACA,MAAM,OACP;;AAIL,SAAS,WAAW,OAAkD;CACpE,MAAM,EACJ,WACA,SACA,SACA,YACA,oBACA,OACA,kBACA,kBACA,sBACA,iBAAiB,OACjB,iBAAiB,mBACb,QACA,OAAO,WAAW,cAChB,OACA,OAAO,SAAS,OAAO,KAC7B,qBAAqB,MACrB,mBAAmB,KACnB,aAAa,oBACb,UAAU,aACV,WAAW,gBACX,oBAAA,uBAAqBA,oBACrB,YACE;CAEJ,MAAM,SAAS,cAEX,aAAa;EACX;EACA;EACA;EACA;EACA;EACA,2BAA2B;EAC3B;EACA,QAAQ;EACR;EACD,CAAC,EACJ;EAAC;EAAS;EAAY;EAAS;EAAW;EAAkB;EAAO;EAAmB,CACvF;CACD,MAAM,CAAC,mBAAmB,wBAAwB,SAAyB,MAAM;;;;CAKjF,MAAM,SAAS,WAAW;CAC1B,MAAM,kBAAkB,gBAAgB,UAAqB;AAC3D,MAAI,QAAQ,IAAI,aAAa,gBAAgB,MAAM,SAAS,WAAW;AAErE,WAAQ,KACN,uBACA,QACI,kFACA,mBACE,uJACA,8CACP;AAED,yBAAsB,qBAAqB,MAAM,CAAC;aACzC,MAAM,SAAS,UACxB,KAAI,YAAY,WAEd,uBAAsB,OAAO,SAAS,CAAC;MAElCC,sBAAmB,MAAM,KAAK,CAAC,MAAM,WAAW;AACnD,OAAI,WAAW,UAAW,uBAAsB,OAAO,SAAS,CAAC;IACjE;WAEK,MAAM,SAAS,aAAa,MAAM,SAAS,aAAa;AAEjE,yBAAsB,qBAAqB,MAAM,CAAC;AAElD,yBAAsB,OAAO,SAAS,CAAC;aAC9B,MAAM,SAAS,UAAU;AAClC,YAAS,OAAO,iBAAiB;AACjC,yBAAsB,qBAAqB,iBAAiB,CAAC;;GAE/D;AACF,iBAAgB;EACd,MAAM,eAAe,OAAO,KACzB,OAAO;GAAC,eAAe,CAAC,CAAC;GAAO,KAAK;GAAY;GAAQ,CAAC,CAC1D,UAAU;GACT,MAAM;GACN,QAAQ,QAAiB;AAEvB,YAAQ,IAAI;;GAEf,CAAC;AACJ,eAAa,aAAa,aAAa;IACtC;EAAC,OAAO;EAAM;EAAS;EAAY;EAAO;EAAQ,CAAC;;;;AAKtD,iBAAgB;AACd,MAAI,oBAAoB,qBACtB,gBAAe,qBAAqB;MAEpC,gBAAe,UAAU;IAE1B,CAAC,kBAAkB,qBAAqB,CAAC;CAE5C,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;;;;AAIrD,iBAAgB;AAEd,MAAI,qBAAqB,CAAE;AAI3B,MAAI,oBAAoB,OAAO;AAC7B,kBAAe,OAAO;AACtB;;AAIF,MAAI,kBAAkB;AACpB,kBAAe,SAAS;AACxB;;AAIF,iBAAe,UAAU;IAExB,CAAC,kBAAkB,MAAM,CAAC;;;;AAK7B,iBAAgB;AACd,MAAI,CAAC,qBAAqB,CAAE;EAC5B,MAAM,aAAa,IAAI,iBAAiB;EAExC,MAAM,UAAU,iBAAiB,eAAe,OAAO,EAAE,IAAM;AAC/D,SAAO,iBACL,YACC,EAAC,WAAiC;AACjC,OACE,QACA,OAAO,SAAS,YAChB,YAAY,QACZ,KAAK,WAAW,qBAChB,UAAU,QACV,KAAK,SAAS,gBACd;AACA,iBAAa,QAAQ;AACrB,mBAAe,sBAAsB,GAAG,wBAAwB,sBAAsB;AACtF,mBAAe,KAAK;AACpB,eAAW,OAAO;;KAGtB,EAAC,QAAQ,WAAW,QAAO,CAC5B;AACD,eAAa;AACX,gBAAa,QAAQ;AACrB,cAAW,OAAO;;IAEnB,EAAE,CAAC;;;;;CAMN,MAAM,0BAA0B,OAAkD,KAAA,EAAU;AAC5F,iBAAgB;AACd,MAAI,CAAC,iBAAkB;AACvB,eAAa,wBAAwB,QAAQ;AAC7C,eAAa;AACX,2BAAwB,UAAU,iBAAiB;AACjD,YAAQ,KAAK,iEAAiE;KAC9E;;IAEH,CAAC,iBAAiB,CAAC;AAEtB,QACE,qBAAA,UAAA,EAAA,UAAA;EACG,oBAAoB,eACnB,oBAAC,qBAAD;GACa;GACF;GACS;GACI;GACtB,CAAA;EAEH,CAAC,oBAAoB,kBAAkB,oBAAC,gBAAD,EAAkB,CAAA;EACzD,qBAAqB,OAAO,SAAS,kBAAkB,IAAI,oBAAoB,KAC9E,oBAAC,mBAAD,EAAmB,UAAU,mBAAqB,CAAA;EAEnD,CAAC,oBAAoB,kBAAkB,oBAAC,gBAAD,EAAkB,CAAA;EACzD,CAAC,oBAAoB,sBAAsB,oBAAC,oBAAD,EAAsB,CAAA;EACjE,EAAA,CAAA;;AAIP,WAAW,cAAc"}
|
package/dist/VisualEditing.js
CHANGED
|
@@ -2,7 +2,6 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { VisualEditing as VisualEditing$1 } from "@sanity/visual-editing/react";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
import { revalidateRootLayout } from "next-sanity/visual-editing/server-actions";
|
|
6
5
|
/**
|
|
7
6
|
* From: https://github.com/vercel/next.js/blob/5469e6427b54ab7e9876d4c85b47f9c3afdc5c1f/packages/next/src/shared/lib/router/utils/path-has-prefix.ts#L10-L17
|
|
8
7
|
* Checks if a given path starts with a given prefix. It ensures it matches
|
|
@@ -123,39 +122,31 @@ function VisualEditing(props) {
|
|
|
123
122
|
searchParams,
|
|
124
123
|
trailingSlash
|
|
125
124
|
]);
|
|
125
|
+
const handleRefresh = useCallback((payload) => {
|
|
126
|
+
switch (payload.source) {
|
|
127
|
+
case "manual":
|
|
128
|
+
routerRef.current.refresh();
|
|
129
|
+
break;
|
|
130
|
+
case "mutation":
|
|
131
|
+
if (payload.livePreviewEnabled) {
|
|
132
|
+
console.debug("Live preview is setup, mutation is skipped assuming its handled by the live preview");
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
routerRef.current.refresh();
|
|
136
|
+
break;
|
|
137
|
+
default: throw new Error("Unknown refresh source", { cause: payload });
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
}, []);
|
|
126
141
|
return /* @__PURE__ */ jsx(VisualEditing$1, {
|
|
127
142
|
plugins,
|
|
128
143
|
components,
|
|
129
144
|
history,
|
|
130
145
|
portal: true,
|
|
131
|
-
refresh:
|
|
132
|
-
if (refresh) return refresh(payload);
|
|
133
|
-
const manualFastRefresh = () => {
|
|
134
|
-
console.debug("Live preview is setup, calling router.refresh() to refresh the server components without refetching cached data");
|
|
135
|
-
routerRef.current.refresh();
|
|
136
|
-
return Promise.resolve();
|
|
137
|
-
};
|
|
138
|
-
const manualFallbackRefresh = () => {
|
|
139
|
-
console.debug("No loaders in live mode detected, or preview kit setup, revalidating root layout");
|
|
140
|
-
return revalidateRootLayout();
|
|
141
|
-
};
|
|
142
|
-
const mutationFallbackRefresh = () => {
|
|
143
|
-
console.debug("No loaders in live mode detected, or preview kit setup, revalidating root layout");
|
|
144
|
-
return revalidateRootLayout();
|
|
145
|
-
};
|
|
146
|
-
switch (payload.source) {
|
|
147
|
-
case "manual": return payload.livePreviewEnabled ? manualFastRefresh() : manualFallbackRefresh();
|
|
148
|
-
case "mutation": return payload.livePreviewEnabled ? mutationFastRefresh() : mutationFallbackRefresh();
|
|
149
|
-
default: throw new Error("Unknown refresh source", { cause: payload });
|
|
150
|
-
}
|
|
151
|
-
}, [refresh]),
|
|
146
|
+
refresh: refresh ?? handleRefresh,
|
|
152
147
|
zIndex
|
|
153
148
|
});
|
|
154
149
|
}
|
|
155
|
-
function mutationFastRefresh() {
|
|
156
|
-
console.debug("Live preview is setup, mutation is skipped assuming its handled by the live preview");
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
150
|
export { VisualEditing as default };
|
|
160
151
|
|
|
161
152
|
//# sourceMappingURL=VisualEditing.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisualEditing.js","names":["VisualEditingComponent"],"sources":["../src/visual-editing/client-component/utils.ts","../src/visual-editing/client-component/VisualEditing.tsx"],"sourcesContent":["/**\n * From: https://github.com/vercel/next.js/blob/5469e6427b54ab7e9876d4c85b47f9c3afdc5c1f/packages/next/src/shared/lib/router/utils/path-has-prefix.ts#L10-L17\n * Checks if a given path starts with a given prefix. It ensures it matches\n * exactly without containing extra chars. e.g. prefix /docs should replace\n * for /docs, /docs/, /docs/a but not /docsss\n * @param path The path to check.\n * @param prefix The prefix to check against.\n */\nfunction pathHasPrefix(path: string, prefix: string): boolean {\n if (typeof path !== 'string') {\n return false\n }\n\n const {pathname} = parsePath(path)\n return pathname === prefix || pathname.startsWith(`${prefix}/`)\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/5469e6427b54ab7e9876d4c85b47f9c3afdc5c1f/packages/next/src/shared/lib/router/utils/parse-path.ts#L6-L22\n * Given a path this function will find the pathname, query and hash and return\n * them. This is useful to parse full paths on the client side.\n * @param path A path to parse e.g. /foo/bar?id=1#hash\n */\nfunction parsePath(path: string): {\n pathname: string\n query: string\n hash: string\n} {\n const hashIndex = path.indexOf('#')\n const queryIndex = path.indexOf('?')\n const hasQuery = queryIndex > -1 && (hashIndex < 0 || queryIndex < hashIndex)\n\n if (hasQuery || hashIndex > -1) {\n return {\n pathname: path.substring(0, hasQuery ? queryIndex : hashIndex),\n query: hasQuery ? path.substring(queryIndex, hashIndex > -1 ? hashIndex : undefined) : '',\n hash: hashIndex > -1 ? path.slice(hashIndex) : '',\n }\n }\n\n return {pathname: path, query: '', hash: ''}\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/5469e6427b54ab7e9876d4c85b47f9c3afdc5c1f/packages/next/src/shared/lib/router/utils/add-path-prefix.ts#L3C1-L14C2\n * Adds the provided prefix to the given path. It first ensures that the path\n * is indeed starting with a slash.\n */\nexport function addPathPrefix(path: string, prefix?: string): string {\n if (!path.startsWith('/') || !prefix) {\n return path\n }\n // If the path is exactly '/' then return just the prefix\n if (path === '/' && prefix) {\n return prefix\n }\n\n const {pathname, query, hash} = parsePath(path)\n return `${prefix}${pathname}${query}${hash}`\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/5469e6427b54ab7e9876d4c85b47f9c3afdc5c1f/packages/next/src/shared/lib/router/utils/remove-path-prefix.ts#L3-L39\n * Given a path and a prefix it will remove the prefix when it exists in the\n * given path. It ensures it matches exactly without containing extra chars\n * and if the prefix is not there it will be noop.\n *\n * @param path The path to remove the prefix from.\n * @param prefix The prefix to be removed.\n */\nexport function removePathPrefix(path: string, prefix: string): string {\n // If the path doesn't start with the prefix we can return it as is. This\n // protects us from situations where the prefix is a substring of the path\n // prefix such as:\n //\n // For prefix: /blog\n //\n // /blog -> true\n // /blog/ -> true\n // /blog/1 -> true\n // /blogging -> false\n // /blogging/ -> false\n // /blogging/1 -> false\n if (!pathHasPrefix(path, prefix)) {\n return path\n }\n\n // Remove the prefix from the path via slicing.\n const withoutPrefix = path.slice(prefix.length)\n\n // If the path without the prefix starts with a `/` we can return it as is.\n if (withoutPrefix.startsWith('/')) {\n return withoutPrefix\n }\n\n // If the path without the prefix doesn't start with a `/` we need to add it\n // back to the path to make sure it's a valid path.\n return `/${withoutPrefix}`\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/dfe7fc03e2268e7cb765dce6a89e02c831c922d5/packages/next/src/client/normalize-trailing-slash.ts#L16\n * Normalizes the trailing slash of a path according to the `trailingSlash` option\n * in `next.config.js`.\n */\nexport const normalizePathTrailingSlash = (path: string, trailingSlash: boolean): string => {\n const {pathname, query, hash} = parsePath(path)\n if (trailingSlash) {\n if (pathname.endsWith('/')) {\n return `${pathname}${query}${hash}`\n }\n return `${pathname}/${query}${hash}`\n }\n\n return `${removeTrailingSlash(pathname)}${query}${hash}`\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/dfe7fc03e2268e7cb765dce6a89e02c831c922d5/packages/next/src/shared/lib/router/utils/remove-trailing-slash.ts#L8\n * Removes the trailing slash for a given route or page path. Preserves the\n * root page. Examples:\n * - `/foo/bar/` -> `/foo/bar`\n * - `/foo/bar` -> `/foo/bar`\n * - `/` -> `/`\n */\nfunction removeTrailingSlash(route: string) {\n return route.replace(/\\/$/, '') || '/'\n}\n","import {\n type HistoryAdapter,\n type HistoryAdapterNavigate,\n type HistoryRefresh,\n VisualEditing as VisualEditingComponent,\n type VisualEditingOptions,\n} from '@sanity/visual-editing/react'\nimport {revalidateRootLayout} from 'next-sanity/visual-editing/server-actions'\nimport {usePathname, useRouter, useSearchParams} from 'next/navigation'\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react'\n\nimport {addPathPrefix, normalizePathTrailingSlash, removePathPrefix} from './utils'\n\n/**\n * @public\n */\nexport interface VisualEditingProps extends Omit<VisualEditingOptions, 'history'> {\n /**\n * @deprecated The histoy adapter is already implemented\n */\n history?: never\n /**\n * If next.config.ts is configured with a basePath we try to configure it automatically,\n * you can disable this by setting basePath to ''.\n * @example basePath=\"/my-custom-base-path\"\n * @alpha experimental and may change without notice\n * @defaultValue process.env.__NEXT_ROUTER_BASEPATH || ''\n */\n basePath?: string\n /**\n * If next.config.ts is configured with a `trailingSlash` we try to detect it automatically,\n * it can be controlled manually by passing a boolean.\n * @example trailingSlash={true}\n * @alpha experimental and may change without notice\n * @defaultValue Boolean(process.env.__NEXT_TRAILING_SLASH)\n */\n trailingSlash?: boolean\n}\n\nexport default function VisualEditing(props: VisualEditingProps): React.JSX.Element | null {\n const {basePath = '', plugins, components, refresh, trailingSlash = false, zIndex} = props\n\n const router = useRouter()\n const routerRef = useRef(router)\n const [navigate, setNavigate] = useState<HistoryAdapterNavigate | undefined>()\n\n useEffect(() => {\n routerRef.current = router\n }, [router])\n\n const history = useMemo<HistoryAdapter>(\n () => ({\n subscribe: (_navigate) => {\n setNavigate(() => _navigate)\n return () => setNavigate(undefined)\n },\n update: (update) => {\n switch (update.type) {\n case 'push':\n return routerRef.current.push(removePathPrefix(update.url, basePath))\n case 'pop':\n return routerRef.current.back()\n case 'replace':\n return routerRef.current.replace(removePathPrefix(update.url, basePath))\n default:\n throw new Error(`Unknown update type`, {cause: update})\n }\n },\n }),\n [basePath],\n )\n\n const pathname = usePathname()\n const searchParams = useSearchParams()\n useEffect(() => {\n if (navigate) {\n navigate({\n type: 'push',\n url: normalizePathTrailingSlash(\n addPathPrefix(\n `${pathname}${searchParams?.size ? `?${searchParams.toString()}` : ''}`,\n basePath,\n ),\n trailingSlash,\n ),\n })\n }\n }, [basePath, navigate, pathname, searchParams, trailingSlash])\n\n const handleRefresh = useCallback(\n (payload: HistoryRefresh) => {\n if (refresh) return refresh(payload)\n\n const manualFastRefresh = () => {\n // oxlint-disable-next-line no-console\n console.debug(\n 'Live preview is setup, calling router.refresh() to refresh the server components without refetching cached data',\n )\n routerRef.current.refresh()\n return Promise.resolve()\n }\n const manualFallbackRefresh = () => {\n // oxlint-disable-next-line no-console\n console.debug(\n 'No loaders in live mode detected, or preview kit setup, revalidating root layout',\n )\n return revalidateRootLayout()\n }\n\n const mutationFallbackRefresh = () => {\n // oxlint-disable-next-line no-console\n console.debug(\n 'No loaders in live mode detected, or preview kit setup, revalidating root layout',\n )\n return revalidateRootLayout()\n }\n\n switch (payload.source) {\n case 'manual':\n return payload.livePreviewEnabled ? manualFastRefresh() : manualFallbackRefresh()\n case 'mutation':\n return payload.livePreviewEnabled ? mutationFastRefresh() : mutationFallbackRefresh()\n default:\n throw new Error('Unknown refresh source', {cause: payload})\n }\n },\n [refresh],\n )\n\n return (\n <VisualEditingComponent\n plugins={plugins}\n components={components}\n history={history}\n portal\n refresh={handleRefresh}\n zIndex={zIndex}\n />\n )\n}\n\nfunction mutationFastRefresh(): false {\n // oxlint-disable-next-line no-console\n console.debug(\n 'Live preview is setup, mutation is skipped assuming its handled by the live preview',\n )\n return false\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VisualEditing.js","names":["VisualEditingComponent"],"sources":["../src/visual-editing/client-component/utils.ts","../src/visual-editing/client-component/VisualEditing.tsx"],"sourcesContent":["/**\n * From: https://github.com/vercel/next.js/blob/5469e6427b54ab7e9876d4c85b47f9c3afdc5c1f/packages/next/src/shared/lib/router/utils/path-has-prefix.ts#L10-L17\n * Checks if a given path starts with a given prefix. It ensures it matches\n * exactly without containing extra chars. e.g. prefix /docs should replace\n * for /docs, /docs/, /docs/a but not /docsss\n * @param path The path to check.\n * @param prefix The prefix to check against.\n */\nfunction pathHasPrefix(path: string, prefix: string): boolean {\n if (typeof path !== 'string') {\n return false\n }\n\n const {pathname} = parsePath(path)\n return pathname === prefix || pathname.startsWith(`${prefix}/`)\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/5469e6427b54ab7e9876d4c85b47f9c3afdc5c1f/packages/next/src/shared/lib/router/utils/parse-path.ts#L6-L22\n * Given a path this function will find the pathname, query and hash and return\n * them. This is useful to parse full paths on the client side.\n * @param path A path to parse e.g. /foo/bar?id=1#hash\n */\nfunction parsePath(path: string): {\n pathname: string\n query: string\n hash: string\n} {\n const hashIndex = path.indexOf('#')\n const queryIndex = path.indexOf('?')\n const hasQuery = queryIndex > -1 && (hashIndex < 0 || queryIndex < hashIndex)\n\n if (hasQuery || hashIndex > -1) {\n return {\n pathname: path.substring(0, hasQuery ? queryIndex : hashIndex),\n query: hasQuery ? path.substring(queryIndex, hashIndex > -1 ? hashIndex : undefined) : '',\n hash: hashIndex > -1 ? path.slice(hashIndex) : '',\n }\n }\n\n return {pathname: path, query: '', hash: ''}\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/5469e6427b54ab7e9876d4c85b47f9c3afdc5c1f/packages/next/src/shared/lib/router/utils/add-path-prefix.ts#L3C1-L14C2\n * Adds the provided prefix to the given path. It first ensures that the path\n * is indeed starting with a slash.\n */\nexport function addPathPrefix(path: string, prefix?: string): string {\n if (!path.startsWith('/') || !prefix) {\n return path\n }\n // If the path is exactly '/' then return just the prefix\n if (path === '/' && prefix) {\n return prefix\n }\n\n const {pathname, query, hash} = parsePath(path)\n return `${prefix}${pathname}${query}${hash}`\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/5469e6427b54ab7e9876d4c85b47f9c3afdc5c1f/packages/next/src/shared/lib/router/utils/remove-path-prefix.ts#L3-L39\n * Given a path and a prefix it will remove the prefix when it exists in the\n * given path. It ensures it matches exactly without containing extra chars\n * and if the prefix is not there it will be noop.\n *\n * @param path The path to remove the prefix from.\n * @param prefix The prefix to be removed.\n */\nexport function removePathPrefix(path: string, prefix: string): string {\n // If the path doesn't start with the prefix we can return it as is. This\n // protects us from situations where the prefix is a substring of the path\n // prefix such as:\n //\n // For prefix: /blog\n //\n // /blog -> true\n // /blog/ -> true\n // /blog/1 -> true\n // /blogging -> false\n // /blogging/ -> false\n // /blogging/1 -> false\n if (!pathHasPrefix(path, prefix)) {\n return path\n }\n\n // Remove the prefix from the path via slicing.\n const withoutPrefix = path.slice(prefix.length)\n\n // If the path without the prefix starts with a `/` we can return it as is.\n if (withoutPrefix.startsWith('/')) {\n return withoutPrefix\n }\n\n // If the path without the prefix doesn't start with a `/` we need to add it\n // back to the path to make sure it's a valid path.\n return `/${withoutPrefix}`\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/dfe7fc03e2268e7cb765dce6a89e02c831c922d5/packages/next/src/client/normalize-trailing-slash.ts#L16\n * Normalizes the trailing slash of a path according to the `trailingSlash` option\n * in `next.config.js`.\n */\nexport const normalizePathTrailingSlash = (path: string, trailingSlash: boolean): string => {\n const {pathname, query, hash} = parsePath(path)\n if (trailingSlash) {\n if (pathname.endsWith('/')) {\n return `${pathname}${query}${hash}`\n }\n return `${pathname}/${query}${hash}`\n }\n\n return `${removeTrailingSlash(pathname)}${query}${hash}`\n}\n\n/**\n * From: https://github.com/vercel/next.js/blob/dfe7fc03e2268e7cb765dce6a89e02c831c922d5/packages/next/src/shared/lib/router/utils/remove-trailing-slash.ts#L8\n * Removes the trailing slash for a given route or page path. Preserves the\n * root page. Examples:\n * - `/foo/bar/` -> `/foo/bar`\n * - `/foo/bar` -> `/foo/bar`\n * - `/` -> `/`\n */\nfunction removeTrailingSlash(route: string) {\n return route.replace(/\\/$/, '') || '/'\n}\n","import {\n type HistoryAdapter,\n type HistoryAdapterNavigate,\n type HistoryRefresh,\n VisualEditing as VisualEditingComponent,\n type VisualEditingOptions,\n} from '@sanity/visual-editing/react'\nimport {usePathname, useRouter, useSearchParams} from 'next/navigation'\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react'\n\nimport {addPathPrefix, normalizePathTrailingSlash, removePathPrefix} from './utils'\n\n/**\n * @public\n */\nexport interface VisualEditingProps extends Omit<VisualEditingOptions, 'history'> {\n /**\n * @deprecated The histoy adapter is already implemented\n */\n history?: never\n /**\n * If next.config.ts is configured with a basePath we try to configure it automatically,\n * you can disable this by setting basePath to ''.\n * @example basePath=\"/my-custom-base-path\"\n * @alpha experimental and may change without notice\n * @defaultValue process.env.__NEXT_ROUTER_BASEPATH || ''\n */\n basePath?: string\n /**\n * If next.config.ts is configured with a `trailingSlash` we try to detect it automatically,\n * it can be controlled manually by passing a boolean.\n * @example trailingSlash={true}\n * @alpha experimental and may change without notice\n * @defaultValue Boolean(process.env.__NEXT_TRAILING_SLASH)\n */\n trailingSlash?: boolean\n}\n\nexport default function VisualEditing(props: VisualEditingProps): React.JSX.Element | null {\n const {basePath = '', plugins, components, refresh, trailingSlash = false, zIndex} = props\n\n const router = useRouter()\n const routerRef = useRef(router)\n const [navigate, setNavigate] = useState<HistoryAdapterNavigate | undefined>()\n\n useEffect(() => {\n routerRef.current = router\n }, [router])\n\n const history = useMemo<HistoryAdapter>(\n () => ({\n subscribe: (_navigate) => {\n setNavigate(() => _navigate)\n return () => setNavigate(undefined)\n },\n update: (update) => {\n switch (update.type) {\n case 'push':\n return routerRef.current.push(removePathPrefix(update.url, basePath))\n case 'pop':\n return routerRef.current.back()\n case 'replace':\n return routerRef.current.replace(removePathPrefix(update.url, basePath))\n default:\n throw new Error(`Unknown update type`, {cause: update})\n }\n },\n }),\n [basePath],\n )\n\n const pathname = usePathname()\n const searchParams = useSearchParams()\n useEffect(() => {\n if (navigate) {\n navigate({\n type: 'push',\n url: normalizePathTrailingSlash(\n addPathPrefix(\n `${pathname}${searchParams?.size ? `?${searchParams.toString()}` : ''}`,\n basePath,\n ),\n trailingSlash,\n ),\n })\n }\n }, [basePath, navigate, pathname, searchParams, trailingSlash])\n\n const handleRefresh = useCallback((payload: HistoryRefresh): false => {\n switch (payload.source) {\n case 'manual':\n routerRef.current.refresh()\n break\n case 'mutation': {\n if (payload.livePreviewEnabled) {\n // oxlint-disable-next-line no-console\n console.debug(\n 'Live preview is setup, mutation is skipped assuming its handled by the live preview',\n )\n return false\n }\n routerRef.current.refresh()\n break\n }\n default:\n throw new Error('Unknown refresh source', {cause: payload})\n }\n return false\n }, [])\n\n return (\n <VisualEditingComponent\n plugins={plugins}\n components={components}\n history={history}\n portal\n refresh={refresh ?? handleRefresh}\n zIndex={zIndex}\n />\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isCorsOriginError.js","names":[],"sources":["../src/live/shared/isCorsOriginError.ts"],"sourcesContent":["import type {CorsOriginError} from '@sanity/client'\n\n/** @public */\nexport function isCorsOriginError(error: unknown): error is CorsOriginError {\n return error instanceof Error && error.name === 'CorsOriginError'\n}\n
|
|
1
|
+
{"version":3,"file":"isCorsOriginError.js","names":[],"sources":["../src/live/shared/isCorsOriginError.ts"],"sourcesContent":["import type {CorsOriginError} from '@sanity/client'\n\n/** @public */\nexport function isCorsOriginError(error: unknown): error is CorsOriginError {\n return error instanceof Error && error.name === 'CorsOriginError'\n}\n"],"mappings":";AAGA,SAAgB,kBAAkB,OAA0C;AAC1E,QAAO,iBAAiB,SAAS,MAAM,SAAS"}
|
|
@@ -9,23 +9,15 @@ interface SanityLiveProps extends Pick<InitializedClientConfig, "projectId" | "d
|
|
|
9
9
|
refreshOnFocus?: boolean;
|
|
10
10
|
refreshOnReconnect?: boolean;
|
|
11
11
|
requestTag: string | undefined;
|
|
12
|
-
/**
|
|
13
|
-
* Handle errors from the Live Events subscription.
|
|
14
|
-
* By default it's reported using `console.error`, you can override this prop to handle it in your own way.
|
|
15
|
-
*/
|
|
16
12
|
onError?: (error: unknown) => void;
|
|
17
13
|
intervalOnGoAway?: number | false;
|
|
18
14
|
onGoAway?: (event: LiveEventGoAway, intervalOnGoAway: number | false) => void;
|
|
19
15
|
revalidateSyncTags?: (tags: SyncTag[]) => Promise<void | "refresh">;
|
|
20
|
-
/**
|
|
21
|
-
* Delays events until after a configured Sanity Function has processed them and called the callback endpoint.
|
|
22
|
-
* When omitted, events are delivered immediately.
|
|
23
|
-
*
|
|
24
|
-
* @remarks
|
|
25
|
-
* When set, any custom `revalidateSyncTags` will not be called — revalidation is handled by the Function instead.
|
|
26
|
-
*/
|
|
27
16
|
waitFor?: "function";
|
|
28
17
|
}
|
|
29
|
-
|
|
30
|
-
|
|
18
|
+
/**
|
|
19
|
+
* @alpha CAUTION: this is an internal component and does not follow semver. Using it directly is at your own risk.
|
|
20
|
+
*/
|
|
21
|
+
declare const SanityLive: React.ComponentType<SanityLiveProps>;
|
|
22
|
+
export { SanityLive };
|
|
31
23
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/live/client-components/SanityLive.tsx"],"mappings":";;AA2BA;;UAAiB,eAAA,SAAwB,IAAA,CACvC,uBAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/live/client-components/SanityLive.tsx","../../../src/live/client-components/index.ts"],"mappings":";;AA2BA;;UAAiB,eAAA,SAAwB,IAAA,CACvC,uBAAA;EASA,gBAAA;EACA,oBAAA,GAAuB,iBAAA;EACvB,cAAA;EACA,cAAA;EACA,kBAAA;EACA,UAAA;EACA,OAAA,IAAW,KAAA;EACX,gBAAA;EACA,QAAA,IAAY,KAAA,EAAO,eAAA,EAAiB,gBAAA;EACpC,kBAAA,IAAsB,IAAA,EAAM,OAAA,OAAc,OAAA;EAC1C,OAAA;AAAA;;AApBF;;cCnBa,UAAA,EAAY,KAAA,CAAM,aAAA,CAAc,eAAA"}
|
|
@@ -1,158 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { d as setEnvironment, f as setPerspective } from "../../context.js";
|
|
3
|
-
import { t as isCorsOriginError } from "../../isCorsOriginError.js";
|
|
4
|
-
import { useRouter } from "next/navigation";
|
|
5
|
-
import { startTransition, useEffect, useEffectEvent, useMemo, useRef, useState } from "react";
|
|
6
|
-
import { isMaybePresentation, isMaybePreviewWindow } from "@sanity/presentation-comlink";
|
|
7
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { createClient } from "@sanity/client";
|
|
9
|
-
import { revalidateSyncTags } from "next-sanity/live/server-actions";
|
|
10
2
|
import dynamic from "next/dynamic";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
function handleError(error) {
|
|
17
|
-
if (isCorsOriginError(error)) console.warn(`Sanity Live is unable to connect to the Sanity API as the current origin - ${window.origin} - is not in the list of allowed CORS origins for this Sanity Project.`, error.addOriginUrl && `Add it here:`, error.addOriginUrl?.toString());
|
|
18
|
-
else console.error(error);
|
|
19
|
-
}
|
|
20
|
-
function handleOnGoAway(event, intervalOnGoAway) {
|
|
21
|
-
if (intervalOnGoAway) console.warn("Sanity Live connection closed, switching to long polling set to a interval of", intervalOnGoAway / 1e3, "seconds and the server gave this reason:", event.reason);
|
|
22
|
-
else console.error("Sanity Live connection closed, automatic revalidation is disabled, the server gave this reason:", event.reason);
|
|
23
|
-
}
|
|
24
|
-
function SanityLive(props) {
|
|
25
|
-
const { projectId, dataset, apiHost, apiVersion, useProjectHostname, token, requestTagPrefix, draftModeEnabled, draftModePerspective, refreshOnMount = false, refreshOnFocus = draftModeEnabled ? false : typeof window === "undefined" ? true : window.self === window.top, refreshOnReconnect = true, intervalOnGoAway = 3e4, requestTag = "next-loader.live", onError = handleError, onGoAway = handleOnGoAway, revalidateSyncTags: revalidateSyncTags$1 = revalidateSyncTags, waitFor } = props;
|
|
26
|
-
const client = useMemo(() => createClient({
|
|
27
|
-
projectId,
|
|
28
|
-
dataset,
|
|
29
|
-
apiHost,
|
|
30
|
-
apiVersion,
|
|
31
|
-
useProjectHostname,
|
|
32
|
-
ignoreBrowserTokenWarning: true,
|
|
33
|
-
token,
|
|
34
|
-
useCdn: false,
|
|
35
|
-
requestTagPrefix
|
|
36
|
-
}), [
|
|
37
|
-
apiHost,
|
|
38
|
-
apiVersion,
|
|
39
|
-
dataset,
|
|
40
|
-
projectId,
|
|
41
|
-
requestTagPrefix,
|
|
42
|
-
token,
|
|
43
|
-
useProjectHostname
|
|
44
|
-
]);
|
|
45
|
-
const [refreshOnInterval, setRefreshOnInterval] = useState(false);
|
|
46
|
-
/**
|
|
47
|
-
* 1. Handle Live Events and call revalidateTag or router.refresh when needed
|
|
48
|
-
*/
|
|
49
|
-
const router = useRouter();
|
|
50
|
-
const handleLiveEvent = useEffectEvent((event) => {
|
|
51
|
-
if (process.env.NODE_ENV !== "production" && event.type === "welcome") {
|
|
52
|
-
console.info("Sanity is live with", token ? "automatic revalidation for draft content changes as well as published content" : draftModeEnabled ? "automatic revalidation for only published content. Provide a `browserToken` to `defineLive` to support draft content outside of Presentation Tool." : "automatic revalidation of published content");
|
|
53
|
-
startTransition(() => setRefreshOnInterval(false));
|
|
54
|
-
} else if (event.type === "message") if (waitFor === "function") router.refresh();
|
|
55
|
-
else revalidateSyncTags$1(event.tags).then((result) => {
|
|
56
|
-
if (result === "refresh") startTransition(() => router.refresh());
|
|
57
|
-
});
|
|
58
|
-
else if (event.type === "restart" || event.type === "reconnect") {
|
|
59
|
-
startTransition(() => setRefreshOnInterval(false));
|
|
60
|
-
startTransition(() => router.refresh());
|
|
61
|
-
} else if (event.type === "goaway") {
|
|
62
|
-
onGoAway(event, intervalOnGoAway);
|
|
63
|
-
startTransition(() => setRefreshOnInterval(intervalOnGoAway));
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
const subscription = client.live.events({
|
|
68
|
-
includeDrafts: !!token,
|
|
69
|
-
tag: requestTag,
|
|
70
|
-
waitFor
|
|
71
|
-
}).subscribe({
|
|
72
|
-
next: handleLiveEvent,
|
|
73
|
-
error: (err) => {
|
|
74
|
-
onError(err);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
return () => subscription.unsubscribe();
|
|
78
|
-
}, [
|
|
79
|
-
client.live,
|
|
80
|
-
onError,
|
|
81
|
-
requestTag,
|
|
82
|
-
token,
|
|
83
|
-
waitFor
|
|
84
|
-
]);
|
|
85
|
-
/**
|
|
86
|
-
* 2. Notify what perspective we're in, when in Draft Mode
|
|
87
|
-
*/
|
|
88
|
-
useEffect(() => {
|
|
89
|
-
if (draftModeEnabled && draftModePerspective) setPerspective(draftModePerspective);
|
|
90
|
-
else setPerspective("unknown");
|
|
91
|
-
}, [draftModeEnabled, draftModePerspective]);
|
|
92
|
-
const [loadComlink, setLoadComlink] = useState(false);
|
|
93
|
-
/**
|
|
94
|
-
* 3. Notify what environment we're in, when in Draft Mode
|
|
95
|
-
*/
|
|
96
|
-
useEffect(() => {
|
|
97
|
-
if (isMaybePresentation()) return;
|
|
98
|
-
if (draftModeEnabled && token) {
|
|
99
|
-
setEnvironment("live");
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
if (draftModeEnabled) {
|
|
103
|
-
setEnvironment("static");
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
setEnvironment("unknown");
|
|
107
|
-
}, [draftModeEnabled, token]);
|
|
108
|
-
/**
|
|
109
|
-
* 4. If Presentation Tool is detected, load up the comlink and integrate with it
|
|
110
|
-
*/
|
|
111
|
-
useEffect(() => {
|
|
112
|
-
if (!isMaybePresentation()) return;
|
|
113
|
-
const controller = new AbortController();
|
|
114
|
-
const timeout = setTimeout(() => setEnvironment("live"), 3e3);
|
|
115
|
-
window.addEventListener("message", ({ data }) => {
|
|
116
|
-
if (data && typeof data === "object" && "domain" in data && data.domain === "sanity/channels" && "from" in data && data.from === "presentation") {
|
|
117
|
-
clearTimeout(timeout);
|
|
118
|
-
setEnvironment(isMaybePreviewWindow() ? "presentation-window" : "presentation-iframe");
|
|
119
|
-
setLoadComlink(true);
|
|
120
|
-
controller.abort();
|
|
121
|
-
}
|
|
122
|
-
}, { signal: controller.signal });
|
|
123
|
-
return () => {
|
|
124
|
-
clearTimeout(timeout);
|
|
125
|
-
controller.abort();
|
|
126
|
-
};
|
|
127
|
-
}, []);
|
|
128
|
-
/**
|
|
129
|
-
* 5. Warn if draft mode is being disabled
|
|
130
|
-
* @TODO move logic into PresentationComlink, or maybe VisualEditing?
|
|
131
|
-
*/
|
|
132
|
-
const draftModeEnabledWarnRef = useRef(void 0);
|
|
133
|
-
useEffect(() => {
|
|
134
|
-
if (!draftModeEnabled) return;
|
|
135
|
-
clearTimeout(draftModeEnabledWarnRef.current);
|
|
136
|
-
return () => {
|
|
137
|
-
draftModeEnabledWarnRef.current = setTimeout(() => {
|
|
138
|
-
console.warn("Sanity Live: Draft mode was enabled, but is now being disabled");
|
|
139
|
-
});
|
|
140
|
-
};
|
|
141
|
-
}, [draftModeEnabled]);
|
|
142
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
143
|
-
draftModeEnabled && loadComlink && /* @__PURE__ */ jsx(PresentationComlink, {
|
|
144
|
-
projectId,
|
|
145
|
-
dataset,
|
|
146
|
-
draftModeEnabled,
|
|
147
|
-
draftModePerspective
|
|
148
|
-
}),
|
|
149
|
-
!draftModeEnabled && refreshOnMount && /* @__PURE__ */ jsx(RefreshOnMount, {}),
|
|
150
|
-
refreshOnInterval && Number.isFinite(refreshOnInterval) && refreshOnInterval > 0 && /* @__PURE__ */ jsx(RefreshOnInterval, { interval: refreshOnInterval }),
|
|
151
|
-
!draftModeEnabled && refreshOnFocus && /* @__PURE__ */ jsx(RefreshOnFocus, {}),
|
|
152
|
-
!draftModeEnabled && refreshOnReconnect && /* @__PURE__ */ jsx(RefreshOnReconnect, {})
|
|
153
|
-
] });
|
|
154
|
-
}
|
|
155
|
-
SanityLive.displayName = "SanityLiveClientComponent";
|
|
156
|
-
export { SanityLive as default };
|
|
3
|
+
/**
|
|
4
|
+
* @alpha CAUTION: this is an internal component and does not follow semver. Using it directly is at your own risk.
|
|
5
|
+
*/
|
|
6
|
+
const SanityLive = dynamic(() => import("../../SanityLive.js"), { ssr: false });
|
|
7
|
+
export { SanityLive };
|
|
157
8
|
|
|
158
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["defaultRevalidateSyncTags","revalidateSyncTags"],"sources":["../../../src/live/client-components/SanityLive.tsx"],"sourcesContent":["import {\n createClient,\n type ClientPerspective,\n type InitializedClientConfig,\n type LiveEvent,\n type LiveEventGoAway,\n type SyncTag,\n} from '@sanity/client'\nimport {isMaybePresentation, isMaybePreviewWindow} from '@sanity/presentation-comlink'\nimport {revalidateSyncTags as defaultRevalidateSyncTags} from 'next-sanity/live/server-actions'\nimport dynamic from 'next/dynamic'\nimport {useRouter} from 'next/navigation'\nimport {useEffect, useMemo, useRef, useState, useEffectEvent, startTransition} from 'react'\n\nimport {isCorsOriginError} from '#live/isCorsOriginError'\n\nimport {setEnvironment, setPerspective} from '../hooks/context'\n\nconst PresentationComlink = dynamic(() => import('./PresentationComlink'))\nconst RefreshOnMount = dynamic(() => import('./RefreshOnMount'))\nconst RefreshOnInterval = dynamic(() => import('./RefreshOnInterval'))\nconst RefreshOnFocus = dynamic(() => import('./RefreshOnFocus'))\nconst RefreshOnReconnect = dynamic(() => import('./RefreshOnReconnect'))\n\n/**\n * @public\n */\nexport interface SanityLiveProps extends Pick<\n InitializedClientConfig,\n | 'projectId'\n | 'dataset'\n | 'apiHost'\n | 'apiVersion'\n | 'useProjectHostname'\n | 'token'\n | 'requestTagPrefix'\n> {\n // handleDraftModeAction: (secret: string) => Promise<void | string>\n draftModeEnabled: boolean\n draftModePerspective?: ClientPerspective\n refreshOnMount?: boolean\n refreshOnFocus?: boolean\n refreshOnReconnect?: boolean\n requestTag: string | undefined\n /**\n * Handle errors from the Live Events subscription.\n * By default it's reported using `console.error`, you can override this prop to handle it in your own way.\n */\n onError?: (error: unknown) => void\n intervalOnGoAway?: number | false\n onGoAway?: (event: LiveEventGoAway, intervalOnGoAway: number | false) => void\n revalidateSyncTags?: (tags: SyncTag[]) => Promise<void | 'refresh'>\n /**\n * Delays events until after a configured Sanity Function has processed them and called the callback endpoint.\n * When omitted, events are delivered immediately.\n *\n * @remarks\n * When set, any custom `revalidateSyncTags` will not be called — revalidation is handled by the Function instead.\n */\n waitFor?: 'function'\n}\n\nfunction handleError(error: unknown) {\n if (isCorsOriginError(error)) {\n console.warn(\n `Sanity Live is unable to connect to the Sanity API as the current origin - ${window.origin} - is not in the list of allowed CORS origins for this Sanity Project.`,\n error.addOriginUrl && `Add it here:`,\n error.addOriginUrl?.toString(),\n )\n } else {\n console.error(error)\n }\n}\n\nfunction handleOnGoAway(event: LiveEventGoAway, intervalOnGoAway: number | false) {\n if (intervalOnGoAway) {\n console.warn(\n 'Sanity Live connection closed, switching to long polling set to a interval of',\n intervalOnGoAway / 1000,\n 'seconds and the server gave this reason:',\n event.reason,\n )\n } else {\n console.error(\n 'Sanity Live connection closed, automatic revalidation is disabled, the server gave this reason:',\n event.reason,\n )\n }\n}\n\nfunction SanityLive(props: SanityLiveProps): React.JSX.Element | null {\n const {\n projectId,\n dataset,\n apiHost,\n apiVersion,\n useProjectHostname,\n token,\n requestTagPrefix,\n // handleDraftModeAction,\n draftModeEnabled,\n draftModePerspective,\n refreshOnMount = false,\n refreshOnFocus = draftModeEnabled\n ? false\n : typeof window === 'undefined'\n ? true\n : window.self === window.top,\n refreshOnReconnect = true,\n intervalOnGoAway = 30_000,\n requestTag = 'next-loader.live',\n onError = handleError,\n onGoAway = handleOnGoAway,\n revalidateSyncTags = defaultRevalidateSyncTags,\n waitFor,\n } = props\n\n const client = useMemo(\n () =>\n createClient({\n projectId,\n dataset,\n apiHost,\n apiVersion,\n useProjectHostname,\n ignoreBrowserTokenWarning: true,\n token,\n useCdn: false,\n requestTagPrefix,\n }),\n [apiHost, apiVersion, dataset, projectId, requestTagPrefix, token, useProjectHostname],\n )\n const [refreshOnInterval, setRefreshOnInterval] = useState<number | false>(false)\n\n /**\n * 1. Handle Live Events and call revalidateTag or router.refresh when needed\n */\n const router = useRouter()\n const handleLiveEvent = useEffectEvent((event: LiveEvent) => {\n if (process.env.NODE_ENV !== 'production' && event.type === 'welcome') {\n // oxlint-disable-next-line no-console\n console.info(\n 'Sanity is live with',\n token\n ? 'automatic revalidation for draft content changes as well as published content'\n : draftModeEnabled\n ? 'automatic revalidation for only published content. Provide a `browserToken` to `defineLive` to support draft content outside of Presentation Tool.'\n : 'automatic revalidation of published content',\n )\n // Disable long polling when welcome event is received, this is a no-op if long polling is already disabled\n startTransition(() => setRefreshOnInterval(false))\n } else if (event.type === 'message') {\n if (waitFor === 'function') {\n // Cache is already revalidated by the Sanity Function, just refresh the router\n router.refresh()\n } else {\n void revalidateSyncTags(event.tags).then((result) => {\n if (result === 'refresh') startTransition(() => router.refresh())\n })\n }\n } else if (event.type === 'restart' || event.type === 'reconnect') {\n // Disable long polling when restart/reconnect event is received, this is a no-op if long polling is already disabled\n startTransition(() => setRefreshOnInterval(false))\n // @TODO add support for `onRestart` and `onReconnect` events so this can be customized\n startTransition(() => router.refresh())\n } else if (event.type === 'goaway') {\n onGoAway(event, intervalOnGoAway)\n startTransition(() => setRefreshOnInterval(intervalOnGoAway))\n }\n })\n useEffect(() => {\n const subscription = client.live\n .events({includeDrafts: !!token, tag: requestTag, waitFor})\n .subscribe({\n next: handleLiveEvent,\n error: (err: unknown) => {\n // console.error('What?', err)\n onError(err)\n },\n })\n return () => subscription.unsubscribe()\n }, [client.live, onError, requestTag, token, waitFor])\n\n /**\n * 2. Notify what perspective we're in, when in Draft Mode\n */\n useEffect(() => {\n if (draftModeEnabled && draftModePerspective) {\n setPerspective(draftModePerspective)\n } else {\n setPerspective('unknown')\n }\n }, [draftModeEnabled, draftModePerspective])\n\n const [loadComlink, setLoadComlink] = useState(false)\n /**\n * 3. Notify what environment we're in, when in Draft Mode\n */\n useEffect(() => {\n // If we might be in Presentation Tool, then skip detecting here as it's handled later\n if (isMaybePresentation()) return\n\n // If we're definitely not in Presentation Tool, then we can set the environment as stand-alone live preview\n // if we have both a browser token, and draft mode is enabled\n if (draftModeEnabled && token) {\n setEnvironment('live')\n return\n }\n // If we're in draft mode, but don't have a browser token, then we're in static mode\n // which means that published content is still live, but draft changes likely need manual refresh\n if (draftModeEnabled) {\n setEnvironment('static')\n return\n }\n\n // Fallback to `unknown` otherwise, as we simply don't know how it's setup\n setEnvironment('unknown')\n return\n }, [draftModeEnabled, token])\n\n /**\n * 4. If Presentation Tool is detected, load up the comlink and integrate with it\n */\n useEffect(() => {\n if (!isMaybePresentation()) return\n const controller = new AbortController()\n // Wait for a while to see if Presentation Tool is detected, before assuming the env to be stand-alone live preview\n const timeout = setTimeout(() => setEnvironment('live'), 3_000)\n window.addEventListener(\n 'message',\n ({data}: MessageEvent<unknown>) => {\n if (\n data &&\n typeof data === 'object' &&\n 'domain' in data &&\n data.domain === 'sanity/channels' &&\n 'from' in data &&\n data.from === 'presentation'\n ) {\n clearTimeout(timeout)\n setEnvironment(isMaybePreviewWindow() ? 'presentation-window' : 'presentation-iframe')\n setLoadComlink(true)\n controller.abort()\n }\n },\n {signal: controller.signal},\n )\n return () => {\n clearTimeout(timeout)\n controller.abort()\n }\n }, [])\n\n /**\n * 5. Warn if draft mode is being disabled\n * @TODO move logic into PresentationComlink, or maybe VisualEditing?\n */\n const draftModeEnabledWarnRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n useEffect(() => {\n if (!draftModeEnabled) return\n clearTimeout(draftModeEnabledWarnRef.current)\n return () => {\n draftModeEnabledWarnRef.current = setTimeout(() => {\n console.warn('Sanity Live: Draft mode was enabled, but is now being disabled')\n })\n }\n }, [draftModeEnabled])\n\n return (\n <>\n {draftModeEnabled && loadComlink && (\n <PresentationComlink\n projectId={projectId!}\n dataset={dataset!}\n // handleDraftModeAction={handleDraftModeAction}\n draftModeEnabled={draftModeEnabled}\n draftModePerspective={draftModePerspective!}\n />\n )}\n {!draftModeEnabled && refreshOnMount && <RefreshOnMount />}\n {refreshOnInterval && Number.isFinite(refreshOnInterval) && refreshOnInterval > 0 && (\n <RefreshOnInterval interval={refreshOnInterval} />\n )}\n {!draftModeEnabled && refreshOnFocus && <RefreshOnFocus />}\n {!draftModeEnabled && refreshOnReconnect && <RefreshOnReconnect />}\n </>\n )\n}\n\nSanityLive.displayName = 'SanityLiveClientComponent'\n\nexport default SanityLive\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/live/client-components/index.ts"],"sourcesContent":["'use client'\n\nimport dynamic from 'next/dynamic'\n\nimport type {SanityLiveProps} from './SanityLive'\n/**\n * @alpha CAUTION: this is an internal component and does not follow semver. Using it directly is at your own risk.\n */\nexport const SanityLive: React.ComponentType<SanityLiveProps> = dynamic(\n () => import('./SanityLive'),\n {ssr: false},\n)\n"],"mappings":";;;;;AAQA,MAAa,aAAmD,cACxD,OAAO,wBACb,EAAC,KAAK,OAAM,CACb"}
|