next-sanity 13.0.0-cache-components.47 → 13.0.0-cache-components.49
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 +2 -3
- package/dist/NextStudio.js +2 -2
- package/dist/NextStudio.js.map +1 -1
- package/dist/live/conditions/default/index.d.ts +40 -9
- package/dist/live/conditions/default/index.d.ts.map +1 -1
- package/dist/live/conditions/default/index.js +40 -9
- package/dist/live/conditions/default/index.js.map +1 -1
- package/dist/live/conditions/next-js/index.js.map +1 -1
- package/dist/live/conditions/react-server/index.d.ts.map +1 -1
- package/dist/live/conditions/react-server/index.js +1 -1
- package/dist/live/conditions/react-server/index.js.map +1 -1
- package/dist/parseTags.d.ts +43 -11
- package/dist/parseTags.d.ts.map +1 -1
- package/dist/resolvePerspectiveFromCookies.js +40 -9
- package/dist/resolvePerspectiveFromCookies.js.map +1 -1
- package/dist/sanitizePerspective.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -73,9 +73,7 @@ npx install-peerdeps --yarn next-sanity
|
|
|
73
73
|
|
|
74
74
|
## Migration guides
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
> You're looking at the README for v12, the README for [v11 is available here](https://github.com/sanity-io/next-sanity/tree/v11?tab=readme-ov-file#next-sanity) as well as a [migration guide][migrate-v11-to-v12].
|
|
78
|
-
|
|
76
|
+
- [From `v12` to `v13`][migrate-v12-to-v13]
|
|
79
77
|
- [From `v11` to `v12`][migrate-v11-to-v12]
|
|
80
78
|
- [From `v10` to `v11`][migrate-v10-to-v11]
|
|
81
79
|
- [From `v9` to `v10`][migrate-v9-to-v10]
|
|
@@ -104,6 +102,7 @@ MIT-licensed. See [LICENSE][LICENSE].
|
|
|
104
102
|
[migrate-v9-to-v10]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v9-to-v10.md
|
|
105
103
|
[migrate-v10-to-v11]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v10-to-v11.md
|
|
106
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
|
|
107
106
|
[next-docs]: https://nextjs.org/docs
|
|
108
107
|
[sanity]: https://www.sanity.io?utm_source=github&utm_medium=readme&utm_campaign=next-sanity
|
|
109
108
|
[sanity-next-clean-starter]: https://www.sanity.io/templates/nextjs-sanity-clean
|
package/dist/NextStudio.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as NextStudioLayout, t as NextStudioNoScript } from "./NextStudioNoScript.js";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useMemo, useSyncExternalStore } from "react";
|
|
3
|
+
import { useDeferredValue, useMemo, useSyncExternalStore } from "react";
|
|
4
4
|
import { Studio } from "sanity";
|
|
5
5
|
import { createHashHistory } from "history";
|
|
6
6
|
/** @internal */
|
|
@@ -43,7 +43,7 @@ function createHashHistoryForStudio() {
|
|
|
43
43
|
}
|
|
44
44
|
/** @internal */
|
|
45
45
|
function useIsMounted() {
|
|
46
|
-
return useSyncExternalStore(emptySubscribe, () => true, () => false);
|
|
46
|
+
return useDeferredValue(useSyncExternalStore(emptySubscribe, () => true, () => false), false);
|
|
47
47
|
}
|
|
48
48
|
const emptySubscribe = () => () => {};
|
|
49
49
|
/**
|
package/dist/NextStudio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextStudio.js","names":[],"sources":["../src/studio/client-component/createHashHistoryForStudio.ts","../src/studio/client-component/useIsMounted.ts","../src/studio/client-component/NextStudio.tsx"],"sourcesContent":["// oxlint-disable unbound-method\nimport {createHashHistory, type History, type Listener} from 'history'\n\n/** @internal */\nexport function createHashHistoryForStudio(): History {\n const history = createHashHistory()\n return {\n get action() {\n return history.action\n },\n get location() {\n return history.location\n },\n get createHref() {\n return history.createHref\n },\n get push() {\n return history.push\n },\n get replace() {\n return history.replace\n },\n get go() {\n return history.go\n },\n get back() {\n return history.back\n },\n get forward() {\n return history.forward\n },\n get block() {\n return history.block\n },\n // Overriding listen to workaround a problem where native history provides history.listen(location => void), but the npm package is history.listen(({action, location}) => void)\n listen(listener: Listener) {\n // return history.listen(({ action, location }) => {\n return history.listen(({location}) => {\n // console.debug('history.listen', action, location)\n // @ts-expect-error -- working around a bug? in studio\n listener(location)\n })\n },\n }\n}\n","import {useSyncExternalStore} from 'react'\n\n/** @internal */\nexport function useIsMounted(): boolean {\n return useSyncExternalStore(\n
|
|
1
|
+
{"version":3,"file":"NextStudio.js","names":[],"sources":["../src/studio/client-component/createHashHistoryForStudio.ts","../src/studio/client-component/useIsMounted.ts","../src/studio/client-component/NextStudio.tsx"],"sourcesContent":["// oxlint-disable unbound-method\nimport {createHashHistory, type History, type Listener} from 'history'\n\n/** @internal */\nexport function createHashHistoryForStudio(): History {\n const history = createHashHistory()\n return {\n get action() {\n return history.action\n },\n get location() {\n return history.location\n },\n get createHref() {\n return history.createHref\n },\n get push() {\n return history.push\n },\n get replace() {\n return history.replace\n },\n get go() {\n return history.go\n },\n get back() {\n return history.back\n },\n get forward() {\n return history.forward\n },\n get block() {\n return history.block\n },\n // Overriding listen to workaround a problem where native history provides history.listen(location => void), but the npm package is history.listen(({action, location}) => void)\n listen(listener: Listener) {\n // return history.listen(({ action, location }) => {\n return history.listen(({location}) => {\n // console.debug('history.listen', action, location)\n // @ts-expect-error -- working around a bug? in studio\n listener(location)\n })\n },\n }\n}\n","import {useDeferredValue, useSyncExternalStore} from 'react'\n\n/** @internal */\nexport function useIsMounted(): boolean {\n return useDeferredValue(\n useSyncExternalStore(\n emptySubscribe,\n () => true,\n () => false,\n ),\n false,\n )\n}\nconst emptySubscribe = () => () => {}\n","import {useMemo} from 'react'\nimport {Studio, type StudioProps} from 'sanity'\n\nimport {NextStudioLayout} from '../NextStudioLayout'\nimport {NextStudioNoScript} from '../NextStudioNoScript'\nimport {createHashHistoryForStudio} from './createHashHistoryForStudio'\nimport {useIsMounted} from './useIsMounted'\n\n/** @public */\nexport interface NextStudioProps extends StudioProps {\n children?: React.ReactNode\n /**\n * Render the <noscript> tag\n * @defaultValue true\n * @alpha\n */\n unstable__noScript?: boolean\n /**\n * The 'hash' option is new feature that is not yet stable for production, but is available for testing and its API won't change in a breaking way.\n * If 'hash' doesn't work for you, or if you want to use a memory based history, you can use the `unstable_history` prop instead.\n * @alpha\n * @defaultValue 'browser'\n */\n history?: 'browser' | 'hash'\n}\n/**\n * Override how the Studio renders by passing children.\n * This is useful for advanced use cases where you're using StudioProvider and StudioLayout instead of Studio:\n * ```\n * import {StudioProvider, StudioLayout} from 'sanity'\n * import {NextStudio} from 'next-sanity/studio'\n * <NextStudio config={config}>\n * <StudioProvider config={config}>\n * <CustomComponentThatUsesContextFromStudioProvider />\n * <StudioLayout />\n * </StudioProvider>\n * </NextStudio>\n * ```\n * @public\n */\nexport default function NextStudioComponent({\n children,\n config,\n unstable__noScript = true,\n scheme,\n history,\n ...props\n}: NextStudioProps): React.JSX.Element {\n const isMounted = useIsMounted()\n const unstableHistory = useMemo<typeof props.unstable_history>(() => {\n if (props.unstable_history && history) {\n throw new Error('Cannot use both `unstable_history` and `history` props at the same time')\n }\n\n if (isMounted && history === 'hash') {\n return createHashHistoryForStudio()\n }\n return props.unstable_history\n }, [history, isMounted, props.unstable_history])\n\n return (\n <>\n {unstable__noScript && <NextStudioNoScript />}\n <NextStudioLayout>\n {history === 'hash' && !isMounted\n ? null\n : children || (\n <Studio\n config={config}\n scheme={scheme}\n unstable_globalStyles\n {...props}\n unstable_history={unstableHistory}\n />\n )}\n </NextStudioLayout>\n </>\n )\n}\n"],"mappings":";;;;;;AAIA,SAAgB,6BAAsC;CACpD,MAAM,UAAU,mBAAmB;AACnC,QAAO;EACL,IAAI,SAAS;AACX,UAAO,QAAQ;;EAEjB,IAAI,WAAW;AACb,UAAO,QAAQ;;EAEjB,IAAI,aAAa;AACf,UAAO,QAAQ;;EAEjB,IAAI,OAAO;AACT,UAAO,QAAQ;;EAEjB,IAAI,UAAU;AACZ,UAAO,QAAQ;;EAEjB,IAAI,KAAK;AACP,UAAO,QAAQ;;EAEjB,IAAI,OAAO;AACT,UAAO,QAAQ;;EAEjB,IAAI,UAAU;AACZ,UAAO,QAAQ;;EAEjB,IAAI,QAAQ;AACV,UAAO,QAAQ;;EAGjB,OAAO,UAAoB;AAEzB,UAAO,QAAQ,QAAQ,EAAC,eAAc;AAGpC,aAAS,SAAS;KAClB;;EAEL;;;ACxCH,SAAgB,eAAwB;AACtC,QAAO,iBACL,qBACE,sBACM,YACA,MACP,EACD,MACD;;AAEH,MAAM,6BAA6B;;;;;;;;;;;;;;;;AC2BnC,SAAwB,oBAAoB,EAC1C,UACA,QACA,qBAAqB,MACrB,QACA,SACA,GAAG,SACkC;CACrC,MAAM,YAAY,cAAc;CAChC,MAAM,kBAAkB,cAA6C;AACnE,MAAI,MAAM,oBAAoB,QAC5B,OAAM,IAAI,MAAM,0EAA0E;AAG5F,MAAI,aAAa,YAAY,OAC3B,QAAO,4BAA4B;AAErC,SAAO,MAAM;IACZ;EAAC;EAAS;EAAW,MAAM;EAAiB,CAAC;AAEhD,QACE,qBAAA,UAAA,EAAA,UAAA,CACG,sBAAsB,oBAAC,oBAAD,EAAsB,CAAA,EAC7C,oBAAC,kBAAD,EAAA,UACG,YAAY,UAAU,CAAC,YACpB,OACA,YACE,oBAAC,QAAD;EACU;EACA;EACR,uBAAA;EACA,GAAI;EACJ,kBAAkB;EAClB,CAAA,EAES,CAAA,CAClB,EAAA,CAAA"}
|
|
@@ -251,21 +251,52 @@ declare function defineLive(config: DefineLiveOptions & {
|
|
|
251
251
|
* @example
|
|
252
252
|
* ```tsx
|
|
253
253
|
* import {cookies, draftMode} from 'next/headers'
|
|
254
|
+
* import {defineQuery} from 'next-sanity'
|
|
254
255
|
* import {resolvePerspectiveFromCookies, type LivePerspective} from 'next-sanity/live'
|
|
255
|
-
* import {sanityFetch} from '#sanity/live'
|
|
256
|
+
* import {sanityFetch, sanityFetchStaticParams} from '#sanity/live'
|
|
257
|
+
*
|
|
258
|
+
* export async function generateStaticParams() {
|
|
259
|
+
* const query = defineQuery(`*[_type == "page" && defined(slug.current)]{"slug": slug.current}`)
|
|
260
|
+
* return await sanityFetchStaticParams({query})
|
|
261
|
+
* }
|
|
256
262
|
*
|
|
257
|
-
* function Page() {
|
|
263
|
+
* export default async function Page({params}: PageProps<'/[slug]'>) {
|
|
258
264
|
* const {isEnabled: isDraftMode} = await draftMode()
|
|
259
|
-
*
|
|
260
|
-
* if(isDraftMode) {
|
|
261
|
-
*
|
|
265
|
+
*
|
|
266
|
+
* if (isDraftMode) {
|
|
267
|
+
* return (
|
|
268
|
+
* <Suspense>
|
|
269
|
+
* <DynamicPage params={params} />
|
|
270
|
+
* </Suspense>
|
|
271
|
+
* )
|
|
262
272
|
* }
|
|
263
|
-
*
|
|
273
|
+
*
|
|
274
|
+
* const {slug} = await params
|
|
275
|
+
*
|
|
276
|
+
* return <CachedPage slug={slug} perspective="published" stega={false} />
|
|
264
277
|
* }
|
|
265
|
-
*
|
|
278
|
+
*
|
|
279
|
+
* async function DynamicPage({params}: Pick<PageProps<'/[slug]'>, 'params'>) {
|
|
280
|
+
* const {slug} = await params
|
|
281
|
+
* const perspective = await resolvePerspectiveFromCookies({cookies: await cookies()})
|
|
282
|
+
*
|
|
283
|
+
* return <CachedPage slug={slug} perspective={perspective} stega />
|
|
284
|
+
* }
|
|
285
|
+
*
|
|
286
|
+
* async function CachedPage({
|
|
287
|
+
* slug,
|
|
288
|
+
* perspective,
|
|
289
|
+
* stega,
|
|
290
|
+
* }: Awaited<PageProps<'/[slug]'>['params']> & {
|
|
291
|
+
* perspective: LivePerspective
|
|
292
|
+
* stega: boolean
|
|
293
|
+
* }) {
|
|
266
294
|
* 'use cache'
|
|
267
|
-
*
|
|
268
|
-
*
|
|
295
|
+
*
|
|
296
|
+
* const query = defineQuery(`*[_type == "page" && slug.current == $slug][0]`)
|
|
297
|
+
* const {data} = await sanityFetch({query, params: {slug}, perspective, stega})
|
|
298
|
+
*
|
|
299
|
+
* return <article>...</article>
|
|
269
300
|
* }
|
|
270
301
|
* ```
|
|
271
302
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/default/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/default/index.ts"],"mappings":";;;;;AA8JA;;;;;;;;;;;;;;;;;;;;AAqFA;;;;;;;;;;;;;;;;;;;;AAsFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA3KgB,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoFrB,6BAAA,SAAsC,+BAAA"}
|
|
@@ -11,21 +11,52 @@ function defineLive(_config) {
|
|
|
11
11
|
* @example
|
|
12
12
|
* ```tsx
|
|
13
13
|
* import {cookies, draftMode} from 'next/headers'
|
|
14
|
+
* import {defineQuery} from 'next-sanity'
|
|
14
15
|
* import {resolvePerspectiveFromCookies, type LivePerspective} from 'next-sanity/live'
|
|
15
|
-
* import {sanityFetch} from '#sanity/live'
|
|
16
|
+
* import {sanityFetch, sanityFetchStaticParams} from '#sanity/live'
|
|
16
17
|
*
|
|
17
|
-
* function
|
|
18
|
+
* export async function generateStaticParams() {
|
|
19
|
+
* const query = defineQuery(`*[_type == "page" && defined(slug.current)]{"slug": slug.current}`)
|
|
20
|
+
* return await sanityFetchStaticParams({query})
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* export default async function Page({params}: PageProps<'/[slug]'>) {
|
|
18
24
|
* const {isEnabled: isDraftMode} = await draftMode()
|
|
19
|
-
*
|
|
20
|
-
* if(isDraftMode) {
|
|
21
|
-
*
|
|
25
|
+
*
|
|
26
|
+
* if (isDraftMode) {
|
|
27
|
+
* return (
|
|
28
|
+
* <Suspense>
|
|
29
|
+
* <DynamicPage params={params} />
|
|
30
|
+
* </Suspense>
|
|
31
|
+
* )
|
|
22
32
|
* }
|
|
23
|
-
*
|
|
33
|
+
*
|
|
34
|
+
* const {slug} = await params
|
|
35
|
+
*
|
|
36
|
+
* return <CachedPage slug={slug} perspective="published" stega={false} />
|
|
24
37
|
* }
|
|
25
|
-
*
|
|
38
|
+
*
|
|
39
|
+
* async function DynamicPage({params}: Pick<PageProps<'/[slug]'>, 'params'>) {
|
|
40
|
+
* const {slug} = await params
|
|
41
|
+
* const perspective = await resolvePerspectiveFromCookies({cookies: await cookies()})
|
|
42
|
+
*
|
|
43
|
+
* return <CachedPage slug={slug} perspective={perspective} stega />
|
|
44
|
+
* }
|
|
45
|
+
*
|
|
46
|
+
* async function CachedPage({
|
|
47
|
+
* slug,
|
|
48
|
+
* perspective,
|
|
49
|
+
* stega,
|
|
50
|
+
* }: Awaited<PageProps<'/[slug]'>['params']> & {
|
|
51
|
+
* perspective: LivePerspective
|
|
52
|
+
* stega: boolean
|
|
53
|
+
* }) {
|
|
26
54
|
* 'use cache'
|
|
27
|
-
*
|
|
28
|
-
*
|
|
55
|
+
*
|
|
56
|
+
* const query = defineQuery(`*[_type == "page" && slug.current == $slug][0]`)
|
|
57
|
+
* const {data} = await sanityFetch({query, params: {slug}, perspective, stega})
|
|
58
|
+
*
|
|
59
|
+
* return <article>...</article>
|
|
29
60
|
* }
|
|
30
61
|
* ```
|
|
31
62
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/live/conditions/default/index.ts"],"sourcesContent":["// This is the fallback export condition for `import 'next-sanity/live'`,\n// it should have the same type definitions as the other conditions so that userland don't have to worry about setting the right\n// `customCondition` in their `tsconfig.json` in order to get accurate typings.\n// The implementation here though should all throw errors, as importing this file means userland made a mistake and somehow a client component is\n// trying to pull in something it shouldn't.\n\nimport type {resolvePerspectiveFromCookies as _resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n\nexport {isCorsOriginError} from '#live/isCorsOriginError'\nexport {parseTags} from '#live/parseTags'\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): never {\n throw new Error(`defineLive can't be imported by a client component`)\n}\n\n/**\n * This helper is intended for use with Next.js Cache Components (`cacheComponents: true`),\n * where `cookies()` and `draftMode()` cannot be called inside `'use cache'` boundaries.\n * Resolve the 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 {resolvePerspectiveFromCookies, type LivePerspective} from 'next-sanity/live'\n * import {sanityFetch} from '#sanity/live'\n *\n * function Page() {\n * const {isEnabled: isDraftMode} = await draftMode()\n * let perspective: LivePerspective = 'published'\n * if(isDraftMode) {\n * perspective = await resolvePerspectiveFromCookies({cookies: await cookies()})\n * }\n * const {data} = await cachedFetch({query, perspective, stega: isDraftMode})\n * }\n * function cachedFetch({query, params, perspective, stega}: {query: string, perspective: LivePerspective, stega: boolean}) {}) {\n * 'use cache'\n * const {data} = await sanityFetch({query, params, perspective, stega})\n * return {data}\n * }\n * ```\n *\n * @public\n */\nexport const resolvePerspectiveFromCookies: typeof _resolvePerspectiveFromCookies = () => {\n throw new Error(`resolvePerspectiveFromCookies can't be imported by a client component`)\n}\n\nexport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n LivePerspective,\n SanityLiveAction,\n SanityLiveActionContext,\n SanityLiveOnError,\n SanityLiveOnGoaway,\n SanityLiveOnReconnect,\n SanityLiveOnRestart,\n SanityLiveOnWelcome,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n"],"mappings":";;AAgQA,SAAgB,WAAW,SAAmC;AAC5D,OAAM,IAAI,MAAM,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BvE,MAAa,sCAA6E;AACxF,OAAM,IAAI,MAAM,wEAAwE"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/live/conditions/default/index.ts"],"sourcesContent":["import type {resolvePerspectiveFromCookies as _resolvePerspectiveFromCookies} from '#live/resolvePerspectiveFromCookies'\nimport type {\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): never {\n throw new Error(`defineLive can't be imported by a client component`)\n}\n\nexport type {\n DefinedFetchType,\n DefinedLiveProps,\n DefineLiveOptions,\n LivePerspective,\n SanityLiveAction,\n SanityLiveActionContext,\n SanityLiveOnError,\n SanityLiveOnGoaway,\n SanityLiveOnReconnect,\n SanityLiveOnRestart,\n SanityLiveOnWelcome,\n StrictDefinedFetchType,\n StrictDefinedLiveProps,\n} from '#live/types'\n\nexport {isCorsOriginError} from '#live/isCorsOriginError'\nexport {parseTags} from '#live/parseTags'\n\n/**\n * This helper is intended for use with Next.js Cache Components (`cacheComponents: true`),\n * where `cookies()` and `draftMode()` cannot be called inside `'use cache'` boundaries.\n * Resolve the perspective once outside the cache boundary and pass it in as a prop / cache key.\n *\n * @example\n * ```tsx\n * import {cookies, draftMode} from 'next/headers'\n * import {defineQuery} from 'next-sanity'\n * import {resolvePerspectiveFromCookies, type LivePerspective} from 'next-sanity/live'\n * import {sanityFetch, sanityFetchStaticParams} from '#sanity/live'\n *\n * export async function generateStaticParams() {\n * const query = defineQuery(`*[_type == \"page\" && defined(slug.current)]{\"slug\": slug.current}`)\n * return await sanityFetchStaticParams({query})\n * }\n *\n * export default async function Page({params}: PageProps<'/[slug]'>) {\n * const {isEnabled: isDraftMode} = await draftMode()\n *\n * if (isDraftMode) {\n * return (\n * <Suspense>\n * <DynamicPage params={params} />\n * </Suspense>\n * )\n * }\n *\n * const {slug} = await params\n *\n * return <CachedPage slug={slug} perspective=\"published\" stega={false} />\n * }\n *\n * async function DynamicPage({params}: Pick<PageProps<'/[slug]'>, 'params'>) {\n * const {slug} = await params\n * const perspective = await resolvePerspectiveFromCookies({cookies: await cookies()})\n *\n * return <CachedPage slug={slug} perspective={perspective} stega />\n * }\n *\n * async function CachedPage({\n * slug,\n * perspective,\n * stega,\n * }: Awaited<PageProps<'/[slug]'>['params']> & {\n * perspective: LivePerspective\n * stega: boolean\n * }) {\n * 'use cache'\n *\n * const query = defineQuery(`*[_type == \"page\" && slug.current == $slug][0]`)\n * const {data} = await sanityFetch({query, params: {slug}, perspective, stega})\n *\n * return <article>...</article>\n * }\n * ```\n *\n * @public\n */\nexport const resolvePerspectiveFromCookies: typeof _resolvePerspectiveFromCookies = () => {\n throw new Error(`resolvePerspectiveFromCookies can't be imported by a client component`)\n}\n"],"mappings":";;AAuPA,SAAgB,WAAW,SAAmC;AAC5D,OAAM,IAAI,MAAM,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFvE,MAAa,sCAA6E;AACxF,OAAM,IAAI,MAAM,wEAAwE"}
|
|
@@ -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\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,\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 const shouldWaitFor = (waitFor === 'function' && !shouldIncludeDrafts) ? waitFor : undefined\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={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? refreshAction : revalidateSyncTagsAction)}\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,QACA,cAAc,eACd,YAAY,eACZ,WACA,SACA,UAEA,iBAAiB,OACjB,iBAAiB,OACjB,qBAAqB,UACnB;EAEJ,MAAM,sBAAsB,OAAO,iBAAiB,YAAY;EAChE,MAAM,gBAAiB,YAAY,cAAc,CAAC,sBAAuB,UAAU,KAAA;EAEnF,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;GACf,SAAS;GACT,QAAQ,WAAW,kBAAkB,aAAa,gBAAgB;GACrD;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,\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 const shouldWaitFor = waitFor === 'function' && !shouldIncludeDrafts ? waitFor : undefined\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={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? refreshAction : revalidateSyncTagsAction)}\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,QACA,cAAc,eACd,YAAY,eACZ,WACA,SACA,UAEA,iBAAiB,OACjB,iBAAiB,OACjB,qBAAqB,UACnB;EAEJ,MAAM,sBAAsB,OAAO,iBAAiB,YAAY;EAChE,MAAM,gBAAgB,YAAY,cAAc,CAAC,sBAAsB,UAAU,KAAA;EAEjF,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;GACf,SAAS;GACT,QAAQ,WAAW,kBAAkB,aAAa,gBAAgB;GACrD;GACF;GACA;GACF;GACC;GACE;GACI;GACA;GACI;GACpB,CAAA;;AAGN,cAAW,cAAc;AAEzB,QAAO;EAAC;EAAa,YAAA;EAAW"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"mappings":";;;;;;AAyKA;;;;;;;;;;;;;;;;;;;;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"}
|
|
@@ -22,7 +22,7 @@ function defineLive(config) {
|
|
|
22
22
|
});
|
|
23
23
|
const { token: originalToken, perspective: originalPerspective = "published" } = client.config();
|
|
24
24
|
const studioUrlDefined = typeof client.config().stega.studioUrl !== "undefined";
|
|
25
|
-
const sanityFetch = async function sanityFetch({ query, params = {}, stega: _stega, tags = [], perspective: _perspective,
|
|
25
|
+
const sanityFetch = async function sanityFetch({ query, params = {}, stega: _stega, tags = [], perspective: _perspective, requestTag = "next-loader.fetch" }) {
|
|
26
26
|
if (strict) validateStrictFetchOptions({
|
|
27
27
|
perspective: _perspective,
|
|
28
28
|
stega: _stega
|
|
@@ -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\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,\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 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}\n waitFor={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? refreshAction : revalidateSyncTagsAction)}\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":";;;;;;;;;;;;;AAiQA,SAAgB,WAAW,QAA2B;CACpD,MAAM,EACJ,QAAQ,SACR,aACA,cACA,OAAO,eAAe,MACtB,SAAS,UACP;AAEJ,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;EAAM,CAAC;CAC3E,MAAM,EAAC,OAAO,eAAe,aAAa,sBAAsB,gBAAe,OAAO,QAAQ;CAC9F,MAAM,mBAAmB,OAAO,OAAO,QAAQ,CAAC,MAAM,cAAc;CAEpE,MAAM,cAAgC,eAAe,YAEnD,EACA,OACA,SAAS,EAAE,EACX,OAAO,QACP,OAAO,EAAE,EACT,aAAa,cACb,KACA,aAAa,OAAO,uBASnB;AACD,MAAI,OACF,4BAA2B;GAAC,aAAa;GAAc,OAAO;GAAO,CAAC;EAExE,MAAM,QAAQ,SACV,SACC,WAAW,gBAAgB,qBAAqB,MAAM,WAAW,EAAE;EACxE,MAAM,cAAc,SAChB,eACC,gBACA,MAAM,yBACL,wBAAwB,QAAQ,cAAc,oBAC/C;EACL,MAAM,SAAS,gBAAgB;EAC/B,MAAM,eAAe,QAAQ,IAAI,kBAAkB;EACnD,MAAM,YAAY,UAAU,CAAC,eAAe,YAAY,KAAA;EACxD,MAAM,iBACJ,gBAAgB,cAAc,iBAAiB,YAAY,iBAAiB;EAG9E,MAAM,EAAC,aAAY,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GACzD,gBAAgB;GACH;GACb,OAAO;GACP,aAAa;GACb;GACA;GACA,KAAK,CAAC,YAAY,kBAAkB,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;GAC/D,CAAC;EAEF,MAAM,YAAY,CAAC,GAAG,MAAM,GAAI,UAAU,KAAK,QAAQ,GAAG,iBAAiB,MAAM,IAAI,EAAE,CAAE;EAGzF,MAAM,EAAC,QAAQ,oBAAmB,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GACxE,gBAAgB;GACH;GACb;GACA,OAAO,gBAAgB,eAAe,cAAc,cAAc;GAClE,MAAM;IAAC,YAAY;IAAO,MAAM;IAAU;GAC1C;GACA;GACA,KAAK;GACN,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,iBAAiB,MAAM,WAAW,EAAE,WACpC,SACA,aAAa,oBAEb,QACA,cAAc,eACd,YAAY,eACZ,YAAY,OACZ,UAAU,OACV,WAAW,OAEX,gBACA,gBACA,uBACE;EACJ,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,QAAQ;EACjB,MAAM,sBAAsB,OAAO,iBAAiB,YAAY;EAChE,MAAM,gBAAiB,YAAY,cAAc,CAAC,sBAAuB,UAAU,KAAA;EAGnF,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;GACf,SAAS;GACT,QAAQ,WAAW,kBAAkB,aAAa,gBAAgB;GACrD;GACF;GACA;GACF;GACC;GACE;GACI;GACA;GACI;GACpB,CAAA;;AAGN,cAAW,cAAc;AAEzB,QAAO;EAAC;EAAa,YAAA;EAAW;;AAGlC,eAAe,yBACb,UAC4C;AAC5C,SAAQ,MAAM,WAAW,EAAE,aACtB,MAAM,SAAS,EAAE,IAAI,sBAAsB,GAC1C,qBAAqB,MAAM,SAAS,EAAE,IAAI,sBAAsB,EAAE,OAAO,SAAS,GAClF,WACF"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["SanityLive","SanityLiveClientComponent"],"sources":["../../../../src/live/conditions/react-server/defineLive.tsx"],"sourcesContent":["import {type ClientPerspective} 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 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 {\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 query,\n params = {},\n stega: _stega,\n tags = [],\n perspective: _perspective,\n requestTag = 'next-loader.fetch',\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,\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 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}\n waitFor={shouldWaitFor}\n action={action ?? (shouldWaitFor === 'function' ? refreshAction : revalidateSyncTagsAction)}\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(fallback: LivePerspective): Promise<LivePerspective> {\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":";;;;;;;;;;;;;AAkQA,SAAgB,WAAW,QAA2B;CACpD,MAAM,EACJ,QAAQ,SACR,aACA,cACA,OAAO,eAAe,MACtB,SAAS,UACP;AAEJ,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;EAAM,CAAC;CAC3E,MAAM,EAAC,OAAO,eAAe,aAAa,sBAAsB,gBAAe,OAAO,QAAQ;CAC9F,MAAM,mBAAmB,OAAO,OAAO,QAAQ,CAAC,MAAM,cAAc;CAEpE,MAAM,cAAgC,eAAe,YAAY,EAC/D,OACA,SAAS,EAAE,EACX,OAAO,QACP,OAAO,EAAE,EACT,aAAa,cACb,aAAa,uBACZ;AACD,MAAI,OACF,4BAA2B;GAAC,aAAa;GAAc,OAAO;GAAO,CAAC;EAExE,MAAM,QAAQ,SACV,SACC,WAAW,gBAAgB,qBAAqB,MAAM,WAAW,EAAE;EACxE,MAAM,cAAc,SAChB,eACC,gBACA,MAAM,yBACL,wBAAwB,QAAQ,cAAc,oBAC/C;EACL,MAAM,SAAS,gBAAgB;EAC/B,MAAM,eAAe,QAAQ,IAAI,kBAAkB;EACnD,MAAM,YAAY,UAAU,CAAC,eAAe,YAAY,KAAA;EACxD,MAAM,iBACJ,gBAAgB,cAAc,iBAAiB,YAAY,iBAAiB;EAG9E,MAAM,EAAC,aAAY,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GACzD,gBAAgB;GACH;GACb,OAAO;GACP,aAAa;GACb;GACA;GACA,KAAK,CAAC,YAAY,kBAAkB,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;GAC/D,CAAC;EAEF,MAAM,YAAY,CAAC,GAAG,MAAM,GAAI,UAAU,KAAK,QAAQ,GAAG,iBAAiB,MAAM,IAAI,EAAE,CAAE;EAGzF,MAAM,EAAC,QAAQ,oBAAmB,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ;GACxE,gBAAgB;GACH;GACb;GACA,OAAO,gBAAgB,eAAe,cAAc,cAAc;GAClE,MAAM;IAAC,YAAY;IAAO,MAAM;IAAU;GAC1C;GACA;GACA,KAAK;GACN,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,iBAAiB,MAAM,WAAW,EAAE,WACpC,SACA,aAAa,oBAEb,QACA,cAAc,eACd,YAAY,eACZ,YAAY,OACZ,UAAU,OACV,WAAW,OAEX,gBACA,gBACA,uBACE;EACJ,MAAM,EAAC,WAAW,SAAS,SAAS,YAAY,oBAAoB,qBAClE,OAAO,QAAQ;EACjB,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;GACf,SAAS;GACT,QAAQ,WAAW,kBAAkB,aAAa,gBAAgB;GACrD;GACF;GACA;GACF;GACC;GACE;GACI;GACA;GACI;GACpB,CAAA;;AAGN,cAAW,cAAc;AAEzB,QAAO;EAAC;EAAa,YAAA;EAAW;;AAGlC,eAAe,yBAAyB,UAAqD;AAC3F,SAAQ,MAAM,WAAW,EAAE,aACtB,MAAM,SAAS,EAAE,IAAI,sBAAsB,GAC1C,qBAAqB,MAAM,SAAS,EAAE,IAAI,sBAAsB,EAAE,OAAO,SAAS,GAClF,WACF"}
|
package/dist/parseTags.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { i as LivePerspective } from "./types.js";
|
|
1
2
|
import { cookies } from "next/headers";
|
|
2
|
-
import {
|
|
3
|
+
import { SyncTag } from "@sanity/client";
|
|
3
4
|
/**
|
|
4
5
|
* This helper is intended for use with Next.js Cache Components (`cacheComponents: true`),
|
|
5
6
|
* where `cookies()` and `draftMode()` cannot be called inside `'use cache'` boundaries.
|
|
@@ -8,21 +9,52 @@ import { ClientPerspective, SyncTag } from "@sanity/client";
|
|
|
8
9
|
* @example
|
|
9
10
|
* ```tsx
|
|
10
11
|
* import {cookies, draftMode} from 'next/headers'
|
|
12
|
+
* import {defineQuery} from 'next-sanity'
|
|
11
13
|
* import {resolvePerspectiveFromCookies, type LivePerspective} from 'next-sanity/live'
|
|
12
|
-
* import {sanityFetch} from '#sanity/live'
|
|
14
|
+
* import {sanityFetch, sanityFetchStaticParams} from '#sanity/live'
|
|
13
15
|
*
|
|
14
|
-
* function
|
|
16
|
+
* export async function generateStaticParams() {
|
|
17
|
+
* const query = defineQuery(`*[_type == "page" && defined(slug.current)]{"slug": slug.current}`)
|
|
18
|
+
* return await sanityFetchStaticParams({query})
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* export default async function Page({params}: PageProps<'/[slug]'>) {
|
|
15
22
|
* const {isEnabled: isDraftMode} = await draftMode()
|
|
16
|
-
*
|
|
17
|
-
* if(isDraftMode) {
|
|
18
|
-
*
|
|
23
|
+
*
|
|
24
|
+
* if (isDraftMode) {
|
|
25
|
+
* return (
|
|
26
|
+
* <Suspense>
|
|
27
|
+
* <DynamicPage params={params} />
|
|
28
|
+
* </Suspense>
|
|
29
|
+
* )
|
|
19
30
|
* }
|
|
20
|
-
*
|
|
31
|
+
*
|
|
32
|
+
* const {slug} = await params
|
|
33
|
+
*
|
|
34
|
+
* return <CachedPage slug={slug} perspective="published" stega={false} />
|
|
21
35
|
* }
|
|
22
|
-
*
|
|
36
|
+
*
|
|
37
|
+
* async function DynamicPage({params}: Pick<PageProps<'/[slug]'>, 'params'>) {
|
|
38
|
+
* const {slug} = await params
|
|
39
|
+
* const perspective = await resolvePerspectiveFromCookies({cookies: await cookies()})
|
|
40
|
+
*
|
|
41
|
+
* return <CachedPage slug={slug} perspective={perspective} stega />
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* async function CachedPage({
|
|
45
|
+
* slug,
|
|
46
|
+
* perspective,
|
|
47
|
+
* stega,
|
|
48
|
+
* }: Awaited<PageProps<'/[slug]'>['params']> & {
|
|
49
|
+
* perspective: LivePerspective
|
|
50
|
+
* stega: boolean
|
|
51
|
+
* }) {
|
|
23
52
|
* 'use cache'
|
|
24
|
-
*
|
|
25
|
-
*
|
|
53
|
+
*
|
|
54
|
+
* const query = defineQuery(`*[_type == "page" && slug.current == $slug][0]`)
|
|
55
|
+
* const {data} = await sanityFetch({query, params: {slug}, perspective, stega})
|
|
56
|
+
*
|
|
57
|
+
* return <article>...</article>
|
|
26
58
|
* }
|
|
27
59
|
* ```
|
|
28
60
|
*
|
|
@@ -32,7 +64,7 @@ declare function resolvePerspectiveFromCookies({
|
|
|
32
64
|
cookies: jar
|
|
33
65
|
}: {
|
|
34
66
|
cookies: Awaited<ReturnType<typeof cookies>>;
|
|
35
|
-
}): Promise<
|
|
67
|
+
}): Promise<LivePerspective>;
|
|
36
68
|
declare const cacheTagPrefixes: {
|
|
37
69
|
published: string;
|
|
38
70
|
drafts: string;
|
package/dist/parseTags.d.ts.map
CHANGED
|
@@ -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":"
|
|
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;;;;;;;;;;;;;;;;;;;;;;AC1DA;;;;;;ACL+B;;;;;;;;;;;;;;;;;;AAK7B;;;;;;;;;;;iBF0DoB,6BAAA,CAAA;EACpB,OAAA,EAAS;AAAA;EAET,OAAA,EAAS,OAAA,CAAQ,UAAA,QAAkB,OAAA;AAAA,IACjC,OAAA,CAAQ,eAAA;AAAA,cC9DC,gBAAA;EACX,SAAA;EACA,MAAA;AAAA;AAAA,UCLQ,mBAAA;EACR,IAAA,YAAgB,gBAAA,CAAiB,SAAA,GAAY,OAAA;EAC7C,MAAA,SAAe,gBAAA,CAAiB,SAAA;EAChC,UAAA;AAAA;AAAA,UAEQ,eAAA;EACR,IAAA,YAAgB,gBAAA,CAAiB,MAAA,GAAS,OAAA;EAC1C,MAAA,SAAe,gBAAA,CAAiB,MAAA;EAChC,UAAA;AAAA;AAAA,KAEG,UAAA,GAAa,mBAAA,GAAsB,eAAA;;;;;;;;;;;;;;ADPxC;;;;;;ACL+B;;iBAmCf,SAAA,CAAU,UAAA,YAAsB,UAAA"}
|
|
@@ -16,21 +16,52 @@ function validateStrictFetchOptions(options) {
|
|
|
16
16
|
* @example
|
|
17
17
|
* ```tsx
|
|
18
18
|
* import {cookies, draftMode} from 'next/headers'
|
|
19
|
+
* import {defineQuery} from 'next-sanity'
|
|
19
20
|
* import {resolvePerspectiveFromCookies, type LivePerspective} from 'next-sanity/live'
|
|
20
|
-
* import {sanityFetch} from '#sanity/live'
|
|
21
|
+
* import {sanityFetch, sanityFetchStaticParams} from '#sanity/live'
|
|
21
22
|
*
|
|
22
|
-
* function
|
|
23
|
+
* export async function generateStaticParams() {
|
|
24
|
+
* const query = defineQuery(`*[_type == "page" && defined(slug.current)]{"slug": slug.current}`)
|
|
25
|
+
* return await sanityFetchStaticParams({query})
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* export default async function Page({params}: PageProps<'/[slug]'>) {
|
|
23
29
|
* const {isEnabled: isDraftMode} = await draftMode()
|
|
24
|
-
*
|
|
25
|
-
* if(isDraftMode) {
|
|
26
|
-
*
|
|
30
|
+
*
|
|
31
|
+
* if (isDraftMode) {
|
|
32
|
+
* return (
|
|
33
|
+
* <Suspense>
|
|
34
|
+
* <DynamicPage params={params} />
|
|
35
|
+
* </Suspense>
|
|
36
|
+
* )
|
|
27
37
|
* }
|
|
28
|
-
*
|
|
38
|
+
*
|
|
39
|
+
* const {slug} = await params
|
|
40
|
+
*
|
|
41
|
+
* return <CachedPage slug={slug} perspective="published" stega={false} />
|
|
29
42
|
* }
|
|
30
|
-
*
|
|
43
|
+
*
|
|
44
|
+
* async function DynamicPage({params}: Pick<PageProps<'/[slug]'>, 'params'>) {
|
|
45
|
+
* const {slug} = await params
|
|
46
|
+
* const perspective = await resolvePerspectiveFromCookies({cookies: await cookies()})
|
|
47
|
+
*
|
|
48
|
+
* return <CachedPage slug={slug} perspective={perspective} stega />
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* async function CachedPage({
|
|
52
|
+
* slug,
|
|
53
|
+
* perspective,
|
|
54
|
+
* stega,
|
|
55
|
+
* }: Awaited<PageProps<'/[slug]'>['params']> & {
|
|
56
|
+
* perspective: LivePerspective
|
|
57
|
+
* stega: boolean
|
|
58
|
+
* }) {
|
|
31
59
|
* 'use cache'
|
|
32
|
-
*
|
|
33
|
-
*
|
|
60
|
+
*
|
|
61
|
+
* const query = defineQuery(`*[_type == "page" && slug.current == $slug][0]`)
|
|
62
|
+
* const {data} = await sanityFetch({query, params: {slug}, perspective, stega})
|
|
63
|
+
*
|
|
64
|
+
* return <article>...</article>
|
|
34
65
|
* }
|
|
35
66
|
* ```
|
|
36
67
|
*
|
|
@@ -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
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizePerspective.js","names":[],"sources":["../src/live/shared/sanitizePerspective.ts"],"sourcesContent":["import {validateApiPerspective
|
|
1
|
+
{"version":3,"file":"sanitizePerspective.js","names":[],"sources":["../src/live/shared/sanitizePerspective.ts"],"sourcesContent":["import {validateApiPerspective} from '@sanity/client'\n\nimport type {LivePerspective} from '#live/types'\n\n// @TODO split into sanitizePerspective and parsePerspective, expose parsePerspective on the /live export\nexport function sanitizePerspective(\n _perspective: unknown,\n fallback: 'drafts' | 'published',\n): LivePerspective {\n const perspective =\n typeof _perspective === 'string' && _perspective.includes(',')\n ? _perspective.split(',')\n : Array.isArray(_perspective)\n ? _perspective.filter(Boolean)\n : _perspective\n try {\n validateApiPerspective(perspective)\n return perspective === 'raw' ? fallback : perspective\n } catch (err) {\n console.warn(`Invalid perspective:`, _perspective, perspective, err)\n return fallback\n }\n}\n"],"mappings":";AAKA,SAAgB,oBACd,cACA,UACiB;CACjB,MAAM,cACJ,OAAO,iBAAiB,YAAY,aAAa,SAAS,IAAI,GAC1D,aAAa,MAAM,IAAI,GACvB,MAAM,QAAQ,aAAa,GACzB,aAAa,OAAO,QAAQ,GAC5B;AACR,KAAI;AACF,yBAAuB,YAAY;AACnC,SAAO,gBAAgB,QAAQ,WAAW;UACnC,KAAK;AACZ,UAAQ,KAAK,wBAAwB,cAAc,aAAa,IAAI;AACpE,SAAO"}
|
package/dist/types.d.ts
CHANGED
|
@@ -53,6 +53,10 @@ type DefinedFetchType = <const QueryString extends string>(options: {
|
|
|
53
53
|
sourceMap: ContentSourceMap | null;
|
|
54
54
|
tags: string[];
|
|
55
55
|
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Render this in your root layout.tsx to make your page refresh, or revalidate, on new content live, automatically.
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
56
60
|
interface DefinedLiveProps {
|
|
57
61
|
/**
|
|
58
62
|
* Include draft and content release version events in the live connection.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/live/shared/types.ts"],"mappings":";;AAcA;;;KAAY,eAAA,GAAkB,OAAA,CAAQ,iBAAA;;AAStC;;;;;;KAAY,gBAAA,sCAAsD,OAAA;;;;EAIhE,KAAA,EAAO,WAAA;;;;EAIP,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,WAAA;;;;;;EAM/B,WAAA,GAAc,eAAA;;;;;;;EAOd,KAAA;;;;;;;;EAQA,IAAA;
|
|
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;;;;;;AAyEF;;EAjEE,OAAA;EAqEQ;;;;;;EA9DR,MAAA,GAAS,gBAAA;;;AAuGX;;EAlGE,OAAA,GAAU,iBAAA;EAkGoC;;;;EA7F9C,SAAA,GAAY,mBAAA;EA8FZ;AAOF;;;EAhGE,WAAA,GAAc,qBAAA;;;;;EAKd,SAAA,GAAY,mBAAA;;;;;EAKZ,QAAA,GAAW,kBAAA;;;;;;;;;EAUX,cAAA;;;;;;;EAOA,cAAA;;;;EAIA,kBAAA;;;AA8EF;;;;;EArEE,UAAA;AAAA;AAAA,UAGe,iBAAA;EAkFA;;AAejB;EA7FE,MAAA,EAAQ,YAAA;;;;AAoGV;;;EA7FE,WAAA;;;;;;;AAwGF;EAhGE,YAAA;;;;;;;;EAQA,KAAA;;;;;;;;;AAkGF;;EAvFE,MAAA;AAAA;;;;;UAOe,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;;;;UAee,uBAAA;;;;AAiEjB;EA5DE,aAAA;AAAA;;;;;;;;KAUU,gBAAA,IAAoB,UAAA,cAAwB,OAAA;;;;;;;KAO5C,iBAAA,IACV,KAAA,WACA,OAAA,EAAS,uBAAA,YACC,OAAA;;;;;;;;KAQA,mBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,uBAAA,YACC,OAAA;;;;;;;KAOA,qBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,uBAAA,YACC,OAAA;;;;;;;KAOA,mBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,uBAAA,YACC,OAAA;;;;;;;;;KASA,kBAAA,IACV,KAAA,EAAO,OAAA,CAAQ,SAAA;EAAY,IAAA;AAAA,IAC3B,OAAA,EAAS,uBAAA,EACT,kBAAA,GAAqB,QAAA,6BACX,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-sanity",
|
|
3
|
-
"version": "13.0.0-cache-components.
|
|
3
|
+
"version": "13.0.0-cache-components.49",
|
|
4
4
|
"description": "Sanity.io toolkit for Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"live",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"@vitejs/plugin-react": "^6.0.1",
|
|
77
77
|
"@vitest/coverage-v8": "^4.1.5",
|
|
78
78
|
"js-yaml": "^4.1.1",
|
|
79
|
-
"next": "16.3.0-canary.
|
|
79
|
+
"next": "16.3.0-canary.14",
|
|
80
80
|
"publint": "^0.3.18",
|
|
81
81
|
"react": "^19.2.6",
|
|
82
82
|
"react-dom": "^19.2.6",
|