@swell/apps-sdk 1.0.162 → 1.0.164

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.js CHANGED
@@ -7199,6 +7199,7 @@
7199
7199
  });
7200
7200
  var NULL_VALUE = "__NULL__";
7201
7201
  var SWR_PROMISE_MAP = /* @__PURE__ */ new Map();
7202
+ var FETCH_PROMISE_MAP = /* @__PURE__ */ new Map();
7202
7203
  var Cache = class {
7203
7204
  client;
7204
7205
  workerCtx;
@@ -7211,8 +7212,30 @@
7211
7212
  ...options
7212
7213
  });
7213
7214
  }
7214
- async fetch(key, fetchFn, ttl) {
7215
- return this.client.wrap(key, fetchFn, ttl);
7215
+ /**
7216
+ * Always fetches fresh data and updates cache
7217
+ * Deduplicates concurrent requests with the same key
7218
+ *
7219
+ * @param key Cache key
7220
+ * @param fetchFn Function to fetch fresh data
7221
+ * @param ttl Time to live in milliseconds (default: DEFAULT_SWR_TTL)
7222
+ * @param isCacheable Whether to store result in cache (default: true)
7223
+ */
7224
+ async fetch(key, fetchFn, ttl = DEFAULT_SWR_TTL, isCacheable = true) {
7225
+ let promise = FETCH_PROMISE_MAP.get(key);
7226
+ if (!promise) {
7227
+ promise = Promise.resolve().then(fetchFn).then(resolveAsyncResources).then(async (value) => {
7228
+ const isNull = value === null || value === void 0;
7229
+ if (isCacheable) {
7230
+ await this.client.set(key, isNull ? NULL_VALUE : value, ttl);
7231
+ }
7232
+ return value;
7233
+ }).finally(() => {
7234
+ FETCH_PROMISE_MAP.delete(key);
7235
+ });
7236
+ FETCH_PROMISE_MAP.set(key, promise);
7237
+ }
7238
+ return await promise;
7216
7239
  }
7217
7240
  /**
7218
7241
  * Fetch cache using SWR (stale-while-revalidate)
@@ -8320,18 +8343,24 @@
8320
8343
  }
8321
8344
  return params;
8322
8345
  }
8346
+ /**
8347
+ * Checks if cache bypass is requested via X-Cache-Bypass header
8348
+ */
8349
+ shouldBypassCache() {
8350
+ return this.headers?.["x-cache-bypass"] === "revalidation";
8351
+ }
8323
8352
  /**
8324
8353
  * Fetches a resource.
8325
8354
  * First attempts to fetch from cache.
8326
8355
  */
8327
8356
  async getCachedResource(key, args, handler, isCacheble = true) {
8328
8357
  const cacheKey = getCacheKey(key, [this.instanceId, args]);
8329
- return this.getResourceCache().fetchSWR(
8330
- cacheKey,
8331
- handler,
8332
- void 0,
8333
- isCacheble
8334
- );
8358
+ const cache = this.getResourceCache();
8359
+ if (this.shouldBypassCache()) {
8360
+ return cache.fetch(cacheKey, handler, void 0, isCacheble);
8361
+ } else {
8362
+ return cache.fetchSWR(cacheKey, handler, void 0, isCacheble);
8363
+ }
8335
8364
  }
8336
8365
  async getAppSettings() {
8337
8366
  const settings = await this.get(
@@ -8498,11 +8527,17 @@
8498
8527
  data,
8499
8528
  opt
8500
8529
  ]);
8501
- return this.getRequestCache().fetchSWR(key, () => {
8530
+ const cache = this.getRequestCache();
8531
+ const fetchFn = () => {
8502
8532
  const requestUrl = id ? `${url}/${id}` : url;
8503
8533
  logger.debug("[SDK] Cacheable API request", { url: requestUrl, key });
8504
8534
  return storefrontRequest(method, url, id, data, opt);
8505
- });
8535
+ };
8536
+ if (this.shouldBypassCache()) {
8537
+ return cache.fetch(key, fetchFn);
8538
+ } else {
8539
+ return cache.fetchSWR(key, fetchFn);
8540
+ }
8506
8541
  }
8507
8542
  switch (method) {
8508
8543
  case "delete":
@@ -15901,7 +15936,7 @@ ${formattedMessage}`;
15901
15936
  function joinAddressLines(...props) {
15902
15937
  return props.filter(Boolean).join("\n");
15903
15938
  }
15904
- function ShopifyCountry(_instance2, countryCode) {
15939
+ function ShopifyCountry(_instance, countryCode) {
15905
15940
  const currencyCode = getCurrencyByCountry(countryCode) || "USD";
15906
15941
  return new ShopifyResource(
15907
15942
  {
@@ -16234,7 +16269,7 @@ ${formattedMessage}`;
16234
16269
  }
16235
16270
 
16236
16271
  // src/compatibility/shopify-objects/font.ts
16237
- function ShopifyFont(_instance2, font) {
16272
+ function ShopifyFont(_instance, font) {
16238
16273
  if (font instanceof ShopifyResource) {
16239
16274
  return font.clone();
16240
16275
  }
@@ -16245,7 +16280,7 @@ ${formattedMessage}`;
16245
16280
  family: font.family,
16246
16281
  style: font.style,
16247
16282
  "system?": font.system,
16248
- variants: font.variants.map((variant) => ShopifyFont(_instance2, variant)),
16283
+ variants: font.variants.map((variant) => ShopifyFont(_instance, variant)),
16249
16284
  weight: font.weight
16250
16285
  });
16251
16286
  }
@@ -16258,7 +16293,7 @@ ${formattedMessage}`;
16258
16293
  })
