@swell/apps-sdk 1.0.160 → 1.0.161

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.cjs CHANGED
@@ -46,6 +46,7 @@ __export(index_exports, {
46
46
  DeferredShopifyResource: () => DeferredShopifyResource,
47
47
  FILE_DATA_INCLUDE_QUERY: () => FILE_DATA_INCLUDE_QUERY,
48
48
  GEO_DATA: () => GEO_DATA,
49
+ HtmlCache: () => HtmlCache,
49
50
  LANG_TO_COUNTRY_CODES: () => LANG_TO_COUNTRY_CODES,
50
51
  LiquidSwell: () => LiquidSwell30,
51
52
  MAX_QUERY_PAGE_LIMIT: () => MAX_QUERY_PAGE_LIMIT,
@@ -93,7 +94,6 @@ __export(index_exports, {
93
94
  ThemeForm: () => ThemeForm,
94
95
  ThemeFormErrors: () => ThemeFormErrors,
95
96
  VariantResource: () => VariantResource,
96
- WorkerHtmlCache: () => WorkerHtmlCache,
97
97
  adaptShopifyFontData: () => adaptShopifyFontData,
98
98
  adaptShopifyFormData: () => adaptShopifyFormData,
99
99
  adaptShopifyMenuData: () => adaptShopifyMenuData,
@@ -121,6 +121,7 @@ __export(index_exports, {
121
121
  getEasyblocksComponentDefinitions: () => getEasyblocksComponentDefinitions,
122
122
  getEasyblocksPagePropsWithConfigs: () => getEasyblocksPagePropsWithConfigs,
123
123
  getEasyblocksPageTemplate: () => getEasyblocksPageTemplate,
124
+ getHtmlCache: () => getHtmlCache,
124
125
  getKVFlavor: () => getKVFlavor,
125
126
  getLayoutSectionGroups: () => getLayoutSectionGroups,
126
127
  getMenuItemStorefrontUrl: () => getMenuItemStorefrontUrl,
@@ -7437,12 +7438,7 @@ var ThemeCache = class extends Cache {
7437
7438
  }
7438
7439
  };
7439
7440
 
7440
- // src/cache/theme-file-storage.ts
7441
- var import_bluebird2 = __toESM(require("bluebird"), 1);
7442
-
7443
7441
  // src/cache/kv-variety.ts
7444
- var import_bluebird = __toESM(require("bluebird"), 1);
7445
- var { Promise: Promise2 } = import_bluebird.default;
7446
7442
  var CFKV = class {
7447
7443
  constructor(kv) {
7448
7444
  this.kv = kv;
@@ -7474,13 +7470,11 @@ var MiniflareKV = class {
7474
7470
  return /* @__PURE__ */ new Map();
7475
7471
  }
7476
7472
  const result = /* @__PURE__ */ new Map();
7477
- await Promise2.map(
7478
- keys,
7479
- async (key) => {
7473
+ await Promise.all(
7474
+ keys.map(async (key) => {
7480
7475
  const value = await this.kv.get(key, "text");
7481
7476
  result.set(key, value);
7482
- },
7483
- { concurrency: 50 }
7477
+ })
7484
7478
  );
7485
7479
  return result;
7486
7480
  }
@@ -7512,16 +7506,13 @@ function createClientKV(env, flavor = "cf") {
7512
7506
  return new MemoryKV();
7513
7507
  }
7514
7508
 
7515
- // src/cache/theme-file-storage.ts
7516
- var { Promise: Promise3 } = import_bluebird2.default;
7517
- var ThemeFileStorage = class {
7509
+ // src/cache/theme-file-cache.ts
7510
+ var ThemeFileCache = class {
7518
7511
  kv;
7519
- maxConcurrency;
7520
7512
  maxBatchSize = 20 * 1024 * 1024;
7521
7513
  // 20MB safety margin
7522
7514
  constructor(env, flavor = "cf") {
7523
7515
  this.kv = createClientKV(env, flavor);
7524
- this.maxConcurrency = flavor === "miniflare" ? 50 : 6;
7525
7516
  }
7526
7517
  /**
7527
7518
  * Build a KV storage key from a file hash
@@ -7614,10 +7605,8 @@ var ThemeFileStorage = class {
7614
7605
  totalSize,
7615
7606
  trace
7616
7607
  });
7617
- const results = await Promise3.map(
7618
- batches,
7619
- (batch) => this.loadBatch(batch),
7620
- { concurrency: Math.min(this.maxConcurrency, batches.length) }
7608
+ const results = await Promise.all(
7609
+ batches.map((batch) => this.loadBatch(batch))
7621
7610
  );
7622
7611
  const mergedConfigs = this.mergeResults(configs, results);
7623
7612
  const loadedCount = mergedConfigs.filter((c) => c.file_data).length;
@@ -7682,10 +7671,8 @@ var ThemeFileStorage = class {
7682
7671
  }
7683
7672
  const existing = /* @__PURE__ */ new Set();
7684
7673
  const batches = this.planGetBatches(configs);
7685
- const results = await Promise3.map(
7686
- batches,
7687
- (batch) => this.kv.get(batch.keys),
7688
- { concurrency: this.maxConcurrency }
7674
+ const results = await Promise.all(
7675
+ batches.map((batch) => this.kv.get(batch.keys))
7689
7676
  );
7690
7677
  for (const batchResult of results) {
7691
7678
  for (const [key, value] of batchResult.entries()) {
@@ -7749,15 +7736,13 @@ var ThemeFileStorage = class {
7749
7736
  skippedExisting: existing.size,
7750
7737
  trace
7751
7738
  });
7752
- await Promise3.map(
7753
- toWrite,
7754
- async (config) => {
7739
+ await Promise.all(
7740
+ toWrite.map(async (config) => {
7755
7741
  const key = this.buildKey(config.hash);
7756
7742
  const metadata = config.file?.content_type ? { content_type: config.file.content_type } : void 0;
7757
- await this.kv.put(key, config.file_data, metadata);
7743
+ await this.kv.put(key, config.file_data, { metadata });
7758
7744
  result.written++;
7759
- },
7760
- { concurrency: this.maxConcurrency }
7745
+ })
7761
7746
  );
7762
7747
  }
7763
7748
  logger.info("[ThemeFileStorage] Put files complete", {
@@ -7771,378 +7756,6 @@ var ThemeFileStorage = class {
7771
7756
  }
7772
7757
  };
7773
7758
 
7774
- // src/cache/constants.ts
7775
- var SECOND = 1e3;
7776
- var MINUTE = 60 * SECOND;
7777
- var HOUR = 60 * MINUTE;
7778
- var DAY = 24 * HOUR;
7779
- var YEAR = 365 * DAY;
7780
- var SHORT_TTL = 5 * SECOND;
7781
-
7782
- // src/cache/worker-html-cache.ts
7783
- var CACHE_NAME = "swell-html-v0";
7784
- var CACHE_KEY_ORIGIN = "https://cache.swell.store";
7785
- var TTL_CONFIG = {
7786
- LIVE: {
7787
- DEFAULT: 20,
7788
- HOME: 20,
7789
- PRODUCT: 20,
7790
- COLLECTION: 20,
7791
- PAGE: 20,
7792
- BLOG: 20,
7793
- SWR: 180
7794
- },
7795
- PREVIEW: {
7796
- DEFAULT: 20,
7797
- HOME: 20,
7798
- PRODUCT: 20,
7799
- COLLECTION: 20,
7800
- PAGE: 20,
7801
- BLOG: 20,
7802
- SWR: 180
7803
- }
7804
- };
7805
- var WorkerHtmlCache = class {
7806
- epoch;
7807
- constructor(epoch) {
7808
- this.epoch = epoch;
7809
- }
7810
- async get(request) {
7811
- const trace = createTraceId();
7812
- if (request.method !== "GET") {
7813
- logger.debug("[SDK Html-cache] non-cacheable", { trace });
7814
- return { found: false, cacheable: false };
7815
- }
7816
- if (!this.isCacheable(request)) {
7817
- logger.debug("[SDK Html-cache] non-cacheable", { trace });
7818
- return { found: false, cacheable: false };
7819
- }
7820
- try {
7821
- const cache = await caches.open(CACHE_NAME + this.epoch);
7822
- const cacheKey = this.buildCacheKey(request);
7823
- const cached = await cache.match(cacheKey);
7824
- if (!cached) {
7825
- logger.debug("[SDK Html-cache] cacheable, MISS", { trace });
7826
- return { found: false, cacheable: true };
7827
- }
7828
- const age = this.getResponseAge(cached);
7829
- const ttl = parseInt(cached.headers.get("X-Original-TTL") || "") || this.getTTLForRequest(request);
7830
- const swr = parseInt(cached.headers.get("X-Original-SWR") || "") || this.getSWRForRequest(request);
7831
- const isStale = age >= ttl;
7832
- const isExpired = age >= ttl + swr;
7833
- if (!isExpired) {
7834
- logger.debug("[SDK Html-cache] cacheable, HIT", {
7835
- stale: isStale,
7836
- age,
7837
- trace
7838
- });
7839
- const clientResponse = this.buildClientResponse(
7840
- cached,
7841
- ttl,
7842
- swr,
7843
- isStale,
7844
- age
7845
- );
7846
- return {
7847
- found: true,
7848
- stale: isStale,
7849
- response: clientResponse,
7850
- cacheable: true,
7851
- age: Math.floor(age)
7852
- };
7853
- }
7854
- logger.debug("[SDK Html-cache] cacheable, hit, expired", { trace });
7855
- return { found: false, cacheable: true };
7856
- } catch (_) {
7857
- logger.warn("[SDK Html-cache] no get support", { trace });
7858
- return null;
7859
- }
7860
- }
7861
- // 304 support
7862
- async getWithConditionals(request) {
7863
- const result = await this.get(request);
7864
- if (!result?.found || result.stale) {
7865
- return result;
7866
- }
7867
- const ifModifiedSince = request.headers.get("If-Modified-Since");
7868
- const ifNoneMatch = request.headers.get("If-None-Match");
7869
- if ((ifModifiedSince || ifNoneMatch) && result.response) {
7870
- const lastModified = result.response.headers.get("Last-Modified");
7871
- const etag = result.response.headers.get("ETag");
7872
- if (this.checkNotModified(ifModifiedSince, ifNoneMatch, lastModified, etag)) {
7873
- result.notModified = true;
7874
- result.conditional304 = new Response(null, {
7875
- status: 304,
7876
- headers: {
7877
- "Last-Modified": lastModified || "",
7878
- ETag: etag || "",
7879
- "Cache-Control": result.response.headers.get("Cache-Control") || "",
7880
- "Cloudflare-CDN-Cache-Control": result.response.headers.get("Cloudflare-CDN-Cache-Control") || "",
7881
- "X-Cache-Status": "HIT-304"
7882
- }
7883
- });
7884
- }
7885
- }
7886
- return result;
7887
- }
7888
- checkNotModified(ifModifiedSince, ifNoneMatch, lastModified, etag) {
7889
- if (ifNoneMatch && etag) {
7890
- return ifNoneMatch === etag;
7891
- }
7892
- if (ifModifiedSince && lastModified) {
7893
- const ifModDate = new Date(ifModifiedSince);
7894
- const lastModDate = new Date(lastModified);
7895
- return !isNaN(ifModDate.getTime()) && !isNaN(lastModDate.getTime()) && ifModDate >= lastModDate;
7896
- }
7897
- return false;
7898
- }
7899
- createRevalidationRequest(request) {
7900
- const headers = new Headers(request.headers);
7901
- headers.set("X-Cache-Bypass", "revalidation");
7902
- headers.delete("If-None-Match");
7903
- headers.delete("If-Modified-Since");
7904
- headers.delete("Cache-Control");
7905
- headers.delete("Pragma");
7906
- return new Request(request.url, {
7907
- method: "GET",
7908
- headers
7909
- });
7910
- }
7911
- async put(request, response) {
7912
- const trace = createTraceId();
7913
- if (request.method !== "GET" || !response.ok) {
7914
- logger.debug("[SDK Html-cache] put skipped", { trace });
7915
- return;
7916
- }
7917
- if (!this.isCacheable(request) || !this.isResponseCacheable(response)) {
7918
- logger.debug("[SDK Html-cache] put skipped, non-cacheable", {
7919
- trace
7920
- });
7921
- return;
7922
- }
7923
- try {
7924
- const cache = await caches.open(CACHE_NAME + this.epoch);
7925
- const cacheKey = this.buildCacheKey(request);
7926
- await cache.delete(cacheKey);
7927
- const ttl = this.getTTLForRequest(request);
7928
- const swr = this.getSWRForRequest(request);
7929
- const headers = new Headers(response.headers);
7930
- const existingCacheControl = response.headers.get("Cache-Control");
7931
- if (!existingCacheControl || existingCacheControl === "public") {
7932
- const internalMaxAge = ttl + swr;
7933
- headers.set("Cache-Control", `public, max-age=${internalMaxAge}`);
7934
- }
7935
- const cacheTime = (/* @__PURE__ */ new Date()).toISOString();
7936
- headers.set("X-Cache-Time", cacheTime);
7937
- headers.set("X-Original-TTL", ttl.toString());
7938
- headers.set("X-Original-SWR", swr.toString());
7939
- if (!headers.get("Last-Modified")) {
7940
- headers.set("Last-Modified", new Date(cacheTime).toUTCString());
7941
- }
7942
- const cacheableResponse = new Response(response.body, {
7943
- status: response.status,
7944
- statusText: response.statusText,
7945
- headers
7946
- });
7947
- await cache.put(cacheKey, cacheableResponse);
7948
- logger.debug("[SDK Html-cache] put done", { trace });
7949
- } catch (_) {
7950
- logger.warn("[SDK Html-cache] no put support", { trace });
7951
- }
7952
- }
7953
- buildClientResponse(cachedResponse, ttl, swr, isStale, age) {
7954
- const headers = new Headers(cachedResponse.headers);
7955
- headers.set(
7956
- "Cache-Control",
7957
- `public, max-age=${ttl}, stale-while-revalidate=${swr}`
7958
- );
7959
- headers.set(
7960
- "Cloudflare-CDN-Cache-Control",
7961
- `public, s-maxage=${ttl}, stale-while-revalidate=${swr}, stale-if-error=60`
7962
- );
7963
- const cacheTime = headers.get("X-Cache-Time");
7964
- if (cacheTime) {
7965
- const lastModified = new Date(cacheTime).toUTCString();
7966
- headers.set("Last-Modified", lastModified);
7967
- }
7968
- headers.set("X-Cache-Status", isStale ? "STALE" : "HIT");
7969
- headers.set("X-Cache-Age", Math.floor(age).toString());
7970
- headers.delete("X-Original-TTL");
7971
- headers.delete("X-Original-SWR");
7972
- headers.delete("X-Cache-Time");
7973
- return new Response(cachedResponse.body, {
7974
- status: cachedResponse.status,
7975
- statusText: cachedResponse.statusText,
7976
- headers
7977
- });
7978
- }
7979
- buildCacheKey(request) {
7980
- const url = new URL(request.url);
7981
- const versionHash = this.generateVersionHash(request.headers);
7982
- const normalizedQuery = this.normalizeSearchParams(url.searchParams);
7983
- const cacheKeyPath = `${versionHash}${url.pathname}`;
7984
- const keyUrl = new URL(`${CACHE_KEY_ORIGIN}${cacheKeyPath}`);
7985
- if (normalizedQuery) {
7986
- keyUrl.search = `?${normalizedQuery}`;
7987
- }
7988
- const sanitizedHeaders = this.sanitizeHeaders(request.headers);
7989
- return new Request(keyUrl.toString(), {
7990
- method: "GET",
7991
- headers: sanitizedHeaders
7992
- });
7993
- }
7994
- sanitizeHeaders(originalHeaders) {
7995
- const CACHE_RELEVANT_HEADERS = [
7996
- // Content negotiation (affects response format)
7997
- "accept",
7998
- "accept-language"
7999
- ];
8000
- const sanitized = new Headers();
8001
- CACHE_RELEVANT_HEADERS.forEach((header) => {
8002
- const value = originalHeaders.get(header);
8003
- if (value) {
8004
- sanitized.set(header, value);
8005
- }
8006
- });
8007
- return sanitized;
8008
- }
8009
- generateVersionHash(headers) {
8010
- const swellData = this.extractSwellData(headers);
8011
- const versionFactors = {
8012
- store: headers.get("swell-storefront-id") || "",
8013
- auth: headers.get("swell-access-token") || "",
8014
- theme: headers.get("swell-theme-version-hash") || "",
8015
- modified: headers.get("swell-cache-modified") || "",
8016
- currency: swellData["swell-currency"] || "USD",
8017
- locale: headers.get("x-locale") || headers.get("accept-language")?.split(",")[0] || "default",
8018
- context: headers.get("swell-storefront-context"),
8019
- epoch: this.epoch
8020
- };
8021
- return md5(JSON.stringify(versionFactors));
8022
- }
8023
- extractSwellData(headers) {
8024
- const cookie = headers.get("cookie");
8025
- if (!cookie) return {};
8026
- const swellDataMatch = cookie.match(/swell-data=([^;]+)/);
8027
- if (!swellDataMatch) return {};
8028
- try {
8029
- const parsed = JSON.parse(decodeURIComponent(swellDataMatch[1]));
8030
- if (typeof parsed === "object" && parsed !== null) {
8031
- return parsed;
8032
- }
8033
- return {};
8034
- } catch {
8035
- return {};
8036
- }
8037
- }
8038
- isCacheable(request) {
8039
- const url = new URL(request.url);
8040
- const headers = request.headers;
8041
- if (headers.get("swell-deployment-mode") === "editor") {
8042
- return false;
8043
- }
8044
- const skipPaths = ["/checkout"];
8045
- if (skipPaths.some((path) => url.pathname.startsWith(path))) {
8046
- return false;
8047
- }
8048
- if (headers.get("cache-control")?.includes("no-cache")) {
8049
- return false;
8050
- }
8051
- return true;
8052
- }
8053
- isResponseCacheable(response) {
8054
- const contentType = response.headers.get("content-type");
8055
- if (!contentType?.includes("text/html")) {
8056
- return false;
8057
- }
8058
- if (response.headers.get("set-cookie")) {
8059
- return false;
8060
- }
8061
- const cacheControl = response.headers.get("cache-control");
8062
- if (cacheControl?.includes("no-store") || cacheControl?.includes("private")) {
8063
- return false;
8064
- }
8065
- return true;
8066
- }
8067
- getDeploymentMode(headers) {
8068
- const mode = headers.get("swell-deployment-mode");
8069
- if (mode === "preview" || mode === "editor") {
8070
- return mode;
8071
- }
8072
- return "live";
8073
- }
8074
- getTTLForRequest(request) {
8075
- const url = new URL(request.url);
8076
- const path = url.pathname;
8077
- const mode = this.getDeploymentMode(request.headers);
8078
- if (mode === "editor") {
8079
- return 0;
8080
- }
8081
- const config = mode === "preview" ? TTL_CONFIG.PREVIEW : TTL_CONFIG.LIVE;
8082
- if (path === "/") {
8083
- return config.HOME;
8084
- }
8085
- if (path.startsWith("/products/")) {
8086
- return config.PRODUCT;
8087
- }
8088
- if (path.startsWith("/categories/")) {
8089
- return config.COLLECTION;
8090
- }
8091
- if (path.startsWith("/pages/")) {
8092
- return config.PAGE;
8093
- }
8094
- if (path.startsWith("/blogs/")) {
8095
- return config.BLOG;
8096
- }
8097
- return config.DEFAULT;
8098
- }
8099
- getSWRForRequest(request) {
8100
- const mode = this.getDeploymentMode(request.headers);
8101
- if (mode === "editor") {
8102
- return 0;
8103
- }
8104
- return mode === "preview" ? TTL_CONFIG.PREVIEW.SWR : TTL_CONFIG.LIVE.SWR;
8105
- }
8106
- getResponseAge(response) {
8107
- const cacheTime = response.headers.get("X-Cache-Time");
8108
- if (!cacheTime) {
8109
- return Infinity;
8110
- }
8111
- const cacheDate = new Date(cacheTime);
8112
- if (isNaN(cacheDate.getTime())) {
8113
- return Infinity;
8114
- }
8115
- const age = (Date.now() - cacheDate.getTime()) / 1e3;
8116
- return Math.max(0, age);
8117
- }
8118
- normalizeSearchParams(searchParams) {
8119
- const ignoredParams = [
8120
- "utm_source",
8121
- "utm_medium",
8122
- "utm_campaign",
8123
- "utm_content",
8124
- "utm_term",
8125
- "fbclid",
8126
- "gclid",
8127
- "gbraid",
8128
- "wbraid",
8129
- "ref",
8130
- "source",
8131
- "mc_cid",
8132
- "mc_eid"
8133
- ];
8134
- const relevantParams = [];
8135
- searchParams.forEach((value, key) => {
8136
- if (!ignoredParams.includes(key)) {
8137
- relevantParams.push(
8138
- `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
8139
- );
8140
- }
8141
- });
8142
- return relevantParams.sort().join("&");
8143
- }
8144
- };
8145
-
8146
7759
  // src/resources/addresses.ts
8147
7760
  var SwellAddresses = class extends SwellStorefrontCollection {
8148
7761
  constructor(swell, query) {
@@ -16408,7 +16021,7 @@ function ShopifyAddress(instance, address, account) {
16408
16021
  function joinAddressLines(...props) {
16409
16022
  return props.filter(Boolean).join("\n");
16410
16023
  }
16411
- function ShopifyCountry(_instance, countryCode) {
16024
+ function ShopifyCountry(_instance2, countryCode) {
16412
16025
  const currencyCode = getCurrencyByCountry(countryCode) || "USD";
16413
16026
  return new ShopifyResource(
16414
16027
  {
@@ -16741,7 +16354,7 @@ async function resolveLastOrder(instance, account) {
16741
16354
  }
16742
16355
 
16743
16356
  // src/compatibility/shopify-objects/font.ts
16744
- function ShopifyFont(_instance, font) {
16357
+ function ShopifyFont(_instance2, font) {
16745
16358
  if (font instanceof ShopifyResource) {
16746
16359
  return font.clone();
16747
16360
  }
@@ -16752,7 +16365,7 @@ function ShopifyFont(_instance, font) {
16752
16365
  family: font.family,
16753
16366
  style: font.style,
16754
16367
  "system?": font.system,
16755
- variants: font.variants.map((variant) => ShopifyFont(_instance, variant)),
16368
+ variants: font.variants.map((variant) => ShopifyFont(_instance2, variant)),
16756
16369
  weight: font.weight
16757
16370
  });
16758
16371
  }
@@ -16765,7 +16378,7 @@ var SHOPIFY_FORMS = {
16765
16378
  })
16766
16379
  }
16767
16380
  };
16768
- function ShopifyForm(_instance, form) {
16381
+ function ShopifyForm(_instance2, form) {
16769
16382
  if (form instanceof ShopifyResource) {
16770
16383
  return form.clone();
16771
16384
  }
@@ -17062,7 +16675,7 @@ function ShopifyRecommendations(instance, product) {
17062
16675
  }
17063
16676
 
17064
16677
  // src/compatibility/shopify-objects/page.ts
17065
- function ShopifyPage(_instance, page) {
16678
+ function ShopifyPage(_instance2, page) {
17066
16679
  if (page instanceof ShopifyResource) {
17067
16680
  return page.clone();
17068
16681
  }
@@ -18274,7 +17887,7 @@ ${injects.join("\n")}</script>`;
18274
17887
  };
18275
17888
 
18276
17889
  // src/compatibility/shopify-objects/template.ts
18277
- function ShopifyTemplate(_instance, template) {
17890
+ function ShopifyTemplate(_instance2, template) {
18278
17891
  return new ShopifyResource(
18279
17892
  {
18280
17893
  directory: template.path,
@@ -20586,7 +20199,7 @@ var ThemeLoader = class _ThemeLoader {
20586
20199
  flavor,
20587
20200
  trace
20588
20201
  });
20589
- const storage = new ThemeFileStorage(this.swell.workerEnv, flavor);
20202
+ const storage = new ThemeFileCache(this.swell.workerEnv, flavor);
20590
20203
  const result = await storage.putFiles(configs);
20591
20204
  if (result.warnings.length > 0) {
20592
20205
  logger.warn("[ThemeLoader] Theme cache updated with warnings", {
@@ -20624,7 +20237,7 @@ var ThemeLoader = class _ThemeLoader {
20624
20237
  total: configMetadata.length
20625
20238
  });
20626
20239
  const flavor = getKVFlavor(this.swell.workerEnv);
20627
- const storage = new ThemeFileStorage(this.swell.workerEnv, flavor);
20240
+ const storage = new ThemeFileCache(this.swell.workerEnv, flavor);
20628
20241
  const kvHydrated = await storage.getFiles(configMetadata);
20629
20242
  const completeConfigs = await this.ensureConfigsHaveData(kvHydrated);
20630
20243
  for (const config of completeConfigs) {
@@ -22846,6 +22459,547 @@ function getResourceQuery(slug, query) {
22846
22459
  ...query
22847
22460
  };
22848
22461
  }
22462
+
22463
+ // src/cache/html-cache/html-cache.ts
22464
+ var CACHE_KEY_ORIGIN = "https://cache.swell.store";
22465
+ var TTL_CONFIG = {
22466
+ LIVE: {
22467
+ DEFAULT: 20,
22468
+ HOME: 20,
22469
+ PRODUCT: 20,
22470
+ COLLECTION: 20,
22471
+ PAGE: 20,
22472
+ BLOG: 20,
22473
+ SWR: 60 * 60 * 24 * 7
22474
+ // 1 week
22475
+ },
22476
+ PREVIEW: {
22477
+ DEFAULT: 10,
22478
+ HOME: 10,
22479
+ PRODUCT: 10,
22480
+ COLLECTION: 10,
22481
+ PAGE: 10,
22482
+ BLOG: 10,
22483
+ SWR: 60 * 60 * 24 * 7
22484
+ // 1 week
22485
+ }
22486
+ };
22487
+ var HtmlCache = class {
22488
+ epoch;
22489
+ backend;
22490
+ constructor(epoch, backend) {
22491
+ this.epoch = epoch;
22492
+ this.backend = backend;
22493
+ }
22494
+ async get(request) {
22495
+ const trace = createTraceId();
22496
+ if (request.method !== "GET") {
22497
+ logger.debug("[SDK Html-cache] non-cacheable method", { trace });
22498
+ return { found: false, cacheable: false };
22499
+ }
22500
+ if (!this.isCacheable(request)) {
22501
+ logger.debug("[SDK Html-cache] non-cacheable request", { trace });
22502
+ return { found: false, cacheable: false };
22503
+ }
22504
+ try {
22505
+ const cacheKey = this.buildCacheKey(request);
22506
+ const entry = await this.backend.read(cacheKey);
22507
+ if (!entry) {
22508
+ logger.debug("[SDK Html-cache] cacheable, MISS", { trace });
22509
+ return { found: false, cacheable: true };
22510
+ }
22511
+ const age = this.getEntryAge(entry);
22512
+ const { ttl, swr } = entry;
22513
+ const isStale = age >= ttl;
22514
+ const isExpired = age >= ttl + swr;
22515
+ if (!isExpired) {
22516
+ logger.debug("[SDK Html-cache] cacheable, HIT", {
22517
+ stale: isStale,
22518
+ age,
22519
+ trace
22520
+ });
22521
+ const clientResponse = this.buildClientResponse(entry, isStale, age);
22522
+ return {
22523
+ found: true,
22524
+ stale: isStale,
22525
+ response: clientResponse,
22526
+ cacheable: true,
22527
+ age: Math.floor(age)
22528
+ };
22529
+ }
22530
+ logger.debug("[SDK Html-cache] cacheable, hit, expired", { trace });
22531
+ return { found: false, cacheable: true };
22532
+ } catch (e) {
22533
+ logger.warn("[SDK Html-cache] get failed", {
22534
+ trace,
22535
+ error: e instanceof Error ? e.message : String(e)
22536
+ });
22537
+ return null;
22538
+ }
22539
+ }
22540
+ async getWithConditionals(request) {
22541
+ const result = await this.get(request);
22542
+ if (!result?.found || result.stale) {
22543
+ return result;
22544
+ }
22545
+ const ifModifiedSince = request.headers.get("If-Modified-Since");
22546
+ const ifNoneMatch = request.headers.get("If-None-Match");
22547
+ if ((ifModifiedSince || ifNoneMatch) && result.response) {
22548
+ const lastModified = result.response.headers.get("Last-Modified");
22549
+ const etag = result.response.headers.get("ETag");
22550
+ if (this.checkNotModified(ifModifiedSince, ifNoneMatch, lastModified, etag)) {
22551
+ result.notModified = true;
22552
+ result.conditional304 = new Response(null, {
22553
+ status: 304,
22554
+ headers: {
22555
+ "Last-Modified": lastModified || "",
22556
+ ETag: etag || "",
22557
+ "Cache-Control": result.response.headers.get("Cache-Control") || "",
22558
+ "Cloudflare-CDN-Cache-Control": result.response.headers.get("Cloudflare-CDN-Cache-Control") || "",
22559
+ "X-Cache-Status": "HIT-304"
22560
+ }
22561
+ });
22562
+ }
22563
+ }
22564
+ return result;
22565
+ }
22566
+ async put(request, response) {
22567
+ const trace = createTraceId();
22568
+ if (request.method !== "GET" || !response.ok) {
22569
+ logger.debug("[SDK Html-cache] put skipped, invalid method or response", {
22570
+ trace
22571
+ });
22572
+ return;
22573
+ }
22574
+ if (!this.isCacheable(request) || !this.isResponseCacheable(response)) {
22575
+ logger.debug("[SDK Html-cache] put skipped, non-cacheable", { trace });
22576
+ return;
22577
+ }
22578
+ try {
22579
+ let lowercaseHeaders2 = function(headers2) {
22580
+ const out = {};
22581
+ headers2.forEach((value, key) => {
22582
+ out[key.toLowerCase()] = value;
22583
+ });
22584
+ return out;
22585
+ };
22586
+ var lowercaseHeaders = lowercaseHeaders2;
22587
+ const cacheKey = this.buildCacheKey(request);
22588
+ const ttl = this.getTTLForRequest(request);
22589
+ const swr = this.getSWRForRequest(request);
22590
+ const body = await response.text();
22591
+ const cacheTimeISO = (/* @__PURE__ */ new Date()).toISOString();
22592
+ const headers = lowercaseHeaders2(response.headers);
22593
+ const entry = {
22594
+ status: response.status,
22595
+ statusText: response.statusText,
22596
+ headers,
22597
+ body,
22598
+ cacheTimeISO,
22599
+ ttl,
22600
+ swr,
22601
+ etag: this.quoteETag(headers["etag"] || md5(body)),
22602
+ lastModifiedUTC: headers["last-modified"] || new Date(cacheTimeISO).toUTCString()
22603
+ };
22604
+ const hardExpireSeconds = ttl + swr;
22605
+ await this.backend.write(cacheKey, entry, hardExpireSeconds);
22606
+ logger.debug("[SDK Html-cache] put done", { trace });
22607
+ } catch (e) {
22608
+ logger.warn("[SDK Html-cache] put failed", {
22609
+ trace,
22610
+ error: e instanceof Error ? e.message : String(e)
22611
+ });
22612
+ }
22613
+ }
22614
+ async delete(requestOrKey) {
22615
+ try {
22616
+ const key = typeof requestOrKey === "string" ? requestOrKey : this.buildCacheKey(requestOrKey);
22617
+ if (this.backend.delete) {
22618
+ await this.backend.delete(key);
22619
+ }
22620
+ } catch (e) {
22621
+ logger.warn("[SDK Html-cache] delete failed", {
22622
+ error: e instanceof Error ? e.message : String(e)
22623
+ });
22624
+ }
22625
+ }
22626
+ isReadCacheCandidate(request) {
22627
+ const m = request.method.toUpperCase();
22628
+ return (m === "GET" || m === "HEAD") && this.isCacheable(request);
22629
+ }
22630
+ isWriteCacheCandidate(request, response) {
22631
+ if (request.method.toUpperCase() !== "GET") return false;
22632
+ if (!this.isCacheable(request)) return false;
22633
+ return this.isResponseCacheable(response);
22634
+ }
22635
+ createRevalidationRequest(request) {
22636
+ const headers = new Headers(request.headers);
22637
+ headers.set("X-Cache-Bypass", "revalidation");
22638
+ headers.delete("If-None-Match");
22639
+ headers.delete("If-Modified-Since");
22640
+ headers.delete("Cache-Control");
22641
+ headers.delete("Pragma");
22642
+ return new Request(request.url, {
22643
+ method: "GET",
22644
+ headers
22645
+ });
22646
+ }
22647
+ buildClientResponse(entry, isStale, age) {
22648
+ const headers = new Headers(entry.headers);
22649
+ headers.set("Cache-Control", "public, max-age=0, must-revalidate");
22650
+ headers.set(
22651
+ "Cloudflare-CDN-Cache-Control",
22652
+ `public, s-maxage=${entry.ttl}, stale-while-revalidate=${entry.swr}, stale-if-error=60`
22653
+ );
22654
+ if (entry.lastModifiedUTC) {
22655
+ headers.set("Last-Modified", entry.lastModifiedUTC);
22656
+ }
22657
+ if (entry.etag) {
22658
+ headers.set("ETag", entry.etag);
22659
+ }
22660
+ headers.set("X-Cache-Status", isStale ? "STALE" : "HIT");
22661
+ headers.set("X-Cache-Age", Math.floor(age).toString());
22662
+ this.sanitizeClientHeaders(headers);
22663
+ return new Response(entry.body, {
22664
+ status: entry.status,
22665
+ statusText: entry.statusText,
22666
+ headers
22667
+ });
22668
+ }
22669
+ buildCacheKey(request) {
22670
+ const url = new URL(request.url);
22671
+ const versionHash = this.generateVersionHash(request.headers);
22672
+ const normalizedQuery = this.normalizeSearchParams(url.searchParams);
22673
+ const cacheKeyPath = `${versionHash}${url.pathname}`;
22674
+ const keyUrl = new URL(`${CACHE_KEY_ORIGIN}${cacheKeyPath}`);
22675
+ if (normalizedQuery) {
22676
+ keyUrl.search = `?${normalizedQuery}`;
22677
+ }
22678
+ return keyUrl.toString();
22679
+ }
22680
+ checkNotModified(ifModifiedSince, ifNoneMatch, lastModified, etag) {
22681
+ if (this.ifNoneMatchMatches(ifNoneMatch, etag)) {
22682
+ return true;
22683
+ }
22684
+ if (ifModifiedSince && lastModified) {
22685
+ try {
22686
+ const ifModDate = new Date(ifModifiedSince);
22687
+ const lastModDate = new Date(lastModified);
22688
+ if (isNaN(ifModDate.getTime()) || isNaN(lastModDate.getTime())) {
22689
+ return false;
22690
+ }
22691
+ return ifModDate >= lastModDate;
22692
+ } catch {
22693
+ return false;
22694
+ }
22695
+ }
22696
+ return false;
22697
+ }
22698
+ ifNoneMatchMatches(ifNoneMatch, etag) {
22699
+ if (!ifNoneMatch || !etag) return false;
22700
+ const header = ifNoneMatch.trim();
22701
+ if (header === "*") return true;
22702
+ const tokens = header.split(",").map((t) => t.trim());
22703
+ const normalizedEtag = etag.replace(/^W\//, "");
22704
+ for (const token of tokens) {
22705
+ if (token === etag) return true;
22706
+ const normalizedToken = token.replace(/^W\//, "");
22707
+ if (normalizedToken === normalizedEtag) return true;
22708
+ }
22709
+ return false;
22710
+ }
22711
+ quoteETag(value) {
22712
+ if (!value) return value;
22713
+ if (value.startsWith('"') || value.startsWith('W/"')) return value;
22714
+ if (value.startsWith("W/")) return `W/"${value.slice(2)}"`;
22715
+ return `"${value}"`;
22716
+ }
22717
+ sanitizeClientHeaders(headers) {
22718
+ const HOP_BY_HOP = [
22719
+ "connection",
22720
+ "proxy-connection",
22721
+ "keep-alive",
22722
+ "transfer-encoding",
22723
+ "upgrade",
22724
+ "proxy-authenticate",
22725
+ "proxy-authorization",
22726
+ "te",
22727
+ "trailers",
22728
+ "via",
22729
+ "alt-svc",
22730
+ "content-length"
22731
+ ];
22732
+ for (const h of HOP_BY_HOP) headers.delete(h);
22733
+ headers.delete("content-encoding");
22734
+ headers.delete("x-original-ttl");
22735
+ headers.delete("x-original-swr");
22736
+ headers.delete("x-cache-time");
22737
+ }
22738
+ generateVersionHash(headers) {
22739
+ const swellData = this.extractSwellData(headers);
22740
+ const acceptLang = headers.get("accept-language") || "";
22741
+ const accept = headers.get("accept") || "";
22742
+ const versionFactors = {
22743
+ store: headers.get("swell-storefront-id") || "",
22744
+ auth: headers.get("swell-access-token") || "",
22745
+ theme: headers.get("swell-theme-version-hash") || "",
22746
+ modified: headers.get("swell-cache-modified") || "",
22747
+ currency: swellData["swell-currency"] || "USD",
22748
+ locale: headers.get("x-locale") || acceptLang.split(",")[0].trim().toLowerCase() || "default",
22749
+ context: headers.get("swell-storefront-context"),
22750
+ accept,
22751
+ epoch: this.epoch
22752
+ };
22753
+ return md5(JSON.stringify(versionFactors));
22754
+ }
22755
+ extractSwellData(headers) {
22756
+ const cookie = headers.get("cookie");
22757
+ if (!cookie) return {};
22758
+ const swellDataMatch = cookie.match(/swell-data=([^;]+)/);
22759
+ if (!swellDataMatch) return {};
22760
+ try {
22761
+ return JSON.parse(decodeURIComponent(swellDataMatch[1])) || {};
22762
+ } catch {
22763
+ return {};
22764
+ }
22765
+ }
22766
+ isCacheable(request) {
22767
+ const url = new URL(request.url);
22768
+ if (request.headers.get("swell-deployment-mode") === "editor") return false;
22769
+ const skipPaths = ["/checkout"];
22770
+ if (skipPaths.some((path) => url.pathname.startsWith(path))) return false;
22771
+ if (request.headers.get("cache-control")?.includes("no-cache"))
22772
+ return false;
22773
+ return true;
22774
+ }
22775
+ isResponseCacheable(response) {
22776
+ if (!response.headers.get("content-type")?.includes("text/html"))
22777
+ return false;
22778
+ if (response.headers.get("set-cookie")) return false;
22779
+ const cacheControl = response.headers.get("cache-control");
22780
+ if (cacheControl?.includes("no-store") || cacheControl?.includes("private"))
22781
+ return false;
22782
+ return true;
22783
+ }
22784
+ getDeploymentMode(headers) {
22785
+ const mode = headers.get("swell-deployment-mode");
22786
+ return mode === "preview" || mode === "editor" ? mode : "live";
22787
+ }
22788
+ getTTLForRequest(request) {
22789
+ const url = new URL(request.url);
22790
+ const mode = this.getDeploymentMode(request.headers);
22791
+ if (mode === "editor") return 0;
22792
+ const config = mode === "preview" ? TTL_CONFIG.PREVIEW : TTL_CONFIG.LIVE;
22793
+ if (url.pathname === "/") return config.HOME;
22794
+ if (url.pathname.startsWith("/products/")) return config.PRODUCT;
22795
+ if (url.pathname.startsWith("/categories/")) return config.COLLECTION;
22796
+ if (url.pathname.startsWith("/pages/")) return config.PAGE;
22797
+ if (url.pathname.startsWith("/blogs/")) return config.BLOG;
22798
+ return config.DEFAULT;
22799
+ }
22800
+ getSWRForRequest(request) {
22801
+ const mode = this.getDeploymentMode(request.headers);
22802
+ if (mode === "editor") return 0;
22803
+ return mode === "preview" ? TTL_CONFIG.PREVIEW.SWR : TTL_CONFIG.LIVE.SWR;
22804
+ }
22805
+ getEntryAge(entry) {
22806
+ const t = Date.parse(entry.cacheTimeISO);
22807
+ if (Number.isNaN(t)) return Infinity;
22808
+ const age = (Date.now() - t) / 1e3;
22809
+ return age < 0 ? 0 : age;
22810
+ }
22811
+ normalizeSearchParams(searchParams) {
22812
+ const ignoredParams = [
22813
+ "utm_source",
22814
+ "utm_medium",
22815
+ "utm_campaign",
22816
+ "utm_content",
22817
+ "utm_term",
22818
+ "fbclid",
22819
+ "gclid",
22820
+ "gbraid",
22821
+ "wbraid",
22822
+ "ref",
22823
+ "source",
22824
+ "mc_cid",
22825
+ "mc_eid"
22826
+ ];
22827
+ const relevantParams = [];
22828
+ searchParams.forEach((value, key) => {
22829
+ if (!ignoredParams.includes(key)) {
22830
+ relevantParams.push(
22831
+ `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
22832
+ );
22833
+ }
22834
+ });
22835
+ return relevantParams.sort().join("&");
22836
+ }
22837
+ };
22838
+
22839
+ // src/cache/html-cache/html-cache-kv.ts
22840
+ var KVCacheBackend = class {
22841
+ kv;
22842
+ prefix;
22843
+ hashKeys;
22844
+ maxValueBytes;
22845
+ constructor(kv, opts = {}) {
22846
+ this.kv = kv;
22847
+ this.prefix = opts.prefix;
22848
+ this.hashKeys = opts.hashKeys !== false;
22849
+ this.maxValueBytes = opts.maxValueBytes ?? Math.floor(24.5 * 1024 * 1024);
22850
+ }
22851
+ async read(key) {
22852
+ const kvKey = this.makeKey(key);
22853
+ const value = await this.kv.get(kvKey, "json");
22854
+ if (!value) return null;
22855
+ const entry = {
22856
+ status: value.status,
22857
+ statusText: value.statusText,
22858
+ headers: value.headers,
22859
+ body: value.body,
22860
+ cacheTimeISO: value.cacheTimeISO,
22861
+ ttl: value.ttl,
22862
+ swr: value.swr,
22863
+ etag: value.etag,
22864
+ lastModifiedUTC: value.lastModifiedUTC
22865
+ };
22866
+ return entry;
22867
+ }
22868
+ async write(key, entry, hardExpireSeconds) {
22869
+ const kvKey = this.makeKey(key);
22870
+ const payload = {
22871
+ v: 1,
22872
+ status: entry.status,
22873
+ statusText: entry.statusText,
22874
+ headers: entry.headers,
22875
+ body: entry.body,
22876
+ cacheTimeISO: entry.cacheTimeISO,
22877
+ ttl: entry.ttl,
22878
+ swr: entry.swr,
22879
+ etag: entry.etag,
22880
+ lastModifiedUTC: entry.lastModifiedUTC
22881
+ };
22882
+ const json = JSON.stringify(payload);
22883
+ this.assertSize(json);
22884
+ const metadata = {
22885
+ v: 1,
22886
+ cacheTimeISO: entry.cacheTimeISO,
22887
+ ttl: entry.ttl,
22888
+ swr: entry.swr,
22889
+ etag: entry.etag,
22890
+ lastModifiedUTC: entry.lastModifiedUTC
22891
+ };
22892
+ await this.kv.put(kvKey, json, {
22893
+ expirationTtl: hardExpireSeconds + 60,
22894
+ // natural hard expiry after SWR + grace period
22895
+ metadata
22896
+ });
22897
+ }
22898
+ async delete(key) {
22899
+ const kvKey = this.makeKey(key);
22900
+ await this.kv.delete(kvKey);
22901
+ }
22902
+ // ---- private helpers ----
22903
+ makeKey(raw) {
22904
+ const core = this.hashKeys ? md5(raw) : raw;
22905
+ return this.prefix ? `${this.prefix}:${core}` : core;
22906
+ }
22907
+ assertSize(json) {
22908
+ const bytes = typeof TextEncoder !== "undefined" ? new TextEncoder().encode(json).length : this.approxUtf8Bytes(json);
22909
+ if (bytes > this.maxValueBytes) {
22910
+ throw new Error(
22911
+ `KV value too large: ${bytes} bytes exceeds limit ${this.maxValueBytes} bytes`
22912
+ );
22913
+ }
22914
+ }
22915
+ approxUtf8Bytes(str) {
22916
+ let count = 0;
22917
+ for (let i = 0; i < str.length; i++) {
22918
+ const code = str.charCodeAt(i);
22919
+ if (code <= 127) count += 1;
22920
+ else if (code <= 2047) count += 2;
22921
+ else count += 3;
22922
+ }
22923
+ return count;
22924
+ }
22925
+ };
22926
+
22927
+ // src/cache/html-cache/html-cache-worker.ts
22928
+ var CACHE_NAME_PREFIX = "swell-html-v0";
22929
+ var WorkerCacheBackend = class {
22930
+ cacheName;
22931
+ constructor(epoch) {
22932
+ this.cacheName = CACHE_NAME_PREFIX + epoch;
22933
+ }
22934
+ async read(key) {
22935
+ const cache = await caches.open(this.cacheName);
22936
+ const request = new Request(key);
22937
+ const response = await cache.match(request);
22938
+ if (!response) return null;
22939
+ const headers = {};
22940
+ response.headers.forEach((value, name) => {
22941
+ headers[name.toLowerCase()] = value;
22942
+ });
22943
+ return {
22944
+ status: response.status,
22945
+ statusText: response.statusText,
22946
+ headers,
22947
+ body: await response.text(),
22948
+ cacheTimeISO: response.headers.get("x-cache-time") || (/* @__PURE__ */ new Date(0)).toISOString(),
22949
+ ttl: parseInt(response.headers.get("x-original-ttl") || "0", 10),
22950
+ swr: parseInt(response.headers.get("x-original-swr") || "0", 10),
22951
+ etag: response.headers.get("etag") || void 0,
22952
+ lastModifiedUTC: response.headers.get("last-modified") || void 0
22953
+ };
22954
+ }
22955
+ async write(key, entry, _hardExpireSeconds) {
22956
+ const cache = await caches.open(this.cacheName);
22957
+ const request = new Request(key);
22958
+ const headers = new Headers(entry.headers);
22959
+ if (entry.lastModifiedUTC && !headers.get("Last-Modified")) {
22960
+ headers.set("Last-Modified", entry.lastModifiedUTC);
22961
+ }
22962
+ if (entry.etag && !headers.get("ETag")) {
22963
+ headers.set("ETag", entry.etag);
22964
+ }
22965
+ headers.set("X-Cache-Time", entry.cacheTimeISO);
22966
+ headers.set("X-Original-TTL", String(entry.ttl));
22967
+ headers.set("X-Original-SWR", String(entry.swr));
22968
+ headers.delete("content-encoding");
22969
+ headers.delete("content-length");
22970
+ const existing = headers.get("Cache-Control");
22971
+ if (!existing || existing.trim().toLowerCase() === "public") {
22972
+ headers.set("Cache-Control", `public, max-age=${entry.ttl + entry.swr}`);
22973
+ }
22974
+ const response = new Response(entry.body, {
22975
+ status: entry.status,
22976
+ statusText: entry.statusText,
22977
+ headers
22978
+ });
22979
+ await cache.delete(request);
22980
+ await cache.put(request, response);
22981
+ }
22982
+ async delete(key) {
22983
+ const cache = await caches.open(this.cacheName);
22984
+ const request = new Request(key);
22985
+ await cache.delete(request);
22986
+ }
22987
+ };
22988
+
22989
+ // src/cache/html-cache/html-cache-factory.ts
22990
+ var _instance = null;
22991
+ function getHtmlCache(env) {
22992
+ const epoch = env?.HTML_CACHE_EPOCH;
22993
+ if (typeof epoch !== "string" || !epoch) return null;
22994
+ if (_instance) return _instance;
22995
+ const kv = env?.NAMESPACE;
22996
+ if (env?.HTML_CACHE_BACKEND !== "worker" && kv) {
22997
+ _instance = new HtmlCache(epoch, new KVCacheBackend(kv));
22998
+ return _instance;
22999
+ }
23000
+ _instance = new HtmlCache(epoch, new WorkerCacheBackend(epoch));
23001
+ return _instance;
23002
+ }
22849
23003
  // Annotate the CommonJS export names for ESM import in node:
22850
23004
  0 && (module.exports = {
22851
23005
  AccountAddressesResource,
@@ -22864,6 +23018,7 @@ function getResourceQuery(slug, query) {
22864
23018
  DeferredShopifyResource,
22865
23019
  FILE_DATA_INCLUDE_QUERY,
22866
23020
  GEO_DATA,
23021
+ HtmlCache,
22867
23022
  LANG_TO_COUNTRY_CODES,
22868
23023
  LiquidSwell,
22869
23024
  MAX_QUERY_PAGE_LIMIT,
@@ -22911,7 +23066,6 @@ function getResourceQuery(slug, query) {
22911
23066
  ThemeForm,
22912
23067
  ThemeFormErrors,
22913
23068
  VariantResource,
22914
- WorkerHtmlCache,
22915
23069
  adaptShopifyFontData,
22916
23070
  adaptShopifyFormData,
22917
23071
  adaptShopifyMenuData,
@@ -22939,6 +23093,7 @@ function getResourceQuery(slug, query) {
22939
23093
  getEasyblocksComponentDefinitions,
22940
23094
  getEasyblocksPagePropsWithConfigs,
22941
23095
  getEasyblocksPageTemplate,
23096
+ getHtmlCache,
22942
23097
  getKVFlavor,
22943
23098
  getLayoutSectionGroups,
22944
23099
  getMenuItemStorefrontUrl,