@weaverse/hydrogen 5.3.4 → 5.4.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { createWithCache, generateCacheControlHeader, getSelectedProductOptions as getSelectedProductOptions$1 } from '@shopify/hydrogen';
1
+ import { createWithCache, getSelectedProductOptions as getSelectedProductOptions$1 } from '@shopify/hydrogen';
2
2
  import { Weaverse, WeaverseItemStore, loadScript, WeaverseRoot, isBrowser, EventEmitter, useSafeExternalStore } from '@weaverse/react';
3
3
  export { isBrowser, isIframe, useChildInstances, useItemInstance, useParentInstance, useWeaverse } from '@weaverse/react';
4
4
  import { createSchema } from '@weaverse/schema';
@@ -41,6 +41,33 @@ var schema = createSchema({
41
41
  var defaultComponents = [main_exports];
42
42
 
43
43
  // src/types.ts
44
+ var WeaverseError = class _WeaverseError extends Error {
45
+ code;
46
+ statusCode;
47
+ context;
48
+ constructor(message, code = "WEAVERSE_ERROR", statusCode, context) {
49
+ super(message);
50
+ this.name = "WeaverseError";
51
+ this.code = code;
52
+ this.statusCode = statusCode;
53
+ this.context = context;
54
+ if (Error.captureStackTrace) {
55
+ Error.captureStackTrace(this, _WeaverseError);
56
+ }
57
+ }
58
+ };
59
+ function isWithCacheFetchResponse(response) {
60
+ return typeof response === "object" && response !== null && "data" in response && "response" in response;
61
+ }
62
+ function isFetchProjectPayload(payload) {
63
+ return typeof payload === "object" && payload !== null && "page" in payload && "project" in payload && "pageAssignment" in payload;
64
+ }
65
+ function hasError(response) {
66
+ return typeof response === "object" && response !== null && "error" in response && typeof response.error === "string";
67
+ }
68
+ function isThemeSettingsResponse(data) {
69
+ return typeof data === "object" && data !== null && data.theme !== void 0;
70
+ }
44
71
  function isValidHydrogenSchema(schema2) {
45
72
  return typeof schema2 === "object" && schema2 !== null && "type" in schema2 && "title" in schema2;
46
73
  }
@@ -57,8 +84,12 @@ function deepMergeArrays(target, source) {
57
84
  return [...target, ...source];
58
85
  }
59
86
  function mergeInspectorSettings(settings, inspector, type) {
60
- if (!inspector?.length) return settings;
61
- if (!settings?.length) return inspector;
87
+ if (!inspector?.length) {
88
+ return settings;
89
+ }
90
+ if (!settings?.length) {
91
+ return inspector;
92
+ }
62
93
  console.info(
63
94
  `Schema "${type}": Both 'settings' and 'inspector' found. Using 'settings' with 'inspector' as fallback.`
64
95
  );
@@ -80,6 +111,7 @@ function getWeaverseConfigs(request, env) {
80
111
  WEAVERSE_PROJECT_ID,
81
112
  WEAVERSE_API_KEY,
82
113
  WEAVERSE_HOST,
114
+ WEAVERSE_API_BASE,
83
115
  PUBLIC_STORE_DOMAIN,
84
116
  PUBLIC_STOREFRONT_API_TOKEN
85
117
  } = env || {};
@@ -96,10 +128,11 @@ function getWeaverseConfigs(request, env) {
96
128
  return {
97
129
  projectId: weaverseProjectId || WEAVERSE_PROJECT_ID || envFromProcess.WEAVERSE_PROJECT_ID || "",
98
130
  weaverseHost: weaverseHost || WEAVERSE_HOST || envFromProcess.WEAVERSE_HOST || "https://studio.weaverse.io",
131
+ weaverseApiBase: WEAVERSE_API_BASE || envFromProcess.WEAVERSE_API_BASE || "https://api.weaverse.io",
99
132
  weaverseApiKey: weaverseApiKey || WEAVERSE_API_KEY || envFromProcess.WEAVERSE_API_KEY || "",
100
133
  weaverseVersion: weaverseVersion || "",
101
- isDesignMode: isDesignMode || false,
102
- isPreviewMode: isPreviewMode || false,
134
+ isDesignMode,
135
+ isPreviewMode,
103
136
  sectionType: sectionType || "",
104
137
  publicEnv: {
105
138
  PUBLIC_STORE_DOMAIN: PUBLIC_STORE_DOMAIN || "",
@@ -295,7 +328,9 @@ function useStudio(weaverse) {
295
328
  function usePixel(context) {
296
329
  let { projectId, pageId, weaverseHost, isDesignMode } = context;
297
330
  useEffect(() => {
298
- if (!projectId || !pageId || !weaverseHost || isDesignMode) return;
331
+ if (!(projectId && pageId && weaverseHost) || isDesignMode) {
332
+ return;
333
+ }
299
334
  let url = `${weaverseHost}/api/public/px`;
300
335
  let img = new Image();
301
336
  img.onload = () => img.remove();
@@ -323,6 +358,14 @@ var WeaverseHydrogen = class extends Weaverse {
323
358
  pageId;
324
359
  internal;
325
360
  requestInfo;
361
+ projectId;
362
+ weaverseHost;
363
+ weaverseApiBase;
364
+ weaverseApiKey;
365
+ weaverseVersion;
366
+ isDesignMode;
367
+ isPreviewMode;
368
+ sectionType;
326
369
  static itemInstances;
327
370
  static elementRegistry;
328
371
  constructor(params) {
@@ -331,6 +374,14 @@ var WeaverseHydrogen = class extends Weaverse {
331
374
  this.internal = internal;
332
375
  this.pageId = pageId;
333
376
  this.requestInfo = requestInfo;
377
+ this.projectId = params.projectId;
378
+ this.weaverseHost = params.weaverseHost;
379
+ this.weaverseApiBase = params.weaverseApiBase;
380
+ this.weaverseApiKey = params.weaverseApiKey;
381
+ this.weaverseVersion = params.weaverseVersion || "";
382
+ this.isDesignMode = params.isDesignMode ?? false;
383
+ this.isPreviewMode = params.isPreviewMode ?? false;
384
+ this.sectionType = params.sectionType || "";
334
385
  }
335
386
  };
336
387
  function createWeaverseInstance(params) {
@@ -387,9 +438,9 @@ var WeaverseHydrogenRoot = memo(
387
438
  let data = loaderData?.weaverseData;
388
439
  if (data) {
389
440
  if (data instanceof Promise) {
390
- return /* @__PURE__ */ jsx(ErrorBoundary, { fallbackRender: ErrorComponent, children: /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(Await, { resolve: data, children: (resolvedData) => /* @__PURE__ */ jsx(RenderRoot, { data: resolvedData, components }) }) }) });
441
+ return /* @__PURE__ */ jsx(ErrorBoundary, { fallbackRender: ErrorComponent, children: /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(Await, { resolve: data, children: (resolvedData) => /* @__PURE__ */ jsx(RenderRoot, { components, data: resolvedData }) }) }) });
391
442
  }
392
- return /* @__PURE__ */ jsx(RenderRoot, { data, components });
443
+ return /* @__PURE__ */ jsx(RenderRoot, { components, data });
393
444
  }
394
445
  return /* @__PURE__ */ jsx(
395
446
  ErrorComponent,
@@ -416,12 +467,17 @@ function useThemeSettings() {
416
467
  );
417
468
  return settings;
418
469
  }
419
- var API_PATH = "api/public";
470
+ var API_PATH = "v1";
420
471
  var DEFAULT_CACHE_STRATEGY = {
421
- maxAge: 10,
422
- sMaxAge: 10,
423
- staleWhileRevalidate: 82800,
424
- staleIfError: 82800
472
+ maxAge: 5,
473
+ // 5 seconds for development/testing
474
+ sMaxAge: 5,
475
+ // 5 seconds CDN cache
476
+ staleWhileRevalidate: 5,
477
+ // 5 seconds
478
+ staleIfError: 82800,
479
+ // 23 hours
480
+ mode: "public"
425
481
  };
426
482
  var WeaverseClient = class {
427
483
  API = API_PATH;
@@ -454,11 +510,16 @@ var WeaverseClient = class {
454
510
  this.env = env;
455
511
  this.cache = cache;
456
512
  this.waitUntil = waitUntil;
457
- this.withCache = createWithCache({ cache, waitUntil, request });
513
+ this.withCache = createWithCache({
514
+ cache,
515
+ waitUntil: waitUntil || (() => Promise.resolve()),
516
+ request
517
+ });
458
518
  this.configs = getWeaverseConfigs(request, env);
459
519
  this.basePageConfigs = {
460
520
  projectId: this.configs.projectId,
461
521
  weaverseHost: this.configs.weaverseHost,
522
+ weaverseApiBase: this.configs.weaverseApiBase,
462
523
  weaverseApiKey: this.configs.weaverseApiKey,
463
524
  weaverseVersion: this.configs.weaverseVersion,
464
525
  isDesignMode: this.configs.isDesignMode
@@ -469,73 +530,90 @@ var WeaverseClient = class {
469
530
  projectId: this.configs.projectId
470
531
  };
471
532
  }
472
- // Helper method for direct fetching in design mode
533
+ // Helper method for direct fetching in design mode - returns same format as withCache.fetch
473
534
  directFetch = async (url, options = {}) => {
474
535
  try {
475
- let res = await fetch(url, options);
476
- if (!res.ok) {
477
- let error = await res.text();
478
- throw new Error(`${res.status} ${res.statusText} ${error}`);
536
+ let response = await fetch(url, options);
537
+ if (!response.ok) {
538
+ let error = await response.text();
539
+ throw new Error(`${response.status} ${response.statusText} ${error}`);
479
540
  }
480
- return res.json();
541
+ let data = await response.json();
542
+ return {
543
+ data,
544
+ response
545
+ };
481
546
  } catch (err) {
482
547
  throw new Error(`Failed to fetch data from ${url}`, { cause: err });
483
548
  }
484
549
  };
550
+ // Helper method for building API URLs consistently
551
+ getApiUrl(endpoint, useProxy = !this.configs.isDesignMode) {
552
+ const { weaverseHost, weaverseApiBase, projectId } = this.configs;
553
+ if (useProxy) {
554
+ return `${weaverseApiBase}/v1/${endpoint}?projectId=${projectId}`;
555
+ }
556
+ return `${weaverseHost}/api/public/${endpoint}`;
557
+ }
485
558
  fetchWithCache = async (url, options = {}) => {
486
- let {
487
- strategy = this.storefront.CacheCustom(DEFAULT_CACHE_STRATEGY),
488
- ...reqInit
489
- } = options;
490
- let cacheKey = [url, options.body];
559
+ const strategy = options.strategy || this.storefront.CacheCustom(DEFAULT_CACHE_STRATEGY);
560
+ const cacheKey = [url, options.method || "GET", options.body];
561
+ let result;
491
562
  if (this.configs.isDesignMode) {
492
- return this.directFetch(url, reqInit);
493
- }
494
- return this.withCache.run(
495
- {
563
+ result = await this.directFetch(url, options);
564
+ } else {
565
+ result = await this.withCache.fetch(url, options, {
496
566
  cacheKey,
497
567
  cacheStrategy: strategy,
498
- shouldCacheResult: (result) => result?.data
499
- },
500
- async () => {
501
- return this.directFetch(url, {
502
- ...reqInit,
503
- headers: {
504
- "Cache-Control": generateCacheControlHeader(strategy),
505
- ...reqInit.headers
506
- }
507
- });
508
- }
509
- );
568
+ shouldCacheResponse: (response) => {
569
+ return !hasError(response) && response !== null && response !== void 0;
570
+ },
571
+ displayName: "Weaverse API"
572
+ });
573
+ }
574
+ return result.data;
510
575
  };
511
576
  loadThemeSettings = async (strategy) => {
512
577
  let defaultThemeSettings = generateDataFromSchema(this.themeSchema);
513
578
  try {
514
- let { API, configs } = this;
515
- let { weaverseHost, projectId, isDesignMode } = configs;
579
+ let { configs } = this;
580
+ let { weaverseApiBase, weaverseHost, projectId, isDesignMode } = configs;
516
581
  if (!projectId) {
517
582
  throw new Error("Missing Weaverse projectId!");
518
583
  }
519
- let url = `${weaverseHost}/${API}/project_configs`;
520
- let res;
584
+ let url = this.getApiUrl("project_configs");
521
585
  let body = JSON.stringify({ isDesignMode, projectId });
522
- if (isDesignMode) {
523
- res = await fetch(url, { method: "POST", body }).then(
524
- (res2) => res2.json()
586
+ let data = await this.fetchWithCache(url, {
587
+ method: "POST",
588
+ strategy,
589
+ body,
590
+ headers: {
591
+ "Content-Type": "application/json",
592
+ Accept: "application/json",
593
+ "Accept-Encoding": "gzip, deflate, br"
594
+ }
595
+ });
596
+ if (typeof data !== "object" || data === null) {
597
+ console.warn(
598
+ "Invalid theme settings response format, using defaults:",
599
+ {
600
+ type: typeof data,
601
+ isString: typeof data === "string",
602
+ length: typeof data === "string" ? data.length : "N/A",
603
+ preview: typeof data === "string" ? `${data.substring(0, 50)}...` : String(data)
604
+ }
525
605
  );
526
- } else {
527
- res = await this.fetchWithCache(url, {
528
- method: "POST",
529
- strategy,
530
- body
531
- });
606
+ data = { theme: defaultThemeSettings };
532
607
  }
533
- let data = res || {};
534
608
  if (this.themeSchema?.settings || this.themeSchema?.inspector) {
535
- data.theme = {
536
- ...defaultThemeSettings,
537
- ...data.theme
538
- };
609
+ if (!data.theme || typeof data.theme !== "object") {
610
+ data.theme = defaultThemeSettings;
611
+ } else {
612
+ data.theme = {
613
+ ...defaultThemeSettings,
614
+ ...data.theme
615
+ };
616
+ }
539
617
  }
540
618
  if (this.configs.isDesignMode) {
541
619
  data = {
@@ -554,14 +632,14 @@ var WeaverseClient = class {
554
632
  return input;
555
633
  })
556
634
  }))
557
- } : null,
635
+ } : void 0,
558
636
  publicEnv: this.configs.publicEnv
559
637
  };
560
638
  }
561
639
  return data;
562
640
  } catch (e) {
563
641
  console.info("Unable to load theme settings", e);
564
- return defaultThemeSettings;
642
+ return { theme: defaultThemeSettings };
565
643
  }
566
644
  };
567
645
  generateFallbackPage = (message) => {
@@ -586,11 +664,12 @@ var WeaverseClient = class {
586
664
  projectId,
587
665
  isDesignMode,
588
666
  weaverseHost,
667
+ weaverseApiBase,
589
668
  isPreviewMode,
590
669
  sectionType
591
670
  } = this.configs;
592
671
  if (isPreviewMode) {
593
- return getPreviewData(sectionType, this.components, weaverseHost);
672
+ return getPreviewData(sectionType || "", this.components, weaverseHost);
594
673
  }
595
674
  if (!projectId) {
596
675
  throw new Error("Missing Weaverse projectId!");
@@ -603,30 +682,29 @@ var WeaverseClient = class {
603
682
  };
604
683
  let reqInit = {
605
684
  method: "POST",
606
- body: JSON.stringify(body)
685
+ body: JSON.stringify(body),
686
+ headers: {
687
+ "Content-Type": "application/json",
688
+ Accept: "application/json",
689
+ "Accept-Encoding": "gzip, deflate, br"
690
+ }
607
691
  };
608
- let url = `${weaverseHost}/${this.API}/project`;
609
- let payload;
610
- if (isDesignMode) {
611
- payload = await fetch(url, reqInit).then((res) => res.json());
612
- } else {
613
- payload = await this.fetchWithCache(url, {
614
- ...reqInit,
615
- strategy
616
- });
617
- }
618
- if (payload?.error) {
619
- throw new Error(payload?.error);
692
+ let url = this.getApiUrl("project");
693
+ let projectData = await this.fetchWithCache(url, {
694
+ ...reqInit,
695
+ strategy
696
+ });
697
+ if (hasError(projectData)) {
698
+ throw new Error(projectData.error);
620
699
  }
621
- let { page, project, pageAssignment } = payload;
700
+ let { page, project, pageAssignment } = projectData;
622
701
  if (!project) {
623
- console.error("Weaverse project not found. Id:", projectId);
702
+ console.warn("Weaverse project not found. Id:", projectId);
624
703
  project = {
625
704
  id: projectId,
626
705
  name: "Weaverse project not found.",
627
706
  weaverseShopId: ""
628
707
  };
629
- page = this.generateFallbackPage("Weaverse project not found.");
630
708
  }
631
709
  if (!page) {
632
710
  page = this.generateFallbackPage("Please add new section to start.");
@@ -658,7 +736,7 @@ var WeaverseClient = class {
658
736
  let { data = {}, type, id } = item;
659
737
  let component = this.components?.find(({ schema: schema2 }) => schema2?.type === type);
660
738
  let loader = component?.loader;
661
- if (typeof loader === "function") {
739
+ if (typeof loader === "function" && component) {
662
740
  try {
663
741
  return {
664
742
  ...item,
@@ -717,6 +795,6 @@ var IMAGES_PLACEHOLDERS = {
717
795
  product_18: "https://cdn.shopify.com/s/files/1/0838/0052/3057/files/fpo-product-watch-2-1024x1024.svg"
718
796
  };
719
797
 
720
- export { IMAGES_PLACEHOLDERS, WeaverseClient, WeaverseHydrogen, WeaverseHydrogenItem, WeaverseHydrogenRoot, defaultComponents, generateDataFromSchema, getPreviewData, getRequestQueries, getSelectedProductOptions, getWeaverseConfigs, isValidHydrogenSchema, registerComponent, useThemeSettings, withWeaverse };
798
+ export { IMAGES_PLACEHOLDERS, WeaverseClient, WeaverseError, WeaverseHydrogen, WeaverseHydrogenItem, WeaverseHydrogenRoot, defaultComponents, generateDataFromSchema, getPreviewData, getRequestQueries, getSelectedProductOptions, getWeaverseConfigs, hasError, isFetchProjectPayload, isThemeSettingsResponse, isValidHydrogenSchema, isWithCacheFetchResponse, registerComponent, useThemeSettings, withWeaverse };
721
799
  //# sourceMappingURL=index.mjs.map
722
800
  //# sourceMappingURL=index.mjs.map