@weaverse/hydrogen 1.1.3 → 1.1.4

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
@@ -2,6 +2,7 @@ import React, { ForwardRefExoticComponent } from 'react';
2
2
  import { LoaderArgs, AppLoadContext } from '@shopify/remix-oxygen';
3
3
  import { ElementData, ElementSchema, BasicInput, WeaverseElement, Weaverse, WeaverseItemStore } from '@weaverse/react';
4
4
  export * from '@weaverse/react';
5
+ import { LanguageCode, CountryCode, CurrencyCode } from '@shopify/hydrogen/storefront-api-types';
5
6
  import * as _shopify_hydrogen_react_storefront_api_types from '@shopify/hydrogen-react/storefront-api-types';
6
7
 
7
8
  declare let STORE_PAGES: {
@@ -21,6 +22,13 @@ declare let STORE_PAGES: {
21
22
  CUSTOM: string;
22
23
  };
23
24
 
25
+ type Locale = {
26
+ language: LanguageCode;
27
+ country: CountryCode;
28
+ label: string;
29
+ currency: CurrencyCode;
30
+ };
31
+ type Localizations = Record<string, Locale>;
24
32
  type TODO = any;
25
33
  declare module '@shopify/remix-oxygen' {
26
34
  interface AppLoadContext {
@@ -29,6 +37,7 @@ declare module '@shopify/remix-oxygen' {
29
37
  storefront: TODO;
30
38
  env: TODO;
31
39
  cart: TODO;
40
+ withCache?: TODO;
32
41
  }
33
42
  }
34
43
  type WeaverseLoaderArgs = LoaderArgs & {
@@ -70,11 +79,7 @@ interface HydrogenComponentProps<L = any> extends WeaverseElement {
70
79
  loaderData?: L;
71
80
  children?: React.JSX.Element[];
72
81
  }
73
- type I18nLocale = {
74
- country: string;
75
- currency: string;
76
- language: string;
77
- label: string;
82
+ type I18nLocale = Locale & {
78
83
  pathPrefix: string;
79
84
  };
80
85
  type WeaverseLoaderRequestInfo = {
@@ -108,8 +113,12 @@ type HydrogenProjectType = {
108
113
  config: HydrogenProjectConfig;
109
114
  [key: string]: any;
110
115
  };
116
+ type WeaverseThemeConfigs = {
117
+ schema: HydrogenThemeSchema;
118
+ countries: Localizations;
119
+ };
111
120
  type WeaverseInternal = {
112
- themeSchema: HydrogenThemeSchema;
121
+ themeConfigs: WeaverseThemeConfigs;
113
122
  pageAssignment: HydrogenPageAssignment;
114
123
  project: HydrogenProjectType;
115
124
  navigate: NavigateFunction;
@@ -213,11 +222,18 @@ type WeaverseLoaderConfigs = {
213
222
  locale?: string;
214
223
  handle?: string;
215
224
  };
225
+ type FetchProjectRequestBody = {
226
+ projectId: string;
227
+ url: string;
228
+ countries: Localizations;
229
+ i18n?: I18nLocale;
230
+ loaderConfigs?: WeaverseLoaderConfigs;
231
+ };
216
232
  declare global {
217
233
  interface Window {
218
234
  __weaverse: WeaverseHydrogen;
219
235
  __weaverses: WeaverseHydrogen[];
220
- __weaverseHydrogenThemeSchema: HydrogenThemeSchema;
236
+ __weaverseThemeConfigs: WeaverseThemeConfigs;
221
237
  }
222
238
  }
223
239
 
@@ -231,17 +247,22 @@ type FetchWithServerCacheParams = {
231
247
  */
232
248
  declare function fetchWithServerCache(params: FetchWithServerCacheParams): Promise<any>;
233
249
 
234
- declare function useThemeSettings(): (Record<string, any> | ((newSettings: any) => void))[];
250
+ declare function weaverseLoader(args: LoaderArgs, components: HydrogenComponent[], countries: Localizations, loaderConfigs?: WeaverseLoaderConfigs): Promise<WeaverseLoaderData | null>;
235
251
 
236
- declare function getSelectedProductOptions(request: Request): _shopify_hydrogen_react_storefront_api_types.SelectedOptionInput[];
252
+ declare function WeaverseStudio(): React.JSX.Element | null;
237
253
 
238
- declare function weaverseLoader(args: LoaderArgs, components: HydrogenComponent[], loaderConfigs?: WeaverseLoaderConfigs): Promise<WeaverseLoaderData | null>;
254
+ declare function getRequestQueries<T = Record<string, string | boolean>>(request: Request): T;
255
+ /**
256
+ * Check if the request is from Weaverse Studio.
257
+ * @param request Request
258
+ * @returns boolean
259
+ */
260
+ declare function studioCheck(request: Request): boolean;
239
261
 
240
- type StudioProps = {
241
- themeSchema: HydrogenThemeSchema;
242
- };
243
- declare function HydrogenStudio({ themeSchema }: StudioProps): React.JSX.Element | null;
262
+ declare function getSelectedProductOptions(request: Request): _shopify_hydrogen_react_storefront_api_types.SelectedOptionInput[];
263
+
264
+ declare function useThemeSettings(): (Record<string, any> | ((newSettings: any) => void))[];
244
265
 
245
266
  declare function WeaverseHydrogenRoot({ components, errorComponent: ErrorComponent, }: WeaverseHydrogenRootProps): React.JSX.Element;
246
267
 
247
- export { HydrogenComponent, HydrogenComponentData, HydrogenComponentInstance, HydrogenComponentPresets, HydrogenComponentProps, HydrogenComponentSchema, HydrogenElement, HydrogenPageAssignment, HydrogenPageConfigs, HydrogenPageData, HydrogenProjectConfig, HydrogenProjectType, HydrogenStudio, HydrogenThemeInfo, HydrogenThemeSchema, HydrogenToolbarAction, InspectorGroup, NavigateFunction, PageType, TODO, WeaverseHydrogen, WeaverseHydrogenRoot, WeaverseHydrogenRootProps, WeaverseInternal, WeaverseLoaderArgs, WeaverseLoaderConfigs, WeaverseLoaderData, WeaverseLoaderRequestInfo, WeaverseStorefrontData, fetchWithServerCache, getSelectedProductOptions, useThemeSettings, weaverseLoader };
268
+ export { FetchProjectRequestBody, HydrogenComponent, HydrogenComponentData, HydrogenComponentInstance, HydrogenComponentPresets, HydrogenComponentProps, HydrogenComponentSchema, HydrogenElement, HydrogenPageAssignment, HydrogenPageConfigs, HydrogenPageData, HydrogenProjectConfig, HydrogenProjectType, HydrogenThemeInfo, HydrogenThemeSchema, HydrogenToolbarAction, I18nLocale, InspectorGroup, Locale, Localizations, NavigateFunction, PageType, TODO, WeaverseHydrogen, WeaverseHydrogenRoot, WeaverseHydrogenRootProps, WeaverseInternal, WeaverseLoaderArgs, WeaverseLoaderConfigs, WeaverseLoaderData, WeaverseLoaderRequestInfo, WeaverseStorefrontData, WeaverseStudio, WeaverseThemeConfigs, fetchWithServerCache, getRequestQueries, getSelectedProductOptions, studioCheck, useThemeSettings, weaverseLoader };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import React, { ForwardRefExoticComponent } from 'react';
2
2
  import { LoaderArgs, AppLoadContext } from '@shopify/remix-oxygen';
3
3
  import { ElementData, ElementSchema, BasicInput, WeaverseElement, Weaverse, WeaverseItemStore } from '@weaverse/react';
4
4
  export * from '@weaverse/react';
5
+ import { LanguageCode, CountryCode, CurrencyCode } from '@shopify/hydrogen/storefront-api-types';
5
6
  import * as _shopify_hydrogen_react_storefront_api_types from '@shopify/hydrogen-react/storefront-api-types';
6
7
 
7
8
  declare let STORE_PAGES: {
@@ -21,6 +22,13 @@ declare let STORE_PAGES: {
21
22
  CUSTOM: string;
22
23
  };
23
24
 
25
+ type Locale = {
26
+ language: LanguageCode;
27
+ country: CountryCode;
28
+ label: string;
29
+ currency: CurrencyCode;
30
+ };
31
+ type Localizations = Record<string, Locale>;
24
32
  type TODO = any;
25
33
  declare module '@shopify/remix-oxygen' {
26
34
  interface AppLoadContext {
@@ -29,6 +37,7 @@ declare module '@shopify/remix-oxygen' {
29
37
  storefront: TODO;
30
38
  env: TODO;
31
39
  cart: TODO;
40
+ withCache?: TODO;
32
41
  }
33
42
  }
34
43
  type WeaverseLoaderArgs = LoaderArgs & {
@@ -70,11 +79,7 @@ interface HydrogenComponentProps<L = any> extends WeaverseElement {
70
79
  loaderData?: L;
71
80
  children?: React.JSX.Element[];
72
81
  }
73
- type I18nLocale = {
74
- country: string;
75
- currency: string;
76
- language: string;
77
- label: string;
82
+ type I18nLocale = Locale & {
78
83
  pathPrefix: string;
79
84
  };
80
85
  type WeaverseLoaderRequestInfo = {
@@ -108,8 +113,12 @@ type HydrogenProjectType = {
108
113
  config: HydrogenProjectConfig;
109
114
  [key: string]: any;
110
115
  };
116
+ type WeaverseThemeConfigs = {
117
+ schema: HydrogenThemeSchema;
118
+ countries: Localizations;
119
+ };
111
120
  type WeaverseInternal = {
112
- themeSchema: HydrogenThemeSchema;
121
+ themeConfigs: WeaverseThemeConfigs;
113
122
  pageAssignment: HydrogenPageAssignment;
114
123
  project: HydrogenProjectType;
115
124
  navigate: NavigateFunction;
@@ -213,11 +222,18 @@ type WeaverseLoaderConfigs = {
213
222
  locale?: string;
214
223
  handle?: string;
215
224
  };
225
+ type FetchProjectRequestBody = {
226
+ projectId: string;
227
+ url: string;
228
+ countries: Localizations;
229
+ i18n?: I18nLocale;
230
+ loaderConfigs?: WeaverseLoaderConfigs;
231
+ };
216
232
  declare global {
217
233
  interface Window {
218
234
  __weaverse: WeaverseHydrogen;
219
235
  __weaverses: WeaverseHydrogen[];
220
- __weaverseHydrogenThemeSchema: HydrogenThemeSchema;
236
+ __weaverseThemeConfigs: WeaverseThemeConfigs;
221
237
  }
222
238
  }
223
239
 
@@ -231,17 +247,22 @@ type FetchWithServerCacheParams = {
231
247
  */
232
248
  declare function fetchWithServerCache(params: FetchWithServerCacheParams): Promise<any>;
233
249
 
234
- declare function useThemeSettings(): (Record<string, any> | ((newSettings: any) => void))[];
250
+ declare function weaverseLoader(args: LoaderArgs, components: HydrogenComponent[], countries: Localizations, loaderConfigs?: WeaverseLoaderConfigs): Promise<WeaverseLoaderData | null>;
235
251
 
236
- declare function getSelectedProductOptions(request: Request): _shopify_hydrogen_react_storefront_api_types.SelectedOptionInput[];
252
+ declare function WeaverseStudio(): React.JSX.Element | null;
237
253
 
238
- declare function weaverseLoader(args: LoaderArgs, components: HydrogenComponent[], loaderConfigs?: WeaverseLoaderConfigs): Promise<WeaverseLoaderData | null>;
254
+ declare function getRequestQueries<T = Record<string, string | boolean>>(request: Request): T;
255
+ /**
256
+ * Check if the request is from Weaverse Studio.
257
+ * @param request Request
258
+ * @returns boolean
259
+ */
260
+ declare function studioCheck(request: Request): boolean;
239
261
 
240
- type StudioProps = {
241
- themeSchema: HydrogenThemeSchema;
242
- };
243
- declare function HydrogenStudio({ themeSchema }: StudioProps): React.JSX.Element | null;
262
+ declare function getSelectedProductOptions(request: Request): _shopify_hydrogen_react_storefront_api_types.SelectedOptionInput[];
263
+
264
+ declare function useThemeSettings(): (Record<string, any> | ((newSettings: any) => void))[];
244
265
 
245
266
  declare function WeaverseHydrogenRoot({ components, errorComponent: ErrorComponent, }: WeaverseHydrogenRootProps): React.JSX.Element;
246
267
 
247
- export { HydrogenComponent, HydrogenComponentData, HydrogenComponentInstance, HydrogenComponentPresets, HydrogenComponentProps, HydrogenComponentSchema, HydrogenElement, HydrogenPageAssignment, HydrogenPageConfigs, HydrogenPageData, HydrogenProjectConfig, HydrogenProjectType, HydrogenStudio, HydrogenThemeInfo, HydrogenThemeSchema, HydrogenToolbarAction, InspectorGroup, NavigateFunction, PageType, TODO, WeaverseHydrogen, WeaverseHydrogenRoot, WeaverseHydrogenRootProps, WeaverseInternal, WeaverseLoaderArgs, WeaverseLoaderConfigs, WeaverseLoaderData, WeaverseLoaderRequestInfo, WeaverseStorefrontData, fetchWithServerCache, getSelectedProductOptions, useThemeSettings, weaverseLoader };
268
+ export { FetchProjectRequestBody, HydrogenComponent, HydrogenComponentData, HydrogenComponentInstance, HydrogenComponentPresets, HydrogenComponentProps, HydrogenComponentSchema, HydrogenElement, HydrogenPageAssignment, HydrogenPageConfigs, HydrogenPageData, HydrogenProjectConfig, HydrogenProjectType, HydrogenThemeInfo, HydrogenThemeSchema, HydrogenToolbarAction, I18nLocale, InspectorGroup, Locale, Localizations, NavigateFunction, PageType, TODO, WeaverseHydrogen, WeaverseHydrogenRoot, WeaverseHydrogenRootProps, WeaverseInternal, WeaverseLoaderArgs, WeaverseLoaderConfigs, WeaverseLoaderData, WeaverseLoaderRequestInfo, WeaverseStorefrontData, WeaverseStudio, WeaverseThemeConfigs, fetchWithServerCache, getRequestQueries, getSelectedProductOptions, studioCheck, useThemeSettings, weaverseLoader };
package/dist/index.js CHANGED
@@ -31,10 +31,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/index.tsx
32
32
  var src_exports = {};
33
33
  __export(src_exports, {
34
- HydrogenStudio: () => HydrogenStudio,
35
34
  WeaverseHydrogenRoot: () => WeaverseHydrogenRoot,
35
+ WeaverseStudio: () => WeaverseStudio,
36
36
  fetchWithServerCache: () => fetchWithServerCache,
37
+ getRequestQueries: () => getRequestQueries,
37
38
  getSelectedProductOptions: () => getSelectedProductOptions,
39
+ studioCheck: () => studioCheck,
38
40
  useThemeSettings: () => useThemeSettings,
39
41
  weaverseLoader: () => weaverseLoader
40
42
  });
@@ -111,26 +113,21 @@ __reExport(src_exports, require("@weaverse/react"), module.exports);
111
113
 
112
114
  // src/fetch.ts
113
115
  var import_hydrogen = require("@shopify/hydrogen");
116
+ async function fetchWithServerCache(params) {
117
+ let { url, options = {}, context } = params;
118
+ let { storefront } = context;
119
+ let withCache = (0, import_hydrogen.createWithCache)(storefront);
120
+ let cacheKey = [url, options.body];
121
+ let data = await withCache(cacheKey, storefront.CacheShort(), async () => {
122
+ let response = await fetch(url, options);
123
+ if (!response.ok)
124
+ throw new Error("Something went wrong. Skipping cache.");
125
+ return await response.json();
126
+ });
127
+ return data;
128
+ }
114
129
 
115
130
  // src/utils.ts
116
- function hashKey(queryKey) {
117
- const rawKeys = Array.isArray(queryKey) ? queryKey : [queryKey];
118
- let hash = "";
119
- for (const key of rawKeys) {
120
- if (key != null) {
121
- if (typeof key === "object") {
122
- if (!!key.body && typeof key.body === "string") {
123
- hash += key.body;
124
- } else {
125
- hash += JSON.stringify(key);
126
- }
127
- } else {
128
- hash += key;
129
- }
130
- }
131
- }
132
- return hash;
133
- }
134
131
  function getRequestQueries(request) {
135
132
  let url = new URL(request.url);
136
133
  return Array.from(url.searchParams.entries()).reduce(
@@ -141,66 +138,22 @@ function getRequestQueries(request) {
141
138
  {}
142
139
  );
143
140
  }
144
-
145
- // src/fetch.ts
146
- var cacheControl = (0, import_hydrogen.generateCacheControlHeader)((0, import_hydrogen.CacheShort)());
147
- async function fetchWithServerCache(params) {
148
- let { url, options = {}, context } = params;
149
- let { storefront, waitUntil } = context;
150
- if (!storefront?.cache || !waitUntil) {
151
- return fetch(url, options);
152
- }
153
- let cacheUrl = new URL(url);
154
- cacheUrl.pathname = "/cache" + cacheUrl.pathname + hashKey([options.body]);
155
- let cacheKey = new Request(cacheUrl.toString());
156
- let response = await storefront.cache.match(cacheKey);
157
- if (!response) {
158
- response = await fetch(url, {
159
- ...options,
160
- headers: {
161
- "cache-control": cacheControl,
162
- ...options.headers
163
- }
164
- });
165
- waitUntil?.(storefront.cache.put(cacheKey, response.clone()));
166
- }
167
- return response;
168
- }
169
-
170
- // src/hooks/use-theme-settings.ts
171
- var import_react5 = require("@weaverse/react");
172
- function useThemeSettings() {
173
- let weaverse = (0, import_react5.useWeaverse)();
174
- let settings = weaverse?.internal?.project?.config?.theme;
175
- let updateSettings = (newSettings) => {
176
- weaverse.internal.project.config.theme = Object.assign(
177
- {},
178
- settings,
179
- newSettings
180
- );
181
- weaverse.triggerUpdate();
182
- };
183
- return [settings, updateSettings];
184
- }
185
-
186
- // src/hydrogen-wrappers.ts
187
- var import_hydrogen2 = require("@shopify/hydrogen");
188
- function getSelectedProductOptions(request) {
189
- let options = (0, import_hydrogen2.getSelectedProductOptions)(request);
190
- return options.filter(
191
- ({ name }) => name !== "isDesignMode" && !name.startsWith("weaverse")
141
+ function studioCheck(request) {
142
+ let queries = getRequestQueries(request);
143
+ let { weaverseProjectId, weaverseHost, isDesignMode, weaverseVersion } = queries;
144
+ return Boolean(
145
+ isDesignMode && weaverseProjectId && weaverseHost && weaverseVersion
192
146
  );
193
147
  }
194
148
 
195
149
  // src/loader.ts
196
- async function weaverseLoader(args, components, loaderConfigs) {
150
+ async function weaverseLoader(args, components, countries, loaderConfigs) {
197
151
  return new Promise(async (resolve, reject) => {
198
152
  try {
199
153
  let { request, context, params } = args;
200
- let i18n = context?.storefront?.i18n;
201
154
  let queries = getRequestQueries(request);
202
155
  let { WEAVERSE_PROJECT_ID, WEAVERSE_HOST } = context?.env || {};
203
- let { weaverseProjectId, weaverseHost, weaverseVersion, isDesignMode } = queries;
156
+ let { weaverseProjectId, weaverseHost } = queries;
204
157
  let projectId = weaverseProjectId || WEAVERSE_PROJECT_ID;
205
158
  weaverseHost = weaverseHost || WEAVERSE_HOST || "https://weaverse.io";
206
159
  if (!projectId) {
@@ -208,33 +161,19 @@ async function weaverseLoader(args, components, loaderConfigs) {
208
161
  `Missing Weaverse project's id. Try adding WEAVERSE_PROJECT_ID to your .env file then restart the server.`
209
162
  );
210
163
  }
211
- let configs = {
164
+ let i18n = context?.storefront?.i18n;
165
+ let reqBody = {
166
+ i18n,
167
+ countries,
212
168
  projectId,
213
- weaverseHost,
214
- weaverseVersion,
215
- isDesignMode,
216
- requestInfo: {
217
- i18n,
218
- params,
219
- queries,
220
- pathname: new URL(request.url).pathname,
221
- search: new URL(request.url).search
222
- }
169
+ loaderConfigs,
170
+ url: request.url
223
171
  };
224
- let res = await fetchWithServerCache({
172
+ let payload = await fetchWithServerCache({
225
173
  url: `${weaverseHost}/api/public/project`,
226
- options: {
227
- method: "POST",
228
- body: JSON.stringify({
229
- i18n,
230
- projectId,
231
- loaderConfigs,
232
- url: request.url
233
- })
234
- },
174
+ options: { method: "POST", body: JSON.stringify(reqBody) },
235
175
  context
236
176
  });
237
- let payload = await res.json();
238
177
  let { page, project, pageAssignment } = payload;
239
178
  if (!page || !project || !pageAssignment) {
240
179
  throw new Error(
@@ -242,30 +181,22 @@ async function weaverseLoader(args, components, loaderConfigs) {
242
181
  payload?.error || "Invalid Weaverse project payload!"
243
182
  );
244
183
  }
184
+ let configs = {
185
+ projectId,
186
+ weaverseHost,
187
+ weaverseVersion: queries.weaverseVersion,
188
+ isDesignMode: queries.isDesignMode,
189
+ requestInfo: {
190
+ i18n,
191
+ params,
192
+ queries,
193
+ pathname: new URL(request.url).pathname,
194
+ search: new URL(request.url).search
195
+ }
196
+ };
245
197
  if (page?.items) {
246
198
  let items = page.items;
247
- page.items = await Promise.all(
248
- items.map(async (itemData) => {
249
- let type = itemData.type;
250
- let { loader } = components.find(({ schema }) => schema?.type === type) || {};
251
- if (loader && typeof loader === "function") {
252
- try {
253
- return {
254
- ...itemData,
255
- loaderData: await loader({
256
- itemData,
257
- configs,
258
- ...args
259
- })
260
- };
261
- } catch (err) {
262
- console.log(`\u274C Loader run failed! Item: ${itemData}: ${err}`);
263
- return itemData;
264
- }
265
- }
266
- return itemData;
267
- })
268
- );
199
+ page.items = await withLoaderData(items, components, configs, args);
269
200
  }
270
201
  resolve({ page, configs, project, pageAssignment });
271
202
  } catch (err) {
@@ -274,39 +205,90 @@ async function weaverseLoader(args, components, loaderConfigs) {
274
205
  }
275
206
  });
276
207
  }
208
+ async function withLoaderData(items, components, configs, args) {
209
+ return await Promise.all(
210
+ items.map(async (itemData) => {
211
+ let type = itemData.type;
212
+ let { loader } = components.find(({ schema }) => schema?.type === type) || {};
213
+ if (loader && typeof loader === "function") {
214
+ try {
215
+ return {
216
+ ...itemData,
217
+ loaderData: await loader({
218
+ itemData,
219
+ configs,
220
+ ...args
221
+ })
222
+ };
223
+ } catch (err) {
224
+ console.log(`\u274C Loader run failed! Item: ${itemData}: ${err}`);
225
+ return itemData;
226
+ }
227
+ }
228
+ return itemData;
229
+ })
230
+ );
231
+ }
277
232
 
278
233
  // src/studio.tsx
279
- var import_react6 = require("@remix-run/react");
280
- var import_react7 = __toESM(require("react"));
281
- function HydrogenStudio({ themeSchema }) {
282
- let { search } = (0, import_react6.useLocation)();
283
- let params = new URLSearchParams(search);
284
- if (params) {
285
- let isDesignMode = params.get("isDesignMode") === "true";
234
+ var import_react5 = require("@remix-run/react");
235
+ var import_react6 = __toESM(require("react"));
236
+ function WeaverseStudio() {
237
+ let { search } = (0, import_react5.useLocation)();
238
+ let { weaverseThemeConfigs } = (0, import_react5.useLoaderData)();
239
+ if (weaverseThemeConfigs instanceof Promise) {
240
+ let params = new URLSearchParams(search);
286
241
  let weaverseHost = params.get("weaverseHost");
287
242
  let weaverseVersion = params.get("weaverseVersion");
288
- if (isDesignMode && weaverseHost && weaverseVersion) {
289
- return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement(
243
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.Suspense, null, /* @__PURE__ */ import_react6.default.createElement(import_react5.Await, { resolve: weaverseThemeConfigs }, (configs) => {
244
+ if (!configs)
245
+ return null;
246
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(
290
247
  "script",
291
248
  {
292
249
  src: `${weaverseHost}/assets/studio/hydrogen/index.js?v=${weaverseVersion}`,
293
250
  async: true
294
251
  }
295
- ), /* @__PURE__ */ import_react7.default.createElement(
252
+ ), /* @__PURE__ */ import_react6.default.createElement(
296
253
  "script",
297
254
  {
298
255
  dangerouslySetInnerHTML: {
299
- __html: `window.__weaverseHydrogenThemeSchema = ${JSON.stringify(
300
- themeSchema
256
+ __html: `window.__weaverseThemeConfigs = ${JSON.stringify(
257
+ configs
301
258
  )}`
302
259
  }
303
260
  }
304
261
  ));
305
- }
262
+ }));
306
263
  }
307
264
  return null;
308
265
  }
309
266
 
267
+ // src/hydrogen-wrappers.ts
268
+ var import_hydrogen2 = require("@shopify/hydrogen");
269
+ function getSelectedProductOptions(request) {
270
+ let options = (0, import_hydrogen2.getSelectedProductOptions)(request);
271
+ return options.filter(
272
+ ({ name }) => name !== "isDesignMode" && !name.startsWith("weaverse")
273
+ );
274
+ }
275
+
276
+ // src/hooks/use-theme-settings.ts
277
+ var import_react7 = require("@weaverse/react");
278
+ function useThemeSettings() {
279
+ let weaverse = (0, import_react7.useWeaverse)();
280
+ let settings = weaverse?.internal?.project?.config?.theme;
281
+ let updateSettings = (newSettings) => {
282
+ weaverse.internal.project.config.theme = Object.assign(
283
+ {},
284
+ settings,
285
+ newSettings
286
+ );
287
+ weaverse.triggerUpdate();
288
+ };
289
+ return [settings, updateSettings];
290
+ }
291
+
310
292
  // src/index.tsx
311
293
  function WeaverseHydrogenRoot({
312
294
  components,
@@ -349,10 +331,12 @@ function RenderWeaverseRoot(props) {
349
331
  }
350
332
  // Annotate the CommonJS export names for ESM import in node:
351
333
  0 && (module.exports = {
352
- HydrogenStudio,
353
334
  WeaverseHydrogenRoot,
335
+ WeaverseStudio,
354
336
  fetchWithServerCache,
337
+ getRequestQueries,
355
338
  getSelectedProductOptions,
339
+ studioCheck,
356
340
  useThemeSettings,
357
341
  weaverseLoader,
358
342
  ...require("@weaverse/react")
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/index.tsx
2
- import { Await, useLoaderData } from "@remix-run/react";
2
+ import { Await as Await2, useLoaderData as useLoaderData2 } from "@remix-run/react";
3
3
  import { WeaverseRoot } from "@weaverse/react";
4
- import React2, { Suspense } from "react";
4
+ import React2, { Suspense as Suspense2 } from "react";
5
5
  import { ErrorBoundary } from "react-error-boundary";
6
6
 
7
7
  // src/context.ts
@@ -70,27 +70,22 @@ function useStudio(weaverse) {
70
70
  export * from "@weaverse/react";
71
71
 
72
72
  // src/fetch.ts
73
- import { CacheShort, generateCacheControlHeader } from "@shopify/hydrogen";
73
+ import { createWithCache } from "@shopify/hydrogen";
74
+ async function fetchWithServerCache(params) {
75
+ let { url, options = {}, context } = params;
76
+ let { storefront } = context;
77
+ let withCache = createWithCache(storefront);
78
+ let cacheKey = [url, options.body];
79
+ let data = await withCache(cacheKey, storefront.CacheShort(), async () => {
80
+ let response = await fetch(url, options);
81
+ if (!response.ok)
82
+ throw new Error("Something went wrong. Skipping cache.");
83
+ return await response.json();
84
+ });
85
+ return data;
86
+ }
74
87
 
75
88
  // src/utils.ts
76
- function hashKey(queryKey) {
77
- const rawKeys = Array.isArray(queryKey) ? queryKey : [queryKey];
78
- let hash = "";
79
- for (const key of rawKeys) {
80
- if (key != null) {
81
- if (typeof key === "object") {
82
- if (!!key.body && typeof key.body === "string") {
83
- hash += key.body;
84
- } else {
85
- hash += JSON.stringify(key);
86
- }
87
- } else {
88
- hash += key;
89
- }
90
- }
91
- }
92
- return hash;
93
- }
94
89
  function getRequestQueries(request) {
95
90
  let url = new URL(request.url);
96
91
  return Array.from(url.searchParams.entries()).reduce(
@@ -101,66 +96,22 @@ function getRequestQueries(request) {
101
96
  {}
102
97
  );
103
98
  }
104
-
105
- // src/fetch.ts
106
- var cacheControl = generateCacheControlHeader(CacheShort());
107
- async function fetchWithServerCache(params) {
108
- let { url, options = {}, context } = params;
109
- let { storefront, waitUntil } = context;
110
- if (!storefront?.cache || !waitUntil) {
111
- return fetch(url, options);
112
- }
113
- let cacheUrl = new URL(url);
114
- cacheUrl.pathname = "/cache" + cacheUrl.pathname + hashKey([options.body]);
115
- let cacheKey = new Request(cacheUrl.toString());
116
- let response = await storefront.cache.match(cacheKey);
117
- if (!response) {
118
- response = await fetch(url, {
119
- ...options,
120
- headers: {
121
- "cache-control": cacheControl,
122
- ...options.headers
123
- }
124
- });
125
- waitUntil?.(storefront.cache.put(cacheKey, response.clone()));
126
- }
127
- return response;
128
- }
129
-
130
- // src/hooks/use-theme-settings.ts
131
- import { useWeaverse } from "@weaverse/react";
132
- function useThemeSettings() {
133
- let weaverse = useWeaverse();
134
- let settings = weaverse?.internal?.project?.config?.theme;
135
- let updateSettings = (newSettings) => {
136
- weaverse.internal.project.config.theme = Object.assign(
137
- {},
138
- settings,
139
- newSettings
140
- );
141
- weaverse.triggerUpdate();
142
- };
143
- return [settings, updateSettings];
144
- }
145
-
146
- // src/hydrogen-wrappers.ts
147
- import { getSelectedProductOptions as hydrogen_getSelectedProductOptions } from "@shopify/hydrogen";
148
- function getSelectedProductOptions(request) {
149
- let options = hydrogen_getSelectedProductOptions(request);
150
- return options.filter(
151
- ({ name }) => name !== "isDesignMode" && !name.startsWith("weaverse")
99
+ function studioCheck(request) {
100
+ let queries = getRequestQueries(request);
101
+ let { weaverseProjectId, weaverseHost, isDesignMode, weaverseVersion } = queries;
102
+ return Boolean(
103
+ isDesignMode && weaverseProjectId && weaverseHost && weaverseVersion
152
104
  );
153
105
  }
154
106
 
155
107
  // src/loader.ts
156
- async function weaverseLoader(args, components, loaderConfigs) {
108
+ async function weaverseLoader(args, components, countries, loaderConfigs) {
157
109
  return new Promise(async (resolve, reject) => {
158
110
  try {
159
111
  let { request, context, params } = args;
160
- let i18n = context?.storefront?.i18n;
161
112
  let queries = getRequestQueries(request);
162
113
  let { WEAVERSE_PROJECT_ID, WEAVERSE_HOST } = context?.env || {};
163
- let { weaverseProjectId, weaverseHost, weaverseVersion, isDesignMode } = queries;
114
+ let { weaverseProjectId, weaverseHost } = queries;
164
115
  let projectId = weaverseProjectId || WEAVERSE_PROJECT_ID;
165
116
  weaverseHost = weaverseHost || WEAVERSE_HOST || "https://weaverse.io";
166
117
  if (!projectId) {
@@ -168,33 +119,19 @@ async function weaverseLoader(args, components, loaderConfigs) {
168
119
  `Missing Weaverse project's id. Try adding WEAVERSE_PROJECT_ID to your .env file then restart the server.`
169
120
  );
170
121
  }
171
- let configs = {
122
+ let i18n = context?.storefront?.i18n;
123
+ let reqBody = {
124
+ i18n,
125
+ countries,
172
126
  projectId,
173
- weaverseHost,
174
- weaverseVersion,
175
- isDesignMode,
176
- requestInfo: {
177
- i18n,
178
- params,
179
- queries,
180
- pathname: new URL(request.url).pathname,
181
- search: new URL(request.url).search
182
- }
127
+ loaderConfigs,
128
+ url: request.url
183
129
  };
184
- let res = await fetchWithServerCache({
130
+ let payload = await fetchWithServerCache({
185
131
  url: `${weaverseHost}/api/public/project`,
186
- options: {
187
- method: "POST",
188
- body: JSON.stringify({
189
- i18n,
190
- projectId,
191
- loaderConfigs,
192
- url: request.url
193
- })
194
- },
132
+ options: { method: "POST", body: JSON.stringify(reqBody) },
195
133
  context
196
134
  });
197
- let payload = await res.json();
198
135
  let { page, project, pageAssignment } = payload;
199
136
  if (!page || !project || !pageAssignment) {
200
137
  throw new Error(
@@ -202,30 +139,22 @@ async function weaverseLoader(args, components, loaderConfigs) {
202
139
  payload?.error || "Invalid Weaverse project payload!"
203
140
  );
204
141
  }
142
+ let configs = {
143
+ projectId,
144
+ weaverseHost,
145
+ weaverseVersion: queries.weaverseVersion,
146
+ isDesignMode: queries.isDesignMode,
147
+ requestInfo: {
148
+ i18n,
149
+ params,
150
+ queries,
151
+ pathname: new URL(request.url).pathname,
152
+ search: new URL(request.url).search
153
+ }
154
+ };
205
155
  if (page?.items) {
206
156
  let items = page.items;
207
- page.items = await Promise.all(
208
- items.map(async (itemData) => {
209
- let type = itemData.type;
210
- let { loader } = components.find(({ schema }) => schema?.type === type) || {};
211
- if (loader && typeof loader === "function") {
212
- try {
213
- return {
214
- ...itemData,
215
- loaderData: await loader({
216
- itemData,
217
- configs,
218
- ...args
219
- })
220
- };
221
- } catch (err) {
222
- console.log(`\u274C Loader run failed! Item: ${itemData}: ${err}`);
223
- return itemData;
224
- }
225
- }
226
- return itemData;
227
- })
228
- );
157
+ page.items = await withLoaderData(items, components, configs, args);
229
158
  }
230
159
  resolve({ page, configs, project, pageAssignment });
231
160
  } catch (err) {
@@ -234,18 +163,44 @@ async function weaverseLoader(args, components, loaderConfigs) {
234
163
  }
235
164
  });
236
165
  }
166
+ async function withLoaderData(items, components, configs, args) {
167
+ return await Promise.all(
168
+ items.map(async (itemData) => {
169
+ let type = itemData.type;
170
+ let { loader } = components.find(({ schema }) => schema?.type === type) || {};
171
+ if (loader && typeof loader === "function") {
172
+ try {
173
+ return {
174
+ ...itemData,
175
+ loaderData: await loader({
176
+ itemData,
177
+ configs,
178
+ ...args
179
+ })
180
+ };
181
+ } catch (err) {
182
+ console.log(`\u274C Loader run failed! Item: ${itemData}: ${err}`);
183
+ return itemData;
184
+ }
185
+ }
186
+ return itemData;
187
+ })
188
+ );
189
+ }
237
190
 
238
191
  // src/studio.tsx
239
- import { useLocation } from "@remix-run/react";
240
- import React from "react";
241
- function HydrogenStudio({ themeSchema }) {
192
+ import { Await, useLoaderData, useLocation } from "@remix-run/react";
193
+ import React, { Suspense } from "react";
194
+ function WeaverseStudio() {
242
195
  let { search } = useLocation();
243
- let params = new URLSearchParams(search);
244
- if (params) {
245
- let isDesignMode = params.get("isDesignMode") === "true";
196
+ let { weaverseThemeConfigs } = useLoaderData();
197
+ if (weaverseThemeConfigs instanceof Promise) {
198
+ let params = new URLSearchParams(search);
246
199
  let weaverseHost = params.get("weaverseHost");
247
200
  let weaverseVersion = params.get("weaverseVersion");
248
- if (isDesignMode && weaverseHost && weaverseVersion) {
201
+ return /* @__PURE__ */ React.createElement(Suspense, null, /* @__PURE__ */ React.createElement(Await, { resolve: weaverseThemeConfigs }, (configs) => {
202
+ if (!configs)
203
+ return null;
249
204
  return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
250
205
  "script",
251
206
  {
@@ -256,27 +211,52 @@ function HydrogenStudio({ themeSchema }) {
256
211
  "script",
257
212
  {
258
213
  dangerouslySetInnerHTML: {
259
- __html: `window.__weaverseHydrogenThemeSchema = ${JSON.stringify(
260
- themeSchema
214
+ __html: `window.__weaverseThemeConfigs = ${JSON.stringify(
215
+ configs
261
216
  )}`
262
217
  }
263
218
  }
264
219
  ));
265
- }
220
+ }));
266
221
  }
267
222
  return null;
268
223
  }
269
224
 
225
+ // src/hydrogen-wrappers.ts
226
+ import { getSelectedProductOptions as hydrogen_getSelectedProductOptions } from "@shopify/hydrogen";
227
+ function getSelectedProductOptions(request) {
228
+ let options = hydrogen_getSelectedProductOptions(request);
229
+ return options.filter(
230
+ ({ name }) => name !== "isDesignMode" && !name.startsWith("weaverse")
231
+ );
232
+ }
233
+
234
+ // src/hooks/use-theme-settings.ts
235
+ import { useWeaverse } from "@weaverse/react";
236
+ function useThemeSettings() {
237
+ let weaverse = useWeaverse();
238
+ let settings = weaverse?.internal?.project?.config?.theme;
239
+ let updateSettings = (newSettings) => {
240
+ weaverse.internal.project.config.theme = Object.assign(
241
+ {},
242
+ settings,
243
+ newSettings
244
+ );
245
+ weaverse.triggerUpdate();
246
+ };
247
+ return [settings, updateSettings];
248
+ }
249
+
270
250
  // src/index.tsx
271
251
  function WeaverseHydrogenRoot({
272
252
  components,
273
253
  errorComponent: ErrorComponent
274
254
  }) {
275
- let data = useLoaderData();
255
+ let data = useLoaderData2();
276
256
  let weaverseDataFromLoader = data?.weaverseData;
277
257
  if (weaverseDataFromLoader) {
278
258
  if (weaverseDataFromLoader instanceof Promise) {
279
- return /* @__PURE__ */ React2.createElement(ErrorBoundary, { fallbackRender: ErrorComponent }, /* @__PURE__ */ React2.createElement(Suspense, null, /* @__PURE__ */ React2.createElement(Await, { resolve: weaverseDataFromLoader }, (resolvedData) => {
259
+ return /* @__PURE__ */ React2.createElement(ErrorBoundary, { fallbackRender: ErrorComponent }, /* @__PURE__ */ React2.createElement(Suspense2, null, /* @__PURE__ */ React2.createElement(Await2, { resolve: weaverseDataFromLoader }, (resolvedData) => {
280
260
  return /* @__PURE__ */ React2.createElement(
281
261
  RenderWeaverseRoot,
282
262
  {
@@ -308,10 +288,12 @@ function RenderWeaverseRoot(props) {
308
288
  return /* @__PURE__ */ React2.createElement(WeaverseRoot, { context: weaverse });
309
289
  }
310
290
  export {
311
- HydrogenStudio,
312
291
  WeaverseHydrogenRoot,
292
+ WeaverseStudio,
313
293
  fetchWithServerCache,
294
+ getRequestQueries,
314
295
  getSelectedProductOptions,
296
+ studioCheck,
315
297
  useThemeSettings,
316
298
  weaverseLoader
317
299
  };
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.3",
2
+ "version": "1.1.4",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -34,10 +34,10 @@
34
34
  "dependencies": {
35
35
  "@remix-run/react": "1.19.1",
36
36
  "@shopify/hydrogen": "2023.7.1",
37
- "@weaverse/react": "1.1.3",
37
+ "@weaverse/react": "1.1.4",
38
38
  "react-error-boundary": "^4.0.10"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@shopify/remix-oxygen": "^1.1.2"
42
42
  }
43
- }
43
+ }