next-sanity 13.0.0-cache-components.61 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,7 +102,7 @@ MIT-licensed. See [LICENSE][LICENSE].
102
102
  [migrate-v9-to-v10]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v9-to-v10.md
103
103
  [migrate-v10-to-v11]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v10-to-v11.md
104
104
  [migrate-v11-to-v12]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v11-to-v12.md
105
- [migrate-v12-to-v13]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/CHANGELOG.md#1300
105
+ [migrate-v12-to-v13]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v12-to-v13.md
106
106
  [next-docs]: https://nextjs.org/docs
107
107
  [sanity]: https://www.sanity.io?utm_source=github&utm_medium=readme&utm_campaign=next-sanity
108
108
  [sanity-next-clean-starter]: https://www.sanity.io/templates/nextjs-sanity-clean
package/dist/constants.js CHANGED
@@ -1,8 +1,4 @@
1
- /**
2
- * Sanity Live handles on-demand revalidation, so the default 15min time based revalidation is too short
3
- */
4
- const revalidate = 31536e3;
5
1
  const cacheTagPrefix = "sanity:";
6
- export { revalidate as n, cacheTagPrefix as t };
2
+ export { cacheTagPrefix as t };
7
3
 
8
4
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":[],"sources":["../src/live/shared/constants.ts"],"sourcesContent":["import type {CacheTagPrefix} from '#live/types'\n\n/**\n * Sanity Live handles on-demand revalidation, so the default 15min time based revalidation is too short\n */\nexport const revalidate = 31_536_000 // 365 days\n\n// @TODO make this configurable\nexport const cacheTagPrefix = 'sanity:' satisfies CacheTagPrefix\n"],"mappings":";;;AAKA,MAAa,aAAa;AAG1B,MAAa,iBAAiB"}
1
+ {"version":3,"file":"constants.js","names":[],"sources":["../src/live/shared/constants.ts"],"sourcesContent":["import type {CacheTagPrefix} from '#live/types'\n\n// @TODO make this configurable\nexport const cacheTagPrefix = 'sanity:' satisfies CacheTagPrefix\n"],"mappings":"AAGA,MAAa,iBAAiB"}
@@ -4,30 +4,21 @@
4
4
  * // next.config.ts
5
5
  *
6
6
  * import type {NextConfig} from 'next'
7
- * import {sanity} from 'next-sanity/cache-life'
7
+ * import {sanity} from 'next-sanity/live/cache-life'
8
8
  *
9
9
  * const nextConfig: NextConfig = {
10
10
  * cacheComponents: true,
11
11
  * cacheLife: {
12
- * sanity
12
+ * default: sanity,
13
13
  * }
14
14
  * }
15
15
  *
16
16
  * export default nextConfig
17
17
  * ```
18
- *
19
- * ```ts
20
- *
21
- * async function sanityFetch() {
22
- * 'use cache'
23
- * cacheLife('sanity')
24
- * const {data} = await fetch({query, params})
25
- * return data
26
- * }
27
18
  */
