hydrogen-sanity 5.2.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/vite/index.js +18 -0
- package/dist/vite/index.js.map +1 -1
- package/package.json +23 -23
- package/src/index.ts +2 -1
- package/src/vite/plugin.ts +20 -0
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {Any} from '@sanity/client'
|
|
|
2
2
|
import {CachingStrategy} from '@shopify/hydrogen'
|
|
3
3
|
import {ClientConfig} from '@sanity/client'
|
|
4
4
|
import {ClientReturn} from '@sanity/client'
|
|
5
|
-
import {createDataAttribute} from '@sanity/
|
|
5
|
+
import {createDataAttribute} from '@sanity/core-loader/create-data-attribute'
|
|
6
6
|
import {EncodeDataAttributeFunction} from '@sanity/core-loader/encode-data-attribute'
|
|
7
7
|
import type {HTMLProps} from 'react'
|
|
8
8
|
import {HydrogenSession} from '@shopify/hydrogen'
|
package/dist/index.js
CHANGED
|
@@ -8,8 +8,9 @@ import { supportsPerspectiveStack, getPerspective, hashQuery, isServer } from '.
|
|
|
8
8
|
import { createImageUrlBuilder } from '@sanity/image-url';
|
|
9
9
|
import { jsx } from 'react/jsx-runtime';
|
|
10
10
|
import { useQuery as useQuery$1 } from '@sanity/react-loader';
|
|
11
|
-
export {
|
|
11
|
+
export { useEncodeDataAttribute } from '@sanity/react-loader';
|
|
12
12
|
import { registerQuery } from './_chunks-es/registry.js';
|
|
13
|
+
export { createDataAttribute } from '@sanity/core-loader/create-data-attribute';
|
|
13
14
|
|
|
14
15
|
const DEFAULT_API_VERSION = "v2025-02-19";
|
|
15
16
|
const DEFAULT_CACHE_STRATEGY = CacheLong();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/constants.ts","../src/context.ts","../src/image.ts","../src/Query.tsx","../src/visual-editing/useQuery.tsx"],"sourcesContent":["import {CacheLong, type CachingStrategy} from '@shopify/hydrogen'\n\n/** Default Sanity API version with perspective stack support */\nexport const DEFAULT_API_VERSION = 'v2025-02-19'\n\n/** Default Hydrogen caching strategy for Sanity queries */\nexport const DEFAULT_CACHE_STRATEGY: CachingStrategy = CacheLong()\n","import {\n type Any,\n type ClientConfig,\n type ClientPerspective,\n type ClientReturn,\n createClient,\n type QueryParams,\n type QueryWithoutParams,\n type ResponseQueryOptions,\n SanityClient,\n} from '@sanity/client'\nimport type {QueryResponseInitial} from '@sanity/react-loader'\nimport {type CachingStrategy, createWithCache, type HydrogenSession} from '@shopify/hydrogen'\nimport {createElement, type PropsWithChildren, type ReactNode} from 'react'\n\nimport {DEFAULT_API_VERSION, DEFAULT_CACHE_STRATEGY} from './constants'\nimport type {SanityPreviewSession} from './preview/session'\nimport {isPreviewEnabled} from './preview/utils'\nimport {SanityProvider, type SanityProviderValue} from './provider'\nimport type {CacheActionFunctionParam, WaitUntil} from './types'\nimport {getPerspective} from './utils'\nimport {hashQuery, supportsPerspectiveStack} from './utils'\n\nlet didWarnAboutNoApiVersion = false\nlet didWarnAboutNoPerspectiveSupport = false\nlet didWarnAboutLoadQuery = false\nlet didInitializeLoader = false\n\nexport type CreateSanityContextOptions = {\n request: Request\n\n cache?: Cache | undefined\n waitUntil?: WaitUntil | undefined\n\n /**\n * Sanity client or configuration to use.\n */\n client: SanityClient | ClientConfig\n\n /**\n * The default caching strategy to use for `loadQuery` subrequests.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies\n *\n * Defaults to `CacheLong`\n */\n defaultStrategy?: CachingStrategy | null\n\n /**\n * Configuration for enabling preview mode.\n */\n preview?: {\n token: string\n session: SanityPreviewSession | HydrogenSession\n }\n}\n\ninterface RequestInit {\n hydrogen?: {\n /**\n * The caching strategy to use for the subrequest.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies\n */\n cache?: CachingStrategy\n\n /**\n * Optional debugging information to be displayed in the subrequest profiler.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/debugging/subrequest-profiler#how-to-provide-more-debug-information-for-a-request\n */\n debug?: {\n displayName: string\n }\n }\n}\n\ntype HydrogenResponseQueryOptions = Omit<ResponseQueryOptions, 'next' | 'cache'> & {\n hydrogen?: 'hydrogen' extends keyof RequestInit ? RequestInit['hydrogen'] : never\n}\n\nexport type LoadQueryOptions<T> = Pick<\n HydrogenResponseQueryOptions,\n 'perspective' | 'hydrogen' | 'useCdn' | 'stega' | 'headers' | 'tag'\n> & {\n hydrogen?: {\n /**\n * The caching strategy to use for the subrequest.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies\n */\n cache?: CachingStrategy\n\n /**\n * Optional debugging information to be displayed in the subrequest profiler.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/debugging/subrequest-profiler#how-to-provide-more-debug-information-for-a-request\n */\n debug?: {\n displayName: string\n }\n\n /**\n * Whether to cache the result of the query or not.\n * @defaultValue () => true\n */\n shouldCacheResult?: (value: QueryResponseInitial<T>) => boolean\n }\n}\n\nexport type FetchOptions<T> = HydrogenResponseQueryOptions & {\n hydrogen?: {\n /**\n * The caching strategy to use for the subrequest.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies\n */\n cache?: CachingStrategy\n\n /**\n * Optional debugging information to be displayed in the subrequest profiler.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/debugging/subrequest-profiler#how-to-provide-more-debug-information-for-a-request\n */\n debug?: {\n displayName: string\n }\n\n /**\n * Whether to cache the result of the query or not.\n * @defaultValue () => true\n */\n shouldCacheResult?: (value: QueryResponseInitial<T>) => boolean\n }\n}\n\nexport interface SanityContext {\n /**\n * Query Sanity using the loader.\n * @see https://www.sanity.io/docs/loaders\n */\n loadQuery<Result = Any, Query extends string = string>(\n query: Query,\n params?: QueryParams | QueryWithoutParams,\n options?: LoadQueryOptions<ClientReturn<Query, Result>>,\n ): Promise<QueryResponseInitial<ClientReturn<Query, Result>>>\n\n /**\n * Query Sanity using direct client fetch with Hydrogen caching.\n * Use this when you need direct client results without react-loader integration.\n * Automatically disables caching in preview mode for real-time updates.\n */\n fetch<Result = Any, Query extends string = string>(\n query: Query,\n params?: QueryParams | QueryWithoutParams,\n options?: FetchOptions<Result>,\n ): Promise<ClientReturn<Query, Result>>\n\n /**\n * Conditionally query Sanity using either loadQuery (for preview mode) or fetch (for static mode).\n * This optimizes bundle size by only loading @sanity/react-loader dependencies when in preview mode.\n */\n query<Result = Any, Query extends string = string>(\n query: Query,\n params?: QueryParams | QueryWithoutParams,\n options?: LoadQueryOptions<ClientReturn<Query, Result>> & FetchOptions<Result>,\n ): Promise<QueryResponseInitial<ClientReturn<Query, Result>> | ClientReturn<Query, Result>>\n\n /**\n * The Sanity client, automatically configured for preview mode when enabled.\n * Uses preview token, perspective, and CDN settings based on session state.\n */\n client: SanityClient\n\n preview?: CreateSanityContextOptions['preview'] & {\n /**\n * Whether preview mode is currently enabled based on session detection\n */\n enabled: boolean\n }\n\n SanityProvider: (props: PropsWithChildren<object>) => ReactNode\n}\n\n/**\n * @public\n */\nexport async function createSanityContext(\n options: CreateSanityContextOptions,\n): Promise<SanityContext> {\n const {cache, waitUntil = () => Promise.resolve(), request, preview, defaultStrategy} = options\n const withCache = cache ? createWithCache({cache, waitUntil, request}) : null\n let client =\n options.client instanceof SanityClient ? options.client : createClient(options.client)\n\n if (client.config().apiVersion === '1') {\n if (process.env.NODE_ENV === 'development' && !didWarnAboutNoApiVersion) {\n console.warn(\n `\nNo API version specified, defaulting to \\`${DEFAULT_API_VERSION}\\` which supports perspectives and Content Releases.\nYou can find the latest version in the Sanity changelog: https://www.sanity.io/changelog.\n `.trim(),\n )\n\n didWarnAboutNoApiVersion = true\n }\n\n client = client.withConfig({apiVersion: DEFAULT_API_VERSION})\n }\n\n // Determine if preview is enabled and configure the client accordingly\n let previewEnabled = false\n if (preview) {\n if (!preview.token) {\n throw new Error('Enabling preview mode requires a token.')\n }\n\n previewEnabled = isPreviewEnabled(client.config().projectId!, preview.session)\n\n if (previewEnabled) {\n const apiVersion = client.config().apiVersion\n let perspective: ClientPerspective\n if (supportsPerspectiveStack(apiVersion)) {\n perspective = getPerspective(preview.session)\n } else {\n if (process.env.NODE_ENV === 'development' && !didWarnAboutNoPerspectiveSupport) {\n console.warn(\n `API version \\`${apiVersion}\\` does not support perspective stacks. Using \\`previewDrafts\\` perspective. Consider upgrading to \\`v2025-02-19\\` or later for full perspective support.`,\n )\n\n didWarnAboutNoPerspectiveSupport = true\n }\n perspective = 'previewDrafts'\n }\n\n client = client.withConfig({\n useCdn: false,\n token: preview.token,\n perspective,\n })\n }\n }\n\n // Server client will be initialized lazily on first loadQuery call\n const {apiHost, projectId, dataset, apiVersion} = client.config()\n const providerValue: SanityProviderValue = {\n projectId: projectId!,\n dataset: dataset!,\n apiHost,\n apiVersion: apiVersion!,\n previewEnabled,\n perspective: client.config().perspective || 'published',\n stegaEnabled: client.config().stega?.enabled ?? false,\n }\n\n return {\n /**\n * Loads a Sanity query with client-side loader support and Hydrogen cache integration.\n * Bypasses Hydrogen cache in preview mode.\n */\n async loadQuery<Result = Any, Query extends string = string>(\n query: Query,\n params: QueryParams | QueryWithoutParams,\n loaderOptions?: LoadQueryOptions<ClientReturn<Query, Result>>,\n ): Promise<QueryResponseInitial<ClientReturn<Query, Result>>> {\n // Lazy initialize the loader on first call with the configured client\n if (!didInitializeLoader) {\n const {setServerClient} = await import('@sanity/react-loader')\n setServerClient(client)\n didInitializeLoader = true\n }\n\n // Warn users to migrate to `query` method when using loadQuery outside preview mode\n if (!previewEnabled && process.env.NODE_ENV === 'development' && !didWarnAboutLoadQuery) {\n console.warn(\n `\\`loadQuery\\` is being called outside of preview mode. Consider using \\`query\\` instead, which automatically handles both preview and production modes efficiently, or use \\`fetch\\`. \\`loadQuery\\` is intended to be called conditionally in preview and visual editing contexts.`,\n )\n didWarnAboutLoadQuery = true\n }\n\n if (!withCache || previewEnabled) {\n const {loadQuery} = await import('@sanity/react-loader')\n return await loadQuery<ClientReturn<Query, Result>>(query, params, loaderOptions)\n }\n\n const cacheStrategy =\n loaderOptions?.hydrogen?.cache || defaultStrategy || DEFAULT_CACHE_STRATEGY\n const queryHash = await hashQuery(query, params)\n const shouldCacheResult = loaderOptions?.hydrogen?.shouldCacheResult ?? (() => true)\n\n return await withCache.run(\n {cacheKey: queryHash, cacheStrategy, shouldCacheResult},\n async ({\n addDebugData,\n }: CacheActionFunctionParam): Promise<\n QueryResponseInitial<ClientReturn<Query, Result>>\n > => {\n // Name displayed in the subrequest profiler\n const displayName = loaderOptions?.hydrogen?.debug?.displayName || 'query Sanity'\n\n addDebugData({\n displayName,\n })\n\n const {loadQuery} = await import('@sanity/react-loader')\n return await loadQuery<ClientReturn<Query, Result>>(query, params, loaderOptions)\n },\n )\n },\n\n /**\n * Executes a Sanity query with Hydrogen cache integration.\n * Direct client fetch without loader integration. Bypasses cache in preview mode.\n */\n async fetch<Result = Any, Query extends string = string>(\n query: Query,\n params: QueryParams | QueryWithoutParams = {},\n fetchOptions?: Pick<\n LoadQueryOptions<Result>,\n 'perspective' | 'hydrogen' | 'useCdn' | 'headers' | 'tag'\n >,\n ): Promise<ClientReturn<Query, Result>> {\n if (!withCache || previewEnabled) {\n return await client.fetch<ClientReturn<Query, Result>>(query, params, fetchOptions)\n }\n\n const cacheStrategy =\n fetchOptions?.hydrogen?.cache || defaultStrategy || DEFAULT_CACHE_STRATEGY\n const queryHash = await hashQuery(query, params)\n\n return await withCache.run(\n {cacheKey: queryHash, cacheStrategy, shouldCacheResult: () => true},\n async ({addDebugData}: CacheActionFunctionParam): Promise<ClientReturn<Query, Result>> => {\n // Name displayed in the subrequest profiler\n const displayName = fetchOptions?.hydrogen?.debug?.displayName || 'fetch Sanity'\n\n addDebugData({\n displayName,\n })\n\n return await client.fetch<ClientReturn<Query, Result>>(query, params, fetchOptions)\n },\n )\n },\n\n /**\n * Automatic query method that automatically adapts based on preview mode state.\n * Uses `loadQuery` (with client-side loader integration) when preview is enabled, `fetch` otherwise.\n * Bypasses cache in preview mode.\n */\n async query<Result = Any, Query extends string = string>(\n query: Query,\n params?: QueryParams | QueryWithoutParams,\n queryOptions?: LoadQueryOptions<ClientReturn<Query, Result>> & FetchOptions<Result>,\n ): Promise<QueryResponseInitial<ClientReturn<Query, Result>> | ClientReturn<Query, Result>> {\n return await (previewEnabled ? this.loadQuery : this.fetch)(query, params, queryOptions)\n },\n\n /** The configured Sanity client instance */\n client,\n\n /** Preview configuration with session-based state, undefined when preview is not configured */\n preview: preview ? {...preview, enabled: previewEnabled} : undefined,\n\n /**\n * React Provider component that serializes Sanity configuration across server-client boundary.\n */\n SanityProvider({children}: PropsWithChildren<object>) {\n return createElement(\n SanityProvider,\n {\n value: Object.freeze(providerValue),\n },\n children,\n )\n },\n } satisfies SanityContext\n}\n","import type {ImageUrlBuilder, SanityImageSource, SanityModernClientLike} from '@sanity/image-url'\nimport {createImageUrlBuilder} from '@sanity/image-url'\nimport {useMemo} from 'react'\n\nimport {useSanityProviderValue} from './provider'\n\n/**\n * Hook that returns a Sanity image URL builder configured with current provider settings.\n * Use this to create custom image transformations beyond `useImageUrl`.\n */\nexport function useImageUrlBuilder(): ImageUrlBuilder {\n const {projectId, dataset, apiHost} = useSanityProviderValue()\n return useMemo(() => {\n return createImageUrlBuilder({\n config: () => ({projectId, dataset, apiHost}),\n } as SanityModernClientLike)\n }, [apiHost, dataset, projectId])\n}\n\n/**\n * Hook that generates image URLs from Sanity image assets.\n * Returns a configured image URL builder for the given source.\n */\nexport function useImageUrl(source: SanityImageSource): ImageUrlBuilder {\n const builder = useImageUrlBuilder()\n return builder.image(source)\n}\n\nexport type * from '@sanity/image-url'\n","import type {Any, ClientReturn, QueryParams, QueryWithoutParams} from '@sanity/client'\nimport type {EncodeDataAttributeFunction} from '@sanity/core-loader/encode-data-attribute'\nimport type {QueryResponseInitial} from '@sanity/react-loader'\nimport {lazy, type ReactNode, Suspense, type SuspenseProps, useSyncExternalStore} from 'react'\n\nimport type {LoadQueryOptions} from './context'\nimport {usePreviewMode} from './preview/hooks'\nimport type {QueryClientProps} from './Query.client'\nimport {isServer} from './utils'\n\n/**\n * Fallback component that renders nothing, preventing hydration mismatches.\n */\nfunction SanityQueryFallback(): ReactNode {\n return null\n}\n\n/**\n * Simple hydration store to avoid hydration mismatches.\n * Returns false on server, true on client after hydration.\n */\nfunction useIsHydrated(): boolean {\n return useSyncExternalStore(\n // eslint-disable-next-line no-empty-function\n () => () => {},\n () => true,\n () => false,\n )\n}\n\nconst QueryClient = isServer()\n ? SanityQueryFallback\n : (lazy(\n () =>\n /**\n * `lazy` expects the component as the default export\n * @see https://react.dev/reference/react/lazy\n */\n import('./Query.client'),\n ) as <Result = Any, Query extends string = string>(\n props: QueryClientProps<Result, Query>,\n ) => ReactNode)\n\nconst noopEncodeDataAttribute: EncodeDataAttributeFunction = Object.assign(() => undefined, {\n scope: () => noopEncodeDataAttribute,\n})\n\nexport interface QueryProps<Result = Any, Query extends string = string> extends Omit<\n QueryClientProps<Result, Query>,\n 'options'\n> {\n query: Query\n params?: QueryParams | QueryWithoutParams\n options: {\n initial: ClientReturn<Query, Result> | QueryResponseInitial<ClientReturn<Query, Result>>\n } & LoadQueryOptions<ClientReturn<Query, Result>>\n children: (\n data: ClientReturn<Query, Result>,\n encodeDataAttribute: EncodeDataAttributeFunction,\n ) => ReactNode\n}\n\n/**\n * Query component that provides live updates in preview mode and static data otherwise.\n *\n * @public\n */\nexport function Query<Result = Any, Query extends string = string>({\n query,\n params,\n options,\n children,\n ...suspenseProps\n}: QueryProps<Result, Query> & Omit<SuspenseProps, 'children'>): ReactNode {\n const isPreviewMode = usePreviewMode()\n const isHydrated = useIsHydrated()\n\n // If in preview mode and hydrated, render the client component\n if (isPreviewMode && isHydrated) {\n return (\n <Suspense {...suspenseProps} fallback={suspenseProps.fallback ?? <SanityQueryFallback />}>\n <QueryClient<Result, Query>\n query={query}\n params={params}\n options={options as QueryClientProps<Result, Query>['options']}\n >\n {children}\n </QueryClient>\n </Suspense>\n )\n }\n\n // Render static data in non-preview mode or during hydration\n return children(options.initial as ClientReturn<Query, Result>, noopEncodeDataAttribute)\n}\n","import {useQuery as _useQuery, type UseQueryOptionsDefinedInitial} from '@sanity/react-loader'\nimport {useEffect, useId} from 'react'\n\nimport {registerQuery} from './registry'\n\n/**\n * Automatically registers with the query detection system.\n * This enables automatic live mode detection in `VisualEditing` components.\n */\nexport function useQuery<QueryResponseResult = unknown>(\n query: string,\n params?: Record<string, unknown>,\n options?: UseQueryOptionsDefinedInitial<QueryResponseResult>,\n): ReturnType<typeof _useQuery<QueryResponseResult>> {\n // Generate stable ID for this `useQuery` instance\n const id = useId()\n\n // Register this `useQuery` instance with the detection system\n useEffect(() => {\n const unregister = registerQuery(id)\n return unregister\n }, [id])\n\n // Call the original `useQuery` with all the same arguments\n return _useQuery<QueryResponseResult>(query, params, options)\n}\n"],"names":["apiVersion","_useQuery"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/constants.ts","../src/context.ts","../src/image.ts","../src/Query.tsx","../src/visual-editing/useQuery.tsx"],"sourcesContent":["import {CacheLong, type CachingStrategy} from '@shopify/hydrogen'\n\n/** Default Sanity API version with perspective stack support */\nexport const DEFAULT_API_VERSION = 'v2025-02-19'\n\n/** Default Hydrogen caching strategy for Sanity queries */\nexport const DEFAULT_CACHE_STRATEGY: CachingStrategy = CacheLong()\n","import {\n type Any,\n type ClientConfig,\n type ClientPerspective,\n type ClientReturn,\n createClient,\n type QueryParams,\n type QueryWithoutParams,\n type ResponseQueryOptions,\n SanityClient,\n} from '@sanity/client'\nimport type {QueryResponseInitial} from '@sanity/react-loader'\nimport {type CachingStrategy, createWithCache, type HydrogenSession} from '@shopify/hydrogen'\nimport {createElement, type PropsWithChildren, type ReactNode} from 'react'\n\nimport {DEFAULT_API_VERSION, DEFAULT_CACHE_STRATEGY} from './constants'\nimport type {SanityPreviewSession} from './preview/session'\nimport {isPreviewEnabled} from './preview/utils'\nimport {SanityProvider, type SanityProviderValue} from './provider'\nimport type {CacheActionFunctionParam, WaitUntil} from './types'\nimport {getPerspective} from './utils'\nimport {hashQuery, supportsPerspectiveStack} from './utils'\n\nlet didWarnAboutNoApiVersion = false\nlet didWarnAboutNoPerspectiveSupport = false\nlet didWarnAboutLoadQuery = false\nlet didInitializeLoader = false\n\nexport type CreateSanityContextOptions = {\n request: Request\n\n cache?: Cache | undefined\n waitUntil?: WaitUntil | undefined\n\n /**\n * Sanity client or configuration to use.\n */\n client: SanityClient | ClientConfig\n\n /**\n * The default caching strategy to use for `loadQuery` subrequests.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies\n *\n * Defaults to `CacheLong`\n */\n defaultStrategy?: CachingStrategy | null\n\n /**\n * Configuration for enabling preview mode.\n */\n preview?: {\n token: string\n session: SanityPreviewSession | HydrogenSession\n }\n}\n\ninterface RequestInit {\n hydrogen?: {\n /**\n * The caching strategy to use for the subrequest.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies\n */\n cache?: CachingStrategy\n\n /**\n * Optional debugging information to be displayed in the subrequest profiler.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/debugging/subrequest-profiler#how-to-provide-more-debug-information-for-a-request\n */\n debug?: {\n displayName: string\n }\n }\n}\n\ntype HydrogenResponseQueryOptions = Omit<ResponseQueryOptions, 'next' | 'cache'> & {\n hydrogen?: 'hydrogen' extends keyof RequestInit ? RequestInit['hydrogen'] : never\n}\n\nexport type LoadQueryOptions<T> = Pick<\n HydrogenResponseQueryOptions,\n 'perspective' | 'hydrogen' | 'useCdn' | 'stega' | 'headers' | 'tag'\n> & {\n hydrogen?: {\n /**\n * The caching strategy to use for the subrequest.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies\n */\n cache?: CachingStrategy\n\n /**\n * Optional debugging information to be displayed in the subrequest profiler.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/debugging/subrequest-profiler#how-to-provide-more-debug-information-for-a-request\n */\n debug?: {\n displayName: string\n }\n\n /**\n * Whether to cache the result of the query or not.\n * @defaultValue () => true\n */\n shouldCacheResult?: (value: QueryResponseInitial<T>) => boolean\n }\n}\n\nexport type FetchOptions<T> = HydrogenResponseQueryOptions & {\n hydrogen?: {\n /**\n * The caching strategy to use for the subrequest.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies\n */\n cache?: CachingStrategy\n\n /**\n * Optional debugging information to be displayed in the subrequest profiler.\n * @see https://shopify.dev/docs/custom-storefronts/hydrogen/debugging/subrequest-profiler#how-to-provide-more-debug-information-for-a-request\n */\n debug?: {\n displayName: string\n }\n\n /**\n * Whether to cache the result of the query or not.\n * @defaultValue () => true\n */\n shouldCacheResult?: (value: QueryResponseInitial<T>) => boolean\n }\n}\n\nexport interface SanityContext {\n /**\n * Query Sanity using the loader.\n * @see https://www.sanity.io/docs/loaders\n */\n loadQuery<Result = Any, Query extends string = string>(\n query: Query,\n params?: QueryParams | QueryWithoutParams,\n options?: LoadQueryOptions<ClientReturn<Query, Result>>,\n ): Promise<QueryResponseInitial<ClientReturn<Query, Result>>>\n\n /**\n * Query Sanity using direct client fetch with Hydrogen caching.\n * Use this when you need direct client results without react-loader integration.\n * Automatically disables caching in preview mode for real-time updates.\n */\n fetch<Result = Any, Query extends string = string>(\n query: Query,\n params?: QueryParams | QueryWithoutParams,\n options?: FetchOptions<Result>,\n ): Promise<ClientReturn<Query, Result>>\n\n /**\n * Conditionally query Sanity using either loadQuery (for preview mode) or fetch (for static mode).\n * This optimizes bundle size by only loading @sanity/react-loader dependencies when in preview mode.\n */\n query<Result = Any, Query extends string = string>(\n query: Query,\n params?: QueryParams | QueryWithoutParams,\n options?: LoadQueryOptions<ClientReturn<Query, Result>> & FetchOptions<Result>,\n ): Promise<QueryResponseInitial<ClientReturn<Query, Result>> | ClientReturn<Query, Result>>\n\n /**\n * The Sanity client, automatically configured for preview mode when enabled.\n * Uses preview token, perspective, and CDN settings based on session state.\n */\n client: SanityClient\n\n preview?: CreateSanityContextOptions['preview'] & {\n /**\n * Whether preview mode is currently enabled based on session detection\n */\n enabled: boolean\n }\n\n SanityProvider: (props: PropsWithChildren<object>) => ReactNode\n}\n\n/**\n * @public\n */\nexport async function createSanityContext(\n options: CreateSanityContextOptions,\n): Promise<SanityContext> {\n const {cache, waitUntil = () => Promise.resolve(), request, preview, defaultStrategy} = options\n const withCache = cache ? createWithCache({cache, waitUntil, request}) : null\n let client =\n options.client instanceof SanityClient ? options.client : createClient(options.client)\n\n if (client.config().apiVersion === '1') {\n if (process.env.NODE_ENV === 'development' && !didWarnAboutNoApiVersion) {\n console.warn(\n `\nNo API version specified, defaulting to \\`${DEFAULT_API_VERSION}\\` which supports perspectives and Content Releases.\nYou can find the latest version in the Sanity changelog: https://www.sanity.io/changelog.\n `.trim(),\n )\n\n didWarnAboutNoApiVersion = true\n }\n\n client = client.withConfig({apiVersion: DEFAULT_API_VERSION})\n }\n\n // Determine if preview is enabled and configure the client accordingly\n let previewEnabled = false\n if (preview) {\n if (!preview.token) {\n throw new Error('Enabling preview mode requires a token.')\n }\n\n previewEnabled = isPreviewEnabled(client.config().projectId!, preview.session)\n\n if (previewEnabled) {\n const apiVersion = client.config().apiVersion\n let perspective: ClientPerspective\n if (supportsPerspectiveStack(apiVersion)) {\n perspective = getPerspective(preview.session)\n } else {\n if (process.env.NODE_ENV === 'development' && !didWarnAboutNoPerspectiveSupport) {\n console.warn(\n `API version \\`${apiVersion}\\` does not support perspective stacks. Using \\`previewDrafts\\` perspective. Consider upgrading to \\`v2025-02-19\\` or later for full perspective support.`,\n )\n\n didWarnAboutNoPerspectiveSupport = true\n }\n perspective = 'previewDrafts'\n }\n\n client = client.withConfig({\n useCdn: false,\n token: preview.token,\n perspective,\n })\n }\n }\n\n // Server client will be initialized lazily on first loadQuery call\n const {apiHost, projectId, dataset, apiVersion} = client.config()\n const providerValue: SanityProviderValue = {\n projectId: projectId!,\n dataset: dataset!,\n apiHost,\n apiVersion: apiVersion!,\n previewEnabled,\n perspective: client.config().perspective || 'published',\n stegaEnabled: client.config().stega?.enabled ?? false,\n }\n\n return {\n /**\n * Loads a Sanity query with client-side loader support and Hydrogen cache integration.\n * Bypasses Hydrogen cache in preview mode.\n */\n async loadQuery<Result = Any, Query extends string = string>(\n query: Query,\n params: QueryParams | QueryWithoutParams,\n loaderOptions?: LoadQueryOptions<ClientReturn<Query, Result>>,\n ): Promise<QueryResponseInitial<ClientReturn<Query, Result>>> {\n // Lazy initialize the loader on first call with the configured client\n if (!didInitializeLoader) {\n const {setServerClient} = await import('@sanity/react-loader')\n setServerClient(client)\n didInitializeLoader = true\n }\n\n // Warn users to migrate to `query` method when using loadQuery outside preview mode\n if (!previewEnabled && process.env.NODE_ENV === 'development' && !didWarnAboutLoadQuery) {\n console.warn(\n `\\`loadQuery\\` is being called outside of preview mode. Consider using \\`query\\` instead, which automatically handles both preview and production modes efficiently, or use \\`fetch\\`. \\`loadQuery\\` is intended to be called conditionally in preview and visual editing contexts.`,\n )\n didWarnAboutLoadQuery = true\n }\n\n if (!withCache || previewEnabled) {\n const {loadQuery} = await import('@sanity/react-loader')\n return await loadQuery<ClientReturn<Query, Result>>(query, params, loaderOptions)\n }\n\n const cacheStrategy =\n loaderOptions?.hydrogen?.cache || defaultStrategy || DEFAULT_CACHE_STRATEGY\n const queryHash = await hashQuery(query, params)\n const shouldCacheResult = loaderOptions?.hydrogen?.shouldCacheResult ?? (() => true)\n\n return await withCache.run(\n {cacheKey: queryHash, cacheStrategy, shouldCacheResult},\n async ({\n addDebugData,\n }: CacheActionFunctionParam): Promise<\n QueryResponseInitial<ClientReturn<Query, Result>>\n > => {\n // Name displayed in the subrequest profiler\n const displayName = loaderOptions?.hydrogen?.debug?.displayName || 'query Sanity'\n\n addDebugData({\n displayName,\n })\n\n const {loadQuery} = await import('@sanity/react-loader')\n return await loadQuery<ClientReturn<Query, Result>>(query, params, loaderOptions)\n },\n )\n },\n\n /**\n * Executes a Sanity query with Hydrogen cache integration.\n * Direct client fetch without loader integration. Bypasses cache in preview mode.\n */\n async fetch<Result = Any, Query extends string = string>(\n query: Query,\n params: QueryParams | QueryWithoutParams = {},\n fetchOptions?: Pick<\n LoadQueryOptions<Result>,\n 'perspective' | 'hydrogen' | 'useCdn' | 'headers' | 'tag'\n >,\n ): Promise<ClientReturn<Query, Result>> {\n if (!withCache || previewEnabled) {\n return await client.fetch<ClientReturn<Query, Result>>(query, params, fetchOptions)\n }\n\n const cacheStrategy =\n fetchOptions?.hydrogen?.cache || defaultStrategy || DEFAULT_CACHE_STRATEGY\n const queryHash = await hashQuery(query, params)\n\n return await withCache.run(\n {cacheKey: queryHash, cacheStrategy, shouldCacheResult: () => true},\n async ({addDebugData}: CacheActionFunctionParam): Promise<ClientReturn<Query, Result>> => {\n // Name displayed in the subrequest profiler\n const displayName = fetchOptions?.hydrogen?.debug?.displayName || 'fetch Sanity'\n\n addDebugData({\n displayName,\n })\n\n return await client.fetch<ClientReturn<Query, Result>>(query, params, fetchOptions)\n },\n )\n },\n\n /**\n * Automatic query method that automatically adapts based on preview mode state.\n * Uses `loadQuery` (with client-side loader integration) when preview is enabled, `fetch` otherwise.\n * Bypasses cache in preview mode.\n */\n async query<Result = Any, Query extends string = string>(\n query: Query,\n params?: QueryParams | QueryWithoutParams,\n queryOptions?: LoadQueryOptions<ClientReturn<Query, Result>> & FetchOptions<Result>,\n ): Promise<QueryResponseInitial<ClientReturn<Query, Result>> | ClientReturn<Query, Result>> {\n return await (previewEnabled ? this.loadQuery : this.fetch)(query, params, queryOptions)\n },\n\n /** The configured Sanity client instance */\n client,\n\n /** Preview configuration with session-based state, undefined when preview is not configured */\n preview: preview ? {...preview, enabled: previewEnabled} : undefined,\n\n /**\n * React Provider component that serializes Sanity configuration across server-client boundary.\n */\n SanityProvider({children}: PropsWithChildren<object>) {\n return createElement(\n SanityProvider,\n {\n value: Object.freeze(providerValue),\n },\n children,\n )\n },\n } satisfies SanityContext\n}\n","import type {ImageUrlBuilder, SanityImageSource, SanityModernClientLike} from '@sanity/image-url'\nimport {createImageUrlBuilder} from '@sanity/image-url'\nimport {useMemo} from 'react'\n\nimport {useSanityProviderValue} from './provider'\n\n/**\n * Hook that returns a Sanity image URL builder configured with current provider settings.\n * Use this to create custom image transformations beyond `useImageUrl`.\n */\nexport function useImageUrlBuilder(): ImageUrlBuilder {\n const {projectId, dataset, apiHost} = useSanityProviderValue()\n return useMemo(() => {\n return createImageUrlBuilder({\n config: () => ({projectId, dataset, apiHost}),\n } as SanityModernClientLike)\n }, [apiHost, dataset, projectId])\n}\n\n/**\n * Hook that generates image URLs from Sanity image assets.\n * Returns a configured image URL builder for the given source.\n */\nexport function useImageUrl(source: SanityImageSource): ImageUrlBuilder {\n const builder = useImageUrlBuilder()\n return builder.image(source)\n}\n\nexport type * from '@sanity/image-url'\n","import type {Any, ClientReturn, QueryParams, QueryWithoutParams} from '@sanity/client'\nimport type {EncodeDataAttributeFunction} from '@sanity/core-loader/encode-data-attribute'\nimport type {QueryResponseInitial} from '@sanity/react-loader'\nimport {lazy, type ReactNode, Suspense, type SuspenseProps, useSyncExternalStore} from 'react'\n\nimport type {LoadQueryOptions} from './context'\nimport {usePreviewMode} from './preview/hooks'\nimport type {QueryClientProps} from './Query.client'\nimport {isServer} from './utils'\n\n/**\n * Fallback component that renders nothing, preventing hydration mismatches.\n */\nfunction SanityQueryFallback(): ReactNode {\n return null\n}\n\n/**\n * Simple hydration store to avoid hydration mismatches.\n * Returns false on server, true on client after hydration.\n */\nfunction useIsHydrated(): boolean {\n return useSyncExternalStore(\n // eslint-disable-next-line no-empty-function\n () => () => {},\n () => true,\n () => false,\n )\n}\n\nconst QueryClient = isServer()\n ? SanityQueryFallback\n : (lazy(\n () =>\n /**\n * `lazy` expects the component as the default export\n * @see https://react.dev/reference/react/lazy\n */\n import('./Query.client'),\n ) as <Result = Any, Query extends string = string>(\n props: QueryClientProps<Result, Query>,\n ) => ReactNode)\n\nconst noopEncodeDataAttribute: EncodeDataAttributeFunction = Object.assign(() => undefined, {\n scope: () => noopEncodeDataAttribute,\n})\n\nexport interface QueryProps<Result = Any, Query extends string = string> extends Omit<\n QueryClientProps<Result, Query>,\n 'options'\n> {\n query: Query\n params?: QueryParams | QueryWithoutParams\n options: {\n initial: ClientReturn<Query, Result> | QueryResponseInitial<ClientReturn<Query, Result>>\n } & LoadQueryOptions<ClientReturn<Query, Result>>\n children: (\n data: ClientReturn<Query, Result>,\n encodeDataAttribute: EncodeDataAttributeFunction,\n ) => ReactNode\n}\n\n/**\n * Query component that provides live updates in preview mode and static data otherwise.\n *\n * @public\n */\nexport function Query<Result = Any, Query extends string = string>({\n query,\n params,\n options,\n children,\n ...suspenseProps\n}: QueryProps<Result, Query> & Omit<SuspenseProps, 'children'>): ReactNode {\n const isPreviewMode = usePreviewMode()\n const isHydrated = useIsHydrated()\n\n // If in preview mode and hydrated, render the client component\n if (isPreviewMode && isHydrated) {\n return (\n <Suspense {...suspenseProps} fallback={suspenseProps.fallback ?? <SanityQueryFallback />}>\n <QueryClient<Result, Query>\n query={query}\n params={params}\n options={options as QueryClientProps<Result, Query>['options']}\n >\n {children}\n </QueryClient>\n </Suspense>\n )\n }\n\n // Render static data in non-preview mode or during hydration\n return children(options.initial as ClientReturn<Query, Result>, noopEncodeDataAttribute)\n}\n","import {useQuery as _useQuery, type UseQueryOptionsDefinedInitial} from '@sanity/react-loader'\nimport {useEffect, useId} from 'react'\n\nimport {registerQuery} from './registry'\n\n/**\n * Automatically registers with the query detection system.\n * This enables automatic live mode detection in `VisualEditing` components.\n */\nexport function useQuery<QueryResponseResult = unknown>(\n query: string,\n params?: Record<string, unknown>,\n options?: UseQueryOptionsDefinedInitial<QueryResponseResult>,\n): ReturnType<typeof _useQuery<QueryResponseResult>> {\n // Generate stable ID for this `useQuery` instance\n const id = useId()\n\n // Register this `useQuery` instance with the detection system\n useEffect(() => {\n const unregister = registerQuery(id)\n return unregister\n }, [id])\n\n // Call the original `useQuery` with all the same arguments\n return _useQuery<QueryResponseResult>(query, params, options)\n}\n"],"names":["apiVersion","_useQuery"],"mappings":";;;;;;;;;;;;;;AAGO,MAAM,mBAAA,GAAsB;AAG5B,MAAM,yBAA0C,SAAA;;ACiBvD,IAAI,wBAAA,GAA2B,KAAA;AAC/B,IAAI,gCAAA,GAAmC,KAAA;AACvC,IAAI,qBAAA,GAAwB,KAAA;AAC5B,IAAI,mBAAA,GAAsB,KAAA;AA0J1B,eAAsB,oBACpB,OAAA,EACwB;AACxB,EAAA,MAAM,EAAC,KAAA,EAAO,SAAA,GAAY,MAAM,OAAA,CAAQ,SAAQ,EAAG,OAAA,EAAS,OAAA,EAAS,eAAA,EAAe,GAAI,OAAA;AACxF,EAAA,MAAM,SAAA,GAAY,QAAQ,eAAA,CAAgB,EAAC,OAAO,SAAA,EAAW,OAAA,EAAQ,CAAA,GAAI,IAAA;AACzE,EAAA,IAAI,MAAA,GACF,QAAQ,MAAA,YAAkB,YAAA,GAAe,QAAQ,MAAA,GAAS,YAAA,CAAa,QAAQ,MAAM,CAAA;AAEvF,EAAA,IAAI,MAAA,CAAO,MAAA,EAAO,CAAE,UAAA,KAAe,GAAA,EAAK;AACtC,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA,IAAiB,CAAC,wBAAA,EAA0B;AACvE,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN;AAAA,0CAAA,EACoC,mBAAmB,CAAA;AAAA;AAAA,IAAA,CAAA,CAEzD,IAAA;AAAK,OACL;AAEA,MAAA,wBAAA,GAA2B,IAAA;AAAA,IAC7B;AAEA,IAAA,MAAA,GAAS,MAAA,CAAO,UAAA,CAAW,EAAC,UAAA,EAAY,qBAAoB,CAAA;AAAA,EAC9D;AAGA,EAAA,IAAI,cAAA,GAAiB,KAAA;AACrB,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,IAAI,CAAC,QAAQ,KAAA,EAAO;AAClB,MAAA,MAAM,IAAI,MAAM,yCAAyC,CAAA;AAAA,IAC3D;AAEA,IAAA,cAAA,GAAiB,iBAAiB,MAAA,CAAO,MAAA,EAAO,CAAE,SAAA,EAAY,QAAQ,OAAO,CAAA;AAE7E,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,MAAMA,WAAAA,GAAa,MAAA,CAAO,MAAA,EAAO,CAAE,UAAA;AACnC,MAAA,IAAI,WAAA;AACJ,MAAA,IAAI,wBAAA,CAAyBA,WAAU,CAAA,EAAG;AACxC,QAAA,WAAA,GAAc,cAAA,CAAe,QAAQ,OAAO,CAAA;AAAA,MAC9C,CAAA,MAAO;AACL,QAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA,IAAiB,CAAC,gCAAA,EAAkC;AAC/E,UAAA,OAAA,CAAQ,IAAA;AAAA,YACN,iBAAiBA,WAAU,CAAA,yJAAA;AAAA,WAC7B;AAEA,UAAA,gCAAA,GAAmC,IAAA;AAAA,QACrC;AACA,QAAA,WAAA,GAAc,eAAA;AAAA,MAChB;AAEA,MAAA,MAAA,GAAS,OAAO,UAAA,CAAW;AAAA,QACzB,MAAA,EAAQ,KAAA;AAAA,QACR,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAGA,EAAA,MAAM,EAAC,OAAA,EAAS,SAAA,EAAW,SAAS,UAAA,EAAU,GAAI,OAAO,MAAA,EAAO;AAChE,EAAA,MAAM,aAAA,GAAqC;AAAA,IACzC,SAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAA,EAAa,MAAA,CAAO,MAAA,EAAO,CAAE,WAAA,IAAe,WAAA;AAAA,IAC5C,YAAA,EAAc,MAAA,CAAO,MAAA,EAAO,CAAE,OAAO,OAAA,IAAW;AAAA,GAClD;AAEA,EAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKL,MAAM,SAAA,CACJ,KAAA,EACA,MAAA,EACA,aAAA,EAC4D;AAE5D,MAAA,IAAI,CAAC,mBAAA,EAAqB;AACxB,QAAA,MAAM,EAAC,eAAA,EAAe,GAAI,MAAM,OAAO,sBAAsB,CAAA;AAC7D,QAAA,eAAA,CAAgB,MAAM,CAAA;AACtB,QAAA,mBAAA,GAAsB,IAAA;AAAA,MACxB;AAGA,MAAA,IAAI,CAAC,cAAA,IAAkB,OAAA,CAAQ,IAAI,QAAA,KAAa,aAAA,IAAiB,CAAC,qBAAA,EAAuB;AACvF,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,CAAA,kRAAA;AAAA,SACF;AACA,QAAA,qBAAA,GAAwB,IAAA;AAAA,MAC1B;AAEA,MAAA,IAAI,CAAC,aAAa,cAAA,EAAgB;AAChC,QAAA,MAAM,EAAC,SAAA,EAAS,GAAI,MAAM,OAAO,sBAAsB,CAAA;AACvD,QAAA,OAAO,MAAM,SAAA,CAAuC,KAAA,EAAO,MAAA,EAAQ,aAAa,CAAA;AAAA,MAClF;AAEA,MAAA,MAAM,aAAA,GACJ,aAAA,EAAe,QAAA,EAAU,KAAA,IAAS,eAAA,IAAmB,sBAAA;AACvD,MAAA,MAAM,SAAA,GAAY,MAAM,SAAA,CAAU,KAAA,EAAO,MAAM,CAAA;AAC/C,MAAA,MAAM,iBAAA,GAAoB,aAAA,EAAe,QAAA,EAAU,iBAAA,KAAsB,MAAM,IAAA,CAAA;AAE/E,MAAA,OAAO,MAAM,SAAA,CAAU,GAAA;AAAA,QACrB,EAAC,QAAA,EAAU,SAAA,EAAW,aAAA,EAAe,iBAAA,EAAiB;AAAA,QACtD,OAAO;AAAA,UACL;AAAA,SACF,KAEK;AAEH,UAAA,MAAM,WAAA,GAAc,aAAA,EAAe,QAAA,EAAU,KAAA,EAAO,WAAA,IAAe,cAAA;AAEnE,UAAA,YAAA,CAAa;AAAA,YACX;AAAA,WACD,CAAA;AAED,UAAA,MAAM,EAAC,SAAA,EAAS,GAAI,MAAM,OAAO,sBAAsB,CAAA;AACvD,UAAA,OAAO,MAAM,SAAA,CAAuC,KAAA,EAAO,MAAA,EAAQ,aAAa,CAAA;AAAA,QAClF;AAAA,OACF;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,KAAA,CACJ,KAAA,EACA,MAAA,GAA2C,IAC3C,YAAA,EAIsC;AACtC,MAAA,IAAI,CAAC,aAAa,cAAA,EAAgB;AAChC,QAAA,OAAO,MAAM,MAAA,CAAO,KAAA,CAAmC,KAAA,EAAO,QAAQ,YAAY,CAAA;AAAA,MACpF;AAEA,MAAA,MAAM,aAAA,GACJ,YAAA,EAAc,QAAA,EAAU,KAAA,IAAS,eAAA,IAAmB,sBAAA;AACtD,MAAA,MAAM,SAAA,GAAY,MAAM,SAAA,CAAU,KAAA,EAAO,MAAM,CAAA;AAE/C,MAAA,OAAO,MAAM,SAAA,CAAU,GAAA;AAAA,QACrB,EAAC,QAAA,EAAU,SAAA,EAAW,aAAA,EAAe,iBAAA,EAAmB,MAAM,IAAA,EAAI;AAAA,QAClE,OAAO,EAAC,YAAA,EAAY,KAAsE;AAExF,UAAA,MAAM,WAAA,GAAc,YAAA,EAAc,QAAA,EAAU,KAAA,EAAO,WAAA,IAAe,cAAA;AAElE,UAAA,YAAA,CAAa;AAAA,YACX;AAAA,WACD,CAAA;AAED,UAAA,OAAO,MAAM,MAAA,CAAO,KAAA,CAAmC,KAAA,EAAO,QAAQ,YAAY,CAAA;AAAA,QACpF;AAAA,OACF;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,MAAM,KAAA,CACJ,KAAA,EACA,MAAA,EACA,YAAA,EAC0F;AAC1F,MAAA,OAAO,MAAA,CAAO,iBAAiB,IAAA,CAAK,SAAA,GAAY,KAAK,KAAA,EAAO,KAAA,EAAO,QAAQ,YAAY,CAAA;AAAA,IACzF,CAAA;AAAA;AAAA,IAGA,MAAA;AAAA;AAAA,IAGA,SAAS,OAAA,GAAU,EAAC,GAAG,OAAA,EAAS,OAAA,EAAS,gBAAc,GAAI,MAAA;AAAA;AAAA;AAAA;AAAA,IAK3D,cAAA,CAAe,EAAC,QAAA,EAAQ,EAA8B;AACpD,MAAA,OAAO,aAAA;AAAA,QACL,cAAA;AAAA,QACA;AAAA,UACE,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,aAAa;AAAA,SACpC;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAAA,GACF;AACF;;ACxWO,SAAS,kBAAA,GAAsC;AACpD,EAAA,MAAM,EAAC,SAAA,EAAW,OAAA,EAAS,OAAA,KAAW,sBAAA,EAAuB;AAC7D,EAAA,OAAO,QAAQ,MAAM;AACnB,IAAA,OAAO,qBAAA,CAAsB;AAAA,MAC3B,MAAA,EAAQ,OAAO,EAAC,SAAA,EAAW,SAAS,OAAA,EAAO;AAAA,KAClB,CAAA;AAAA,EAC7B,CAAA,EAAG,CAAC,OAAA,EAAS,OAAA,EAAS,SAAS,CAAC,CAAA;AAClC;AAMO,SAAS,YAAY,MAAA,EAA4C;AACtE,EAAA,MAAM,UAAU,kBAAA,EAAmB;AACnC,EAAA,OAAO,OAAA,CAAQ,MAAM,MAAM,CAAA;AAC7B;;ACbA,SAAS,mBAAA,GAAiC;AACxC,EAAA,OAAO,IAAA;AACT;AAMA,SAAS,aAAA,GAAyB;AAChC,EAAA,OAAO,oBAAA;AAAA;AAAA,IAEL,MAAM,MAAM;AAAA,IAAC,CAAA;AAAA,IACb,MAAM,IAAA;AAAA,IACN,MAAM;AAAA,GACR;AACF;AAEA,MAAM,WAAA,GAAc,QAAA,EAAS,GACzB,mBAAA,GACC,IAAA;AAAA,EACC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKE,OAAO,8BAAgB;AAAA;AAC3B,CAAA;AAIJ,MAAM,uBAAA,GAAuD,MAAA,CAAO,MAAA,CAAO,MAAM,MAAA,EAAW;AAAA,EAC1F,OAAO,MAAM;AACf,CAAC,CAAA;AAsBM,SAAS,KAAA,CAAmD;AAAA,EACjE,KAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA2E;AACzE,EAAA,MAAM,gBAAgB,cAAA,EAAe;AACrC,EAAA,MAAM,aAAa,aAAA,EAAc;AAGjC,EAAA,IAAI,iBAAiB,UAAA,EAAY;AAC/B,IAAA,uBACE,GAAA,CAAC,YAAU,GAAG,aAAA,EAAe,UAAU,aAAA,CAAc,QAAA,oBAAY,GAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EACpF,QAAA,kBAAA,GAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,KAAA;AAAA,QACA,MAAA;AAAA,QACA,OAAA;AAAA,QAEC;AAAA;AAAA,KACH,EACF,CAAA;AAAA,EAEJ;AAGA,EAAA,OAAO,QAAA,CAAS,OAAA,CAAQ,OAAA,EAAwC,uBAAuB,CAAA;AACzF;;ACrFO,SAAS,QAAA,CACd,KAAA,EACA,MAAA,EACA,OAAA,EACmD;AAEnD,EAAA,MAAM,KAAK,KAAA,EAAM;AAGjB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAA,GAAa,cAAc,EAAE,CAAA;AACnC,IAAA,OAAO,UAAA;AAAA,EACT,CAAA,EAAG,CAAC,EAAE,CAAC,CAAA;AAGP,EAAA,OAAOC,UAAA,CAA+B,KAAA,EAAO,MAAA,EAAQ,OAAO,CAAA;AAC9D;;;;"}
|
package/dist/vite/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
function sanity() {
|
|
2
2
|
return {
|
|
3
3
|
name: "sanity",
|
|
4
|
+
enforce: "pre",
|
|
5
|
+
// Run before other plugins to intercept @sanity/react-loader resolution
|
|
4
6
|
async config() {
|
|
5
7
|
return {
|
|
6
8
|
envPrefix: ["SANITY_STUDIO_"],
|
|
@@ -33,6 +35,22 @@ function sanity() {
|
|
|
33
35
|
];
|
|
34
36
|
resolvedConfig.environments.ssr.resolve.conditions = envConditions;
|
|
35
37
|
}
|
|
38
|
+
},
|
|
39
|
+
// Surgically redirect @sanity/react-loader to its server bundle during SSR
|
|
40
|
+
// The browser bundle doesn't export server-only functions like setServerClient/loadQuery
|
|
41
|
+
// Without this, Hydrogen/Oxygen's 'browser' condition causes the wrong bundle to load
|
|
42
|
+
async resolveId(id, importer, options) {
|
|
43
|
+
if (id === "@sanity/react-loader" && options.ssr) {
|
|
44
|
+
const pkgResolved = await this.resolve("@sanity/react-loader/package.json", importer, {
|
|
45
|
+
...options,
|
|
46
|
+
skipSelf: true
|
|
47
|
+
});
|
|
48
|
+
if (pkgResolved) {
|
|
49
|
+
const serverBundle = pkgResolved.id.replace("/package.json", "/dist/index.js");
|
|
50
|
+
return { id: serverBundle };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
36
54
|
}
|
|
37
55
|
};
|
|
38
56
|
}
|
package/dist/vite/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/vite/plugin.ts"],"sourcesContent":["import type {Plugin, ResolvedConfig} from 'vite'\n\n/**\n * Vite plugin for optimizing Sanity integration in Hydrogen applications.\n * Configures SSR optimization, dependency bundling, and ESM resolution for Sanity packages.\n */\nexport function sanity(): Plugin {\n return {\n name: 'sanity',\n\n async config() {\n return {\n envPrefix: ['SANITY_STUDIO_'],\n ssr: {\n optimizeDeps: {\n // Pre-bundle Sanity dependencies for better SSR performance\n include: ['@sanity/client'],\n },\n // Prevent externalization of Sanity dependencies to ensure proper ESM resolution\n noExternal: ['@sanity/client'],\n },\n }\n },\n\n configResolved(resolvedConfig: ResolvedConfig) {\n // Force ESM resolution for transitive dependencies (specifically `rxjs`) in SSR builds\n // The Hydrogen/Oxygen plugins add 'node' conditions which cause packages like rxjs\n // to resolve to their CJS versions (dist/cjs/index.js) instead of ESM versions\n // We prepend 'es2015' and filter out 'node'/'require' to force ESM resolution\n\n // Prepend es2015 and remove node/require to force ESM resolution in SSR\n const ssrConditions = [\n 'es2015',\n ...(resolvedConfig.ssr?.resolve?.conditions || []).filter(\n (condition) => condition !== 'es2015' && condition !== 'node' && condition !== 'require',\n ),\n ]\n\n // Override SSR resolve conditions\n if (resolvedConfig.ssr?.resolve) {\n resolvedConfig.ssr.resolve.conditions = ssrConditions\n }\n\n // Handle SSR environment (modern environments API)\n if (resolvedConfig.environments?.ssr?.resolve?.conditions) {\n const envConditions = [\n 'es2015',\n ...resolvedConfig.environments.ssr.resolve.conditions.filter(\n (condition) =>\n condition !== 'es2015' && condition !== 'node' && condition !== 'require',\n ),\n ]\n resolvedConfig.environments.ssr.resolve.conditions = envConditions\n }\n },\n }\n}\n"],"names":[],"mappings":"AAMO,SAAS,MAAA,GAAiB;AAC/B,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/vite/plugin.ts"],"sourcesContent":["import type {Plugin, ResolvedConfig} from 'vite'\n\n/**\n * Vite plugin for optimizing Sanity integration in Hydrogen applications.\n * Configures SSR optimization, dependency bundling, and ESM resolution for Sanity packages.\n */\nexport function sanity(): Plugin {\n return {\n name: 'sanity',\n enforce: 'pre', // Run before other plugins to intercept @sanity/react-loader resolution\n\n async config() {\n return {\n envPrefix: ['SANITY_STUDIO_'],\n ssr: {\n optimizeDeps: {\n // Pre-bundle Sanity dependencies for better SSR performance\n include: ['@sanity/client'],\n },\n // Prevent externalization of Sanity dependencies to ensure proper ESM resolution\n noExternal: ['@sanity/client'],\n },\n }\n },\n\n configResolved(resolvedConfig: ResolvedConfig) {\n // Force ESM resolution for transitive dependencies (specifically `rxjs`) in SSR builds\n // The Hydrogen/Oxygen plugins add 'node' conditions which cause packages like rxjs\n // to resolve to their CJS versions (dist/cjs/index.js) instead of ESM versions\n // We prepend 'es2015' and filter out 'node'/'require' to force ESM resolution\n\n // Prepend es2015 and remove node/require to force ESM resolution in SSR\n const ssrConditions = [\n 'es2015',\n ...(resolvedConfig.ssr?.resolve?.conditions || []).filter(\n (condition) => condition !== 'es2015' && condition !== 'node' && condition !== 'require',\n ),\n ]\n\n // Override SSR resolve conditions\n if (resolvedConfig.ssr?.resolve) {\n resolvedConfig.ssr.resolve.conditions = ssrConditions\n }\n\n // Handle SSR environment (modern environments API)\n if (resolvedConfig.environments?.ssr?.resolve?.conditions) {\n const envConditions = [\n 'es2015',\n ...resolvedConfig.environments.ssr.resolve.conditions.filter(\n (condition) =>\n condition !== 'es2015' && condition !== 'node' && condition !== 'require',\n ),\n ]\n resolvedConfig.environments.ssr.resolve.conditions = envConditions\n }\n },\n\n // Surgically redirect @sanity/react-loader to its server bundle during SSR\n // The browser bundle doesn't export server-only functions like setServerClient/loadQuery\n // Without this, Hydrogen/Oxygen's 'browser' condition causes the wrong bundle to load\n async resolveId(id, importer, options) {\n if (id === '@sanity/react-loader' && options.ssr) {\n // Resolve package.json (always exported) to find the package location\n const pkgResolved = await this.resolve('@sanity/react-loader/package.json', importer, {\n ...options,\n skipSelf: true,\n })\n if (pkgResolved) {\n // Construct absolute path to the server bundle, bypassing export conditions\n const serverBundle = pkgResolved.id.replace('/package.json', '/dist/index.js')\n return {id: serverBundle}\n }\n }\n return null\n },\n }\n}\n"],"names":[],"mappings":"AAMO,SAAS,MAAA,GAAiB;AAC/B,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,OAAA,EAAS,KAAA;AAAA;AAAA,IAET,MAAM,MAAA,GAAS;AACb,MAAA,OAAO;AAAA,QACL,SAAA,EAAW,CAAC,gBAAgB,CAAA;AAAA,QAC5B,GAAA,EAAK;AAAA,UACH,YAAA,EAAc;AAAA;AAAA,YAEZ,OAAA,EAAS,CAAC,gBAAgB;AAAA,WAC5B;AAAA;AAAA,UAEA,UAAA,EAAY,CAAC,gBAAgB;AAAA;AAC/B,OACF;AAAA,IACF,CAAA;AAAA,IAEA,eAAe,cAAA,EAAgC;AAO7C,MAAA,MAAM,aAAA,GAAgB;AAAA,QACpB,QAAA;AAAA,QACA,IAAI,cAAA,CAAe,GAAA,EAAK,OAAA,EAAS,UAAA,IAAc,EAAC,EAAG,MAAA;AAAA,UACjD,CAAC,SAAA,KAAc,SAAA,KAAc,QAAA,IAAY,SAAA,KAAc,UAAU,SAAA,KAAc;AAAA;AACjF,OACF;AAGA,MAAA,IAAI,cAAA,CAAe,KAAK,OAAA,EAAS;AAC/B,QAAA,cAAA,CAAe,GAAA,CAAI,QAAQ,UAAA,GAAa,aAAA;AAAA,MAC1C;AAGA,MAAA,IAAI,cAAA,CAAe,YAAA,EAAc,GAAA,EAAK,OAAA,EAAS,UAAA,EAAY;AACzD,QAAA,MAAM,aAAA,GAAgB;AAAA,UACpB,QAAA;AAAA,UACA,GAAG,cAAA,CAAe,YAAA,CAAa,GAAA,CAAI,QAAQ,UAAA,CAAW,MAAA;AAAA,YACpD,CAAC,SAAA,KACC,SAAA,KAAc,QAAA,IAAY,SAAA,KAAc,UAAU,SAAA,KAAc;AAAA;AACpE,SACF;AACA,QAAA,cAAA,CAAe,YAAA,CAAa,GAAA,CAAI,OAAA,CAAQ,UAAA,GAAa,aAAA;AAAA,MACvD;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,SAAA,CAAU,EAAA,EAAI,QAAA,EAAU,OAAA,EAAS;AACrC,MAAA,IAAI,EAAA,KAAO,sBAAA,IAA0B,OAAA,CAAQ,GAAA,EAAK;AAEhD,QAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,OAAA,CAAQ,qCAAqC,QAAA,EAAU;AAAA,UACpF,GAAG,OAAA;AAAA,UACH,QAAA,EAAU;AAAA,SACX,CAAA;AACD,QAAA,IAAI,WAAA,EAAa;AAEf,UAAA,MAAM,YAAA,GAAe,WAAA,CAAY,EAAA,CAAG,OAAA,CAAQ,iBAAiB,gBAAgB,CAAA;AAC7E,UAAA,OAAO,EAAC,IAAI,YAAA,EAAY;AAAA,QAC1B;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,GACF;AACF;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hydrogen-sanity",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Sanity.io toolkit for Hydrogen",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -127,42 +127,42 @@
|
|
|
127
127
|
"watch": "pkg-utils watch --strict"
|
|
128
128
|
},
|
|
129
129
|
"dependencies": {
|
|
130
|
-
"@sanity/comlink": "^
|
|
131
|
-
"@sanity/core-loader": "^
|
|
132
|
-
"@sanity/image-url": "^2.0.
|
|
133
|
-
"@sanity/presentation-comlink": "^
|
|
134
|
-
"@sanity/preview-url-secret": "^
|
|
135
|
-
"@sanity/react-loader": "^
|
|
136
|
-
"@sanity/visual-editing": "^
|
|
130
|
+
"@sanity/comlink": "^4.0.1",
|
|
131
|
+
"@sanity/core-loader": "^2.0.5",
|
|
132
|
+
"@sanity/image-url": "^2.0.3",
|
|
133
|
+
"@sanity/presentation-comlink": "^2.0.1",
|
|
134
|
+
"@sanity/preview-url-secret": "^4.0.2",
|
|
135
|
+
"@sanity/react-loader": "^2.0.5",
|
|
136
|
+
"@sanity/visual-editing": "^4.0.3",
|
|
137
137
|
"use-effect-event": "^2.0.3"
|
|
138
138
|
},
|
|
139
139
|
"devDependencies": {
|
|
140
140
|
"@eslint/eslintrc": "^3.3.3",
|
|
141
|
-
"@eslint/js": "^9.39.
|
|
141
|
+
"@eslint/js": "^9.39.2",
|
|
142
142
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
143
|
-
"@sanity/client": "^7.
|
|
144
|
-
"@sanity/pkg-utils": "^10.
|
|
143
|
+
"@sanity/client": "^7.14.0",
|
|
144
|
+
"@sanity/pkg-utils": "^10.3.2",
|
|
145
145
|
"@sanity/semantic-release-preset": "^6.0.0",
|
|
146
|
-
"@shopify/hydrogen": "~2025.7.
|
|
147
|
-
"@testing-library/react": "^16.3.
|
|
148
|
-
"@types/react": "^18.3.
|
|
149
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
150
|
-
"@typescript-eslint/parser": "^8.
|
|
151
|
-
"eslint": "^9.39.
|
|
146
|
+
"@shopify/hydrogen": "~2025.7.2",
|
|
147
|
+
"@testing-library/react": "^16.3.1",
|
|
148
|
+
"@types/react": "^18.3.27",
|
|
149
|
+
"@typescript-eslint/eslint-plugin": "^8.53.0",
|
|
150
|
+
"@typescript-eslint/parser": "^8.53.0",
|
|
151
|
+
"eslint": "^9.39.2",
|
|
152
152
|
"eslint-config-prettier": "^10.1.8",
|
|
153
153
|
"eslint-config-sanity": "^7.1.4",
|
|
154
|
-
"eslint-plugin-prettier": "^5.5.
|
|
154
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
155
155
|
"eslint-plugin-react": "^7.37.5",
|
|
156
|
-
"eslint-plugin-react-hooks": "
|
|
156
|
+
"eslint-plugin-react-hooks": "7.0.1",
|
|
157
157
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
158
|
-
"groq": "^4.
|
|
158
|
+
"groq": "^5.4.0",
|
|
159
159
|
"react": "^18.3.1",
|
|
160
160
|
"react-dom": "^18.3.1",
|
|
161
161
|
"react-router": "7.12.0",
|
|
162
162
|
"semantic-release": "^25.0.2",
|
|
163
163
|
"typescript": "^5.9.3",
|
|
164
|
-
"vite": "^6.
|
|
165
|
-
"vitest": "^4.0.
|
|
164
|
+
"vite": "^6.4.1",
|
|
165
|
+
"vitest": "^4.0.17"
|
|
166
166
|
},
|
|
167
167
|
"peerDependencies": {
|
|
168
168
|
"@sanity/client": "^7",
|
|
@@ -172,6 +172,6 @@
|
|
|
172
172
|
"vite": "^5.1.0 || ^6.2.1"
|
|
173
173
|
},
|
|
174
174
|
"engines": {
|
|
175
|
-
"node": ">=20"
|
|
175
|
+
"node": ">=20.19 <22 || >=22.12"
|
|
176
176
|
}
|
|
177
177
|
}
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export {useImageUrl, useImageUrlBuilder} from './image'
|
|
|
4
4
|
export {Sanity, useSanityProviderValue} from './provider'
|
|
5
5
|
export {Query, type QueryProps} from './Query'
|
|
6
6
|
export {useQuery} from './visual-editing/useQuery'
|
|
7
|
+
export {createDataAttribute} from '@sanity/core-loader/create-data-attribute'
|
|
7
8
|
export type {EncodeDataAttributeFunction} from '@sanity/core-loader/encode-data-attribute'
|
|
8
9
|
export type * from '@sanity/react-loader'
|
|
9
|
-
export {
|
|
10
|
+
export {useEncodeDataAttribute} from '@sanity/react-loader'
|
package/src/vite/plugin.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type {Plugin, ResolvedConfig} from 'vite'
|
|
|
7
7
|
export function sanity(): Plugin {
|
|
8
8
|
return {
|
|
9
9
|
name: 'sanity',
|
|
10
|
+
enforce: 'pre', // Run before other plugins to intercept @sanity/react-loader resolution
|
|
10
11
|
|
|
11
12
|
async config() {
|
|
12
13
|
return {
|
|
@@ -53,5 +54,24 @@ export function sanity(): Plugin {
|
|
|
53
54
|
resolvedConfig.environments.ssr.resolve.conditions = envConditions
|
|
54
55
|
}
|
|
55
56
|
},
|
|
57
|
+
|
|
58
|
+
// Surgically redirect @sanity/react-loader to its server bundle during SSR
|
|
59
|
+
// The browser bundle doesn't export server-only functions like setServerClient/loadQuery
|
|
60
|
+
// Without this, Hydrogen/Oxygen's 'browser' condition causes the wrong bundle to load
|
|
61
|
+
async resolveId(id, importer, options) {
|
|
62
|
+
if (id === '@sanity/react-loader' && options.ssr) {
|
|
63
|
+
// Resolve package.json (always exported) to find the package location
|
|
64
|
+
const pkgResolved = await this.resolve('@sanity/react-loader/package.json', importer, {
|
|
65
|
+
...options,
|
|
66
|
+
skipSelf: true,
|
|
67
|
+
})
|
|
68
|
+
if (pkgResolved) {
|
|
69
|
+
// Construct absolute path to the server bundle, bypassing export conditions
|
|
70
|
+
const serverBundle = pkgResolved.id.replace('/package.json', '/dist/index.js')
|
|
71
|
+
return {id: serverBundle}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return null
|
|
75
|
+
},
|
|
56
76
|
}
|
|
57
77
|
}
|