@weaverse/hydrogen 6.1.2 → 6.2.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.
Files changed (142) hide show
  1. package/dist/index.js +5 -6
  2. package/dist/index.mjs +1 -2
  3. package/dist/internal.js +18 -29
  4. package/dist/internal.mjs +3 -14
  5. package/dist/next-client-boundary.js +1088 -0
  6. package/dist/next-client-boundary.js.map +1 -0
  7. package/dist/next-client-boundary.mjs +1038 -0
  8. package/dist/next-client-boundary.mjs.map +1 -0
  9. package/dist/next-server.js +669 -13
  10. package/dist/next-server.js.map +1 -0
  11. package/dist/next-server.mjs +666 -2
  12. package/dist/next-server.mjs.map +1 -0
  13. package/dist/next.js +33 -41
  14. package/dist/next.mjs +5 -3
  15. package/dist/react-router.js +6 -7
  16. package/dist/react-router.mjs +2 -3
  17. package/dist/seo-B8u2r3rX.mjs +205 -0
  18. package/dist/seo-B8u2r3rX.mjs.map +1 -0
  19. package/dist/seo-D9A9uRQ4.js +264 -0
  20. package/dist/seo-D9A9uRQ4.js.map +1 -0
  21. package/dist/translate-Celryv8j.mjs +26 -0
  22. package/dist/translate-Celryv8j.mjs.map +1 -0
  23. package/dist/translate-Kt1BYL1n.js +37 -0
  24. package/dist/translate-Kt1BYL1n.js.map +1 -0
  25. package/dist/{nested-key-CR3-YMFi.js → translation-store-BmGxBALf.js} +46 -137
  26. package/dist/translation-store-BmGxBALf.js.map +1 -0
  27. package/dist/{nested-key-_k9aW_Wd.mjs → translation-store-JFs-4lvf.mjs} +35 -138
  28. package/dist/translation-store-JFs-4lvf.mjs.map +1 -0
  29. package/dist/types/hooks/translation-context.d.ts +2 -36
  30. package/dist/types/hooks/translation-context.d.ts.map +1 -1
  31. package/dist/types/next/client-boundary.d.ts +25 -0
  32. package/dist/types/next/client-boundary.d.ts.map +1 -0
  33. package/dist/types/next/client.d.ts +16 -0
  34. package/dist/types/next/client.d.ts.map +1 -0
  35. package/dist/types/next/hooks.d.ts +20 -0
  36. package/dist/types/next/hooks.d.ts.map +1 -0
  37. package/dist/types/next/index.d.ts +34 -0
  38. package/dist/types/next/index.d.ts.map +1 -0
  39. package/dist/types/next/item.d.ts +60 -0
  40. package/dist/types/next/item.d.ts.map +1 -0
  41. package/dist/types/next/loader.d.ts +25 -0
  42. package/dist/types/next/loader.d.ts.map +1 -0
  43. package/dist/types/next/main.d.ts +11 -0
  44. package/dist/types/next/main.d.ts.map +1 -0
  45. package/dist/types/next/provider.d.ts +85 -0
  46. package/dist/types/next/provider.d.ts.map +1 -0
  47. package/dist/types/next/registry.d.ts +15 -0
  48. package/dist/types/next/registry.d.ts.map +1 -0
  49. package/dist/types/next/renderer.d.ts +21 -0
  50. package/dist/types/next/renderer.d.ts.map +1 -0
  51. package/dist/types/next/request-info.d.ts +19 -0
  52. package/dist/types/next/request-info.d.ts.map +1 -0
  53. package/dist/types/next/revalidate-item.d.ts +82 -0
  54. package/dist/types/next/revalidate-item.d.ts.map +1 -0
  55. package/dist/types/next/root-provider.d.ts +65 -0
  56. package/dist/types/next/root-provider.d.ts.map +1 -0
  57. package/dist/types/next/runtime.d.ts +113 -0
  58. package/dist/types/next/runtime.d.ts.map +1 -0
  59. package/dist/types/next/seo.d.ts +55 -0
  60. package/dist/types/next/seo.d.ts.map +1 -0
  61. package/dist/types/next/server/configs.d.ts +27 -0
  62. package/dist/types/next/server/configs.d.ts.map +1 -0
  63. package/dist/types/next/server/normalize-page-url.d.ts +19 -0
  64. package/dist/types/next/server/normalize-page-url.d.ts.map +1 -0
  65. package/dist/types/next/server/revalidate-handler.d.ts +55 -0
  66. package/dist/types/next/server/revalidate-handler.d.ts.map +1 -0
  67. package/dist/types/next/server/server-client.d.ts +21 -0
  68. package/dist/types/next/server/server-client.d.ts.map +1 -0
  69. package/dist/types/next/server.d.ts +19 -0
  70. package/dist/types/next/server.d.ts.map +1 -0
  71. package/dist/types/next/studio-bridge.d.ts +16 -0
  72. package/dist/types/next/studio-bridge.d.ts.map +1 -0
  73. package/dist/types/next/studio-connect.d.ts +27 -0
  74. package/dist/types/next/studio-connect.d.ts.map +1 -0
  75. package/dist/types/next/studio-router.d.ts +50 -0
  76. package/dist/types/next/studio-router.d.ts.map +1 -0
  77. package/dist/types/next/studio-script-src.d.ts +12 -0
  78. package/dist/types/next/studio-script-src.d.ts.map +1 -0
  79. package/dist/types/next/theme-settings-store.d.ts +18 -0
  80. package/dist/types/next/theme-settings-store.d.ts.map +1 -0
  81. package/dist/types/next/translation-context.d.ts +109 -0
  82. package/dist/types/next/translation-context.d.ts.map +1 -0
  83. package/dist/types/next/types.d.ts +674 -0
  84. package/dist/types/next/types.d.ts.map +1 -0
  85. package/dist/types/next/use-weaverse-next-studio.d.ts +34 -0
  86. package/dist/types/next/use-weaverse-next-studio.d.ts.map +1 -0
  87. package/dist/types/next/utils.d.ts +21 -0
  88. package/dist/types/next/utils.d.ts.map +1 -0
  89. package/dist/types/next-server.d.ts +3 -1
  90. package/dist/types/next-server.d.ts.map +1 -1
  91. package/dist/types/next.d.ts +4 -3
  92. package/dist/types/next.d.ts.map +1 -1
  93. package/dist/types/utils/translate.d.ts +51 -0
  94. package/dist/types/utils/translate.d.ts.map +1 -0
  95. package/dist/{weaverse-client-C9IgIH7O.js → weaverse-client-BmceZc5q.js} +49 -771
  96. package/dist/weaverse-client-BmceZc5q.js.map +1 -0
  97. package/dist/{weaverse-client-D59mBW0j.mjs → weaverse-client-CXnM9ayH.mjs} +4 -720
  98. package/dist/weaverse-client-CXnM9ayH.mjs.map +1 -0
  99. package/package.json +13 -7
  100. package/src/hooks/translation-context.tsx +7 -84
  101. package/src/next/client-boundary.ts +51 -0
  102. package/src/next/client.ts +102 -0
  103. package/src/next/hooks.ts +52 -0
  104. package/src/next/index.ts +145 -0
  105. package/src/next/item.ts +167 -0
  106. package/src/next/loader.ts +135 -0
  107. package/src/next/main.tsx +45 -0
  108. package/src/next/provider.tsx +241 -0
  109. package/src/next/registry.ts +63 -0
  110. package/src/next/renderer.tsx +102 -0
  111. package/src/next/request-info.ts +124 -0
  112. package/src/next/revalidate-item.ts +211 -0
  113. package/src/next/root-provider.tsx +201 -0
  114. package/src/next/runtime.ts +559 -0
  115. package/src/next/seo.ts +157 -0
  116. package/src/next/server/configs.ts +178 -0
  117. package/src/next/server/normalize-page-url.ts +73 -0
  118. package/src/next/server/revalidate-handler.ts +357 -0
  119. package/src/next/server/server-client.ts +728 -0
  120. package/src/next/server.ts +67 -0
  121. package/src/next/studio-bridge.tsx +82 -0
  122. package/src/next/studio-connect.tsx +88 -0
  123. package/src/next/studio-router.ts +85 -0
  124. package/src/next/studio-script-src.ts +128 -0
  125. package/src/next/theme-settings-store.ts +47 -0
  126. package/src/next/translation-context.tsx +182 -0
  127. package/src/next/types.ts +764 -0
  128. package/src/next/use-weaverse-next-studio.tsx +106 -0
  129. package/src/next/utils.ts +48 -0
  130. package/src/next-server.ts +41 -1
  131. package/src/next.ts +51 -15
  132. package/src/utils/translate.ts +101 -0
  133. package/dist/internal.js.map +0 -1
  134. package/dist/internal.mjs.map +0 -1
  135. package/dist/nested-key-CR3-YMFi.js.map +0 -1
  136. package/dist/nested-key-_k9aW_Wd.mjs.map +0 -1
  137. package/dist/translation-store-4fAV771j.js +0 -69
  138. package/dist/translation-store-4fAV771j.js.map +0 -1
  139. package/dist/translation-store-BBrw0FOk.mjs +0 -58
  140. package/dist/translation-store-BBrw0FOk.mjs.map +0 -1
  141. package/dist/weaverse-client-C9IgIH7O.js.map +0 -1
  142. package/dist/weaverse-client-D59mBW0j.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"nested-key-_k9aW_Wd.mjs","names":[],"sources":["../src/types.ts","../src/utils/studio-script-src.ts","../src/utils/index.ts","../src/utils/nested-key.ts"],"sourcesContent":["import type {\n CacheInstance,\n CachingStrategy,\n I18nConfig,\n StorefrontClient,\n} from '@shopify/hydrogen'\nimport type {\n ElementData,\n PositionInputValue,\n StudioSelectionStore,\n WeaverseCoreParams,\n WeaverseElement,\n WeaverseImage,\n WeaverseProjectDataType,\n WeaverseResourcePickerData,\n WeaverseVideo,\n} from '@weaverse/react'\nimport type {\n // Enhanced type exports from schema package\n BasicInput,\n ComponentAvailabilityContext,\n ComponentGroup,\n HeadingInput,\n InputType,\n InspectorGroup,\n PageSEOData,\n PageType,\n Resolvable,\n ComponentPresets as SchemaComponentPresets,\n SchemaType,\n SchemaValidationIssue,\n SchemaValidationResult,\n ThemeOutline,\n ThemeRoutes,\n} from '@weaverse/schema'\nimport { isValidSchema } from '@weaverse/schema'\nimport type * as React from 'react'\nimport type { ForwardRefExoticComponent } from 'react'\nimport type {\n AppLoadContext,\n LoaderFunctionArgs,\n NavigateFunction,\n} from 'react-router'\nimport type { TranslationStore } from './utils/translation-store'\nimport type { ThemeSettingsStore } from './utils/use-theme-settings-store'\nimport type { WeaverseHydrogen } from './WeaverseHydrogenRoot'\nimport type { WeaverseClient } from './weaverse-client'\n\n// Re-export CachingStrategy from Hydrogen for convenience\nexport type { CachingStrategy } from '@shopify/hydrogen'\n// Re-export types from schema for backward compatibility and convenience\nexport type {\n // Enhanced type exports\n BasicInput,\n ComponentAvailabilityContext,\n ComponentGroup,\n HeadingInput,\n InputType,\n InspectorGroup,\n PageType,\n PositionInputValue,\n Resolvable,\n SchemaValidationIssue,\n SchemaValidationResult,\n WeaverseImage,\n WeaverseVideo,\n}\n\n/** Arguments passed to a component's server-side loader. */\nexport type WeaverseComponentLoaderArgs<T = any, _E = any> = {\n /** Persisted component data merged with schema defaults. */\n data: T\n /** Request-scoped client available to the component loader. */\n weaverse: WeaverseClient\n}\n\n/** Application load context initialized with a request-scoped Weaverse client. */\nexport interface WeaverseRouteAppLoadContext extends AppLoadContext {\n /** Client used to load Weaverse content for the current request. */\n weaverse: WeaverseClient\n}\n\n/** React Router loader arguments whose app context includes the Weaverse client. */\nexport interface RouteLoaderArgs extends LoaderFunctionArgs {\n /** Request-scoped application context with the initialized Weaverse client. */\n context: WeaverseRouteAppLoadContext\n}\n\n/** Primitive value accepted in a component's persisted data. */\nexport type ComponentDataValue = string | number | boolean | undefined | null\n\n/** Reference to a direct child component instance. */\nexport interface WeaverseChildComponentReference {\n /** Unique identifier of the child component instance. */\n id: string\n}\n\n/** Serialized component instance returned in a Weaverse page. */\nexport interface WeaverseComponentData extends ElementData {\n /** References to direct child component instances. */\n children?: WeaverseChildComponentReference[]\n /** ISO timestamp recording when the component instance was created. */\n createdAt?: string\n /** Persisted component setting values and structured payloads. */\n data?: Record<string, ComponentDataValue | Record<string, unknown>>\n /** ISO timestamp recording soft deletion, when applicable. */\n deletedAt?: string\n /** Unique component instance identifier. */\n id: string\n /** Registered component type used to select its renderer. */\n type: string\n /** ISO timestamp recording the latest component update. */\n updatedAt?: string\n}\n\n/**\n * Optimized: Use Zod-inferred SchemaType directly instead of extending\n * This ensures perfect type consistency with the schema validation\n */\nexport type WeaverseComponentSchema = SchemaType\n\n/** Props supplied by Weaverse when rendering a registered Hydrogen component. */\nexport interface WeaverseComponentProps<L = any> extends WeaverseElement {\n /** Rendered child component instances. */\n children?: React.JSX.Element[]\n /** Optional CSS class passed through by the renderer. */\n className?: string\n /** Result returned by the component's server-side loader. */\n loaderData?: L\n}\n\n/** Normalized request details attached to loader data for Studio navigation. */\nexport type WeaverseLoaderRequestInfo = {\n /** URL search string, including the leading question mark when present. */\n search: string\n /** Storefront request pathname. */\n pathname: string\n /** Parsed request query parameters. */\n queries: {\n /** Query parameter value keyed by parameter name. */\n [key: string]: string | boolean\n }\n /** Locale used to load the page. */\n i18n: WeaverseI18n\n}\n\n/** Published theme setting values keyed by schema setting name. */\nexport type WeaverseThemeSettings = {\n /** Published theme setting value keyed by schema setting name. */\n [key: string]: any\n}\n\n/** Project metadata returned with a Weaverse page payload. */\nexport type WeaverseProjectType = {\n /** Unique Weaverse project identifier. */\n id: string\n /** Identifier of the Shopify shop connected to the project. */\n weaverseShopId: string\n /** Human-readable project name. */\n name: string\n /** Additional project metadata returned by the content API. */\n [key: string]: any\n}\n\n/** Runtime services and project metadata exposed to Weaverse integrations. */\nexport type WeaverseInternal = {\n /** Route assignment for the rendered Weaverse page. */\n pageAssignment: WeaversePageAssignment\n /** Metadata for the active Weaverse project. */\n project: WeaverseProjectType\n /** React Router navigation function, attached in design mode. */\n navigate: NavigateFunction\n /** Revalidates the active React Router data routes. */\n revalidate: () => void\n /** Mutable theme settings store used by Studio. */\n themeSettingsStore: ThemeSettingsStore\n /**\n * Studio selection store the Studio bridge writes; read by `useStudioSelection`.\n * One store per root layout, shared by every Weaverse root on the document:\n * Studio has one selection and writes it only through the root it is editing.\n */\n studioSelectionStore?: StudioSelectionStore | null\n /** Mutable translation store used by Studio, when translations are enabled. */\n translationStore?: TranslationStore | null\n /** @deprecated Use translationStore instead. */\n themeTextStore?: TranslationStore | null\n /** Active-locale merchant translation overrides. */\n merchantOverrides?: Record<string, unknown> | null\n}\n\n/**\n * Optimized: Use direct type alias to maintain consistency\n */\nexport type HydrogenComponentPresets = SchemaComponentPresets\n\n/** Registered runtime definition for a Hydrogen component type. */\nexport type HydrogenElement = {\n /** React renderer for this registered component type. */\n Component:\n | ForwardRefExoticComponent<WeaverseComponentProps>\n | ((props: WeaverseComponentProps) => React.JSX.Element)\n /** Unique component type matching the component schema. */\n type: string\n /** Component schema used for settings, defaults, and availability. */\n schema?: WeaverseComponentSchema\n /** Optional data loader function for server-side data fetching. */\n loader?: (args: WeaverseComponentLoaderArgs) => Promise<unknown>\n}\n\n/** Initialization parameters for a request-scoped {@link WeaverseHydrogen} runtime. */\nexport interface WeaverseHydrogenParams\n extends Omit<WeaverseCoreParams, 'ItemConstructor'> {\n /** Page content used to initialize component instances. */\n data: WeaversePageData\n /** Route loader data made available to component data bindings. */\n dataContext?: Record<string, unknown> | null\n /** Runtime services and metadata available to integrations. */\n internal: Partial<WeaverseInternal>\n /** Whether the page is running inside the visual editor. */\n isDesignMode?: boolean\n /** Whether a component preview is being rendered. */\n isPreviewMode?: boolean\n /** Whether a saved page revision is being previewed. */\n isRevisionPreview?: boolean\n /** Identifier of the page being rendered. */\n pageId: string\n /** Identifier of the Weaverse project supplying content. */\n projectId: string\n /** Normalized URL and locale information for this request. */\n requestInfo: WeaverseLoaderRequestInfo\n /** Component type requested by section preview mode. */\n sectionType?: string\n /** Base URL used for public Weaverse API requests. */\n weaverseApiBase: string\n /**\n * API key read from environment/configuration for storefront requests or\n * supplied by Studio requests while editing and previewing.\n */\n weaverseApiKey: string\n /** Origin used for Weaverse Studio assets and editor communication. */\n weaverseHost: string\n /**\n * Public data API origin. Keep `weaverseHost` for Studio scripts/editor\n * assets; point this at the Cloudflare proxy (`https://api.weaverse.io`)\n * when edge caching is enabled.\n */\n weaversePublicApiBase?: string\n /** Optional Studio asset version used by preview integrations. */\n weaverseVersion?: string\n}\n\n/** Export shape for a renderable component, its schema, and optional loader. */\nexport type WeaverseComponent<T extends WeaverseComponentProps = any> = {\n /** React renderer exported by the component module. */\n default: ForwardRefExoticComponent<T> | ((props: T) => React.JSX.Element)\n /** Schema exported by the component module. */\n schema: WeaverseComponentSchema\n /** Optional data loader function for server-side data fetching. */\n loader?: (args: WeaverseComponentLoaderArgs) => Promise<unknown>\n}\n\n/** Weaverse Studio query parameters recognized by the Hydrogen runtime. */\nexport type WeaverseStudioQueries = {\n /** Project identifier selected by Studio for this request. */\n weaverseProjectId: string\n /** API key passed by Studio for design and preview requests. */\n weaverseApiKey: string\n /** Studio origin serving editor assets and APIs. */\n weaverseHost: string\n /** Studio asset version requested by the editor. */\n weaverseVersion: string\n /** Whether the request is for the visual editor. */\n isDesignMode: boolean\n /** Whether the request renders a component preview. */\n isPreviewMode?: boolean\n /** Component type requested for section preview. */\n sectionType?: string\n}\n\n/** Storefront-safe environment values exposed with theme settings. */\nexport type PublicEnv = {\n /** Public Shopify storefront domain. */\n PUBLIC_STORE_DOMAIN: string\n /** Public Storefront API access token. */\n PUBLIC_STOREFRONT_API_TOKEN: string\n}\n\n/** Resolved project, API endpoint, and rendering-mode configuration. */\nexport type WeaverseProjectConfigs = {\n /** Identifier of the Weaverse project supplying content. */\n projectId: string\n /** Origin used for Studio assets and editor communication. */\n weaverseHost: string\n /** Base URL used for public Weaverse content API requests. */\n weaverseApiBase: string\n /** Explicit public data API origin, when separately configured. */\n weaversePublicApiBase?: string\n /**\n * API key read from environment/configuration for storefront requests or\n * supplied by Studio requests while editing and previewing.\n */\n weaverseApiKey: string\n /** Optional Studio asset version. */\n weaverseVersion?: string\n /** Whether the request is running inside the visual editor. */\n isDesignMode?: boolean\n /** Whether the request renders a component preview. */\n isPreviewMode?: boolean\n /** Whether the request previews a saved page revision. */\n isRevisionPreview?: boolean\n /** Component type requested for section preview. */\n sectionType?: string\n /** Storefront-safe environment values exposed with theme settings. */\n publicEnv?: PublicEnv\n}\n\n/** Assignment describing which project page handles a storefront route. */\nexport type WeaversePageAssignment = {\n /** Project identifier owning the assigned page. */\n projectId: string\n /** Storefront page type matched by the assignment. */\n type: PageType\n /** Route or resource handle matched by the assignment. */\n handle: string\n /** Locale matched by the assignment. */\n locale: string\n /** Inheritance details when the assignment comes from another project. */\n meta?: {\n /** Whether the assignment was inherited. */\n inherited: boolean\n /** Project identifier where the assignment originated. */\n sourceProjectId: string\n /** Number of inheritance levels traversed. */\n depth: number\n }\n}\n\n/** Complete payload returned by `WeaverseClient.loadPage()`. */\nexport type WeaverseLoaderData = {\n /** Resolved runtime configuration and normalized request details. */\n configs: Omit<WeaverseProjectConfigs, 'publicEnv'> & {\n /** Normalized URL and locale information for the request. */\n requestInfo: WeaverseLoaderRequestInfo\n }\n /** Published page content to render. */\n page: WeaversePageData\n /** Metadata for the project supplying the page. */\n project: WeaverseProjectType\n /** Route assignment that selected the page, when available. */\n pageAssignment?: WeaversePageAssignment\n}\n\n/** Published Weaverse page content consumed by the Hydrogen renderer. */\nexport interface WeaversePageData extends WeaverseProjectDataType {\n /** Internal cache identifier attached by the content API when available. */\n __cacheId?: string\n /** Unique page identifier. */\n id: string\n /** Serialized component instances belonging to the page. */\n items: WeaverseComponentData[]\n /** Human-readable page name. */\n name: string\n /**\n * Page-level SEO metadata published by Weaverse Builder. `null` when\n * the page has no `PageSeo` row; absent on revision snapshots that\n * predate the SEO feature. Themes should treat both as \"no Weaverse\n * override\".\n */\n seo?: PageSEOData | null\n /** Additional page fields supplied by the content API. */\n [key: string]: any\n}\n\n/** Locale metadata used when requesting localized Weaverse content. */\nexport type WeaverseI18n = I18nConfig & {\n /** Human-readable locale label displayed in Studio. */\n label?: string\n /** Locale path prefix used by the storefront router. */\n pathPrefix?: string\n /** Additional locale metadata supplied by the storefront. */\n [key: string]: any\n}\n\n/** Theme metadata, global settings, and localization configuration. */\nexport type WeaverseThemeSchema = {\n /** Theme identity, author, and support metadata. */\n info: {\n /** Human-readable theme name. */\n name: string\n /** Theme version displayed in Studio. */\n version: string\n /** Theme author name. */\n author: string\n /** URL of the theme author's profile image. */\n authorProfilePhoto: string\n /** URL of the theme documentation. */\n documentationUrl: string\n /** URL where merchants can request theme support. */\n supportUrl: string\n }\n /** @deprecated Use settings instead. */\n inspector?: InspectorGroup[]\n /**\n * Store-wide defaults for the Media Manager gallery. Mirrors\n * `MediaInputConfigs` in `@weaverse/schema`, which documents the fields.\n *\n * Deliberately a sibling of `settings` rather than an entry inside it:\n * `settings` renders as merchant-editable controls in Studio, and these\n * rules are meant to be fixed by the theme author. An individual `image` or\n * `video` input can still override them through its own `configs`.\n *\n * Note: duplicated instead of imported because this package pins the\n * published `@weaverse/schema`, which does not export the type yet. Replace\n * with the shared type once schema ships it.\n */\n media?: {\n /** Filename prefixes hidden from the Media Manager gallery. */\n excludeFilenamePrefixes?: string[]\n /** Hide files used in products. Matches usage, not origin. */\n excludeProductFiles?: boolean\n }\n /** Groups of global theme settings exposed in Studio. */\n settings?: InspectorGroup[]\n /**\n * URL patterns for the page types whose routes differ from the Shopify\n * convention, so Studio can navigate to them, e.g.\n * `{ COLLECTION: '/shop/:handle' }`. See `ThemeRoutes`.\n */\n routes?: ThemeRoutes\n /**\n * Settings groups listed in the Studio Page Outline, keyed by area. See\n * `ThemeOutline`.\n */\n outline?: ThemeOutline\n /** Theme localization configuration. */\n i18n?: {\n /** Strategy used to encode the locale in storefront URLs. */\n urlStructure: 'url-path' | 'subdomain' | 'top-level-domain'\n /** Locale used when no localized route is selected. */\n defaultLocale: WeaverseI18n\n /** Locales enabled for the connected Shopify shop. */\n shopLocales: WeaverseI18n[]\n /** Default-locale static translation content. */\n staticContent?: Record<string, unknown>\n /** Enable the translation UI in the builder. */\n translation?: boolean\n }\n}\n\n/** Request body sent to the Weaverse project content endpoint. */\nexport type FetchProjectRequestBody = {\n /** Identifier of the project to load. */\n projectId: string\n /** Normalized storefront URL being resolved. */\n url: string\n /** Storefront locale for localized content. */\n i18n?: WeaverseI18n\n /** Optional route-specific page lookup parameters. */\n params?: {\n /** Storefront page type to load. */\n type?: PageType\n /** Locale override for this page lookup. */\n locale?: string\n /** Resource or custom-page handle to load. */\n handle?: string\n }\n /** Whether draft editor content should be returned. */\n isDesignMode?: boolean\n}\n\n/** Project content response before it is normalized into loader data. */\nexport type FetchProjectPayload = {\n /** Published or draft page content; absent when no page matches. */\n page?: WeaversePageData\n /** Project metadata; absent in some error responses. */\n project?: WeaverseProjectType\n /** Assignment that selected the page, when one matched. */\n pageAssignment?: WeaversePageAssignment\n /** API error message, when the request could not be fulfilled. */\n error?: string\n /** Additional fields returned by compatible API versions. */\n [key: string]: any\n}\n\n/**\n * Project identifier value - can be static string or dynamic function.\n *\n * **Static String**: Direct project ID reference\n * ```ts\n * 'project-abc-123'\n * ```\n *\n * **Synchronous Function**: Returns project ID based on request context\n * ```ts\n * () => {\n * const host = new URL(request.url).hostname\n * return PROJECT_MAP[host] || 'default-project'\n * }\n * ```\n *\n * **Asynchronous Function**: Async project resolution (must be awaited before passing)\n * ```ts\n * async () => {\n * return await database.getProjectId(userId)\n * }\n * ```\n */\nexport type ProjectIdValue = string | (() => string) | (() => Promise<string>)\n\n/**\n * Type guard for detecting function-based projectId.\n *\n * Used internally by WeaverseClient constructor to determine\n * if projectId needs evaluation or can be used directly.\n */\nexport function isProjectIdFunction(\n projectId: ProjectIdValue | undefined\n): projectId is (() => string) | (() => Promise<string>) {\n return typeof projectId === 'function'\n}\n\n/**\n * Extended WeaverseClient constructor arguments supporting multi-project architecture.\n *\n * @example Static project (existing pattern - backward compatible)\n * ```ts\n * const weaverse = new WeaverseClient({\n * ...hydrogenContext,\n * projectId: 'project-default-123'\n * })\n * ```\n *\n * @example Dynamic project selection (new capability)\n * ```ts\n * const weaverse = new WeaverseClient({\n * ...hydrogenContext,\n * projectId: () => {\n * const origin = new URL(request.url).origin\n * if (origin === 'https://mystore.se') return process.env.WEAVERSE_PROJECT_SWEDEN!\n * if (origin === 'https://mystore.fr') return process.env.WEAVERSE_PROJECT_FRANCE!\n * return process.env.WEAVERSE_PROJECT_ID!\n * }\n * })\n * ```\n *\n * **Priority Chain** (highest to lowest):\n * 1. URL query parameter: `?weaverseProjectId=...` (design mode, preview mode)\n * 2. Function result (if function provided)\n * 3. Explicit string value (if string provided)\n * 4. Environment variable: `WEAVERSE_PROJECT_ID` (Hydrogen env or process.env)\n * 5. Empty string (triggers validation error in methods)\n *\n * **Function Requirements**:\n * - Must return non-empty string\n * - Can access request via closure for routing decisions\n * - Evaluated once per WeaverseClient instance (request-scoped)\n * - Async functions must be awaited before passing to constructor\n * - Should handle edge cases (missing headers, invalid domains, etc.)\n *\n * **Request Context Access**:\n * Functions access request via closure from constructor arguments.\n */\nexport type WeaverseClientArgs = {\n /**\n * Request-scoped Hydrogen Storefront API client. Section loaders reach it\n * as `weaverse.storefront`; its `i18n` selects the content locale unless\n * {@link WeaverseClientArgs.locale} is given.\n */\n storefront: WeaverseStorefront\n\n /**\n * The market this request serves, as Weaverse identifies it. It selects the\n * Translation Manager overrides (`${language}-${country}`, lowercased), the\n * locale sent with page requests and the `requestInfo.i18n` Studio reads,\n * so include `pathPrefix`. Pass it when the storefront's `i18n.language` is\n * a Shopify `LanguageCode` that differs from the market's public language,\n * such as `ZH_TW` for a Traditional Chinese Hong Kong market.\n *\n * @defaultValue `storefront.i18n`\n */\n locale?: WeaverseI18n\n\n /** Runtime environment variables, such as the Oxygen worker `env`. */\n env: WeaverseEnv\n\n /** Keeps the runtime alive for background cache writes and refreshes. */\n waitUntil?: (promise: Promise<unknown>) => void\n\n /**\n * Customer Account API client, when the storefront has one. Weaverse only\n * passes it through to section loaders.\n */\n customerAccount?: unknown\n\n /**\n * React components registered with Weaverse CMS.\n * Each component must have a schema defining its properties and settings.\n */\n components: WeaverseComponent[]\n\n /**\n * Theme schema defining global theme settings (colors, fonts, layouts).\n * Used to generate default theme configuration and validate theme data.\n */\n themeSchema: WeaverseThemeSchema\n\n /**\n * Incoming HTTP request object from React Router loader.\n * Provides access to URL, headers, cookies for dynamic routing decisions.\n */\n request: Request\n\n /**\n * Hydrogen cache instance for content caching, such as the worker's\n * `caches.open('hydrogen-v1')`. Cache keys include the project ID.\n */\n cache: CacheInstance\n\n /**\n * Project identifier for loading content from Weaverse CMS.\n *\n * **Value Types**:\n * - Static string: 'project-123' (existing usage)\n * - Synchronous function: () => determineProject(request)\n * - Asynchronous function: async () => await getProject(request) (must be awaited)\n *\n * **Backward Compatibility**:\n * - Optional parameter (defaults to environment variable)\n * - Existing code without projectId continues to work unchanged\n *\n * **Cache Isolation**:\n * ProjectId is included in cache keys to prevent cross-project content pollution.\n * Each project's content is cached separately, ensuring multi-tenant isolation.\n */\n projectId?: ProjectIdValue\n\n /**\n * Fetch timeout in milliseconds for API requests.\n * Defaults to 10000ms (10 seconds) if not specified.\n * Useful for adjusting based on network conditions or deployment environment.\n *\n * @default 10000\n * @example\n * ```typescript\n * new WeaverseClient({\n * // ... other args\n * fetchTimeoutMs: 5000 // 5 second timeout\n * })\n * ```\n */\n fetchTimeoutMs?: number\n\n /**\n * Reject `loadPage()` with a {@link WeaverseLoadError} when the page cannot\n * be loaded, instead of resolving to `null`.\n *\n * With the default (`false`), an unavailable API, an invalid response and a\n * configuration failure all resolve to `null`, the same value a missing\n * project produces, so a route cannot tell an outage from a 404. Enable this\n * to answer failures with a retryable or configuration error response while\n * genuine absence keeps resolving to `null` or a fallback page.\n *\n * @default false\n */\n throwPageLoadFailures?: boolean\n}\n\n/** Per-call options the storefront client accepts in addition to Hydrogen's. */\nexport type WeaverseStorefrontCallOptions = {\n /** Caching strategy for this Storefront API request. */\n cache?: CachingStrategy\n}\n\n/** Storefront API client accepted by `WeaverseClient`, with a per-call `cache` option. */\nexport type WeaverseStorefront = StorefrontClient<WeaverseStorefrontCallOptions>\n\n/** Environment variables read by Weaverse, plus any other storefront variables. */\nexport interface WeaverseEnv {\n /** Shopify store domain exposed to Studio. */\n PUBLIC_STORE_DOMAIN?: string\n /** Public Storefront API token exposed to Studio. */\n PUBLIC_STOREFRONT_API_TOKEN?: string\n /** Weaverse API key. */\n WEAVERSE_API_KEY?: string\n /** Weaverse Studio host, e.g. `https://studio.weaverse.io`. */\n WEAVERSE_HOST?: string\n /** Default Weaverse project ID. */\n WEAVERSE_PROJECT_ID?: string\n /** Base URL of the Weaverse public content API. */\n WEAVERSE_PUBLIC_API_BASE?: string\n /** Any other storefront variable. */\n [key: string]: string | undefined\n}\n\n/** Product selected through a Weaverse resource-picker setting. */\nexport type WeaverseProduct = WeaverseResourcePickerData\n/** Collection selected through a Weaverse resource-picker setting. */\nexport type WeaverseCollection = WeaverseResourcePickerData\n/** Blog selected through a Weaverse resource-picker setting. */\nexport type WeaverseBlog = WeaverseResourcePickerData\n/** Article selected through a Weaverse resource-picker setting. */\nexport type WeaverseArticle = WeaverseResourcePickerData\n/** Metaobject selected through a Weaverse resource-picker setting. */\nexport type WeaverseMetaObject = WeaverseResourcePickerData\n\n/** Response returned by Hydrogen's cached fetch helper. */\nexport type WithCacheFetchResponse<T> = {\n /** Parsed response payload. */\n data: T\n /** Underlying Fetch API response. */\n response: Response\n}\n\n/** Theme configuration returned by the Weaverse project API. */\nexport type WeaverseThemeSettingsResponse = {\n /** Published theme setting values. */\n theme?: WeaverseThemeSettings\n /** Theme schema included for Studio editing. */\n schema?: WeaverseThemeSchema\n /** Storefront-safe environment values included in design mode. */\n publicEnv?: PublicEnv\n /** Theme's default locale JSON from `themeSchema.i18n.staticContent`. */\n staticContent?: Record<string, unknown>\n /** Locale-specific merchant overrides from the API. */\n merchantOverrides?: Record<string, unknown>\n /** Diagnostic message when loading fell back to schema defaults. */\n _error?: string\n /** Whether remote theme settings failed to load. */\n _loadFailed?: boolean\n}\n\n/**\n * Legacy data-or-error response shape retained for compatibility.\n *\n * The client's current direct-fetch implementation uses\n * {@link WithCacheFetchResponse} internally instead of returning this shape.\n */\nexport type DirectFetchResponse<T = unknown> = {\n /** Parsed payload when the legacy request succeeded. */\n data?: T\n /** Error message when the legacy request failed. */\n error?: string\n}\n\n/** Predicate used to decide whether a fetched response may be cached. */\nexport type CacheResponseValidator<T = unknown> = (\n response: WithCacheFetchResponse<T> | T\n) => boolean\n\n/** Error raised by Weaverse requests with a stable code and optional context. */\nexport class WeaverseError extends Error {\n /** Machine-readable error code. */\n public readonly code: string\n /** HTTP status associated with the failure, when available. */\n public readonly statusCode?: number\n /** Structured diagnostic details for logging and error handling. */\n public readonly context?: Record<string, unknown>\n\n /** Creates a Weaverse request error with a stable code and diagnostics. */\n constructor(\n message: string,\n code = 'WEAVERSE_ERROR',\n statusCode?: number,\n context?: Record<string, unknown>\n ) {\n super(message)\n this.name = 'WeaverseError'\n this.code = code\n this.statusCode = statusCode\n this.context = context\n\n // Maintains proper stack trace for where our error was thrown\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, WeaverseError)\n }\n }\n}\n\n/**\n * Why a Weaverse page could not be loaded, as distinct from the page being\n * genuinely absent.\n *\n * - `unavailable`: the Weaverse API timed out, could not be reached, or\n * answered with a transient status (408, 425, 429 or 5xx) after the built-in\n * retry. Retrying later can succeed.\n * - `invalid-response`: the API answered successfully with a body that is not\n * a page/project envelope.\n * - `configuration`: the request was refused or could not be built (missing or\n * invalid project ID, 400/401/403 from the API). Retrying will not help.\n */\nexport type WeaverseLoadFailureKind =\n | 'unavailable'\n | 'invalid-response'\n | 'configuration'\n\n/**\n * Error thrown by `WeaverseClient.loadPage()` when the client is created\n * with `throwPageLoadFailures: true` and the page cannot be loaded.\n *\n * Genuine absence is not an error: a missing project still resolves to `null`\n * and an unassigned page still resolves to a fallback page.\n */\nexport class WeaverseLoadError extends WeaverseError {\n /** Failure class used to choose a response status or recovery action. */\n public readonly kind: WeaverseLoadFailureKind\n\n /** Creates a classified page-load failure. */\n constructor(\n message: string,\n kind: WeaverseLoadFailureKind,\n statusCode?: number,\n context?: Record<string, unknown>\n ) {\n super(message, 'LOAD_FAILURE', statusCode, context)\n this.name = 'WeaverseLoadError'\n this.kind = kind\n }\n}\n\n/**\n * Validation result type for project ID validation.\n * Returns validation status with optional error message.\n */\nexport type ProjectIdValidationResult = {\n /** Whether the project identifier passed validation. */\n valid: boolean\n /** Validation error message when `valid` is false. */\n error?: string\n}\n\n/** Published custom page entry suitable for sitemap generation. */\nexport interface CustomPageEntry {\n /** Suggested sitemap update frequency. */\n changeFrequency?: 'daily' | 'weekly' | 'monthly'\n /** Weaverse custom page handle. */\n handle: string\n /** ISO timestamp of the latest published update. */\n lastModified: string\n /** Locale code, or `null` for the project's default locale. */\n locale: string | null\n /** Storefront path for the custom page. */\n path: string\n /** Optional sitemap priority from zero to one. */\n priority?: number\n}\n\n/**\n * Type guards for response validation\n */\n\nexport function isWithCacheFetchResponse<T>(\n response: unknown\n): response is WithCacheFetchResponse<T> {\n return (\n typeof response === 'object' &&\n response !== null &&\n 'data' in response &&\n 'response' in response\n )\n}\n\n/** Checks whether a value contains the required project response fields. */\nexport function isFetchProjectPayload(\n payload: unknown\n): payload is FetchProjectPayload {\n return (\n typeof payload === 'object' &&\n payload !== null &&\n 'page' in payload &&\n 'project' in payload &&\n 'pageAssignment' in payload\n )\n}\n\n/** Response containing an error message returned by a Weaverse request. */\nexport interface WeaverseErrorResponse {\n /** Human-readable request failure message. */\n error: string\n}\n\n/** Checks whether a response contains a string error message. */\nexport function hasError(response: unknown): response is WeaverseErrorResponse {\n return (\n typeof response === 'object' &&\n response !== null &&\n 'error' in response &&\n typeof (response as Record<string, unknown>).error === 'string'\n )\n}\n\n/** Checks whether a value contains a theme settings object. */\nexport function isThemeSettingsResponse(\n data: unknown\n): data is WeaverseThemeSettingsResponse {\n if (typeof data !== 'object' || data === null) {\n return false\n }\n\n const record = data as Record<string, unknown>\n return (\n 'theme' in record &&\n typeof record.theme === 'object' &&\n record.theme !== null\n )\n}\n\n/**\n * Enhanced type utilities for better development experience\n */\nexport type HydrogenSchemaValidationResult =\n SchemaValidationResult<WeaverseComponentSchema>\n\n/**\n * Type guard to check if a schema is valid.\n * Leverages validation from @weaverse/schema package which provides\n * comprehensive Zod-based validation with the ElementSchema.\n *\n * @param schema - Unknown value to validate\n * @returns True if schema is a valid WeaverseComponentSchema\n *\n * @example\n * ```typescript\n * if (isValidHydrogenSchema(userInput)) {\n * // userInput is now typed as WeaverseComponentSchema\n * console.log(userInput.type)\n * }\n * ```\n */\nexport function isValidHydrogenSchema(\n schema: unknown\n): schema is WeaverseComponentSchema {\n // Use the comprehensive validation from @weaverse/schema package\n return isValidSchema(schema)\n}\n\n/** Type-safe component schema authoring options. */\nexport type CreateHydrogenSchemaOptions = {\n /** Human-readable component title displayed in Studio. */\n title: string\n /** Unique component type used for registration and persisted items. */\n type: string\n /** Maximum number of instances allowed in the containing scope. */\n limit?: number\n /** Inspector groups defining editable component settings. */\n settings?: InspectorGroup[]\n /** Component types allowed as direct children. */\n childTypes?: string[]\n /**\n * Legacy page and placement availability restrictions.\n *\n * @deprecated Use `enabled` instead. Convert the arrays to checks in an\n * `enabled` resolver, for example:\n * `enabled: ({page, group}) => pages.includes(page.type) &&\n * (groups.includes('*') || groups.includes(group))`.\n */\n enabledOn?: {\n /** Page types where the component can be inserted. */\n pages?: PageType[]\n /** Placement groups where the component can be inserted; `*` allows all. */\n groups?: ('*' | 'header' | 'footer' | 'body')[]\n }\n /** Static or context-aware component availability rule. */\n enabled?: Resolvable<boolean, ComponentAvailabilityContext>\n /** Default component data and optional nested component presets. */\n presets?: {\n /** Components inserted as children by the preset. */\n children?: SchemaComponentPresets[]\n /** Additional default setting value keyed by setting name. */\n [key: string]: any\n }\n}\n\n// Extended window interface for hydrogen-specific globals\n// `__weaverse`/`__weaverses` are typed where they are used: the Next.js\n// adapter declares the same globals with its own runtime type.\ndeclare global {\n interface Window {\n __weaverseThemeSettingsStore?: ThemeSettingsStore\n }\n}\n\n/** Browser bridge exposed by Weaverse Studio in design and preview modes. */\nexport interface WeaverseStudio {\n /** Connects Studio to a newly created Hydrogen runtime. */\n init: (weaverse: WeaverseHydrogen) => void\n /** Refreshes Studio after the active runtime configuration changes. */\n refreshStudio: (params: WeaverseHydrogenParams) => void\n}\n\n/** Browser window after the Weaverse Studio bridge has initialized. */\nexport interface WeaverseStudioWindow extends Window {\n /** Studio bridge used to initialize and refresh the Hydrogen runtime. */\n weaverseStudio: WeaverseStudio\n}\n\n/** Checks whether the browser window exposes the Weaverse Studio bridge. */\nexport function hasWeaverseStudio(\n window: Window\n): window is WeaverseStudioWindow {\n return 'weaverseStudio' in window && typeof window.weaverseStudio === 'object'\n}\n\ndeclare module 'react-router' {\n interface AppLoadContext {\n weaverse: WeaverseClient\n }\n interface RouterContextProvider {\n weaverse: WeaverseClient\n }\n}\n\n/**\n * Parameters for loadPage method supporting route-level project override.\n *\n * @example Basic usage (uses client-level project)\n * ```ts\n * const weaverseData = await weaverse.loadPage({\n * type: 'PRODUCT',\n * handle: params.productHandle\n * })\n * ```\n *\n * @example Route-level project override\n * ```ts\n * export async function loader({ params, context }: LoaderFunctionArgs) {\n * const { weaverse } = context\n *\n * // Use special campaign project for this route only\n * const weaverseData = await weaverse.loadPage({\n * type: 'PRODUCT',\n * handle: params.productHandle,\n * projectId: process.env.WEAVERSE_PROJECT_CAMPAIGN // Override\n * })\n *\n * return { weaverseData }\n * }\n * ```\n */\nexport type LoadPageParams = {\n /**\n * Page type to load from Weaverse CMS.\n *\n * Determines which template to use for rendering the page.\n * Falls back to 'INDEX' if not specified or if page type doesn't exist.\n *\n * @default 'INDEX'\n */\n type?: PageType\n\n /**\n * Locale for internationalization.\n *\n * Format: IETF BCP 47 language tag (e.g., 'en-US', 'fr-FR', 'de-DE')\n * Used to load locale-specific content and translations.\n */\n locale?: string\n\n /**\n * Page handle for dynamic pages.\n *\n * Identifies specific resource within page type:\n * - Product handle: 'red-sneakers'\n * - Collection handle: 'summer-sale'\n * - Page handle: 'about-us'\n * - Article handle: 'how-to-style-sneakers'\n */\n handle?: string\n\n /**\n * Cache strategy override for this specific page load.\n *\n * Overrides default cache strategy for special use cases:\n * - Fresh content for checkout pages (no cache)\n * - Long-lived cache for static pages (1 hour+)\n * - Short-lived cache for frequently updated content (5 minutes)\n */\n strategy?: CachingStrategy\n\n /**\n * Optional project override for this specific page load.\n *\n * **Precedence**: Route-level projectId takes precedence over client-level projectId.\n *\n * **Use Cases**:\n * - Campaign landing pages with custom content\n * - VIP customer experiences with dedicated projects\n * - A/B testing specific pages without changing global config\n * - Seasonal promotions with limited-time content\n *\n * **Validation**:\n * - Must be non-empty string\n * - Validated before API call\n * - Falls back to client-level projectId if undefined\n * - Does NOT support function (string only)\n *\n * **Cache Isolation**:\n * Override projectId is included in cache key, ensuring separate caches\n * for different projects even on the same route.\n *\n * @example Campaign page override\n * ```ts\n * const campaignData = await weaverse.loadPage({\n * type: 'PAGE',\n * handle: 'summer-sale',\n * projectId: process.env.WEAVERSE_PROJECT_CAMPAIGN\n * })\n * ```\n */\n projectId?: string\n}\n\n// ─── Translation sidecar types (design mode) ─────────────────────────\n\n/** A single translated field for one item. */\nexport interface TranslationMapEntry {\n /** Source-locale value used to detect subsequent content changes. */\n originalValue: string\n /** Localized value rendered for the target locale. */\n translatedValue: string\n}\n\n/** Per-item translation fields, keyed by field name */\nexport type TranslationItemEntry = {\n /** Translation entry keyed by component field name. */\n [key: string]: TranslationMapEntry\n}\n\n/**\n * Translation map sent from the builder alongside page data in design mode.\n * Keyed by item ID, each value maps field names to translation entries.\n */\nexport type TranslationMap = {\n /** Translated fields keyed by component instance identifier. */\n [itemId: string]: TranslationItemEntry\n}\n\n/** A single translation entry for save payloads. */\nexport interface TranslationEntry {\n /** Marks an existing translation for deletion. */\n deleted?: boolean\n /** Identifier of the component instance owning the field. */\n itemId: string\n /** Dot-path to the translated component field. */\n key: string\n /** Source-locale value used to detect content changes. */\n originalValue: string\n /** Localized value to persist. */\n translatedValue: string\n}\n\n/** Result of collecting translation changes for the save flow */\nexport type TranslationChanges = {\n /** Builder language identifier receiving the changes. */\n languageId: string\n /** Translation entries to create, update, or delete. */\n entries: TranslationEntry[]\n}\n","/** Rendering mode and host details used to select a Studio bridge script. */\nexport interface StudioMode {\n /** Whether the storefront is running inside the visual editor. */\n isDesignMode?: boolean\n /** Whether a component preview is being rendered. */\n isPreviewMode?: boolean\n /** Whether a saved page revision is being previewed. */\n isRevisionPreview?: boolean\n /** Trusted origin serving Studio bridge assets. */\n weaverseHost: string\n /** Studio asset version appended to the script URL. */\n weaverseVersion: string\n}\n\nconst DEFAULT_WEAVERSE_HOST = 'https://studio.weaverse.io'\n\n/**\n * Weaverse-controlled apex domains the Studio bridge may be served from\n * (matched on the host itself and any subdomain).\n */\nconst TRUSTED_STUDIO_DOMAINS = ['weaverse.io', 'weaverse.dev']\n\nfunction isLoopbackHostname(hostname: string): boolean {\n return (\n hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname.endsWith('.localhost')\n )\n}\n\nexport interface TrustedStudioHostOptions {\n /**\n * Also trust loopback hosts (`localhost` / `127.0.0.1` / `*.localhost`) over\n * http or https.\n *\n * Only safe when the **storefront itself** is loopback (genuine local-builder\n * dev). A production https page can still load a loopback script — loopback is\n * a \"potentially trustworthy\" origin and is not blocked as mixed content — so\n * honoring a query-supplied loopback host on a public storefront would let a\n * crafted link run whatever a visitor's local service serves inside the\n * storefront origin. MUST stay off on the server, where it is an SSRF vector\n * for page/theme fetches.\n */\n allowLoopback?: boolean\n}\n\n/**\n * Whether `host` is an origin we trust to serve the Studio bridge script (or,\n * server-side, to resolve page/theme data).\n *\n * The bridge executes inside the storefront document and the host can drive\n * server-side fetches, so a host taken from an attacker-controllable source —\n * e.g. a crafted `?weaverseHost=` query — is both an XSS and an SSRF vector.\n * Callers MUST reject untrusted hosts before acting on them. Trusts\n * `weaverse.io`/`weaverse.dev` and their subdomains over https; loopback is\n * opt-in (see {@link TrustedStudioHostOptions.allowLoopback}).\n */\nexport function isTrustedStudioHost(\n host: string,\n options?: TrustedStudioHostOptions\n): boolean {\n let parsed: URL\n try {\n parsed = new URL(host)\n } catch {\n return false\n }\n let { hostname, protocol } = parsed\n // Loopback (opt-in) is the only place http is allowed — a local builder\n // serves the bridge over http and there is no cleartext-downgrade risk to a\n // private address. Every other trusted host must be https so server-side\n // page/theme fetches are never downgraded to cleartext.\n if (options?.allowLoopback && isLoopbackHostname(hostname)) {\n return protocol === 'http:' || protocol === 'https:'\n }\n if (protocol !== 'https:') {\n return false\n }\n return TRUSTED_STUDIO_DOMAINS.some(\n (domain) => hostname === domain || hostname.endsWith(`.${domain}`)\n )\n}\n\n/**\n * Build the Studio bridge script URL for the current mode, or `null` when the\n * storefront is not being previewed inside Weaverse Studio.\n *\n * This is the single gate that keeps the bridge off production storefronts:\n * a normal visitor's URL carries none of the design/preview markers, so the\n * result is `null` and no script is ever requested.\n *\n * Shared by the page-scoped `useStudio` (which also binds the page for\n * editing) and the root-level `useStudioConnect` (which only needs the script\n * to load so Studio's `checkWeaversePage()` handshake can answer on routes\n * with no Weaverse content).\n */\nexport function getStudioScriptSrc(mode: StudioMode): string | null {\n let {\n isDesignMode,\n isPreviewMode,\n isRevisionPreview,\n weaverseHost,\n weaverseVersion,\n } = mode\n let base = `${weaverseHost}/static/studio/hydrogen`\n let version = `?v=${weaverseVersion}`\n if (isRevisionPreview || isPreviewMode) {\n return `${base}/preview.js${version}`\n }\n if (isDesignMode) {\n return `${base}/index.js${version}`\n }\n return null\n}\n\n/**\n * Resolve the Studio bridge script URL from a URL query string — the markers\n * Studio attaches when it drives the preview iframe (`isDesignMode`,\n * `isPreviewMode`, `__revisionId`, `weaverseHost`, `weaverseVersion`) — or\n * `null` outside Studio.\n *\n * `storefrontHostname` is the document's own hostname: a loopback Studio host\n * is only honored when the storefront itself is loopback (genuine local-builder\n * dev), so a crafted public link can't load a script from a visitor's loopback\n * service into the storefront origin.\n *\n * The `weaverseHost` query is attacker-controllable, so a host that is not a\n * {@link isTrustedStudioHost trusted origin} resolves to `null` (no bridge) —\n * it is never silently replaced with production Studio, which would otherwise\n * inject the wrong bridge for self-hosted/staging deployments. Such deployments\n * (a non-`weaverse.io` `WEAVERSE_HOST`) therefore don't load the root bridge on\n * content-less routes; the page-scoped {@link getStudioScriptSrc} via\n * `useStudio` still uses the configured host on content routes.\n *\n * Pure (no DOM) so the root-level connect's production gate stays unit-testable\n * and needs no loader data.\n */\nexport function resolveStudioScriptSrc(\n search: string,\n storefrontHostname = ''\n): string | null {\n let params = new URLSearchParams(search)\n // Match the server's getRequestQueries(), which keeps the LAST value of a\n // duplicated key. Studio appends its own control params, so a pre-existing\n // (stale/untrusted) `weaverseHost` earlier in the URL must not win here, or\n // the root bridge would be skipped while the loader uses the later host.\n let last = (key: string) => params.getAll(key).at(-1)\n let host = last('weaverseHost')\n if (host) {\n let allowLoopback = isLoopbackHostname(storefrontHostname)\n if (!isTrustedStudioHost(host, { allowLoopback })) {\n return null\n }\n }\n return getStudioScriptSrc({\n isDesignMode: last('isDesignMode') === 'true',\n isPreviewMode: last('isPreviewMode') === 'true',\n isRevisionPreview: params.has('__revisionId'),\n weaverseHost: host || DEFAULT_WEAVERSE_HOST,\n weaverseVersion: last('weaverseVersion') || '',\n })\n}\n","import type {\n WeaverseComponent,\n WeaverseComponentSchema,\n WeaverseEnv,\n WeaverseLoaderData,\n WeaverseProjectConfigs,\n WeaverseStudioQueries,\n WeaverseThemeSchema,\n} from '../types'\nimport { isTrustedStudioHost } from './studio-script-src'\n\n// Track warned types to avoid spam\nlet warnedTypes = new Set<string>()\n\nfunction logOnce(type: string, message: string) {\n if (!warnedTypes.has(type)) {\n console.warn(message)\n warnedTypes.add(type)\n }\n}\n\nfunction deepMergeArrays<T>(target: T[], source: T[]): T[] {\n return [...target, ...source]\n}\n\nfunction mergeInspectorSettings(\n settings: any[],\n inspector: any[],\n type: string\n): any[] {\n if (!inspector?.length) {\n return settings\n }\n if (!settings?.length) {\n return inspector\n }\n\n // Log collision notice\n console.info(\n `Schema \"${type}\": Both 'settings' and 'inspector' found. Using 'settings' with 'inspector' as fallback.`\n )\n\n return deepMergeArrays(settings, inspector)\n}\n\n/** Options for extracting query parameters from a request URL. */\nexport interface RequestQueryOptions {\n /** Query parameter names to include; all parameters are included when omitted. */\n allowedKeys?: string[]\n}\n\n/**\n * Extract and parse query parameters from a request URL.\n * Supports optional allowlist for security-sensitive applications.\n *\n * @param request - The incoming request\n * @param options - Optional configuration\n * @param options.allowedKeys - If provided, only these keys will be extracted\n * @returns Parsed query parameters with type coercion for booleans\n *\n * @example\n * ```typescript\n * // Extract all params\n * const queries = getRequestQueries(request)\n *\n * // Extract only allowed params (security-sensitive)\n * const queries = getRequestQueries(request, {\n * allowedKeys: ['weaverseProjectId', 'weaverseHost']\n * })\n * ```\n */\nexport function getRequestQueries<T = Record<string, string | boolean>>(\n request: Request,\n options?: RequestQueryOptions\n): T {\n let url = new URL(request.url)\n let queries: Record<string, unknown> = {}\n\n for (let [key, value] of url.searchParams.entries()) {\n // If allowlist provided, skip non-allowed keys\n if (options?.allowedKeys && !options.allowedKeys.includes(key)) {\n continue\n }\n\n // Type-safe conversion for known boolean patterns\n if (value === 'true') {\n queries[key] = true\n } else if (value === 'false') {\n queries[key] = false\n } else {\n queries[key] = value\n }\n }\n\n return queries as T\n}\n\n/**\n * Resolves project, endpoint, and Studio mode configuration for a request.\n * URL-provided Studio values take precedence over environment defaults.\n */\nexport function getWeaverseConfigs(\n request: Request,\n env: WeaverseEnv\n): WeaverseProjectConfigs {\n let queries = getRequestQueries<WeaverseStudioQueries>(request)\n let {\n WEAVERSE_PROJECT_ID,\n WEAVERSE_API_KEY,\n WEAVERSE_HOST,\n WEAVERSE_PUBLIC_API_BASE,\n PUBLIC_STORE_DOMAIN,\n PUBLIC_STOREFRONT_API_TOKEN,\n } = env || {}\n let envFromProcess: WeaverseEnv =\n (typeof process !== 'undefined' && process.env) || {}\n let {\n weaverseProjectId,\n weaverseHost,\n isDesignMode,\n isPreviewMode,\n sectionType,\n weaverseVersion,\n weaverseApiKey,\n } = queries\n\n let url = new URL(request.url)\n let isRevisionPreview = url.searchParams.has('__revisionId')\n let configuredWeaverseHost = WEAVERSE_HOST || envFromProcess.WEAVERSE_HOST\n // `weaverseHost` arrives from the request URL (Studio drives the preview\n // iframe with it), so it is attacker-controllable; only honor it when it is a\n // trusted Weaverse origin, otherwise fall back to the env/default host. This\n // stops a crafted `?weaverseHost=` from pointing Studio scripts or data reads\n // at an arbitrary origin.\n let trustedUrlHost =\n typeof weaverseHost === 'string' && isTrustedStudioHost(weaverseHost)\n ? weaverseHost\n : ''\n let resolvedWeaverseHost =\n trustedUrlHost || configuredWeaverseHost || 'https://studio.weaverse.io'\n // Public data reads default to the edge proxy, but an explicit custom\n // WEAVERSE_HOST (staging/self-hosted Weaverse) must stay the API base so\n // those deployments don't fetch page/config data from the production proxy.\n let resolvedWeaverseApiBase = trustedUrlHost\n ? trustedUrlHost\n : WEAVERSE_PUBLIC_API_BASE ||\n envFromProcess.WEAVERSE_PUBLIC_API_BASE ||\n (configuredWeaverseHost &&\n configuredWeaverseHost !== 'https://studio.weaverse.io'\n ? configuredWeaverseHost\n : 'https://api.weaverse.io')\n\n return {\n projectId:\n weaverseProjectId ||\n WEAVERSE_PROJECT_ID ||\n envFromProcess.WEAVERSE_PROJECT_ID ||\n '',\n weaverseHost: resolvedWeaverseHost,\n weaverseApiBase: resolvedWeaverseApiBase,\n weaversePublicApiBase: resolvedWeaverseApiBase,\n weaverseApiKey:\n weaverseApiKey ||\n WEAVERSE_API_KEY ||\n envFromProcess.WEAVERSE_API_KEY ||\n '',\n weaverseVersion: weaverseVersion || '',\n isDesignMode,\n isPreviewMode,\n isRevisionPreview,\n sectionType: sectionType || '',\n publicEnv: {\n PUBLIC_STORE_DOMAIN: PUBLIC_STORE_DOMAIN || '',\n PUBLIC_STOREFRONT_API_TOKEN: PUBLIC_STOREFRONT_API_TOKEN || '',\n },\n }\n}\n\n/**\n * Cache for generateDataFromSchema results using WeakMap.\n * WeakMap allows garbage collection when schema objects are no longer referenced.\n */\nconst schemaDefaultsCache = new WeakMap<\n WeaverseComponentSchema | WeaverseThemeSchema,\n Record<string, any>\n>()\n\n/**\n * Generate default data from component or theme schema.\n * Results are memoized using WeakMap for performance.\n *\n * @param schema - Component or theme schema\n * @returns Default data object extracted from schema inputs\n */\nexport function generateDataFromSchema(\n schema: WeaverseComponentSchema | WeaverseThemeSchema\n) {\n // Check cache first for performance\n const cached = schemaDefaultsCache.get(schema)\n if (cached) {\n return cached\n }\n\n let data: Record<string, any> = {}\n\n // Handle migration from inspector to settings\n let inspectorGroups: any[] = []\n\n // Type guard to check if it's a component schema\n const isComponentSchema = (\n s: WeaverseComponentSchema | WeaverseThemeSchema\n ): s is WeaverseComponentSchema => 'type' in s && typeof s.type === 'string'\n\n if (isComponentSchema(schema)) {\n // Handle WeaverseComponentSchema\n if (schema.settings) {\n inspectorGroups = schema.settings\n }\n\n if (schema.inspector) {\n if (schema.settings?.length) {\n // Both exist - merge with settings taking priority\n inspectorGroups = mergeInspectorSettings(\n schema.settings,\n schema.inspector,\n schema.type || 'unknown'\n )\n } else {\n // Only inspector exists - use it but warn about deprecation\n inspectorGroups = schema.inspector\n if (schema.type) {\n logOnce(\n schema.type,\n `⚠️ Schema \"${schema.type}\": The 'inspector' property is deprecated. Please use 'settings' instead.`\n )\n }\n }\n }\n } else {\n // Handle WeaverseThemeSchema\n if (schema.settings) {\n inspectorGroups = schema.settings\n }\n\n if (schema.inspector) {\n if (schema.settings?.length) {\n // Both exist - merge with settings taking priority\n inspectorGroups = mergeInspectorSettings(\n schema.settings,\n schema.inspector,\n 'Theme Schema'\n )\n } else {\n // Only inspector exists - use it but warn about deprecation\n inspectorGroups = schema.inspector\n logOnce(\n 'ThemeSchema',\n `⚠️ Theme Schema: The 'inspector' property is deprecated. Please use 'settings' instead.`\n )\n }\n }\n }\n\n if (inspectorGroups?.length) {\n for (let group of inspectorGroups) {\n for (let input of group.inputs) {\n let { name, defaultValue } = input\n if (name && defaultValue !== null && defaultValue !== undefined) {\n data[name] = defaultValue\n }\n }\n }\n }\n\n // Cache the result before returning\n schemaDefaultsCache.set(schema, data)\n\n return data\n}\n\nfunction recursivelyAddDataItem(\n type: string,\n components: WeaverseComponent<any>[],\n items: any[],\n initData?: object\n) {\n let component = components.find((c) => c.schema.type === type)\n if (!component) {\n return\n }\n let childIds = []\n let id = crypto.randomUUID()\n let { children, ...data } = component.schema?.presets || {}\n if (children) {\n for (let c of children) {\n let { type, children, ...data } = c\n let childId = recursivelyAddDataItem(type, components, items, data)\n childIds.push({ id: childId } as never)\n }\n }\n items.push({\n data: { ...data, ...initData },\n id,\n type,\n children: childIds,\n })\n return id\n}\n\n/** Creates synthetic loader data for previewing one registered component type. */\nexport function getPreviewData(\n type: string,\n components: WeaverseComponent[],\n weaverseHost: string\n) {\n let items = []\n return {\n project: { id: 'x', weaverseShopId: 'shop-id', name: 'Section Preview' },\n configs: {\n projectId: 'x',\n weaverseHost,\n isDesignMode: false,\n isPreviewMode: true,\n requestInfo: {\n i18n: {\n label: 'United States (USD $)',\n language: 'EN',\n country: 'US',\n currency: 'USD',\n pathPrefix: '',\n },\n queries: {},\n pathname: '/',\n search: '',\n },\n },\n page: {\n id: 'weaverse-preview-page',\n name: 'Preview section',\n rootId: '1',\n items: [\n {\n data: {},\n id: '1',\n type: 'main',\n children: [{ id: recursivelyAddDataItem(type, components, items) }],\n },\n ...items,\n ],\n },\n } as unknown as WeaverseLoaderData\n}\n","/**\n * Traverse a nested object by dot-path.\n *\n * @example\n * getNestedKey({ cart: { title: 'Cart' } }, 'cart.title') // => 'Cart'\n * getNestedKey({}, 'cart.title', 'fallback') // => 'fallback'\n */\nexport function getNestedKey(\n obj: Record<string, unknown>,\n path: string,\n fallback?: string\n): string | undefined {\n const keys = path.split('.')\n let current: unknown = obj\n\n for (const key of keys) {\n if (current == null || typeof current !== 'object') {\n return fallback\n }\n current = (current as Record<string, unknown>)[key]\n }\n\n if (typeof current === 'string') {\n return current\n }\n\n return fallback\n}\n"],"mappings":"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"}
