@weaverse/hydrogen 5.25.0 → 6.0.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 (80) hide show
  1. package/dist/index.js +23 -2444
  2. package/dist/index.mjs +4 -2407
  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 +7 -7
  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 +88 -68
  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/use-studio.d.ts +1 -1
  49. package/dist/types/utils/use-studio.d.ts.map +1 -1
  50. package/dist/types/utils/use-theme-settings-store.d.ts +8 -8
  51. package/dist/types/utils/use-theme-settings-store.d.ts.map +1 -1
  52. package/dist/types/weaverse-client.d.ts +14 -16
  53. package/dist/types/weaverse-client.d.ts.map +1 -1
  54. package/dist/weaverse-client-Clu3u7md.mjs +1966 -0
  55. package/dist/weaverse-client-Clu3u7md.mjs.map +1 -0
  56. package/dist/weaverse-client-yC4TYuVV.js +2073 -0
  57. package/dist/weaverse-client-yC4TYuVV.js.map +1 -0
  58. package/package.json +44 -6
  59. package/readme.md +44 -24
  60. package/src/WeaverseHydrogenRoot.tsx +18 -15
  61. package/src/components/index.ts +2 -2
  62. package/src/components/main.tsx +2 -2
  63. package/src/hooks/translation-context.tsx +3 -28
  64. package/src/index.ts +42 -81
  65. package/src/internal.ts +64 -0
  66. package/src/next-server.ts +13 -0
  67. package/src/next.ts +35 -0
  68. package/src/react-router.ts +52 -0
  69. package/src/react.ts +16 -0
  70. package/src/seo.ts +5 -5
  71. package/src/types.ts +104 -74
  72. package/src/utils/index.ts +15 -14
  73. package/src/utils/nested-key.ts +28 -0
  74. package/src/utils/normalize-page-url.ts +1 -1
  75. package/src/utils/product-options.ts +28 -0
  76. package/src/utils/use-studio.ts +1 -1
  77. package/src/utils/use-theme-settings-store.ts +7 -7
  78. package/src/weaverse-client.ts +88 -96
  79. package/dist/index.js.map +0 -1
  80. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,548 @@
