@numueg/theme-sdk 0.2.3 → 0.3.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
@@ -1,9 +1,9 @@
1
- import { S as Store, e as Product, b as Collection, C as Cart, c as Customer, P as Page, g as ProductVariant } from './entities-C8B2U-V0.mjs';
2
- export { A as Address, a as CartItem, O as Order, d as OrderItem, f as ProductImage, h as ProductOption } from './entities-C8B2U-V0.mjs';
1
+ import { i as Store, e as Product, b as Collection, C as Cart, c as Customer, P as Page, S as SizeChart, g as ProductVariant } from './entities-6MGANln7.mjs';
2
+ export { A as Address, a as CartItem, O as Order, d as OrderItem, f as ProductImage, j as ProductOption, h as SizeChartMode } from './entities-6MGANln7.mjs';
3
3
  import { T as ThemeSettingsV3, c as SectionInstance, M as MountResult, B as BlockInstance, b as BlockSchema, a as BlockProps$1, f as SectionSchema, e as SectionProps$1 } from './theme-D0QybTQS.mjs';
4
4
  export { E as ExternalThemeMetadata, h as MAX_BLOCK_DEPTH, P as PageTemplate, i as PresetBlock, S as SectionGroup, d as SectionPreset, g as SettingDefinition } from './theme-D0QybTQS.mjs';
5
5
  import * as react from 'react';
6
- import { ReactNode, ElementType, CSSProperties, ImgHTMLAttributes, AnchorHTMLAttributes, ButtonHTMLAttributes, HTMLAttributes, FormHTMLAttributes, ComponentType } from 'react';
6
+ import { ReactNode, ReactElement, ElementType, CSSProperties, ImgHTMLAttributes, AnchorHTMLAttributes, ButtonHTMLAttributes, HTMLAttributes, FormHTMLAttributes, ComponentType } from 'react';
7
7
  export { resolveThemeSettings } from './normalize.mjs';
8
8
 
9
9
  /**
@@ -744,6 +744,33 @@ declare function useRelatedProducts(productId: string | null | undefined, option
744
744
  limit?: number;
745
745
  }): RelatedProductsState;
746
746
 
747
+ /**
748
+ * useProductSizeChart — resolve the size chart to show for a product.
749
+ *
750
+ * The merchant hub writes the per-product chart to
751
+ * `product.attributes.size_chart` and the store-wide default to
752
+ * `store.settings.size_chart`, with an explicit `mode`:
753
+ *
754
+ * "off" → never show, even if a store default exists
755
+ * "custom" → use the product's own chart
756
+ * "default" → fall back to the store-wide chart
757
+ * (legacy) → no `mode`: a populated product chart wins, else the default
758
+ *
759
+ * This hook centralises that precedence so every theme resolves it identically
760
+ * (the backend `SizeChartSchema` validator and the hub editor share the same
761
+ * shape). Returns `null` when there is nothing to show — render the size-guide
762
+ * trigger only when this is non-null.
763
+ *
764
+ * @param productOverride - resolve against this product instead of the one in
765
+ * context (e.g. when rendering a chart for a related/quick-view product).
766
+ */
767
+ declare function useProductSizeChart(productOverride?: Product | null): SizeChart | null;
768
+ /**
769
+ * Pure resolver (no React) — exported so non-hook code (SSR helpers, tests)
770
+ * can apply the same precedence.
771
+ */
772
+ declare function resolveSizeChart(productAttributes: Record<string, unknown> | undefined, storeSettings: Record<string, unknown> | undefined): SizeChart | null;
773
+
747
774
  /**
748
775
  * Multi-currency presentment — Phase 6.
749
776
  *
@@ -1155,6 +1182,14 @@ interface ThemeMountContext {
1155
1182
  demo?: boolean;
1156
1183
  /** Store navigation menus keyed by handle, resolved server-side. */
1157
1184
  navigation?: Record<string, MenuItemData[]>;
1185
+ /**
1186
+ * Host signal that the container already holds server-rendered HTML for
1187
+ * this exact ctx (produced via `createApp` from `defineThemeEntry`).
1188
+ * `mountTheme` then adopts it with `hydrateRoot` instead of re-rendering
1189
+ * from scratch. Ignored when the container is empty, so a host can pass
1190
+ * it optimistically and still get a plain client mount on SSR failure.
1191
+ */
1192
+ hydrate?: boolean;
1158
1193
  [extra: string]: unknown;
1159
1194
  }
1160
1195
  /** Arguments handed to a theme's render callback on every (re)render. */
@@ -1170,17 +1205,81 @@ interface ThemeRenderArgs {
1170
1205
  /** Live theme settings (reflects customizer drafts via applyDraft). */
1171
1206
  themeSettings: ThemeSettingsV3;
1172
1207
  }
1208
+ interface DraftHandle {
1209
+ applyDraft: (next: ThemeSettingsV3) => void;
1210
+ }
1211
+ /**
1212
+ * Build the canonical theme element tree for a ctx. BOTH render paths go
1213
+ * through here — `mountTheme` (client mount/hydrate) and `createApp`
1214
+ * (host-side `renderToString`) — so the server markup and the hydration
1215
+ * tree are the same React tree by construction. `mountEl` is a prop, not
1216
+ * DOM output, so it differing between server (null) and client (the
1217
+ * container) cannot cause a hydration mismatch.
1218
+ */
1219
+ declare function buildThemeElement(ctx: ThemeMountContext, mountEl: HTMLElement | null, renderApp: (args: ThemeRenderArgs) => ReactNode, ref?: (h: DraftHandle | null) => void): ReactElement;
1173
1220
  /**
1174
1221
  * Mount a V3 theme. Owns the React root, the provider stack (catalog + nav +
1175
1222
  * style tokens), and the live-preview draft cycle. Returns the host-contract
1176
1223
  * `MountResult` (`cleanup` + `applyDraft`).
1177
1224
  *
1225
+ * When the host passes `ctx.hydrate === true` and the container already
1226
+ * holds server-rendered HTML (produced by this theme's `createApp` with the
1227
+ * identical ctx), the tree is adopted via `hydrateRoot` — no re-render, no
1228
+ * flash. An empty container downgrades to a plain client mount so hosts can
1229
+ * pass the flag optimistically.
1230
+ *
1178
1231
  * @param el the host-supplied container element
1179
1232
  * @param ctx the mount context (either host or legacy/dev shape)
1180
1233
  * @param renderApp returns the theme's section tree for the current args
1181
1234
  */
