next-sanity 13.0.0-cache-components.42 → 13.0.0-cache-components.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/SanityLive.js +5 -3
  2. package/dist/SanityLive.js.map +1 -1
  3. package/dist/isCorsOriginError.js.map +1 -1
  4. package/dist/live/client-components/index.d.ts +7 -8
  5. package/dist/live/client-components/index.d.ts.map +1 -1
  6. package/dist/live/client-components/index.js +1 -1
  7. package/dist/live/client-components/index.js.map +1 -1
  8. package/dist/live/conditions/default/index.d.ts +226 -4
  9. package/dist/live/conditions/default/index.d.ts.map +1 -1
  10. package/dist/live/conditions/default/index.js +0 -4
  11. package/dist/live/conditions/default/index.js.map +1 -1
  12. package/dist/live/conditions/next-js/index.d.ts +232 -2
  13. package/dist/live/conditions/next-js/index.d.ts.map +1 -1
  14. package/dist/live/conditions/next-js/index.js +2 -1
  15. package/dist/live/conditions/next-js/index.js.map +1 -1
  16. package/dist/live/conditions/react-server/index.d.ts +232 -2
  17. package/dist/live/conditions/react-server/index.d.ts.map +1 -1
  18. package/dist/live/conditions/react-server/index.js +2 -1
  19. package/dist/live/conditions/react-server/index.js.map +1 -1
  20. package/dist/live/server-actions/{index.default.d.ts → index.d.ts} +1 -1
  21. package/dist/live/server-actions/index.d.ts.map +1 -0
  22. package/dist/live/server-actions/{index.next-js.js → index.js} +1 -1
  23. package/dist/live/server-actions/index.js.map +1 -0
  24. package/dist/types.d.ts +155 -77
  25. package/dist/types.d.ts.map +1 -1
  26. package/package.json +4 -10
  27. package/dist/live/server-actions/index.default.d.ts.map +0 -1
  28. package/dist/live/server-actions/index.default.js +0 -27
  29. package/dist/live/server-actions/index.default.js.map +0 -1
  30. package/dist/live/server-actions/index.next-js.d.ts +0 -11
  31. package/dist/live/server-actions/index.next-js.d.ts.map +0 -1
  32. package/dist/live/server-actions/index.next-js.js.map +0 -1
@@ -1,17 +1,247 @@
1
1
  import { t as isCorsOriginError } from "../../../isCorsOriginError.js";
2
- import { d as StrictDefinedFetchType, f as StrictDefinedLiveProps, i as LivePerspective, n as DefinedFetchType, r as DefinedLiveProps, t as DefineLiveOptions } from "../../../types.js";
2
+ import { c as SanityLiveOnError, d as SanityLiveOnRestart, f as SanityLiveOnWelcome, i as LivePerspective, l as SanityLiveOnGoaway, m as StrictDefinedLiveProps, n as DefinedFetchType, o as SanityLiveAction, p as StrictDefinedFetchType, r as DefinedLiveProps, s as SanityLiveActionContext, t as DefineLiveOptions, u as SanityLiveOnReconnect } from "../../../types.js";
3
3
  import { n as resolvePerspectiveFromCookies, t as parseTags } from "../../../parseTags.js";