28
19
  declare const sanity: {
29
20
  /**
30
- * Sanity Live handles on-demand revalidation, so the default 15min time based revalidation is too short
21
+ * Sanity Live handles on-demand revalidation, so the default 15min time-based revalidation is too short
31
22
  */
32
23
  readonly revalidate: 31_536_000;
33
24
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cache-life.d.ts","names":[],"sources":["../../src/live/cache-life.ts"],"mappings":"AA6BA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,cAAa,MAAA;;;;WAIX,UAAA;AAAA"}
1
+ {"version":3,"file":"cache-life.d.ts","names":[],"sources":["../../src/live/cache-life.ts"],"mappings":"AAkBA;;;;;;;;;;;;;;;;;;AAAA,cAAa,MAAA;;;;WAIX,UAAA;AAAA"}
@@ -4,30 +4,21 @@
4
4
  * // next.config.ts
5
5
  *
6
6
  * import type {NextConfig} from 'next'
7
- * import {sanity} from 'next-sanity/cache-life'
7
+ * import {sanity} from 'next-sanity/live/cache-life'
8
8
  *
9
9
  * const nextConfig: NextConfig = {
10
10
  * cacheComponents: true,
11
11
  * cacheLife: {
12
- * sanity
12
+ * default: sanity,
13
13
  * }
14
14
  * }
15
15
  *
16
16
  * export default nextConfig
17
17
  * ```
18
- *
19
- * ```ts
20
- *
21
- * async function sanityFetch() {
22
- * 'use cache'
23
- * cacheLife('sanity')
24
- * const {data} = await fetch({query, params})
25
- * return data
26
- * }
27
18
  */
28
19
  const sanity = {
29
20
  /**
30
- * Sanity Live handles on-demand revalidation, so the default 15min time based revalidation is too short
21
+ * Sanity Live handles on-demand revalidation, so the default 15min time-based revalidation is too short
31
22
  */
32
23
  revalidate: 31536e3 };
33
24
  export { sanity };
@@ -1 +1 @@
1
- {"version":3,"file":"cache-life.js","names":[],"sources":["../../src/live/cache-life.ts"],"sourcesContent":["import {revalidate} from '#live/constants'\n\n/**\n * For usage with `cacheComponents: true`, and `defineLive`:\n * ```ts\n * // next.config.ts\n *\n * import type {NextConfig} from 'next'\n * import {sanity} from 'next-sanity/cache-life'\n *\n * const nextConfig: NextConfig = {\n * cacheComponents: true,\n * cacheLife: {\n * sanity\n * }\n * }\n *\n * export default nextConfig\n * ```\n *\n * ```ts\n *\n * async function sanityFetch() {\n * 'use cache'\n * cacheLife('sanity')\n * const {data} = await fetch({query, params})\n * return data\n * }\n */\nexport const sanity = {\n /**\n * Sanity Live handles on-demand revalidation, so the default 15min time based revalidation is too short\n */\n revalidate: 31_536_000, // 365 days\n} as const satisfies {\n /**\n * This cache may be stale on clients for ... seconds before checking with the server.\n */\n stale?: number\n /**\n * If the server receives a new request after ... seconds, start revalidating new values in the background.\n */\n revalidate?: typeof revalidate\n /**\n * If this entry has no traffic for ... seconds it will expire. The next request will recompute it.\n */\n expire?: number\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAa,SAAS;;;;AAIpB,YAAY,SACb"}
1
+ {"version":3,"file":"cache-life.js","names":[],"sources":["../../src/live/cache-life.ts"],"sourcesContent":["/**\n * For usage with `cacheComponents: true`, and `defineLive`:\n * ```ts\n * // next.config.ts\n *\n * import type {NextConfig} from 'next'\n * import {sanity} from 'next-sanity/live/cache-life'\n *\n * const nextConfig: NextConfig = {\n * cacheComponents: true,\n * cacheLife: {\n * default: sanity,\n * }\n * }\n *\n * export default nextConfig\n * ```\n */\nexport const sanity = {\n /**\n * Sanity Live handles on-demand revalidation, so the default 15min time-based revalidation is too short\n */\n revalidate: 31_536_000, // 365 days\n} as const satisfies {\n /**\n * This cache may be stale on clients for ... seconds before checking with the server.\n */\n stale?: number\n /**\n * If the server receives a new request after ... seconds, start revalidating new values in the background.\n */\n revalidate?: number\n /**\n * If this entry has no traffic for ... seconds it will expire. The next request will recompute it.\n */\n expire?: number\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,MAAa,SAAS;;;;AAIpB,YAAY,SACb"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/next-js/defineLive.tsx"],"mappings":";;;;;;AAqKA;;;;;;;;;;;;;;;;;;;;AAqFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBArFgB,UAAA,CAAW,MAAA,EAAQ,iBAAA;EAAqB,MAAA;AAAA;EACtD,WAAA,EAAa,sBAAA;EACb,UAAA,EAAY,KAAA,CAAM,aAAA,CAAc,sBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmFlB,UAAA,CAAW,MAAA,EAAQ,iBAAA;EAAqB,MAAA;AAAA;EACtD,WAAA,EAAa,gBAAA;EACb,UAAA,EAAY,KAAA,CAAM,aAAA,CAAc,gBAAA;AAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/next-js/defineLive.tsx"],"mappings":";;;;;;AAsKA;;;;;;;;;;;;;;;;;;;;AAqFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBArFgB,UAAA,CAAW,MAAA,EAAQ,iBAAA;EAAqB,MAAA;AAAA;EACtD,WAAA,EAAa,sBAAA;EACb,UAAA,EAAY,KAAA,CAAM,aAAA,CAAc,sBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmFlB,UAAA,CAAW,MAAA,EAAQ,iBAAA;EAAqB,MAAA;AAAA;EACtD,WAAA,EAAa,gBAAA;EACb,UAAA,EAAY,KAAA,CAAM,aAAA,CAAc,gBAAA;AAAA"}
@@ -1,13 +1,13 @@
1
1
  import { t as isCorsOriginError } from "../../../isCorsOriginError.js";
2
- import { n as revalidate, t as cacheTagPrefix } from "../../../constants.js";
3
- import { n as validateStrictFetchOptions, r as validateStrictSanityLiveProps, t as resolvePerspectiveFromCookies } from "../../../resolvePerspectiveFromCookies.js";
2
+ import { t as cacheTagPrefix } from "../../../constants.js";
3
+ import { i as preconnect, n as validateStrictFetchOptions, r as validateStrictSanityLiveProps, t as resolvePerspectiveFromCookies } from "../../../resolvePerspectiveFromCookies.js";
4
4
  import { t as parseTags } from "../../../parseTags.js";
5
5
  import { jsx } from "react/jsx-runtime";
6
+ import { sanity } from "next-sanity/live/cache-life";
6
7
  import { SanityLive } from "next-sanity/live/client-components";
7
8
  import { revalidateSyncTagsAction } from "next-sanity/live/server-actions";
8
9
  import { cacheLife, cacheTag } from "next/cache";
9
10
  import { PHASE_PRODUCTION_BUILD } from "next/constants";
10
- import { preconnect } from "react-dom";
11
11
  function defineLive(config) {
12
12
  const { client: _client, serverToken, browserToken, strict = false } = config;
13
13
  if (!_client) throw new Error("`client` is required for `defineLive` to function");
@@ -24,27 +24,31 @@ function defineLive(config) {
24
24
  perspective,
25
25
  stega
26
26
  });
27
- const cacheMode = !(process.env["NEXT_PHASE"] === PHASE_PRODUCTION_BUILD) ? "noStale" : void 0;
27
+ const useCdn = perspective ? perspective === "published" : void 0;
28
+ const isBuildPhase = process.env["NEXT_PHASE"] === PHASE_PRODUCTION_BUILD;
29
+ const cacheMode = useCdn !== false && !isBuildPhase ? "noStale" : void 0;
30
+ const token = (perspective && perspective !== "published" || stega) && serverToken ? serverToken : void 0;
28
31
  const { result, resultSourceMap, syncTags } = await client.fetch(query, await params, {
29
32
  filterResponse: false,
30
- returnQuery: false,
31
33
  perspective,
32
34
  stega,
33
- useCdn: perspective ? perspective === "published" : void 0,
35
+ returnQuery: false,
36
+ useCdn,
34
37
  cacheMode,
35
38
  tag: requestTag,
36
- token: (perspective && perspective !== "published" || stega) && serverToken ? serverToken : void 0
39
+ token
37
40
  });
38
41
  const tags = [...customCacheTags, ...(syncTags || []).map((tag) => `${cacheTagPrefix}${tag}`)];
39
42
  /**
40
- * The tags used here, are expired later on in the `expireTags` Server Action with the `expireTag` function from `next/cache`
43
+ * The tags used here, are expired later on in the `action` Server Action given to `<SanityLive />` with the `revalidateTag` function from `next/cache`,
44
+ * or by a route handler that userland sets up.
41
45
  */
42
46
  cacheTag(...tags);
43
47
  /**
44
- * Sanity Live handles on-demand revalidation, so the default 15min time based revalidation is too short,
48
+ * Sanity Live handles on-demand revalidation, so the default 15min time-based revalidation is too short,
45
49
  * userland can still set a shorter revalidate time by calling `cacheLife` themselves.
46
50
  */
47
- cacheLife({ revalidate });
51
+ cacheLife(sanity);
48
52
  return {
49
53
  data: result,
50
54
  sourceMap: resultSourceMap || null,
@@ -53,12 +57,11 @@ function defineLive(config) {
53
57
  };
54
58
  const SanityLive$2 = function SanityLive$1(props) {
55
59
  if (strict) validateStrictSanityLiveProps(props);
56
- const { includeDrafts = false, requestTag = "next-loader.live.cache-components", waitFor, action, onError, onWelcome, onReconnect, onRestart, onGoAway } = props;
60
+ const { includeDrafts: _includeDrafts = false, requestTag = "next-loader.live.cache-components", waitFor, action, onError, onWelcome, onReconnect, onRestart, onGoAway } = props;
57
61
  const { projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix } = client.config();
58
- const shouldIncludeDrafts = typeof browserToken === "string" && includeDrafts;
59
- const shouldWaitFor = waitFor === "function" && !shouldIncludeDrafts ? waitFor : void 0;
60
- const { origin } = new URL(client.getUrl("", false));
61
- preconnect(origin);
62
+ const includeDrafts = typeof browserToken === "string" && !!browserToken && _includeDrafts;
63
+ const shouldWaitFor = waitFor === "function" && !includeDrafts ? waitFor : void 0;
64
+ preconnect(client);
62
65
  return /* @__PURE__ */ jsx(SanityLive, {
63
66
  config: {
64
67
  projectId,
@@ -67,9 +70,9 @@ function defineLive(config) {
67
70
  apiVersion,
68
71
  useProjectHostname,
69
72
  requestTagPrefix,
70
- token: shouldIncludeDrafts ? browserToken : void 0
73
+ token: includeDrafts ? browserToken : void 0
71
74
  },
72
- includeDrafts: shouldIncludeDrafts ? true : void 0,
75
+ includeDrafts: includeDrafts ? true : void 0,
73
76
  requestTag,
74
77
  waitFor: shouldWaitFor,
75
78
  action: action ?? (shouldWaitFor === "function" ? "refresh" : revalidateSyncTagsAction),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["SanityLive","SanityLiveClientComponent"],"sources":["../../../../src/live/conditions/next-js/defineLive.tsx"],"sourcesContent":["import {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'\nimport {preconnect} from 'react-dom'\n\nimport {cacheTagPrefix, revalidate} from '#live/constants'\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 * type LivePerspective,\n * } from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * strict: true,\n * })\n *\n * export interface DynamicFetchOptions {\n * perspective: LivePerspective\n * stega: boolean\n * }\n *\n * // Resolve dynamic values outside 'use cache' boundaries.\n * export async function getDynamicFetchOptions(): Promise<DynamicFetchOptions> {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (!isDraftMode) {\n * return {perspective: 'published', stega: false}\n * }\n *\n * const jar = await cookies()\n * const perspective = await resolvePerspectiveFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', stega: true}\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {draftMode} from 'next/headers'\n *\n * import {SanityLive} from '@/sanity/live'\n *\n * export default async function RootLayout({children}: {children: React.ReactNode}) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive includeDrafts={isDraftMode} />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {draftMode} from 'next/headers'\n * import {Suspense} from 'react'\n * import {defineQuery} from 'next-sanity'\n *\n * import {\n * getDynamicFetchOptions,\n * sanityFetch,\n * type DynamicFetchOptions,\n * } from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (isDraftMode) {\n * return (\n * <Suspense fallback={<div>Loading...</div>}>\n * <DynamicPage params={props.params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await props.params\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage(props: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await props.params\n * const {perspective, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * stega,\n * }: {slug: string} & DynamicFetchOptions) {\n * 'use cache'\n *\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * perspective,\n * stega,\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict: true}): {\n sanityFetch: StrictDefinedFetchType\n SanityLive: React.ComponentType<StrictDefinedLiveProps>\n}\n/**\n * Set up Sanity Live. `defineLive` returns `sanityFetch` and `<SanityLive />`,\n * which connect your Sanity client to the Live Content API so pages can serve\n * cached content and update in response to fine-grained content changes.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * import {createClient} from 'next-sanity'\n * import {defineLive} from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * })\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {SanityLive} from '@/sanity/live'\n *\n * export default function RootLayout({children}: {children: React.ReactNode}) {\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {defineQuery} from 'next-sanity'\n * import {sanityFetch} from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {slug} = await props.params\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict?: false}): {\n sanityFetch: DefinedFetchType\n SanityLive: React.ComponentType<DefinedLiveProps>\n}\nexport function defineLive(config: DefineLiveOptions) {\n const {client: _client, serverToken, browserToken, strict = false} = config\n\n if (!_client) {\n throw new Error('`client` is required for `defineLive` to function')\n }\n\n if (process.env.NODE_ENV === 'development' && !serverToken && serverToken !== false) {\n console.warn(\n 'No `serverToken` provided to `defineLive`. This means that only published content will be fetched and respond to live events. You can silence this warning by setting `serverToken: false`.',\n )\n }\n\n if (process.env.NODE_ENV === 'development' && !browserToken && browserToken !== false) {\n console.warn(\n 'No `browserToken` provided to `defineLive`. This means that live previewing drafts will only work when using the Presentation Tool in your Sanity Studio. To support live previewing drafts stand-alone, provide a `browserToken`. It is shared with the browser so it should only have Viewer rights or lower. You can silence this warning by setting `browserToken: false`.',\n )\n }\n\n const client = _client.withConfig({\n allowReconfigure: false,\n useCdn: true,\n perspective: 'published',\n stega: false,\n })\n\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective,\n stega,\n tags: customCacheTags = [],\n requestTag = 'next-loader.fetch.cache-components',\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective, stega})\n }\n\n const isBuildPhase = process.env['NEXT_PHASE'] === PHASE_PRODUCTION_BUILD\n const cacheMode = !isBuildPhase ? 'noStale' : undefined\n\n const {result, resultSourceMap, syncTags} = await client.fetch(query, await params, {\n filterResponse: false,\n returnQuery: false,\n perspective,\n stega,\n useCdn: perspective ? perspective === 'published' : undefined,\n cacheMode,\n tag: requestTag,\n token:\n ((perspective && perspective !== 'published') || stega) && serverToken\n ? serverToken\n : undefined,\n })\n const tags = [...customCacheTags, ...(syncTags || []).map((tag) => `${cacheTagPrefix}${tag}`)]\n /**\n * The tags used here, are expired later on in the `expireTags` Server Action with the `expireTag` function from `next/cache`\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({revalidate})\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 = 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 shouldIncludeDrafts = typeof browserToken === 'string' && includeDrafts\n const shouldWaitFor = waitFor === 'function' && !shouldIncludeDrafts ? waitFor : undefined\n\n // Preconnect to the Live Event API origin early, as the Sanity API is almost always on a different origin than the app\n const {origin} = new URL(client.getUrl('', false))\n preconnect(origin)\n\n return (\n <SanityLiveClientComponent\n config={{\n projectId,\n dataset,\n apiHost,\n apiVersion,\n useProjectHostname,\n requestTagPrefix,\n token: shouldIncludeDrafts ? browserToken : undefined,\n }}\n includeDrafts={shouldIncludeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? 'refresh' : revalidateSyncTagsAction)}\n onError={onError}\n onWelcome={onWelcome}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onGoAway={onGoAway}\n />\n )\n }\n SanityLive.displayName = 'SanityLiveServerComponent'\n\n return {sanityFetch, SanityLive}\n}\n"],"mappings":";;;;;;;;;;AA8PA,SAAgB,WAAW,QAA2B;CACpD,MAAM,EAAC,QAAQ,SAAS,aAAa,cAAc,SAAS,UAAS;AAErE,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,oDAAoD;AAGtE,KAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,eAAe,gBAAgB,MAC5E,SAAQ,KACN,8LACD;AAGH,KAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,gBAAgB,iBAAiB,MAC9E,SAAQ,KACN,iXACD;CAGH,MAAM,SAAS,QAAQ,WAAW;EAChC,kBAAkB;EAClB,QAAQ;EACR,aAAa;EACb,OAAO;EACR,CAAC;CAEF,MAAM,cAAgC,eAAe,YAAY,EAC/D,OACA,SAAS,EAAE,EACX,aACA,OACA,MAAM,kBAAkB,EAAE,EAC1B,aAAa,wCACZ;AACD,MAAI,OACF,4BAA2B;GAAC;GAAa;GAAM,CAAC;EAIlD,MAAM,YAAY,EADG,QAAQ,IAAI,kBAAkB,0BACjB,YAAY,KAAA;EAE9C,MAAM,EAAC,QAAQ,iBAAiB,aAAY,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GAClF,gBAAgB;GAChB,aAAa;GACb;GACA;GACA,QAAQ,cAAc,gBAAgB,cAAc,KAAA;GACpD;GACA,KAAK;GACL,QACI,eAAe,gBAAgB,eAAgB,UAAU,cACvD,cACA,KAAA;GACP,CAAC;EACF,MAAM,OAAO,CAAC,GAAG,iBAAiB,IAAI,YAAY,EAAE,EAAE,KAAK,QAAQ,GAAG,iBAAiB,MAAM,CAAC;;;;AAI9F,WAAS,GAAG,KAAK;;;;;AAKjB,YAAU,EAAC,YAAW,CAAC;AAEvB,SAAO;GAAC,MAAM;GAAQ,WAAW,mBAAmB;GAAM;GAAK;;CAGjE,MAAMA,eAAoD,SAASA,aAAW,OAAO;AACnF,MAAI,OACF,+BAA8B,MAAM;EAEtC,MAAM,EACJ,gBAAgB,OAChB,aAAa,qCACb,SAEA,QACA,SACA,WACA,aACA,WACA,aACE;EACJ,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,QAAQ;EAEjB,MAAM,sBAAsB,OAAO,iBAAiB,YAAY;EAChE,MAAM,gBAAgB,YAAY,cAAc,CAAC,sBAAsB,UAAU,KAAA;EAGjF,MAAM,EAAC,WAAU,IAAI,IAAI,OAAO,OAAO,IAAI,MAAM,CAAC;AAClD,aAAW,OAAO;AAElB,SACE,oBAACC,YAAD;GACE,QAAQ;IACN;IACA;IACA;IACA;IACA;IACA;IACA,OAAO,sBAAsB,eAAe,KAAA;IAC7C;GACD,eAAe,sBAAsB,OAAO,KAAA;GAChC;GACZ,SAAS;GACT,QAAQ,WAAW,kBAAkB,aAAa,YAAY;GACrD;GACE;GACE;GACF;GACD;GACV,CAAA;;AAGN,cAAW,cAAc;AAEzB,QAAO;EAAC;EAAa,YAAA;EAAW"}
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} 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 * type LivePerspective,\n * } from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * strict: true,\n * })\n *\n * export interface DynamicFetchOptions {\n * perspective: LivePerspective\n * stega: boolean\n * }\n *\n * // Resolve dynamic values outside 'use cache' boundaries.\n * export async function getDynamicFetchOptions(): Promise<DynamicFetchOptions> {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (!isDraftMode) {\n * return {perspective: 'published', stega: false}\n * }\n *\n * const jar = await cookies()\n * const perspective = await resolvePerspectiveFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', stega: true}\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {draftMode} from 'next/headers'\n *\n * import {SanityLive} from '@/sanity/live'\n *\n * export default async function RootLayout({children}: {children: React.ReactNode}) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive includeDrafts={isDraftMode} />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {draftMode} from 'next/headers'\n * import {Suspense} from 'react'\n * import {defineQuery} from 'next-sanity'\n *\n * import {\n * getDynamicFetchOptions,\n * sanityFetch,\n * type DynamicFetchOptions,\n * } from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (isDraftMode) {\n * return (\n * <Suspense fallback={<div>Loading...</div>}>\n * <DynamicPage params={props.params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await props.params\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage(props: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await props.params\n * const {perspective, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * stega,\n * }: {slug: string} & DynamicFetchOptions) {\n * 'use cache'\n *\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * perspective,\n * stega,\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict: true}): {\n sanityFetch: StrictDefinedFetchType\n SanityLive: React.ComponentType<StrictDefinedLiveProps>\n}\n/**\n * Set up Sanity Live. `defineLive` returns `sanityFetch` and `<SanityLive />`,\n * which connect your Sanity client to the Live Content API so pages can serve\n * cached content and update in response to fine-grained content changes.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * import {createClient} from 'next-sanity'\n * import {defineLive} from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * })\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {SanityLive} from '@/sanity/live'\n *\n * export default function RootLayout({children}: {children: React.ReactNode}) {\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {defineQuery} from 'next-sanity'\n * import {sanityFetch} from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {slug} = await props.params\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict?: false}): {\n sanityFetch: DefinedFetchType\n SanityLive: React.ComponentType<DefinedLiveProps>\n}\nexport function defineLive(config: DefineLiveOptions) {\n const {client: _client, serverToken, browserToken, strict = false} = config\n\n if (!_client) {\n throw new Error('`client` is required for `defineLive` to function')\n }\n\n if (process.env.NODE_ENV === 'development' && !serverToken && serverToken !== false) {\n console.warn(\n 'No `serverToken` provided to `defineLive`. This means that only published content will be fetched and respond to live events. You can silence this warning by setting `serverToken: false`.',\n )\n }\n\n if (process.env.NODE_ENV === 'development' && !browserToken && browserToken !== false) {\n console.warn(\n 'No `browserToken` provided to `defineLive`. This means that live previewing drafts will only work when using the Presentation Tool in your Sanity Studio. To support live previewing drafts stand-alone, provide a `browserToken`. It is shared with the browser so it should only have Viewer rights or lower. You can silence this warning by setting `browserToken: false`.',\n )\n }\n\n const client = _client.withConfig({\n allowReconfigure: false,\n useCdn: true,\n perspective: 'published',\n stega: false,\n })\n\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective,\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 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,\n apiVersion,\n useProjectHostname,\n requestTagPrefix,\n token: includeDrafts ? browserToken : undefined,\n }}\n includeDrafts={includeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? 'refresh' : revalidateSyncTagsAction)}\n onError={onError}\n onWelcome={onWelcome}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onGoAway={onGoAway}\n />\n )\n }\n SanityLive.displayName = 'SanityLiveServerComponent'\n\n return {sanityFetch, SanityLive}\n}\n"],"mappings":";;;;;;;;;;AA+PA,SAAgB,WAAW,QAA2B;CACpD,MAAM,EAAC,QAAQ,SAAS,aAAa,cAAc,SAAS,UAAS;AAErE,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,oDAAoD;AAGtE,KAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,eAAe,gBAAgB,MAC5E,SAAQ,KACN,8LACD;AAGH,KAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,gBAAgB,iBAAiB,MAC9E,SAAQ,KACN,iXACD;CAGH,MAAM,SAAS,QAAQ,WAAW;EAChC,kBAAkB;EAClB,QAAQ;EACR,aAAa;EACb,OAAO;EACR,CAAC;CAEF,MAAM,cAAgC,eAAe,YAAY,EAC/D,OACA,SAAS,EAAE,EACX,aACA,OACA,MAAM,kBAAkB,EAAE,EAC1B,aAAa,wCACZ;AACD,MAAI,OACF,4BAA2B;GAAC;GAAa;GAAM,CAAC;EAGlD,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,aAAa;GACb;GACA;GACA,KAAK;GACL;GACD,CAAC;EACF,MAAM,OAAO,CAAC,GAAG,iBAAiB,IAAI,YAAY,EAAE,EAAE,KAAK,QAAQ,GAAG,iBAAiB,MAAM,CAAC;;;;;AAK9F,WAAS,GAAG,KAAK;;;;;AAKjB,YAAUA,OAAgB;AAE1B,SAAO;GAAC,MAAM;GAAQ,WAAW,mBAAmB;GAAM;GAAK;;CAGjE,MAAMC,eAAoD,SAASA,aAAW,OAAO;AACnF,MAAI,OACF,+BAA8B,MAAM;EAEtC,MAAM,EACJ,eAAe,iBAAiB,OAChC,aAAa,qCACb,SAEA,QACA,SACA,WACA,aACA,WACA,aACE;EACJ,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,QAAQ;EAEjB,MAAM,gBAAgB,OAAO,iBAAiB,YAAY,CAAC,CAAC,gBAAgB;EAC5E,MAAM,gBAAgB,YAAY,cAAc,CAAC,gBAAgB,UAAU,KAAA;AAG3E,aAAW,OAAO;AAElB,SACE,oBAACC,YAAD;GACE,QAAQ;IACN;IACA;IACA;IACA;IACA;IACA;IACA,OAAO,gBAAgB,eAAe,KAAA;IACvC;GACD,eAAe,gBAAgB,OAAO,KAAA;GAC1B;GACZ,SAAS;GACT,QAAQ,WAAW,kBAAkB,aAAa,YAAY;GACrD;GACE;GACE;GACF;GACD;GACV,CAAA;;AAGN,cAAW,cAAc;AAEzB,QAAO;EAAC;EAAa,YAAA;EAAW"}
@@ -1,13 +1,12 @@
1
1
  import { t as isCorsOriginError } from "../../../isCorsOriginError.js";
2
2
  import "../../../constants.js";
3
- import { n as validateStrictFetchOptions, r as validateStrictSanityLiveProps, t as resolvePerspectiveFromCookies } from "../../../resolvePerspectiveFromCookies.js";
3
+ import { i as preconnect, n as validateStrictFetchOptions, r as validateStrictSanityLiveProps, t as resolvePerspectiveFromCookies } from "../../../resolvePerspectiveFromCookies.js";
4
4
  import { t as parseTags } from "../../../parseTags.js";
5
5
  import { cookies, draftMode } from "next/headers";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { SanityLive } from "next-sanity/live/client-components";
8
8
  import { revalidateSyncTagsAction } from "next-sanity/live/server-actions";
9
9
  import { PHASE_PRODUCTION_BUILD } from "next/constants";
10
- import { preconnect } from "react-dom";
11
10
  function defineLive(config) {
12
11
  const { client: _client, serverToken, browserToken, strict = false } = config;
13
12
  if (!_client) throw new Error("`client` is required for `defineLive` to function");
@@ -68,8 +67,7 @@ function defineLive(config) {
68
67
  const { projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix } = client.config();
69
68
  const includeDrafts = typeof browserToken === "string" && !!browserToken && (_includeDrafts ?? (await draftMode()).isEnabled);
70
69
  const shouldWaitFor = waitFor === "function" && !includeDrafts ? waitFor : void 0;
71
- const { origin } = new URL(client.getUrl("", false));
72
- preconnect(origin);
70
+ preconnect(client);
73
71
  return /* @__PURE__ */ jsx(SanityLive, {
74
72
  config: {
75
73
  projectId,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["SanityLive","SanityLiveClientComponent"],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"sourcesContent":["import {SanityLive as SanityLiveClientComponent} from 'next-sanity/live/client-components'\nimport {revalidateSyncTagsAction} from 'next-sanity/live/server-actions'\nimport {PHASE_PRODUCTION_BUILD} from 'next/constants'\nimport {cookies, draftMode} from 'next/headers'\nimport {preconnect} from 'react-dom'\n\nimport {cacheTagPrefix} from '#live/constants'\nimport {resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport {validateStrictFetchOptions, validateStrictSanityLiveProps} from '#live/strictValidation'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n LivePerspective,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n\n/**\n * Set up Sanity Live for Cache Components. `defineLive` returns `sanityFetch`\n * and `<SanityLive />`, which connect your Sanity client to the Live Content API\n * so cached pages can update in response to fine-grained content changes.\n *\n * With `strict: true`, `perspective` and `stega` become required\n * `sanityFetch` options, and `includeDrafts` becomes required on\n * `<SanityLive />`. Resolve dynamic values from `draftMode()` and `cookies()`\n * outside `'use cache'` boundaries, then pass them into cached components.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * // sanity/live.ts\n * import {cookies, draftMode} from 'next/headers'\n * import {createClient} from 'next-sanity'\n * import {\n * defineLive,\n * resolvePerspectiveFromCookies,\n * type LivePerspective,\n * } from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * strict: true,\n * })\n *\n * export interface DynamicFetchOptions {\n * perspective: LivePerspective\n * stega: boolean\n * }\n *\n * // Resolve dynamic values outside 'use cache' boundaries.\n * export async function getDynamicFetchOptions(): Promise<DynamicFetchOptions> {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (!isDraftMode) {\n * return {perspective: 'published', stega: false}\n * }\n *\n * const jar = await cookies()\n * const perspective = await resolvePerspectiveFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', stega: true}\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {draftMode} from 'next/headers'\n *\n * import {SanityLive} from '@/sanity/live'\n *\n * export default async function RootLayout({children}: {children: React.ReactNode}) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive includeDrafts={isDraftMode} />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {draftMode} from 'next/headers'\n * import {Suspense} from 'react'\n * import {defineQuery} from 'next-sanity'\n *\n * import {\n * getDynamicFetchOptions,\n * sanityFetch,\n * type DynamicFetchOptions,\n * } from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (isDraftMode) {\n * return (\n * <Suspense fallback={<div>Loading...</div>}>\n * <DynamicPage params={props.params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await props.params\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage(props: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await props.params\n * const {perspective, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * stega,\n * }: {slug: string} & DynamicFetchOptions) {\n * 'use cache'\n *\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * perspective,\n * stega,\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict: true}): {\n sanityFetch: StrictDefinedFetchType\n SanityLive: React.ComponentType<StrictDefinedLiveProps>\n}\n/**\n * Set up Sanity Live. `defineLive` returns `sanityFetch` and `<SanityLive />`,\n * which connect your Sanity client to the Live Content API so pages can serve\n * cached content and update in response to fine-grained content changes.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * import {createClient} from 'next-sanity'\n * import {defineLive} from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * })\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {SanityLive} from '@/sanity/live'\n *\n * export default function RootLayout({children}: {children: React.ReactNode}) {\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {defineQuery} from 'next-sanity'\n * import {sanityFetch} from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {slug} = await props.params\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict?: false}): {\n sanityFetch: DefinedFetchType\n SanityLive: React.ComponentType<DefinedLiveProps>\n}\nexport function defineLive(config: DefineLiveOptions) {\n const {client: _client, serverToken, browserToken, strict = false} = config\n\n if (!_client) {\n throw new Error('`client` is required for `defineLive` to function')\n }\n\n if (process.env.NODE_ENV === 'development' && !serverToken && serverToken !== false) {\n console.warn(\n 'No `serverToken` provided to `defineLive`. This means that only published content will be fetched and respond to live events. You can silence this warning by setting `serverToken: false`.',\n )\n }\n\n if (process.env.NODE_ENV === 'development' && !browserToken && browserToken !== false) {\n console.warn(\n 'No `browserToken` provided to `defineLive`. This means that live previewing drafts will only work when using the Presentation Tool in your Sanity Studio. To support live previewing drafts stand-alone, provide a `browserToken`. It is shared with the browser so it should only have Viewer rights or lower. You can silence this warning by setting `browserToken: false`.',\n )\n }\n\n const client = _client.withConfig({\n allowReconfigure: false,\n useCdn: true,\n perspective: 'published',\n stega: false,\n })\n const studioUrlDefined = typeof client.config().stega.studioUrl !== 'undefined'\n\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective: _perspective,\n stega: _stega,\n tags = [],\n requestTag = 'next-loader.fetch',\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective: _perspective, stega: _stega})\n }\n const stega = strict\n ? _stega\n : (_stega ?? (serverToken && studioUrlDefined ? (await draftMode()).isEnabled : false))\n const perspective = strict\n ? _perspective\n : (_perspective ?? (serverToken ? await resolveCookiePerspective() : undefined))\n const useCdn = perspective ? perspective === 'published' : undefined\n const isBuildPhase = process.env['NEXT_PHASE'] === PHASE_PRODUCTION_BUILD\n const cacheMode = useCdn !== false && !isBuildPhase ? 'noStale' : undefined\n const token =\n ((perspective && perspective !== 'published') || stega) && serverToken\n ? serverToken\n : undefined\n\n // 1. Fetch the tags first, with an uncached request, but that does not count towards the Sanity API quota\n const {syncTags} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n stega: false,\n resultSourceMap: false,\n returnQuery: false,\n useCdn,\n cacheMode,\n tag: [requestTag, 'fetch-sync-tags'].filter(Boolean).join('.'),\n token,\n })\n\n const cacheTags = [...tags, ...(syncTags?.map((tag) => `${cacheTagPrefix}${tag}`) || [])]\n\n // 2. Then fetch the data, using the fetch cache with specified tags\n const {result, resultSourceMap} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n stega,\n next: {revalidate: false, tags: cacheTags},\n useCdn,\n cacheMode,\n tag: requestTag,\n token,\n })\n return {data: result, sourceMap: resultSourceMap || null, tags: cacheTags}\n }\n\n const SanityLive: React.ComponentType<DefinedLiveProps> = async function SanityLive(props) {\n if (strict) {\n validateStrictSanityLiveProps(props)\n }\n const {\n includeDrafts: _includeDrafts,\n requestTag = 'next-loader.live',\n waitFor,\n\n action,\n onError,\n onWelcome,\n onReconnect,\n onRestart,\n onGoAway,\n } = props\n const {projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix} =\n client.config()\n\n const includeDrafts =\n typeof browserToken === 'string' &&\n !!browserToken &&\n (_includeDrafts ?? (await draftMode()).isEnabled)\n const shouldWaitFor = waitFor === 'function' && !includeDrafts ? waitFor : undefined\n\n // Preconnect to the Live Event API origin early, as the Sanity API is almost always on a different origin than the app\n const {origin} = new URL(client.getUrl('', false))\n preconnect(origin)\n\n return (\n <SanityLiveClientComponent\n config={{\n projectId,\n dataset,\n apiHost,\n apiVersion,\n useProjectHostname,\n requestTagPrefix,\n token: includeDrafts ? browserToken : undefined,\n }}\n includeDrafts={includeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? 'refresh' : revalidateSyncTagsAction)}\n onError={onError}\n onWelcome={onWelcome}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onGoAway={onGoAway}\n />\n )\n }\n SanityLive.displayName = 'SanityLiveServerComponent'\n\n return {sanityFetch, SanityLive}\n}\n\nasync function resolveCookiePerspective(): Promise<LivePerspective | undefined> {\n return (await draftMode()).isEnabled\n ? await resolvePerspectiveFromCookies({cookies: await cookies()})\n : undefined\n}\n"],"mappings":";;;;;;;;;;AAgQA,SAAgB,WAAW,QAA2B;CACpD,MAAM,EAAC,QAAQ,SAAS,aAAa,cAAc,SAAS,UAAS;AAErE,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,oDAAoD;AAGtE,KAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,eAAe,gBAAgB,MAC5E,SAAQ,KACN,8LACD;AAGH,KAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,gBAAgB,iBAAiB,MAC9E,SAAQ,KACN,iXACD;CAGH,MAAM,SAAS,QAAQ,WAAW;EAChC,kBAAkB;EAClB,QAAQ;EACR,aAAa;EACb,OAAO;EACR,CAAC;CACF,MAAM,mBAAmB,OAAO,OAAO,QAAQ,CAAC,MAAM,cAAc;CAEpE,MAAM,cAAgC,eAAe,YAAY,EAC/D,OACA,SAAS,EAAE,EACX,aAAa,cACb,OAAO,QACP,OAAO,EAAE,EACT,aAAa,uBACZ;AACD,MAAI,OACF,4BAA2B;GAAC,aAAa;GAAc,OAAO;GAAO,CAAC;EAExE,MAAM,QAAQ,SACV,SACC,WAAW,eAAe,oBAAoB,MAAM,WAAW,EAAE,YAAY;EAClF,MAAM,cAAc,SAChB,eACC,iBAAiB,cAAc,MAAM,0BAA0B,GAAG,KAAA;EACvE,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;EAGN,MAAM,EAAC,aAAY,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GACzD,gBAAgB;GAChB;GACA,OAAO;GACP,iBAAiB;GACjB,aAAa;GACb;GACA;GACA,KAAK,CAAC,YAAY,kBAAkB,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;GAC9D;GACD,CAAC;EAEF,MAAM,YAAY,CAAC,GAAG,MAAM,GAAI,UAAU,KAAK,QAAQ,UAAoB,MAAM,IAAI,EAAE,CAAE;EAGzF,MAAM,EAAC,QAAQ,oBAAmB,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GACxE,gBAAgB;GAChB;GACA;GACA,MAAM;IAAC,YAAY;IAAO,MAAM;IAAU;GAC1C;GACA;GACA,KAAK;GACL;GACD,CAAC;AACF,SAAO;GAAC,MAAM;GAAQ,WAAW,mBAAmB;GAAM,MAAM;GAAU;;CAG5E,MAAMA,eAAoD,eAAeA,aAAW,OAAO;AACzF,MAAI,OACF,+BAA8B,MAAM;EAEtC,MAAM,EACJ,eAAe,gBACf,aAAa,oBACb,SAEA,QACA,SACA,WACA,aACA,WACA,aACE;EACJ,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,QAAQ;EAEjB,MAAM,gBACJ,OAAO,iBAAiB,YACxB,CAAC,CAAC,iBACD,mBAAmB,MAAM,WAAW,EAAE;EACzC,MAAM,gBAAgB,YAAY,cAAc,CAAC,gBAAgB,UAAU,KAAA;EAG3E,MAAM,EAAC,WAAU,IAAI,IAAI,OAAO,OAAO,IAAI,MAAM,CAAC;AAClD,aAAW,OAAO;AAElB,SACE,oBAACC,YAAD;GACE,QAAQ;IACN;IACA;IACA;IACA;IACA;IACA;IACA,OAAO,gBAAgB,eAAe,KAAA;IACvC;GACD,eAAe,gBAAgB,OAAO,KAAA;GAC1B;GACZ,SAAS;GACT,QAAQ,WAAW,kBAAkB,aAAa,YAAY;GACrD;GACE;GACE;GACF;GACD;GACV,CAAA;;AAGN,cAAW,cAAc;AAEzB,QAAO;EAAC;EAAa,YAAA;EAAW;;AAGlC,eAAe,2BAAiE;AAC9E,SAAQ,MAAM,WAAW,EAAE,YACvB,MAAM,8BAA8B,EAAC,SAAS,MAAM,SAAS,EAAC,CAAC,GAC/D,KAAA"}
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} from '#live/constants'\nimport {preconnect} from '#live/preconnect'\nimport {resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport {validateStrictFetchOptions, validateStrictSanityLiveProps} from '#live/strictValidation'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n LivePerspective,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n\n/**\n * Set up Sanity Live for Cache Components. `defineLive` returns `sanityFetch`\n * and `<SanityLive />`, which connect your Sanity client to the Live Content API\n * so cached pages can update in response to fine-grained content changes.\n *\n * With `strict: true`, `perspective` and `stega` become required\n * `sanityFetch` options, and `includeDrafts` becomes required on\n * `<SanityLive />`. Resolve dynamic values from `draftMode()` and `cookies()`\n * outside `'use cache'` boundaries, then pass them into cached components.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * // sanity/live.ts\n * import {cookies, draftMode} from 'next/headers'\n * import {createClient} from 'next-sanity'\n * import {\n * defineLive,\n * resolvePerspectiveFromCookies,\n * type LivePerspective,\n * } from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * strict: true,\n * })\n *\n * export interface DynamicFetchOptions {\n * perspective: LivePerspective\n * stega: boolean\n * }\n *\n * // Resolve dynamic values outside 'use cache' boundaries.\n * export async function getDynamicFetchOptions(): Promise<DynamicFetchOptions> {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (!isDraftMode) {\n * return {perspective: 'published', stega: false}\n * }\n *\n * const jar = await cookies()\n * const perspective = await resolvePerspectiveFromCookies({cookies: jar})\n * return {perspective: perspective ?? 'drafts', stega: true}\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {draftMode} from 'next/headers'\n *\n * import {SanityLive} from '@/sanity/live'\n *\n * export default async function RootLayout({children}: {children: React.ReactNode}) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive includeDrafts={isDraftMode} />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {draftMode} from 'next/headers'\n * import {Suspense} from 'react'\n * import {defineQuery} from 'next-sanity'\n *\n * import {\n * getDynamicFetchOptions,\n * sanityFetch,\n * type DynamicFetchOptions,\n * } from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n * if (isDraftMode) {\n * return (\n * <Suspense fallback={<div>Loading...</div>}>\n * <DynamicPage params={props.params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await props.params\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage(props: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await props.params\n * const {perspective, stega} = await getDynamicFetchOptions()\n *\n * return <CachedPage slug={slug} perspective={perspective} stega={stega} />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * stega,\n * }: {slug: string} & DynamicFetchOptions) {\n * 'use cache'\n *\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * perspective,\n * stega,\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict: true}): {\n sanityFetch: StrictDefinedFetchType\n SanityLive: React.ComponentType<StrictDefinedLiveProps>\n}\n/**\n * Set up Sanity Live. `defineLive` returns `sanityFetch` and `<SanityLive />`,\n * which connect your Sanity client to the Live Content API so pages can serve\n * cached content and update in response to fine-grained content changes.\n *\n * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)\n * @see [Sanity Live](https://www.sanity.io/live)\n *\n * @example\n * ```tsx\n * import {createClient} from 'next-sanity'\n * import {defineLive} from 'next-sanity/live'\n *\n * const client = createClient({\n * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n * useCdn: true,\n * perspective: 'published',\n * })\n * const token = process.env.SANITY_API_READ_TOKEN\n *\n * export const {sanityFetch, SanityLive} = defineLive({\n * client,\n * browserToken: token,\n * serverToken: token,\n * })\n * ```\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import {SanityLive} from '@/sanity/live'\n *\n * export default function RootLayout({children}: {children: React.ReactNode}) {\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <SanityLive />\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // app/[slug]/page.tsx\n * import {defineQuery} from 'next-sanity'\n * import {sanityFetch} from '@/sanity/live'\n *\n * const POSTS_SLUGS_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current]{\"slug\": slug.current}\n * `)\n * const POST_QUERY = defineQuery(`\n * *[_type == \"post\" && slug.current == $slug][0]\n * `)\n *\n * export async function generateStaticParams() {\n * const {data} = await sanityFetch({\n * query: POSTS_SLUGS_QUERY,\n * perspective: 'published',\n * stega: false,\n * })\n *\n * return data\n * }\n *\n * export default async function Page(props: PageProps<'/[slug]'>) {\n * const {slug} = await props.params\n * const {data} = await sanityFetch({\n * query: POST_QUERY,\n * params: {slug},\n * })\n *\n * return <pre>{JSON.stringify(data, null, 2)}</pre>\n * }\n * ```\n *\n * @public\n */\nexport function defineLive(config: DefineLiveOptions & {strict?: false}): {\n sanityFetch: DefinedFetchType\n SanityLive: React.ComponentType<DefinedLiveProps>\n}\nexport function defineLive(config: DefineLiveOptions) {\n const {client: _client, serverToken, browserToken, strict = false} = config\n\n if (!_client) {\n throw new Error('`client` is required for `defineLive` to function')\n }\n\n if (process.env.NODE_ENV === 'development' && !serverToken && serverToken !== false) {\n console.warn(\n 'No `serverToken` provided to `defineLive`. This means that only published content will be fetched and respond to live events. You can silence this warning by setting `serverToken: false`.',\n )\n }\n\n if (process.env.NODE_ENV === 'development' && !browserToken && browserToken !== false) {\n console.warn(\n 'No `browserToken` provided to `defineLive`. This means that live previewing drafts will only work when using the Presentation Tool in your Sanity Studio. To support live previewing drafts stand-alone, provide a `browserToken`. It is shared with the browser so it should only have Viewer rights or lower. You can silence this warning by setting `browserToken: false`.',\n )\n }\n\n const client = _client.withConfig({\n allowReconfigure: false,\n useCdn: true,\n perspective: 'published',\n stega: false,\n })\n const studioUrlDefined = typeof client.config().stega.studioUrl !== 'undefined'\n\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective: _perspective,\n stega: _stega,\n tags = [],\n requestTag = 'next-loader.fetch',\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective: _perspective, stega: _stega})\n }\n const stega = strict\n ? _stega\n : (_stega ?? (serverToken && studioUrlDefined ? (await draftMode()).isEnabled : false))\n const perspective = strict\n ? _perspective\n : (_perspective ?? (serverToken ? await resolveCookiePerspective() : undefined))\n const useCdn = perspective ? perspective === 'published' : undefined\n const isBuildPhase = process.env['NEXT_PHASE'] === PHASE_PRODUCTION_BUILD\n const cacheMode = useCdn !== false && !isBuildPhase ? 'noStale' : undefined\n const token =\n ((perspective && perspective !== 'published') || stega) && serverToken\n ? serverToken\n : undefined\n\n // 1. Fetch the tags first, with an uncached request, but that does not count towards the Sanity API quota\n const {syncTags} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n stega: false,\n resultSourceMap: false,\n returnQuery: false,\n useCdn,\n cacheMode,\n tag: [requestTag, 'fetch-sync-tags'].filter(Boolean).join('.'),\n token,\n })\n\n const cacheTags = [...tags, ...(syncTags?.map((tag) => `${cacheTagPrefix}${tag}`) || [])]\n\n // 2. Then fetch the data, using the fetch cache with specified tags\n const {result, resultSourceMap} = await client.fetch(query, await params, {\n filterResponse: false,\n perspective,\n stega,\n next: {revalidate: false, tags: cacheTags},\n useCdn,\n cacheMode,\n tag: requestTag,\n token,\n })\n return {data: result, sourceMap: resultSourceMap || null, tags: cacheTags}\n }\n\n const SanityLive: React.ComponentType<DefinedLiveProps> = async function SanityLive(props) {\n if (strict) {\n validateStrictSanityLiveProps(props)\n }\n const {\n includeDrafts: _includeDrafts,\n requestTag = 'next-loader.live',\n waitFor,\n\n action,\n onError,\n onWelcome,\n onReconnect,\n onRestart,\n onGoAway,\n } = props\n const {projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix} =\n client.config()\n\n const includeDrafts =\n typeof browserToken === 'string' &&\n !!browserToken &&\n (_includeDrafts ?? (await draftMode()).isEnabled)\n const shouldWaitFor = waitFor === 'function' && !includeDrafts ? waitFor : undefined\n\n // Preconnect to the Live Event API origin early, as the Sanity API is almost always on a different origin than the app\n preconnect(client)\n\n return (\n <SanityLiveClientComponent\n config={{\n projectId,\n dataset,\n apiHost,\n apiVersion,\n useProjectHostname,\n requestTagPrefix,\n token: includeDrafts ? browserToken : undefined,\n }}\n includeDrafts={includeDrafts ? true : undefined}\n requestTag={requestTag}\n waitFor={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? 'refresh' : revalidateSyncTagsAction)}\n onError={onError}\n onWelcome={onWelcome}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onGoAway={onGoAway}\n />\n )\n }\n SanityLive.displayName = 'SanityLiveServerComponent'\n\n return {sanityFetch, SanityLive}\n}\n\nasync function resolveCookiePerspective(): Promise<LivePerspective | undefined> {\n return (await draftMode()).isEnabled\n ? await resolvePerspectiveFromCookies({cookies: await cookies()})\n : undefined\n}\n"],"mappings":";;;;;;;;;AAgQA,SAAgB,WAAW,QAA2B;CACpD,MAAM,EAAC,QAAQ,SAAS,aAAa,cAAc,SAAS,UAAS;AAErE,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,oDAAoD;AAGtE,KAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,eAAe,gBAAgB,MAC5E,SAAQ,KACN,8LACD;AAGH,KAAI,QAAQ,IAAI,aAAa,iBAAiB,CAAC,gBAAgB,iBAAiB,MAC9E,SAAQ,KACN,iXACD;CAGH,MAAM,SAAS,QAAQ,WAAW;EAChC,kBAAkB;EAClB,QAAQ;EACR,aAAa;EACb,OAAO;EACR,CAAC;CACF,MAAM,mBAAmB,OAAO,OAAO,QAAQ,CAAC,MAAM,cAAc;CAEpE,MAAM,cAAgC,eAAe,YAAY,EAC/D,OACA,SAAS,EAAE,EACX,aAAa,cACb,OAAO,QACP,OAAO,EAAE,EACT,aAAa,uBACZ;AACD,MAAI,OACF,4BAA2B;GAAC,aAAa;GAAc,OAAO;GAAO,CAAC;EAExE,MAAM,QAAQ,SACV,SACC,WAAW,eAAe,oBAAoB,MAAM,WAAW,EAAE,YAAY;EAClF,MAAM,cAAc,SAChB,eACC,iBAAiB,cAAc,MAAM,0BAA0B,GAAG,KAAA;EACvE,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;EAGN,MAAM,EAAC,aAAY,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GACzD,gBAAgB;GAChB;GACA,OAAO;GACP,iBAAiB;GACjB,aAAa;GACb;GACA;GACA,KAAK,CAAC,YAAY,kBAAkB,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;GAC9D;GACD,CAAC;EAEF,MAAM,YAAY,CAAC,GAAG,MAAM,GAAI,UAAU,KAAK,QAAQ,UAAoB,MAAM,IAAI,EAAE,CAAE;EAGzF,MAAM,EAAC,QAAQ,oBAAmB,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GACxE,gBAAgB;GAChB;GACA;GACA,MAAM;IAAC,YAAY;IAAO,MAAM;IAAU;GAC1C;GACA;GACA,KAAK;GACL;GACD,CAAC;AACF,SAAO;GAAC,MAAM;GAAQ,WAAW,mBAAmB;GAAM,MAAM;GAAU;;CAG5E,MAAMA,eAAoD,eAAeA,aAAW,OAAO;AACzF,MAAI,OACF,+BAA8B,MAAM;EAEtC,MAAM,EACJ,eAAe,gBACf,aAAa,oBACb,SAEA,QACA,SACA,WACA,aACA,WACA,aACE;EACJ,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,QAAQ;EAEjB,MAAM,gBACJ,OAAO,iBAAiB,YACxB,CAAC,CAAC,iBACD,mBAAmB,MAAM,WAAW,EAAE;EACzC,MAAM,gBAAgB,YAAY,cAAc,CAAC,gBAAgB,UAAU,KAAA;AAG3E,aAAW,OAAO;AAElB,SACE,oBAACC,YAAD;GACE,QAAQ;IACN;IACA;IACA;IACA;IACA;IACA;IACA,OAAO,gBAAgB,eAAe,KAAA;IACvC;GACD,eAAe,gBAAgB,OAAO,KAAA;GAC1B;GACZ,SAAS;GACT,QAAQ,WAAW,kBAAkB,aAAa,YAAY;GACrD;GACE;GACE;GACF;GACD;GACV,CAAA;;AAGN,cAAW,cAAc;AAEzB,QAAO;EAAC;EAAa,YAAA;EAAW;;AAGlC,eAAe,2BAAiE;AAC9E,SAAQ,MAAM,WAAW,EAAE,YACvB,MAAM,8BAA8B,EAAC,SAAS,MAAM,SAAS,EAAC,CAAC,GAC/D,KAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"parseTags.d.ts","names":[],"sources":["../src/live/shared/resolvePerspectiveFromCookies.ts","../src/live/shared/constants.ts","../src/live/shared/parseTags.ts"],"mappings":";;;;;AAiEA;;;;;;;;;;;;;;;;;;;;;;ACzDA;;;;;;ACN6B;;;;;;;;;;;;;;;;;;AA6B7B;;;;;;;;;;;iBFkCsB,6BAAA,CAAA;EACpB,OAAA,EAAS;AAAA;EAET,OAAA,EAAS,OAAA,CAAQ,UAAA,QAAkB,OAAA;AAAA,IACjC,OAAA,CAAQ,eAAA;AAAA,cC7DC,cAAA;AAAA,UCJH,UAAA;EACR,IAAA,YAAgB,cAAA,GAAiB,OAAA;EACjC,iBAAA,EAAmB,OAAA;EACnB,MAAA,SAAe,cAAA;AAAA;;;;;;;;;;;;;;;;;;;;ADCjB;;iBCuBgB,SAAA,CAAU,UAAA,YAAsB,UAAA"}
1
+ {"version":3,"file":"parseTags.d.ts","names":[],"sources":["../src/live/shared/resolvePerspectiveFromCookies.ts","../src/live/shared/constants.ts","../src/live/shared/parseTags.ts"],"mappings":";;;;;AAiEA;;;;;;;;;;;;;;;;;;;;;;AC9DA;;;;;;ACD6B;;;;;;;;;;;;;;;;;;AA6B7B;;;;;;;;;;;iBFkCsB,6BAAA,CAAA;EACpB,OAAA,EAAS;AAAA;EAET,OAAA,EAAS,OAAA,CAAQ,UAAA,QAAkB,OAAA;AAAA,IACjC,OAAA,CAAQ,eAAA;AAAA,cClEC,cAAA;AAAA,UCCH,UAAA;EACR,IAAA,YAAgB,cAAA,GAAiB,OAAA;EACjC,iBAAA,EAAmB,OAAA;EACnB,MAAA,SAAe,cAAA;AAAA;;;;;;;;;;;;;;;;;;;;ADJjB;;iBC4BgB,SAAA,CAAU,UAAA,YAAsB,UAAA"}
@@ -1,6 +1,14 @@
1
1
  import { t as sanitizePerspective } from "./sanitizePerspective.js";
2
2
  import { perspectiveCookieName } from "@sanity/preview-url-secret/constants";
3
+ import { preconnect } from "react-dom";
3
4
  import { generateHelpUrl } from "@sanity/generate-help-url";
5
+ /**
6
+ * Uses the React DOM `preconnect` function to preconnect to the Live Event API origin early, Next.js will set the right headers and meta tags to speed up the connection.
7
+ */
8
+ function preconnect$1(client) {
9
+ const { origin } = new URL(client.getUrl("", false));
10
+ preconnect(origin);
11
+ }
4
12
  function validateStrictSanityLiveProps(props) {
5
13
  if (typeof props.includeDrafts !== "boolean") throw new Error(`<SanityLive> requires an explicit \`includeDrafts\` prop (true or false) when \`strict: true\` is set on \`defineLive\`.\n\nMore information: ${generateHelpUrl("next-sanity-live-strict")}`, { cause: props });
6
14
  }
@@ -70,6 +78,6 @@ function validateStrictFetchOptions(options) {
70
78
  async function resolvePerspectiveFromCookies({ cookies: jar }) {
71
79
  return jar.has(perspectiveCookieName) ? sanitizePerspective(jar.get(perspectiveCookieName)?.value, "drafts") : "drafts";
72
80
  }
73
- export { validateStrictFetchOptions as n, validateStrictSanityLiveProps as r, resolvePerspectiveFromCookies as t };
81
+ export { preconnect$1 as i, validateStrictFetchOptions as n, validateStrictSanityLiveProps as r, resolvePerspectiveFromCookies as t };
74
82
 
75
83
  //# sourceMappingURL=resolvePerspectiveFromCookies.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolvePerspectiveFromCookies.js","names":[],"sources":["../src/live/shared/strictValidation.ts","../src/live/shared/resolvePerspectiveFromCookies.ts"],"sourcesContent":["import {generateHelpUrl} from '@sanity/generate-help-url'\n\nexport function validateStrictSanityLiveProps(props: {includeDrafts?: unknown}): void {\n if (typeof props.includeDrafts !== 'boolean') {\n throw new Error(\n `<SanityLive> requires an explicit \\`includeDrafts\\` prop (true or false) when \\`strict: true\\` is set on \\`defineLive\\`.\\n\\nMore information: ${generateHelpUrl('next-sanity-live-strict')}`,\n {cause: props},\n )\n }\n}\n\nexport function validateStrictFetchOptions(options: {\n perspective?: unknown\n stega?: unknown\n}): void {\n if (typeof options.perspective === 'undefined' || options.perspective === null) {\n throw new Error(\n `sanityFetch() requires an explicit \\`perspective\\` option when \\`strict: true\\` is set on \\`defineLive\\`.\\n\\nMore information: ${generateHelpUrl('next-sanity-fetch-strict')}`,\n {cause: options},\n )\n }\n if (typeof options.stega !== 'boolean') {\n throw new Error(\n `sanityFetch() requires an explicit \\`stega\\` option (true or false) when \\`strict: true\\` is set on \\`defineLive\\`.\\n\\nMore information: ${generateHelpUrl('next-sanity-fetch-strict')}`,\n {cause: options},\n )\n }\n}\n","import {perspectiveCookieName} from '@sanity/preview-url-secret/constants'\nimport type {cookies} from 'next/headers'\n\nimport {sanitizePerspective} from '#live/sanitizePerspective'\nimport type {LivePerspective} from '#live/types'\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 async function resolvePerspectiveFromCookies({\n cookies: jar,\n}: {\n cookies: Awaited<ReturnType<typeof cookies>>\n}): Promise<LivePerspective> {\n return jar.has(perspectiveCookieName)\n ? sanitizePerspective(jar.get(perspectiveCookieName)?.value, 'drafts')\n : 'drafts'\n}\n"],"mappings":";;;AAEA,SAAgB,8BAA8B,OAAwC;AACpF,KAAI,OAAO,MAAM,kBAAkB,UACjC,OAAM,IAAI,MACR,iJAAiJ,gBAAgB,0BAA0B,IAC3L,EAAC,OAAO,OAAM,CACf;;AAIL,SAAgB,2BAA2B,SAGlC;AACP,KAAI,OAAO,QAAQ,gBAAgB,eAAe,QAAQ,gBAAgB,KACxE,OAAM,IAAI,MACR,kIAAkI,gBAAgB,2BAA2B,IAC7K,EAAC,OAAO,SAAQ,CACjB;AAEH,KAAI,OAAO,QAAQ,UAAU,UAC3B,OAAM,IAAI,MACR,4IAA4I,gBAAgB,2BAA2B,IACvL,EAAC,OAAO,SAAQ,CACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACwCL,eAAsB,8BAA8B,EAClD,SAAS,OAGkB;AAC3B,QAAO,IAAI,IAAI,sBAAsB,GACjC,oBAAoB,IAAI,IAAI,sBAAsB,EAAE,OAAO,SAAS,GACpE"}
1
+ {"version":3,"file":"resolvePerspectiveFromCookies.js","names":["preconnect"],"sources":["../src/live/shared/preconnect.ts","../src/live/shared/strictValidation.ts","../src/live/shared/resolvePerspectiveFromCookies.ts"],"sourcesContent":["import type {SanityClient} from 'next-sanity'\nimport {preconnect as reactDomPreconnect} from 'react-dom'\n\n/**\n * Uses the React DOM `preconnect` function to preconnect to the Live Event API origin early, Next.js will set the right headers and meta tags to speed up the connection.\n */\nexport function preconnect(client: SanityClient): void {\n const {origin} = new URL(client.getUrl('', false))\n reactDomPreconnect(origin)\n}\n","import {generateHelpUrl} from '@sanity/generate-help-url'\n\nexport function validateStrictSanityLiveProps(props: {includeDrafts?: unknown}): void {\n if (typeof props.includeDrafts !== 'boolean') {\n throw new Error(\n `<SanityLive> requires an explicit \\`includeDrafts\\` prop (true or false) when \\`strict: true\\` is set on \\`defineLive\\`.\\n\\nMore information: ${generateHelpUrl('next-sanity-live-strict')}`,\n {cause: props},\n )\n }\n}\n\nexport function validateStrictFetchOptions(options: {\n perspective?: unknown\n stega?: unknown\n}): void {\n if (typeof options.perspective === 'undefined' || options.perspective === null) {\n throw new Error(\n `sanityFetch() requires an explicit \\`perspective\\` option when \\`strict: true\\` is set on \\`defineLive\\`.\\n\\nMore information: ${generateHelpUrl('next-sanity-fetch-strict')}`,\n {cause: options},\n )\n }\n if (typeof options.stega !== 'boolean') {\n throw new Error(\n `sanityFetch() requires an explicit \\`stega\\` option (true or false) when \\`strict: true\\` is set on \\`defineLive\\`.\\n\\nMore information: ${generateHelpUrl('next-sanity-fetch-strict')}`,\n {cause: options},\n )\n }\n}\n","import {perspectiveCookieName} from '@sanity/preview-url-secret/constants'\nimport type {cookies} from 'next/headers'\n\nimport {sanitizePerspective} from '#live/sanitizePerspective'\nimport type {LivePerspective} from '#live/types'\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 async function resolvePerspectiveFromCookies({\n cookies: jar,\n}: {\n cookies: Awaited<ReturnType<typeof cookies>>\n}): Promise<LivePerspective> {\n return jar.has(perspectiveCookieName)\n ? sanitizePerspective(jar.get(perspectiveCookieName)?.value, 'drafts')\n : 'drafts'\n}\n"],"mappings":";;;;;;;AAMA,SAAgBA,aAAW,QAA4B;CACrD,MAAM,EAAC,WAAU,IAAI,IAAI,OAAO,OAAO,IAAI,MAAM,CAAC;AAClD,YAAmB,OAAO;;ACN5B,SAAgB,8BAA8B,OAAwC;AACpF,KAAI,OAAO,MAAM,kBAAkB,UACjC,OAAM,IAAI,MACR,iJAAiJ,gBAAgB,0BAA0B,IAC3L,EAAC,OAAO,OAAM,CACf;;AAIL,SAAgB,2BAA2B,SAGlC;AACP,KAAI,OAAO,QAAQ,gBAAgB,eAAe,QAAQ,gBAAgB,KACxE,OAAM,IAAI,MACR,kIAAkI,gBAAgB,2BAA2B,IAC7K,EAAC,OAAO,SAAQ,CACjB;AAEH,KAAI,OAAO,QAAQ,UAAU,UAC3B,OAAM,IAAI,MACR,4IAA4I,gBAAgB,2BAA2B,IACvL,EAAC,OAAO,SAAQ,CACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACwCL,eAAsB,8BAA8B,EAClD,SAAS,OAGkB;AAC3B,QAAO,IAAI,IAAI,sBAAsB,GACjC,oBAAoB,IAAI,IAAI,sBAAsB,EAAE,OAAO,SAAS,GACpE"}
package/dist/types.d.ts CHANGED
@@ -23,29 +23,59 @@ type DefinedFetchType = <const QueryString extends string>(options: {
23
23
  /**
24
24
  * Content perspective used for the fetch.
25
25
  *
26
- * @defaultValue The configured client perspective, usually `'published'`.
26
+ * @remarks
27
+ * Requires `serverToken` to be configured in `defineLive()`
28
+ *
29
+ * @defaultValue
30
+ * The default is `'published'` unless
31
+ * - `Cache Components` are disabled
32
+ * - `defineLive()` was given a `serverToken`
33
+ * - `defineLive()` is not set to `strict: true`
34
+ * - `draftMode()` is enabled
35
+ *
36
+ * If all of the above conditions are met, then the default value will be resolved from attempting to read the `'sanity-preview-perspective'` cookie and fall back to `'drafts'` if not set
27
37
  */
28
38
  perspective?: LivePerspective;
29
39
  /**
30
40
  * Enables stega encoding of the data. This is typically only used in draft
31
41
  * mode with `perspective: 'drafts'` and `@sanity/visual-editing`.
32
42
  *
33
- * @defaultValue `false`
43
+ * @remarks
44
+ * Requires `serverToken` to be configured in `defineLive()`
45
+ *
46
+ * @defaultValue
47
+ * The default is `false` unless
48
+ * - `Cache Components` are disabled
49
+ * - `defineLive()` was given a `serverToken`
50
+ * - `defineLive()` is not set to `strict: true`
51
+ * - `defineLive()` was given a `client` that defines `stega.studioUrl`
52
+ * - `draftMode()` is enabled
53
+ *
54
+ * If all of the above conditions are met, then the default value will be `true`
34
55
  */
35
56
  stega?: boolean;
36
57
  /**
37
58
  * Additional cache tags to associate with this fetch.
38
59
  *
39
- * `sanityFetch` automatically adds Sanity Live sync tags for the query. Use
40
- * this for custom tags that should also be invalidated by your own server
41
- * actions, for example after a mutation that needs read-your-own-write UI.
60
+ * @remarks
61
+ * The default behavior will always add cache tags automatically for the query based on the `syncTags` response returned by Content Lake.
62
+ * You only need to define custom tags if you also mutate content in a server action and need to implement read-your-own-write UI.
63
+ * @see https://nextjs.org/docs/app/api-reference/functions/updateTag#server-action-with-read-your-own-writes
64
+ *
65
+ * When `cacheComponents: false` your custom tags are appended to the underlying `next.tags` array on the `fetch` request and are subject to the tag length and max tag items limits of Next.js.
66
+ * @see https://nextjs.org/docs/app/api-reference/functions/fetch#optionsnexttags
67
+ * When `cacheComponents: true` your custom tags are appended to the underlying `cacheTag()` call and are subject to the tag length and max tag items limits of Next.js.
68
+ * @see https://nextjs.org/docs/app/api-reference/functions/cacheTag#good-to-know
42
69
  */
43
70
  tags?: string[];
44
71
  /**
45
72
  * Request tag used to identify the request in Sanity Content Lake logs.
46
73
  *
47
74
  * @see https://www.sanity.io/docs/reference-api-request-tags
48
- * @defaultValue `'next-loader.fetch'` or `'next-loader.fetch.cache-components'`
75
+ *
76
+ * @defaultValue
77
+ * If `cacheComponents: true` then the default value is `'next-loader.fetch.cache-components'`
78
+ * otherwise it's `'next-loader.fetch'`
49
79
  */
50
80
  requestTag?: string;
51
81
  }) => Promise<{
@@ -59,20 +89,29 @@ type DefinedFetchType = <const QueryString extends string>(options: {
59
89
  */
60
90
  interface DefinedLiveProps {
61
91
  /**
62
- * Include draft and content release version events in the live connection.
92
+ * Include draft and content release version events in the live connection. Otherwise only events for published content are included.
63
93
  *
64
- * Set this to `true` when draft mode is enabled. A `browserToken` must be
65
- * configured in `defineLive()` for draft events to be included.
94
+ * @remarks
95
+ * Requires `browserToken` to be configured in `defineLive()`
66
96
  *
67
- * @defaultValue `false`
97
+ * @defaultValue
98
+ * The default is `false` unless
99
+ * - `Cache Components` are disabled
100
+ * - `defineLive()` was given a `browserToken`
101
+ * - `defineLive()` is not set to `strict: true`
102
+ * - `draftMode()` is enabled
103
+ *
104
+ * If all of the above conditions are met, then the default value will be `true`
68
105
  */
69
106
  includeDrafts?: boolean;
70
107
  /**
71
- * Request tag used to identify the live EventSource request in Sanity Content
72
- * Lake logs.
108
+ * Request tag used to identify the live EventSource request in Sanity Content Lake logs.
73
109
  *
74
110
  * @see https://www.sanity.io/docs/reference-api-request-tags
75
- * @defaultValue `'next-loader.live'` or `'next-loader.live.cache-components'`
111
+ *
112
+ * @defaultValue
113
+ * If `cacheComponents: true` then the default value is `'next-loader.live.cache-components'`
114
+ * otherwise it's `'next-loader.live'`
76
115
  */
77
116
  requestTag?: string;
78
117
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../src/live/shared/types.ts"],"mappings":";;AAcA;;;KAAY,eAAA,GAAkB,OAAA,CAAQ,iBAAA;;AAStC;;;;;;KAAY,gBAAA,sCAAsD,OAAA;;;;EAIhE,KAAA,EAAO,WAAA;;;;EAIP,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,WAAA;;;;;;EAM/B,WAAA,GAAc,eAAA;;;;;;;EAOd,KAAA;;;;;;;;EAQA,IAAA;EAkBF;;;;;;EAXE,UAAA;AAAA,MACI,OAAA;EACJ,IAAA,EAAM,YAAA,CAAa,WAAA;EACnB,SAAA,EAAW,gBAAA;EACX,IAAA;AAAA;;;;;UAOe,gBAAA;;;;;;;;;EASf,aAAA;;;AAiDF;;;;;EAzCE,UAAA;;;;;EAKA,OAAA;EAyEF;;;;;;EAlEE,MAAA,GAAS,gBAAA;;;AA0EX;;;EApEE,OAAA,GAAU,iBAAA;;;;;EAKV,SAAA,GAAY,mBAAA;;;;;EAKZ,WAAA,GAAc,qBAAA;;;;;EAKd,SAAA,GAAY,mBAAA;;;;;EAKZ,QAAA,GAAW,kBAAA;AAAA;AAAA,UAGI,iBAAA;;;;EAIf,MAAA,EAAQ,YAAA;;;;;;;EAOR,WAAA;EA+Ce;;;;AAcjB;;;EArDE,YAAA;EA8DA;AAiBF;;;;;AASA;;;;EA7EE,MAAA;AAAA;;;;AAqFF;UA9EiB,sBAAA,SAA+B,IAAA,CAAK,gBAAA;EACnD,aAAA;AAAA;;;;;KAOU,sBAAA,sCAA4D,OAAA;EACtE,KAAA,EAAO,WAAA;EACP,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,WAAA;EAC/B,WAAA,EAAa,eAAA;EACb,KAAA;EACA,IAAA;EACA,UAAA;AAAA,MACI,OAAA;EACJ,IAAA,EAAM,YAAA,CAAa,WAAA;EACnB,SAAA,EAAW,gBAAA;EACX,IAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,IAAA,CAC1C,uBAAA;;;;UAae,iBAAA;;;;;EAKf,aAAA;;;;EAIA,OAAA;AAAA;;AAsDF;;;;;;;;;;;;;KArCY,gBAAA,KAAqB,UAAA,cAAwB,OAAA;;;;;AAmDzD;;;;KA1CY,iBAAA,KAAsB,KAAA,WAAgB,OAAA,EAAS,iBAAA;;;;;;;;KAQ/C,mBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,YACC,OAAA;;;;;;KAMA,qBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,YACC,OAAA;;;;;;;KAQA,mBAAA,KAEN,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,YACC,OAAA;;;;;;;;;KAUJ,kBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,EACT,kBAAA,GAAqB,QAAA,6BACX,OAAA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../src/live/shared/types.ts"],"mappings":";;AAcA;;;KAAY,eAAA,GAAkB,OAAA,CAAQ,iBAAA;;AAStC;;;;;;KAAY,gBAAA,sCAAsD,OAAA;;;;EAIhE,KAAA,EAAO,WAAA;;;;EAIP,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,WAAA;;;;;;;;;;;;;;;;EAgB/B,WAAA,GAAc,eAAA;;;;;;AAqDhB;;;;;;;;;;;;EAnCE,KAAA;;;;;;;;;;;;;;EAcA,IAAA;EAqFW;AAGb;;;;;;;;EA9EE,UAAA;AAAA,MACI,OAAA;EACJ,IAAA,EAAM,YAAA,CAAa,WAAA;EACnB,SAAA,EAAW,gBAAA;EACX,IAAA;AAAA;;;;;UAOe,gBAAA;EAyGf;AAOF;;;;;;;;;;;;;;EAhGE,aAAA;;;;;;;;;;EAUA,UAAA;;;;;EAKA,OAAA;;;;;;;EAOA,MAAA,GAAS,gBAAA;EAuFM;;;;AAcjB;EA/FE,OAAA,GAAU,iBAAA;;;;AAyHZ;EApHE,SAAA,GAAY,mBAAA;;;;AA6Hd;EAxHE,WAAA,GAAc,qBAAA;;;;;EAKd,SAAA,GAAY,mBAAA;;;AA2Hd;;EAtHE,QAAA,GAAW,kBAAA;AAAA;AAAA,UAGI,iBAAA;;;;EAIf,MAAA,EAAQ,YAAA;;;;;;;EAOR,WAAA;;;AAiHF;;;;;EAzGE,YAAA;;;;;;;;;;;EAWA,MAAA;AAAA;AAyGF;;;;AAAA,UAlGiB,sBAAA,SAA+B,IAAA,CAAK,gBAAA;EACnD,aAAA;AAAA;;;;;KAOU,sBAAA,sCAA4D,OAAA;EACtE,KAAA,EAAO,WAAA;EACP,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,WAAA;EAC/B,WAAA,EAAa,eAAA;EACb,KAAA;EACA,IAAA;EACA,UAAA;AAAA,MACI,OAAA;EACJ,IAAA,EAAM,YAAA,CAAa,WAAA;EACnB,SAAA,EAAW,gBAAA;EACX,IAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,IAAA,CAC1C,uBAAA;;;;UAae,iBAAA;;;;;EAKf,aAAA;;;;EAIA,OAAA;AAAA;;;;;;;;;;;;;;;KAiBU,gBAAA,KAAqB,UAAA,cAAwB,OAAA;;;;;;;;;KAS7C,iBAAA,KAAsB,KAAA,WAAgB,OAAA,EAAS,iBAAA;;;;;;;;KAQ/C,mBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,YACC,OAAA;;;;;;KAMA,qBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,YACC,OAAA;;;;;;;KAQA,mBAAA,KAEN,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,YACC,OAAA;;;;;;;;;KAUJ,kBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,iBAAA,EACT,kBAAA,GAAqB,QAAA,6BACX,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-sanity",
3
- "version": "13.0.0-cache-components.61",
3
+ "version": "13.0.0",
4
4
  "description": "Sanity.io toolkit for Next.js",
5
5
  "keywords": [
6
6
  "live",
@@ -64,22 +64,22 @@
64
64
  "@sanity/preview-url-secret": "^4.0.6",
65
65
  "@sanity/visual-editing": "^5.3.6",
66
66
  "@sanity/webhook": "^4.0.4",
67
- "groq": "^5.25.1",
67
+ "groq": "^5.26.0",
68
68
  "history": "^5.3.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@sanity/tsconfig": "^2.1.0",
72
72
  "@types/js-yaml": "^4.0.9",
73
73
  "@types/node": "^24.12.4",
74
- "@types/react": "^19.2.14",
74
+ "@types/react": "^19.2.15",
75
75
  "@types/react-dom": "^19.2.3",
76
76
  "@vercel/stega": "^1.1.0",
77
77
  "@vitejs/plugin-react": "^6.0.2",
78
- "@vitest/browser-playwright": "^4.1.6",
79
- "@vitest/coverage-v8": "^4.1.6",
78
+ "@vitest/browser-playwright": "^4.1.7",
79
+ "@vitest/coverage-v8": "^4.1.7",
80
80
  "js-yaml": "^4.1.1",
81
81
  "msw": "^2.14.6",
82
- "next": "16.3.0-canary.22",
82
+ "next": "16.3.0-canary.24",
83
83
  "publint": "^0.3.21",
84
84
  "react": "^19.2.6",
85
85
  "react-dom": "^19.2.6",
@@ -88,7 +88,7 @@
88
88
  "typedoc": "^0.28.19",
89
89
  "typescript": "5.9.3",
90
90
  "vite": "^8.0.13",
91
- "vitest": "^4.1.6",
91
+ "vitest": "^4.1.7",
92
92
  "vitest-browser-react": "^2.2.0",
93
93
  "vitest-package-exports": "^1.2.0"
94
94
  },
@@ -97,7 +97,7 @@
97
97
  "next": "^16.0.0-0",
98
98
  "react": "^19.2.3",
99
99
  "react-dom": "^19.2.3",
100
- "sanity": "^5.25.1",
100
+ "sanity": "^5.26.0",
101
101
  "styled-components": "^6.1"
102
102
  },
103
103
  "engines": {