@weaverse/hydrogen 5.23.0 → 6.0.0-beta.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 (81) hide show
  1. package/dist/index.js +29 -2271
  2. package/dist/index.mjs +4 -2213
  3. package/dist/internal.js +64 -0
  4. package/dist/internal.js.map +1 -0
  5. package/dist/internal.mjs +16 -0
  6. package/dist/internal.mjs.map +1 -0
  7. package/dist/next-server.js +14 -0
  8. package/dist/next-server.mjs +2 -0
  9. package/dist/next.js +119 -0
  10. package/dist/next.mjs +5 -0
  11. package/dist/react-router.js +68 -0
  12. package/dist/react-router.mjs +5 -0
  13. package/dist/react.js +26 -0
  14. package/dist/react.mjs +2 -0
  15. package/dist/translation-store-BpPWqZ0B.js +548 -0
  16. package/dist/translation-store-BpPWqZ0B.js.map +1 -0
  17. package/dist/translation-store-C42QdI0e.mjs +441 -0
  18. package/dist/translation-store-C42QdI0e.mjs.map +1 -0
  19. package/dist/types/WeaverseHydrogenRoot.d.ts +8 -8
  20. package/dist/types/WeaverseHydrogenRoot.d.ts.map +1 -1
  21. package/dist/types/components/index.d.ts +2 -2
  22. package/dist/types/components/main.d.ts +2 -2
  23. package/dist/types/hooks/translation-context.d.ts +2 -8
  24. package/dist/types/hooks/translation-context.d.ts.map +1 -1
  25. package/dist/types/index.d.ts +12 -33
  26. package/dist/types/index.d.ts.map +1 -1
  27. package/dist/types/internal.d.ts +24 -0
  28. package/dist/types/internal.d.ts.map +1 -0
  29. package/dist/types/next-server.d.ts +8 -0
  30. package/dist/types/next-server.d.ts.map +1 -0
  31. package/dist/types/next.d.ts +12 -0
  32. package/dist/types/next.d.ts.map +1 -0
  33. package/dist/types/react-router.d.ts +18 -0
  34. package/dist/types/react-router.d.ts.map +1 -0
  35. package/dist/types/react.d.ts +11 -0
  36. package/dist/types/react.d.ts.map +1 -0
  37. package/dist/types/seo.d.ts +4 -4
  38. package/dist/types/seo.d.ts.map +1 -1
  39. package/dist/types/types.d.ts +126 -67
  40. package/dist/types/types.d.ts.map +1 -1
  41. package/dist/types/utils/index.d.ts +4 -5
  42. package/dist/types/utils/index.d.ts.map +1 -1
  43. package/dist/types/utils/nested-key.d.ts +9 -0
  44. package/dist/types/utils/nested-key.d.ts.map +1 -0
  45. package/dist/types/utils/normalize-page-url.d.ts +1 -1
  46. package/dist/types/utils/product-options.d.ts +18 -0
  47. package/dist/types/utils/product-options.d.ts.map +1 -0
  48. package/dist/types/utils/translation-store.d.ts.map +1 -1
  49. package/dist/types/utils/use-studio.d.ts +1 -1
  50. package/dist/types/utils/use-studio.d.ts.map +1 -1
  51. package/dist/types/utils/use-theme-settings-store.d.ts +8 -8
  52. package/dist/types/utils/use-theme-settings-store.d.ts.map +1 -1
  53. package/dist/types/weaverse-client.d.ts +15 -16
  54. package/dist/types/weaverse-client.d.ts.map +1 -1
  55. package/dist/weaverse-client-Clu3u7md.mjs +1966 -0
  56. package/dist/weaverse-client-Clu3u7md.mjs.map +1 -0
  57. package/dist/weaverse-client-yC4TYuVV.js +2073 -0
  58. package/dist/weaverse-client-yC4TYuVV.js.map +1 -0
  59. package/package.json +44 -20
  60. package/readme.md +76 -23
  61. package/src/WeaverseHydrogenRoot.tsx +18 -15
  62. package/src/components/index.ts +2 -2
  63. package/src/components/main.tsx +2 -2
  64. package/src/hooks/translation-context.tsx +3 -28
  65. package/src/index.ts +42 -81
  66. package/src/internal.ts +64 -0
  67. package/src/next-server.ts +13 -0
  68. package/src/next.ts +35 -0
  69. package/src/react-router.ts +52 -0
  70. package/src/react.ts +16 -0
  71. package/src/seo.ts +5 -5
  72. package/src/types.ts +158 -73
  73. package/src/utils/index.ts +15 -14
  74. package/src/utils/nested-key.ts +28 -0
  75. package/src/utils/normalize-page-url.ts +1 -1
  76. package/src/utils/product-options.ts +28 -0
  77. package/src/utils/use-studio.ts +1 -1
  78. package/src/utils/use-theme-settings-store.ts +7 -7
  79. package/src/weaverse-client.ts +313 -148
  80. package/dist/index.js.map +0 -1
  81. package/dist/index.mjs.map +0 -1