4
+ /**
5
+ * Set up Sanity Live for Cache Components. `defineLive` returns `sanityFetch`
6
+ * and `<SanityLive />`, which connect your Sanity client to the Live Content API
7
+ * so cached pages can update in response to fine-grained content changes.
8
+ *
9
+ * With `strict: true`, `perspective` and `stega` become required
10
+ * `sanityFetch` options, and `includeDrafts` becomes required on
11
+ * `<SanityLive />`. Resolve dynamic values from `draftMode()` and `cookies()`
12
+ * outside `'use cache'` boundaries, then pass them into cached components.
13
+ *
14
+ * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)
15
+ * @see [Sanity Live](https://www.sanity.io/live)
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * // sanity/live.ts
20
+ * import {cookies, draftMode} from 'next/headers'
21
+ * import {createClient} from 'next-sanity'
22
+ * import {
23
+ * defineLive,
24
+ * resolvePerspectiveFromCookies,
25
+ * type LivePerspective,
26
+ * } from 'next-sanity/live'
27
+ *
28
+ * const client = createClient({
29
+ * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
30
+ * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
31
+ * useCdn: true,
32
+ * perspective: 'published',
33
+ * })
34
+ * const token = process.env.SANITY_API_READ_TOKEN
35
+ *
36
+ * export const {sanityFetch, SanityLive} = defineLive({
37
+ * client,
38
+ * browserToken: token,
39
+ * serverToken: token,
40
+ * strict: true,
41
+ * })
42
+ *
43
+ * export interface DynamicFetchOptions {
44
+ * perspective: LivePerspective
45
+ * stega: boolean
46
+ * }
47
+ *
48
+ * // Resolve dynamic values outside 'use cache' boundaries.
49
+ * export async function getDynamicFetchOptions(): Promise<DynamicFetchOptions> {
50
+ * const {isEnabled: isDraftMode} = await draftMode()
51
+ * if (!isDraftMode) {
52
+ * return {perspective: 'published', stega: false}
53
+ * }
54
+ *
55
+ * const jar = await cookies()
56
+ * const perspective = await resolvePerspectiveFromCookies({cookies: jar})
57
+ * return {perspective: perspective ?? 'drafts', stega: true}
58
+ * }
59
+ * ```
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * // app/layout.tsx
64
+ * import {draftMode} from 'next/headers'
65
+ *
66
+ * import {SanityLive} from '@/sanity/live'
67
+ *
68
+ * export default async function RootLayout({children}: {children: React.ReactNode}) {
69
+ * const {isEnabled: isDraftMode} = await draftMode()
70
+ *
71
+ * return (
72
+ * <html lang="en">
73
+ * <body>
74
+ * {children}
75
+ * <SanityLive includeDrafts={isDraftMode} />
76
+ * </body>
77
+ * </html>
78
+ * )
79
+ * }
80
+ * ```
81
+ *
82
+ * @example
83
+ * ```tsx
84
+ * // app/[slug]/page.tsx
85
+ * import {draftMode} from 'next/headers'
86
+ * import {Suspense} from 'react'
87
+ * import {defineQuery} from 'next-sanity'
88
+ *
89
+ * import {
90
+ * getDynamicFetchOptions,
91
+ * sanityFetch,
92
+ * type DynamicFetchOptions,
93
+ * } from '@/sanity/live'
94
+ *
95
+ * const POSTS_SLUGS_QUERY = defineQuery(`
96
+ * *[_type == "post" && slug.current]{"slug": slug.current}
97
+ * `)
98
+ * const POST_QUERY = defineQuery(`
99
+ * *[_type == "post" && slug.current == $slug][0]
100
+ * `)
101
+ *
102
+ * export async function generateStaticParams() {
103
+ * const {data} = await sanityFetch({
104
+ * query: POSTS_SLUGS_QUERY,
105
+ * perspective: 'published',
106
+ * stega: false,
107
+ * })
108
+ *
109
+ * return data
110
+ * }
111
+ *
112
+ * export default async function Page(props: PageProps<'/[slug]'>) {
113
+ * const {isEnabled: isDraftMode} = await draftMode()
114
+ * if (isDraftMode) {
115
+ * return (
116
+ * <Suspense fallback={<div>Loading...</div>}>
117
+ * <DynamicPage params={props.params} />
118
+ * </Suspense>
119
+ * )
120
+ * }
121
+ *
122
+ * const {slug} = await props.params
123
+ * return <CachedPage slug={slug} perspective="published" stega={false} />
124
+ * }
125
+ *
126
+ * async function DynamicPage(props: Pick<PageProps<'/[slug]'>, 'params'>) {
127
+ * const {slug} = await props.params
128
+ * const {perspective, stega} = await getDynamicFetchOptions()
129
+ *
130
+ * return <CachedPage slug={slug} perspective={perspective} stega={stega} />
131
+ * }
132
+ *
133
+ * async function CachedPage({
134
+ * slug,
135
+ * perspective,
136
+ * stega,
137
+ * }: {slug: string} & DynamicFetchOptions) {
138
+ * 'use cache'
139
+ *
140
+ * const {data} = await sanityFetch({
141
+ * query: POST_QUERY,
142
+ * params: {slug},
143
+ * perspective,
144
+ * stega,
145
+ * })
146
+ *
147
+ * return <pre>{JSON.stringify(data, null, 2)}</pre>
148
+ * }
149
+ * ```
150
+ *
151
+ * @public
152
+ */
4
153
  declare function defineLive(config: DefineLiveOptions & {
5
154
  strict: true;
6
155
  }): {
7
156
  sanityFetch: StrictDefinedFetchType;
8
157
  SanityLive: React.ComponentType<StrictDefinedLiveProps>;
9
158
  };
159
+ /**
160
+ * Set up Sanity Live. `defineLive` returns `sanityFetch` and `<SanityLive />`,
161
+ * which connect your Sanity client to the Live Content API so pages can serve
162
+ * cached content and update in response to fine-grained content changes.
163
+ *
164
+ * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)
165
+ * @see [Sanity Live](https://www.sanity.io/live)
166
+ *
167
+ * @example
168
+ * ```tsx
169
+ * import {createClient} from 'next-sanity'
170
+ * import {defineLive} from 'next-sanity/live'
171
+ *
172
+ * const client = createClient({
173
+ * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
174
+ * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
175
+ * useCdn: true,
176
+ * perspective: 'published',
177
+ * })
178
+ * const token = process.env.SANITY_API_READ_TOKEN
179
+ *
180
+ * export const {sanityFetch, SanityLive} = defineLive({
181
+ * client,
182
+ * browserToken: token,
183
+ * serverToken: token,
184
+ * })
185
+ * ```
186
+ *
187
+ * @example
188
+ * ```tsx
189
+ * // app/layout.tsx
190
+ * import {SanityLive} from '@/sanity/live'
191
+ *
192
+ * export default function RootLayout({children}: {children: React.ReactNode}) {
193
+ * return (
194
+ * <html lang="en">
195
+ * <body>
196
+ * {children}
197
+ * <SanityLive />
198
+ * </body>
199
+ * </html>
200
+ * )
201
+ * }
202
+ * ```
203
+ *
204
+ * @example
205
+ * ```tsx
206
+ * // app/[slug]/page.tsx
207
+ * import {defineQuery} from 'next-sanity'
208
+ * import {sanityFetch} from '@/sanity/live'
209
+ *
210
+ * const POSTS_SLUGS_QUERY = defineQuery(`
211
+ * *[_type == "post" && slug.current]{"slug": slug.current}
212
+ * `)
213
+ * const POST_QUERY = defineQuery(`
214
+ * *[_type == "post" && slug.current == $slug][0]
215
+ * `)
216
+ *
217
+ * export async function generateStaticParams() {
218
+ * const {data} = await sanityFetch({
219
+ * query: POSTS_SLUGS_QUERY,
220
+ * perspective: 'published',
221
+ * stega: false,
222
+ * })
223
+ *
224
+ * return data
225
+ * }
226
+ *
227
+ * export default async function Page(props: PageProps<'/[slug]'>) {
228
+ * const {slug} = await props.params
229
+ * const {data} = await sanityFetch({
230
+ * query: POST_QUERY,
231
+ * params: {slug},
232
+ * })
233
+ *
234
+ * return <pre>{JSON.stringify(data, null, 2)}</pre>
235
+ * }
236
+ * ```
237
+ *
238
+ * @public
239
+ */
10
240
  declare function defineLive(config: DefineLiveOptions & {
11
241
  strict?: false;
12
242
  }): {
13
243
  sanityFetch: DefinedFetchType;
14
244
  SanityLive: React.ComponentType<DefinedLiveProps>;
15
245
  };
