@weaverse/hydrogen 5.12.0 → 5.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -12,6 +12,27 @@ import { ReactNode, ComponentType, JSX, ForwardRefExoticComponent } from 'react'
12
12
  import { NavigateFunction, UIMatch } from 'react-router';
13
13
  import * as react_jsx_runtime from 'react/jsx-runtime';
14
14
 
15
+ /**
16
+ * Minimal mutable store for design-mode static text overrides.
17
+ *
18
+ * useSyncExternalStore-compatible. Passed into ThemeTextProvider which
19
+ * subscribes internally and merges overrides into merchantOverrides.
20
+ * The studio bridge calls updateOverrides() via weaverse.internal.themeTextStore.
21
+ *
22
+ * Shape: flat Record<string, string> — dot-notation keys map to values
23
+ * (e.g. "cart.title" → "Shopping Cart").
24
+ */
25
+ declare class ThemeTextStore {
26
+ overrides: Record<string, string>;
27
+ private listeners;
28
+ setOverrides: (overrides: Record<string, string>) => void;
29
+ updateOverrides: (newOverrides: Record<string, string>) => void;
30
+ getSnapshot: () => Record<string, string>;
31
+ getServerSnapshot: () => Record<string, string>;
32
+ subscribe: (callback: () => void) => () => void;
33
+ private emit;
34
+ }
35
+
15
36
  type WeaverseThemeData = {
16
37
  theme: HydrogenThemeSettings;
17
38
  schema?: HydrogenThemeSchema;
@@ -59,7 +80,7 @@ type ThemeTextValue = {
59
80
  *
60
81
  * Priority chain (highest wins):
61
82
  * 1. External `t` (passed into `withWeaverse` / `ThemeTextProvider`)
62
- * 2. `merchantOverrides` (DB overrides for the current locale)
83
+ * 2. `merchantOverrides` (DB overrides for the current locale + design overrides)
63
84
  * 3. `staticContent` (theme default JSON)
64
85
  * 4. The key itself (fallback)
65
86
  *
@@ -68,6 +89,10 @@ type ThemeTextValue = {
68
89
  * t('badge.sale', { percentage: 15 }) // => "-15% Off"
69
90
  */
70
91
  t: TranslateFunction;
92
+ /** Exposed for useStudio to attach to weaverse.internal. Null in production. */
93
+ themeTextStore: ThemeTextStore | null;
94
+ /** Active-locale translated keys loaded from the storefront API. */
95
+ merchantOverrides: Record<string, unknown> | null;
71
96
  };
72
97
  type ThemeTextProviderProps = {
73
98
  staticContent: Record<string, unknown>;
@@ -79,6 +104,8 @@ type ThemeTextProviderProps = {
79
104
  * that value is used; otherwise the internal resolution chain continues.
80
105
  */
81
106
  t?: TranslateFunction;
107
+ /** Optional store for live design-mode text overrides from the builder. */
108
+ themeTextStore?: ThemeTextStore | null;
82
109
  children: ReactNode;
83
110
  };
84
111
  /**
@@ -86,8 +113,9 @@ type ThemeTextProviderProps = {
86
113
  *
87
114
  * - `staticContent` – the theme's default locale JSON (from themeSchema.i18n)
88
115
  * - `merchantOverrides` – locale-specific overrides fetched from the API
116
+ * - `themeTextStore` – optional store for live design-mode text overrides
89
117
  */
90
- declare function ThemeTextProvider({ staticContent, merchantOverrides, t: externalT, children, }: ThemeTextProviderProps): react_jsx_runtime.JSX.Element;
118
+ declare function ThemeTextProvider({ staticContent, merchantOverrides, t: externalT, themeTextStore, children, }: ThemeTextProviderProps): react_jsx_runtime.JSX.Element;
91
119
  /**
92
120
  * Hook to access the theme text `t()` function.
93
121
  *
@@ -489,6 +517,8 @@ type WeaverseInternal = {
489
517
  navigate: NavigateFunction;
490
518
  revalidate: () => void;
491
519
  themeSettingsStore: ThemeSettingsStore;
520
+ themeTextStore?: ThemeTextStore | null;
521
+ merchantOverrides?: Record<string, unknown> | null;
492
522
  };
493
523
  /**
494
524
  * Optimized: Use direct type alias to maintain consistency
@@ -1097,4 +1127,4 @@ declare const IMAGES_PLACEHOLDERS: {
1097
1127
  product_18: string;
1098
1128
  };
1099
1129
 
1100
- export { type CacheResponseValidator, type ComponentDataValue, type ComponentLoaderArgs, type CreateHydrogenSchemaOptions, type DirectFetchResponse, type FetchProjectPayload, type FetchProjectRequestBody, type HydrogenComponent, type HydrogenComponentData, type HydrogenComponentPresets, type HydrogenComponentProps, type HydrogenComponentSchema, type HydrogenElement, type HydrogenPageAssignment, type HydrogenPageData, type HydrogenProjectType, type HydrogenSchemaValidationResult, type HydrogenThemeSchema, type HydrogenThemeSettings, IMAGES_PLACEHOLDERS, type LoadPageParams, type ProjectIdValidationResult, type ProjectIdValue, type PublicEnv, type RouteLoaderArgs, type ThemeSettingsResponse, ThemeTextProvider, type ThemeTextProviderProps, type ThemeTextValue, type TranslateFunction, type TranslationChanges, type TranslationEntry, type TranslationItemEntry, type TranslationMap, type TranslationMapEntry, type WeaverseArticle, type WeaverseBlog, WeaverseClient, type WeaverseClientArgs, type WeaverseCollection, type WeaverseDataContext, WeaverseError, WeaverseHydrogen, WeaverseHydrogenItem, type WeaverseHydrogenParams, WeaverseHydrogenRoot, type WeaverseI18n, type WeaverseInternal, type WeaverseLoaderData, type WeaverseLoaderRequestInfo, type WeaverseMetaObject, type WeaverseProduct, type WeaverseProjectConfigs, type WeaverseStudioQueries, type WithCacheFetchResponse, type WithWeaverseOptions, createWeaverseDataContext, defaultComponents, generateDataFromSchema, getNestedKey, getPreviewData, getRequestQueries, getSelectedProductOptions, getWeaverseConfigs, hasError, hasWeaverseStudio, interpolate, isFetchProjectPayload, isProjectIdFunction, isThemeSettingsResponse, isValidHydrogenSchema, isWithCacheFetchResponse, registerComponent, useThemeSettings, useThemeText, useWeaverseDataContext, withWeaverse };
1130
+ export { type CacheResponseValidator, type ComponentDataValue, type ComponentLoaderArgs, type CreateHydrogenSchemaOptions, type DirectFetchResponse, type FetchProjectPayload, type FetchProjectRequestBody, type HydrogenComponent, type HydrogenComponentData, type HydrogenComponentPresets, type HydrogenComponentProps, type HydrogenComponentSchema, type HydrogenElement, type HydrogenPageAssignment, type HydrogenPageData, type HydrogenProjectType, type HydrogenSchemaValidationResult, type HydrogenThemeSchema, type HydrogenThemeSettings, IMAGES_PLACEHOLDERS, type LoadPageParams, type ProjectIdValidationResult, type ProjectIdValue, type PublicEnv, type RouteLoaderArgs, type ThemeSettingsResponse, ThemeTextProvider, type ThemeTextProviderProps, ThemeTextStore, type ThemeTextValue, type TranslateFunction, type TranslationChanges, type TranslationEntry, type TranslationItemEntry, type TranslationMap, type TranslationMapEntry, type WeaverseArticle, type WeaverseBlog, WeaverseClient, type WeaverseClientArgs, type WeaverseCollection, type WeaverseDataContext, WeaverseError, WeaverseHydrogen, WeaverseHydrogenItem, type WeaverseHydrogenParams, WeaverseHydrogenRoot, type WeaverseI18n, type WeaverseInternal, type WeaverseLoaderData, type WeaverseLoaderRequestInfo, type WeaverseMetaObject, type WeaverseProduct, type WeaverseProjectConfigs, type WeaverseStudioQueries, type WithCacheFetchResponse, type WithWeaverseOptions, createWeaverseDataContext, defaultComponents, generateDataFromSchema, getNestedKey, getPreviewData, getRequestQueries, getSelectedProductOptions, getWeaverseConfigs, hasError, hasWeaverseStudio, interpolate, isFetchProjectPayload, isProjectIdFunction, isThemeSettingsResponse, isValidHydrogenSchema, isWithCacheFetchResponse, registerComponent, useThemeSettings, useThemeText, useWeaverseDataContext, withWeaverse };
package/dist/index.d.ts CHANGED
@@ -12,6 +12,27 @@ import { ReactNode, ComponentType, JSX, ForwardRefExoticComponent } from 'react'
12
12
  import { NavigateFunction, UIMatch } from 'react-router';
13
13
  import * as react_jsx_runtime from 'react/jsx-runtime';
14
14
 
15
+ /**
16
+ * Minimal mutable store for design-mode static text overrides.
17
+ *
18
+ * useSyncExternalStore-compatible. Passed into ThemeTextProvider which
19
+ * subscribes internally and merges overrides into merchantOverrides.
20
+ * The studio bridge calls updateOverrides() via weaverse.internal.themeTextStore.
21
+ *
22
+ * Shape: flat Record<string, string> — dot-notation keys map to values
23
+ * (e.g. "cart.title" → "Shopping Cart").
24
+ */
25
+ declare class ThemeTextStore {
26
+ overrides: Record<string, string>;
27
+ private listeners;
28
+ setOverrides: (overrides: Record<string, string>) => void;
29
+ updateOverrides: (newOverrides: Record<string, string>) => void;
30
+ getSnapshot: () => Record<string, string>;
31
+ getServerSnapshot: () => Record<string, string>;
32
+ subscribe: (callback: () => void) => () => void;
33
+ private emit;
34
+ }
35
+
15
36
  type WeaverseThemeData = {
16
37
  theme: HydrogenThemeSettings;
17
38
  schema?: HydrogenThemeSchema;
@@ -59,7 +80,7 @@ type ThemeTextValue = {
59
80
  *
60
81
  * Priority chain (highest wins):
61
82
  * 1. External `t` (passed into `withWeaverse` / `ThemeTextProvider`)
62
- * 2. `merchantOverrides` (DB overrides for the current locale)
83
+ * 2. `merchantOverrides` (DB overrides for the current locale + design overrides)
63
84
  * 3. `staticContent` (theme default JSON)
64
85
  * 4. The key itself (fallback)
65
86
  *
@@ -68,6 +89,10 @@ type ThemeTextValue = {
68
89
  * t('badge.sale', { percentage: 15 }) // => "-15% Off"
69
90
  */
70
91
  t: TranslateFunction;
92
+ /** Exposed for useStudio to attach to weaverse.internal. Null in production. */
93
+ themeTextStore: ThemeTextStore | null;
94
+ /** Active-locale translated keys loaded from the storefront API. */
95
+ merchantOverrides: Record<string, unknown> | null;
71
96
  };
72
97
  type ThemeTextProviderProps = {
73
98
  staticContent: Record<string, unknown>;
@@ -79,6 +104,8 @@ type ThemeTextProviderProps = {
79
104
  * that value is used; otherwise the internal resolution chain continues.
80
105
  */
81
106
  t?: TranslateFunction;
107
+ /** Optional store for live design-mode text overrides from the builder. */
108
+ themeTextStore?: ThemeTextStore | null;
82
109
  children: ReactNode;
83
110
  };
84
111
  /**
@@ -86,8 +113,9 @@ type ThemeTextProviderProps = {
86
113
  *
87
114
  * - `staticContent` – the theme's default locale JSON (from themeSchema.i18n)
88
115
  * - `merchantOverrides` – locale-specific overrides fetched from the API
116
+ * - `themeTextStore` – optional store for live design-mode text overrides
89
117
  */
90
- declare function ThemeTextProvider({ staticContent, merchantOverrides, t: externalT, children, }: ThemeTextProviderProps): react_jsx_runtime.JSX.Element;
118
+ declare function ThemeTextProvider({ staticContent, merchantOverrides, t: externalT, themeTextStore, children, }: ThemeTextProviderProps): react_jsx_runtime.JSX.Element;
91
119
  /**
92
120
  * Hook to access the theme text `t()` function.
93
121
  *
@@ -489,6 +517,8 @@ type WeaverseInternal = {
489
517
  navigate: NavigateFunction;
490
518
  revalidate: () => void;
491
519
  themeSettingsStore: ThemeSettingsStore;
520
+ themeTextStore?: ThemeTextStore | null;
521
+ merchantOverrides?: Record<string, unknown> | null;
492
522
  };
493
523
  /**
494
524
  * Optimized: Use direct type alias to maintain consistency
@@ -1097,4 +1127,4 @@ declare const IMAGES_PLACEHOLDERS: {
1097
1127
  product_18: string;
1098
1128
  };
1099
1129
 
1100
- export { type CacheResponseValidator, type ComponentDataValue, type ComponentLoaderArgs, type CreateHydrogenSchemaOptions, type DirectFetchResponse, type FetchProjectPayload, type FetchProjectRequestBody, type HydrogenComponent, type HydrogenComponentData, type HydrogenComponentPresets, type HydrogenComponentProps, type HydrogenComponentSchema, type HydrogenElement, type HydrogenPageAssignment, type HydrogenPageData, type HydrogenProjectType, type HydrogenSchemaValidationResult, type HydrogenThemeSchema, type HydrogenThemeSettings, IMAGES_PLACEHOLDERS, type LoadPageParams, type ProjectIdValidationResult, type ProjectIdValue, type PublicEnv, type RouteLoaderArgs, type ThemeSettingsResponse, ThemeTextProvider, type ThemeTextProviderProps, type ThemeTextValue, type TranslateFunction, type TranslationChanges, type TranslationEntry, type TranslationItemEntry, type TranslationMap, type TranslationMapEntry, type WeaverseArticle, type WeaverseBlog, WeaverseClient, type WeaverseClientArgs, type WeaverseCollection, type WeaverseDataContext, WeaverseError, WeaverseHydrogen, WeaverseHydrogenItem, type WeaverseHydrogenParams, WeaverseHydrogenRoot, type WeaverseI18n, type WeaverseInternal, type WeaverseLoaderData, type WeaverseLoaderRequestInfo, type WeaverseMetaObject, type WeaverseProduct, type WeaverseProjectConfigs, type WeaverseStudioQueries, type WithCacheFetchResponse, type WithWeaverseOptions, createWeaverseDataContext, defaultComponents, generateDataFromSchema, getNestedKey, getPreviewData, getRequestQueries, getSelectedProductOptions, getWeaverseConfigs, hasError, hasWeaverseStudio, interpolate, isFetchProjectPayload, isProjectIdFunction, isThemeSettingsResponse, isValidHydrogenSchema, isWithCacheFetchResponse, registerComponent, useThemeSettings, useThemeText, useWeaverseDataContext, withWeaverse };
1130
+ export { type CacheResponseValidator, type ComponentDataValue, type ComponentLoaderArgs, type CreateHydrogenSchemaOptions, type DirectFetchResponse, type FetchProjectPayload, type FetchProjectRequestBody, type HydrogenComponent, type HydrogenComponentData, type HydrogenComponentPresets, type HydrogenComponentProps, type HydrogenComponentSchema, type HydrogenElement, type HydrogenPageAssignment, type HydrogenPageData, type HydrogenProjectType, type HydrogenSchemaValidationResult, type HydrogenThemeSchema, type HydrogenThemeSettings, IMAGES_PLACEHOLDERS, type LoadPageParams, type ProjectIdValidationResult, type ProjectIdValue, type PublicEnv, type RouteLoaderArgs, type ThemeSettingsResponse, ThemeTextProvider, type ThemeTextProviderProps, ThemeTextStore, type ThemeTextValue, type TranslateFunction, type TranslationChanges, type TranslationEntry, type TranslationItemEntry, type TranslationMap, type TranslationMapEntry, type WeaverseArticle, type WeaverseBlog, WeaverseClient, type WeaverseClientArgs, type WeaverseCollection, type WeaverseDataContext, WeaverseError, WeaverseHydrogen, WeaverseHydrogenItem, type WeaverseHydrogenParams, WeaverseHydrogenRoot, type WeaverseI18n, type WeaverseInternal, type WeaverseLoaderData, type WeaverseLoaderRequestInfo, type WeaverseMetaObject, type WeaverseProduct, type WeaverseProjectConfigs, type WeaverseStudioQueries, type WithCacheFetchResponse, type WithWeaverseOptions, createWeaverseDataContext, defaultComponents, generateDataFromSchema, getNestedKey, getPreviewData, getRequestQueries, getSelectedProductOptions, getWeaverseConfigs, hasError, hasWeaverseStudio, interpolate, isFetchProjectPayload, isProjectIdFunction, isThemeSettingsResponse, isValidHydrogenSchema, isWithCacheFetchResponse, registerComponent, useThemeSettings, useThemeText, useWeaverseDataContext, withWeaverse };
package/dist/index.js CHANGED
@@ -58,12 +58,39 @@ function interpolate(template, variables) {
58
58
  }
59
59
  var ThemeTextContext = react$1.createContext(null);
60
60
  ThemeTextContext.displayName = "WeaverseThemeTextContext";
61
+ function unflattenKeys(flat) {
62
+ const result = {};
63
+ for (const [dotPath, value] of Object.entries(flat)) {
64
+ const keys = dotPath.split(".");
65
+ let current = result;
66
+ for (let i = 0; i < keys.length - 1; i++) {
67
+ const k = keys[i];
68
+ if (!(k in current) || typeof current[k] !== "object") {
69
+ current[k] = {};
70
+ }
71
+ current = current[k];
72
+ }
73
+ current[keys[keys.length - 1]] = value;
74
+ }
75
+ return result;
76
+ }
77
+ var EMPTY = {};
78
+ var NOOP_SUBSCRIBE = () => () => {
79
+ };
80
+ var NOOP_SNAPSHOT = () => EMPTY;
61
81
  function ThemeTextProvider({
62
82
  staticContent,
63
83
  merchantOverrides,
64
84
  t: externalT,
85
+ themeTextStore,
65
86
  children
66
87
  }) {
88
+ const designOverrides = react.useSafeExternalStore(
89
+ themeTextStore?.subscribe ?? NOOP_SUBSCRIBE,
90
+ themeTextStore?.getSnapshot ?? NOOP_SNAPSHOT,
91
+ themeTextStore?.getServerSnapshot ?? NOOP_SNAPSHOT
92
+ );
93
+ const mergedOverrides = designOverrides !== EMPTY && Object.keys(designOverrides).length > 0 ? { ...merchantOverrides, ...unflattenKeys(designOverrides) } : merchantOverrides;
67
94
  const value = react$1.useMemo(() => {
68
95
  const t = (key, variables) => {
69
96
  if (externalT) {
@@ -72,13 +99,23 @@ function ThemeTextProvider({
72
99
  return external;
73
100
  }
74
101
  }
75
- const override = merchantOverrides ? getNestedKey(merchantOverrides, key) : void 0;
102
+ const override = mergedOverrides ? getNestedKey(mergedOverrides, key) : void 0;
76
103
  const staticValue = getNestedKey(staticContent, key);
77
104
  const raw = override ?? staticValue ?? key;
78
105
  return interpolate(raw, variables);
79
106
  };
80
- return { t };
81
- }, [staticContent, merchantOverrides, externalT]);
107
+ return {
108
+ t,
109
+ themeTextStore: themeTextStore ?? null,
110
+ merchantOverrides: merchantOverrides ?? null
111
+ };
112
+ }, [
113
+ staticContent,
114
+ merchantOverrides,
115
+ mergedOverrides,
116
+ externalT,
117
+ themeTextStore
118
+ ]);
82
119
  return /* @__PURE__ */ jsxRuntime.jsx(ThemeTextContext.Provider, { value, children });
83
120
  }
84
121
  function useThemeText() {
@@ -349,6 +386,37 @@ function getPreviewData(type, components, weaverseHost) {
349
386
  }
350
387
  };
351
388
  }
389
+
390
+ // src/utils/theme-text-store.ts
391
+ var ThemeTextStore = class {
392
+ overrides = {};
393
+ listeners = /* @__PURE__ */ new Set();
394
+ setOverrides = (overrides) => {
395
+ this.overrides = { ...overrides };
396
+ this.emit();
397
+ };
398
+ updateOverrides = (newOverrides) => {
399
+ this.overrides = { ...this.overrides, ...newOverrides };
400
+ this.emit();
401
+ };
402
+ getSnapshot = () => this.overrides;
403
+ getServerSnapshot = () => this.overrides;
404
+ subscribe = (callback) => {
405
+ this.listeners.add(callback);
406
+ return () => {
407
+ this.listeners.delete(callback);
408
+ };
409
+ };
410
+ emit = () => {
411
+ for (const listener of Array.from(this.listeners)) {
412
+ try {
413
+ listener();
414
+ } catch (error) {
415
+ console.error("ThemeTextStore: Listener error", error);
416
+ }
417
+ }
418
+ };
419
+ };
352
420
  var ThemeSettingsStore = class {
353
421
  settings = {};
354
422
  schema;
@@ -459,6 +527,7 @@ function useStudio(weaverse) {
459
527
  let { pathname, search } = reactRouter.useLocation();
460
528
  let navigate = reactRouter.useNavigate();
461
529
  let themeSettingsStore = useThemeSettingsStore();
530
+ let { themeTextStore, merchantOverrides } = useThemeText();
462
531
  let {
463
532
  isDesignMode,
464
533
  weaverseHost,
@@ -476,7 +545,9 @@ function useStudio(weaverse) {
476
545
  ...weaverse.internal,
477
546
  navigate,
478
547
  revalidate,
479
- themeSettingsStore
548
+ merchantOverrides,
549
+ themeSettingsStore,
550
+ themeTextStore
480
551
  };
481
552
  let studioSrc = `${weaverseHost}/static/studio/hydrogen/index.js?v=${weaverseVersion}`;
482
553
  react.loadScript(studioSrc).then(() => {
@@ -761,12 +832,17 @@ function withWeaverse(Component, options) {
761
832
  return (props) => {
762
833
  const themeSettingsStore = useCreateThemeSettingsStore();
763
834
  const themeTextData = useThemeTextData();
835
+ const themeTextStoreRef = react$1.useRef(null);
836
+ if (!themeTextStoreRef.current) {
837
+ themeTextStoreRef.current = new ThemeTextStore();
838
+ }
764
839
  return /* @__PURE__ */ jsxRuntime.jsx(ThemeSettingsStoreContext.Provider, { value: themeSettingsStore, children: /* @__PURE__ */ jsxRuntime.jsx(
765
840
  ThemeTextProvider,
766
841
  {
767
842
  merchantOverrides: themeTextData.merchantOverrides,
768
843
  staticContent: themeTextData.staticContent,
769
844
  t: options?.t,
845
+ themeTextStore: themeTextStoreRef.current,
770
846
  children: /* @__PURE__ */ jsxRuntime.jsx(Component, { ...props })
771
847
  }
772
848
  ) });
@@ -1584,6 +1660,7 @@ Object.defineProperty(exports, "useWeaverse", {
1584
1660
  });
1585
1661
  exports.IMAGES_PLACEHOLDERS = IMAGES_PLACEHOLDERS;
1586
1662
  exports.ThemeTextProvider = ThemeTextProvider;
1663
+ exports.ThemeTextStore = ThemeTextStore;
1587
1664
  exports.WeaverseClient = WeaverseClient;
1588
1665
  exports.WeaverseError = WeaverseError;
1589
1666
  exports.WeaverseHydrogen = WeaverseHydrogen;