@weaverse/hydrogen 5.3.4 → 5.4.1-beta.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.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,14 @@ 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
472
  maxAge: 10,
422
473
  sMaxAge: 10,
423
474
  staleWhileRevalidate: 82800,
475
+ // 23 hours
424
476
  staleIfError: 82800
477
+ // 23 hours
425
478
  };
426
479
  var WeaverseClient = class {
427
480
  API = API_PATH;
@@ -454,11 +507,16 @@ var WeaverseClient = class {
454
507
  this.env = env;
455
508
  this.cache = cache;
456
509
  this.waitUntil = waitUntil;
457
- this.withCache = createWithCache({ cache, waitUntil, request });
510
+ this.withCache = createWithCache({
511
+ cache,
512
+ waitUntil: waitUntil || (() => Promise.resolve()),
513
+ request
514
+ });
458
515
  this.configs = getWeaverseConfigs(request, env);
459
516
  this.basePageConfigs = {
460
517
  projectId: this.configs.projectId,
461
518
  weaverseHost: this.configs.weaverseHost,
519
+ weaverseApiBase: this.configs.weaverseApiBase,
462
520
  weaverseApiKey: this.configs.weaverseApiKey,
463
521
  weaverseVersion: this.configs.weaverseVersion,
464
522
  isDesignMode: this.configs.isDesignMode
@@ -469,73 +527,91 @@ var WeaverseClient = class {
469
527
  projectId: this.configs.projectId
470
528
  };
471
529
  }
472
- // Helper method for direct fetching in design mode
530
+ // Helper method for direct fetching in design mode - returns same format as withCache.fetch
473
531
  directFetch = async (url, options = {}) => {
474
532
  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}`);
533
+ let response = await fetch(url, options);
534
+ if (!response.ok) {
535
+ let error = await response.text();
536
+ throw new Error(`${response.status} ${response.statusText} ${error}`);
479
537
  }
480
- return res.json();
538
+ let data = await response.json();
539
+ return {
540
+ data,
541
+ response
542
+ };
481
543
  } catch (err) {
482
544
  throw new Error(`Failed to fetch data from ${url}`, { cause: err });
483
545
  }
484
546
  };
547
+ // Helper method for building API URLs consistently
548
+ getApiUrl(endpoint, useProxy = !this.configs.isDesignMode) {
549
+ const { weaverseHost, weaverseApiBase, projectId } = this.configs;
550
+ if (useProxy) {
551
+ console.log("useProxy", weaverseApiBase, endpoint, projectId);
552
+ return `${weaverseApiBase}/v1/${endpoint}?projectId=${projectId}`;
553
+ }
554
+ return `${weaverseHost}/api/public/${endpoint}`;
555
+ }
485
556
  fetchWithCache = async (url, options = {}) => {
486
- let {
487
- strategy = this.storefront.CacheCustom(DEFAULT_CACHE_STRATEGY),
488
- ...reqInit
489
- } = options;
490
- let cacheKey = [url, options.body];
557
+ const strategy = options.strategy || this.storefront.CacheCustom(DEFAULT_CACHE_STRATEGY);
558
+ const cacheKey = [url, options.method || "GET", options.body];
559
+ let result;
491
560
  if (this.configs.isDesignMode) {
492
- return this.directFetch(url, reqInit);
493
- }
494
- return this.withCache.run(
495
- {
561
+ result = await this.directFetch(url, options);
562
+ } else {
563
+ result = await this.withCache.fetch(url, options, {
496
564
  cacheKey,
497
565
  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
- );
566
+ shouldCacheResponse: (response) => {
567
+ return !hasError(response) && response !== null && response !== void 0;
568
+ },
569
+ displayName: "Weaverse API"
570
+ });
571
+ }
572
+ return result.data;
510
573
  };
511
574
  loadThemeSettings = async (strategy) => {
512
575
  let defaultThemeSettings = generateDataFromSchema(this.themeSchema);
513
576
  try {
514
- let { API, configs } = this;
515
- let { weaverseHost, projectId, isDesignMode } = configs;
577
+ let { configs } = this;
578
+ let { weaverseApiBase, weaverseHost, projectId, isDesignMode } = configs;
516
579
  if (!projectId) {
517
580
  throw new Error("Missing Weaverse projectId!");
518
581
  }
519
- let url = `${weaverseHost}/${API}/project_configs`;
520
- let res;
582
+ let url = this.getApiUrl("project_configs");
521
583
  let body = JSON.stringify({ isDesignMode, projectId });
522
- if (isDesignMode) {
523
- res = await fetch(url, { method: "POST", body }).then(
524
- (res2) => res2.json()
584
+ let data = await this.fetchWithCache(url, {
585
+ method: "POST",
586
+ strategy,
587
+ body,
588
+ headers: {
589
+ "Content-Type": "application/json",
590
+ Accept: "application/json",
591
+ "Accept-Encoding": "gzip, deflate, br"
592
+ }
593
+ });
594
+ if (typeof data !== "object" || data === null) {
595
+ console.warn(
596
+ "Invalid theme settings response format, using defaults:",
597
+ {
598
+ type: typeof data,
599
+ isString: typeof data === "string",
600
+ length: typeof data === "string" ? data.length : "N/A",
601
+ preview: typeof data === "string" ? `${data.substring(0, 50)}...` : String(data)
602
+ }
525
603
  );
526
- } else {
527
- res = await this.fetchWithCache(url, {
528
- method: "POST",
529
- strategy,
530
- body
531
- });
604
+ data = { theme: defaultThemeSettings };
532
605
  }
533
- let data = res || {};
534
606
  if (this.themeSchema?.settings || this.themeSchema?.inspector) {
535
- data.theme = {
536
- ...defaultThemeSettings,
537
- ...data.theme
538
- };
607
+ if (!data.theme || typeof data.theme !== "object") {
608
+ data.theme = defaultThemeSettings;
609
+ } else {
610
+ data.theme = {
611
+ ...defaultThemeSettings,
612
+ ...data.theme
613
+ };
614
+ }
539
615
  }
540
616
  if (this.configs.isDesignMode) {
541
617
  data = {
@@ -554,14 +630,14 @@ var WeaverseClient = class {
554
630
  return input;
555
631
  })
556
632
  }))
557
- } : null,
633
+ } : void 0,
558
634
  publicEnv: this.configs.publicEnv
559
635
  };
560
636
  }
561
637
  return data;
562
638
  } catch (e) {
563
639
  console.info("Unable to load theme settings", e);
564
- return defaultThemeSettings;
640
+ return { theme: defaultThemeSettings };
565
641
  }
566
642
  };
567
643
  generateFallbackPage = (message) => {
@@ -582,15 +658,9 @@ var WeaverseClient = class {
582
658
  loadPage = async (params = {}) => {
583
659
  try {
584
660
  let { request, storefront, basePageRequestBody, basePageConfigs } = this;
585
- let {
586
- projectId,
587
- isDesignMode,
588
- weaverseHost,
589
- isPreviewMode,
590
- sectionType
591
- } = this.configs;
661
+ let { projectId, weaverseHost, isPreviewMode, sectionType } = this.configs;
592
662
  if (isPreviewMode) {
593
- return getPreviewData(sectionType, this.components, weaverseHost);
663
+ return getPreviewData(sectionType || "", this.components, weaverseHost);
594
664
  }
595
665
  if (!projectId) {
596
666
  throw new Error("Missing Weaverse projectId!");
@@ -603,30 +673,29 @@ var WeaverseClient = class {
603
673
  };
604
674
  let reqInit = {
605
675
  method: "POST",
606
- body: JSON.stringify(body)
676
+ body: JSON.stringify(body),
677
+ headers: {
678
+ "Content-Type": "application/json",
679
+ Accept: "application/json",
680
+ "Accept-Encoding": "gzip, deflate, br"
681
+ }
607
682
  };
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);
683
+ let url = this.getApiUrl("project");
684
+ let projectData = await this.fetchWithCache(url, {
685
+ ...reqInit,
686
+ strategy
687
+ });
688
+ if (hasError(projectData)) {
689
+ throw new Error(projectData.error);
620
690
  }
621
- let { page, project, pageAssignment } = payload;
691
+ let { page, project, pageAssignment } = projectData;
622
692
  if (!project) {
623
- console.error("Weaverse project not found. Id:", projectId);
693
+ console.warn("Weaverse project not found. Id:", projectId);
624
694
  project = {
625
695
  id: projectId,
626
696
  name: "Weaverse project not found.",
627
697
  weaverseShopId: ""
628
698
  };
629
- page = this.generateFallbackPage("Weaverse project not found.");
630
699
  }
631
700
  if (!page) {
632
701
  page = this.generateFallbackPage("Please add new section to start.");
@@ -658,7 +727,7 @@ var WeaverseClient = class {
658
727
  let { data = {}, type, id } = item;
659
728
  let component = this.components?.find(({ schema: schema2 }) => schema2?.type === type);
660
729
  let loader = component?.loader;
661
- if (typeof loader === "function") {
730
+ if (typeof loader === "function" && component) {
662
731
  try {
663
732
  return {
664
733
  ...item,
@@ -717,6 +786,6 @@ var IMAGES_PLACEHOLDERS = {
717
786
  product_18: "https://cdn.shopify.com/s/files/1/0838/0052/3057/files/fpo-product-watch-2-1024x1024.svg"
718
787
  };
719
788
 
720
- export { IMAGES_PLACEHOLDERS, WeaverseClient, WeaverseHydrogen, WeaverseHydrogenItem, WeaverseHydrogenRoot, defaultComponents, generateDataFromSchema, getPreviewData, getRequestQueries, getSelectedProductOptions, getWeaverseConfigs, isValidHydrogenSchema, registerComponent, useThemeSettings, withWeaverse };
789
+ export { IMAGES_PLACEHOLDERS, WeaverseClient, WeaverseError, WeaverseHydrogen, WeaverseHydrogenItem, WeaverseHydrogenRoot, defaultComponents, generateDataFromSchema, getPreviewData, getRequestQueries, getSelectedProductOptions, getWeaverseConfigs, hasError, isFetchProjectPayload, isThemeSettingsResponse, isValidHydrogenSchema, isWithCacheFetchResponse, registerComponent, useThemeSettings, withWeaverse };
721
790
  //# sourceMappingURL=index.mjs.map
722
791
  //# sourceMappingURL=index.mjs.map