next-sanity 13.2.3 → 13.3.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.
@@ -71,9 +71,7 @@ function SanityLive(props) {
71
71
  if (onGoAway) startTransition(() => onGoAway(event, actionContext, (interval) => startTransition(() => setRefreshOnInterval(interval))));
72
72
  else if (!onGoAway) handleErrorEvent(new Error(`Sanity Live connection closed, automatic revalidation is disabled, the server gave this reason: ${event.reason}`, { cause: event }));
73
73
  break;
74
- default:
75
- handleErrorEvent(new Error("Unknown live event type", { cause: event }));
76
- break;
74
+ default: handleErrorEvent(new Error("Unknown live event type", { cause: event }));
77
75
  }
78
76
  });
79
77
  useEffect(() => {
@@ -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, defaultApiHost} 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 {\n projectId,\n dataset,\n apiHost = defaultApiHost,\n apiVersion,\n useProjectHostname = true,\n token,\n 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
+ {"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, defaultApiHost} 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 {\n projectId,\n dataset,\n apiHost = defaultApiHost,\n apiVersion,\n useProjectHostname = true,\n token,\n 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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"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,133 @@
1
1
  import { t as isCorsOriginError } from "./isCorsOriginError.js";
2
2
  import { createClient, unstable__adapter, unstable__environment } from "@sanity/client";
3
- import { stegaClean } from "@sanity/client/stega";
3
+ import { ClientReturnStega, StegaBranded, StegaBranded as StegaBranded$1, StegaCleaned, StegaCleaned as StegaCleaned$1, StegaString, stegaBrand, stegaClean } from "@sanity/client/stega";
4
4
  import { CreateDataAttribute, CreateDataAttributeProps, createDataAttribute } from "@sanity/visual-editing/create-data-attribute";
5
+ import { InferComponents as InferComponents$1, InferStrictComponents as InferStrictComponents$1, InferValue as InferValue$1 } from "@portabletext/react";
5
6
  import groq, { defineQuery } from "groq";
6
7
  export * from "@sanity/client";
7
8
  export * from "@portabletext/react";
9
+ /**
10
+ * Widens a query result type to cover both sides of stega branding:
11
+ * the clean TypeGen shape (`sanityFetch` with `stega: false`) and the
12
+ * stega-branded shape (`sanityFetch` when stega may be enabled).
13
+ *
14
+ * This is what lets the `Infer*` types accept `data` from any `sanityFetch`
15
+ * call without requiring a wholesale `stegaClean()`, which would strip the
16
+ * hidden characters Visual Editing needs to make each paragraph clickable.
17
+ */
18
+ type StegaAware<T> = StegaCleaned$1<T> | StegaBranded$1<T>;
19
+ /**
20
+ * Infer the Portable Text array value type from
21
+ * {@link https://www.sanity.io/docs/apis-and-sdks/sanity-typegen | Sanity TypeGen}
22
+ * generated types.
23
+ *
24
+ * Stega-aware version of `InferValue` from `@portabletext/react`: the inferred
25
+ * value type accepts both clean query results (`sanityFetch` with
26
+ * `stega: false`) and stega-branded results (`sanityFetch` when stega may be
27
+ * enabled). Don't clean the value with `stegaClean()` before rendering it,
28
+ * that strips the hidden characters `@sanity/visual-editing` uses to make each
29
+ * paragraph clickable. Instead, use `stegaClean` on individual strings at the
30
+ * point where they're compared against literals.
31
+ *
32
+ * Useful when building a re-usable wrapper component that only takes `value`
33
+ * as an input prop and sets up `components` internally. Pass a TypeGen-
34
+ * generated query result type that contains Portable Text fields - such as
35
+ * an individual query result like `PostQueryResult`, or the `SanityQueries`
36
+ * interface from `@sanity/client` - and `InferValue<T>` returns an array type
37
+ * containing every Portable Text item shape it can find.
38
+ *
39
+ * Always feed `InferValue<T>` query result types, not Sanity schema types.
40
+ * Schema types describe how content is stored, which can differ from how it
41
+ * is queried (e.g. references resolved with `->`).
42
+ *
43
+ * @example
44
+ * ```tsx
45
+ * // Re-usable component typed against every registered query. Relies on
46
+ * // `overloadClientMethods` being enabled in `sanity.cli.ts#typegen` (the default).
47
+ * import {
48
+ * PortableText,
49
+ * type InferStrictComponents,
50
+ * type InferValue,
51
+ * type SanityQueries,
52
+ * } from 'next-sanity'
53
+ *
54
+ * type PortableTextValue = InferValue<SanityQueries[keyof SanityQueries]>
55
+ *
56
+ * export function CustomPortableText(props: {value: PortableTextValue}) {
57
+ * const components = {
58
+ * types: {
59
+ * // custom types are autocompleted and fully typed
60
+ * },
61
+ * } satisfies InferStrictComponents<PortableTextValue>
62
+ *
63
+ * return <PortableText components={components} value={props.value} />
64
+ * }
65
+ * ```
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * // Rendering `sanityFetch` results, with or without stega, type-checks:
70
+ * const {data} = await sanityFetch({query: postQuery, params})
71
+ * return Array.isArray(data?.content) && <CustomPortableText value={data.content} />
72
+ * ```
73
+ */
74
+ type InferValue<T> = InferValue$1<StegaAware<T>>;
75
+ /**
76
+ * Infer Portable Text components from a value type. This matches the inference
77
+ * behavior of the `components` prop on `<PortableText>`.
78
+ *
79
+ * Stega-aware version of `InferComponents` from `@portabletext/react`: the
80
+ * inferred component props cover both clean query results (`sanityFetch` with
81
+ * `stega: false`) and stega-branded results (`sanityFetch` when stega may be
82
+ * enabled), so the same `components` object can render both. Strings that may
83
+ * carry stega payloads stay branded inside component props: render them as-is
84
+ * to keep Visual Editing working, and use `stegaClean` on the individual
85
+ * values you compare against string literals.
86
+ *
87
+ * This is useful when working with
88
+ * {@link https://www.sanity.io/docs/apis-and-sdks/sanity-typegen | Sanity TypeGen},
89
+ * where `defineQuery()` and `sanityFetch()` can infer the shape of Portable
90
+ * Text fields.
91
+ *
92
+ * @example
93
+ * ```tsx
94
+ * import {PortableText, type InferComponents, defineQuery} from 'next-sanity'
95
+ * import {sanityFetch} from '@/sanity/lib/live'
96
+ *
97
+ * export default async function Page({slug}: {slug: string}) {
98
+ * const query = defineQuery(`*[_type == "post" && slug.current == $slug][0]{title,content}`)
99
+ * const {data} = await sanityFetch({query, params: {slug}})
100
+ * const components = {
101
+ * block: {
102
+ * // custom types are autocompleted and fully typed
103
+ * },
104
+ * } satisfies InferComponents<typeof data.content>
105
+ *
106
+ * return (
107
+ * <>
108
+ * ...
109
+ * {Array.isArray(data?.content) && <PortableText components={components} value={data.content} />}
110
+ * </>
111
+ * )
112
+ * }
113
+ * ```
114
+ */
115
+ type InferComponents<T> = InferComponents$1<StegaAware<T>>;
116
+ /**
117
+ * Infer Portable Text components from a value type, requiring handlers for all
118
+ * custom object types and disallowing extra custom object type handlers.
119
+ *
120
+ * Stega-aware version of `InferStrictComponents` from `@portabletext/react`,
121
+ * see {@link InferComponents} for how stega branding is handled.
122
+ *
123
+ * This is used the same way as {@link InferComponents}, but serves a different
124
+ * purpose: `InferComponents` is forgiving and mirrors the inline
125
+ * `<PortableText components={...} />` experience, allowing custom handlers to
126
+ * be omitted and allowing handlers for types that do not exist in, or could not
127
+ * be inferred from, the value type. `InferStrictComponents` is strict: it
128
+ * requires inferred custom handlers and rejects unknown ones.
129
+ */
130
+ type InferStrictComponents<T> = InferStrictComponents$1<StegaAware<T>>;
8
131
  /**
9
132
  * API version required for editing variants queries.
10
133
  * Uses the `X` alias while variants are in beta; will move to a dated version when stable.
@@ -12,5 +135,5 @@ export * from "@portabletext/react";
12
135
  * @public
13
136
  */
14
137
  declare const variantsApiVersion = "X";
15
- export { type CreateDataAttribute, type CreateDataAttributeProps, createClient, createDataAttribute, defineQuery, groq, isCorsOriginError, stegaClean, unstable__adapter, unstable__environment, variantsApiVersion };
138
+ export { type ClientReturnStega, type CreateDataAttribute, type CreateDataAttributeProps, type InferComponents, type InferStrictComponents, type InferValue, type StegaBranded, type StegaCleaned, type StegaString, createClient, createDataAttribute, defineQuery, groq, isCorsOriginError, stegaBrand, stegaClean, unstable__adapter, unstable__environment, variantsApiVersion };
16
139
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/variants/constants.ts"],"mappings":";;;;;;;;;;;;;cAMa"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/portable-text.ts","../src/variants/constants.ts"],"mappings":";;;;;;;;;;;;;;;;;KAgBK,WAAW,KAAK,eAAa,KAAK,eAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyDxC,WAAW,KAAK,aAAuB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA0ClD,gBAAgB,KAAK,kBAA4B,WAAW;;;;;;;;;;;;;;;KAgB5D,sBAAsB,KAAK,wBAAkC,WAAW;;;;;;;cC7HvE"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { t as isCorsOriginError } from "./isCorsOriginError.js";
2
2
  import { createClient, unstable__adapter, unstable__environment } from "@sanity/client";
3
- import { stegaClean } from "@sanity/client/stega";
3
+ import { stegaBrand, stegaClean } from "@sanity/client/stega";
4
4
  import { createDataAttribute } from "@sanity/visual-editing/create-data-attribute";
5
5
  import groq, { defineQuery } from "groq";
6
6
  export * from "@portabletext/react";
@@ -11,6 +11,6 @@ export * from "@portabletext/react";
11
11
  * @public
12
12
  */
13
13
  const variantsApiVersion = "X";
14
- export { createClient, createDataAttribute, defineQuery, groq, isCorsOriginError, stegaClean, unstable__adapter, unstable__environment, variantsApiVersion };
14
+ export { createClient, createDataAttribute, defineQuery, groq, isCorsOriginError, stegaBrand, stegaClean, unstable__adapter, unstable__environment, variantsApiVersion };
15
15
 
16
16
  //# sourceMappingURL=index.js.map
@@ -11,6 +11,11 @@ import { n as resolveVariantFromCookies$1, r as resolvePerspectiveFromCookies$1,
11
11
  * `<SanityLive />`. Resolve dynamic values from `draftMode()` and `cookies()`
12
12
  * outside `'use cache'` boundaries, then pass them into cached components.
13
13
  *
14
+ * `sanityFetch` brands `data` with stega string types when `stega` is `true`,
15
+ * a non-literal `boolean`, or omitted (react-server may auto-enable stega).
16
+ * Pass the literal `stega: false` for clean TypeGen types. Use `stegaClean`
17
+ * before comparing branded strings to literals.
18
+ *
14
19
  * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)
15
20
  * @see [Sanity Live](https://www.sanity.io/live)
16
21
  *
@@ -44,6 +49,7 @@ import { n as resolveVariantFromCookies$1, r as resolvePerspectiveFromCookies$1,
44
49
  * export interface DynamicFetchOptions {
45
50
  * perspective: LivePerspective
46
51
  * variant?: string
52
+ * // `boolean` brands `sanityFetch` `data`; use literal `false` for clean types
47
53
  * stega: boolean
48
54
  * }
49
55
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/default/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoKgB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmFlB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoFrB,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAsEtC,kCAAkC"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/default/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0KgB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmFlB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoFrB,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAsEtC,kCAAkC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/live/conditions/default/index.ts"],"sourcesContent":["import type {resolvePerspectiveFromCookies as _resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport type {resolveVariantFromCookies as _resolveVariantFromCookies} from '#live/resolveVariantFromCookies'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\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 * resolveVariantFromCookies,\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 * variant?: string\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 * const variant = await resolveVariantFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', variant, 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, variant, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} variant={variant} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * variant,\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 * variant,\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): never {\n throw new Error(`defineLive can't be imported by a client component`)\n}\n\nexport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n LivePerspective,\n SanityLiveAction,\n SanityLiveContext,\n SanityLiveOnError,\n SanityLiveOnGoaway,\n SanityLiveOnReconnect,\n SanityLiveOnRestart,\n SanityLiveOnWelcome,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n\nexport {isCorsOriginError} from '#live/isCorsOriginError'\nexport {parseTags} from '#live/parseTags'\n\n/**\n * This helper is intended for use with Next.js Cache Components (`cacheComponents: true`),\n * where `cookies()` and `draftMode()` cannot be called inside `'use cache'` boundaries.\n * Resolve the perspective once outside the cache boundary and pass it in as a prop / cache key.\n *\n * @example\n * ```tsx\n * import {cookies, draftMode} from 'next/headers'\n * import {defineQuery} from 'next-sanity'\n * import {resolvePerspectiveFromCookies, type LivePerspective} from 'next-sanity/live'\n * import {sanityFetch, sanityFetchStaticParams} from '#sanity/live'\n *\n * export async function generateStaticParams() {\n * const query = defineQuery(`*[_type == \"page\" && defined(slug.current)]{\"slug\": slug.current}`)\n * return await sanityFetchStaticParams({query})\n * }\n *\n * export default async function Page({params}: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * if (isDraftMode) {\n * return (\n * <Suspense>\n * <DynamicPage params={params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await params\n *\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage({params}: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await params\n * const perspective = await resolvePerspectiveFromCookies({cookies: await cookies()})\n *\n * return <CachedPage slug={slug} perspective={perspective} stega />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * stega,\n * }: Awaited<PageProps<'/[slug]'>['params']> & {\n * perspective: LivePerspective\n * stega: boolean\n * }) {\n * 'use cache'\n *\n * const query = defineQuery(`*[_type == \"page\" && slug.current == $slug][0]`)\n * const {data} = await sanityFetch({query, params: {slug}, perspective, stega})\n *\n * return <article>...</article>\n * }\n * ```\n *\n * @public\n */\nexport const resolvePerspectiveFromCookies: typeof _resolvePerspectiveFromCookies = () => {\n throw new Error(`resolvePerspectiveFromCookies can't be imported by a client component`)\n}\n\n/**\n * This helper is intended for use with Next.js Cache Components (`cacheComponents: true`),\n * where `cookies()` and `draftMode()` cannot be called inside `'use cache'` boundaries.\n * Resolve the variant once outside the cache boundary and pass it in as a prop / cache key.\n *\n * Unlike `resolvePerspectiveFromCookies` there is no fallback value: when no\n * variant cookie is set (or its value is invalid) it resolves to `undefined`,\n * meaning \"no variant selected\" and queries return base content.\n *\n * @example\n * ```tsx\n * import {cookies, draftMode} from 'next/headers'\n * import {defineQuery} from 'next-sanity'\n * import {\n * resolvePerspectiveFromCookies,\n * resolveVariantFromCookies,\n * type LivePerspective,\n * } from 'next-sanity/live'\n * import {sanityFetch} from '#sanity/live'\n *\n * export default async function Page({params}: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * if (isDraftMode) {\n * return (\n * <Suspense>\n * <DynamicPage params={params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await params\n *\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage({params}: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await params\n * const jar = await cookies()\n * const perspective = await resolvePerspectiveFromCookies({cookies: jar})\n * const variant = await resolveVariantFromCookies({cookies: jar})\n *\n * return <CachedPage slug={slug} perspective={perspective} variant={variant} stega />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * variant,\n * stega,\n * }: Awaited<PageProps<'/[slug]'>['params']> & {\n * perspective: LivePerspective\n * variant: string | undefined\n * stega: boolean\n * }) {\n * 'use cache'\n *\n * const query = defineQuery(`*[_type == \"page\" && slug.current == $slug][0]`)\n * const {data} = await sanityFetch({query, params: {slug}, perspective, variant, stega})\n *\n * return <article>...</article>\n * }\n * ```\n *\n * @public\n */\nexport const resolveVariantFromCookies: typeof _resolveVariantFromCookies = () => {\n throw new Error(`resolveVariantFromCookies can't be imported by a client component`)\n}\n"],"mappings":";;AA6PA,SAAgB,WAAW,SAAmC;CAC5D,MAAM,IAAI,MAAM,oDAAoD;AACtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,MAAa,sCAA6E;CACxF,MAAM,IAAI,MAAM,uEAAuE;AACzF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoEA,MAAa,kCAAqE;CAChF,MAAM,IAAI,MAAM,mEAAmE;AACrF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/live/conditions/default/index.ts"],"sourcesContent":["import type {resolvePerspectiveFromCookies as _resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport type {resolveVariantFromCookies as _resolveVariantFromCookies} from '#live/resolveVariantFromCookies'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\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 * `sanityFetch` brands `data` with stega string types when `stega` is `true`,\n * a non-literal `boolean`, or omitted (react-server may auto-enable stega).\n * Pass the literal `stega: false` for clean TypeGen types. Use `stegaClean`\n * before comparing branded strings to literals.\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 * resolveVariantFromCookies,\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 * variant?: string\n * // `boolean` brands `sanityFetch` `data`; use literal `false` for clean types\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 * const variant = await resolveVariantFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', variant, 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, variant, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} variant={variant} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * variant,\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 * variant,\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): never {\n throw new Error(`defineLive can't be imported by a client component`)\n}\n\nexport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n LivePerspective,\n SanityLiveAction,\n SanityLiveContext,\n SanityLiveOnError,\n SanityLiveOnGoaway,\n SanityLiveOnReconnect,\n SanityLiveOnRestart,\n SanityLiveOnWelcome,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n\nexport {isCorsOriginError} from '#live/isCorsOriginError'\nexport {parseTags} from '#live/parseTags'\n\n/**\n * This helper is intended for use with Next.js Cache Components (`cacheComponents: true`),\n * where `cookies()` and `draftMode()` cannot be called inside `'use cache'` boundaries.\n * Resolve the perspective once outside the cache boundary and pass it in as a prop / cache key.\n *\n * @example\n * ```tsx\n * import {cookies, draftMode} from 'next/headers'\n * import {defineQuery} from 'next-sanity'\n * import {resolvePerspectiveFromCookies, type LivePerspective} from 'next-sanity/live'\n * import {sanityFetch, sanityFetchStaticParams} from '#sanity/live'\n *\n * export async function generateStaticParams() {\n * const query = defineQuery(`*[_type == \"page\" && defined(slug.current)]{\"slug\": slug.current}`)\n * return await sanityFetchStaticParams({query})\n * }\n *\n * export default async function Page({params}: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * if (isDraftMode) {\n * return (\n * <Suspense>\n * <DynamicPage params={params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await params\n *\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage({params}: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await params\n * const perspective = await resolvePerspectiveFromCookies({cookies: await cookies()})\n *\n * return <CachedPage slug={slug} perspective={perspective} stega />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * stega,\n * }: Awaited<PageProps<'/[slug]'>['params']> & {\n * perspective: LivePerspective\n * stega: boolean\n * }) {\n * 'use cache'\n *\n * const query = defineQuery(`*[_type == \"page\" && slug.current == $slug][0]`)\n * const {data} = await sanityFetch({query, params: {slug}, perspective, stega})\n *\n * return <article>...</article>\n * }\n * ```\n *\n * @public\n */\nexport const resolvePerspectiveFromCookies: typeof _resolvePerspectiveFromCookies = () => {\n throw new Error(`resolvePerspectiveFromCookies can't be imported by a client component`)\n}\n\n/**\n * This helper is intended for use with Next.js Cache Components (`cacheComponents: true`),\n * where `cookies()` and `draftMode()` cannot be called inside `'use cache'` boundaries.\n * Resolve the variant once outside the cache boundary and pass it in as a prop / cache key.\n *\n * Unlike `resolvePerspectiveFromCookies` there is no fallback value: when no\n * variant cookie is set (or its value is invalid) it resolves to `undefined`,\n * meaning \"no variant selected\" and queries return base content.\n *\n * @example\n * ```tsx\n * import {cookies, draftMode} from 'next/headers'\n * import {defineQuery} from 'next-sanity'\n * import {\n * resolvePerspectiveFromCookies,\n * resolveVariantFromCookies,\n * type LivePerspective,\n * } from 'next-sanity/live'\n * import {sanityFetch} from '#sanity/live'\n *\n * export default async function Page({params}: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * if (isDraftMode) {\n * return (\n * <Suspense>\n * <DynamicPage params={params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await params\n *\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage({params}: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await params\n * const jar = await cookies()\n * const perspective = await resolvePerspectiveFromCookies({cookies: jar})\n * const variant = await resolveVariantFromCookies({cookies: jar})\n *\n * return <CachedPage slug={slug} perspective={perspective} variant={variant} stega />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * variant,\n * stega,\n * }: Awaited<PageProps<'/[slug]'>['params']> & {\n * perspective: LivePerspective\n * variant: string | undefined\n * stega: boolean\n * }) {\n * 'use cache'\n *\n * const query = defineQuery(`*[_type == \"page\" && slug.current == $slug][0]`)\n * const {data} = await sanityFetch({query, params: {slug}, perspective, variant, stega})\n *\n * return <article>...</article>\n * }\n * ```\n *\n * @public\n */\nexport const resolveVariantFromCookies: typeof _resolveVariantFromCookies = () => {\n throw new Error(`resolveVariantFromCookies can't be imported by a client component`)\n}\n"],"mappings":";;AAmQA,SAAgB,WAAW,SAAmC;CAC5D,MAAM,IAAI,MAAM,oDAAoD;AACtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,MAAa,sCAA6E;CACxF,MAAM,IAAI,MAAM,uEAAuE;AACzF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoEA,MAAa,kCAAqE;CAChF,MAAM,IAAI,MAAM,mEAAmE;AACrF"}
@@ -11,6 +11,11 @@ import { n as resolveVariantFromCookies, r as resolvePerspectiveFromCookies, t a
11
11
  * `<SanityLive />`. Resolve dynamic values from `draftMode()` and `cookies()`
12
12
  * outside `'use cache'` boundaries, then pass them into cached components.
13
13
  *
14
+ * `sanityFetch` brands `data` with stega string types when `stega` is `true`,
15
+ * a non-literal `boolean`, or omitted (react-server may auto-enable stega).
16
+ * Pass the literal `stega: false` for clean TypeGen types. Use `stegaClean`
17
+ * before comparing branded strings to literals.
18
+ *
14
19
  * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)
15
20
  * @see [Sanity Live](https://www.sanity.io/live)
16
21
  *
@@ -44,6 +49,7 @@ import { n as resolveVariantFromCookies, r as resolvePerspectiveFromCookies, t a
44
49
  * export interface DynamicFetchOptions {
45
50
  * perspective: LivePerspective
46
51
  * variant?: string
52
+ * // `boolean` brands `sanityFetch` `data`; use literal `false` for clean types
47
53
  * stega: boolean
48
54
  * }
49
55
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/next-js/defineLive.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2KgB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmFlB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/next-js/defineLive.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiLgB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmFlB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["sanityCacheLife","SanityLive","SanityLiveClientComponent"],"sources":["../../../../src/live/conditions/next-js/defineLive.tsx"],"sourcesContent":["import {sanity as sanityCacheLife} from 'next-sanity/live/cache-life'\nimport {SanityLive as SanityLiveClientComponent} from 'next-sanity/live/client-components'\nimport {revalidateSyncTagsAction} from 'next-sanity/live/server-actions'\nimport {cacheLife, cacheTag} from 'next/cache'\nimport {PHASE_PRODUCTION_BUILD} from 'next/constants'\n\nimport {cacheTagPrefix, defaultApiHost} from '#live/constants'\nimport {preconnect} from '#live/preconnect'\nimport {validateStrictFetchOptions, validateStrictSanityLiveProps} from '#live/strictValidation'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\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 * resolveVariantFromCookies,\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 * variant?: string\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 * const variant = await resolveVariantFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', variant, 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, variant, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} variant={variant} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * variant,\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 * variant,\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\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective,\n variant,\n stega,\n tags: customCacheTags = [],\n requestTag = 'next-loader.fetch.cache-components',\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective, stega})\n }\n\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 const {result, resultSourceMap, syncTags} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n variant,\n stega,\n returnQuery: false,\n useCdn,\n cacheMode,\n tag: requestTag,\n token,\n })\n const tags = [...customCacheTags, ...(syncTags || []).map((tag) => `${cacheTagPrefix}${tag}`)]\n /**\n * The tags used here, are expired later on in the `action` Server Action given to `<SanityLive />` with the `revalidateTag` function from `next/cache`,\n * or by a route handler that userland sets up.\n */\n cacheTag(...tags)\n /**\n * Sanity Live handles on-demand revalidation, so the default 15min time-based revalidation is too short,\n * userland can still set a shorter revalidate time by calling `cacheLife` themselves.\n */\n cacheLife(sanityCacheLife)\n\n return {data: result, sourceMap: resultSourceMap || null, tags}\n }\n\n const SanityLive: React.ComponentType<DefinedLiveProps> = function SanityLive(props) {\n if (strict) {\n validateStrictSanityLiveProps(props)\n }\n const {\n includeDrafts: _includeDrafts = false,\n requestTag = 'next-loader.live.cache-components',\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 = typeof browserToken === 'string' && !!browserToken && _includeDrafts\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 preconnect(client)\n\n return (\n <SanityLiveClientComponent\n config={{\n projectId,\n dataset,\n apiHost: apiHost === defaultApiHost ? undefined : apiHost,\n apiVersion,\n useProjectHostname: useProjectHostname ? undefined : useProjectHostname,\n requestTagPrefix,\n token: includeDrafts ? browserToken : undefined,\n }}\n includeDrafts={includeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={\n action ??\n (shouldWaitFor === 'function' || includeDrafts ? 'refresh' : revalidateSyncTagsAction)\n }\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"],"mappings":";;;;;;;;;;AAoQA,SAAgB,WAAW,QAA2B;CACpD,MAAM,EAAC,QAAQ,SAAS,aAAa,cAAc,SAAS,UAAS;CAErE,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,mDAAmD;CAGrE,IAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,eAAe,gBAAgB,OAC5E,QAAQ,KACN,6LACF;CAGF,IAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,gBAAgB,iBAAiB,OAC9E,QAAQ,KACN,gXACF;CAGF,MAAM,SAAS,QAAQ,WAAW;EAChC,kBAAkB;EAClB,QAAQ;EACR,aAAa;EACb,OAAO;CACT,CAAC;CAED,MAAM,cAAgC,eAAe,YAAY,EAC/D,OACA,SAAS,CAAC,GACV,aACA,SACA,OACA,MAAM,kBAAkB,CAAC,GACzB,aAAa,wCACZ;EACD,IAAI,QACF,2BAA2B;GAAC;GAAa;EAAK,CAAC;EAGjD,MAAM,SAAS,cAAc,gBAAgB,cAAc,KAAA;EAC3D,MAAM,eAAe,QAAQ,IAAI,kBAAkB;EACnD,MAAM,YAAY,WAAW,SAAS,CAAC,eAAe,YAAY,KAAA;EAClE,MAAM,SACF,eAAe,gBAAgB,eAAgB,UAAU,cACvD,cACA,KAAA;EAEN,MAAM,EAAC,QAAQ,iBAAiB,aAAY,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GAClF,gBAAgB;GAChB;GACA;GACA;GACA,aAAa;GACb;GACA;GACA,KAAK;GACL;EACF,CAAC;EACD,MAAM,OAAO,CAAC,GAAG,iBAAiB,IAAI,YAAY,CAAC,EAAA,CAAG,KAAK,QAAQ,GAAG,iBAAiB,KAAK,CAAC;;;;;EAK7F,SAAS,GAAG,IAAI;;;;;EAKhB,UAAUA,MAAe;EAEzB,OAAO;GAAC,MAAM;GAAQ,WAAW,mBAAmB;GAAM;EAAI;CAChE;CAEA,MAAMC,eAAoD,SAASA,aAAW,OAAO;EACnF,IAAI,QACF,8BAA8B,KAAK;EAErC,MAAM,EACJ,eAAe,iBAAiB,OAChC,aAAa,qCACb,SAEA,QACA,SACA,WACA,aACA,WACA,aACE;EACJ,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,OAAO;EAEhB,MAAM,gBAAgB,OAAO,iBAAiB,YAAY,CAAC,CAAC,gBAAgB;EAC5E,MAAM,gBAAgB,YAAY,cAAc,CAAC,gBAAgB,UAAU,KAAA;EAG3E,WAAW,MAAM;EAEjB,OACE,oBAACC,YAAD;GACE,QAAQ;IACN;IACA;IACA,SAAS,YAAA,0BAA6B,KAAA,IAAY;IAClD;IACA,oBAAoB,qBAAqB,KAAA,IAAY;IACrD;IACA,OAAO,gBAAgB,eAAe,KAAA;GACxC;GACA,eAAe,gBAAgB,OAAO,KAAA;GAC1B;GACZ,SAAS;GACT,QACE,WACC,kBAAkB,cAAc,gBAAgB,YAAY;GAEtD;GACE;GACE;GACF;GACD;EACX,CAAA;CAEL;CACA,aAAW,cAAc;CAEzB,OAAO;EAAC;EAAa,YAAA;CAAU;AACjC"}
1
+ {"version":3,"file":"index.js","names":["sanityCacheLife","SanityLive","SanityLiveClientComponent"],"sources":["../../../../src/live/conditions/next-js/defineLive.tsx"],"sourcesContent":["import {sanity as sanityCacheLife} from 'next-sanity/live/cache-life'\nimport {SanityLive as SanityLiveClientComponent} from 'next-sanity/live/client-components'\nimport {revalidateSyncTagsAction} from 'next-sanity/live/server-actions'\nimport {cacheLife, cacheTag} from 'next/cache'\nimport {PHASE_PRODUCTION_BUILD} from 'next/constants'\n\nimport {cacheTagPrefix, defaultApiHost} from '#live/constants'\nimport {preconnect} from '#live/preconnect'\nimport {validateStrictFetchOptions, validateStrictSanityLiveProps} from '#live/strictValidation'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\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 * `sanityFetch` brands `data` with stega string types when `stega` is `true`,\n * a non-literal `boolean`, or omitted (react-server may auto-enable stega).\n * Pass the literal `stega: false` for clean TypeGen types. Use `stegaClean`\n * before comparing branded strings to literals.\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 * resolveVariantFromCookies,\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 * variant?: string\n * // `boolean` brands `sanityFetch` `data`; use literal `false` for clean types\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 * const variant = await resolveVariantFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', variant, 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, variant, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} variant={variant} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * variant,\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 * variant,\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\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective,\n variant,\n stega,\n tags: customCacheTags = [],\n requestTag = 'next-loader.fetch.cache-components',\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective, stega})\n }\n\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 const {result, resultSourceMap, syncTags} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n variant,\n stega,\n returnQuery: false,\n useCdn,\n cacheMode,\n tag: requestTag,\n token,\n })\n const tags = [...customCacheTags, ...(syncTags || []).map((tag) => `${cacheTagPrefix}${tag}`)]\n /**\n * The tags used here, are expired later on in the `action` Server Action given to `<SanityLive />` with the `revalidateTag` function from `next/cache`,\n * or by a route handler that userland sets up.\n */\n cacheTag(...tags)\n /**\n * Sanity Live handles on-demand revalidation, so the default 15min time-based revalidation is too short,\n * userland can still set a shorter revalidate time by calling `cacheLife` themselves.\n */\n cacheLife(sanityCacheLife)\n\n return {data: result, sourceMap: resultSourceMap || null, tags}\n }\n\n const SanityLive: React.ComponentType<DefinedLiveProps> = function SanityLive(props) {\n if (strict) {\n validateStrictSanityLiveProps(props)\n }\n const {\n includeDrafts: _includeDrafts = false,\n requestTag = 'next-loader.live.cache-components',\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 = typeof browserToken === 'string' && !!browserToken && _includeDrafts\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 preconnect(client)\n\n return (\n <SanityLiveClientComponent\n config={{\n projectId,\n dataset,\n apiHost: apiHost === defaultApiHost ? undefined : apiHost,\n apiVersion,\n useProjectHostname: useProjectHostname ? undefined : useProjectHostname,\n requestTagPrefix,\n token: includeDrafts ? browserToken : undefined,\n }}\n includeDrafts={includeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={\n action ??\n (shouldWaitFor === 'function' || includeDrafts ? 'refresh' : revalidateSyncTagsAction)\n }\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"],"mappings":";;;;;;;;;;AA0QA,SAAgB,WAAW,QAA2B;CACpD,MAAM,EAAC,QAAQ,SAAS,aAAa,cAAc,SAAS,UAAS;CAErE,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,mDAAmD;CAGrE,IAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,eAAe,gBAAgB,OAC5E,QAAQ,KACN,6LACF;CAGF,IAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,gBAAgB,iBAAiB,OAC9E,QAAQ,KACN,gXACF;CAGF,MAAM,SAAS,QAAQ,WAAW;EAChC,kBAAkB;EAClB,QAAQ;EACR,aAAa;EACb,OAAO;CACT,CAAC;CAED,MAAM,cAAgC,eAAe,YAAY,EAC/D,OACA,SAAS,CAAC,GACV,aACA,SACA,OACA,MAAM,kBAAkB,CAAC,GACzB,aAAa,wCACZ;EACD,IAAI,QACF,2BAA2B;GAAC;GAAa;EAAK,CAAC;EAGjD,MAAM,SAAS,cAAc,gBAAgB,cAAc,KAAA;EAC3D,MAAM,eAAe,QAAQ,IAAI,kBAAkB;EACnD,MAAM,YAAY,WAAW,SAAS,CAAC,eAAe,YAAY,KAAA;EAClE,MAAM,SACF,eAAe,gBAAgB,eAAgB,UAAU,cACvD,cACA,KAAA;EAEN,MAAM,EAAC,QAAQ,iBAAiB,aAAY,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GAClF,gBAAgB;GAChB;GACA;GACA;GACA,aAAa;GACb;GACA;GACA,KAAK;GACL;EACF,CAAC;EACD,MAAM,OAAO,CAAC,GAAG,iBAAiB,IAAI,YAAY,CAAC,EAAA,CAAG,KAAK,QAAQ,GAAG,iBAAiB,KAAK,CAAC;;;;;EAK7F,SAAS,GAAG,IAAI;;;;;EAKhB,UAAUA,MAAe;EAEzB,OAAO;GAAC,MAAM;GAAQ,WAAW,mBAAmB;GAAM;EAAI;CAChE;CAEA,MAAMC,eAAoD,SAASA,aAAW,OAAO;EACnF,IAAI,QACF,8BAA8B,KAAK;EAErC,MAAM,EACJ,eAAe,iBAAiB,OAChC,aAAa,qCACb,SAEA,QACA,SACA,WACA,aACA,WACA,aACE;EACJ,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,OAAO;EAEhB,MAAM,gBAAgB,OAAO,iBAAiB,YAAY,CAAC,CAAC,gBAAgB;EAC5E,MAAM,gBAAgB,YAAY,cAAc,CAAC,gBAAgB,UAAU,KAAA;EAG3E,WAAW,MAAM;EAEjB,OACE,oBAACC,YAAD;GACE,QAAQ;IACN;IACA;IACA,SAAS,YAAA,0BAA6B,KAAA,IAAY;IAClD;IACA,oBAAoB,qBAAqB,KAAA,IAAY;IACrD;IACA,OAAO,gBAAgB,eAAe,KAAA;GACxC;GACA,eAAe,gBAAgB,OAAO,KAAA;GAC1B;GACZ,SAAS;GACT,QACE,WACC,kBAAkB,cAAc,gBAAgB,YAAY;GAEtD;GACE;GACE;GACF;GACD;EACX,CAAA;CAEL;CACA,aAAW,cAAc;CAEzB,OAAO;EAAC;EAAa,YAAA;CAAU;AACjC"}
@@ -11,6 +11,11 @@ import { n as resolveVariantFromCookies, r as resolvePerspectiveFromCookies, t a
11
11
  * `<SanityLive />`. Resolve dynamic values from `draftMode()` and `cookies()`
12
12
  * outside `'use cache'` boundaries, then pass them into cached components.
13
13
  *
14
+ * `sanityFetch` brands `data` with stega string types when `stega` is `true`,
15
+ * a non-literal `boolean`, or omitted (react-server may auto-enable stega).
16
+ * Pass the literal `stega: false` for clean TypeGen types. Use `stegaClean`
17
+ * before comparing branded strings to literals.
18
+ *
14
19
  * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)
15
20
  * @see [Sanity Live](https://www.sanity.io/live)
16
21
  *
@@ -44,6 +49,7 @@ import { n as resolveVariantFromCookies, r as resolvePerspectiveFromCookies, t a
44
49
  * export interface DynamicFetchOptions {
45
50
  * perspective: LivePerspective
46
51
  * variant?: string
52
+ * // `boolean` brands `sanityFetch` `data`; use literal `false` for clean types
47
53
  * stega: boolean
48
54
  * }
49
55
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6KgB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmFlB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmLgB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmFlB,WAAW,QAAQ;EAAqB;;EACtD,aAAa;EACb,YAAY,MAAM,cAAc"}
@@ -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'\n\nimport {cacheTagPrefix, defaultApiHost} from '#live/constants'\nimport {preconnect} from '#live/preconnect'\nimport {resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport {resolveVariantFromCookies} from '#live/resolveVariantFromCookies'\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 * resolveVariantFromCookies,\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 * variant?: string\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 * const variant = await resolveVariantFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', variant, 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, variant, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} variant={variant} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * variant,\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 * variant,\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 variant: _variant,\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 // The variant cookie is only auto-resolved when the perspective is too:\n // an explicit `perspective` opts out of cookie resolution entirely, which\n // keeps fetches with explicit options free of dynamic API calls.\n const variant = strict\n ? _variant\n : (_variant ??\n (serverToken && typeof _perspective === 'undefined'\n ? await resolveCookieVariant()\n : 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 variant,\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 variant,\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 preconnect(client)\n\n return (\n <SanityLiveClientComponent\n config={{\n projectId,\n dataset,\n apiHost: apiHost === defaultApiHost ? undefined : apiHost,\n apiVersion,\n useProjectHostname: useProjectHostname ? undefined : useProjectHostname,\n requestTagPrefix,\n token: includeDrafts ? browserToken : undefined,\n }}\n includeDrafts={includeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={\n action ??\n (shouldWaitFor === 'function' || includeDrafts ? 'refresh' : revalidateSyncTagsAction)\n }\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\nasync function resolveCookieVariant(): Promise<string | undefined> {\n return (await draftMode()).isEnabled\n ? await resolveVariantFromCookies({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'\n\nimport {cacheTagPrefix, defaultApiHost} from '#live/constants'\nimport {preconnect} from '#live/preconnect'\nimport {resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport {resolveVariantFromCookies} from '#live/resolveVariantFromCookies'\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 * `sanityFetch` brands `data` with stega string types when `stega` is `true`,\n * a non-literal `boolean`, or omitted (react-server may auto-enable stega).\n * Pass the literal `stega: false` for clean TypeGen types. Use `stegaClean`\n * before comparing branded strings to literals.\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 * resolveVariantFromCookies,\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 * variant?: string\n * // `boolean` brands `sanityFetch` `data`; use literal `false` for clean types\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 * const variant = await resolveVariantFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', variant, 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, variant, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} variant={variant} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * variant,\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 * variant,\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 variant: _variant,\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 // The variant cookie is only auto-resolved when the perspective is too:\n // an explicit `perspective` opts out of cookie resolution entirely, which\n // keeps fetches with explicit options free of dynamic API calls.\n const variant = strict\n ? _variant\n : (_variant ??\n (serverToken && typeof _perspective === 'undefined'\n ? await resolveCookieVariant()\n : 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 variant,\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 variant,\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 preconnect(client)\n\n return (\n <SanityLiveClientComponent\n config={{\n projectId,\n dataset,\n apiHost: apiHost === defaultApiHost ? undefined : apiHost,\n apiVersion,\n useProjectHostname: useProjectHostname ? undefined : useProjectHostname,\n requestTagPrefix,\n token: includeDrafts ? browserToken : undefined,\n }}\n includeDrafts={includeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={\n action ??\n (shouldWaitFor === 'function' || includeDrafts ? 'refresh' : revalidateSyncTagsAction)\n }\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\nasync function resolveCookieVariant(): Promise<string | undefined> {\n return (await draftMode()).isEnabled\n ? await resolveVariantFromCookies({cookies: await cookies()})\n : undefined\n}\n"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,17 +1,27 @@
1
+ import { StegaBranded } from "@sanity/client/stega";
1
2
  import { ClientPerspective, ClientReturn, ContentSourceMap, InitializedClientConfig, LiveEvent, QueryParams, SanityClient } from "next-sanity";
3
+ /**
4
+ * Like `ClientReturnStega` from `@sanity/client/stega`, but composed from the
5
+ * main-entry {@link ClientReturn} so `SanityQueries` TypeGen augmentations on
6
+ * `@sanity/client` apply. The stega subpath ships a bundled `ClientReturn` that
7
+ * does not see those augmentations.
8
+ */
9
+ type FetchClientReturnStega<QueryString extends string> = StegaBranded<ClientReturn<QueryString, unknown>>;
2
10
  /**
3
11
  * Perspectives supported by Sanity Live.
4
12
  * Using the legacy `'raw'` perspective is not supported and leads to undefined behavior.
5
13
  */
6
14
  type LivePerspective = Exclude<ClientPerspective, "raw">;
15
+ type DefinedFetchResult<Data> = Promise<{
16
+ data: Data;
17
+ sourceMap: ContentSourceMap | null;
18
+ tags: string[];
19
+ }>;
7
20
  /**
8
- * Fetches data through the configured Sanity client and returns the result
9
- * together with the source map and cache tags that Sanity Live uses for
10
- * targeted revalidation.
11
- *
12
- * Returned by `defineLive({strict: false})` and `defineLive({strict: undefined})`.
21
+ * Options accepted by `sanityFetch()` returned by `defineLive({strict: false})`
22
+ * and `defineLive({strict: undefined})`.
13
23
  */
14
- type DefinedFetchType = <const QueryString extends string>(options: {
24
+ interface DefinedFetchOptions<QueryString extends string> {
15
25
  /**
16
26
  * GROQ query to execute.
17
27
  */
@@ -57,6 +67,12 @@ type DefinedFetchType = <const QueryString extends string>(options: {
57
67
  * Enables stega encoding of the data. This is typically only used in draft
58
68
  * mode with `perspective: 'drafts'` and `@sanity/visual-editing`.
59
69
  *
70
+ * Unless this option is the literal `false`, the returned `data` is
71
+ * stega-branded (`StegaBranded<ClientReturn<...>>`): strings that may carry
72
+ * stega payloads are typed as `StegaString` and must be cleaned with
73
+ * `stegaClean` before they can be compared against string literals. Pass the
74
+ * literal `stega: false` to keep clean TypeGen / {@link ClientReturn} types.
75
+ *
60
76
  * @remarks
61
77
  * Requires `serverToken` to be configured in `defineLive()`
62
78
  *
@@ -95,11 +111,54 @@ type DefinedFetchType = <const QueryString extends string>(options: {
95
111
  * otherwise it's `'next-loader.fetch'`
96
112
  */
97
113
  requestTag?: string;
98
- }) => Promise<{
99
- data: ClientReturn<QueryString, unknown>;
100
- sourceMap: ContentSourceMap | null;
101
- tags: string[];
102
- }>;
114
+ }
115
+ /**
116
+ * Like {@link DefinedFetchOptions} but with `stega` fixed to `true`, selecting
117
+ * the overload that brands the returned `data` with stega string types.
118
+ * All other options inherit their documentation from {@link DefinedFetchOptions}.
119
+ */
120
+ interface DefinedFetchStegaEnabledOptions<QueryString extends string> extends DefinedFetchOptions<QueryString> {
121
+ /**
122
+ * Enables stega encoding of the data. This is typically only used in draft
123
+ * mode with `perspective: 'drafts'` and `@sanity/visual-editing`.
124
+ *
125
+ * With the literal `true`, the returned `data` is stega-branded
126
+ * (`StegaBranded<ClientReturn<...>>`): use `stegaClean` before comparing
127
+ * strings against literals.
128
+ *
129
+ * @remarks
130
+ * Requires `serverToken` to be configured in `defineLive()`
131
+ */
132
+ stega: true;
133
+ }
134
+ /**
135
+ * Like {@link DefinedFetchOptions} but with `stega` fixed to `false`, selecting
136
+ * the overload that keeps the returned `data` free of stega branding.
137
+ * All other options inherit their documentation from {@link DefinedFetchOptions}.
138
+ */
139
+ interface DefinedFetchStegaDisabledOptions<QueryString extends string> extends DefinedFetchOptions<QueryString> {
140
+ /**
141
+ * Disables stega encoding for this fetch. The returned `data` keeps clean
142
+ * TypeGen / {@link ClientReturn} types, no `stegaClean` needed.
143
+ */
144
+ stega: false;
145
+ }
146
+ /**
147
+ * Fetches data through the configured Sanity client and returns the result
148
+ * together with the source map and cache tags that Sanity Live uses for
149
+ * targeted revalidation.
150
+ *
151
+ * Returned by `defineLive({strict: false})` and `defineLive({strict: undefined})`.
152
+ *
153
+ * Overloads brand `data` with stega string types when stega may be enabled
154
+ * (`stega: true`, a non-literal `boolean`, or omitted). Literal `stega: false`
155
+ * keeps clean TypeGen / {@link ClientReturn} types.
156
+ */
157
+ type DefinedFetchType = {
158
+ <const QueryString extends string>(options: DefinedFetchStegaEnabledOptions<QueryString>): DefinedFetchResult<FetchClientReturnStega<QueryString>>;
159
+ <const QueryString extends string>(options: DefinedFetchStegaDisabledOptions<QueryString>): DefinedFetchResult<ClientReturn<QueryString, unknown>>;
160
+ <const QueryString extends string>(options: DefinedFetchOptions<QueryString>): DefinedFetchResult<FetchClientReturnStega<QueryString>>;
161
+ };
103
162
  /**
104
163
  * Render this in your root layout.tsx to make your page refresh, or revalidate, on new content live, automatically.
105
164
  * @public
@@ -210,12 +269,20 @@ interface StrictDefinedLiveProps extends Omit<DefinedLiveProps, "includeDrafts">
210
269
  includeDrafts: boolean;
211
270
  }
212
271
  /**
213
- * Like {@link DefinedFetchType} but with `perspective` and `stega` required.
214
- * Returned by `defineLive({strict: true})`.
272
+ * Options accepted by `sanityFetch()` returned by `defineLive({strict: true})`.
273
+ * Like {@link DefinedFetchOptions} but with `perspective` and `stega` required,
274
+ * and no cookie or `draftMode()` auto-resolution of defaults.
215
275
  */
216
- type StrictDefinedFetchType = <const QueryString extends string>(options: {
217
- query: QueryString;
218
- params?: QueryParams | Promise<QueryParams>;
276
+ interface StrictDefinedFetchOptions<QueryString extends string> extends DefinedFetchOptions<QueryString> {
277
+ /**
278
+ * Content perspective used for the fetch.
279
+ *
280
+ * Required when `strict: true` is set on `defineLive()`: there is no cookie
281
+ * auto-resolution; only the explicit option is used.
282
+ *
283
+ * @remarks
284
+ * Non-`'published'` perspectives require `serverToken` to be configured in `defineLive()`
285
+ */
219
286
  perspective: LivePerspective;
220
287
  /**
221
288
  * Editing variant used for the fetch, as the bare variant id (e.g. `Ab12cd34`).
@@ -225,14 +292,64 @@ type StrictDefinedFetchType = <const QueryString extends string>(options: {
225
292
  * only the explicit option is used.
226
293
  */
227
294
  variant?: string;
295
+ /**
296
+ * Enables stega encoding of the data. This is typically only used in draft
297
+ * mode with `perspective: 'drafts'` and `@sanity/visual-editing`.
298
+ *
299
+ * Required when `strict: true` is set on `defineLive()`. Unless this option
300
+ * is the literal `false`, the returned `data` is stega-branded
301
+ * (`StegaBranded<ClientReturn<...>>`) — conservative: treat strings as
302
+ * possibly stega-encoded until cleaned with `stegaClean`.
303
+ *
304
+ * @remarks
305
+ * Requires `serverToken` to be configured in `defineLive()`
306
+ */
228
307
  stega: boolean;
229
- tags?: string[];
230
- requestTag?: string;
231
- }) => Promise<{
232
- data: ClientReturn<QueryString, unknown>;
233
- sourceMap: ContentSourceMap | null;
234
- tags: string[];
235
- }>;
308
+ }
309
+ /**
310
+ * Like {@link StrictDefinedFetchOptions} but with `stega` fixed to `true`,
311
+ * selecting the overload that brands the returned `data` with stega string types.
312
+ * All other options inherit their documentation from {@link StrictDefinedFetchOptions}.
313
+ */
314
+ interface StrictDefinedFetchStegaEnabledOptions<QueryString extends string> extends StrictDefinedFetchOptions<QueryString> {
315
+ /**
316
+ * Enables stega encoding of the data. This is typically only used in draft
317
+ * mode with `perspective: 'drafts'` and `@sanity/visual-editing`.
318
+ *
319
+ * With the literal `true`, the returned `data` is stega-branded
320
+ * (`StegaBranded<ClientReturn<...>>`): use `stegaClean` before comparing
321
+ * strings against literals.
322
+ *
323
+ * @remarks
324
+ * Requires `serverToken` to be configured in `defineLive()`
325
+ */
326
+ stega: true;
327
+ }
328
+ /**
329
+ * Like {@link StrictDefinedFetchOptions} but with `stega` fixed to `false`,
330
+ * selecting the overload that keeps the returned `data` free of stega branding.
331
+ * All other options inherit their documentation from {@link StrictDefinedFetchOptions}.
332
+ */
333
+ interface StrictDefinedFetchStegaDisabledOptions<QueryString extends string> extends StrictDefinedFetchOptions<QueryString> {
334
+ /**
335
+ * Disables stega encoding for this fetch. The returned `data` keeps clean
336
+ * TypeGen / {@link ClientReturn} types, no `stegaClean` needed.
337
+ */
338
+ stega: false;
339
+ }
340
+ /**
341
+ * Like {@link DefinedFetchType} but with `perspective` and `stega` required.
342
+ * Returned by `defineLive({strict: true})`.
343
+ *
344
+ * Overloads brand `data` with stega string types when stega may be enabled
345
+ * (`stega: true` or a non-literal `boolean`). Literal `stega: false` keeps
346
+ * clean TypeGen / {@link ClientReturn} types.
347
+ */
348
+ type StrictDefinedFetchType = {
349
+ <const QueryString extends string>(options: StrictDefinedFetchStegaEnabledOptions<QueryString>): DefinedFetchResult<FetchClientReturnStega<QueryString>>;
350
+ <const QueryString extends string>(options: StrictDefinedFetchStegaDisabledOptions<QueryString>): DefinedFetchResult<ClientReturn<QueryString, unknown>>;
351
+ <const QueryString extends string>(options: StrictDefinedFetchOptions<QueryString>): DefinedFetchResult<FetchClientReturnStega<QueryString>>;
352
+ };
236
353
  interface SanityClientConfig extends Pick<InitializedClientConfig, "projectId" | "dataset" | "apiVersion" | "token" | "requestTagPrefix"> {
237
354
  apiHost: string | undefined;
238
355
  useProjectHostname: boolean | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../src/live/shared/types.ts"],"mappings":";;;;;KAcY,kBAAkB,QAAQ;;;;;;;;KAS1B,0BAA0B,4BAA4B;;;;EAIhE,OAAO;;;;EAIP,SAAS,cAAc,QAAQ;;;;;;;;;;;;;;;;EAgB/B,cAAc;;;;;;;;;;;;;;;;;EAiBd;;;;;;;;;;;;;;;;;;EAkBA;;;;;;;;;;;;;;EAcA;;;;;;;;;;EAUA;MACI;EACJ,MAAM,aAAa;EACnB,WAAW;EACX;;;;;;UAOe;;;;;;;;;;;;;;;;EAgBf;;;;;;;;;;EAUA;;;;;EAKA;;;;;;;EAOA,SAAS;;;;;;EAMT,UAAU;;;;;EAKV,YAAY;;;;;EAKZ,cAAc;;;;;EAKd,YAAY;;;;;EAKZ,WAAW;;UAGI;;;;EAIf,QAAQ;;;;;;;EAOR;;;;;;;;EAQA;;;;;;;;;;;EAWA;;;;;;UAOe,+BAA+B,KAAK;EACnD;;;;;;KAOU,gCAAgC,4BAA4B;EACtE,OAAO;EACP,SAAS,cAAc,QAAQ;EAC/B,aAAa;;;;;;;;EAQb;EACA;EACA;EACA;MACI;EACJ,MAAM,aAAa;EACnB,WAAW;EACX;;UAGe,2BAA2B,KAC1C;EAGA;EACA;;;;;UAMe;;;;;EAKf;;;;EAIA;;;;;;;;;;;;;;;;KAiBU,qBAAqB,wBAAwB;;;;;;;;;KAS7C,sBAAsB,gBAAgB,SAAS;;;;;;;;KAQ/C,uBACV,OAAO,QAAQ;EAAY;IAC3B,SAAS,6BACC;;;;;;KAMA,yBACV,OAAO,QAAQ;EAAY;IAC3B,SAAS,6BACC;;;;;;;KAQA,wBAEN,OAAO,QAAQ;EAAY;IAC3B,SAAS,6BACC;;;;;;;;;KAUJ,sBACV,OAAO,QAAQ;EAAY;IAC3B,SAAS,mBACT,qBAAqB,qCACX"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../src/live/shared/types.ts"],"mappings":";;;;;;;;KAiBK,uBAAuB,8BAA8B,aACxD,aAAa;;;;;KAOH,kBAAkB,QAAQ;KAEjC,mBAAmB,QAAQ;EAC9B,MAAM;EACN,WAAW;EACX;;;;;;UAOQ,oBAAoB;;;;EAI5B,OAAO;;;;EAIP,SAAS,cAAc,QAAQ;;;;;;;;;;;;;;;;EAgB/B,cAAc;;;;;;;;;;;;;;;;;EAiBd;;;;;;;;;;;;;;;;;;;;;;;;EAwBA;;;;;;;;;;;;;;EAcA;;;;;;;;;;EAUA;;;;;;;UAQQ,gCACR,oCACQ,oBAAoB;;;;;;;;;;;;EAY5B;;;;;;;UAQQ,iCACR,oCACQ,oBAAoB;;;;;EAK5B;;;;;;;;;;;;;KAcU;SACH,4BACL,SAAS,gCAAgC,eACxC,mBAAmB,uBAAuB;SACtC,4BACL,SAAS,iCAAiC,eACzC,mBAAmB,aAAa;SAC5B,4BACL,SAAS,oBAAoB,eAC5B,mBAAmB,uBAAuB;;;;;;UAO9B;;;;;;;;;;;;;;;;EAgBf;;;;;;;;;;EAUA;;;;;EAKA;;;;;;;EAOA,SAAS;;;;;;EAMT,UAAU;;;;;EAKV,YAAY;;;;;EAKZ,cAAc;;;;;EAKd,YAAY;;;;;EAKZ,WAAW;;UAGI;;;;EAIf,QAAQ;;;;;;;EAOR;;;;;;;;EAQA;;;;;;;;;;;EAWA;;;;;;UAOe,+BAA+B,KAAK;EACnD;;;;;;;UAQQ,0BACR,oCACQ,oBAAoB;;;;;;;;;;EAU5B,aAAa;;;;;;;;EAQb;;;;;;;;;;;;;EAaA;;;;;;;UAQQ,sCACR,oCACQ,0BAA0B;;;;;;;;;;;;EAYlC;;;;;;;UAQQ,uCACR,oCACQ,0BAA0B;;;;;EAKlC;;;;;;;;;;KAWU;SACH,4BACL,SAAS,sCAAsC,eAC9C,mBAAmB,uBAAuB;SACtC,4BACL,SAAS,uCAAuC,eAC/C,mBAAmB,aAAa;SAC5B,4BACL,SAAS,0BAA0B,eAClC,mBAAmB,uBAAuB;;UAG9B,2BAA2B,KAC1C;EAGA;EACA;;;;;UAMe;;;;;EAKf;;;;EAIA;;;;;;;;;;;;;;;;KAiBU,qBAAqB,wBAAwB;;;;;;;;;KAS7C,sBAAsB,gBAAgB,SAAS;;;;;;;;KAQ/C,uBACV,OAAO,QAAQ;EAAY;IAC3B,SAAS,6BACC;;;;;;KAMA,yBACV,OAAO,QAAQ;EAAY;IAC3B,SAAS,6BACC;;;;;;;KAQA,wBAEN,OAAO,QAAQ;EAAY;IAC3B,SAAS,6BACC;;;;;;;;;KAUJ,sBACV,OAAO,QAAQ;EAAY;IAC3B,SAAS,mBACT,qBAAqB,qCACX"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-sanity",
3
- "version": "13.2.3",
3
+ "version": "13.3.1",
4
4
  "description": "Sanity.io toolkit for Next.js",
5
5
  "keywords": [
6
6
  "live",
@@ -59,39 +59,39 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@portabletext/react": "^7.0.1",
62
- "@sanity/client": "^7.25.0",
62
+ "@sanity/client": "^7.26.1",
63
63
  "@sanity/generate-help-url": "^4.0.0",
64
64
  "@sanity/preview-url-secret": "^4.1.2",
65
65
  "@sanity/visual-editing": "^5.7.3",
66
66
  "@sanity/webhook": "^4.0.4",
67
- "groq": "^6.7.0",
67
+ "groq": "^6.8.0",
68
68
  "history": "^5.3.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@sanity/tsconfig": "^2.2.1",
72
72
  "@types/node": "^24.13.3",
73
- "@types/react": "^19.2.17",
74
- "@types/react-dom": "^19.2.3",
73
+ "@types/react": "^19.2.18",
74
+ "@types/react-dom": "^19.2.4",
75
75
  "@vercel/stega": "^1.1.0",
76
- "@vitejs/plugin-react": "^6.0.4",
76
+ "@vitejs/plugin-react": "^6.0.5",
77
77
  "@vitest/browser-playwright": "^4.1.10",
78
78
  "@vitest/coverage-v8": "^4.1.10",
79
- "js-yaml": "^5.2.2",
79
+ "js-yaml": "^5.2.3",
80
80
  "msw": "^2.15.0",
81
- "next": "16.3.0-canary.99",
81
+ "next": "16.3.1-canary.0",
82
82
  "publint": "^0.3.22",
83
83
  "react": "^19.2.8",
84
84
  "react-dom": "^19.2.8",
85
85
  "styled-components": "^6.4.4",
86
86
  "tsdown": "^0.22.14",
87
87
  "typescript": "7.0.2",
88
- "vite": "^8.1.5",
88
+ "vite": "^8.2.0",
89
89
  "vitest": "^4.1.10",
90
90
  "vitest-browser-react": "^2.2.0",
91
91
  "vitest-package-exports": "^1.2.0"
92
92
  },
93
93
  "peerDependencies": {
94
- "@sanity/client": "^7.25.0",
94
+ "@sanity/client": "^7.26.1",
95
95
  "next": "^16.0.0-0",
96
96
  "react": "^19.2.3",
97
97
  "react-dom": "^19.2.3",