@@ -1,69 +0,0 @@
1
- //#region src/utils/translation-store.ts
2
- /**
3
- * Minimal mutable store for design-mode static text overrides.
4
- *
5
- * useSyncExternalStore-compatible. Passed into TranslationProvider which
6
- * subscribes internally and merges overrides into merchantOverrides.
7
- * The studio bridge calls updateOverrides() via weaverse.internal.translationStore
8
- * (also exposed as the deprecated weaverse.internal.themeTextStore alias).
9
- *
10
- * Shape: flat Record<string, string> — dot-notation keys map to values
11
- * (e.g. "cart.title" → "Shopping Cart").
12
- */
13
- var TranslationStore = class {
14
- /** Current flat translation overrides keyed by dot-path. */
15
- overrides = {};
16
- listeners = /* @__PURE__ */ new Set();
17
- /** Replaces all overrides and notifies subscribers. */
18
- setOverrides = (overrides) => {
19
- this.overrides = { ...overrides };
20
- this.emit();
21
- };
22
- /** Merges changed overrides and notifies subscribers. */
23
- updateOverrides = (newOverrides) => {
24
- this.overrides = {
25
- ...this.overrides,
26
- ...newOverrides
27
- };
28
- this.emit();
29
- };
30
- /** Returns the current client snapshot for `useSyncExternalStore`. */
31
- getSnapshot = () => this.overrides;
32
- /** Returns the current server snapshot for `useSyncExternalStore`. */
33
- getServerSnapshot = () => this.overrides;
34
- /** Subscribes to override changes and returns an unsubscribe callback. */
35
- subscribe = (callback) => {
36
- this.listeners.add(callback);
37
- return () => {
38
- this.listeners.delete(callback);
39
- };
40
- };
41
- emit = () => {
42
- for (const listener of Array.from(this.listeners)) try {
43
- listener();
44
- } catch (error) {
45
- console.error("TranslationStore: Listener error", error);
46
- }
47
- };
48
- };
49
- /**
50
- * Legacy constructor alias retained for existing theme text integrations.
51
- * @deprecated Use {@link TranslationStore} instead. This alias remains available
52
- * for backward compatibility.
53
- */
54
- const ThemeTextStore = TranslationStore;
55
- //#endregion
56
- Object.defineProperty(exports, "ThemeTextStore", {
57
- enumerable: true,
58
- get: function() {
59
- return ThemeTextStore;
60
- }
61
- });
62
- Object.defineProperty(exports, "TranslationStore", {
63
- enumerable: true,
64
- get: function() {
65
- return TranslationStore;
66
- }
67
- });
68
-
69
- //# sourceMappingURL=translation-store-4fAV771j.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"translation-store-4fAV771j.js","names":[],"sources":["../src/utils/translation-store.ts"],"sourcesContent":["/**\n * Minimal mutable store for design-mode static text overrides.\n *\n * useSyncExternalStore-compatible. Passed into TranslationProvider which\n * subscribes internally and merges overrides into merchantOverrides.\n * The studio bridge calls updateOverrides() via weaverse.internal.translationStore\n * (also exposed as the deprecated weaverse.internal.themeTextStore alias).\n *\n * Shape: flat Record<string, string> — dot-notation keys map to values\n * (e.g. \"cart.title\" → \"Shopping Cart\").\n */\nexport class TranslationStore {\n /** Current flat translation overrides keyed by dot-path. */\n overrides: Record<string, string> = {}\n private listeners: Set<() => void> = new Set()\n\n /** Replaces all overrides and notifies subscribers. */\n setOverrides = (overrides: Record<string, string>) => {\n this.overrides = { ...overrides }\n this.emit()\n }\n\n /** Merges changed overrides and notifies subscribers. */\n updateOverrides = (newOverrides: Record<string, string>) => {\n this.overrides = { ...this.overrides, ...newOverrides }\n this.emit()\n }\n\n /** Returns the current client snapshot for `useSyncExternalStore`. */\n getSnapshot = () => this.overrides\n\n /** Returns the current server snapshot for `useSyncExternalStore`. */\n getServerSnapshot = () => this.overrides\n\n /** Subscribes to override changes and returns an unsubscribe callback. */\n subscribe = (callback: () => void) => {\n this.listeners.add(callback)\n return () => {\n this.listeners.delete(callback)\n }\n }\n\n private emit = () => {\n for (const listener of Array.from(this.listeners)) {\n try {\n listener()\n } catch (error) {\n console.error('TranslationStore: Listener error', error)\n }\n }\n }\n}\n\n/**\n * Legacy constructor alias retained for existing theme text integrations.\n * @deprecated Use {@link TranslationStore} instead. This alias remains available\n * for backward compatibility.\n */\nexport const ThemeTextStore = TranslationStore\n/**\n * Legacy type alias retained for existing theme text integrations.\n * @deprecated Use {@link TranslationStore} instead. This alias remains available\n * for backward compatibility.\n */\nexport type ThemeTextStore = TranslationStore\n"],"mappings":";;;;;;;;;;;;AAWA,IAAa,mBAAb,MAA8B;;CAE5B,YAAoC,CAAC;CACrC,4BAAqC,IAAI,IAAI;;CAG7C,gBAAgB,cAAsC;EACpD,KAAK,YAAY,EAAE,GAAG,UAAU;EAChC,KAAK,KAAK;CACZ;;CAGA,mBAAmB,iBAAyC;EAC1D,KAAK,YAAY;GAAE,GAAG,KAAK;GAAW,GAAG;EAAa;EACtD,KAAK,KAAK;CACZ;;CAGA,oBAAoB,KAAK;;CAGzB,0BAA0B,KAAK;;CAG/B,aAAa,aAAyB;EACpC,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa;GACX,KAAK,UAAU,OAAO,QAAQ;EAChC;CACF;CAEA,aAAqB;EACnB,KAAK,MAAM,YAAY,MAAM,KAAK,KAAK,SAAS,GAC9C,IAAI;GACF,SAAS;EACX,SAAS,OAAO;GACd,QAAQ,MAAM,oCAAoC,KAAK;EACzD;CAEJ;AACF;;;;;;AAOA,MAAa,iBAAiB"}
@@ -1,58 +0,0 @@
1
- //#region src/utils/translation-store.ts
2
- /**
3
- * Minimal mutable store for design-mode static text overrides.
4
- *
5
- * useSyncExternalStore-compatible. Passed into TranslationProvider which
6
- * subscribes internally and merges overrides into merchantOverrides.
7
- * The studio bridge calls updateOverrides() via weaverse.internal.translationStore
8
- * (also exposed as the deprecated weaverse.internal.themeTextStore alias).
9
- *
10
- * Shape: flat Record<string, string> — dot-notation keys map to values
11
- * (e.g. "cart.title" → "Shopping Cart").
12
- */
13
- var TranslationStore = class {
14
- /** Current flat translation overrides keyed by dot-path. */
15
- overrides = {};
16
- listeners = /* @__PURE__ */ new Set();
17
- /** Replaces all overrides and notifies subscribers. */
18
- setOverrides = (overrides) => {
19
- this.overrides = { ...overrides };
20
- this.emit();
21
- };
22
- /** Merges changed overrides and notifies subscribers. */
23
- updateOverrides = (newOverrides) => {
24
- this.overrides = {
25
- ...this.overrides,
26
- ...newOverrides
27
- };
28
- this.emit();
29
- };
30
- /** Returns the current client snapshot for `useSyncExternalStore`. */
31
- getSnapshot = () => this.overrides;
32
- /** Returns the current server snapshot for `useSyncExternalStore`. */
33
- getServerSnapshot = () => this.overrides;
34
- /** Subscribes to override changes and returns an unsubscribe callback. */
35
- subscribe = (callback) => {
36
- this.listeners.add(callback);
37
- return () => {
38
- this.listeners.delete(callback);
39
- };
40
- };
41
- emit = () => {
42
- for (const listener of Array.from(this.listeners)) try {
43
- listener();
44
- } catch (error) {
45
- console.error("TranslationStore: Listener error", error);
46
- }
47
- };
48
- };
49
- /**
50
- * Legacy constructor alias retained for existing theme text integrations.
51
- * @deprecated Use {@link TranslationStore} instead. This alias remains available
52
- * for backward compatibility.
53
- */
54
- const ThemeTextStore = TranslationStore;
55
- //#endregion
56
- export { TranslationStore as n, ThemeTextStore as t };
57
-
58
- //# sourceMappingURL=translation-store-BBrw0FOk.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"translation-store-BBrw0FOk.mjs","names":[],"sources":["../src/utils/translation-store.ts"],"sourcesContent":["/**\n * Minimal mutable store for design-mode static text overrides.\n *\n * useSyncExternalStore-compatible. Passed into TranslationProvider which\n * subscribes internally and merges overrides into merchantOverrides.\n * The studio bridge calls updateOverrides() via weaverse.internal.translationStore\n * (also exposed as the deprecated weaverse.internal.themeTextStore alias).\n *\n * Shape: flat Record<string, string> — dot-notation keys map to values\n * (e.g. \"cart.title\" → \"Shopping Cart\").\n */\nexport class TranslationStore {\n /** Current flat translation overrides keyed by dot-path. */\n overrides: Record<string, string> = {}\n private listeners: Set<() => void> = new Set()\n\n /** Replaces all overrides and notifies subscribers. */\n setOverrides = (overrides: Record<string, string>) => {\n this.overrides = { ...overrides }\n this.emit()\n }\n\n /** Merges changed overrides and notifies subscribers. */\n updateOverrides = (newOverrides: Record<string, string>) => {\n this.overrides = { ...this.overrides, ...newOverrides }\n this.emit()\n }\n\n /** Returns the current client snapshot for `useSyncExternalStore`. */\n getSnapshot = () => this.overrides\n\n /** Returns the current server snapshot for `useSyncExternalStore`. */\n getServerSnapshot = () => this.overrides\n\n /** Subscribes to override changes and returns an unsubscribe callback. */\n subscribe = (callback: () => void) => {\n this.listeners.add(callback)\n return () => {\n this.listeners.delete(callback)\n }\n }\n\n private emit = () => {\n for (const listener of Array.from(this.listeners)) {\n try {\n listener()\n } catch (error) {\n console.error('TranslationStore: Listener error', error)\n }\n }\n }\n}\n\n/**\n * Legacy constructor alias retained for existing theme text integrations.\n * @deprecated Use {@link TranslationStore} instead. This alias remains available\n * for backward compatibility.\n */\nexport const ThemeTextStore = TranslationStore\n/**\n * Legacy type alias retained for existing theme text integrations.\n * @deprecated Use {@link TranslationStore} instead. This alias remains available\n * for backward compatibility.\n */\nexport type ThemeTextStore = TranslationStore\n"],"mappings":";;;;;;;;;;;;AAWA,IAAa,mBAAb,MAA8B;;CAE5B,YAAoC,CAAC;CACrC,4BAAqC,IAAI,IAAI;;CAG7C,gBAAgB,cAAsC;EACpD,KAAK,YAAY,EAAE,GAAG,UAAU;EAChC,KAAK,KAAK;CACZ;;CAGA,mBAAmB,iBAAyC;EAC1D,KAAK,YAAY;GAAE,GAAG,KAAK;GAAW,GAAG;EAAa;EACtD,KAAK,KAAK;CACZ;;CAGA,oBAAoB,KAAK;;CAGzB,0BAA0B,KAAK;;CAG/B,aAAa,aAAyB;EACpC,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa;GACX,KAAK,UAAU,OAAO,QAAQ;EAChC;CACF;CAEA,aAAqB;EACnB,KAAK,MAAM,YAAY,MAAM,KAAK,KAAK,SAAS,GAC9C,IAAI;GACF,SAAS;EACX,SAAS,OAAO;GACd,QAAQ,MAAM,oCAAoC,KAAK;EACzD;CAEJ;AACF;;;;;;AAOA,MAAa,iBAAiB"}