16
- export { type LivePerspective, defineLive, isCorsOriginError, parseTags, resolvePerspectiveFromCookies };
246
+ export { type DefineLiveOptions, type DefinedFetchType, type DefinedLiveProps, type LivePerspective, type SanityLiveAction, type SanityLiveActionContext, type SanityLiveOnError, type SanityLiveOnGoaway, type SanityLiveOnReconnect, type SanityLiveOnRestart, type SanityLiveOnWelcome, type StrictDefinedFetchType, type StrictDefinedLiveProps, defineLive, isCorsOriginError, parseTags, resolvePerspectiveFromCookies };
17
247
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/next-js/defineLive.tsx"],"mappings":";;;iBAgBgB,UAAA,CAAW,MAAA,EAAQ,iBAAA;EAAqB,MAAA;AAAA;EACtD,WAAA,EAAa,sBAAA;EACb,UAAA,EAAY,KAAA,CAAM,aAAA,CAAc,sBAAA;AAAA;AAAA,iBAElB,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":";;;;;;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"}
@@ -57,7 +57,7 @@ function defineLive(config) {
57
57
  };
58
58
  const SanityLive$2 = function SanityLive$1(props) {
59
59
  if (strict) validateStrictSanityLiveProps(props);
60
- const { includeDrafts = false, action = revalidateSyncTagsAction, onReconnect = refreshAction, onRestart = refreshAction, onWelcome, onError, onGoAway, refreshOnMount = false, refreshOnFocus = false, refreshOnReconnect = false, requestTag = "next-loader.live.cache-components" } = props;
60
+ const { includeDrafts = false, waitFor, requestTag = "next-loader.live.cache-components", action = waitFor === "function" ? refreshAction : revalidateSyncTagsAction, onReconnect = refreshAction, onRestart = refreshAction, onWelcome, onError, onGoAway, refreshOnMount = false, refreshOnFocus = false, refreshOnReconnect = false } = props;
61
61
  const shouldIncludeDrafts = typeof browserToken === "string" && includeDrafts;
62
62
  const { projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix } = client.config();
63
63
  const { origin } = new URL(client.getUrl("", false));
@@ -73,6 +73,7 @@ function defineLive(config) {
73
73
  token: shouldIncludeDrafts ? browserToken : void 0
74
74
  },
75
75
  includeDrafts: shouldIncludeDrafts,
76
+ waitFor,
76
77
  action,
77
78
  onReconnect,
78
79
  onRestart,
@@ -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 {refreshAction, 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 {cacheTagPrefixes, 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\nexport function defineLive(config: DefineLiveOptions & {strict: true}): {\n sanityFetch: StrictDefinedFetchType\n SanityLive: React.ComponentType<StrictDefinedLiveProps>\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 !== 'production' && !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 !== 'production' && !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({allowReconfigure: false, useCdn: true})\n const {token: originalToken, perspective: originalPerspective = 'published'} = client.config()\n\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective: _perspective,\n stega: _stega,\n tags: customCacheTags = [],\n requestTag = 'next-loader.fetch.cache-components',\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective: _perspective, stega: _stega})\n }\n const perspective = _perspective ?? originalPerspective\n const stega = _stega ?? false\n const useCdn = perspective === 'published'\n const isBuildPhase = process.env['NEXT_PHASE'] === PHASE_PRODUCTION_BUILD\n const cacheMode = useCdn && !isBuildPhase ? 'noStale' : undefined\n\n const cacheTagPrefix =\n perspective === 'published' ? cacheTagPrefixes.published : cacheTagPrefixes.drafts\n const {result, resultSourceMap, syncTags} = await client.fetch(query, await params, {\n filterResponse: false,\n returnQuery: false,\n perspective,\n useCdn,\n stega,\n cacheMode,\n tag: requestTag,\n token: perspective === 'published' ? originalToken : serverToken || originalToken, // @TODO can pass undefined instead of config.token here?\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 action = revalidateSyncTagsAction,\n onReconnect = refreshAction,\n onRestart = refreshAction,\n\n onWelcome,\n onError,\n onGoAway,\n\n refreshOnMount = false,\n refreshOnFocus = false,\n refreshOnReconnect = false,\n requestTag = 'next-loader.live.cache-components',\n } = props\n\n const shouldIncludeDrafts = typeof browserToken === 'string' && includeDrafts\n\n const {projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix} =\n client.config()\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}\n action={action}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onWelcome={onWelcome}\n onError={onError}\n onGoAway={onGoAway}\n requestTag={requestTag}\n refreshOnMount={refreshOnMount}\n refreshOnFocus={refreshOnFocus}\n refreshOnReconnect={refreshOnReconnect}\n />\n )\n }\n SanityLive.displayName = 'SanityLiveServerComponent'\n\n return {sanityFetch, SanityLive}\n}\n"],"mappings":";;;;;;;;;;AAwBA,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,gBAAgB,CAAC,eAAe,gBAAgB,MAC3E,SAAQ,KACN,8LACD;AAGH,KAAI,QAAQ,IAAI,aAAa,gBAAgB,CAAC,gBAAgB,iBAAiB,MAC7E,SAAQ,KACN,iXACD;CAGH,MAAM,SAAS,QAAQ,WAAW;EAAC,kBAAkB;EAAO,QAAQ;EAAK,CAAC;CAC1E,MAAM,EAAC,OAAO,eAAe,aAAa,sBAAsB,gBAAe,OAAO,QAAQ;CAE9F,MAAM,cAAgC,eAAe,YAAY,EAC/D,OACA,SAAS,EAAE,EACX,aAAa,cACb,OAAO,QACP,MAAM,kBAAkB,EAAE,EAC1B,aAAa,wCACZ;AACD,MAAI,OACF,4BAA2B;GAAC,aAAa;GAAc,OAAO;GAAO,CAAC;EAExE,MAAM,cAAc,gBAAgB;EACpC,MAAM,QAAQ,UAAU;EACxB,MAAM,SAAS,gBAAgB;EAC/B,MAAM,eAAe,QAAQ,IAAI,kBAAkB;EACnD,MAAM,YAAY,UAAU,CAAC,eAAe,YAAY,KAAA;EAExD,MAAM,iBACJ,gBAAgB,cAAc,iBAAiB,YAAY,iBAAiB;EAC9E,MAAM,EAAC,QAAQ,iBAAiB,aAAY,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GAClF,gBAAgB;GAChB,aAAa;GACb;GACA;GACA;GACA;GACA,KAAK;GACL,OAAO,gBAAgB,cAAc,gBAAgB,eAAe;GACrE,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,SAAS,0BACT,cAAc,eACd,YAAY,eAEZ,WACA,SACA,UAEA,iBAAiB,OACjB,iBAAiB,OACjB,qBAAqB,OACrB,aAAa,wCACX;EAEJ,MAAM,sBAAsB,OAAO,iBAAiB,YAAY;EAEhE,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,QAAQ;EAGjB,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;GACP;GACK;GACF;GACA;GACF;GACC;GACE;GACI;GACA;GACI;GACpB,CAAA;;AAGN,cAAW,cAAc;AAEzB,QAAO;EAAC;EAAa,YAAA;EAAW"}
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 {refreshAction, 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 {cacheTagPrefixes, 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 !== 'production' && !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 !== 'production' && !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({allowReconfigure: false, useCdn: true})\n const {token: originalToken, perspective: originalPerspective = 'published'} = client.config()\n\n const sanityFetch: DefinedFetchType = async function sanityFetch({\n query,\n params = {},\n perspective: _perspective,\n stega: _stega,\n tags: customCacheTags = [],\n requestTag = 'next-loader.fetch.cache-components',\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective: _perspective, stega: _stega})\n }\n const perspective = _perspective ?? originalPerspective\n const stega = _stega ?? false\n const useCdn = perspective === 'published'\n const isBuildPhase = process.env['NEXT_PHASE'] === PHASE_PRODUCTION_BUILD\n const cacheMode = useCdn && !isBuildPhase ? 'noStale' : undefined\n\n const cacheTagPrefix =\n perspective === 'published' ? cacheTagPrefixes.published : cacheTagPrefixes.drafts\n const {result, resultSourceMap, syncTags} = await client.fetch(query, await params, {\n filterResponse: false,\n returnQuery: false,\n perspective,\n useCdn,\n stega,\n cacheMode,\n tag: requestTag,\n token: perspective === 'published' ? originalToken : serverToken || originalToken, // @TODO can pass undefined instead of config.token here?\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 waitFor,\n requestTag = 'next-loader.live.cache-components',\n\n action = waitFor === 'function' ? refreshAction : revalidateSyncTagsAction,\n onReconnect = refreshAction,\n onRestart = refreshAction,\n onWelcome,\n onError,\n onGoAway,\n\n refreshOnMount = false,\n refreshOnFocus = false,\n refreshOnReconnect = false,\n } = props\n\n const shouldIncludeDrafts = typeof browserToken === 'string' && includeDrafts\n\n const {projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix} =\n client.config()\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}\n waitFor={waitFor}\n action={action}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onWelcome={onWelcome}\n onError={onError}\n onGoAway={onGoAway}\n requestTag={requestTag}\n refreshOnMount={refreshOnMount}\n refreshOnFocus={refreshOnFocus}\n refreshOnReconnect={refreshOnReconnect}\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,gBAAgB,CAAC,eAAe,gBAAgB,MAC3E,SAAQ,KACN,8LACD;AAGH,KAAI,QAAQ,IAAI,aAAa,gBAAgB,CAAC,gBAAgB,iBAAiB,MAC7E,SAAQ,KACN,iXACD;CAGH,MAAM,SAAS,QAAQ,WAAW;EAAC,kBAAkB;EAAO,QAAQ;EAAK,CAAC;CAC1E,MAAM,EAAC,OAAO,eAAe,aAAa,sBAAsB,gBAAe,OAAO,QAAQ;CAE9F,MAAM,cAAgC,eAAe,YAAY,EAC/D,OACA,SAAS,EAAE,EACX,aAAa,cACb,OAAO,QACP,MAAM,kBAAkB,EAAE,EAC1B,aAAa,wCACZ;AACD,MAAI,OACF,4BAA2B;GAAC,aAAa;GAAc,OAAO;GAAO,CAAC;EAExE,MAAM,cAAc,gBAAgB;EACpC,MAAM,QAAQ,UAAU;EACxB,MAAM,SAAS,gBAAgB;EAC/B,MAAM,eAAe,QAAQ,IAAI,kBAAkB;EACnD,MAAM,YAAY,UAAU,CAAC,eAAe,YAAY,KAAA;EAExD,MAAM,iBACJ,gBAAgB,cAAc,iBAAiB,YAAY,iBAAiB;EAC9E,MAAM,EAAC,QAAQ,iBAAiB,aAAY,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GAClF,gBAAgB;GAChB,aAAa;GACb;GACA;GACA;GACA;GACA,KAAK;GACL,OAAO,gBAAgB,cAAc,gBAAgB,eAAe;GACrE,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,SACA,aAAa,qCAEb,SAAS,YAAY,aAAa,gBAAgB,0BAClD,cAAc,eACd,YAAY,eACZ,WACA,SACA,UAEA,iBAAiB,OACjB,iBAAiB,OACjB,qBAAqB,UACnB;EAEJ,MAAM,sBAAsB,OAAO,iBAAiB,YAAY;EAEhE,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,QAAQ;EAGjB,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;GACN;GACD;GACK;GACF;GACA;GACF;GACC;GACE;GACI;GACA;GACI;GACpB,CAAA;;AAGN,cAAW,cAAc;AAEzB,QAAO;EAAC;EAAa,YAAA;EAAW"}
@@ -1,17 +1,247 @@
1
1
  import { t as isCorsOriginError } from "../../../isCorsOriginError.js";
2
- import { d as StrictDefinedFetchType, f as StrictDefinedLiveProps, i as LivePerspective, n as DefinedFetchType, r as DefinedLiveProps, t as DefineLiveOptions } from "../../../types.js";
2
+ import { c as SanityLiveOnError, d as SanityLiveOnRestart, f as SanityLiveOnWelcome, i as LivePerspective, l as SanityLiveOnGoaway, m as StrictDefinedLiveProps, n as DefinedFetchType, o as SanityLiveAction, p as StrictDefinedFetchType, r as DefinedLiveProps, s as SanityLiveActionContext, t as DefineLiveOptions, u as SanityLiveOnReconnect } from "../../../types.js";
3
3
  import { n as resolvePerspectiveFromCookies, t as parseTags } from "../../../parseTags.js";
4
+ /**
5
+ * Set up Sanity Live for Cache Components. `defineLive` returns `sanityFetch`
6
+ * and `<SanityLive />`, which connect your Sanity client to the Live Content API
7
+ * so cached pages can update in response to fine-grained content changes.
8
+ *
9
+ * With `strict: true`, `perspective` and `stega` become required
10
+ * `sanityFetch` options, and `includeDrafts` becomes required on
11
+ * `<SanityLive />`. Resolve dynamic values from `draftMode()` and `cookies()`
12
+ * outside `'use cache'` boundaries, then pass them into cached components.
13
+ *
14
+ * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)
15
+ * @see [Sanity Live](https://www.sanity.io/live)
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * // sanity/live.ts
20
+ * import {cookies, draftMode} from 'next/headers'
21
+ * import {createClient} from 'next-sanity'
22
+ * import {
23
+ * defineLive,
24
+ * resolvePerspectiveFromCookies,
25
+ * type LivePerspective,
26
+ * } from 'next-sanity/live'
27
+ *
28
+ * const client = createClient({
29
+ * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
30
+ * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
31
+ * useCdn: true,
32
+ * perspective: 'published',
33
+ * })
34
+ * const token = process.env.SANITY_API_READ_TOKEN
35
+ *
36
+ * export const {sanityFetch, SanityLive} = defineLive({
37
+ * client,
38
+ * browserToken: token,
39
+ * serverToken: token,
40
+ * strict: true,
41
+ * })
42
+ *
43
+ * export interface DynamicFetchOptions {
44
+ * perspective: LivePerspective
45
+ * stega: boolean
46
+ * }
47
+ *
48
+ * // Resolve dynamic values outside 'use cache' boundaries.
49
+ * export async function getDynamicFetchOptions(): Promise<DynamicFetchOptions> {
50
+ * const {isEnabled: isDraftMode} = await draftMode()
51
+ * if (!isDraftMode) {
52
+ * return {perspective: 'published', stega: false}
53
+ * }
54
+ *
55
+ * const jar = await cookies()
56
+ * const perspective = await resolvePerspectiveFromCookies({cookies: jar})
57
+ * return {perspective: perspective ?? 'drafts', stega: true}
58
+ * }
59
+ * ```
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * // app/layout.tsx
64
+ * import {draftMode} from 'next/headers'
65
+ *
66
+ * import {SanityLive} from '@/sanity/live'
67
+ *
68
+ * export default async function RootLayout({children}: {children: React.ReactNode}) {
69
+ * const {isEnabled: isDraftMode} = await draftMode()
70
+ *
71
+ * return (
72
+ * <html lang="en">
73
+ * <body>
74
+ * {children}
75
+ * <SanityLive includeDrafts={isDraftMode} />
76
+ * </body>
77
+ * </html>
78
+ * )
79
+ * }
80
+ * ```
81
+ *
82
+ * @example
83
+ * ```tsx
84
+ * // app/[slug]/page.tsx
85
+ * import {draftMode} from 'next/headers'
86
+ * import {Suspense} from 'react'
87
+ * import {defineQuery} from 'next-sanity'
88
+ *
89
+ * import {
90
+ * getDynamicFetchOptions,
91
+ * sanityFetch,
92
+ * type DynamicFetchOptions,
93
+ * } from '@/sanity/live'
94
+ *
95
+ * const POSTS_SLUGS_QUERY = defineQuery(`
96
+ * *[_type == "post" && slug.current]{"slug": slug.current}
97
+ * `)
98
+ * const POST_QUERY = defineQuery(`
99
+ * *[_type == "post" && slug.current == $slug][0]
100
+ * `)
101
+ *
102
+ * export async function generateStaticParams() {
103
+ * const {data} = await sanityFetch({
104
+ * query: POSTS_SLUGS_QUERY,
105
+ * perspective: 'published',
106
+ * stega: false,
107
+ * })
108
+ *
109
+ * return data
110
+ * }
111
+ *
112
+ * export default async function Page(props: PageProps<'/[slug]'>) {
113
+ * const {isEnabled: isDraftMode} = await draftMode()
114
+ * if (isDraftMode) {
115
+ * return (
116
+ * <Suspense fallback={<div>Loading...</div>}>
117
+ * <DynamicPage params={props.params} />
118
+ * </Suspense>
119
+ * )
120
+ * }
121
+ *
122
+ * const {slug} = await props.params
123
+ * return <CachedPage slug={slug} perspective="published" stega={false} />
124
+ * }
125
+ *
126
+ * async function DynamicPage(props: Pick<PageProps<'/[slug]'>, 'params'>) {
127
+ * const {slug} = await props.params
128
+ * const {perspective, stega} = await getDynamicFetchOptions()
129
+ *
130
+ * return <CachedPage slug={slug} perspective={perspective} stega={stega} />
131
+ * }
132
+ *
133
+ * async function CachedPage({
134
+ * slug,
135
+ * perspective,
136
+ * stega,
137
+ * }: {slug: string} & DynamicFetchOptions) {
138
+ * 'use cache'
139
+ *
140
+ * const {data} = await sanityFetch({
141
+ * query: POST_QUERY,
142
+ * params: {slug},
143
+ * perspective,
144
+ * stega,
145
+ * })
146
+ *
147
+ * return <pre>{JSON.stringify(data, null, 2)}</pre>
148
+ * }
149
+ * ```
150
+ *
151
+ * @public
152
+ */
4
153
  declare function defineLive(config: DefineLiveOptions & {
5
154
  strict: true;
6
155
  }): {
7
156
  sanityFetch: StrictDefinedFetchType;
8
157
  SanityLive: React.ComponentType<StrictDefinedLiveProps>;
9
158
  };
159
+ /**
160
+ * Set up Sanity Live. `defineLive` returns `sanityFetch` and `<SanityLive />`,
161
+ * which connect your Sanity client to the Live Content API so pages can serve
162
+ * cached content and update in response to fine-grained content changes.
163
+ *
164
+ * @see [Live Content API](https://www.sanity.io/docs/content-lake/live-content-api)
165
+ * @see [Sanity Live](https://www.sanity.io/live)
166
+ *
167
+ * @example
168
+ * ```tsx
169
+ * import {createClient} from 'next-sanity'
170
+ * import {defineLive} from 'next-sanity/live'
171
+ *
172
+ * const client = createClient({
173
+ * projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
174
+ * dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
175
+ * useCdn: true,
176
+ * perspective: 'published',
177
+ * })
178
+ * const token = process.env.SANITY_API_READ_TOKEN
179
+ *
180
+ * export const {sanityFetch, SanityLive} = defineLive({
181
+ * client,
182
+ * browserToken: token,
183
+ * serverToken: token,
184
+ * })
185
+ * ```
186
+ *
187
+ * @example
188
+ * ```tsx
189
+ * // app/layout.tsx
190
+ * import {SanityLive} from '@/sanity/live'
191
+ *
192
+ * export default function RootLayout({children}: {children: React.ReactNode}) {
193
+ * return (
194
+ * <html lang="en">
195
+ * <body>
196
+ * {children}
197
+ * <SanityLive />
198
+ * </body>
199
+ * </html>
200
+ * )
201
+ * }
202
+ * ```
203
+ *
204
+ * @example
205
+ * ```tsx
206
+ * // app/[slug]/page.tsx
207
+ * import {defineQuery} from 'next-sanity'
208
+ * import {sanityFetch} from '@/sanity/live'
209
+ *
210
+ * const POSTS_SLUGS_QUERY = defineQuery(`
211
+ * *[_type == "post" && slug.current]{"slug": slug.current}
212
+ * `)
213
+ * const POST_QUERY = defineQuery(`
214
+ * *[_type == "post" && slug.current == $slug][0]
215
+ * `)
216
+ *
217
+ * export async function generateStaticParams() {
218
+ * const {data} = await sanityFetch({
219
+ * query: POSTS_SLUGS_QUERY,
220
+ * perspective: 'published',
221
+ * stega: false,
222
+ * })
223
+ *
224
+ * return data
225
+ * }
226
+ *
227
+ * export default async function Page(props: PageProps<'/[slug]'>) {
228
+ * const {slug} = await props.params
229
+ * const {data} = await sanityFetch({
230
+ * query: POST_QUERY,
231
+ * params: {slug},
232
+ * })
233
+ *
234
+ * return <pre>{JSON.stringify(data, null, 2)}</pre>
235
+ * }
236
+ * ```
237
+ *
238
+ * @public
239
+ */
10
240
  declare function defineLive(config: DefineLiveOptions & {
11
241
  strict?: false;
12
242
  }): {
13
243
  sanityFetch: DefinedFetchType;
14
244
  SanityLive: React.ComponentType<DefinedLiveProps>;
15
245
  };
16
- export { type LivePerspective, defineLive, isCorsOriginError, parseTags, resolvePerspectiveFromCookies };
246
+ export { type DefineLiveOptions, type DefinedFetchType, type DefinedLiveProps, type LivePerspective, type SanityLiveAction, type SanityLiveActionContext, type SanityLiveOnError, type SanityLiveOnGoaway, type SanityLiveOnReconnect, type SanityLiveOnRestart, type SanityLiveOnWelcome, type StrictDefinedFetchType, type StrictDefinedLiveProps, defineLive, isCorsOriginError, parseTags, resolvePerspectiveFromCookies };
17
247
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"mappings":";;;iBAmBgB,UAAA,CAAW,MAAA,EAAQ,iBAAA;EAAqB,MAAA;AAAA;EACtD,WAAA,EAAa,sBAAA;EACb,UAAA,EAAY,KAAA,CAAM,aAAA,CAAc,sBAAA;AAAA;AAAA,iBAElB,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/react-server/defineLive.tsx"],"mappings":";;;;;;AAwKA;;;;;;;;;;;;;;;;;;;;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"}
@@ -64,7 +64,7 @@ function defineLive(config) {
64
64
  };
65
65
  const SanityLive$2 = async function SanityLive$1(props) {
66
66
  if (strict) validateStrictSanityLiveProps(props);
67
- const { includeDrafts = (await draftMode()).isEnabled, action = revalidateSyncTagsAction, onReconnect = refreshAction, onRestart = refreshAction, onWelcome = false, onError = false, onGoAway = false, refreshOnMount, refreshOnFocus, refreshOnReconnect, requestTag = "next-loader.live" } = props;
67
+ const { includeDrafts = (await draftMode()).isEnabled, waitFor, requestTag = "next-loader.live", action = waitFor === "function" ? refreshAction : revalidateSyncTagsAction, onReconnect = refreshAction, onRestart = refreshAction, onWelcome = false, onError = false, onGoAway = false, refreshOnMount, refreshOnFocus, refreshOnReconnect } = props;
68
68
  const { projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix } = client.config();
69
69
  const shouldIncludeDrafts = typeof browserToken === "string" && includeDrafts;
70
70
  const { origin } = new URL(client.getUrl("", false));
@@ -80,6 +80,7 @@ function defineLive(config) {
80
80
  token: shouldIncludeDrafts ? browserToken : void 0
81
81
  },
82
82
  includeDrafts: shouldIncludeDrafts,
83
+ waitFor,
83
84
  action,
84
85
  onReconnect,
85
86
  onRestart,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["SanityLive","SanityLiveClientComponent"],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"sourcesContent":["import {type ClientPerspective, type QueryParams} from '@sanity/client'\nimport {perspectiveCookieName} from '@sanity/preview-url-secret/constants'\nimport {SanityLive as SanityLiveClientComponent} from 'next-sanity/live/client-components'\nimport {refreshAction, 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 {cacheTagPrefixes} from '#live/constants'\nimport {sanitizePerspective} from '#live/sanitizePerspective'\nimport {validateStrictFetchOptions, validateStrictSanityLiveProps} from '#live/strictValidation'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n\nexport function defineLive(config: DefineLiveOptions & {strict: true}): {\n sanityFetch: StrictDefinedFetchType\n SanityLive: React.ComponentType<StrictDefinedLiveProps>\n}\nexport function defineLive(config: DefineLiveOptions & {strict?: false}): {\n sanityFetch: DefinedFetchType\n SanityLive: React.ComponentType<DefinedLiveProps>\n}\nexport function defineLive(config: DefineLiveOptions) {\n const {\n client: _client,\n serverToken,\n browserToken,\n stega: stegaEnabled = true,\n strict = false,\n } = config\n\n if (!_client) {\n throw new Error('`client` is required for `defineLive` to function')\n }\n\n if (process.env.NODE_ENV !== 'production' && !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 !== 'production' && !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({allowReconfigure: false, useCdn: false})\n const {token: originalToken, perspective: originalPerspective = 'published'} = client.config()\n const studioUrlDefined = typeof client.config().stega.studioUrl !== 'undefined'\n\n const sanityFetch: DefinedFetchType = async function sanityFetch<\n const QueryString extends string,\n >({\n query,\n params = {},\n stega: _stega,\n tags = [],\n perspective: _perspective,\n tag,\n requestTag = tag ?? 'next-loader.fetch',\n }: {\n query: QueryString\n params?: QueryParams | Promise<QueryParams>\n stega?: boolean\n tags?: string[]\n perspective?: Exclude<ClientPerspective, 'raw'>\n tag?: string\n requestTag?: string\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective: _perspective, stega: _stega})\n }\n const stega = strict\n ? _stega!\n : (_stega ?? (stegaEnabled && studioUrlDefined && (await draftMode()).isEnabled))\n const perspective = strict\n ? _perspective!\n : (_perspective ??\n (await resolveCookiePerspective(\n originalPerspective === 'raw' ? 'published' : originalPerspective,\n )))\n const useCdn = perspective === 'published'\n const isBuildPhase = process.env['NEXT_PHASE'] === PHASE_PRODUCTION_BUILD\n const cacheMode = useCdn && !isBuildPhase ? 'noStale' : undefined\n const cacheTagPrefix =\n perspective === 'published' ? cacheTagPrefixes.published : cacheTagPrefixes.drafts\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: perspective as ClientPerspective,\n stega: false,\n returnQuery: false,\n useCdn,\n cacheMode,\n tag: [requestTag, 'fetch-sync-tags'].filter(Boolean).join('.'),\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: perspective as ClientPerspective,\n stega,\n token: perspective !== 'published' && serverToken ? serverToken : originalToken,\n next: {revalidate: false, tags: cacheTags},\n useCdn,\n cacheMode,\n tag: requestTag,\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 = (await draftMode()).isEnabled,\n action = revalidateSyncTagsAction,\n onReconnect = refreshAction,\n onRestart = refreshAction,\n\n onWelcome = false,\n onError = false,\n onGoAway = false,\n\n refreshOnMount,\n refreshOnFocus,\n refreshOnReconnect,\n requestTag = 'next-loader.live',\n } = props\n const {projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix} =\n client.config()\n const shouldIncludeDrafts = typeof browserToken === 'string' && includeDrafts\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}\n action={action}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onWelcome={onWelcome}\n onError={onError}\n onGoAway={onGoAway}\n requestTag={requestTag}\n refreshOnMount={refreshOnMount}\n refreshOnFocus={refreshOnFocus}\n refreshOnReconnect={refreshOnReconnect}\n />\n )\n }\n SanityLive.displayName = 'SanityLiveServerComponent'\n\n return {sanityFetch, SanityLive}\n}\n\nasync function resolveCookiePerspective(\n fallback: Exclude<ClientPerspective, 'raw'>,\n): Promise<Exclude<ClientPerspective, 'raw'>> {\n return (await draftMode()).isEnabled\n ? (await cookies()).has(perspectiveCookieName)\n ? sanitizePerspective((await cookies()).get(perspectiveCookieName)?.value, 'drafts')\n : 'drafts'\n : fallback\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 {type ClientPerspective, type QueryParams} from '@sanity/client'\nimport {perspectiveCookieName} from '@sanity/preview-url-secret/constants'\nimport {SanityLive as SanityLiveClientComponent} from 'next-sanity/live/client-components'\nimport {refreshAction, 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 {cacheTagPrefixes} from '#live/constants'\nimport {sanitizePerspective} from '#live/sanitizePerspective'\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 {\n client: _client,\n serverToken,\n browserToken,\n stega: stegaEnabled = true,\n strict = false,\n } = config\n\n if (!_client) {\n throw new Error('`client` is required for `defineLive` to function')\n }\n\n if (process.env.NODE_ENV !== 'production' && !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 !== 'production' && !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({allowReconfigure: false, useCdn: false})\n const {token: originalToken, perspective: originalPerspective = 'published'} = client.config()\n const studioUrlDefined = typeof client.config().stega.studioUrl !== 'undefined'\n\n const sanityFetch: DefinedFetchType = async function sanityFetch<\n const QueryString extends string,\n >({\n query,\n params = {},\n stega: _stega,\n tags = [],\n perspective: _perspective,\n tag,\n requestTag = tag ?? 'next-loader.fetch',\n }: {\n query: QueryString\n params?: QueryParams | Promise<QueryParams>\n stega?: boolean\n tags?: string[]\n perspective?: Exclude<ClientPerspective, 'raw'>\n tag?: string\n requestTag?: string\n }) {\n if (strict) {\n validateStrictFetchOptions({perspective: _perspective, stega: _stega})\n }\n const stega = strict\n ? _stega!\n : (_stega ?? (stegaEnabled && studioUrlDefined && (await draftMode()).isEnabled))\n const perspective = strict\n ? _perspective!\n : (_perspective ??\n (await resolveCookiePerspective(\n originalPerspective === 'raw' ? 'published' : originalPerspective,\n )))\n const useCdn = perspective === 'published'\n const isBuildPhase = process.env['NEXT_PHASE'] === PHASE_PRODUCTION_BUILD\n const cacheMode = useCdn && !isBuildPhase ? 'noStale' : undefined\n const cacheTagPrefix =\n perspective === 'published' ? cacheTagPrefixes.published : cacheTagPrefixes.drafts\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: perspective as ClientPerspective,\n stega: false,\n returnQuery: false,\n useCdn,\n cacheMode,\n tag: [requestTag, 'fetch-sync-tags'].filter(Boolean).join('.'),\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: perspective as ClientPerspective,\n stega,\n token: perspective !== 'published' && serverToken ? serverToken : originalToken,\n next: {revalidate: false, tags: cacheTags},\n useCdn,\n cacheMode,\n tag: requestTag,\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 = (await draftMode()).isEnabled,\n waitFor,\n requestTag = 'next-loader.live',\n\n action = waitFor === 'function' ? refreshAction : revalidateSyncTagsAction,\n onReconnect = refreshAction,\n onRestart = refreshAction,\n onWelcome = false,\n onError = false,\n onGoAway = false,\n\n refreshOnMount,\n refreshOnFocus,\n refreshOnReconnect,\n } = props\n const {projectId, dataset, apiHost, apiVersion, useProjectHostname, requestTagPrefix} =\n client.config()\n const shouldIncludeDrafts = typeof browserToken === 'string' && includeDrafts\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}\n waitFor={waitFor}\n action={action}\n onReconnect={onReconnect}\n onRestart={onRestart}\n onWelcome={onWelcome}\n onError={onError}\n onGoAway={onGoAway}\n requestTag={requestTag}\n refreshOnMount={refreshOnMount}\n refreshOnFocus={refreshOnFocus}\n refreshOnReconnect={refreshOnReconnect}\n />\n )\n }\n SanityLive.displayName = 'SanityLiveServerComponent'\n\n return {sanityFetch, SanityLive}\n}\n\nasync function resolveCookiePerspective(\n fallback: Exclude<ClientPerspective, 'raw'>,\n): Promise<Exclude<ClientPerspective, 'raw'>> {\n return (await draftMode()).isEnabled\n ? (await cookies()).has(perspectiveCookieName)\n ? sanitizePerspective((await cookies()).get(perspectiveCookieName)?.value, 'drafts')\n : 'drafts'\n : fallback\n}\n"],"mappings":"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"}