16259
16294
  }
16260
16295
  };
16261
- function ShopifyForm(_instance2, form) {
16296
+ function ShopifyForm(_instance, form) {
16262
16297
  if (form instanceof ShopifyResource) {
16263
16298
  return form.clone();
16264
16299
  }
@@ -16555,7 +16590,7 @@ ${formattedMessage}`;
16555
16590
  }
16556
16591
 
16557
16592
  // src/compatibility/shopify-objects/page.ts
16558
- function ShopifyPage(_instance2, page) {
16593
+ function ShopifyPage(_instance, page) {
16559
16594
  if (page instanceof ShopifyResource) {
16560
16595
  return page.clone();
16561
16596
  }
@@ -17767,7 +17802,7 @@ ${injects.join("\n")}<\/script>`;
17767
17802
  };
17768
17803
 
17769
17804
  // src/compatibility/shopify-objects/template.ts
17770
- function ShopifyTemplate(_instance2, template) {
17805
+ function ShopifyTemplate(_instance, template) {
17771
17806
  return new ShopifyResource(
17772
17807
  {
17773
17808
  directory: template.path,
@@ -22344,9 +22379,7 @@ ${this.shopifyCompatibility.getContentForHeader()}`;
22344
22379
  preview: { ttl: 10, swr: 60 * 60 * 24 * 7 }
22345
22380
  // 10s TTL, 1 week SWR
22346
22381
  },
22347
- pathRules: [
22348
- { path: "/checkout/*", skip: true }
22349
- ]
22382
+ pathRules: [{ path: "/checkout/*", skip: true }]
22350
22383
  };
22351
22384
  var HtmlCache = class {
22352
22385
  epoch;
@@ -22436,6 +22469,16 @@ ${this.shopifyCompatibility.getContentForHeader()}`;
22436
22469
  const ttl = this.getTTLForRequest(request);
22437
22470
  const swr = this.getSWRForRequest(request);
22438
22471
  const body = await response.text();
22472
+ if (!body || body.trim().length === 0) {
22473
+ logger.warn(
22474
+ "[SDK Html-cache] put skipped, empty or minimal response body",
22475
+ {
22476
+ trace,
22477
+ bodyLength: body.length
22478
+ }
22479
+ );
22480
+ return;
22481
+ }
22439
22482
  const cacheTimeISO = (/* @__PURE__ */ new Date()).toISOString();
22440
22483
  const headers = this.normalizeHeaders(response.headers);
22441
22484
  const entry = {
@@ -22493,7 +22536,7 @@ ${this.shopifyCompatibility.getContentForHeader()}`;
22493
22536
  }
22494
22537
  buildClientResponse(entry, isStale, age) {
22495
22538
  const headers = new Headers(entry.headers);
22496
- headers.set("Cache-Control", "public, max-age=0, must-revalidate");
22539
+ headers.set("Cache-Control", "public, max-age=1, must-revalidate");
22497
22540
  headers.set(
22498
22541
  "Cloudflare-CDN-Cache-Control",
22499
22542
  `public, s-maxage=${entry.ttl}, stale-while-revalidate=${entry.swr}, stale-if-error=60`
@@ -22588,7 +22631,7 @@ ${this.shopifyCompatibility.getContentForHeader()}`;
22588
22631
  const accept = headers.get("accept") || "";
22589
22632
  const versionFactors = {
22590
22633
  store: headers.get("swell-storefront-id") || "",
22591
- app: (headers.get("swell-app-id") || "") + "@" + (swellData["swell-app-version"] || ""),
22634
+ app: (headers.get("swell-app-id") || "") + "@" + (headers.get("host") || ""),
22592
22635
  auth: headers.get("swell-access-token") || "",
22593
22636
  theme: headers.get("swell-theme-version-hash") || "",
22594
22637
  modified: headers.get("swell-cache-modified") || "",
@@ -22854,7 +22897,6 @@ ${this.shopifyCompatibility.getContentForHeader()}`;
22854
22897
  statusText: entry.statusText,
22855
22898
  headers
22856
22899
  });
22857
- await cache.delete(request);
22858
22900
  await cache.put(request, response);
22859
22901
  }
22860
22902
  async delete(key) {
@@ -22865,19 +22907,15 @@ ${this.shopifyCompatibility.getContentForHeader()}`;
22865
22907
  };
22866
22908
 
22867
22909
  // src/cache/html-cache/html-cache-factory.ts
22868
- var _instance = null;
22869
22910
  function getHtmlCache(env, cacheRules) {
22870
22911
  const epoch = env?.HTML_CACHE_EPOCH;
22871
22912
  if (typeof epoch !== "string" || !epoch) return null;
22872
- if (_instance) return _instance;
22873
22913
  const kv = env?.NAMESPACE;
22874
22914
  const rules = cacheRules || env?.HTML_CACHE_RULES;
22875
22915
  if (env?.HTML_CACHE_BACKEND !== "worker" && kv) {
22876
- _instance = new HtmlCache(epoch, new KVCacheBackend(kv), rules);
22877
- return _instance;
22916
+ return new HtmlCache(epoch, new KVCacheBackend(kv), rules);
22878
22917
  }
22879
- _instance = new HtmlCache(epoch, new WorkerCacheBackend(epoch), rules);
22880
- return _instance;
22918
+ return new HtmlCache(epoch, new WorkerCacheBackend(epoch), rules);
22881
22919
  }
22882
22920
  })();
22883
22921
  //# sourceMappingURL=index.js.map