package/src/types.ts CHANGED
@@ -1,12 +1,9 @@
1
1
  import type {
2
+ CacheInstance,
2
3
  CachingStrategy,
3
- HydrogenContext,
4
- I18nBase,
4
+ I18nConfig,
5
+ StorefrontClient,
5
6
  } from '@shopify/hydrogen'
6
- import type {
7
- AppLoadContext,
8
- LoaderFunctionArgs as RemixOxygenLoaderArgs,
9
- } from '@shopify/remix-oxygen'
10
7
  import type {
11
8
  ElementData,
12
9
  PositionInputValue,
@@ -37,7 +34,11 @@ import type {
37
34
  import { isValidSchema } from '@weaverse/schema'
38
35
  import type * as React from 'react'
39
36
  import type { ForwardRefExoticComponent } from 'react'
40
- import type { NavigateFunction } from 'react-router'
37
+ import type {
38
+ AppLoadContext,
39
+ LoaderFunctionArgs,
40
+ NavigateFunction,
41
+ } from 'react-router'
41
42
  import type { TranslationStore } from './utils/translation-store'
42
43
  import type { ThemeSettingsStore } from './utils/use-theme-settings-store'
43
44
  import type { WeaverseHydrogen } from './WeaverseHydrogenRoot'
@@ -64,7 +65,7 @@ export type {
64
65
  }
65
66
 
66
67
  /** Arguments passed to a component's server-side loader. */
67
- export type ComponentLoaderArgs<T = any, _E = any> = {
68
+ export type WeaverseComponentLoaderArgs<T = any, _E = any> = {
68
69
  /** Persisted component data merged with schema defaults. */
69
70
  data: T
70
71
  /** Request-scoped client available to the component loader. */
@@ -78,7 +79,7 @@ export interface WeaverseRouteAppLoadContext extends AppLoadContext {
78
79
  }
79
80
 
80
81
  /** React Router loader arguments whose app context includes the Weaverse client. */
81
- export interface RouteLoaderArgs extends RemixOxygenLoaderArgs {
82
+ export interface RouteLoaderArgs extends LoaderFunctionArgs {
82
83
  /** Request-scoped application context with the initialized Weaverse client. */
83
84
  context: WeaverseRouteAppLoadContext
84
85
  }
@@ -87,15 +88,15 @@ export interface RouteLoaderArgs extends RemixOxygenLoaderArgs {
87
88
  export type ComponentDataValue = string | number | boolean | undefined | null
88
89
 
89
90
  /** Reference to a direct child component instance. */
90
- export interface HydrogenChildComponentReference {
91
+ export interface WeaverseChildComponentReference {
91
92
  /** Unique identifier of the child component instance. */
92
93
  id: string
93
94
  }
94
95
 
95
96
  /** Serialized component instance returned in a Weaverse page. */
96
- export interface HydrogenComponentData extends ElementData {
97
+ export interface WeaverseComponentData extends ElementData {
97
98
  /** References to direct child component instances. */
98
- children?: HydrogenChildComponentReference[]
99
+ children?: WeaverseChildComponentReference[]
99
100
  /** ISO timestamp recording when the component instance was created. */
100
101
  createdAt?: string
101
102
  /** Persisted component setting values and structured payloads. */
@@ -114,10 +115,10 @@ export interface HydrogenComponentData extends ElementData {
114
115
  * Optimized: Use Zod-inferred SchemaType directly instead of extending
115
116
  * This ensures perfect type consistency with the schema validation
116
117
  */
117
- export type HydrogenComponentSchema = SchemaType
118
+ export type WeaverseComponentSchema = SchemaType
118
119
 
119
120
  /** Props supplied by Weaverse when rendering a registered Hydrogen component. */
120
- export interface HydrogenComponentProps<L = any> extends WeaverseElement {
121
+ export interface WeaverseComponentProps<L = any> extends WeaverseElement {
121
122
  /** Rendered child component instances. */
122
123
  children?: React.JSX.Element[]
123
124
  /** Optional CSS class passed through by the renderer. */
@@ -142,13 +143,13 @@ export type WeaverseLoaderRequestInfo = {
142
143
  }
143
144
 
144
145
  /** Published theme setting values keyed by schema setting name. */
145
- export type HydrogenThemeSettings = {
146
+ export type WeaverseThemeSettings = {
146
147
  /** Published theme setting value keyed by schema setting name. */
147
148
  [key: string]: any
148
149
  }
149
150
 
150
151
  /** Project metadata returned with a Weaverse page payload. */
151
- export type HydrogenProjectType = {
152
+ export type WeaverseProjectType = {
152
153
  /** Unique Weaverse project identifier. */
153
154
  id: string
154
155
  /** Identifier of the Shopify shop connected to the project. */
@@ -162,9 +163,9 @@ export type HydrogenProjectType = {
162
163
  /** Runtime services and project metadata exposed to Weaverse integrations. */
163
164
  export type WeaverseInternal = {
164
165
  /** Route assignment for the rendered Weaverse page. */
165
- pageAssignment: HydrogenPageAssignment
166
+ pageAssignment: WeaversePageAssignment
166
167
  /** Metadata for the active Weaverse project. */
167
- project: HydrogenProjectType
168
+ project: WeaverseProjectType
168
169
  /** React Router navigation function, attached in design mode. */
169
170
  navigate: NavigateFunction
170
171
  /** Revalidates the active React Router data routes. */
@@ -188,21 +189,21 @@ export type HydrogenComponentPresets = SchemaComponentPresets
188
189
  export type HydrogenElement = {
189
190
  /** React renderer for this registered component type. */
190
191
  Component:
191
- | ForwardRefExoticComponent<HydrogenComponentProps>
192
- | ((props: HydrogenComponentProps) => React.JSX.Element)
192
+ | ForwardRefExoticComponent<WeaverseComponentProps>
193
+ | ((props: WeaverseComponentProps) => React.JSX.Element)
193
194
  /** Unique component type matching the component schema. */
194
195
  type: string
195
196
  /** Component schema used for settings, defaults, and availability. */
196
- schema?: HydrogenComponentSchema
197
+ schema?: WeaverseComponentSchema
197
198
  /** Optional data loader function for server-side data fetching. */
198
- loader?: (args: ComponentLoaderArgs) => Promise<unknown>
199
+ loader?: (args: WeaverseComponentLoaderArgs) => Promise<unknown>
199
200
  }
200
201
 
201
202
  /** Initialization parameters for a request-scoped {@link WeaverseHydrogen} runtime. */
202
203
  export interface WeaverseHydrogenParams
203
204
  extends Omit<WeaverseCoreParams, 'ItemConstructor'> {
204
205
  /** Page content used to initialize component instances. */
205
- data: HydrogenPageData
206
+ data: WeaversePageData
206
207
  /** Route loader data made available to component data bindings. */
207
208
  dataContext?: Record<string, unknown> | null
208
209
  /** Runtime services and metadata available to integrations. */
@@ -241,13 +242,13 @@ export interface WeaverseHydrogenParams
241
242
  }
242
243
 
243
244
  /** Export shape for a renderable component, its schema, and optional loader. */
244
- export type HydrogenComponent<T extends HydrogenComponentProps = any> = {
245
+ export type WeaverseComponent<T extends WeaverseComponentProps = any> = {
245
246
  /** React renderer exported by the component module. */
246
247
  default: ForwardRefExoticComponent<T> | ((props: T) => React.JSX.Element)
247
248
  /** Schema exported by the component module. */
248
- schema: HydrogenComponentSchema
249
+ schema: WeaverseComponentSchema
249
250
  /** Optional data loader function for server-side data fetching. */
250
- loader?: (args: ComponentLoaderArgs) => Promise<unknown>
251
+ loader?: (args: WeaverseComponentLoaderArgs) => Promise<unknown>
251
252
  }
252
253
 
253
254
  /** Weaverse Studio query parameters recognized by the Hydrogen runtime. */
@@ -306,7 +307,7 @@ export type WeaverseProjectConfigs = {
306
307
  }
307
308
 
308
309
  /** Assignment describing which project page handles a storefront route. */
309
- export type HydrogenPageAssignment = {
310
+ export type WeaversePageAssignment = {
310
311
  /** Project identifier owning the assigned page. */
311
312
  projectId: string
312
313
  /** Storefront page type matched by the assignment. */
@@ -326,7 +327,7 @@ export type HydrogenPageAssignment = {
326
327
  }
327
328
  }
328
329
 
329
- /** Complete payload returned by {@link WeaverseClient.loadPage}. */
330
+ /** Complete payload returned by `WeaverseClient.loadPage()`. */
330
331
  export type WeaverseLoaderData = {
331
332
  /** Resolved runtime configuration and normalized request details. */
332
333
  configs: Omit<WeaverseProjectConfigs, 'publicEnv'> & {
@@ -334,21 +335,21 @@ export type WeaverseLoaderData = {
334
335
  requestInfo: WeaverseLoaderRequestInfo
335
336
  }
336
337
  /** Published page content to render. */
337
- page: HydrogenPageData
338
+ page: WeaversePageData
338
339
  /** Metadata for the project supplying the page. */
339
- project: HydrogenProjectType
340
+ project: WeaverseProjectType
340
341
  /** Route assignment that selected the page, when available. */
341
- pageAssignment?: HydrogenPageAssignment
342
+ pageAssignment?: WeaversePageAssignment
342
343
  }
343
344
 
344
345
  /** Published Weaverse page content consumed by the Hydrogen renderer. */
345
- export interface HydrogenPageData extends WeaverseProjectDataType {
346
+ export interface WeaversePageData extends WeaverseProjectDataType {
346
347
  /** Internal cache identifier attached by the content API when available. */
347
348
  __cacheId?: string
348
349
  /** Unique page identifier. */
349
350
  id: string
350
351
  /** Serialized component instances belonging to the page. */
351
- items: HydrogenComponentData[]
352
+ items: WeaverseComponentData[]
352
353
  /** Human-readable page name. */
353
354
  name: string
354
355
  /**
@@ -363,7 +364,7 @@ export interface HydrogenPageData extends WeaverseProjectDataType {
363
364
  }
364
365
 
365
366
  /** Locale metadata used when requesting localized Weaverse content. */
366
- export type WeaverseI18n = I18nBase & {
367
+ export type WeaverseI18n = I18nConfig & {
367
368
  /** Human-readable locale label displayed in Studio. */
368
369
  label?: string
369
370
  /** Locale path prefix used by the storefront router. */
@@ -373,7 +374,7 @@ export type WeaverseI18n = I18nBase & {
373
374
  }
374
375
 
375
376
  /** Theme metadata, global settings, and localization configuration. */
376
- export type HydrogenThemeSchema = {
377
+ export type WeaverseThemeSchema = {
377
378
  /** Theme identity, author, and support metadata. */
378
379
  info: {
379
380
  /** Human-readable theme name. */
@@ -457,11 +458,11 @@ export type FetchProjectRequestBody = {
457
458
  /** Project content response before it is normalized into loader data. */
458
459
  export type FetchProjectPayload = {
459
460
  /** Published or draft page content; absent when no page matches. */
460
- page?: HydrogenPageData
461
+ page?: WeaversePageData
461
462
  /** Project metadata; absent in some error responses. */
462
- project?: HydrogenProjectType
463
+ project?: WeaverseProjectType
463
464
  /** Assignment that selected the page, when one matched. */
464
- pageAssignment?: HydrogenPageAssignment
465
+ pageAssignment?: WeaversePageAssignment
465
466
  /** API error message, when the request could not be fulfilled. */
466
467
  error?: string
467
468
  /** Additional fields returned by compatible API versions. */
@@ -546,18 +547,36 @@ export function isProjectIdFunction(
546
547
  * **Request Context Access**:
547
548
  * Functions access request via closure from constructor arguments.
548
549
  */
549
- export type WeaverseClientArgs = HydrogenContext & {
550
+ export type WeaverseClientArgs = {
551
+ /**
552
+ * Request-scoped Hydrogen Storefront API client. Section loaders reach it
553
+ * as `weaverse.storefront`; its `i18n` selects the content locale.
554
+ */
555
+ storefront: WeaverseStorefront
556
+
557
+ /** Runtime environment variables, such as the Oxygen worker `env`. */
558
+ env: WeaverseEnv
559
+
560
+ /** Keeps the runtime alive for background cache writes and refreshes. */
561
+ waitUntil?: (promise: Promise<unknown>) => void
562
+
563
+ /**
564
+ * Customer Account API client, when the storefront has one. Weaverse only
565
+ * passes it through to section loaders.
566
+ */
567
+ customerAccount?: unknown
568
+
550
569
  /**
551
570
  * React components registered with Weaverse CMS.
552
571
  * Each component must have a schema defining its properties and settings.
553
572
  */
554
- components: HydrogenComponent[]
573
+ components: WeaverseComponent[]
555
574
 
556
575
  /**
557
576
  * Theme schema defining global theme settings (colors, fonts, layouts).
558
577
  * Used to generate default theme configuration and validate theme data.
559
578
  */
560
- themeSchema: HydrogenThemeSchema
579
+ themeSchema: WeaverseThemeSchema
561
580
 
562
581
  /**
563
582
  * Incoming HTTP request object from React Router loader.
@@ -566,10 +585,10 @@ export type WeaverseClientArgs = HydrogenContext & {
566
585
  request: Request
567
586
 
568
587
  /**
569
- * Hydrogen cache instance for content caching.
570
- *Supports multi-tenant caching with project-specific cache keys.
588
+ * Hydrogen cache instance for content caching, such as the worker's
589
+ * `caches.open('hydrogen-v1')`. Cache keys include the project ID.
571
590
  */
572
- cache: Cache
591
+ cache: CacheInstance
573
592
 
574
593
  /**
575
594
  * Project identifier for loading content from Weaverse CMS.
@@ -604,6 +623,47 @@ export type WeaverseClientArgs = HydrogenContext & {
604
623
  * ```
605
624
  */
606
625
  fetchTimeoutMs?: number
626
+
627
+ /**
628
+ * Reject `loadPage()` with a {@link WeaverseLoadError} when the page cannot
629
+ * be loaded, instead of resolving to `null`.
630
+ *
631
+ * With the default (`false`), an unavailable API, an invalid response and a
632
+ * configuration failure all resolve to `null`, the same value a missing
633
+ * project produces, so a route cannot tell an outage from a 404. Enable this
634
+ * to answer failures with a retryable or configuration error response while
635
+ * genuine absence keeps resolving to `null` or a fallback page.
636
+ *
637
+ * @default false
638
+ */
639
+ throwPageLoadFailures?: boolean
640
+ }
641
+
642
+ /** Per-call options the storefront client accepts in addition to Hydrogen's. */
643
+ export type WeaverseStorefrontCallOptions = {
644
+ /** Caching strategy for this Storefront API request. */
645
+ cache?: CachingStrategy
646
+ }
647
+
648
+ /** Storefront API client accepted by `WeaverseClient`, with a per-call `cache` option. */
649
+ export type WeaverseStorefront = StorefrontClient<WeaverseStorefrontCallOptions>
650
+
651
+ /** Environment variables read by Weaverse, plus any other storefront variables. */
652
+ export interface WeaverseEnv {
653
+ /** Shopify store domain exposed to Studio. */
654
+ PUBLIC_STORE_DOMAIN?: string
655
+ /** Public Storefront API token exposed to Studio. */
656
+ PUBLIC_STOREFRONT_API_TOKEN?: string
657
+ /** Weaverse API key. */
658
+ WEAVERSE_API_KEY?: string
659
+ /** Weaverse Studio host, e.g. `https://studio.weaverse.io`. */
660
+ WEAVERSE_HOST?: string
661
+ /** Default Weaverse project ID. */
662
+ WEAVERSE_PROJECT_ID?: string
663
+ /** Base URL of the Weaverse public content API. */
664
+ WEAVERSE_PUBLIC_API_BASE?: string
665
+ /** Any other storefront variable. */
666
+ [key: string]: string | undefined
607
667
  }
608
668
 
609
669
  /** Product selected through a Weaverse resource-picker setting. */
@@ -626,11 +686,11 @@ export type WithCacheFetchResponse<T> = {
626
686
  }
627
687
 
628
688
  /** Theme configuration returned by the Weaverse project API. */
629
- export type ThemeSettingsResponse = {
689
+ export type WeaverseThemeSettingsResponse = {
630
690
  /** Published theme setting values. */
631
- theme?: HydrogenThemeSettings
691
+ theme?: WeaverseThemeSettings
632
692
  /** Theme schema included for Studio editing. */
633
- schema?: HydrogenThemeSchema
693
+ schema?: WeaverseThemeSchema
634
694
  /** Storefront-safe environment values included in design mode. */
635
695
  publicEnv?: PublicEnv
636
696
  /** Theme's default locale JSON from `themeSchema.i18n.staticContent`. */
@@ -690,6 +750,47 @@ export class WeaverseError extends Error {
690
750
  }
691
751
  }
692
752
 
753
+ /**
754
+ * Why a Weaverse page could not be loaded, as distinct from the page being
755
+ * genuinely absent.
756
+ *
757
+ * - `unavailable`: the Weaverse API timed out, could not be reached, or
758
+ * answered with a transient status (408, 425, 429 or 5xx) after the built-in
759
+ * retry. Retrying later can succeed.
760
+ * - `invalid-response`: the API answered successfully with a body that is not
761
+ * a page/project envelope.
762
+ * - `configuration`: the request was refused or could not be built (missing or
763
+ * invalid project ID, 400/401/403 from the API). Retrying will not help.
764
+ */
765
+ export type WeaverseLoadFailureKind =
766
+ | 'unavailable'
767
+ | 'invalid-response'
768
+ | 'configuration'
769
+
770
+ /**
771
+ * Error thrown by `WeaverseClient.loadPage()` when the client is created
772
+ * with `throwPageLoadFailures: true` and the page cannot be loaded.
773
+ *
774
+ * Genuine absence is not an error: a missing project still resolves to `null`
775
+ * and an unassigned page still resolves to a fallback page.
776
+ */
777
+ export class WeaverseLoadError extends WeaverseError {
778
+ /** Failure class used to choose a response status or recovery action. */
779
+ public readonly kind: WeaverseLoadFailureKind
780
+
781
+ /** Creates a classified page-load failure. */
782
+ constructor(
783
+ message: string,
784
+ kind: WeaverseLoadFailureKind,
785
+ statusCode?: number,
786
+ context?: Record<string, unknown>
787
+ ) {
788
+ super(message, 'LOAD_FAILURE', statusCode, context)
789
+ this.name = 'WeaverseLoadError'
790
+ this.kind = kind
791
+ }
792
+ }
793
+
693
794
  /**
694
795
  * Validation result type for project ID validation.
695
796
  * Returns validation status with optional error message.
@@ -764,7 +865,7 @@ export function hasError(response: unknown): response is WeaverseErrorResponse {
764
865
  /** Checks whether a value contains a theme settings object. */
765
866
  export function isThemeSettingsResponse(
766
867
  data: unknown
767
- ): data is ThemeSettingsResponse {
868
+ ): data is WeaverseThemeSettingsResponse {
768
869
  if (typeof data !== 'object' || data === null) {
769
870
  return false
770
871
  }
@@ -781,7 +882,7 @@ export function isThemeSettingsResponse(
781
882
  * Enhanced type utilities for better development experience
782
883
  */
783
884
  export type HydrogenSchemaValidationResult =
784
- SchemaValidationResult<HydrogenComponentSchema>
885
+ SchemaValidationResult<WeaverseComponentSchema>
785
886
 
786
887
  /**
787
888
  * Type guard to check if a schema is valid.
@@ -789,19 +890,19 @@ export type HydrogenSchemaValidationResult =
789
890
  * comprehensive Zod-based validation with the ElementSchema.
790
891
  *
791
892
  * @param schema - Unknown value to validate
792
- * @returns True if schema is a valid HydrogenComponentSchema
893
+ * @returns True if schema is a valid WeaverseComponentSchema
793
894
  *
794
895
  * @example
795
896
  * ```typescript
796
897
  * if (isValidHydrogenSchema(userInput)) {
797
- * // userInput is now typed as HydrogenComponentSchema
898
+ * // userInput is now typed as WeaverseComponentSchema
798
899
  * console.log(userInput.type)
799
900
  * }
800
901
  * ```
801
902
  */
802
903
  export function isValidHydrogenSchema(
803
904
  schema: unknown
804
- ): schema is HydrogenComponentSchema {
905
+ ): schema is WeaverseComponentSchema {
805
906
  // Use the comprehensive validation from @weaverse/schema package
806
907
  return isValidSchema(schema)
807
908
  }
@@ -844,10 +945,10 @@ export type CreateHydrogenSchemaOptions = {
844
945
  }
845
946
 
846
947
  // Extended window interface for hydrogen-specific globals
948
+ // `__weaverse`/`__weaverses` are typed where they are used: the Next.js
949
+ // adapter declares the same globals with its own runtime type.
847
950
  declare global {
848
951
  interface Window {
849
- __weaverse?: WeaverseHydrogen
850
- __weaverses?: Record<string, WeaverseHydrogen>
851
952
  __weaverseThemeSettingsStore?: ThemeSettingsStore
852
953
  }
853
954
  }
@@ -873,28 +974,12 @@ export function hasWeaverseStudio(
873
974
  return 'weaverseStudio' in window && typeof window.weaverseStudio === 'object'
874
975
  }
875
976
 
876
- declare module '@shopify/remix-oxygen' {
977
+ declare module 'react-router' {
877
978
  interface AppLoadContext {
878
979
  weaverse: WeaverseClient
879
980
  }
880
- }
881
-
882
- declare module '@shopify/hydrogen' {
883
- interface HydrogenEnv {
884
- CUSTOM_COLLECTION_BANNER_METAFIELD: string
885
- JUDGEME_PRIVATE_API_TOKEN: string
886
- KLAVIYO_PRIVATE_API_TOKEN: string
887
- METAOBJECT_COLOR_NAME_KEY: string
888
- METAOBJECT_COLOR_VALUE_KEY: string
889
- METAOBJECT_COLORS_TYPE: string
890
- PUBLIC_GOOGLE_GTM_ID: string
891
- PUBLIC_SHOPIFY_INBOX_SHOP_ID: string
892
- PUBLIC_STORE_DOMAIN: string
893
- PUBLIC_STOREFRONT_API_TOKEN: string
894
- WEAVERSE_API_KEY: string
895
- WEAVERSE_HOST?: string
896
- WEAVERSE_PROJECT_ID: string
897
- WEAVERSE_PUBLIC_API_BASE?: string
981
+ interface RouterContextProvider {
982
+ weaverse: WeaverseClient
898
983
  }
899
984
  }
900
985
 
@@ -1,11 +1,11 @@
1
- import type { HydrogenEnv } from '@shopify/hydrogen'
2
1
  import type {
3
- HydrogenComponent,
4
- HydrogenComponentSchema,
5
- HydrogenThemeSchema,
2
+ WeaverseComponent,
3
+ WeaverseComponentSchema,
4
+ WeaverseEnv,
6
5
  WeaverseLoaderData,
7
6
  WeaverseProjectConfigs,
8
7
  WeaverseStudioQueries,
8
+ WeaverseThemeSchema,
9
9
  } from '../types'
10
10
  import { isTrustedStudioHost } from './studio-script-src'
11
11
 
@@ -101,7 +101,7 @@ export function getRequestQueries<T = Record<string, string | boolean>>(
101
101
  */
102
102
  export function getWeaverseConfigs(
103
103
  request: Request,
104
- env: HydrogenEnv
104
+ env: WeaverseEnv
105
105
  ): WeaverseProjectConfigs {
106
106
  let queries = getRequestQueries<WeaverseStudioQueries>(request)
107
107
  let {
@@ -112,7 +112,8 @@ export function getWeaverseConfigs(
112
112
  PUBLIC_STORE_DOMAIN,
113
113
  PUBLIC_STOREFRONT_API_TOKEN,
114
114
  } = env || {}
115
- let envFromProcess = (typeof process !== 'undefined' && process.env) || {}
115
+ let envFromProcess: WeaverseEnv =
116
+ (typeof process !== 'undefined' && process.env) || {}
116
117
  let {
117
118
  weaverseProjectId,
118
119
  weaverseHost,
@@ -180,7 +181,7 @@ export function getWeaverseConfigs(
180
181
  * WeakMap allows garbage collection when schema objects are no longer referenced.
181
182
  */
182
183
  const schemaDefaultsCache = new WeakMap<
183
- HydrogenComponentSchema | HydrogenThemeSchema,
184
+ WeaverseComponentSchema | WeaverseThemeSchema,
184
185
  Record<string, any>
185
186
  >()
186
187
 
@@ -192,7 +193,7 @@ const schemaDefaultsCache = new WeakMap<
192
193
  * @returns Default data object extracted from schema inputs
193
194
  */
194
195
  export function generateDataFromSchema(
195
- schema: HydrogenComponentSchema | HydrogenThemeSchema
196
+ schema: WeaverseComponentSchema | WeaverseThemeSchema
196
197
  ) {
197
198
  // Check cache first for performance
198
199
  const cached = schemaDefaultsCache.get(schema)
@@ -207,11 +208,11 @@ export function generateDataFromSchema(
207
208
 
208
209
  // Type guard to check if it's a component schema
209
210
  const isComponentSchema = (
210
- s: HydrogenComponentSchema | HydrogenThemeSchema
211
- ): s is HydrogenComponentSchema => 'type' in s && typeof s.type === 'string'
211
+ s: WeaverseComponentSchema | WeaverseThemeSchema
212
+ ): s is WeaverseComponentSchema => 'type' in s && typeof s.type === 'string'
212
213
 
213
214
  if (isComponentSchema(schema)) {
214
- // Handle HydrogenComponentSchema
215
+ // Handle WeaverseComponentSchema
215
216
  if (schema.settings) {
216
217
  inspectorGroups = schema.settings
217
218
  }
@@ -236,7 +237,7 @@ export function generateDataFromSchema(
236
237
  }
237
238
  }
238
239
  } else {
239
- // Handle HydrogenThemeSchema
240
+ // Handle WeaverseThemeSchema
240
241
  if (schema.settings) {
241
242
  inspectorGroups = schema.settings
242
243
  }
@@ -279,7 +280,7 @@ export function generateDataFromSchema(
279
280
 
280
281
  function recursivelyAddDataItem(
281
282
  type: string,
282
- components: HydrogenComponent<any>[],
283
+ components: WeaverseComponent<any>[],
283
284
  items: any[],
284
285
  initData?: object
285
286
  ) {
@@ -309,7 +310,7 @@ function recursivelyAddDataItem(
309
310
  /** Creates synthetic loader data for previewing one registered component type. */
310
311
  export function getPreviewData(
311
312
  type: string,
312
- components: HydrogenComponent[],
313
+ components: WeaverseComponent[],
313
314
  weaverseHost: string
314
315
  ) {
315
316
  let items = []
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Traverse a nested object by dot-path.
3
+ *
4
+ * @example
5
+ * getNestedKey({ cart: { title: 'Cart' } }, 'cart.title') // => 'Cart'
6
+ * getNestedKey({}, 'cart.title', 'fallback') // => 'fallback'
7
+ */
8
+ export function getNestedKey(
9
+ obj: Record<string, unknown>,
10
+ path: string,
11
+ fallback?: string
12
+ ): string | undefined {
13
+ const keys = path.split('.')
14
+ let current: unknown = obj
15
+
16
+ for (const key of keys) {
17
+ if (current == null || typeof current !== 'object') {
18
+ return fallback
19
+ }
20
+ current = (current as Record<string, unknown>)[key]
21
+ }
22
+
23
+ if (typeof current === 'string') {
24
+ return current
25
+ }
26
+
27
+ return fallback
28
+ }
@@ -7,7 +7,7 @@ const KEPT_PARAM_RE = /^(?:__revisionId|isDesignMode|weaverse)/
7
7
  /**
8
8
  * Normalize the storefront URL sent in the Builder page API request body.
9
9
  *
10
- * The POST body participates in the `withCache` cache key, so a raw
10
+ * The POST body participates in Hydrogen's cached fetch key, so a raw
11
11
  * `request.url` fragments the cache by every marketing/tracking param:
12
12
  * each distinct `?utm_…`/`fbclid` URL is a guaranteed Builder round-trip
13
13
  * even when the resolved page is identical — precisely the paid/social
@@ -0,0 +1,28 @@
1
+ import {
2
+ getSelectedProductOptions as hydrogen_getSelectedProductOptions,
3
+ type SelectedOption,
4
+ } from '@shopify/hydrogen'
5
+
6
+ /**
7
+ * Filter out Weaverse-specific query parameters from product options.
8
+ * Removes `isDesignMode` and any parameters starting with `weaverse` prefix.
9
+ *
10
+ * @param request - The incoming HTTP request
11
+ * @returns Filtered product options for Shopify Hydrogen
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * export async function loader({ request }: LoaderFunctionArgs) {
16
+ * const selectedOptions = getSelectedProductOptions(request)
17
+ * // Use selectedOptions for product queries without Weaverse params
18
+ * }
19
+ * ```
20
+ */
21
+ export function getSelectedProductOptions(request: Request): SelectedOption[] {
22
+ let options = hydrogen_getSelectedProductOptions({
23
+ searchParams: new URL(request.url).searchParams,
24
+ })
25
+ return options.filter(
26
+ ({ name }) => name !== 'isDesignMode' && !name.startsWith('weaverse')
27
+ )
28
+ }
@@ -7,7 +7,7 @@ import {
7
7
  useRevalidator,
8
8
  } from 'react-router'
9
9
  import { useTranslation } from '../hooks/translation-context'
10
- import type { WeaverseHydrogen } from '../index'
10
+ import type { WeaverseHydrogen } from '../internal'
11
11
  import { hasWeaverseStudio } from '../types'
12
12
  import { getStudioScriptSrc, resolveStudioScriptSrc } from './studio-script-src'
13
13
  import { useThemeSettingsStore } from './use-theme-settings-store'
@@ -2,9 +2,9 @@ import { isBrowser } from '@weaverse/react'
2
2
  import { createContext, useContext, useEffect, useRef } from 'react'
3
3
  import { useRouteLoaderData } from 'react-router'
4
4
  import type {
5
- HydrogenThemeSchema,
6
- HydrogenThemeSettings,
7
5
  PublicEnv,
6
+ WeaverseThemeSchema,
7
+ WeaverseThemeSettings,
8
8
  } from '../types'
9
9
 
10
10
  /** Root-loader theme data used to initialize a {@link ThemeSettingsStore}. */
@@ -12,17 +12,17 @@ export interface WeaverseThemeData {
12
12
  /** Storefront-safe environment values, when available. */
13
13
  publicEnv?: PublicEnv
14
14
  /** Theme schema exposed to Studio, when available. */
15
- schema?: HydrogenThemeSchema
15
+ schema?: WeaverseThemeSchema
16
16
  /** Published theme setting values. */
17
- theme: HydrogenThemeSettings
17
+ theme: WeaverseThemeSettings
18
18
  }
19
19
 
20
20
  /** Mutable, subscribable store for theme settings received from the root loader. */
21
21
  export class ThemeSettingsStore {
22
22
  /** Current merged theme setting values. */
23
- settings: HydrogenThemeSettings = {}
23
+ settings: WeaverseThemeSettings = {}
24
24
  /** Theme schema exposed to Studio, when available. */
25
- schema?: HydrogenThemeSchema
25
+ schema?: WeaverseThemeSchema
26
26
  /** Storefront-safe environment values, when available. */
27
27
  publicEnv?: PublicEnv
28
28
  private listeners: Set<() => void> = new Set()
@@ -41,7 +41,7 @@ export class ThemeSettingsStore {
41
41
  }
42
42
 
43
43
  /** Merges setting changes into the current snapshot and notifies subscribers. */
44
- updateThemeSettings = (newSettings: HydrogenThemeSettings) => {
44
+ updateThemeSettings = (newSettings: WeaverseThemeSettings) => {
45
45
  if (this.isDestroyed) {
46
46
  console.warn('ThemeSettingsStore: Cannot update destroyed store')
47
47
  return