next-sanity 13.0.0-cache-components.59 → 13.0.0-cache-components.61
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/SanityLive.js +16 -11
- package/dist/SanityLive.js.map +1 -1
- package/dist/live/client-components/index.d.ts.map +1 -1
- package/dist/live/conditions/react-server/index.js +3 -2
- package/dist/live/conditions/react-server/index.js.map +1 -1
- package/dist/live/server-actions/index.js +1 -0
- package/dist/live/server-actions/index.js.map +1 -1
- package/dist/types.d.ts +12 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -8
package/dist/SanityLive.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as isCorsOriginError } from "./isCorsOriginError.js";
|
|
1
2
|
import { t as cacheTagPrefix } from "./constants.js";
|
|
2
3
|
import { useRouter } from "next/navigation";
|
|
3
4
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -13,7 +14,7 @@ function RefreshOnInterval(props) {
|
|
|
13
14
|
}
|
|
14
15
|
RefreshOnInterval.displayName = "RefreshOnInterval";
|
|
15
16
|
function SanityLive(props) {
|
|
16
|
-
const { config, includeDrafts = false, requestTag, waitFor, action, onError, onWelcome = handleWelcome, onReconnect =
|
|
17
|
+
const { config, includeDrafts = false, requestTag, waitFor, action, onError = handleError, onWelcome = handleWelcome, onReconnect = handleReconnect, onRestart = "refresh", onGoAway = handleGoaway } = props;
|
|
17
18
|
const { projectId, dataset, apiHost, apiVersion, useProjectHostname, token, requestTagPrefix } = config;
|
|
18
19
|
const actionContext = {
|
|
19
20
|
includeDrafts,
|
|
@@ -41,9 +42,9 @@ function SanityLive(props) {
|
|
|
41
42
|
const [refreshOnInterval, setRefreshOnInterval] = useState(false);
|
|
42
43
|
const [error, setError] = useState();
|
|
43
44
|
if (error !== void 0) throw error;
|
|
44
|
-
const
|
|
45
|
-
if (onError)
|
|
46
|
-
else
|
|
45
|
+
const handleErrorEvent = useEffectEvent((error) => {
|
|
46
|
+
if (onError === "throw") setError(error);
|
|
47
|
+
else onError(error, actionContext);
|
|
47
48
|
});
|
|
48
49
|
const router = useRouter();
|
|
49
50
|
const handleLiveEvent = useEffectEvent((event) => {
|
|
@@ -58,10 +59,7 @@ function SanityLive(props) {
|
|
|
58
59
|
}));
|
|
59
60
|
break;
|
|
60
61
|
case "reconnect":
|
|
61
|
-
startTransition(() =>
|
|
62
|
-
if (onReconnect) startTransition(() => onReconnect === "refresh" ? router.refresh() : Promise.resolve(onReconnect(event, actionContext)).then((result) => {
|
|
63
|
-
if (result === "refresh") startTransition(() => router.refresh());
|
|
64
|
-
}));
|
|
62
|
+
if (onReconnect) startTransition(() => onReconnect(event, actionContext));
|
|
65
63
|
break;
|
|
66
64
|
case "restart":
|
|
67
65
|
startTransition(() => setRefreshOnInterval(false));
|
|
@@ -71,10 +69,10 @@ function SanityLive(props) {
|
|
|
71
69
|
break;
|
|
72
70
|
case "goaway":
|
|
73
71
|
if (onGoAway) startTransition(() => onGoAway(event, actionContext, (interval) => startTransition(() => setRefreshOnInterval(interval))));
|
|
74
|
-
else if (!onGoAway)
|
|
72
|
+
else if (!onGoAway) handleErrorEvent(new Error(`Sanity Live connection closed, automatic revalidation is disabled, the server gave this reason: ${event.reason}`, { cause: event }));
|
|
75
73
|
break;
|
|
76
74
|
default:
|
|
77
|
-
|
|
75
|
+
handleErrorEvent(new Error("Unknown live event type", { cause: event }));
|
|
78
76
|
break;
|
|
79
77
|
}
|
|
80
78
|
});
|
|
@@ -85,7 +83,7 @@ function SanityLive(props) {
|
|
|
85
83
|
waitFor
|
|
86
84
|
}).subscribe({
|
|
87
85
|
next: handleLiveEvent,
|
|
88
|
-
error:
|
|
86
|
+
error: handleErrorEvent
|
|
89
87
|
});
|
|
90
88
|
return () => subscription.unsubscribe();
|
|
91
89
|
}, [
|
|
@@ -98,9 +96,16 @@ function SanityLive(props) {
|
|
|
98
96
|
return null;
|
|
99
97
|
}
|
|
100
98
|
SanityLive.displayName = "SanityLiveClientComponent";
|
|
99
|
+
const handleError = (error, _context) => {
|
|
100
|
+
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());
|
|
101
|
+
else console.error(error);
|
|
102
|
+
};
|
|
101
103
|
const handleWelcome = (_, { includeDrafts, waitFor }) => {
|
|
102
104
|
console.info(`<SanityLive${includeDrafts ? " includeDrafts" : ""}> is connected and listening for live events to ${includeDrafts ? "all content including drafts and version documents in content releases" : "published content"}.${waitFor === "function" ? " Events will be delayed until after a Sanity Function has processed them." : ""}`);
|
|
103
105
|
};
|
|
106
|
+
const handleReconnect = (_, { includeDrafts }) => {
|
|
107
|
+
console.error(`<SanityLive${includeDrafts ? " includeDrafts" : ""}> is attempting to reconnect`);
|
|
108
|
+
};
|
|
104
109
|
const handleGoaway = (event, { includeDrafts }, setLongPollingInterval) => {
|
|
105
110
|
const interval = 3e4;
|
|
106
111
|
console.warn(`<SanityLive${includeDrafts ? " includeDrafts" : ""}> connection is closed after receiving a 'goaway' event, the server gave this reason:`, JSON.stringify(event.reason), `Content will now be refreshed every ${interval / 1e3} seconds`);
|
package/dist/SanityLive.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SanityLive.js","names":[],"sources":["../src/live/client-components/RefreshOnInterval.tsx","../src/live/client-components/SanityLive.tsx"],"sourcesContent":["'use client'\nimport {useRouter} from 'next/navigation'\nimport {startTransition, useEffect} from 'react'\n\nexport function RefreshOnInterval(props: {interval: number}): null {\n const router = useRouter()\n\n useEffect(() => {\n const interval = setInterval(() => startTransition(() => router.refresh()), props.interval)\n return () => clearInterval(interval)\n }, [router, props.interval])\n\n return null\n}\nRefreshOnInterval.displayName = 'RefreshOnInterval'\n","import {createClient, type LiveEvent} from '@sanity/client'\nimport {useRouter} from 'next/navigation'\nimport {useEffect, useMemo, useState, useEffectEvent, startTransition} from 'react'\n\nimport {cacheTagPrefix} from '#live/constants'\nimport type {\n SanityClientConfig,\n SanityLiveAction,\n SanityLiveContext,\n SanityLiveOnError,\n SanityLiveOnGoaway,\n SanityLiveOnReconnect,\n SanityLiveOnRestart,\n SanityLiveOnWelcome,\n} from '#live/types'\n\nimport {RefreshOnInterval} from './RefreshOnInterval'\n\nexport interface SanityLiveProps {\n config: SanityClientConfig\n includeDrafts: true | undefined\n requestTag: string\n waitFor: 'function' | undefined\n\n action: SanityLiveAction\n onError: SanityLiveOnError | undefined\n onWelcome: SanityLiveOnWelcome | false | undefined\n onReconnect: SanityLiveOnReconnect | false | undefined\n onRestart: SanityLiveOnRestart | false | undefined\n onGoAway: SanityLiveOnGoaway | false | undefined\n}\n\nfunction SanityLive(props: SanityLiveProps): React.JSX.Element | null {\n const {\n config,\n includeDrafts = false,\n requestTag,\n waitFor,\n\n action,\n onError,\n onWelcome = handleWelcome,\n onReconnect =
|
|
1
|
+
{"version":3,"file":"SanityLive.js","names":[],"sources":["../src/live/client-components/RefreshOnInterval.tsx","../src/live/client-components/SanityLive.tsx"],"sourcesContent":["'use client'\nimport {useRouter} from 'next/navigation'\nimport {startTransition, useEffect} from 'react'\n\nexport function RefreshOnInterval(props: {interval: number}): null {\n const router = useRouter()\n\n useEffect(() => {\n const interval = setInterval(() => startTransition(() => router.refresh()), props.interval)\n return () => clearInterval(interval)\n }, [router, props.interval])\n\n return null\n}\nRefreshOnInterval.displayName = 'RefreshOnInterval'\n","import {createClient, type LiveEvent} from '@sanity/client'\nimport {useRouter} from 'next/navigation'\nimport {useEffect, useMemo, useState, useEffectEvent, startTransition} from 'react'\n\nimport {cacheTagPrefix} from '#live/constants'\nimport {isCorsOriginError} from '#live/isCorsOriginError'\nimport type {\n SanityClientConfig,\n SanityLiveAction,\n SanityLiveContext,\n SanityLiveOnError,\n SanityLiveOnGoaway,\n SanityLiveOnReconnect,\n SanityLiveOnRestart,\n SanityLiveOnWelcome,\n} from '#live/types'\n\nimport {RefreshOnInterval} from './RefreshOnInterval'\n\nexport interface SanityLiveProps {\n config: SanityClientConfig\n includeDrafts: true | undefined\n requestTag: string\n waitFor: 'function' | undefined\n\n action: SanityLiveAction\n onError: SanityLiveOnError | undefined\n onWelcome: SanityLiveOnWelcome | false | undefined\n onReconnect: SanityLiveOnReconnect | false | undefined\n onRestart: SanityLiveOnRestart | false | undefined\n onGoAway: SanityLiveOnGoaway | false | undefined\n}\n\nfunction SanityLive(props: SanityLiveProps): React.JSX.Element | null {\n const {\n config,\n includeDrafts = false,\n requestTag,\n waitFor,\n\n action,\n onError = handleError,\n onWelcome = handleWelcome,\n onReconnect = handleReconnect,\n onRestart = 'refresh',\n onGoAway = handleGoaway,\n } = props\n const {projectId, dataset, apiHost, apiVersion, useProjectHostname, token, requestTagPrefix} =\n config\n const actionContext = {includeDrafts, waitFor} satisfies SanityLiveContext\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\n // The interval is set in milliseconds, false means long polling is disabled\n const [refreshOnInterval, setRefreshOnInterval] = useState<number | false>(false)\n\n const [error, setError] = useState<unknown>()\n if (error !== undefined) {\n // Throw during render to bubble up to the nearest <ErrorBoundary>, only when `onError=\"throw\"` is set\n throw error\n }\n const handleErrorEvent = useEffectEvent((error: unknown) => {\n if (onError === 'throw') {\n setError(error)\n } else {\n onError(error, actionContext)\n }\n })\n\n const router = useRouter()\n const handleLiveEvent = useEffectEvent((event: LiveEvent) => {\n switch (event.type) {\n case 'welcome': {\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\n if (onWelcome) {\n startTransition(() => onWelcome(event, actionContext))\n }\n break\n }\n case 'message': {\n startTransition(() =>\n action === 'refresh'\n ? router.refresh()\n : action(event.tags.map((tag) => `${cacheTagPrefix}${tag}`)).then((result) => {\n if (result === 'refresh') {\n startTransition(() => router.refresh())\n }\n }),\n )\n break\n }\n case 'reconnect': {\n if (onReconnect) {\n startTransition(() => onReconnect(event, actionContext))\n }\n break\n }\n case 'restart': {\n // Disable long polling when restart event is received, this is a no-op if long polling is already disabled\n startTransition(() => setRefreshOnInterval(false))\n\n if (onRestart) {\n startTransition(() =>\n onRestart === 'refresh'\n ? router.refresh()\n : Promise.resolve(onRestart(event, actionContext)).then((result) => {\n if (result === 'refresh') {\n startTransition(() => router.refresh())\n }\n }),\n )\n }\n break\n }\n case 'goaway': {\n if (onGoAway) {\n startTransition(() =>\n onGoAway(event, actionContext, (interval) =>\n startTransition(() => setRefreshOnInterval(interval)),\n ),\n )\n } else if (!onGoAway) {\n handleErrorEvent(\n new Error(\n `Sanity Live connection closed, automatic revalidation is disabled, the server gave this reason: ${event.reason}`,\n {cause: event},\n ),\n )\n }\n break\n }\n default:\n handleErrorEvent(new Error('Unknown live event type', {cause: event}))\n break\n }\n })\n useEffect(() => {\n const subscription = client.live\n .events({includeDrafts, tag: requestTag, waitFor})\n .subscribe({next: handleLiveEvent, error: handleErrorEvent})\n return () => subscription.unsubscribe()\n }, [client.live, requestTag, includeDrafts, waitFor])\n\n if (refreshOnInterval && Number.isFinite(refreshOnInterval) && refreshOnInterval > 0) {\n return <RefreshOnInterval interval={refreshOnInterval} />\n }\n return null\n}\n\nSanityLive.displayName = 'SanityLiveClientComponent'\n\nexport default SanityLive\n\nconst handleError: Exclude<SanityLiveOnError, 'throw'> = (error, _context) => {\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\nconst handleWelcome: SanityLiveOnWelcome = (_, {includeDrafts, waitFor}) => {\n // oxlint-disable-next-line no-console\n console.info(\n `<SanityLive${includeDrafts ? ' includeDrafts' : ''}> is connected and listening for live events to ${includeDrafts ? 'all content including drafts and version documents in content releases' : 'published content'}.${waitFor === 'function' ? ' Events will be delayed until after a Sanity Function has processed them.' : ''}`,\n )\n}\n\nconst handleReconnect: SanityLiveOnReconnect = (_, {includeDrafts}) => {\n console.error(`<SanityLive${includeDrafts ? ' includeDrafts' : ''}> is attempting to reconnect`)\n}\n\nconst handleGoaway: SanityLiveOnGoaway = (event, {includeDrafts}, setLongPollingInterval) => {\n const interval = 30_000\n console.warn(\n `<SanityLive${includeDrafts ? ' includeDrafts' : ''}> connection is closed after receiving a 'goaway' event, the server gave this reason:`,\n JSON.stringify(event.reason),\n `Content will now be refreshed every ${interval / 1_000} seconds`,\n )\n setLongPollingInterval(interval)\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/live/client-components/SanityLive.tsx","../../../src/live/client-components/index.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/live/client-components/SanityLive.tsx","../../../src/live/client-components/index.ts"],"mappings":";UAmBiB,eAAA;EACf,MAAA,EAAQ,kBAAA;EACR,aAAA;EACA,UAAA;EACA,OAAA;EAEA,MAAA,EAAQ,gBAAA;EACR,OAAA,EAAS,iBAAA;EACT,SAAA,EAAW,mBAAA;EACX,WAAA,EAAa,qBAAA;EACb,SAAA,EAAW,mBAAA;EACX,QAAA,EAAU,kBAAA;AAAA;;AAXZ;;cCXa,UAAA,EAAY,KAAA,CAAM,aAAA,CAAc,eAAA"}
|
|
@@ -27,9 +27,10 @@ function defineLive(config) {
|
|
|
27
27
|
});
|
|
28
28
|
const stega = strict ? _stega : _stega ?? (serverToken && studioUrlDefined ? (await draftMode()).isEnabled : false);
|
|
29
29
|
const perspective = strict ? _perspective : _perspective ?? (serverToken ? await resolveCookiePerspective() : void 0);
|
|
30
|
-
const cacheMode = !(process.env["NEXT_PHASE"] === PHASE_PRODUCTION_BUILD) ? "noStale" : void 0;
|
|
31
|
-
const token = (perspective && perspective !== "published" || stega) && serverToken ? serverToken : void 0;
|
|
32
30
|
const useCdn = perspective ? perspective === "published" : void 0;
|
|
31
|
+
const isBuildPhase = process.env["NEXT_PHASE"] === PHASE_PRODUCTION_BUILD;
|
|
32
|
+
const cacheMode = useCdn !== false && !isBuildPhase ? "noStale" : void 0;
|
|
33
|
+
const token = (perspective && perspective !== "published" || stega) && serverToken ? serverToken : void 0;
|
|
33
34
|
const { syncTags } = await client.fetch(query, await params, {
|
|
34
35
|
filterResponse: false,
|
|
35
36
|
perspective,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["SanityLive","SanityLiveClientComponent"],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"sourcesContent":["import {SanityLive as SanityLiveClientComponent} from 'next-sanity/live/client-components'\nimport {revalidateSyncTagsAction} from 'next-sanity/live/server-actions'\nimport {PHASE_PRODUCTION_BUILD} from 'next/constants'\nimport {cookies, draftMode} from 'next/headers'\nimport {preconnect} from 'react-dom'\n\nimport {cacheTagPrefix} from '#live/constants'\nimport {resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport {validateStrictFetchOptions, validateStrictSanityLiveProps} from '#live/strictValidation'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n LivePerspective,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n\n/**\n * Set up Sanity Live for Cache Components. `defineLive` returns `sanityFetch`\n * and `<SanityLive />`, which connect your Sanity client to the Live Content API\n * so cached pages can update in response to fine-grained content changes.\n *\n * With `strict: true`, `perspective` and `stega` become required\n * `sanityFetch` options, and `includeDrafts` becomes required on\n * `<SanityLive />`. Resolve dynamic values from `draftMode()` and `cookies()`\n * outside `'use cache'` boundaries, then pass them into cached components.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * // sanity/live.ts\n * import {cookies, draftMode} from 'next/headers'\n * import {createClient} from 'next-sanity'\n * import {\n * defineLive,\n * resolvePerspectiveFromCookies,\n * type LivePerspective,\n * } from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * strict: true,\n * })\n *\n * export interface DynamicFetchOptions {\n * perspective: LivePerspective\n * stega: boolean\n * }\n *\n * // Resolve dynamic values outside 'use cache' boundaries.\n * export async function getDynamicFetchOptions(): Promise<DynamicFetchOptions> {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (!isDraftMode) {\n * return {perspective: 'published', stega: false}\n * }\n *\n * const jar = await cookies()\n * const perspective = await resolvePerspectiveFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', stega: true}\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {draftMode} from 'next/headers'\n *\n * import {SanityLive} from '@/sanity/live'\n *\n * export default async function RootLayout({children}: {children: React.ReactNode}) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive includeDrafts={isDraftMode} />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {draftMode} from 'next/headers'\n * import {Suspense} from 'react'\n * import {defineQuery} from 'next-sanity'\n *\n * import {\n * getDynamicFetchOptions,\n * sanityFetch,\n * type DynamicFetchOptions,\n * } from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (isDraftMode) {\n * return (\n * <Suspense fallback={<div>Loading...</div>}>\n * <DynamicPage params={props.params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await props.params\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage(props: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await props.params\n * const {perspective, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * stega,\n * }: {slug: string} & DynamicFetchOptions) {\n * 'use cache'\n *\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * perspective,\n * stega,\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict: true}): {\n sanityFetch: StrictDefinedFetchType\n SanityLive: React.ComponentType<StrictDefinedLiveProps>\n}\n/**\n * Set up Sanity Live. `defineLive` returns `sanityFetch` and `<SanityLive />`,\n * which connect your Sanity client to the Live Content API so pages can serve\n * cached content and update in response to fine-grained content changes.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * import {createClient} from 'next-sanity'\n * import {defineLive} from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * })\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {SanityLive} from '@/sanity/live'\n *\n * export default function RootLayout({children}: {children: React.ReactNode}) {\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {defineQuery} from 'next-sanity'\n * import {sanityFetch} from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {slug} = await props.params\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict?: false}): {\n sanityFetch: DefinedFetchType\n SanityLive: React.ComponentType<DefinedLiveProps>\n}\nexport function defineLive(config: DefineLiveOptions) {\n const {client: _client, serverToken, browserToken, strict = false} = config\n\n if (!_client) {\n throw new Error('`client` is required for `defineLive` to function')\n }\n\n if (process.env.NODE_ENV === 'development' && !serverToken && serverToken !== false) {\n console.warn(\n 'No `serverToken` provided to `defineLive`. This means that only published content will be fetched and respond to live events. You can silence this warning by setting `serverToken: false`.',\n )\n }\n\n if (process.env.NODE_ENV === 'development' && !browserToken && browserToken !== false) {\n console.warn(\n 'No `browserToken` provided to `defineLive`. This means that live previewing drafts will only work when using the Presentation Tool in your Sanity Studio. To support live previewing drafts stand-alone, provide a `browserToken`. It is shared with the browser so it should only have Viewer rights or lower. You can silence this warning by setting `browserToken: false`.',\n )\n }\n\n const client = _client.withConfig({\n allowReconfigure: false,\n useCdn: true,\n perspective: 'published',\n stega: false,\n })\n const studioUrlDefined = typeof client.config().stega.studioUrl !== 'undefined'\n\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective: _perspective,\n stega: _stega,\n tags = [],\n requestTag = 'next-loader.fetch',\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective: _perspective, stega: _stega})\n }\n const stega = strict\n ? _stega!\n : (_stega ?? (serverToken && studioUrlDefined ? (await draftMode()).isEnabled : false))\n const perspective = strict\n ? _perspective!\n : (_perspective ?? (serverToken ? await resolveCookiePerspective() : undefined))\n const isBuildPhase = process.env['NEXT_PHASE'] === PHASE_PRODUCTION_BUILD\n const cacheMode = !isBuildPhase ? 'noStale' : undefined\n const token =\n ((perspective && perspective !== 'published') || stega) && serverToken\n ? serverToken\n : undefined\n const useCdn = perspective ? perspective === 'published' : undefined\n\n // 1. Fetch the tags first, with an uncached request, but that does not count towards the Sanity API quota\n const {syncTags} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n stega: false,\n resultSourceMap: false,\n returnQuery: false,\n useCdn,\n cacheMode,\n tag: [requestTag, 'fetch-sync-tags'].filter(Boolean).join('.'),\n token,\n })\n\n const cacheTags = [...tags, ...(syncTags?.map((tag) => `${cacheTagPrefix}${tag}`) || [])]\n\n // 2. Then fetch the data, using the fetch cache with specified tags\n const {result, resultSourceMap} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n stega,\n next: {revalidate: false, tags: cacheTags},\n useCdn,\n cacheMode,\n tag: requestTag,\n token,\n })\n return {data: result, sourceMap: resultSourceMap || null, tags: cacheTags}\n }\n\n const SanityLive: React.ComponentType<DefinedLiveProps> = async function SanityLive(props) {\n if (strict) {\n validateStrictSanityLiveProps(props)\n }\n const {\n includeDrafts: _includeDrafts,\n requestTag = 'next-loader.live',\n waitFor,\n\n action,\n onError,\n onWelcome,\n onReconnect,\n onRestart,\n onGoAway,\n } = props\n const {projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix} =\n client.config()\n\n const includeDrafts =\n typeof browserToken === 'string' &&\n !!browserToken &&\n (_includeDrafts ?? (await draftMode()).isEnabled)\n const shouldWaitFor = waitFor === 'function' && !includeDrafts ? waitFor : undefined\n\n // Preconnect to the Live Event API origin early, as the Sanity API is almost always on a different origin than the app\n const {origin} = new URL(client.getUrl('', false))\n preconnect(origin)\n\n return (\n <SanityLiveClientComponent\n config={{\n projectId,\n dataset,\n apiHost,\n apiVersion,\n useProjectHostname,\n requestTagPrefix,\n token: includeDrafts ? browserToken : undefined,\n }}\n includeDrafts={includeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? 'refresh' : revalidateSyncTagsAction)}\n onError={onError}\n onWelcome={onWelcome}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onGoAway={onGoAway}\n />\n )\n }\n SanityLive.displayName = 'SanityLiveServerComponent'\n\n return {sanityFetch, SanityLive}\n}\n\nasync function resolveCookiePerspective(): Promise<LivePerspective | undefined> {\n return (await draftMode()).isEnabled\n ? await resolvePerspectiveFromCookies({cookies: await cookies()})\n : undefined\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["SanityLive","SanityLiveClientComponent"],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"sourcesContent":["import {SanityLive as SanityLiveClientComponent} from 'next-sanity/live/client-components'\nimport {revalidateSyncTagsAction} from 'next-sanity/live/server-actions'\nimport {PHASE_PRODUCTION_BUILD} from 'next/constants'\nimport {cookies, draftMode} from 'next/headers'\nimport {preconnect} from 'react-dom'\n\nimport {cacheTagPrefix} from '#live/constants'\nimport {resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport {validateStrictFetchOptions, validateStrictSanityLiveProps} from '#live/strictValidation'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n LivePerspective,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n\n/**\n * Set up Sanity Live for Cache Components. `defineLive` returns `sanityFetch`\n * and `<SanityLive />`, which connect your Sanity client to the Live Content API\n * so cached pages can update in response to fine-grained content changes.\n *\n * With `strict: true`, `perspective` and `stega` become required\n * `sanityFetch` options, and `includeDrafts` becomes required on\n * `<SanityLive />`. Resolve dynamic values from `draftMode()` and `cookies()`\n * outside `'use cache'` boundaries, then pass them into cached components.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * // sanity/live.ts\n * import {cookies, draftMode} from 'next/headers'\n * import {createClient} from 'next-sanity'\n * import {\n * defineLive,\n * resolvePerspectiveFromCookies,\n * type LivePerspective,\n * } from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * strict: true,\n * })\n *\n * export interface DynamicFetchOptions {\n * perspective: LivePerspective\n * stega: boolean\n * }\n *\n * // Resolve dynamic values outside 'use cache' boundaries.\n * export async function getDynamicFetchOptions(): Promise<DynamicFetchOptions> {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (!isDraftMode) {\n * return {perspective: 'published', stega: false}\n * }\n *\n * const jar = await cookies()\n * const perspective = await resolvePerspectiveFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', stega: true}\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {draftMode} from 'next/headers'\n *\n * import {SanityLive} from '@/sanity/live'\n *\n * export default async function RootLayout({children}: {children: React.ReactNode}) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive includeDrafts={isDraftMode} />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {draftMode} from 'next/headers'\n * import {Suspense} from 'react'\n * import {defineQuery} from 'next-sanity'\n *\n * import {\n * getDynamicFetchOptions,\n * sanityFetch,\n * type DynamicFetchOptions,\n * } from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (isDraftMode) {\n * return (\n * <Suspense fallback={<div>Loading...</div>}>\n * <DynamicPage params={props.params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await props.params\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage(props: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await props.params\n * const {perspective, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * stega,\n * }: {slug: string} & DynamicFetchOptions) {\n * 'use cache'\n *\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * perspective,\n * stega,\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict: true}): {\n sanityFetch: StrictDefinedFetchType\n SanityLive: React.ComponentType<StrictDefinedLiveProps>\n}\n/**\n * Set up Sanity Live. `defineLive` returns `sanityFetch` and `<SanityLive />`,\n * which connect your Sanity client to the Live Content API so pages can serve\n * cached content and update in response to fine-grained content changes.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * import {createClient} from 'next-sanity'\n * import {defineLive} from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * })\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {SanityLive} from '@/sanity/live'\n *\n * export default function RootLayout({children}: {children: React.ReactNode}) {\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {defineQuery} from 'next-sanity'\n * import {sanityFetch} from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {slug} = await props.params\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict?: false}): {\n sanityFetch: DefinedFetchType\n SanityLive: React.ComponentType<DefinedLiveProps>\n}\nexport function defineLive(config: DefineLiveOptions) {\n const {client: _client, serverToken, browserToken, strict = false} = config\n\n if (!_client) {\n throw new Error('`client` is required for `defineLive` to function')\n }\n\n if (process.env.NODE_ENV === 'development' && !serverToken && serverToken !== false) {\n console.warn(\n 'No `serverToken` provided to `defineLive`. This means that only published content will be fetched and respond to live events. You can silence this warning by setting `serverToken: false`.',\n )\n }\n\n if (process.env.NODE_ENV === 'development' && !browserToken && browserToken !== false) {\n console.warn(\n 'No `browserToken` provided to `defineLive`. This means that live previewing drafts will only work when using the Presentation Tool in your Sanity Studio. To support live previewing drafts stand-alone, provide a `browserToken`. It is shared with the browser so it should only have Viewer rights or lower. You can silence this warning by setting `browserToken: false`.',\n )\n }\n\n const client = _client.withConfig({\n allowReconfigure: false,\n useCdn: true,\n perspective: 'published',\n stega: false,\n })\n const studioUrlDefined = typeof client.config().stega.studioUrl !== 'undefined'\n\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective: _perspective,\n stega: _stega,\n tags = [],\n requestTag = 'next-loader.fetch',\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective: _perspective, stega: _stega})\n }\n const stega = strict\n ? _stega\n : (_stega ?? (serverToken && studioUrlDefined ? (await draftMode()).isEnabled : false))\n const perspective = strict\n ? _perspective\n : (_perspective ?? (serverToken ? await resolveCookiePerspective() : undefined))\n const useCdn = perspective ? perspective === 'published' : undefined\n const isBuildPhase = process.env['NEXT_PHASE'] === PHASE_PRODUCTION_BUILD\n const cacheMode = useCdn !== false && !isBuildPhase ? 'noStale' : undefined\n const token =\n ((perspective && perspective !== 'published') || stega) && serverToken\n ? serverToken\n : undefined\n\n // 1. Fetch the tags first, with an uncached request, but that does not count towards the Sanity API quota\n const {syncTags} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n stega: false,\n resultSourceMap: false,\n returnQuery: false,\n useCdn,\n cacheMode,\n tag: [requestTag, 'fetch-sync-tags'].filter(Boolean).join('.'),\n token,\n })\n\n const cacheTags = [...tags, ...(syncTags?.map((tag) => `${cacheTagPrefix}${tag}`) || [])]\n\n // 2. Then fetch the data, using the fetch cache with specified tags\n const {result, resultSourceMap} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n stega,\n next: {revalidate: false, tags: cacheTags},\n useCdn,\n cacheMode,\n tag: requestTag,\n token,\n })\n return {data: result, sourceMap: resultSourceMap || null, tags: cacheTags}\n }\n\n const SanityLive: React.ComponentType<DefinedLiveProps> = async function SanityLive(props) {\n if (strict) {\n validateStrictSanityLiveProps(props)\n }\n const {\n includeDrafts: _includeDrafts,\n requestTag = 'next-loader.live',\n waitFor,\n\n action,\n onError,\n onWelcome,\n onReconnect,\n onRestart,\n onGoAway,\n } = props\n const {projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix} =\n client.config()\n\n const includeDrafts =\n typeof browserToken === 'string' &&\n !!browserToken &&\n (_includeDrafts ?? (await draftMode()).isEnabled)\n const shouldWaitFor = waitFor === 'function' && !includeDrafts ? waitFor : undefined\n\n // Preconnect to the Live Event API origin early, as the Sanity API is almost always on a different origin than the app\n const {origin} = new URL(client.getUrl('', false))\n preconnect(origin)\n\n return (\n <SanityLiveClientComponent\n config={{\n projectId,\n dataset,\n apiHost,\n apiVersion,\n useProjectHostname,\n requestTagPrefix,\n token: includeDrafts ? browserToken : undefined,\n }}\n includeDrafts={includeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? 'refresh' : revalidateSyncTagsAction)}\n onError={onError}\n onWelcome={onWelcome}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onGoAway={onGoAway}\n />\n )\n }\n SanityLive.displayName = 'SanityLiveServerComponent'\n\n return {sanityFetch, SanityLive}\n}\n\nasync function resolveCookiePerspective(): Promise<LivePerspective | undefined> {\n return (await draftMode()).isEnabled\n ? await resolvePerspectiveFromCookies({cookies: await cookies()})\n : undefined\n}\n"],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@ async function revalidateSyncTagsAction(unsafeTags) {
|
|
|
18
18
|
}
|
|
19
19
|
for (const tag of tags) revalidateTag(tag, "max");
|
|
20
20
|
console.log(`<SanityLive /> revalidated tags: ${tags.join(", ")} with cache profile "max" `);
|
|
21
|
+
return "refresh";
|
|
21
22
|
}
|
|
22
23
|
export { revalidateSyncTagsAction };
|
|
23
24
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/live/server-actions/index.ts"],"sourcesContent":["'use server'\n\nimport {refresh, revalidateTag, updateTag} from 'next/cache'\nimport {draftMode} from 'next/headers'\n\nimport {parseTags} from '#live/parseTags'\n\n/**\n * @internal CAUTION: this is an internal action and does not follow semver. Using it directly is at your own risk.\n */\nexport async function revalidateSyncTagsAction(unsafeTags: unknown): Promise<void | 'refresh'> {\n if ((await draftMode()).isEnabled) {\n console.warn(\n `<SanityLive /> action called in draft mode, cache is bypassed in draft mode so the refresh() function is called instead of revalidating tags`,\n )\n return refresh()\n }\n\n const {tags} = parseTags(unsafeTags)\n\n if (process.env.NODE_ENV === 'development') {\n for (const tag of tags) {\n updateTag(tag)\n }\n // oxlint-disable-next-line no-console\n console.log(\n `<SanityLive /> action called in dev mode, updated tags: ${tags.join(', ')}. In production revalidateTag(tag, 'max') will be used instead of updateTag(tag)`,\n )\n return undefined\n }\n\n for (const tag of tags) {\n revalidateTag(tag, 'max')\n }\n // oxlint-disable-next-line no-console\n console.log(`<SanityLive /> revalidated tags: ${tags.join(', ')} with cache profile \"max\" `)\n}\n"],"mappings":";;;;;;;AAUA,eAAsB,yBAAyB,YAAgD;AAC7F,MAAK,MAAM,WAAW,EAAE,WAAW;AACjC,UAAQ,KACN,+IACD;AACD,SAAO,SAAS;;CAGlB,MAAM,EAAC,SAAQ,UAAU,WAAW;AAEpC,KAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,OAAK,MAAM,OAAO,KAChB,WAAU,IAAI;AAGhB,UAAQ,IACN,2DAA2D,KAAK,KAAK,KAAK,CAAC,kFAC5E;AACD;;AAGF,MAAK,MAAM,OAAO,KAChB,eAAc,KAAK,MAAM;AAG3B,SAAQ,IAAI,oCAAoC,KAAK,KAAK,KAAK,CAAC,4BAA4B"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/live/server-actions/index.ts"],"sourcesContent":["'use server'\n\nimport {refresh, revalidateTag, updateTag} from 'next/cache'\nimport {draftMode} from 'next/headers'\n\nimport {parseTags} from '#live/parseTags'\n\n/**\n * @internal CAUTION: this is an internal action and does not follow semver. Using it directly is at your own risk.\n */\nexport async function revalidateSyncTagsAction(unsafeTags: unknown): Promise<void | 'refresh'> {\n if ((await draftMode()).isEnabled) {\n console.warn(\n `<SanityLive /> action called in draft mode, cache is bypassed in draft mode so the refresh() function is called instead of revalidating tags`,\n )\n return refresh()\n }\n\n const {tags} = parseTags(unsafeTags)\n\n if (process.env.NODE_ENV === 'development') {\n for (const tag of tags) {\n updateTag(tag)\n }\n // oxlint-disable-next-line no-console\n console.log(\n `<SanityLive /> action called in dev mode, updated tags: ${tags.join(', ')}. In production revalidateTag(tag, 'max') will be used instead of updateTag(tag)`,\n )\n return undefined\n }\n\n for (const tag of tags) {\n revalidateTag(tag, 'max')\n }\n // oxlint-disable-next-line no-console\n console.log(`<SanityLive /> revalidated tags: ${tags.join(', ')} with cache profile \"max\" `)\n return 'refresh'\n}\n"],"mappings":";;;;;;;AAUA,eAAsB,yBAAyB,YAAgD;AAC7F,MAAK,MAAM,WAAW,EAAE,WAAW;AACjC,UAAQ,KACN,+IACD;AACD,SAAO,SAAS;;CAGlB,MAAM,EAAC,SAAQ,UAAU,WAAW;AAEpC,KAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,OAAK,MAAM,OAAO,KAChB,WAAU,IAAI;AAGhB,UAAQ,IACN,2DAA2D,KAAK,KAAK,KAAK,CAAC,kFAC5E;AACD;;AAGF,MAAK,MAAM,OAAO,KAChB,eAAc,KAAK,MAAM;AAG3B,SAAQ,IAAI,oCAAoC,KAAK,KAAK,KAAK,CAAC,4BAA4B;AAC5F,QAAO"}
|
package/dist/types.d.ts
CHANGED
|
@@ -88,7 +88,9 @@ interface DefinedLiveProps {
|
|
|
88
88
|
*/
|
|
89
89
|
action?: SanityLiveAction;
|
|
90
90
|
/**
|
|
91
|
-
* Custom error handler. If none is provided
|
|
91
|
+
* Custom error handler. If none is provided, errors are logged with `console.error`.
|
|
92
|
+
* Pass `'throw'` to throw errors during render so they can be caught by the
|
|
93
|
+
* {@link https://nextjs.org/docs/app/api-reference/functions/catchError | unstable_catchError API}.
|
|
92
94
|
*/
|
|
93
95
|
onError?: SanityLiveOnError;
|
|
94
96
|
/**
|
|
@@ -98,7 +100,7 @@ interface DefinedLiveProps {
|
|
|
98
100
|
onWelcome?: SanityLiveOnWelcome | false;
|
|
99
101
|
/**
|
|
100
102
|
* Custom handler for the `reconnect` event. Pass `false` to disable the
|
|
101
|
-
* default
|
|
103
|
+
* default log behavior.
|
|
102
104
|
*/
|
|
103
105
|
onReconnect?: SanityLiveOnReconnect | false;
|
|
104
106
|
/**
|
|
@@ -200,10 +202,12 @@ type SanityLiveAction = ((unsafeTags: unknown) => Promise<void | "refresh">) | "
|
|
|
200
202
|
/**
|
|
201
203
|
* Handles connection, parsing, and event-processing errors.
|
|
202
204
|
*
|
|
203
|
-
* If no handler is provided, the error is
|
|
204
|
-
*
|
|
205
|
+
* If no handler is provided, the error is logged with `console.error`.
|
|
206
|
+
* Pass `'throw'` to throw errors during render so they can be caught by the
|
|
207
|
+
* {@link https://nextjs.org/docs/app/api-reference/functions/catchError | unstable_catchError API}
|
|
208
|
+
* which supports `unstable_retry` for retrying the render.
|
|
205
209
|
*/
|
|
206
|
-
type SanityLiveOnError = (error: unknown, context: SanityLiveContext) => void;
|
|
210
|
+
type SanityLiveOnError = ((error: unknown, context: SanityLiveContext) => void) | "throw";
|
|
207
211
|
/**
|
|
208
212
|
* Handles the Live Content API `welcome` event.
|
|
209
213
|
*
|
|
@@ -217,12 +221,11 @@ type SanityLiveOnWelcome = (event: Extract<LiveEvent, {
|
|
|
217
221
|
/**
|
|
218
222
|
* Handles the Live Content API `reconnect` event.
|
|
219
223
|
*
|
|
220
|
-
* The default behavior
|
|
221
|
-
* fresh data after reconnecting.
|
|
224
|
+
* The default behavior just logs the event, as it will eventually result in a `welcome` or `error` event.
|
|
222
225
|
*/
|
|
223
|
-
type SanityLiveOnReconnect = (
|
|
226
|
+
type SanityLiveOnReconnect = (event: Extract<LiveEvent, {
|
|
224
227
|
type: "reconnect";
|
|
225
|
-
}>, context: SanityLiveContext) => void | Promise<void
|
|
228
|
+
}>, context: SanityLiveContext) => void | Promise<void>;
|
|
226
229
|
/**
|
|
227
230
|
* Handles the Live Content API `restart` event.
|
|
228
231
|
*
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/live/shared/types.ts"],"mappings":";;AAcA;;;KAAY,eAAA,GAAkB,OAAA,CAAQ,iBAAA;;AAStC;;;;;;KAAY,gBAAA,sCAAsD,OAAA;;;;EAIhE,KAAA,EAAO,WAAA;;;;EAIP,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,WAAA;;;;;;EAM/B,WAAA,GAAc,eAAA;;;;;;;EAOd,KAAA;;;;;;;;EAQA,IAAA;EAkBF;;;;;;EAXE,UAAA;AAAA,MACI,OAAA;EACJ,IAAA,EAAM,YAAA,CAAa,WAAA;EACnB,SAAA,EAAW,gBAAA;EACX,IAAA;AAAA;;;;;UAOe,gBAAA;;;;;;;;;EASf,aAAA;;;
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/live/shared/types.ts"],"mappings":";;AAcA;;;KAAY,eAAA,GAAkB,OAAA,CAAQ,iBAAA;;AAStC;;;;;;KAAY,gBAAA,sCAAsD,OAAA;;;;EAIhE,KAAA,EAAO,WAAA;;;;EAIP,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,WAAA;;;;;;EAM/B,WAAA,GAAc,eAAA;;;;;;;EAOd,KAAA;;;;;;;;EAQA,IAAA;EAkBF;;;;;;EAXE,UAAA;AAAA,MACI,OAAA;EACJ,IAAA,EAAM,YAAA,CAAa,WAAA;EACnB,SAAA,EAAW,gBAAA;EACX,IAAA;AAAA;;;;;UAOe,gBAAA;;;;;;;;;EASf,aAAA;;;AAiDF;;;;;EAzCE,UAAA;;;;;EAKA,OAAA;EAyEF;;;;;;EAlEE,MAAA,GAAS,gBAAA;;;AA0EX;;;EApEE,OAAA,GAAU,iBAAA;;;;;EAKV,SAAA,GAAY,mBAAA;;;;;EAKZ,WAAA,GAAc,qBAAA;;;;;EAKd,SAAA,GAAY,mBAAA;;;;;EAKZ,QAAA,GAAW,kBAAA;AAAA;AAAA,UAGI,iBAAA;;;;EAIf,MAAA,EAAQ,YAAA;;;;;;;EAOR,WAAA;EA+Ce;;;;AAcjB;;;EArDE,YAAA;EA8DA;AAiBF;;;;;AASA;;;;EA7EE,MAAA;AAAA;;;;AAqFF;UA9EiB,sBAAA,SAA+B,IAAA,CAAK,gBAAA;EACnD,aAAA;AAAA;;;;;KAOU,sBAAA,sCAA4D,OAAA;EACtE,KAAA,EAAO,WAAA;EACP,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,WAAA;EAC/B,WAAA,EAAa,eAAA;EACb,KAAA;EACA,IAAA;EACA,UAAA;AAAA,MACI,OAAA;EACJ,IAAA,EAAM,YAAA,CAAa,WAAA;EACnB,SAAA,EAAW,gBAAA;EACX,IAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,IAAA,CAC1C,uBAAA;;;;UAae,iBAAA;;;;;EAKf,aAAA;;;;EAIA,OAAA;AAAA;;AAsDF;;;;;;;;;;;;;KArCY,gBAAA,KAAqB,UAAA,cAAwB,OAAA;;;;;AAmDzD;;;;KA1CY,iBAAA,KAAsB,KAAA,WAAgB,OAAA,EAAS,iBAAA;;;;;;;;KAQ/C,mBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,YACC,OAAA;;;;;;KAMA,qBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,YACC,OAAA;;;;;;;KAQA,mBAAA,KAEN,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,YACC,OAAA;;;;;;;;;KAUJ,kBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,EACT,kBAAA,GAAqB,QAAA,6BACX,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-sanity",
|
|
3
|
-
"version": "13.0.0-cache-components.
|
|
3
|
+
"version": "13.0.0-cache-components.61",
|
|
4
4
|
"description": "Sanity.io toolkit for Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"live",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@sanity/client": "^7.22.0",
|
|
63
63
|
"@sanity/generate-help-url": "^4.0.0",
|
|
64
64
|
"@sanity/preview-url-secret": "^4.0.6",
|
|
65
|
-
"@sanity/visual-editing": "^5.3.
|
|
65
|
+
"@sanity/visual-editing": "^5.3.6",
|
|
66
66
|
"@sanity/webhook": "^4.0.4",
|
|
67
67
|
"groq": "^5.25.1",
|
|
68
68
|
"history": "^5.3.0"
|
|
@@ -74,21 +74,21 @@
|
|
|
74
74
|
"@types/react": "^19.2.14",
|
|
75
75
|
"@types/react-dom": "^19.2.3",
|
|
76
76
|
"@vercel/stega": "^1.1.0",
|
|
77
|
-
"@vitejs/plugin-react": "^6.0.
|
|
77
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
78
78
|
"@vitest/browser-playwright": "^4.1.6",
|
|
79
|
-
"@vitest/coverage-v8": "^4.1.
|
|
79
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
80
80
|
"js-yaml": "^4.1.1",
|
|
81
81
|
"msw": "^2.14.6",
|
|
82
|
-
"next": "16.3.0-canary.
|
|
83
|
-
"publint": "^0.3.
|
|
82
|
+
"next": "16.3.0-canary.22",
|
|
83
|
+
"publint": "^0.3.21",
|
|
84
84
|
"react": "^19.2.6",
|
|
85
85
|
"react-dom": "^19.2.6",
|
|
86
86
|
"styled-components": "^6.4.1",
|
|
87
87
|
"tsdown": "^0.21.10",
|
|
88
88
|
"typedoc": "^0.28.19",
|
|
89
89
|
"typescript": "5.9.3",
|
|
90
|
-
"vite": "^8.0.
|
|
91
|
-
"vitest": "^4.1.
|
|
90
|
+
"vite": "^8.0.13",
|
|
91
|
+
"vitest": "^4.1.6",
|
|
92
92
|
"vitest-browser-react": "^2.2.0",
|
|
93
93
|
"vitest-package-exports": "^1.2.0"
|
|
94
94
|
},
|