1
+ let _weaverse_schema = require("@weaverse/schema");
2
+ //#region src/types.ts
3
+ /**
4
+ * Type guard for detecting function-based projectId.
5
+ *
6
+ * Used internally by WeaverseClient constructor to determine
7
+ * if projectId needs evaluation or can be used directly.
8
+ */
9
+ function isProjectIdFunction(projectId) {
10
+ return typeof projectId === "function";
11
+ }
12
+ /** Error raised by Weaverse requests with a stable code and optional context. */
13
+ var WeaverseError = class WeaverseError extends Error {
14
+ /** Machine-readable error code. */
15
+ code;
16
+ /** HTTP status associated with the failure, when available. */
17
+ statusCode;
18
+ /** Structured diagnostic details for logging and error handling. */
19
+ context;
20
+ /** Creates a Weaverse request error with a stable code and diagnostics. */
21
+ constructor(message, code = "WEAVERSE_ERROR", statusCode, context) {
22
+ super(message);
23
+ this.name = "WeaverseError";
24
+ this.code = code;
25
+ this.statusCode = statusCode;
26
+ this.context = context;
27
+ if (Error.captureStackTrace) Error.captureStackTrace(this, WeaverseError);
28
+ }
29
+ };
30
+ /**
31
+ * Error thrown by `WeaverseClient.loadPage()` when the client is created
32
+ * with `throwPageLoadFailures: true` and the page cannot be loaded.
33
+ *
34
+ * Genuine absence is not an error: a missing project still resolves to `null`
35
+ * and an unassigned page still resolves to a fallback page.
36
+ */
37
+ var WeaverseLoadError = class extends WeaverseError {
38
+ /** Failure class used to choose a response status or recovery action. */
39
+ kind;
40
+ /** Creates a classified page-load failure. */
41
+ constructor(message, kind, statusCode, context) {
42
+ super(message, "LOAD_FAILURE", statusCode, context);
43
+ this.name = "WeaverseLoadError";
44
+ this.kind = kind;
45
+ }
46
+ };
47
+ /**
48
+ * Type guards for response validation
49
+ */
50
+ function isWithCacheFetchResponse(response) {
51
+ return typeof response === "object" && response !== null && "data" in response && "response" in response;
52
+ }
53
+ /** Checks whether a value contains the required project response fields. */
54
+ function isFetchProjectPayload(payload) {
55
+ return typeof payload === "object" && payload !== null && "page" in payload && "project" in payload && "pageAssignment" in payload;
56
+ }
57
+ /** Checks whether a response contains a string error message. */
58
+ function hasError(response) {
59
+ return typeof response === "object" && response !== null && "error" in response && typeof response.error === "string";
60
+ }
61
+ /** Checks whether a value contains a theme settings object. */
62
+ function isThemeSettingsResponse(data) {
63
+ if (typeof data !== "object" || data === null) return false;
64
+ const record = data;
65
+ return "theme" in record && typeof record.theme === "object" && record.theme !== null;
66
+ }
67
+ /**
68
+ * Type guard to check if a schema is valid.
69
+ * Leverages validation from @weaverse/schema package which provides
70
+ * comprehensive Zod-based validation with the ElementSchema.
71
+ *
72
+ * @param schema - Unknown value to validate
73
+ * @returns True if schema is a valid WeaverseComponentSchema
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * if (isValidHydrogenSchema(userInput)) {
78
+ * // userInput is now typed as WeaverseComponentSchema
79
+ * console.log(userInput.type)
80
+ * }
81
+ * ```
82
+ */
83
+ function isValidHydrogenSchema(schema) {
84
+ return (0, _weaverse_schema.isValidSchema)(schema);
85
+ }
86
+ /** Checks whether the browser window exposes the Weaverse Studio bridge. */
87
+ function hasWeaverseStudio(window) {
88
+ return "weaverseStudio" in window && typeof window.weaverseStudio === "object";
89
+ }
90
+ //#endregion
91
+ //#region src/utils/studio-script-src.ts
92
+ const DEFAULT_WEAVERSE_HOST = "https://studio.weaverse.io";
93
+ /**
94
+ * Weaverse-controlled apex domains the Studio bridge may be served from
95
+ * (matched on the host itself and any subdomain).
96
+ */
97
+ const TRUSTED_STUDIO_DOMAINS = ["weaverse.io", "weaverse.dev"];
98
+ function isLoopbackHostname(hostname) {
99
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname.endsWith(".localhost");
100
+ }
101
+ /**
102
+ * Whether `host` is an origin we trust to serve the Studio bridge script (or,
103
+ * server-side, to resolve page/theme data).
104
+ *
105
+ * The bridge executes inside the storefront document and the host can drive
106
+ * server-side fetches, so a host taken from an attacker-controllable source —
107
+ * e.g. a crafted `?weaverseHost=` query — is both an XSS and an SSRF vector.
108
+ * Callers MUST reject untrusted hosts before acting on them. Trusts
109
+ * `weaverse.io`/`weaverse.dev` and their subdomains over https; loopback is
110
+ * opt-in (see {@link TrustedStudioHostOptions.allowLoopback}).
111
+ */
112
+ function isTrustedStudioHost(host, options) {
113
+ let parsed;
114
+ try {
115
+ parsed = new URL(host);
116
+ } catch {
117
+ return false;
118
+ }
119
+ let { hostname, protocol } = parsed;
120
+ if (options?.allowLoopback && isLoopbackHostname(hostname)) return protocol === "http:" || protocol === "https:";
121
+ if (protocol !== "https:") return false;
122
+ return TRUSTED_STUDIO_DOMAINS.some((domain) => hostname === domain || hostname.endsWith(`.${domain}`));
123
+ }
124
+ /**
125
+ * Build the Studio bridge script URL for the current mode, or `null` when the
126
+ * storefront is not being previewed inside Weaverse Studio.
127
+ *
128
+ * This is the single gate that keeps the bridge off production storefronts:
129
+ * a normal visitor's URL carries none of the design/preview markers, so the
130
+ * result is `null` and no script is ever requested.
131
+ *
132
+ * Shared by the page-scoped `useStudio` (which also binds the page for
133
+ * editing) and the root-level `useStudioConnect` (which only needs the script
134
+ * to load so Studio's `checkWeaversePage()` handshake can answer on routes
135
+ * with no Weaverse content).
136
+ */
137
+ function getStudioScriptSrc(mode) {
138
+ let { isDesignMode, isPreviewMode, isRevisionPreview, weaverseHost, weaverseVersion } = mode;
139
+ let base = `${weaverseHost}/static/studio/hydrogen`;
140
+ let version = `?v=${weaverseVersion}`;
141
+ if (isRevisionPreview || isPreviewMode) return `${base}/preview.js${version}`;
142
+ if (isDesignMode) return `${base}/index.js${version}`;
143
+ return null;
144
+ }
145
+ /**
146
+ * Resolve the Studio bridge script URL from a URL query string — the markers
147
+ * Studio attaches when it drives the preview iframe (`isDesignMode`,
148
+ * `isPreviewMode`, `__revisionId`, `weaverseHost`, `weaverseVersion`) — or
149
+ * `null` outside Studio.
150
+ *
151
+ * `storefrontHostname` is the document's own hostname: a loopback Studio host
152
+ * is only honored when the storefront itself is loopback (genuine local-builder
153
+ * dev), so a crafted public link can't load a script from a visitor's loopback
154
+ * service into the storefront origin.
155
+ *
156
+ * The `weaverseHost` query is attacker-controllable, so a host that is not a
157
+ * {@link isTrustedStudioHost trusted origin} resolves to `null` (no bridge) —
158
+ * it is never silently replaced with production Studio, which would otherwise
159
+ * inject the wrong bridge for self-hosted/staging deployments. Such deployments
160
+ * (a non-`weaverse.io` `WEAVERSE_HOST`) therefore don't load the root bridge on
161
+ * content-less routes; the page-scoped {@link getStudioScriptSrc} via
162
+ * `useStudio` still uses the configured host on content routes.
163
+ *
164
+ * Pure (no DOM) so the root-level connect's production gate stays unit-testable
165
+ * and needs no loader data.
166
+ */
167
+ function resolveStudioScriptSrc(search, storefrontHostname = "") {
168
+ let params = new URLSearchParams(search);
169
+ let last = (key) => params.getAll(key).at(-1);
170
+ let host = last("weaverseHost");
171
+ if (host) {
172
+ if (!isTrustedStudioHost(host, { allowLoopback: isLoopbackHostname(storefrontHostname) })) return null;
173
+ }
174
+ return getStudioScriptSrc({
175
+ isDesignMode: last("isDesignMode") === "true",
176
+ isPreviewMode: last("isPreviewMode") === "true",
177
+ isRevisionPreview: params.has("__revisionId"),
178
+ weaverseHost: host || DEFAULT_WEAVERSE_HOST,
179
+ weaverseVersion: last("weaverseVersion") || ""
180
+ });
181
+ }
182
+ //#endregion
183
+ //#region src/utils/index.ts
184
+ let warnedTypes = /* @__PURE__ */ new Set();
185
+ function logOnce(type, message) {
186
+ if (!warnedTypes.has(type)) {
187
+ console.warn(message);
188
+ warnedTypes.add(type);
189
+ }
190
+ }
191
+ function deepMergeArrays(target, source) {
192
+ return [...target, ...source];
193
+ }
194
+ function mergeInspectorSettings(settings, inspector, type) {
195
+ if (!inspector?.length) return settings;
196
+ if (!settings?.length) return inspector;
197
+ console.info(`Schema "${type}": Both 'settings' and 'inspector' found. Using 'settings' with 'inspector' as fallback.`);
198
+ return deepMergeArrays(settings, inspector);
199
+ }
200
+ /**
201
+ * Extract and parse query parameters from a request URL.
202
+ * Supports optional allowlist for security-sensitive applications.
203
+ *
204
+ * @param request - The incoming request
205
+ * @param options - Optional configuration
206
+ * @param options.allowedKeys - If provided, only these keys will be extracted
207
+ * @returns Parsed query parameters with type coercion for booleans
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * // Extract all params
212
+ * const queries = getRequestQueries(request)
213
+ *
214
+ * // Extract only allowed params (security-sensitive)
215
+ * const queries = getRequestQueries(request, {
216
+ * allowedKeys: ['weaverseProjectId', 'weaverseHost']
217
+ * })
218
+ * ```
219
+ */
220
+ function getRequestQueries(request, options) {
221
+ let url = new URL(request.url);
222
+ let queries = {};
223
+ for (let [key, value] of url.searchParams.entries()) {
224
+ if (options?.allowedKeys && !options.allowedKeys.includes(key)) continue;
225
+ if (value === "true") queries[key] = true;
226
+ else if (value === "false") queries[key] = false;
227
+ else queries[key] = value;
228
+ }
229
+ return queries;
230
+ }
231
+ /**
232
+ * Resolves project, endpoint, and Studio mode configuration for a request.
233
+ * URL-provided Studio values take precedence over environment defaults.
234
+ */
235
+ function getWeaverseConfigs(request, env) {
236
+ let queries = getRequestQueries(request);
237
+ let { WEAVERSE_PROJECT_ID, WEAVERSE_API_KEY, WEAVERSE_HOST, WEAVERSE_PUBLIC_API_BASE, PUBLIC_STORE_DOMAIN, PUBLIC_STOREFRONT_API_TOKEN } = env || {};
238
+ let envFromProcess = typeof process !== "undefined" && process.env || {};
239
+ let { weaverseProjectId, weaverseHost, isDesignMode, isPreviewMode, sectionType, weaverseVersion, weaverseApiKey } = queries;
240
+ let isRevisionPreview = new URL(request.url).searchParams.has("__revisionId");
241
+ let configuredWeaverseHost = WEAVERSE_HOST || envFromProcess.WEAVERSE_HOST;
242
+ let trustedUrlHost = typeof weaverseHost === "string" && isTrustedStudioHost(weaverseHost) ? weaverseHost : "";
243
+ let resolvedWeaverseHost = trustedUrlHost || configuredWeaverseHost || "https://studio.weaverse.io";
244
+ let resolvedWeaverseApiBase = trustedUrlHost ? trustedUrlHost : WEAVERSE_PUBLIC_API_BASE || envFromProcess.WEAVERSE_PUBLIC_API_BASE || (configuredWeaverseHost && configuredWeaverseHost !== "https://studio.weaverse.io" ? configuredWeaverseHost : "https://api.weaverse.io");
245
+ return {
246
+ projectId: weaverseProjectId || WEAVERSE_PROJECT_ID || envFromProcess.WEAVERSE_PROJECT_ID || "",
247
+ weaverseHost: resolvedWeaverseHost,
248
+ weaverseApiBase: resolvedWeaverseApiBase,
249
+ weaversePublicApiBase: resolvedWeaverseApiBase,
250
+ weaverseApiKey: weaverseApiKey || WEAVERSE_API_KEY || envFromProcess.WEAVERSE_API_KEY || "",
251
+ weaverseVersion: weaverseVersion || "",
252
+ isDesignMode,
253
+ isPreviewMode,
254
+ isRevisionPreview,
255
+ sectionType: sectionType || "",
256
+ publicEnv: {
257
+ PUBLIC_STORE_DOMAIN: PUBLIC_STORE_DOMAIN || "",
258
+ PUBLIC_STOREFRONT_API_TOKEN: PUBLIC_STOREFRONT_API_TOKEN || ""
259
+ }
260
+ };
261
+ }
262
+ /**
263
+ * Cache for generateDataFromSchema results using WeakMap.
264
+ * WeakMap allows garbage collection when schema objects are no longer referenced.
265
+ */
266
+ const schemaDefaultsCache = /* @__PURE__ */ new WeakMap();
267
+ /**
268
+ * Generate default data from component or theme schema.
269
+ * Results are memoized using WeakMap for performance.
270
+ *
271
+ * @param schema - Component or theme schema
272
+ * @returns Default data object extracted from schema inputs
273
+ */
274
+ function generateDataFromSchema(schema) {
275
+ const cached = schemaDefaultsCache.get(schema);
276
+ if (cached) return cached;
277
+ let data = {};
278
+ let inspectorGroups = [];
279
+ const isComponentSchema = (s) => "type" in s && typeof s.type === "string";
280
+ if (isComponentSchema(schema)) {
281
+ if (schema.settings) inspectorGroups = schema.settings;
282
+ if (schema.inspector) if (schema.settings?.length) inspectorGroups = mergeInspectorSettings(schema.settings, schema.inspector, schema.type || "unknown");
283
+ else {
284
+ inspectorGroups = schema.inspector;
285
+ if (schema.type) logOnce(schema.type, `⚠️ Schema "${schema.type}": The 'inspector' property is deprecated. Please use 'settings' instead.`);
286
+ }
287
+ } else {
288
+ if (schema.settings) inspectorGroups = schema.settings;
289
+ if (schema.inspector) if (schema.settings?.length) inspectorGroups = mergeInspectorSettings(schema.settings, schema.inspector, "Theme Schema");
290
+ else {
291
+ inspectorGroups = schema.inspector;
292
+ logOnce("ThemeSchema", `⚠️ Theme Schema: The 'inspector' property is deprecated. Please use 'settings' instead.`);
293
+ }
294
+ }
295
+ if (inspectorGroups?.length) for (let group of inspectorGroups) for (let input of group.inputs) {
296
+ let { name, defaultValue } = input;
297
+ if (name && defaultValue !== null && defaultValue !== void 0) data[name] = defaultValue;
298
+ }
299
+ schemaDefaultsCache.set(schema, data);
300
+ return data;
301
+ }
302
+ function recursivelyAddDataItem(type, components, items, initData) {
303
+ let component = components.find((c) => c.schema.type === type);
304
+ if (!component) return;
305
+ let childIds = [];
306
+ let id = crypto.randomUUID();
307
+ let { children, ...data } = component.schema?.presets || {};
308
+ if (children) for (let c of children) {
309
+ let { type, children, ...data } = c;
310
+ let childId = recursivelyAddDataItem(type, components, items, data);
311
+ childIds.push({ id: childId });
312
+ }
313
+ items.push({
314
+ data: {
315
+ ...data,
316
+ ...initData
317
+ },
318
+ id,
319
+ type,
320
+ children: childIds
321
+ });
322
+ return id;
323
+ }
324
+ /** Creates synthetic loader data for previewing one registered component type. */
325
+ function getPreviewData(type, components, weaverseHost) {
326
+ let items = [];
327
+ return {
328
+ project: {
329
+ id: "x",
330
+ weaverseShopId: "shop-id",
331
+ name: "Section Preview"
332
+ },
333
+ configs: {
334
+ projectId: "x",
335
+ weaverseHost,
336
+ isDesignMode: false,
337
+ isPreviewMode: true,
338
+ requestInfo: {
339
+ i18n: {
340
+ label: "United States (USD $)",
341
+ language: "EN",
342
+ country: "US",
343
+ currency: "USD",
344
+ pathPrefix: ""
345
+ },
346
+ queries: {},
347
+ pathname: "/",
348
+ search: ""
349
+ }
350
+ },
351
+ page: {
352
+ id: "weaverse-preview-page",
353
+ name: "Preview section",
354
+ rootId: "1",
355
+ items: [{
356
+ data: {},
357
+ id: "1",
358
+ type: "main",
359
+ children: [{ id: recursivelyAddDataItem(type, components, items) }]
360
+ }, ...items]
361
+ }
362
+ };
363
+ }
364
+ //#endregion
365
+ //#region src/utils/nested-key.ts
366
+ /**
367
+ * Traverse a nested object by dot-path.
368
+ *
369
+ * @example
370
+ * getNestedKey({ cart: { title: 'Cart' } }, 'cart.title') // => 'Cart'
371
+ * getNestedKey({}, 'cart.title', 'fallback') // => 'fallback'
372
+ */
373
+ function getNestedKey(obj, path, fallback) {
374
+ const keys = path.split(".");
375
+ let current = obj;
376
+ for (const key of keys) {
377
+ if (current == null || typeof current !== "object") return fallback;
378
+ current = current[key];
379
+ }
380
+ if (typeof current === "string") return current;
381
+ return fallback;
382
+ }
383
+ //#endregion
384
+ //#region src/utils/translation-store.ts
385
+ /**
386
+ * Minimal mutable store for design-mode static text overrides.
387
+ *
388
+ * useSyncExternalStore-compatible. Passed into TranslationProvider which
389
+ * subscribes internally and merges overrides into merchantOverrides.
390
+ * The studio bridge calls updateOverrides() via weaverse.internal.translationStore
391
+ * (also exposed as the deprecated weaverse.internal.themeTextStore alias).
392
+ *
393
+ * Shape: flat Record<string, string> — dot-notation keys map to values
394
+ * (e.g. "cart.title" → "Shopping Cart").
395
+ */
396
+ var TranslationStore = class {
397
+ /** Current flat translation overrides keyed by dot-path. */
398
+ overrides = {};
399
+ listeners = /* @__PURE__ */ new Set();
400
+ /** Replaces all overrides and notifies subscribers. */
401
+ setOverrides = (overrides) => {
402
+ this.overrides = { ...overrides };
403
+ this.emit();
404
+ };
405
+ /** Merges changed overrides and notifies subscribers. */
406
+ updateOverrides = (newOverrides) => {
407
+ this.overrides = {
408
+ ...this.overrides,
409
+ ...newOverrides
410
+ };
411
+ this.emit();
412
+ };
413
+ /** Returns the current client snapshot for `useSyncExternalStore`. */
414
+ getSnapshot = () => this.overrides;
415
+ /** Returns the current server snapshot for `useSyncExternalStore`. */
416
+ getServerSnapshot = () => this.overrides;
417
+ /** Subscribes to override changes and returns an unsubscribe callback. */
418
+ subscribe = (callback) => {
419
+ this.listeners.add(callback);
420
+ return () => {
421
+ this.listeners.delete(callback);
422
+ };
423
+ };
424
+ emit = () => {
425
+ for (const listener of Array.from(this.listeners)) try {
426
+ listener();
427
+ } catch (error) {
428
+ console.error("TranslationStore: Listener error", error);
429
+ }
430
+ };
431
+ };
432
+ /**
433
+ * Legacy constructor alias retained for existing theme text integrations.
434
+ * @deprecated Use {@link TranslationStore} instead. This alias remains available
435
+ * for backward compatibility.
436
+ */
437
+ const ThemeTextStore = TranslationStore;
438
+ //#endregion
439
+ Object.defineProperty(exports, "ThemeTextStore", {
440
+ enumerable: true,
441
+ get: function() {
442
+ return ThemeTextStore;
443
+ }
444
+ });
445
+ Object.defineProperty(exports, "TranslationStore", {
446
+ enumerable: true,
447
+ get: function() {
448
+ return TranslationStore;
449
+ }
450
+ });
451
+ Object.defineProperty(exports, "WeaverseError", {
452
+ enumerable: true,
453
+ get: function() {
454
+ return WeaverseError;
455
+ }
456
+ });
457
+ Object.defineProperty(exports, "WeaverseLoadError", {
458
+ enumerable: true,
459
+ get: function() {
460
+ return WeaverseLoadError;
461
+ }
462
+ });
463
+ Object.defineProperty(exports, "generateDataFromSchema", {
464
+ enumerable: true,
465
+ get: function() {
466
+ return generateDataFromSchema;
467
+ }
468
+ });
469
+ Object.defineProperty(exports, "getNestedKey", {
470
+ enumerable: true,
471
+ get: function() {
472
+ return getNestedKey;
473
+ }
474
+ });
475
+ Object.defineProperty(exports, "getPreviewData", {
476
+ enumerable: true,
477
+ get: function() {
478
+ return getPreviewData;
479
+ }
480
+ });
481
+ Object.defineProperty(exports, "getRequestQueries", {
482
+ enumerable: true,
483
+ get: function() {
484
+ return getRequestQueries;
485
+ }
486
+ });
487
+ Object.defineProperty(exports, "getStudioScriptSrc", {
488
+ enumerable: true,
489
+ get: function() {
490
+ return getStudioScriptSrc;
491
+ }
492
+ });
493
+ Object.defineProperty(exports, "getWeaverseConfigs", {
494
+ enumerable: true,
495
+ get: function() {
496
+ return getWeaverseConfigs;
497
+ }
498
+ });
499
+ Object.defineProperty(exports, "hasError", {
500
+ enumerable: true,
501
+ get: function() {
502
+ return hasError;
503
+ }
504
+ });
505
+ Object.defineProperty(exports, "hasWeaverseStudio", {
506
+ enumerable: true,
507
+ get: function() {
508
+ return hasWeaverseStudio;
509
+ }
510
+ });
511
+ Object.defineProperty(exports, "isFetchProjectPayload", {
512
+ enumerable: true,
513
+ get: function() {
514
+ return isFetchProjectPayload;
515
+ }
516
+ });
517
+ Object.defineProperty(exports, "isProjectIdFunction", {
518
+ enumerable: true,
519
+ get: function() {
520
+ return isProjectIdFunction;
521
+ }
522
+ });
523
+ Object.defineProperty(exports, "isThemeSettingsResponse", {
524
+ enumerable: true,
525
+ get: function() {
526
+ return isThemeSettingsResponse;
527
+ }
528
+ });
529
+ Object.defineProperty(exports, "isValidHydrogenSchema", {
530
+ enumerable: true,
531
+ get: function() {
532
+ return isValidHydrogenSchema;
533
+ }
534
+ });
535
+ Object.defineProperty(exports, "isWithCacheFetchResponse", {
536
+ enumerable: true,
537
+ get: function() {
538
+ return isWithCacheFetchResponse;
539
+ }
540
+ });
541
+ Object.defineProperty(exports, "resolveStudioScriptSrc", {
542
+ enumerable: true,
543
+ get: function() {
544
+ return resolveStudioScriptSrc;
545
+ }
546
+ });
547
+
548
+ //# sourceMappingURL=translation-store-BpPWqZ0B.js.map