1182
1235
  declare function mountTheme(el: HTMLElement, ctx: ThemeMountContext, renderApp: (args: ThemeRenderArgs) => ReactNode): MountResult;
1183
1236
 
1237
+ /**
1238
+ * `defineThemeEntry(renderApp)` — one-call theme entry that yields BOTH
1239
+ * halves of the V3 contract from a single component:
1240
+ *
1241
+ * - `mount(el, ctx)` — the client entry every host already calls
1242
+ * (now hydration-aware via `ctx.hydrate`).
1243
+ * - `createApp(ctx)` — the same React tree as a plain element, so the
1244
+ * host can `renderToString(createApp(ctx))` on the
1245
+ * server and ship real HTML before any JS runs.
1246
+ *
1247
+ * ```tsx
1248
+ * // src/main.tsx
1249
+ * import { defineThemeEntry } from "@numueg/theme-sdk";
1250
+ *
1251
+ * const entry = defineThemeEntry(({ currentTemplate }) => (
1252
+ * <ThemeApp currentTemplate={currentTemplate} />
1253
+ * ));
1254
+ *
1255
+ * export const mount = entry.mount;
1256
+ * export const createApp = entry.createApp;
1257
+ * ```
1258
+ *
1259
+ * Why both MUST come from one definition: hydration only succeeds when the
1260
+ * server markup and the client tree are identical. Routing both through
1261
+ * `buildThemeElement` makes that true by construction — a theme cannot
1262
+ * accidentally ship a `createApp` that disagrees with its `mount`.
1263
+ *
1264
+ * Themes that only export `mount` keep working exactly as before; they are
1265
+ * simply never server-rendered (the host detects the missing `createApp`
1266
+ * and falls back to today's client-only mount).
1267
+ */
1268
+
1269
+ /** The pair of entry points a V3 theme bundle exports. */
1270
+ interface ThemeEntry {
1271
+ /** Client entry — host contract `mount(el, ctx): MountResult`. */
1272
+ mount: (el: HTMLElement, ctx: ThemeMountContext) => MountResult;
1273
+ /**
1274
+ * Server entry — returns the exact element tree `mount` would render,
1275
+ * for host-side `renderToString`. Must stay side-effect free: no DOM
1276
+ * access happens until React effects run (which they don't on the
1277
+ * server).
1278
+ */
1279
+ createApp: (ctx: ThemeMountContext) => ReactElement;
1280
+ }
1281
+ declare function defineThemeEntry(renderApp: (args: ThemeRenderArgs) => ReactNode): ThemeEntry;
1282
+
1184
1283
  interface NuMuProviderProps {
1185
1284
  store: Store;
1186
1285
  themeSettings: ThemeSettingsV3;
@@ -2126,11 +2225,32 @@ type GlobalSettings = Record<string, unknown> | null | undefined;
2126
2225
  * family/stack the theme author supplied.
2127
2226
  */
2128
2227
  declare function resolveFontStack(value: string): string;
2228
+ /** Result of `computeGlobalStyleTokens` — everything a host needs to paint
2229
+ * global settings without a DOM. */
2230
+ interface ComputedStyleTokens {
2231
+ /** CSS custom properties to set on the theme's mount root. */
2232
+ cssVars: Record<string, string>;
2233
+ /** Google-Fonts stylesheet hrefs for any registry fonts in use. */
2234
+ fontHrefs: string[];
2235
+ }
2236
+ /**
2237
+ * Pure half of `applyGlobalStyleTokens`: compute the exact CSS custom
2238
+ * properties (and webfont hrefs) a settings object maps to, without touching
2239
+ * any DOM. This is what lets a host SERVER-render a theme with the same vars
2240
+ * the bundle applies on mount — both sides call this one function, so the
2241
+ * values cannot drift (drift = unstyled flash or hydration noise).
2242
+ *
2243
+ * Includes the explicit `heading_font` / `body_font` resolution that
2244
+ * `mountTheme` historically layered on top: any string value for those two
2245
+ * ids resolves through the registry (or passes verbatim) so a picked font
2246
+ * gets a real stack even when it isn't a known token.
2247
+ */
2248
+ declare function computeGlobalStyleTokens(globalSettings: GlobalSettings): ComputedStyleTokens;
2129
2249
  /**
2130
2250
  * Map a store's global settings onto CSS custom properties on `el`. Call on
2131
2251
  * mount and on every `applyDraft` (live preview). No-op when `el` or the
2132
2252
  * settings are missing. Reserved `__`-prefixed keys (e.g. `__translations`)
2133
- * are skipped.
2253
+ * are skipped. Thin DOM shell over `computeGlobalStyleTokens`.
2134
2254
  */
2135
2255
  declare function applyGlobalStyleTokens(globalSettings: GlobalSettings, el: HTMLElement | null | undefined): void;
2136
2256
 
@@ -2192,4 +2312,4 @@ declare function pickTranslations(bundle: LocaleBundle, locale: string): LocaleM
2192
2312
  */
2193
2313
  declare function buildLocaleBundle<T extends Record<string, unknown>>(modules: T): LocaleBundle;
2194
2314
 
2195
- export { AddToCartButton, type AddressInput, type AnalyticsApi, type AnalyticsPayload, type AppManifestBlock, type AppPayload, type AppState, Block, BlockInstance, BlockProps$1 as BlockProps, BlockSchema, Cart, CartContext, type CheckoutAddress, type CheckoutApi, type CheckoutSessionState, type CheckoutStep, Collection, CollectionCard, type CollectionCardProps, type CollectionCardSlots, CollectionContext, CollectionProvider, type CurrencyConfig, type CurrencyState, CurrencySwitcher, type CurrencySwitcherProps, Customer, type CustomerAddress, type CustomerAddressesState, CustomerContext, type DefineBlockInput, type DefineSectionInput, type DefinedBlock, type DefinedSection, type DynamicResolveContext, type DynamicSourceRef, EditableImage, type EditableImageProps, EditableText, type EditableTextProps, type FocalSrcOptions, Form, type GiftCardBalance, ICON_NAMES, Icon, IconMap, type IconProps, Image, type ImageTransform, Link, type LocaleBundle, type LocaleMessages, LocaleSwitcher, type LocaleSwitcherProps, LocalizationContext, type MenuItemData, Money, MountResult, NavigationContext, type NavigationItem, type NavigationState, NuMuProvider, type OrderDetail, type OrderListEntry, type OrderListState, type OrderState, Page, PageContext, type PlaceOrderResult, Product, ProductCard, type ProductCardProps, type ProductCardSlots, ProductContext, ProductProvider, ProductVariant, type RelatedProductsState, type ReorderResult, type ReorderSkipReason, type ReorderSkippedItem, RichText, type RichTextProps, type SearchResults, type SearchState, Section, SectionContext, SectionInstance, SectionProps$1 as SectionProps, SectionSchema, type ShippingRateOption, ShopContext, type ShopWithHelpers, Store, type ThemeMountContext, type ThemeMountPage, type ThemeRenderArgs, ThemeSettingsContext, ThemeSettingsV3, type UseGiftCardBalance, type UseReorder, type UseSearchOptions, type UseShippingRatesOptions, type UseShippingRatesState, type UseVariantSelection, type WishlistItem, type WishlistState, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, clearSdkSingleton, collectBlocks, collectSections, defaultVariant, defineBlock, defineSection, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSourcePath, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
2315
+ export { AddToCartButton, type AddressInput, type AnalyticsApi, type AnalyticsPayload, type AppManifestBlock, type AppPayload, type AppState, Block, BlockInstance, BlockProps$1 as BlockProps, BlockSchema, Cart, CartContext, type CheckoutAddress, type CheckoutApi, type CheckoutSessionState, type CheckoutStep, Collection, CollectionCard, type CollectionCardProps, type CollectionCardSlots, CollectionContext, CollectionProvider, type ComputedStyleTokens, type CurrencyConfig, type CurrencyState, CurrencySwitcher, type CurrencySwitcherProps, Customer, type CustomerAddress, type CustomerAddressesState, CustomerContext, type DefineBlockInput, type DefineSectionInput, type DefinedBlock, type DefinedSection, type DynamicResolveContext, type DynamicSourceRef, EditableImage, type EditableImageProps, EditableText, type EditableTextProps, type FocalSrcOptions, Form, type GiftCardBalance, ICON_NAMES, Icon, IconMap, type IconProps, Image, type ImageTransform, Link, type LocaleBundle, type LocaleMessages, LocaleSwitcher, type LocaleSwitcherProps, LocalizationContext, type MenuItemData, Money, MountResult, NavigationContext, type NavigationItem, type NavigationState, NuMuProvider, type OrderDetail, type OrderListEntry, type OrderListState, type OrderState, Page, PageContext, type PlaceOrderResult, Product, ProductCard, type ProductCardProps, type ProductCardSlots, ProductContext, ProductProvider, ProductVariant, type RelatedProductsState, type ReorderResult, type ReorderSkipReason, type ReorderSkippedItem, RichText, type RichTextProps, type SearchResults, type SearchState, Section, SectionContext, SectionInstance, SectionProps$1 as SectionProps, SectionSchema, type ShippingRateOption, ShopContext, type ShopWithHelpers, SizeChart, Store, type ThemeEntry, type ThemeMountContext, type ThemeMountPage, type ThemeRenderArgs, ThemeSettingsContext, ThemeSettingsV3, type UseGiftCardBalance, type UseReorder, type UseSearchOptions, type UseShippingRatesOptions, type UseShippingRatesState, type UseVariantSelection, type WishlistItem, type WishlistState, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, buildThemeElement, clearSdkSingleton, collectBlocks, collectSections, computeGlobalStyleTokens, defaultVariant, defineBlock, defineSection, defineThemeEntry, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSizeChart, resolveSourcePath, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProductSizeChart, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { S as Store, e as Product, b as Collection, C as Cart, c as Customer, P as Page, g as ProductVariant } from './entities-C8B2U-V0.js';
2
- export { A as Address, a as CartItem, O as Order, d as OrderItem, f as ProductImage, h as ProductOption } from './entities-C8B2U-V0.js';
1
+ import { i as Store, e as Product, b as Collection, C as Cart, c as Customer, P as Page, S as SizeChart, g as ProductVariant } from './entities-6MGANln7.js';
2
+ export { A as Address, a as CartItem, O as Order, d as OrderItem, f as ProductImage, j as ProductOption, h as SizeChartMode } from './entities-6MGANln7.js';
3
3
  import { T as ThemeSettingsV3, c as SectionInstance, M as MountResult, B as BlockInstance, b as BlockSchema, a as BlockProps$1, f as SectionSchema, e as SectionProps$1 } from './theme-D0QybTQS.js';
4
4
  export { E as ExternalThemeMetadata, h as MAX_BLOCK_DEPTH, P as PageTemplate, i as PresetBlock, S as SectionGroup, d as SectionPreset, g as SettingDefinition } from './theme-D0QybTQS.js';
5
5
  import * as react from 'react';
6
- import { ReactNode, ElementType, CSSProperties, ImgHTMLAttributes, AnchorHTMLAttributes, ButtonHTMLAttributes, HTMLAttributes, FormHTMLAttributes, ComponentType } from 'react';
6
+ import { ReactNode, ReactElement, ElementType, CSSProperties, ImgHTMLAttributes, AnchorHTMLAttributes, ButtonHTMLAttributes, HTMLAttributes, FormHTMLAttributes, ComponentType } from 'react';
7
7
  export { resolveThemeSettings } from './normalize.js';
8
8
 
9
9
  /**
@@ -744,6 +744,33 @@ declare function useRelatedProducts(productId: string | null | undefined, option
744
744
  limit?: number;
745
745
  }): RelatedProductsState;
746
746
 
747
+ /**
748
+ * useProductSizeChart — resolve the size chart to show for a product.
749
+ *
750
+ * The merchant hub writes the per-product chart to
751
+ * `product.attributes.size_chart` and the store-wide default to
752
+ * `store.settings.size_chart`, with an explicit `mode`:
753
+ *
754
+ * "off" → never show, even if a store default exists
755
+ * "custom" → use the product's own chart
756
+ * "default" → fall back to the store-wide chart
757
+ * (legacy) → no `mode`: a populated product chart wins, else the default
758
+ *
759
+ * This hook centralises that precedence so every theme resolves it identically
760
+ * (the backend `SizeChartSchema` validator and the hub editor share the same
761
+ * shape). Returns `null` when there is nothing to show — render the size-guide
762
+ * trigger only when this is non-null.
763
+ *
764
+ * @param productOverride - resolve against this product instead of the one in
765
+ * context (e.g. when rendering a chart for a related/quick-view product).
766
+ */
767
+ declare function useProductSizeChart(productOverride?: Product | null): SizeChart | null;
768
+ /**
769
+ * Pure resolver (no React) — exported so non-hook code (SSR helpers, tests)
770
+ * can apply the same precedence.
771
+ */
772
+ declare function resolveSizeChart(productAttributes: Record<string, unknown> | undefined, storeSettings: Record<string, unknown> | undefined): SizeChart | null;
773
+
747
774
  /**
748
775
  * Multi-currency presentment — Phase 6.
749
776
  *
@@ -1155,6 +1182,14 @@ interface ThemeMountContext {
1155
1182
  demo?: boolean;
1156
1183
  /** Store navigation menus keyed by handle, resolved server-side. */
1157
1184
  navigation?: Record<string, MenuItemData[]>;
1185
+ /**
1186
+ * Host signal that the container already holds server-rendered HTML for
1187
+ * this exact ctx (produced via `createApp` from `defineThemeEntry`).
1188
+ * `mountTheme` then adopts it with `hydrateRoot` instead of re-rendering
1189
+ * from scratch. Ignored when the container is empty, so a host can pass
1190
+ * it optimistically and still get a plain client mount on SSR failure.
1191
+ */
1192
+ hydrate?: boolean;
1158
1193
  [extra: string]: unknown;
1159
1194
  }
1160
1195
  /** Arguments handed to a theme's render callback on every (re)render. */
@@ -1170,17 +1205,81 @@ interface ThemeRenderArgs {
1170
1205
  /** Live theme settings (reflects customizer drafts via applyDraft). */
1171
1206
  themeSettings: ThemeSettingsV3;
1172
1207
  }
1208
+ interface DraftHandle {
1209
+ applyDraft: (next: ThemeSettingsV3) => void;
1210
+ }
1211
+ /**
1212
+ * Build the canonical theme element tree for a ctx. BOTH render paths go
1213
+ * through here — `mountTheme` (client mount/hydrate) and `createApp`
1214
+ * (host-side `renderToString`) — so the server markup and the hydration
1215
+ * tree are the same React tree by construction. `mountEl` is a prop, not
1216
+ * DOM output, so it differing between server (null) and client (the
1217
+ * container) cannot cause a hydration mismatch.
1218
+ */
1219
+ declare function buildThemeElement(ctx: ThemeMountContext, mountEl: HTMLElement | null, renderApp: (args: ThemeRenderArgs) => ReactNode, ref?: (h: DraftHandle | null) => void): ReactElement;
1173
1220
  /**
1174
1221
  * Mount a V3 theme. Owns the React root, the provider stack (catalog + nav +
1175
1222
  * style tokens), and the live-preview draft cycle. Returns the host-contract
1176
1223
  * `MountResult` (`cleanup` + `applyDraft`).
1177
1224
  *
1225
+ * When the host passes `ctx.hydrate === true` and the container already
1226
+ * holds server-rendered HTML (produced by this theme's `createApp` with the
1227
+ * identical ctx), the tree is adopted via `hydrateRoot` — no re-render, no
1228
+ * flash. An empty container downgrades to a plain client mount so hosts can
1229
+ * pass the flag optimistically.
1230
+ *
1178
1231
  * @param el the host-supplied container element
1179
1232
  * @param ctx the mount context (either host or legacy/dev shape)
1180
1233
  * @param renderApp returns the theme's section tree for the current args
1181
1234
  */
1182
1235
  declare function mountTheme(el: HTMLElement, ctx: ThemeMountContext, renderApp: (args: ThemeRenderArgs) => ReactNode): MountResult;
1183
1236
 
1237
+ /**
1238
+ * `defineThemeEntry(renderApp)` — one-call theme entry that yields BOTH
1239
+ * halves of the V3 contract from a single component:
1240
+ *
1241
+ * - `mount(el, ctx)` — the client entry every host already calls
1242
+ * (now hydration-aware via `ctx.hydrate`).
1243
+ * - `createApp(ctx)` — the same React tree as a plain element, so the
1244
+ * host can `renderToString(createApp(ctx))` on the
1245
+ * server and ship real HTML before any JS runs.
1246
+ *
1247
+ * ```tsx
1248
+ * // src/main.tsx
1249
+ * import { defineThemeEntry } from "@numueg/theme-sdk";
1250
+ *
1251
+ * const entry = defineThemeEntry(({ currentTemplate }) => (
1252
+ * <ThemeApp currentTemplate={currentTemplate} />
1253
+ * ));
1254
+ *
1255
+ * export const mount = entry.mount;
1256
+ * export const createApp = entry.createApp;
1257
+ * ```
1258
+ *
1259
+ * Why both MUST come from one definition: hydration only succeeds when the
1260
+ * server markup and the client tree are identical. Routing both through
1261
+ * `buildThemeElement` makes that true by construction — a theme cannot
1262
+ * accidentally ship a `createApp` that disagrees with its `mount`.
1263
+ *
1264
+ * Themes that only export `mount` keep working exactly as before; they are
1265
+ * simply never server-rendered (the host detects the missing `createApp`
1266
+ * and falls back to today's client-only mount).
1267
+ */
1268
+
1269
+ /** The pair of entry points a V3 theme bundle exports. */
1270
+ interface ThemeEntry {
1271
+ /** Client entry — host contract `mount(el, ctx): MountResult`. */
1272
+ mount: (el: HTMLElement, ctx: ThemeMountContext) => MountResult;
1273
+ /**
1274
+ * Server entry — returns the exact element tree `mount` would render,
1275
+ * for host-side `renderToString`. Must stay side-effect free: no DOM
1276
+ * access happens until React effects run (which they don't on the
1277
+ * server).
1278
+ */
1279
+ createApp: (ctx: ThemeMountContext) => ReactElement;
1280
+ }
1281
+ declare function defineThemeEntry(renderApp: (args: ThemeRenderArgs) => ReactNode): ThemeEntry;
1282
+
1184
1283
  interface NuMuProviderProps {
1185
1284
  store: Store;
1186
1285
  themeSettings: ThemeSettingsV3;
@@ -2126,11 +2225,32 @@ type GlobalSettings = Record<string, unknown> | null | undefined;
2126
2225
  * family/stack the theme author supplied.
2127
2226
  */
2128
2227
  declare function resolveFontStack(value: string): string;
2228
+ /** Result of `computeGlobalStyleTokens` — everything a host needs to paint
2229
+ * global settings without a DOM. */
2230
+ interface ComputedStyleTokens {
2231
+ /** CSS custom properties to set on the theme's mount root. */
2232
+ cssVars: Record<string, string>;
2233
+ /** Google-Fonts stylesheet hrefs for any registry fonts in use. */
2234
+ fontHrefs: string[];
2235
+ }
2236
+ /**
2237
+ * Pure half of `applyGlobalStyleTokens`: compute the exact CSS custom
2238
+ * properties (and webfont hrefs) a settings object maps to, without touching
2239
+ * any DOM. This is what lets a host SERVER-render a theme with the same vars
2240
+ * the bundle applies on mount — both sides call this one function, so the
2241
+ * values cannot drift (drift = unstyled flash or hydration noise).
2242
+ *
2243
+ * Includes the explicit `heading_font` / `body_font` resolution that
2244
+ * `mountTheme` historically layered on top: any string value for those two
2245
+ * ids resolves through the registry (or passes verbatim) so a picked font
2246
+ * gets a real stack even when it isn't a known token.
2247
+ */
2248
+ declare function computeGlobalStyleTokens(globalSettings: GlobalSettings): ComputedStyleTokens;
2129
2249
  /**
2130
2250
  * Map a store's global settings onto CSS custom properties on `el`. Call on
2131
2251
  * mount and on every `applyDraft` (live preview). No-op when `el` or the
2132
2252
  * settings are missing. Reserved `__`-prefixed keys (e.g. `__translations`)
2133
- * are skipped.
2253
+ * are skipped. Thin DOM shell over `computeGlobalStyleTokens`.
2134
2254
  */
2135
2255
  declare function applyGlobalStyleTokens(globalSettings: GlobalSettings, el: HTMLElement | null | undefined): void;
2136
2256
 
@@ -2192,4 +2312,4 @@ declare function pickTranslations(bundle: LocaleBundle, locale: string): LocaleM
2192
2312
  */
2193
2313
  declare function buildLocaleBundle<T extends Record<string, unknown>>(modules: T): LocaleBundle;
2194
2314
 
2195
- export { AddToCartButton, type AddressInput, type AnalyticsApi, type AnalyticsPayload, type AppManifestBlock, type AppPayload, type AppState, Block, BlockInstance, BlockProps$1 as BlockProps, BlockSchema, Cart, CartContext, type CheckoutAddress, type CheckoutApi, type CheckoutSessionState, type CheckoutStep, Collection, CollectionCard, type CollectionCardProps, type CollectionCardSlots, CollectionContext, CollectionProvider, type CurrencyConfig, type CurrencyState, CurrencySwitcher, type CurrencySwitcherProps, Customer, type CustomerAddress, type CustomerAddressesState, CustomerContext, type DefineBlockInput, type DefineSectionInput, type DefinedBlock, type DefinedSection, type DynamicResolveContext, type DynamicSourceRef, EditableImage, type EditableImageProps, EditableText, type EditableTextProps, type FocalSrcOptions, Form, type GiftCardBalance, ICON_NAMES, Icon, IconMap, type IconProps, Image, type ImageTransform, Link, type LocaleBundle, type LocaleMessages, LocaleSwitcher, type LocaleSwitcherProps, LocalizationContext, type MenuItemData, Money, MountResult, NavigationContext, type NavigationItem, type NavigationState, NuMuProvider, type OrderDetail, type OrderListEntry, type OrderListState, type OrderState, Page, PageContext, type PlaceOrderResult, Product, ProductCard, type ProductCardProps, type ProductCardSlots, ProductContext, ProductProvider, ProductVariant, type RelatedProductsState, type ReorderResult, type ReorderSkipReason, type ReorderSkippedItem, RichText, type RichTextProps, type SearchResults, type SearchState, Section, SectionContext, SectionInstance, SectionProps$1 as SectionProps, SectionSchema, type ShippingRateOption, ShopContext, type ShopWithHelpers, Store, type ThemeMountContext, type ThemeMountPage, type ThemeRenderArgs, ThemeSettingsContext, ThemeSettingsV3, type UseGiftCardBalance, type UseReorder, type UseSearchOptions, type UseShippingRatesOptions, type UseShippingRatesState, type UseVariantSelection, type WishlistItem, type WishlistState, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, clearSdkSingleton, collectBlocks, collectSections, defaultVariant, defineBlock, defineSection, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSourcePath, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
2315
+ export { AddToCartButton, type AddressInput, type AnalyticsApi, type AnalyticsPayload, type AppManifestBlock, type AppPayload, type AppState, Block, BlockInstance, BlockProps$1 as BlockProps, BlockSchema, Cart, CartContext, type CheckoutAddress, type CheckoutApi, type CheckoutSessionState, type CheckoutStep, Collection, CollectionCard, type CollectionCardProps, type CollectionCardSlots, CollectionContext, CollectionProvider, type ComputedStyleTokens, type CurrencyConfig, type CurrencyState, CurrencySwitcher, type CurrencySwitcherProps, Customer, type CustomerAddress, type CustomerAddressesState, CustomerContext, type DefineBlockInput, type DefineSectionInput, type DefinedBlock, type DefinedSection, type DynamicResolveContext, type DynamicSourceRef, EditableImage, type EditableImageProps, EditableText, type EditableTextProps, type FocalSrcOptions, Form, type GiftCardBalance, ICON_NAMES, Icon, IconMap, type IconProps, Image, type ImageTransform, Link, type LocaleBundle, type LocaleMessages, LocaleSwitcher, type LocaleSwitcherProps, LocalizationContext, type MenuItemData, Money, MountResult, NavigationContext, type NavigationItem, type NavigationState, NuMuProvider, type OrderDetail, type OrderListEntry, type OrderListState, type OrderState, Page, PageContext, type PlaceOrderResult, Product, ProductCard, type ProductCardProps, type ProductCardSlots, ProductContext, ProductProvider, ProductVariant, type RelatedProductsState, type ReorderResult, type ReorderSkipReason, type ReorderSkippedItem, RichText, type RichTextProps, type SearchResults, type SearchState, Section, SectionContext, SectionInstance, SectionProps$1 as SectionProps, SectionSchema, type ShippingRateOption, ShopContext, type ShopWithHelpers, SizeChart, Store, type ThemeEntry, type ThemeMountContext, type ThemeMountPage, type ThemeRenderArgs, ThemeSettingsContext, ThemeSettingsV3, type UseGiftCardBalance, type UseReorder, type UseSearchOptions, type UseShippingRatesOptions, type UseShippingRatesState, type UseVariantSelection, type WishlistItem, type WishlistState, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, buildThemeElement, clearSdkSingleton, collectBlocks, collectSections, computeGlobalStyleTokens, defaultVariant, defineBlock, defineSection, defineThemeEntry, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSizeChart, resolveSourcePath, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProductSizeChart, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createContext, forwardRef, useState, useImperativeHandle, useEffect, useCallback, useMemo, useRef, useContext, StrictMode, createElement, Component } from 'react';
2
- import { createRoot } from 'react-dom/client';
2
+ import { hydrateRoot, createRoot } from 'react-dom/client';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
 
5
5
  // src/types/theme.ts
@@ -940,6 +940,29 @@ function useRelatedProducts(productId, options = {}) {
940
940
  }, [productId, limit]);
941
941
  return { items, loading, error };
942
942
  }
943
+ function useProductSizeChart(productOverride) {
944
+ const ctxProduct = useProductOptional();
945
+ const product = productOverride ?? ctxProduct;
946
+ const shop = useShop();
947
+ const storeSettings = shop?.settings;
948
+ return useMemo(
949
+ () => resolveSizeChart(product?.attributes, storeSettings),
950
+ [product?.attributes, storeSettings]
951
+ );
952
+ }
953
+ function hasRows(c) {
954
+ return !!c && typeof c === "object" && Array.isArray(c.rows) && c.rows.length > 0;
955
+ }
956
+ function resolveSizeChart(productAttributes, storeSettings) {
957
+ const product = productAttributes?.size_chart;
958
+ const storeDefault = storeSettings?.size_chart;
959
+ if (product?.mode === "off") return null;
960
+ if (product?.mode === "custom") return hasRows(product) ? product : null;
961
+ if (product?.mode === "default") return hasRows(storeDefault) ? storeDefault : null;
962
+ if (hasRows(product)) return product;
963
+ if (hasRows(storeDefault)) return storeDefault;
964
+ return null;
965
+ }
943
966
  var COOKIE_NAME = "numu_currency";
944
967
  var COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
945
968
  function readCookie(name) {
@@ -1989,6 +2012,9 @@ function injectFontLink(href) {
1989
2012
  link.setAttribute("data-numu-font", "");
1990
2013
  document.head.appendChild(link);
1991
2014
  }
2015
+ function lookupFontStack(value) {
2016
+ return FONT_REGISTRY[value]?.stack ?? value;
2017
+ }
1992
2018
  function resolveFontStack(value) {
1993
2019
  const entry = FONT_REGISTRY[value];
1994
2020
  if (entry) {
@@ -1997,39 +2023,69 @@ function resolveFontStack(value) {
1997
2023
  }
1998
2024
  return value;
1999
2025
  }
2000
- function applyGlobalStyleTokens(globalSettings, el) {
2001
- if (!el || !globalSettings || typeof globalSettings !== "object") return;
2002
- const style = el.style;
2026
+ function computeGlobalStyleTokens(globalSettings) {
2027
+ const cssVars = {};
2028
+ const fontHrefs = [];
2029
+ if (!globalSettings || typeof globalSettings !== "object") {
2030
+ return { cssVars, fontHrefs };
2031
+ }
2032
+ const pushHref = (href) => {
2033
+ if (href && !fontHrefs.includes(href)) fontHrefs.push(href);
2034
+ };
2003
2035
  for (const [key, value] of Object.entries(globalSettings)) {
2004
2036
  if (!key || key.startsWith("__")) continue;
2005
2037
  if (value && typeof value === "object" && !Array.isArray(value)) {
2006
2038
  for (const [role, c] of Object.entries(value)) {
2007
- if (isColorValue(c)) style.setProperty(`--scheme-${key}-${role}`, c);
2039
+ if (isColorValue(c)) cssVars[`--scheme-${key}-${role}`] = c;
2008
2040
  }
2009
2041
  continue;
2010
2042
  }
2011
2043
  if (isColorValue(value)) {
2012
- style.setProperty(`--theme-${key}`, value.trim());
2044
+ cssVars[`--theme-${key}`] = value.trim();
2013
2045
  const role = COLOR_ROLE_ALIASES[key];
2014
- if (role) style.setProperty(`--theme-color-${role}`, value.trim());
2046
+ if (role) cssVars[`--theme-color-${role}`] = value.trim();
2015
2047
  continue;
2016
2048
  }
2017
2049
  if (isFontToken(value)) {
2018
- const stack = resolveFontStack(value);
2019
- style.setProperty(`--theme-${key}`, stack);
2050
+ const entry = FONT_REGISTRY[value];
2051
+ cssVars[`--theme-${key}`] = entry.stack;
2020
2052
  const role = FONT_ROLE_ALIASES[key];
2021
- if (role) style.setProperty(`--theme-font-${role}`, stack);
2053
+ if (role) cssVars[`--theme-font-${role}`] = entry.stack;
2054
+ pushHref(entry.href);
2022
2055
  continue;
2023
2056
  }
2024
2057
  if (typeof value === "string" || typeof value === "number") {
2025
2058
  const v = String(value).trim();
2026
- if (v) style.setProperty(`--theme-${key}`, v);
2059
+ if (v) cssVars[`--theme-${key}`] = v;
2060
+ }
2061
+ }
2062
+ for (const id of ["heading_font", "body_font"]) {
2063
+ const value = globalSettings[id];
2064
+ if (typeof value === "string" && value.trim()) {
2065
+ cssVars[`--theme-${id}`] = lookupFontStack(value);
2066
+ pushHref(FONT_REGISTRY[value]?.href);
2027
2067
  }
2028
2068
  }
2069
+ return { cssVars, fontHrefs };
2070
+ }
2071
+ function applyGlobalStyleTokens(globalSettings, el) {
2072
+ if (!el || !globalSettings || typeof globalSettings !== "object") return;
2073
+ const { cssVars, fontHrefs } = computeGlobalStyleTokens(globalSettings);
2074
+ const style = el.style;
2075
+ for (const [prop, value] of Object.entries(cssVars)) {
2076
+ style.setProperty(prop, value);
2077
+ }
2078
+ for (const href of fontHrefs) injectFontLink(href);
2029
2079
  }
2030
2080
  function pickStore(ctx) {
2031
2081
  const s = ctx.storeData ?? ctx.store;
2032
- if (s) return s;
2082
+ if (s) {
2083
+ const raw = s;
2084
+ if (!raw.currency && raw.default_currency) {
2085
+ return { ...raw, currency: raw.default_currency };
2086
+ }
2087
+ return s;
2088
+ }
2033
2089
  return {
2034
2090
  id: "unknown",
2035
2091
  name: "Store",
@@ -2064,19 +2120,9 @@ var ThemeMountBridge = forwardRef(function ThemeMountBridge2({ ctx, mountEl, ren
2064
2120
  []
2065
2121
  );
2066
2122
  useEffect(() => {
2123
+ if (!mountEl) return;
2067
2124
  const gs = themeSettings.global_settings ?? {};
2068
2125
  applyGlobalStyleTokens(gs, mountEl);
2069
- const headingFont = gs.heading_font;
2070
- if (typeof headingFont === "string" && headingFont.trim()) {
2071
- mountEl.style.setProperty(
2072
- "--theme-heading_font",
2073
- resolveFontStack(headingFont)
2074
- );
2075
- }
2076
- const bodyFont = gs.body_font;
2077
- if (typeof bodyFont === "string" && bodyFont.trim()) {
2078
- mountEl.style.setProperty("--theme-body_font", resolveFontStack(bodyFont));
2079
- }
2080
2126
  }, [themeSettings, mountEl]);
2081
2127
  const store = pickStore(ctx);
2082
2128
  const template = pickTemplate(ctx);
@@ -2106,22 +2152,22 @@ var ThemeMountBridge = forwardRef(function ThemeMountBridge2({ ctx, mountEl, ren
2106
2152
  }
2107
2153
  );
2108
2154
  });
2155
+ function buildThemeElement(ctx, mountEl, renderApp, ref) {
2156
+ return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(ThemeMountBridge, { ctx, mountEl, renderApp, ref }) });
2157
+ }
2109
2158
  function mountTheme(el, ctx, renderApp) {
2110
- const root = createRoot(el);
2111
2159
  const handleRef = { current: null };
2112
- root.render(
2113
- /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(
2114
- ThemeMountBridge,
2115
- {
2116
- ctx,
2117
- mountEl: el,
2118
- renderApp,
2119
- ref: (h) => {
2120
- handleRef.current = h;
2121
- }
2122
- }
2123
- ) })
2124
- );
2160
+ const element = buildThemeElement(ctx, el, renderApp, (h) => {
2161
+ handleRef.current = h;
2162
+ });
2163
+ const shouldHydrate = ctx.hydrate === true && el.firstElementChild !== null;
2164
+ let root;
2165
+ if (shouldHydrate) {
2166
+ root = hydrateRoot(el, element);
2167
+ } else {
2168
+ root = createRoot(el);
2169
+ root.render(element);
2170
+ }
2125
2171
  return {
2126
2172
  applyDraft: (next) => handleRef.current?.applyDraft(next),
2127
2173
  cleanup: () => {
@@ -2130,6 +2176,14 @@ function mountTheme(el, ctx, renderApp) {
2130
2176
  }
2131
2177
  };
2132
2178
  }
2179
+
2180
+ // src/entry.tsx
2181
+ function defineThemeEntry(renderApp) {
2182
+ return {
2183
+ mount: (el, ctx) => mountTheme(el, ctx, renderApp),
2184
+ createApp: (ctx) => buildThemeElement(ctx, null, renderApp)
2185
+ };
2186
+ }
2133
2187
  function CollectionProvider({ collection, children }) {
2134
2188
  return /* @__PURE__ */ jsx(CollectionContext.Provider, { value: collection, children });
2135
2189
  }
@@ -2753,7 +2807,14 @@ function sanitizeHtmlServer(input) {
2753
2807
  return s;
2754
2808
  }
2755
2809
  function RichText({ html, className, as = "div" }) {
2756
- const safe = useMemo(() => sanitizeHtml(html || ""), [html]);
2810
+ const [domReady, setDomReady] = useState(false);
2811
+ useEffect(() => {
2812
+ setDomReady(true);
2813
+ }, []);
2814
+ const safe = useMemo(
2815
+ () => domReady ? sanitizeHtml(html || "") : sanitizeHtmlServer(html || ""),
2816
+ [html, domReady]
2817
+ );
2757
2818
  if (!safe) return null;
2758
2819
  const Tag = as;
2759
2820
  return /* @__PURE__ */ jsx(
@@ -3419,8 +3480,13 @@ function collectBlocks(modules) {
3419
3480
 
3420
3481
  // src/utils/assetUrl.ts
3421
3482
  function getRuntime() {
3422
- if (typeof window === "undefined") return {};
3423
- return window;
3483
+ if (typeof window !== "undefined") {
3484
+ return window;
3485
+ }
3486
+ if (typeof globalThis !== "undefined") {
3487
+ return globalThis;
3488
+ }
3489
+ return {};
3424
3490
  }
3425
3491
  function assetUrl(name) {
3426
3492
  if (!name) return "";
@@ -3481,6 +3547,6 @@ function buildLocaleBundle(modules) {
3481
3547
  return bundle;
3482
3548
  }
3483
3549
 
3484
- export { AddToCartButton, Block, CartContext, CollectionCard, CollectionContext, CollectionProvider, CurrencySwitcher, CustomerContext, EditableImage, EditableText, Form, ICON_NAMES, Icon, IconMap, Image, Link, LocaleSwitcher, LocalizationContext, MAX_BLOCK_DEPTH, Money, NavigationContext, NuMuProvider, PageContext, ProductCard, ProductContext, ProductProvider, RichText, Section, SectionContext, ShopContext, ThemeSettingsContext, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, clearSdkSingleton, collectBlocks, collectSections, defaultVariant, defineBlock, defineSection, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSourcePath, resolveThemeSettings, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
3550
+ export { AddToCartButton, Block, CartContext, CollectionCard, CollectionContext, CollectionProvider, CurrencySwitcher, CustomerContext, EditableImage, EditableText, Form, ICON_NAMES, Icon, IconMap, Image, Link, LocaleSwitcher, LocalizationContext, MAX_BLOCK_DEPTH, Money, NavigationContext, NuMuProvider, PageContext, ProductCard, ProductContext, ProductProvider, RichText, Section, SectionContext, ShopContext, ThemeSettingsContext, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, buildThemeElement, clearSdkSingleton, collectBlocks, collectSections, computeGlobalStyleTokens, defaultVariant, defineBlock, defineSection, defineThemeEntry, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSizeChart, resolveSourcePath, resolveThemeSettings, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProductSizeChart, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
3485
3551
  //# sourceMappingURL=index.mjs.map
3486
3552
  //# sourceMappingURL=index.mjs.map