next-sanity 13.0.0-cache-components.8 → 13.0.0-cache-components.10

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Sanity.io
3
+ Copyright (c) 2026 Sanity.io
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1 +1 @@
1
- {"version":3,"file":"NextStudioNoScript.js","names":["styles: Record<'outer' | 'inner', React.CSSProperties>"],"sources":["../src/studio/NextStudioLayout.tsx","../src/studio/NextStudioNoScript.tsx"],"sourcesContent":["/** @public */\nexport interface NextStudioLayoutProps {\n children: React.ReactNode\n}\n\nconst style = {\n height: '100vh',\n maxHeight: '100dvh',\n overscrollBehavior: 'none',\n WebkitFontSmoothing: 'antialiased',\n overflow: 'auto',\n} satisfies React.CSSProperties\n\n/** @public */\nexport const NextStudioLayout = ({children}: NextStudioLayoutProps): React.JSX.Element => {\n return (\n <div id=\"sanity\" data-ui=\"NextStudioLayout\" style={style}>\n {children}\n </div>\n )\n}\n","const styles: Record<'outer' | 'inner', React.CSSProperties> = {\n outer: {\n position: 'absolute',\n top: 0,\n right: 0,\n left: 0,\n bottom: 0,\n background: '#fff',\n zIndex: 1,\n },\n inner: {\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n textAlign: 'center',\n fontFamily: 'helvetica, arial, sans-serif',\n },\n}\n\n/** @internal */\nexport const NextStudioNoScript = (): React.JSX.Element => (\n <noscript>\n <div style={styles.outer}>\n <div style={styles.inner}>\n <h1>JavaScript disabled</h1>\n <p>\n Please <a href=\"https://www.enable-javascript.com/\">enable JavaScript</a> in your browser\n and reload the page to proceed.\n </p>\n </div>\n </div>\n </noscript>\n)\n"],"mappings":";AAKA,MAAM,QAAQ;CACZ,QAAQ;CACR,WAAW;CACX,oBAAoB;CACpB,qBAAqB;CACrB,UAAU;CACX;AAGD,MAAa,oBAAoB,EAAC,eAAwD;AACxF,QACE,oBAAC,OAAA;EAAI,IAAG;EAAS,WAAQ;EAA0B;EAChD;GACG;;AClBV,MAAMA,SAAyD;CAC7D,OAAO;EACL,UAAU;EACV,KAAK;EACL,OAAO;EACP,MAAM;EACN,QAAQ;EACR,YAAY;EACZ,QAAQ;EACT;CACD,OAAO;EACL,UAAU;EACV,KAAK;EACL,MAAM;EACN,WAAW;EACX,WAAW;EACX,YAAY;EACb;CACF;AAGD,MAAa,2BACX,oBAAC,YAAA,EAAA,UACC,oBAAC,OAAA;CAAI,OAAO,OAAO;WACjB,qBAAC,OAAA;EAAI,OAAO,OAAO;aACjB,oBAAC,MAAA,EAAA,UAAG,uBAAA,CAAwB,EAC5B,qBAAC,KAAA,EAAA,UAAA;GAAE;GACM,oBAAC,KAAA;IAAE,MAAK;cAAqC;KAAqB;;MAEvE,CAAA;GACA;EACF,EAAA,CACG"}
1
+ {"version":3,"file":"NextStudioNoScript.js","names":[],"sources":["../src/studio/NextStudioLayout.tsx","../src/studio/NextStudioNoScript.tsx"],"sourcesContent":["/** @public */\nexport interface NextStudioLayoutProps {\n children: React.ReactNode\n}\n\nconst style = {\n height: '100vh',\n maxHeight: '100dvh',\n overscrollBehavior: 'none',\n WebkitFontSmoothing: 'antialiased',\n overflow: 'auto',\n} satisfies React.CSSProperties\n\n/** @public */\nexport const NextStudioLayout = ({children}: NextStudioLayoutProps): React.JSX.Element => {\n return (\n <div id=\"sanity\" data-ui=\"NextStudioLayout\" style={style}>\n {children}\n </div>\n )\n}\n","const styles: Record<'outer' | 'inner', React.CSSProperties> = {\n outer: {\n position: 'absolute',\n top: 0,\n right: 0,\n left: 0,\n bottom: 0,\n background: '#fff',\n zIndex: 1,\n },\n inner: {\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n textAlign: 'center',\n fontFamily: 'helvetica, arial, sans-serif',\n },\n}\n\n/** @internal */\nexport const NextStudioNoScript = (): React.JSX.Element => (\n <noscript>\n <div style={styles.outer}>\n <div style={styles.inner}>\n <h1>JavaScript disabled</h1>\n <p>\n Please <a href=\"https://www.enable-javascript.com/\">enable JavaScript</a> in your browser\n and reload the page to proceed.\n </p>\n </div>\n </div>\n </noscript>\n)\n"],"mappings":";AAKA,MAAM,QAAQ;CACZ,QAAQ;CACR,WAAW;CACX,oBAAoB;CACpB,qBAAqB;CACrB,UAAU;CACX;AAGD,MAAa,oBAAoB,EAAC,eAAwD;AACxF,QACE,oBAAC,OAAA;EAAI,IAAG;EAAS,WAAQ;EAA0B;EAChD;GACG;;AClBV,MAAM,SAAyD;CAC7D,OAAO;EACL,UAAU;EACV,KAAK;EACL,OAAO;EACP,MAAM;EACN,QAAQ;EACR,YAAY;EACZ,QAAQ;EACT;CACD,OAAO;EACL,UAAU;EACV,KAAK;EACL,MAAM;EACN,WAAW;EACX,WAAW;EACX,YAAY;EACb;CACF;AAGD,MAAa,2BACX,oBAAC,YAAA,EAAA,UACC,oBAAC,OAAA;CAAI,OAAO,OAAO;WACjB,qBAAC,OAAA;EAAI,OAAO,OAAO;aACjB,oBAAC,MAAA,EAAA,UAAG,uBAAA,CAAwB,EAC5B,qBAAC,KAAA,EAAA,UAAA;GAAE;GACM,oBAAC,KAAA;IAAE,MAAK;cAAqC;KAAqB;;MAEvE,CAAA;GACA;EACF,EAAA,CACG"}
@@ -1 +1 @@
1
- {"version":3,"file":"PresentationComlink.js","names":["controller: AbortController | undefined"],"sources":["../src/experimental/client-components/PresentationComlink.tsx"],"sourcesContent":["import type {ClientPerspective} from '@sanity/client'\n\nimport {\n setComlink,\n setComlinkClientConfig,\n setPerspective,\n perspective,\n} from '#client-components/context'\nimport {sanitizePerspective} from '#live/sanitizePerspective'\nimport {createNode, createNodeMachine} from '@sanity/comlink'\nimport {\n createCompatibilityActors,\n type LoaderControllerMsg,\n type LoaderNodeMsg,\n} from '@sanity/presentation-comlink'\nimport {setPerspectiveCookie} from 'next-sanity/live/server-actions'\nimport {useRouter} from 'next/navigation'\nimport {startTransition, useEffect, useEffectEvent} from 'react'\n\nexport default function PresentationComlink(props: {\n projectId: string\n dataset: string\n draftModeEnabled: boolean\n}): React.JSX.Element | null {\n const {projectId, dataset, draftModeEnabled} = props\n const router = useRouter()\n\n useEffect(() => {\n setComlinkClientConfig(projectId, dataset)\n }, [dataset, projectId])\n\n const handlePerspectiveChange = useEffectEvent(\n (_perspective: ClientPerspective, signal: AbortSignal) => {\n const nextPerspective = sanitizePerspective(_perspective, 'drafts')\n if (draftModeEnabled && perspective.toString() !== nextPerspective.toString()) {\n setPerspective(nextPerspective)\n startTransition(() =>\n setPerspectiveCookie(nextPerspective)\n .then(() => {\n if (signal.aborted) return\n router.refresh()\n })\n .catch((reason) =>\n console.error('Failed to set the preview perspective cookie', reason),\n ),\n )\n }\n },\n )\n\n useEffect(() => {\n const comlink = createNode<LoaderNodeMsg, LoaderControllerMsg>(\n {name: 'loaders', connectTo: 'presentation'},\n createNodeMachine<LoaderNodeMsg, LoaderControllerMsg>().provide({\n actors: createCompatibilityActors<LoaderNodeMsg>(),\n }),\n )\n\n let controller: AbortController | undefined\n comlink.on('loader/perspective', (data) => {\n controller?.abort()\n controller = new AbortController()\n handlePerspectiveChange(data.perspective, controller.signal)\n })\n\n const stop = comlink.start()\n setComlink(comlink)\n return () => {\n stop()\n }\n }, [])\n\n return null\n}\n"],"mappings":";;;;;;;AAmBA,SAAwB,oBAAoB,OAIf;CAC3B,MAAM,EAAC,WAAW,SAAS,qBAAoB;CAC/C,MAAM,SAAS,WAAW;AAE1B,iBAAgB;AACd,yBAAuB,WAAW,QAAQ;IACzC,CAAC,SAAS,UAAU,CAAC;CAExB,MAAM,0BAA0B,gBAC7B,cAAiC,WAAwB;EACxD,MAAM,kBAAkB,oBAAoB,cAAc,SAAS;AACnE,MAAI,oBAAoB,YAAY,UAAU,KAAK,gBAAgB,UAAU,EAAE;AAC7E,kBAAe,gBAAgB;AAC/B,yBACE,qBAAqB,gBAAgB,CAClC,WAAW;AACV,QAAI,OAAO,QAAS;AACpB,WAAO,SAAS;KAChB,CACD,OAAO,WACN,QAAQ,MAAM,gDAAgD,OAAO,CACtE,CACJ;;GAGN;AAED,iBAAgB;EACd,MAAM,UAAU,WACd;GAAC,MAAM;GAAW,WAAW;GAAe,EAC5C,mBAAuD,CAAC,QAAQ,EAC9D,QAAQ,2BAA0C,EACnD,CAAC,CACH;EAED,IAAIA;AACJ,UAAQ,GAAG,uBAAuB,SAAS;AACzC,eAAY,OAAO;AACnB,gBAAa,IAAI,iBAAiB;AAClC,2BAAwB,KAAK,aAAa,WAAW,OAAO;IAC5D;EAEF,MAAM,OAAO,QAAQ,OAAO;AAC5B,aAAW,QAAQ;AACnB,eAAa;AACX,SAAM;;IAEP,EAAE,CAAC;AAEN,QAAO"}
1
+ {"version":3,"file":"PresentationComlink.js","names":[],"sources":["../src/experimental/client-components/PresentationComlink.tsx"],"sourcesContent":["import type {ClientPerspective} from '@sanity/client'\n\nimport {\n setComlink,\n setComlinkClientConfig,\n setPerspective,\n perspective,\n} from '#client-components/context'\nimport {sanitizePerspective} from '#live/sanitizePerspective'\nimport {createNode, createNodeMachine} from '@sanity/comlink'\nimport {\n createCompatibilityActors,\n type LoaderControllerMsg,\n type LoaderNodeMsg,\n} from '@sanity/presentation-comlink'\nimport {setPerspectiveCookie} from 'next-sanity/live/server-actions'\nimport {useRouter} from 'next/navigation'\nimport {startTransition, useEffect, useEffectEvent} from 'react'\n\nexport default function PresentationComlink(props: {\n projectId: string\n dataset: string\n draftModeEnabled: boolean\n}): React.JSX.Element | null {\n const {projectId, dataset, draftModeEnabled} = props\n const router = useRouter()\n\n useEffect(() => {\n setComlinkClientConfig(projectId, dataset)\n }, [dataset, projectId])\n\n const handlePerspectiveChange = useEffectEvent(\n (_perspective: ClientPerspective, signal: AbortSignal) => {\n const nextPerspective = sanitizePerspective(_perspective, 'drafts')\n if (draftModeEnabled && perspective.toString() !== nextPerspective.toString()) {\n setPerspective(nextPerspective)\n startTransition(() =>\n setPerspectiveCookie(nextPerspective)\n .then(() => {\n if (signal.aborted) return\n router.refresh()\n })\n .catch((reason) =>\n console.error('Failed to set the preview perspective cookie', reason),\n ),\n )\n }\n },\n )\n\n useEffect(() => {\n const comlink = createNode<LoaderNodeMsg, LoaderControllerMsg>(\n {name: 'loaders', connectTo: 'presentation'},\n createNodeMachine<LoaderNodeMsg, LoaderControllerMsg>().provide({\n actors: createCompatibilityActors<LoaderNodeMsg>(),\n }),\n )\n\n let controller: AbortController | undefined\n comlink.on('loader/perspective', (data) => {\n controller?.abort()\n controller = new AbortController()\n handlePerspectiveChange(data.perspective, controller.signal)\n })\n\n const stop = comlink.start()\n setComlink(comlink)\n return () => {\n stop()\n }\n }, [])\n\n return null\n}\n"],"mappings":";;;;;;;AAmBA,SAAwB,oBAAoB,OAIf;CAC3B,MAAM,EAAC,WAAW,SAAS,qBAAoB;CAC/C,MAAM,SAAS,WAAW;AAE1B,iBAAgB;AACd,yBAAuB,WAAW,QAAQ;IACzC,CAAC,SAAS,UAAU,CAAC;CAExB,MAAM,0BAA0B,gBAC7B,cAAiC,WAAwB;EACxD,MAAM,kBAAkB,oBAAoB,cAAc,SAAS;AACnE,MAAI,oBAAoB,YAAY,UAAU,KAAK,gBAAgB,UAAU,EAAE;AAC7E,kBAAe,gBAAgB;AAC/B,yBACE,qBAAqB,gBAAgB,CAClC,WAAW;AACV,QAAI,OAAO,QAAS;AACpB,WAAO,SAAS;KAChB,CACD,OAAO,WACN,QAAQ,MAAM,gDAAgD,OAAO,CACtE,CACJ;;GAGN;AAED,iBAAgB;EACd,MAAM,UAAU,WACd;GAAC,MAAM;GAAW,WAAW;GAAe,EAC5C,mBAAuD,CAAC,QAAQ,EAC9D,QAAQ,2BAA0C,EACnD,CAAC,CACH;EAED,IAAI;AACJ,UAAQ,GAAG,uBAAuB,SAAS;AACzC,eAAY,OAAO;AACnB,gBAAa,IAAI,iBAAiB;AAClC,2BAAwB,KAAK,aAAa,WAAW,OAAO;IAC5D;EAEF,MAAM,OAAO,QAAQ,OAAO;AAC5B,aAAW,QAAQ;AACnB,eAAa;AACX,SAAM;;IAEP,EAAE,CAAC;AAEN,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"PresentationComlink2.js","names":["controller: AbortController | undefined"],"sources":["../src/live/client-components/live/PresentationComlink.tsx"],"sourcesContent":["import type {ClientPerspective} from '@sanity/client'\n\nimport {\n createNode,\n createNodeMachine,\n // type Node,\n} from '@sanity/comlink'\nimport {setComlink, setComlinkClientConfig} from '#client-components/context'\nimport {\n createCompatibilityActors,\n type LoaderControllerMsg,\n type LoaderNodeMsg,\n} from '@sanity/presentation-comlink'\nimport {setPerspectiveCookie} from 'next-sanity/live/server-actions'\nimport {useRouter} from 'next/navigation'\nimport {useEffect, useEffectEvent} from 'react'\n\nfunction PresentationComlink(props: {\n projectId: string\n dataset: string\n // handleDraftModeAction: (secret: string) => Promise<void | string>\n draftModeEnabled: boolean\n draftModePerspective: ClientPerspective\n}): React.JSX.Element | null {\n const {projectId, dataset, draftModeEnabled, draftModePerspective} = props\n const router = useRouter()\n\n // const [presentationComlink, setPresentationComlink] = useState<Node<\n // LoaderControllerMsg,\n // LoaderNodeMsg\n // > | null>(null)\n\n useEffect(() => {\n setComlinkClientConfig(projectId, dataset)\n }, [dataset, projectId])\n\n const handlePerspectiveChange = useEffectEvent(\n (perspective: ClientPerspective, signal: AbortSignal) => {\n if (draftModeEnabled && perspective !== draftModePerspective) {\n setPerspectiveCookie(perspective)\n .then(() => {\n if (signal.aborted) return\n router.refresh()\n })\n .catch((reason) => console.error('Failed to set the preview perspective cookie', reason))\n }\n },\n )\n\n // const [status, setStatus] = useState('disconnected')\n useEffect(() => {\n const comlink = createNode<LoaderNodeMsg, LoaderControllerMsg>(\n {\n name: 'loaders',\n connectTo: 'presentation',\n },\n createNodeMachine<LoaderNodeMsg, LoaderControllerMsg>().provide({\n actors: createCompatibilityActors<LoaderNodeMsg>(),\n }),\n )\n\n // comlink.onStatus((status) => {\n // setStatus(status)\n // })\n\n let controller: AbortController | undefined\n comlink.on('loader/perspective', (data) => {\n controller?.abort()\n controller = new AbortController()\n handlePerspectiveChange(data.perspective, controller.signal)\n })\n\n const stop = comlink.start()\n // setPresentationComlink(comlink)\n setComlink(comlink)\n // console.log('setting comlink', comlink)\n return () => {\n // console.log('stopping comlink')\n stop()\n }\n }, [])\n\n // @TODO come back to this later\n // const handleEnableDraftMode = useEffectEvent(async (signal: AbortSignal) => {\n // if (signal.aborted) return\n // const {secret} = await (presentationComlink?.fetch(\n // {\n // type: 'loader/fetch-preview-url-secret' as const,\n // data: {projectId, dataset},\n // },\n // {signal},\n // ) || {secret: null})\n // if (signal.aborted) return\n // const error = await handleDraftModeAction(secret!)\n // // eslint-disable-next-line no-console\n // // @TODO call another server action here that can tell us if draft mode is actually enabled\n // if (error) {\n // // @TODO use sonnet or whatever to push a toast with the error\n // // eslint-disable-next-line no-console\n // console.error('Error enabling draft mode', error)\n // return\n // }\n // // console.log('Draft mode enabled?', {enabled})\n // if (signal.aborted) return\n // router.refresh()\n // })\n // const connected = status === 'connected'\n // useEffect(() => {\n // if (connected && !draftModeEnabled) {\n // const controller = new AbortController()\n // handleEnableDraftMode(controller.signal).catch((reason) => {\n // // eslint-disable-next-line no-console\n // console.error('Failed to enable draft mode', reason)\n // return handleEnableDraftMode(controller.signal)\n // })\n // return () => {\n // controller.abort()\n // }\n // }\n // return undefined\n // }, [connected, draftModeEnabled, handleEnableDraftMode])\n\n return null\n}\nPresentationComlink.displayName = 'PresentationComlink'\n\nexport default PresentationComlink\n"],"mappings":";;;;;;AAiBA,SAAS,oBAAoB,OAMA;CAC3B,MAAM,EAAC,WAAW,SAAS,kBAAkB,yBAAwB;CACrE,MAAM,SAAS,WAAW;AAO1B,iBAAgB;AACd,yBAAuB,WAAW,QAAQ;IACzC,CAAC,SAAS,UAAU,CAAC;CAExB,MAAM,0BAA0B,gBAC7B,aAAgC,WAAwB;AACvD,MAAI,oBAAoB,gBAAgB,qBACtC,sBAAqB,YAAY,CAC9B,WAAW;AACV,OAAI,OAAO,QAAS;AACpB,UAAO,SAAS;IAChB,CACD,OAAO,WAAW,QAAQ,MAAM,gDAAgD,OAAO,CAAC;GAGhG;AAGD,iBAAgB;EACd,MAAM,UAAU,WACd;GACE,MAAM;GACN,WAAW;GACZ,EACD,mBAAuD,CAAC,QAAQ,EAC9D,QAAQ,2BAA0C,EACnD,CAAC,CACH;EAMD,IAAIA;AACJ,UAAQ,GAAG,uBAAuB,SAAS;AACzC,eAAY,OAAO;AACnB,gBAAa,IAAI,iBAAiB;AAClC,2BAAwB,KAAK,aAAa,WAAW,OAAO;IAC5D;EAEF,MAAM,OAAO,QAAQ,OAAO;AAE5B,aAAW,QAAQ;AAEnB,eAAa;AAEX,SAAM;;IAEP,EAAE,CAAC;AA0CN,QAAO;;AAET,oBAAoB,cAAc;AAElC,IAAA,8BAAe"}
1
+ {"version":3,"file":"PresentationComlink2.js","names":[],"sources":["../src/live/client-components/live/PresentationComlink.tsx"],"sourcesContent":["import type {ClientPerspective} from '@sanity/client'\n\nimport {\n createNode,\n createNodeMachine,\n // type Node,\n} from '@sanity/comlink'\nimport {setComlink, setComlinkClientConfig} from '#client-components/context'\nimport {\n createCompatibilityActors,\n type LoaderControllerMsg,\n type LoaderNodeMsg,\n} from '@sanity/presentation-comlink'\nimport {setPerspectiveCookie} from 'next-sanity/live/server-actions'\nimport {useRouter} from 'next/navigation'\nimport {useEffect, useEffectEvent} from 'react'\n\nfunction PresentationComlink(props: {\n projectId: string\n dataset: string\n // handleDraftModeAction: (secret: string) => Promise<void | string>\n draftModeEnabled: boolean\n draftModePerspective: ClientPerspective\n}): React.JSX.Element | null {\n const {projectId, dataset, draftModeEnabled, draftModePerspective} = props\n const router = useRouter()\n\n // const [presentationComlink, setPresentationComlink] = useState<Node<\n // LoaderControllerMsg,\n // LoaderNodeMsg\n // > | null>(null)\n\n useEffect(() => {\n setComlinkClientConfig(projectId, dataset)\n }, [dataset, projectId])\n\n const handlePerspectiveChange = useEffectEvent(\n (perspective: ClientPerspective, signal: AbortSignal) => {\n if (draftModeEnabled && perspective !== draftModePerspective) {\n setPerspectiveCookie(perspective)\n .then(() => {\n if (signal.aborted) return\n router.refresh()\n })\n .catch((reason) => console.error('Failed to set the preview perspective cookie', reason))\n }\n },\n )\n\n // const [status, setStatus] = useState('disconnected')\n useEffect(() => {\n const comlink = createNode<LoaderNodeMsg, LoaderControllerMsg>(\n {\n name: 'loaders',\n connectTo: 'presentation',\n },\n createNodeMachine<LoaderNodeMsg, LoaderControllerMsg>().provide({\n actors: createCompatibilityActors<LoaderNodeMsg>(),\n }),\n )\n\n // comlink.onStatus((status) => {\n // setStatus(status)\n // })\n\n let controller: AbortController | undefined\n comlink.on('loader/perspective', (data) => {\n controller?.abort()\n controller = new AbortController()\n handlePerspectiveChange(data.perspective, controller.signal)\n })\n\n const stop = comlink.start()\n // setPresentationComlink(comlink)\n setComlink(comlink)\n // console.log('setting comlink', comlink)\n return () => {\n // console.log('stopping comlink')\n stop()\n }\n }, [])\n\n // @TODO come back to this later\n // const handleEnableDraftMode = useEffectEvent(async (signal: AbortSignal) => {\n // if (signal.aborted) return\n // const {secret} = await (presentationComlink?.fetch(\n // {\n // type: 'loader/fetch-preview-url-secret' as const,\n // data: {projectId, dataset},\n // },\n // {signal},\n // ) || {secret: null})\n // if (signal.aborted) return\n // const error = await handleDraftModeAction(secret!)\n // // eslint-disable-next-line no-console\n // // @TODO call another server action here that can tell us if draft mode is actually enabled\n // if (error) {\n // // @TODO use sonnet or whatever to push a toast with the error\n // // eslint-disable-next-line no-console\n // console.error('Error enabling draft mode', error)\n // return\n // }\n // // console.log('Draft mode enabled?', {enabled})\n // if (signal.aborted) return\n // router.refresh()\n // })\n // const connected = status === 'connected'\n // useEffect(() => {\n // if (connected && !draftModeEnabled) {\n // const controller = new AbortController()\n // handleEnableDraftMode(controller.signal).catch((reason) => {\n // // eslint-disable-next-line no-console\n // console.error('Failed to enable draft mode', reason)\n // return handleEnableDraftMode(controller.signal)\n // })\n // return () => {\n // controller.abort()\n // }\n // }\n // return undefined\n // }, [connected, draftModeEnabled, handleEnableDraftMode])\n\n return null\n}\nPresentationComlink.displayName = 'PresentationComlink'\n\nexport default PresentationComlink\n"],"mappings":";;;;;;AAiBA,SAAS,oBAAoB,OAMA;CAC3B,MAAM,EAAC,WAAW,SAAS,kBAAkB,yBAAwB;CACrE,MAAM,SAAS,WAAW;AAO1B,iBAAgB;AACd,yBAAuB,WAAW,QAAQ;IACzC,CAAC,SAAS,UAAU,CAAC;CAExB,MAAM,0BAA0B,gBAC7B,aAAgC,WAAwB;AACvD,MAAI,oBAAoB,gBAAgB,qBACtC,sBAAqB,YAAY,CAC9B,WAAW;AACV,OAAI,OAAO,QAAS;AACpB,UAAO,SAAS;IAChB,CACD,OAAO,WAAW,QAAQ,MAAM,gDAAgD,OAAO,CAAC;GAGhG;AAGD,iBAAgB;EACd,MAAM,UAAU,WACd;GACE,MAAM;GACN,WAAW;GACZ,EACD,mBAAuD,CAAC,QAAQ,EAC9D,QAAQ,2BAA0C,EACnD,CAAC,CACH;EAMD,IAAI;AACJ,UAAQ,GAAG,uBAAuB,SAAS;AACzC,eAAY,OAAO;AACnB,gBAAa,IAAI,iBAAiB;AAClC,2BAAwB,KAAK,aAAa,WAAW,OAAO;IAC5D;EAEF,MAAM,OAAO,QAAQ,OAAO;AAE5B,aAAW,QAAQ;AAEnB,eAAa;AAEX,SAAM;;IAEP,EAAE,CAAC;AA0CN,QAAO;;AAET,oBAAoB,cAAc;AAElC,IAAA,8BAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":["perspectiveListeners: Set<() => void>","perspective: LivePerspective","environmentListeners: Set<() => void>","environment: LiveEnvironment","comlinkListeners: Set<() => void>","comlink: Node<LoaderNodeMsg, LoaderControllerMsg> | null","comlinkProjectId: string | null","comlinkDataset: string | null"],"sources":["../src/shared/client-components/context.tsx"],"sourcesContent":["import type {ClientPerspective} from '@sanity/client'\nimport type {Node} from '@sanity/comlink'\nimport type {LoaderControllerMsg, LoaderNodeMsg} from '@sanity/presentation-comlink'\n\nexport type LivePerspective = 'checking' | 'unknown' | ClientPerspective\n\nexport const perspectiveListeners: Set<() => void> = new Set()\nexport let perspective: LivePerspective = 'checking'\nexport function setPerspective(nextPerspective: LivePerspective): void {\n if (perspective.toString() === nextPerspective.toString()) return\n perspective = nextPerspective\n for (const onPerspectiveChange of perspectiveListeners) {\n onPerspectiveChange()\n }\n}\n\nexport type LiveEnvironment =\n | 'checking'\n | 'presentation-iframe'\n | 'presentation-window'\n | 'live'\n | 'static'\n | 'unknown'\n\nexport const environmentListeners: Set<() => void> = new Set()\nexport let environment: LiveEnvironment = 'checking'\nexport function setEnvironment(nextEnvironment: LiveEnvironment): void {\n environment = nextEnvironment\n for (const onEnvironmentChange of environmentListeners) {\n onEnvironmentChange()\n }\n}\n\nexport const comlinkListeners: Set<() => void> = new Set()\nexport let comlink: Node<LoaderNodeMsg, LoaderControllerMsg> | null = null\nexport let comlinkProjectId: string | null = null\nexport let comlinkDataset: string | null = null\nexport function setComlink(nextComlink: Node<LoaderNodeMsg, LoaderControllerMsg> | null): void {\n comlink = nextComlink\n for (const onComlinkChange of comlinkListeners) {\n onComlinkChange()\n }\n}\nexport function setComlinkClientConfig(\n nextComlinkProjectId: string | null,\n nextComlinkDataset: string | null,\n): void {\n comlinkProjectId = nextComlinkProjectId\n comlinkDataset = nextComlinkDataset\n for (const onComlinkChange of comlinkListeners) {\n onComlinkChange()\n }\n}\n"],"mappings":"AAMA,MAAaA,uCAAwC,IAAI,KAAK;AAC9D,IAAWC,cAA+B;AAC1C,SAAgB,eAAe,iBAAwC;AACrE,KAAI,YAAY,UAAU,KAAK,gBAAgB,UAAU,CAAE;AAC3D,eAAc;AACd,MAAK,MAAM,uBAAuB,qBAChC,sBAAqB;;AAYzB,MAAaC,uCAAwC,IAAI,KAAK;AAC9D,IAAWC,cAA+B;AAC1C,SAAgB,eAAe,iBAAwC;AACrE,eAAc;AACd,MAAK,MAAM,uBAAuB,qBAChC,sBAAqB;;AAIzB,MAAaC,mCAAoC,IAAI,KAAK;AAC1D,IAAWC,UAA2D;AACtE,IAAWC,mBAAkC;AAC7C,IAAWC,iBAAgC;AAC3C,SAAgB,WAAW,aAAoE;AAC7F,WAAU;AACV,MAAK,MAAM,mBAAmB,iBAC5B,kBAAiB;;AAGrB,SAAgB,uBACd,sBACA,oBACM;AACN,oBAAmB;AACnB,kBAAiB;AACjB,MAAK,MAAM,mBAAmB,iBAC5B,kBAAiB"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../src/shared/client-components/context.tsx"],"sourcesContent":["import type {ClientPerspective} from '@sanity/client'\nimport type {Node} from '@sanity/comlink'\nimport type {LoaderControllerMsg, LoaderNodeMsg} from '@sanity/presentation-comlink'\n\nexport type LivePerspective = 'checking' | 'unknown' | ClientPerspective\n\nexport const perspectiveListeners: Set<() => void> = new Set()\nexport let perspective: LivePerspective = 'checking'\nexport function setPerspective(nextPerspective: LivePerspective): void {\n if (perspective.toString() === nextPerspective.toString()) return\n perspective = nextPerspective\n for (const onPerspectiveChange of perspectiveListeners) {\n onPerspectiveChange()\n }\n}\n\nexport type LiveEnvironment =\n | 'checking'\n | 'presentation-iframe'\n | 'presentation-window'\n | 'live'\n | 'static'\n | 'unknown'\n\nexport const environmentListeners: Set<() => void> = new Set()\nexport let environment: LiveEnvironment = 'checking'\nexport function setEnvironment(nextEnvironment: LiveEnvironment): void {\n environment = nextEnvironment\n for (const onEnvironmentChange of environmentListeners) {\n onEnvironmentChange()\n }\n}\n\nexport const comlinkListeners: Set<() => void> = new Set()\nexport let comlink: Node<LoaderNodeMsg, LoaderControllerMsg> | null = null\nexport let comlinkProjectId: string | null = null\nexport let comlinkDataset: string | null = null\nexport function setComlink(nextComlink: Node<LoaderNodeMsg, LoaderControllerMsg> | null): void {\n comlink = nextComlink\n for (const onComlinkChange of comlinkListeners) {\n onComlinkChange()\n }\n}\nexport function setComlinkClientConfig(\n nextComlinkProjectId: string | null,\n nextComlinkDataset: string | null,\n): void {\n comlinkProjectId = nextComlinkProjectId\n comlinkDataset = nextComlinkDataset\n for (const onComlinkChange of comlinkListeners) {\n onComlinkChange()\n }\n}\n"],"mappings":"AAMA,MAAa,uCAAwC,IAAI,KAAK;AAC9D,IAAW,cAA+B;AAC1C,SAAgB,eAAe,iBAAwC;AACrE,KAAI,YAAY,UAAU,KAAK,gBAAgB,UAAU,CAAE;AAC3D,eAAc;AACd,MAAK,MAAM,uBAAuB,qBAChC,sBAAqB;;AAYzB,MAAa,uCAAwC,IAAI,KAAK;AAC9D,IAAW,cAA+B;AAC1C,SAAgB,eAAe,iBAAwC;AACrE,eAAc;AACd,MAAK,MAAM,uBAAuB,qBAChC,sBAAqB;;AAIzB,MAAa,mCAAoC,IAAI,KAAK;AAC1D,IAAW,UAA2D;AACtE,IAAW,mBAAkC;AAC7C,IAAW,iBAAgC;AAC3C,SAAgB,WAAW,aAAoE;AAC7F,WAAU;AACV,MAAK,MAAM,mBAAmB,iBAC5B,kBAAiB;;AAGrB,SAAgB,uBACd,sBACA,oBACM;AACN,oBAAmB;AACnB,kBAAiB;AACjB,MAAK,MAAM,mBAAmB,iBAC5B,kBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":["perspectiveListeners: Set<() => void>","perspective: LivePerspective","environmentListeners: Set<() => void>","environment: LiveEnvironment","comlinkListeners: Set<() => void>","comlink: Node<LoaderNodeMsg, LoaderControllerMsg> | null","comlinkProjectId: string | null","comlinkDataset: string | null"],"sources":["../../src/shared/client-components/context.tsx","../../src/live/hooks/useDraftMode.ts","../../src/live/hooks/useIsPresentationTool.ts","../../src/live/hooks/useIsLivePreview.ts","../../src/live/hooks/usePresentationQuery.ts"],"sourcesContent":[],"mappings":";;;;KAIY,eAAA,4BAA2C;KAY3C,eAAA;;;;;AAZZ;AAYA;;ACIA;AAmBA;;AC3BgB,iBDQA,uBAAA,CAAA,CCRA,EDQ2B,eCR3B;;ACKhB;;ACDA;AAOA;;AACQ,iBHeQ,uBAAA,CAAA,CGfR,EHemC,eGfnC;;;;;;AJpBR;AAYA;;ACIA;AAmBA;iBC3BgB,qBAAA,CAAA;;;;;;AFRhB;AAYA;;ACIA;AAmBA;;AC3BA;;ACKA;;ACDY,iBDCI,gBAAA,CAAA,CCDJ,EAAA,OAAA,GAAA,IAAA;;KAAA,mCAAA;;;EJZZ,WAAY,EAAA,IAAA;AAYZ,CAAA;;ACIgB,KGGJ,iCHH+B,CAAA,oBAAA,MAAA,CAAA,GAAA;EAmB3C,IAAgB,EGfR,YHeQ,CGfK,WHeL,CAAA;aGdH;EFbb,WAAgB,EEcD,iBFdC;;ACKA,KCYJ,2BDZI,CAAA,oBAAA,MAAA,CAAA,GCaZ,mCDbY,GCcZ,iCDdY,CCcsB,WDdtB,CAAA;;ACDhB;AAOA;;;;;;AAMY,iBAyDI,oBAzDJ,CAAA,0BAAA,MAAA,CAAA,CAAA,KAAA,EAAA;EACR,KAAA,EAyDK,WAzDL;EACkC,MAAA,CAAA,EAyD3B,WAzD2B,GAyDb,OAzDa,CAyDL,WAzDK,CAAA;EAAlC,KAAA,CAAA,EAAA,OAAA;CAAA,CAAA,EA2DA,2BA3DA,CA2D4B,WA3D5B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/shared/client-components/context.tsx","../../src/live/hooks/useDraftMode.ts","../../src/live/hooks/useIsPresentationTool.ts","../../src/live/hooks/useIsLivePreview.ts","../../src/live/hooks/usePresentationQuery.ts"],"sourcesContent":[],"mappings":";;;;KAIY,eAAA,4BAA2C;KAY3C,eAAA;;;;;AAZZ;AAYA;;ACIA;AAmBA;;AC3BgB,iBDQA,uBAAA,CAAA,CCRA,EDQ2B,eCR3B;;ACKhB;;ACDA;AAOA;;AACQ,iBHeQ,uBAAA,CAAA,CGfR,EHemC,eGfnC;;;;;;AJpBR;AAYA;;ACIA;AAmBA;iBC3BgB,qBAAA,CAAA;;;;;;AFRhB;AAYA;;ACIA;AAmBA;;AC3BA;;ACKA;;ACDY,iBDCI,gBAAA,CAAA,CCDJ,EAAA,OAAA,GAAA,IAAA;;KAAA,mCAAA;;;EJZZ,WAAY,EAAA,IAAA;AAYZ,CAAA;;ACIgB,KGGJ,iCHH+B,CAAA,oBAAA,MAAA,CAAA,GAAA;EAmB3C,IAAgB,EGfR,YHeQ,CGfK,WHeL,CAAA;aGdH;EFbb,WAAgB,EEcD,iBFdC;;ACKA,KCYJ,2BDZI,CAAA,oBAAA,MAAA,CAAA,GCaZ,mCDbY,GCcZ,iCDdY,CCcsB,WDdtB,CAAA;;ACDhB;AAOA;;;;;;AAMY,iBAyDI,oBAzDJ,CAAA,0BAAA,MAAA,CAAA,CAAA,KAAA,EAAA;EACR,KAAA,EAyDK,WAzDL;EACkC,MAAA,CAAA,EAyD3B,WAzD2B,GAyDb,OAzDa,CAyDL,WAzDK,CAAA;EAAlC,KAAA,CAAA,EAAA,OAAA;CAAA,CAAA,EA2DA,2BA3DA,CA2D4B,WA3D5B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["environment","environment","initialState: UsePresentationQueryReturnsInactive","EMPTY_QUERY_PARAMS: QueryParams","comlink","comlinkSnapshot","perspective"],"sources":["../../src/live/hooks/useDraftMode.ts","../../src/live/hooks/useIsPresentationTool.ts","../../src/live/hooks/useIsLivePreview.ts","../../src/live/hooks/usePresentationQuery.ts"],"sourcesContent":["import {\n environment,\n environmentListeners,\n perspective,\n perspectiveListeners,\n type LiveEnvironment,\n type LivePerspective,\n} from '#client-components/context'\nimport {useCallback, useSyncExternalStore} from 'react'\n\n/**\n * Reports the current draft mode environment.\n * Use it to determine how to adapt the UI based on wether:\n * - Your app is previewed in a iframe, inside Presentation Tool in a Sanity Studio.\n * - Your app is previewed in a new window, spawned from Presentation Tool in a Sanity Studio.\n * - Your app is live previewing drafts in a standalone context.\n * - Your app is previewing drafts, but not live.\n * - Your app is not previewing anything (that could be detected).\n * @public\n */\nexport function useDraftModeEnvironment(): LiveEnvironment {\n const subscribe = useCallback((listener: () => void) => {\n environmentListeners.add(listener)\n return () => environmentListeners.delete(listener)\n }, [])\n\n return useSyncExternalStore(\n subscribe,\n () => environment,\n () => 'checking',\n )\n}\n\n/**\n * Reports the Sanity Client perspective used to fetch data in `sanityFetch` used on the page.\n * If the hook is used outside Draft Mode it will resolve to `'unknown'`.\n * If the hook is used but the `<SanityLive />` component is not present then it'll stay in `'checking'` and console warn after a timeout that it seems like you're missing the component.\n * @public\n */\nexport function useDraftModePerspective(): LivePerspective {\n const subscribe = useCallback((listener: () => void) => {\n perspectiveListeners.add(listener)\n return () => perspectiveListeners.delete(listener)\n }, [])\n\n return useSyncExternalStore(\n subscribe,\n () => perspective,\n () => 'checking',\n )\n}\n","import {useDraftModeEnvironment} from './useDraftMode'\n\n/**\n * Detects if the application is being previewed inside Sanity Presentation Tool.\n * Presentation Tool can open the application in an iframe, or in a new window.\n * When in this context there are some UI you usually don't want to show,\n * for example a Draft Mode toggle, or a \"Viewing draft content\" indicators, these are unnecessary and add clutter to\n * the editorial experience.\n * The hook returns `null` initially, when it's not yet sure if the application is running inside Presentation Tool,\n * then `true` if it is, and `false` otherwise.\n * @public\n */\nexport function useIsPresentationTool(): boolean | null {\n const environment = useDraftModeEnvironment()\n return environment === 'checking'\n ? null\n : environment === 'presentation-iframe' || environment === 'presentation-window'\n}\n","import {useDraftModeEnvironment} from './useDraftMode'\n\n/**\n * Detects if the application is considered to be in a \"Live Preview\" mode.\n * Live Preview means that the application is either:\n * - being previewed inside Sanity Presentation Tool\n * - being previewed in Draft Mode, with a `browserToken` given to `defineLive`, also known as \"Standalone Live Preview'\"\n * When in Live Preview mode, you typically want UI to update as new content comes in, without any manual intervention.\n * This is very different from Live Production mode, where you usually want to delay updates that might cause layout shifts,\n * to avoid interrupting the user that is consuming your content.\n * This hook lets you adapt to this difference, making sure production doesn't cause layout shifts that worsen the UX,\n * while in Live Preview mode layout shift is less of an issue and it's better for the editorial experience to auto refresh in real time.\n *\n * The hook returns `null` initially, to signal it doesn't yet know if it's live previewing or not.\n * Then `true` if it is, and `false` otherwise.\n * @public\n */\nexport function useIsLivePreview(): boolean | null {\n const environment = useDraftModeEnvironment()\n return environment === 'checking'\n ? null\n : environment === 'presentation-iframe' ||\n environment === 'presentation-window' ||\n environment === 'live'\n}\n","import type {ClientPerspective, ClientReturn, ContentSourceMap, QueryParams} from '@sanity/client'\nimport type {LoaderControllerMsg} from '@sanity/presentation-comlink'\n\nimport {\n comlinkDataset,\n comlinkListeners,\n comlinkProjectId,\n comlink as comlinkSnapshot,\n} from '#client-components/context'\nimport {stegaEncodeSourceMap} from '@sanity/client/stega'\nimport {dequal} from 'dequal/lite'\nimport {useEffect, useMemo, useReducer, useSyncExternalStore, useEffectEvent} from 'react'\n\nimport {useDraftModePerspective} from './useDraftMode'\n\n/** @alpha */\nexport type UsePresentationQueryReturnsInactive = {\n data: null\n sourceMap: null\n perspective: null\n}\n\n/** @alpha */\nexport type UsePresentationQueryReturnsActive<QueryString extends string> = {\n data: ClientReturn<QueryString>\n sourceMap: ContentSourceMap | null\n perspective: ClientPerspective\n}\n\nexport type UsePresentationQueryReturns<QueryString extends string> =\n | UsePresentationQueryReturnsInactive\n | UsePresentationQueryReturnsActive<QueryString>\n\ntype Action<QueryString extends string> = {\n type: 'query-change'\n payload: UsePresentationQueryReturnsActive<QueryString>\n}\n\nfunction reducer<QueryString extends string>(\n state: UsePresentationQueryReturns<QueryString>,\n {type, payload}: Action<QueryString>,\n): UsePresentationQueryReturns<QueryString> {\n switch (type) {\n case 'query-change':\n return dequal(state, payload)\n ? state\n : {\n ...state,\n data: dequal(state.data, payload.data)\n ? // oxlint-disable-next-line no-unsafe-type-assertion\n (state.data as ClientReturn<QueryString>)\n : payload.data,\n sourceMap: dequal(state.sourceMap, payload.sourceMap)\n ? state.sourceMap\n : payload.sourceMap,\n perspective: dequal(state.perspective, payload.perspective)\n ? // oxlint-disable-next-line no-unsafe-type-assertion\n (state.perspective as Exclude<ClientPerspective, 'raw'>)\n : payload.perspective,\n }\n default:\n return state\n }\n}\nconst initialState: UsePresentationQueryReturnsInactive = {\n data: null,\n sourceMap: null,\n perspective: null,\n}\n\nfunction subscribe(listener: () => void) {\n comlinkListeners.add(listener)\n return () => comlinkListeners.delete(listener)\n}\n\nconst EMPTY_QUERY_PARAMS: QueryParams = {}\nconst LISTEN_HEARTBEAT_INTERVAL = 10_000\n\n/**\n * Experimental hook that can run queries in Presentation Tool.\n * Query results are sent back over postMessage whenever the query results change.\n * It also works with optimistic updates in the studio itself, offering low latency updates.\n * It's not as low latency as the `useOptimistic` hook, but it's a good compromise for some use cases.\n * Especially until `useOptimistic` propagates edits in the Studio parent window back into the iframe.\n * @alpha\n */\nexport function usePresentationQuery<const QueryString extends string>(props: {\n query: QueryString\n params?: QueryParams | Promise<QueryParams>\n stega?: boolean\n}): UsePresentationQueryReturns<QueryString> {\n const [state, dispatch] = useReducer(reducer, initialState)\n const {query, params = EMPTY_QUERY_PARAMS, stega = true} = props\n\n /**\n * Comlink forwards queries we want to run to the parent window where Presentation Tool handles it for us\n */\n const comlink = useSyncExternalStore(\n subscribe,\n () => comlinkSnapshot,\n () => null,\n )\n /**\n * The comlink events requires projectId and dataset, Presentation Tool uses it to protect against project and dataset mismatch errors.\n * We don't want to force the consumers of the `usePresentationQuery` hook to provide these,\n * so we set them in the component that establishes the comlink connection and propagates it to all the subscribes.\n */\n const projectId = useSyncExternalStore(\n subscribe,\n () => comlinkProjectId,\n () => null,\n )\n const dataset = useSyncExternalStore(\n subscribe,\n () => comlinkDataset,\n () => null,\n )\n /**\n * The perspective is kept in sync with Presentation Tool's perspective, and even knows what perspective the page loaded with initially and can forward it to the Sanity Studio.\n */\n const perspective = useDraftModePerspective()\n const handleQueryHeartbeat = useEffectEvent((comlink: NonNullable<typeof comlinkSnapshot>) => {\n // Handle odd case where the comlink can take events but some data is missing\n if (!projectId || !dataset || !perspective) {\n console.warn('usePresentationQuery: projectId, dataset and perspective must be set', {\n projectId,\n dataset,\n perspective,\n })\n return\n }\n // Another odd case where the initial perspective states haven't resolved to the actual perspective state\n if (perspective === 'checking' || perspective === 'unknown') {\n return\n }\n comlink.post('loader/query-listen', {\n projectId,\n dataset,\n perspective,\n query,\n params,\n heartbeat: LISTEN_HEARTBEAT_INTERVAL,\n })\n })\n const handleQueryChange = useEffectEvent(\n (event: Extract<LoaderControllerMsg, {type: 'loader/query-change'}>['data']) => {\n if (\n dequal(\n {\n projectId,\n dataset,\n query,\n params,\n },\n {\n projectId: event.projectId,\n dataset: event.dataset,\n query: event.query,\n params: event.params,\n },\n )\n ) {\n dispatch({\n type: 'query-change',\n payload: {\n data: event.result,\n sourceMap: event.resultSourceMap || null,\n perspective: event.perspective,\n },\n })\n }\n },\n )\n useEffect(() => {\n if (!comlink) return\n\n const unsubscribe = comlink.on('loader/query-change', handleQueryChange)\n const interval = setInterval(() => handleQueryHeartbeat(comlink), LISTEN_HEARTBEAT_INTERVAL)\n return () => {\n clearInterval(interval)\n unsubscribe()\n }\n }, [comlink])\n\n return useMemo(() => {\n if (stega && state.sourceMap) {\n return {\n ...state,\n data: stegaEncodeSourceMap(state.data, state.sourceMap, {enabled: true, studioUrl: '/'}),\n }\n }\n return state\n }, [state, stega])\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["environment","environment","comlink","comlinkSnapshot","perspective"],"sources":["../../src/live/hooks/useDraftMode.ts","../../src/live/hooks/useIsPresentationTool.ts","../../src/live/hooks/useIsLivePreview.ts","../../src/live/hooks/usePresentationQuery.ts"],"sourcesContent":["import {\n environment,\n environmentListeners,\n perspective,\n perspectiveListeners,\n type LiveEnvironment,\n type LivePerspective,\n} from '#client-components/context'\nimport {useCallback, useSyncExternalStore} from 'react'\n\n/**\n * Reports the current draft mode environment.\n * Use it to determine how to adapt the UI based on wether:\n * - Your app is previewed in a iframe, inside Presentation Tool in a Sanity Studio.\n * - Your app is previewed in a new window, spawned from Presentation Tool in a Sanity Studio.\n * - Your app is live previewing drafts in a standalone context.\n * - Your app is previewing drafts, but not live.\n * - Your app is not previewing anything (that could be detected).\n * @public\n */\nexport function useDraftModeEnvironment(): LiveEnvironment {\n const subscribe = useCallback((listener: () => void) => {\n environmentListeners.add(listener)\n return () => environmentListeners.delete(listener)\n }, [])\n\n return useSyncExternalStore(\n subscribe,\n () => environment,\n () => 'checking',\n )\n}\n\n/**\n * Reports the Sanity Client perspective used to fetch data in `sanityFetch` used on the page.\n * If the hook is used outside Draft Mode it will resolve to `'unknown'`.\n * If the hook is used but the `<SanityLive />` component is not present then it'll stay in `'checking'` and console warn after a timeout that it seems like you're missing the component.\n * @public\n */\nexport function useDraftModePerspective(): LivePerspective {\n const subscribe = useCallback((listener: () => void) => {\n perspectiveListeners.add(listener)\n return () => perspectiveListeners.delete(listener)\n }, [])\n\n return useSyncExternalStore(\n subscribe,\n () => perspective,\n () => 'checking',\n )\n}\n","import {useDraftModeEnvironment} from './useDraftMode'\n\n/**\n * Detects if the application is being previewed inside Sanity Presentation Tool.\n * Presentation Tool can open the application in an iframe, or in a new window.\n * When in this context there are some UI you usually don't want to show,\n * for example a Draft Mode toggle, or a \"Viewing draft content\" indicators, these are unnecessary and add clutter to\n * the editorial experience.\n * The hook returns `null` initially, when it's not yet sure if the application is running inside Presentation Tool,\n * then `true` if it is, and `false` otherwise.\n * @public\n */\nexport function useIsPresentationTool(): boolean | null {\n const environment = useDraftModeEnvironment()\n return environment === 'checking'\n ? null\n : environment === 'presentation-iframe' || environment === 'presentation-window'\n}\n","import {useDraftModeEnvironment} from './useDraftMode'\n\n/**\n * Detects if the application is considered to be in a \"Live Preview\" mode.\n * Live Preview means that the application is either:\n * - being previewed inside Sanity Presentation Tool\n * - being previewed in Draft Mode, with a `browserToken` given to `defineLive`, also known as \"Standalone Live Preview'\"\n * When in Live Preview mode, you typically want UI to update as new content comes in, without any manual intervention.\n * This is very different from Live Production mode, where you usually want to delay updates that might cause layout shifts,\n * to avoid interrupting the user that is consuming your content.\n * This hook lets you adapt to this difference, making sure production doesn't cause layout shifts that worsen the UX,\n * while in Live Preview mode layout shift is less of an issue and it's better for the editorial experience to auto refresh in real time.\n *\n * The hook returns `null` initially, to signal it doesn't yet know if it's live previewing or not.\n * Then `true` if it is, and `false` otherwise.\n * @public\n */\nexport function useIsLivePreview(): boolean | null {\n const environment = useDraftModeEnvironment()\n return environment === 'checking'\n ? null\n : environment === 'presentation-iframe' ||\n environment === 'presentation-window' ||\n environment === 'live'\n}\n","import type {ClientPerspective, ClientReturn, ContentSourceMap, QueryParams} from '@sanity/client'\nimport type {LoaderControllerMsg} from '@sanity/presentation-comlink'\n\nimport {\n comlinkDataset,\n comlinkListeners,\n comlinkProjectId,\n comlink as comlinkSnapshot,\n} from '#client-components/context'\nimport {stegaEncodeSourceMap} from '@sanity/client/stega'\nimport {dequal} from 'dequal/lite'\nimport {useEffect, useMemo, useReducer, useSyncExternalStore, useEffectEvent} from 'react'\n\nimport {useDraftModePerspective} from './useDraftMode'\n\n/** @alpha */\nexport type UsePresentationQueryReturnsInactive = {\n data: null\n sourceMap: null\n perspective: null\n}\n\n/** @alpha */\nexport type UsePresentationQueryReturnsActive<QueryString extends string> = {\n data: ClientReturn<QueryString>\n sourceMap: ContentSourceMap | null\n perspective: ClientPerspective\n}\n\nexport type UsePresentationQueryReturns<QueryString extends string> =\n | UsePresentationQueryReturnsInactive\n | UsePresentationQueryReturnsActive<QueryString>\n\ntype Action<QueryString extends string> = {\n type: 'query-change'\n payload: UsePresentationQueryReturnsActive<QueryString>\n}\n\nfunction reducer<QueryString extends string>(\n state: UsePresentationQueryReturns<QueryString>,\n {type, payload}: Action<QueryString>,\n): UsePresentationQueryReturns<QueryString> {\n switch (type) {\n case 'query-change':\n return dequal(state, payload)\n ? state\n : {\n ...state,\n data: dequal(state.data, payload.data)\n ? // oxlint-disable-next-line no-unsafe-type-assertion\n (state.data as ClientReturn<QueryString>)\n : payload.data,\n sourceMap: dequal(state.sourceMap, payload.sourceMap)\n ? state.sourceMap\n : payload.sourceMap,\n perspective: dequal(state.perspective, payload.perspective)\n ? // oxlint-disable-next-line no-unsafe-type-assertion\n (state.perspective as Exclude<ClientPerspective, 'raw'>)\n : payload.perspective,\n }\n default:\n return state\n }\n}\nconst initialState: UsePresentationQueryReturnsInactive = {\n data: null,\n sourceMap: null,\n perspective: null,\n}\n\nfunction subscribe(listener: () => void) {\n comlinkListeners.add(listener)\n return () => comlinkListeners.delete(listener)\n}\n\nconst EMPTY_QUERY_PARAMS: QueryParams = {}\nconst LISTEN_HEARTBEAT_INTERVAL = 10_000\n\n/**\n * Experimental hook that can run queries in Presentation Tool.\n * Query results are sent back over postMessage whenever the query results change.\n * It also works with optimistic updates in the studio itself, offering low latency updates.\n * It's not as low latency as the `useOptimistic` hook, but it's a good compromise for some use cases.\n * Especially until `useOptimistic` propagates edits in the Studio parent window back into the iframe.\n * @alpha\n */\nexport function usePresentationQuery<const QueryString extends string>(props: {\n query: QueryString\n params?: QueryParams | Promise<QueryParams>\n stega?: boolean\n}): UsePresentationQueryReturns<QueryString> {\n const [state, dispatch] = useReducer(reducer, initialState)\n const {query, params = EMPTY_QUERY_PARAMS, stega = true} = props\n\n /**\n * Comlink forwards queries we want to run to the parent window where Presentation Tool handles it for us\n */\n const comlink = useSyncExternalStore(\n subscribe,\n () => comlinkSnapshot,\n () => null,\n )\n /**\n * The comlink events requires projectId and dataset, Presentation Tool uses it to protect against project and dataset mismatch errors.\n * We don't want to force the consumers of the `usePresentationQuery` hook to provide these,\n * so we set them in the component that establishes the comlink connection and propagates it to all the subscribes.\n */\n const projectId = useSyncExternalStore(\n subscribe,\n () => comlinkProjectId,\n () => null,\n )\n const dataset = useSyncExternalStore(\n subscribe,\n () => comlinkDataset,\n () => null,\n )\n /**\n * The perspective is kept in sync with Presentation Tool's perspective, and even knows what perspective the page loaded with initially and can forward it to the Sanity Studio.\n */\n const perspective = useDraftModePerspective()\n const handleQueryHeartbeat = useEffectEvent((comlink: NonNullable<typeof comlinkSnapshot>) => {\n // Handle odd case where the comlink can take events but some data is missing\n if (!projectId || !dataset || !perspective) {\n console.warn('usePresentationQuery: projectId, dataset and perspective must be set', {\n projectId,\n dataset,\n perspective,\n })\n return\n }\n // Another odd case where the initial perspective states haven't resolved to the actual perspective state\n if (perspective === 'checking' || perspective === 'unknown') {\n return\n }\n comlink.post('loader/query-listen', {\n projectId,\n dataset,\n perspective,\n query,\n params,\n heartbeat: LISTEN_HEARTBEAT_INTERVAL,\n })\n })\n const handleQueryChange = useEffectEvent(\n (event: Extract<LoaderControllerMsg, {type: 'loader/query-change'}>['data']) => {\n if (\n dequal(\n {\n projectId,\n dataset,\n query,\n params,\n },\n {\n projectId: event.projectId,\n dataset: event.dataset,\n query: event.query,\n params: event.params,\n },\n )\n ) {\n dispatch({\n type: 'query-change',\n payload: {\n data: event.result,\n sourceMap: event.resultSourceMap || null,\n perspective: event.perspective,\n },\n })\n }\n },\n )\n useEffect(() => {\n if (!comlink) return\n\n const unsubscribe = comlink.on('loader/query-change', handleQueryChange)\n const interval = setInterval(() => handleQueryHeartbeat(comlink), LISTEN_HEARTBEAT_INTERVAL)\n return () => {\n clearInterval(interval)\n unsubscribe()\n }\n }, [comlink])\n\n return useMemo(() => {\n if (stega && state.sourceMap) {\n return {\n ...state,\n data: stegaEncodeSourceMap(state.data, state.sourceMap, {enabled: true, studioUrl: '/'}),\n }\n }\n return state\n }, [state, stega])\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":["imageLoader: ImageLoader"],"sources":["../../src/image/Image.tsx","../../src/image/imageLoader.ts"],"sourcesContent":[],"mappings":";;AAOA;AAcA;UAdiB,UAAA,SAAmB,KAAK;ECFzC;;;;;;;;;;;;iBDgBgB,KAAA,QAAa,aAAa,KAAA,CAAM,GAAA,CAAI;;AAdpD;AAcA;cChBaA,aAAa"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/image/Image.tsx","../../src/image/imageLoader.ts"],"sourcesContent":[],"mappings":";;AAOA;AAcA;UAdiB,UAAA,SAAmB,KAAK;ECFzC;;;;;;;;;;;;iBDgBgB,KAAA,QAAa,aAAa,KAAA,CAAM,GAAA,CAAI;;AAdpD;AAcA;cChBa,aAAa"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["imageLoader: ImageLoader","srcUrl: URL"],"sources":["../../src/image/imageLoader.ts","../../src/image/Image.tsx"],"sourcesContent":["import type {ImageLoader} from 'next/image'\n\n/**\n * @alpha\n */\nexport const imageLoader: ImageLoader = ({src, width, quality}) => {\n const url = new URL(src)\n url.searchParams.set('auto', 'format')\n if (!url.searchParams.has('fit')) {\n url.searchParams.set('fit', url.searchParams.has('h') ? 'min' : 'max')\n }\n if (url.searchParams.has('h') && url.searchParams.has('w')) {\n const originalHeight = parseInt(url.searchParams.get('h')!, 10)\n const originalWidth = parseInt(url.searchParams.get('w')!, 10)\n url.searchParams.set('h', Math.round((originalHeight / originalWidth) * width).toString())\n }\n url.searchParams.set('w', width.toString())\n if (quality) {\n url.searchParams.set('q', quality.toString())\n }\n return url.href\n}\n","import NextImage, {type ImageProps as NextImageProps} from 'next/image'\n\nimport {imageLoader} from './imageLoader'\n\n/**\n * @alpha\n */\nexport interface ImageProps extends Omit<NextImageProps, 'loader' | 'src'> {\n /**\n * The `loader` prop is not supported on `Image` components. Use `next/image` directly to use a custom loader.\n */\n loader?: never\n /**\n * Must be a string that is a valid URL to an image on the Sanity Image CDN.\n */\n src: string\n}\n\n/**\n * @alpha\n */\nexport function Image(props: ImageProps): React.JSX.Element {\n const {loader, src, ...rest} = props\n if (loader) {\n throw new TypeError(\n 'The `loader` prop is not supported on `Image` components. Use `next/image` directly to use a custom loader.',\n )\n }\n let srcUrl: URL\n try {\n srcUrl = new URL(src)\n if (props.height) {\n srcUrl.searchParams.set('h', `${props.height}`)\n }\n if (props.width) {\n srcUrl.searchParams.set('w', `${props.width}`)\n }\n } catch (err) {\n throw new TypeError('The `src` prop must be a valid URL to an image on the Sanity Image CDN.', {\n cause: err,\n })\n }\n return <NextImage {...rest} src={srcUrl.toString()} loader={imageLoader} />\n}\n"],"mappings":";;;AAKA,MAAaA,eAA4B,EAAC,KAAK,OAAO,cAAa;CACjE,MAAM,MAAM,IAAI,IAAI,IAAI;AACxB,KAAI,aAAa,IAAI,QAAQ,SAAS;AACtC,KAAI,CAAC,IAAI,aAAa,IAAI,MAAM,CAC9B,KAAI,aAAa,IAAI,OAAO,IAAI,aAAa,IAAI,IAAI,GAAG,QAAQ,MAAM;AAExE,KAAI,IAAI,aAAa,IAAI,IAAI,IAAI,IAAI,aAAa,IAAI,IAAI,EAAE;EAC1D,MAAM,iBAAiB,SAAS,IAAI,aAAa,IAAI,IAAI,EAAG,GAAG;EAC/D,MAAM,gBAAgB,SAAS,IAAI,aAAa,IAAI,IAAI,EAAG,GAAG;AAC9D,MAAI,aAAa,IAAI,KAAK,KAAK,MAAO,iBAAiB,gBAAiB,MAAM,CAAC,UAAU,CAAC;;AAE5F,KAAI,aAAa,IAAI,KAAK,MAAM,UAAU,CAAC;AAC3C,KAAI,QACF,KAAI,aAAa,IAAI,KAAK,QAAQ,UAAU,CAAC;AAE/C,QAAO,IAAI;;ACCb,SAAgB,MAAM,OAAsC;CAC1D,MAAM,EAAC,QAAQ,KAAK,GAAG,SAAQ;AAC/B,KAAI,OACF,OAAM,IAAI,UACR,8GACD;CAEH,IAAIC;AACJ,KAAI;AACF,WAAS,IAAI,IAAI,IAAI;AACrB,MAAI,MAAM,OACR,QAAO,aAAa,IAAI,KAAK,GAAG,MAAM,SAAS;AAEjD,MAAI,MAAM,MACR,QAAO,aAAa,IAAI,KAAK,GAAG,MAAM,QAAQ;UAEzC,KAAK;AACZ,QAAM,IAAI,UAAU,2EAA2E,EAC7F,OAAO,KACR,CAAC;;AAEJ,QAAO,oBAAC,WAAA;EAAU,GAAI;EAAM,KAAK,OAAO,UAAU;EAAE,QAAQ;GAAe"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/image/imageLoader.ts","../../src/image/Image.tsx"],"sourcesContent":["import type {ImageLoader} from 'next/image'\n\n/**\n * @alpha\n */\nexport const imageLoader: ImageLoader = ({src, width, quality}) => {\n const url = new URL(src)\n url.searchParams.set('auto', 'format')\n if (!url.searchParams.has('fit')) {\n url.searchParams.set('fit', url.searchParams.has('h') ? 'min' : 'max')\n }\n if (url.searchParams.has('h') && url.searchParams.has('w')) {\n const originalHeight = parseInt(url.searchParams.get('h')!, 10)\n const originalWidth = parseInt(url.searchParams.get('w')!, 10)\n url.searchParams.set('h', Math.round((originalHeight / originalWidth) * width).toString())\n }\n url.searchParams.set('w', width.toString())\n if (quality) {\n url.searchParams.set('q', quality.toString())\n }\n return url.href\n}\n","import NextImage, {type ImageProps as NextImageProps} from 'next/image'\n\nimport {imageLoader} from './imageLoader'\n\n/**\n * @alpha\n */\nexport interface ImageProps extends Omit<NextImageProps, 'loader' | 'src'> {\n /**\n * The `loader` prop is not supported on `Image` components. Use `next/image` directly to use a custom loader.\n */\n loader?: never\n /**\n * Must be a string that is a valid URL to an image on the Sanity Image CDN.\n */\n src: string\n}\n\n/**\n * @alpha\n */\nexport function Image(props: ImageProps): React.JSX.Element {\n const {loader, src, ...rest} = props\n if (loader) {\n throw new TypeError(\n 'The `loader` prop is not supported on `Image` components. Use `next/image` directly to use a custom loader.',\n )\n }\n let srcUrl: URL\n try {\n srcUrl = new URL(src)\n if (props.height) {\n srcUrl.searchParams.set('h', `${props.height}`)\n }\n if (props.width) {\n srcUrl.searchParams.set('w', `${props.width}`)\n }\n } catch (err) {\n throw new TypeError('The `src` prop must be a valid URL to an image on the Sanity Image CDN.', {\n cause: err,\n })\n }\n return <NextImage {...rest} src={srcUrl.toString()} loader={imageLoader} />\n}\n"],"mappings":";;;AAKA,MAAa,eAA4B,EAAC,KAAK,OAAO,cAAa;CACjE,MAAM,MAAM,IAAI,IAAI,IAAI;AACxB,KAAI,aAAa,IAAI,QAAQ,SAAS;AACtC,KAAI,CAAC,IAAI,aAAa,IAAI,MAAM,CAC9B,KAAI,aAAa,IAAI,OAAO,IAAI,aAAa,IAAI,IAAI,GAAG,QAAQ,MAAM;AAExE,KAAI,IAAI,aAAa,IAAI,IAAI,IAAI,IAAI,aAAa,IAAI,IAAI,EAAE;EAC1D,MAAM,iBAAiB,SAAS,IAAI,aAAa,IAAI,IAAI,EAAG,GAAG;EAC/D,MAAM,gBAAgB,SAAS,IAAI,aAAa,IAAI,IAAI,EAAG,GAAG;AAC9D,MAAI,aAAa,IAAI,KAAK,KAAK,MAAO,iBAAiB,gBAAiB,MAAM,CAAC,UAAU,CAAC;;AAE5F,KAAI,aAAa,IAAI,KAAK,MAAM,UAAU,CAAC;AAC3C,KAAI,QACF,KAAI,aAAa,IAAI,KAAK,QAAQ,UAAU,CAAC;AAE/C,QAAO,IAAI;;ACCb,SAAgB,MAAM,OAAsC;CAC1D,MAAM,EAAC,QAAQ,KAAK,GAAG,SAAQ;AAC/B,KAAI,OACF,OAAM,IAAI,UACR,8GACD;CAEH,IAAI;AACJ,KAAI;AACF,WAAS,IAAI,IAAI,IAAI;AACrB,MAAI,MAAM,OACR,QAAO,aAAa,IAAI,KAAK,GAAG,MAAM,SAAS;AAEjD,MAAI,MAAM,MACR,QAAO,aAAa,IAAI,KAAK,GAAG,MAAM,QAAQ;UAEzC,KAAK;AACZ,QAAM,IAAI,UAAU,2EAA2E,EAC7F,OAAO,KACR,CAAC;;AAEJ,QAAO,oBAAC,WAAA;EAAU,GAAI;EAAM,KAAK,OAAO,UAAU;EAAE,QAAQ;GAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"live.d.ts","names":["resolvePerspectiveFromCookies: ResolvePerspectiveFromCookies"],"sources":["../src/live.tsx"],"sourcesContent":[],"mappings":";;;;;AAsBc,iBAFE,UAAA,CAEF,OAAA,EAFsB,uBAEtB,CAAA,EAAA;EAIC,KAAA,EALN,gBAKM;EAImB,IAAA,EAR1B,KAAA,CAAM,aAQoB,CARN,gBAQM,CAAA;EAApB;;AASd;eAbe;;;;cAID,KAAA,CAAM,cAAc;;;;;;cASrBA,+BAA+B"}
1
+ {"version":3,"file":"live.d.ts","names":[],"sources":["../src/live.tsx"],"sourcesContent":[],"mappings":";;;;;AAsBc,iBAFE,UAAA,CAEF,OAAA,EAFsB,uBAEtB,CAAA,EAAA;EAIC,KAAA,EALN,gBAKM;EAImB,IAAA,EAR1B,KAAA,CAAM,aAQoB,CARN,gBAQM,CAAA;EAApB;;AASd;eAbe;;;;cAID,KAAA,CAAM,cAAc;;;;;;cASrB,+BAA+B"}
package/dist/live.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"live.js","names":["resolvePerspectiveFromCookies: ResolvePerspectiveFromCookies"],"sources":["../src/live.tsx"],"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} from '#live/resolvePerspectiveFromCookies'\nimport type {DefinedFetchType, DefinedLiveProps} from '#live/types'\n\nimport type {\n DefineSanityLiveOptions,\n DefinedSanityFetchType,\n DefinedSanityLiveProps,\n} from './live/defineLive'\n\nexport {isCorsOriginError} from '#live/isCorsOriginError'\n\n/**\n * @public\n */\nexport function defineLive(_config: DefineSanityLiveOptions): {\n fetch: DefinedFetchType\n Live: React.ComponentType<DefinedLiveProps>\n /**\n * @deprecated use `fetch` instead, and define your own `sanityFetch` function with logic for when to toggle `stega` and `perspective`\n */\n sanityFetch: DefinedSanityFetchType\n /**\n * @deprecated use `Live` instead, and define your own `SanityLive` component with logic for when to toggle `perspective`\n */\n SanityLive: React.ComponentType<DefinedSanityLiveProps>\n} {\n throw new Error(`defineLive can't be imported by a client component`)\n}\n\n/**\n * Resolves the perspective from the cookie that is set by `import { defineEnableDraftMode } from \"next-sanity/draft-mode\"`\n * @public\n */\nexport const resolvePerspectiveFromCookies: ResolvePerspectiveFromCookies = () => {\n throw new Error(`resolvePerspectiveFromCookies can't be imported by a client component`)\n}\n\nexport type {PerspectiveType as LivePerspective} from '#live/types'\n"],"mappings":";AAoBA,SAAgB,WAAW,SAWzB;AACA,OAAM,IAAI,MAAM,qDAAqD;;AAOvE,MAAaA,sCAAqE;AAChF,OAAM,IAAI,MAAM,wEAAwE"}
1
+ {"version":3,"file":"live.js","names":[],"sources":["../src/live.tsx"],"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} from '#live/resolvePerspectiveFromCookies'\nimport type {DefinedFetchType, DefinedLiveProps} from '#live/types'\n\nimport type {\n DefineSanityLiveOptions,\n DefinedSanityFetchType,\n DefinedSanityLiveProps,\n} from './live/defineLive'\n\nexport {isCorsOriginError} from '#live/isCorsOriginError'\n\n/**\n * @public\n */\nexport function defineLive(_config: DefineSanityLiveOptions): {\n fetch: DefinedFetchType\n Live: React.ComponentType<DefinedLiveProps>\n /**\n * @deprecated use `fetch` instead, and define your own `sanityFetch` function with logic for when to toggle `stega` and `perspective`\n */\n sanityFetch: DefinedSanityFetchType\n /**\n * @deprecated use `Live` instead, and define your own `SanityLive` component with logic for when to toggle `perspective`\n */\n SanityLive: React.ComponentType<DefinedSanityLiveProps>\n} {\n throw new Error(`defineLive can't be imported by a client component`)\n}\n\n/**\n * Resolves the perspective from the cookie that is set by `import { defineEnableDraftMode } from \"next-sanity/draft-mode\"`\n * @public\n */\nexport const resolvePerspectiveFromCookies: ResolvePerspectiveFromCookies = () => {\n throw new Error(`resolvePerspectiveFromCookies can't be imported by a client component`)\n}\n\nexport type {PerspectiveType as LivePerspective} from '#live/types'\n"],"mappings":";AAoBA,SAAgB,WAAW,SAWzB;AACA,OAAM,IAAI,MAAM,qDAAqD;;AAOvE,MAAa,sCAAqE;AAChF,OAAM,IAAI,MAAM,wEAAwE"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["autoBasePath: string | undefined","autoTrailingSlash: boolean | undefined"],"sources":["../../src/visual-editing/VisualEditing.tsx"],"sourcesContent":["import type {VisualEditingProps} from 'next-sanity/visual-editing/client-component'\n\nimport VisualEditingComponent from 'next-sanity/visual-editing/client-component'\n\n/**\n * @public\n */\nexport function VisualEditing(props: VisualEditingProps): React.ReactElement {\n let autoBasePath: string | undefined\n if (typeof props.basePath !== 'string') {\n try {\n autoBasePath = process.env['__NEXT_ROUTER_BASEPATH']\n if (autoBasePath) {\n // oxlint-disable-next-line no-console\n console.log(\n `Detected next basePath as ${JSON.stringify(autoBasePath)} by reading \"process.env.__NEXT_ROUTER_BASEPATH\". If this is incorrect then you can set it manually with the basePath prop on the <VisualEditing /> component.`,\n )\n }\n } catch (err) {\n console.error('Failed detecting basePath', err)\n }\n }\n let autoTrailingSlash: boolean | undefined\n if (typeof props.trailingSlash !== 'boolean') {\n try {\n autoTrailingSlash = Boolean(process.env['__NEXT_TRAILING_SLASH'])\n if (autoTrailingSlash) {\n // oxlint-disable-next-line no-console\n console.log(\n `Detected next trailingSlash as ${JSON.stringify(autoTrailingSlash)} by reading \"process.env.__NEXT_TRAILING_SLASH\". If this is incorrect then you can set it manually with the trailingSlash prop on the <VisualEditing /> component.`,\n )\n }\n } catch (err) {\n console.error('Failed detecting trailingSlash', err)\n }\n }\n return (\n <VisualEditingComponent\n {...props}\n basePath={props.basePath ?? autoBasePath}\n trailingSlash={props.trailingSlash ?? autoTrailingSlash}\n />\n )\n}\n\nexport type {VisualEditingProps} from 'next-sanity/visual-editing/client-component'\n"],"mappings":";;AAOA,SAAgB,cAAc,OAA+C;CAC3E,IAAIA;AACJ,KAAI,OAAO,MAAM,aAAa,SAC5B,KAAI;AACF,iBAAe,QAAQ,IAAI;AAC3B,MAAI,aAEF,SAAQ,IACN,6BAA6B,KAAK,UAAU,aAAa,CAAC,gKAC3D;UAEI,KAAK;AACZ,UAAQ,MAAM,6BAA6B,IAAI;;CAGnD,IAAIC;AACJ,KAAI,OAAO,MAAM,kBAAkB,UACjC,KAAI;AACF,sBAAoB,QAAQ,QAAQ,IAAI,yBAAyB;AACjE,MAAI,kBAEF,SAAQ,IACN,kCAAkC,KAAK,UAAU,kBAAkB,CAAC,oKACrE;UAEI,KAAK;AACZ,UAAQ,MAAM,kCAAkC,IAAI;;AAGxD,QACE,oBAAC,wBAAA;EACC,GAAI;EACJ,UAAU,MAAM,YAAY;EAC5B,eAAe,MAAM,iBAAiB;GACtC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/visual-editing/VisualEditing.tsx"],"sourcesContent":["import type {VisualEditingProps} from 'next-sanity/visual-editing/client-component'\n\nimport VisualEditingComponent from 'next-sanity/visual-editing/client-component'\n\n/**\n * @public\n */\nexport function VisualEditing(props: VisualEditingProps): React.ReactElement {\n let autoBasePath: string | undefined\n if (typeof props.basePath !== 'string') {\n try {\n autoBasePath = process.env['__NEXT_ROUTER_BASEPATH']\n if (autoBasePath) {\n // oxlint-disable-next-line no-console\n console.log(\n `Detected next basePath as ${JSON.stringify(autoBasePath)} by reading \"process.env.__NEXT_ROUTER_BASEPATH\". If this is incorrect then you can set it manually with the basePath prop on the <VisualEditing /> component.`,\n )\n }\n } catch (err) {\n console.error('Failed detecting basePath', err)\n }\n }\n let autoTrailingSlash: boolean | undefined\n if (typeof props.trailingSlash !== 'boolean') {\n try {\n autoTrailingSlash = Boolean(process.env['__NEXT_TRAILING_SLASH'])\n if (autoTrailingSlash) {\n // oxlint-disable-next-line no-console\n console.log(\n `Detected next trailingSlash as ${JSON.stringify(autoTrailingSlash)} by reading \"process.env.__NEXT_TRAILING_SLASH\". If this is incorrect then you can set it manually with the trailingSlash prop on the <VisualEditing /> component.`,\n )\n }\n } catch (err) {\n console.error('Failed detecting trailingSlash', err)\n }\n }\n return (\n <VisualEditingComponent\n {...props}\n basePath={props.basePath ?? autoBasePath}\n trailingSlash={props.trailingSlash ?? autoTrailingSlash}\n />\n )\n}\n\nexport type {VisualEditingProps} from 'next-sanity/visual-editing/client-component'\n"],"mappings":";;AAOA,SAAgB,cAAc,OAA+C;CAC3E,IAAI;AACJ,KAAI,OAAO,MAAM,aAAa,SAC5B,KAAI;AACF,iBAAe,QAAQ,IAAI;AAC3B,MAAI,aAEF,SAAQ,IACN,6BAA6B,KAAK,UAAU,aAAa,CAAC,gKAC3D;UAEI,KAAK;AACZ,UAAQ,MAAM,6BAA6B,IAAI;;CAGnD,IAAI;AACJ,KAAI,OAAO,MAAM,kBAAkB,UACjC,KAAI;AACF,sBAAoB,QAAQ,QAAQ,IAAI,yBAAyB;AACjE,MAAI,kBAEF,SAAQ,IACN,kCAAkC,KAAK,UAAU,kBAAkB,CAAC,oKACrE;UAEI,KAAK;AACZ,UAAQ,MAAM,kCAAkC,IAAI;;AAGxD,QACE,oBAAC,wBAAA;EACC,GAAI;EACJ,UAAU,MAAM,YAAY;EAC5B,eAAe,MAAM,iBAAiB;GACtC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-sanity",
3
- "version": "13.0.0-cache-components.8",
3
+ "version": "13.0.0-cache-components.10",
4
4
  "description": "Sanity.io toolkit for Next.js",
5
5
  "keywords": [
6
6
  "live",
@@ -27,8 +27,6 @@
27
27
  ],
28
28
  "type": "module",
29
29
  "sideEffects": false,
30
- "main": "./dist/index.js",
31
- "module": "./dist/index.js",
32
30
  "types": "./dist/index.d.ts",
33
31
  "imports": {
34
32
  "#client-components/*": "./src/shared/client-components/*.tsx",
@@ -57,14 +55,14 @@
57
55
  "./package.json": "./package.json"
58
56
  },
59
57
  "dependencies": {
60
- "@portabletext/react": "^6.0.0",
58
+ "@portabletext/react": "^6.0.1",
61
59
  "@sanity/client": "^7.13.2",
62
60
  "@sanity/comlink": "^4.0.1",
63
61
  "@sanity/presentation-comlink": "^2.0.1",
64
62
  "@sanity/preview-url-secret": "^4.0.1",
65
63
  "@sanity/visual-editing": "^5.0.3",
66
64
  "dequal": "^2.0.3",
67
- "groq": "^5.0.1",
65
+ "groq": "^5.1.0",
68
66
  "history": "^5.3.0"
69
67
  },
70
68
  "devDependencies": {
@@ -75,12 +73,12 @@
75
73
  "@types/react": "^19.2.7",
76
74
  "@types/react-dom": "^19.2.3",
77
75
  "@vitest/coverage-v8": "^4.0.16",
78
- "next": "16.1.1-canary.0",
76
+ "next": "16.1.1-canary.10",
79
77
  "publint": "^0.3.16",
80
78
  "react": "^19.2.3",
81
79
  "react-dom": "^19.2.3",
82
80
  "styled-components": "^6.1.19",
83
- "tsdown": "0.18.1",
81
+ "tsdown": "0.19.0-beta.1",
84
82
  "typescript": "5.9.3",
85
83
  "vitest": "^4.0.16"
86
84
  },
@@ -89,7 +87,7 @@
89
87
  "next": "^16.0.0-0",
90
88
  "react": "^19.2.3",
91
89
  "react-dom": "^19.2.3",
92
- "sanity": "^5.0.1",
90
+ "sanity": "^5.1.0",
93
91
  "styled-components": "^6.1"
94
92
  },
95
93
  "browserslist": "extends @sanity/browserslist-config",