@swell/apps-sdk 1.0.151 → 1.0.152
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 +414 -80
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +412 -80
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +413 -80
- package/dist/index.mjs.map +4 -4
- package/dist/src/cache/cache-api-stub.d.ts +25 -0
- package/dist/src/cache/index.d.ts +2 -0
- package/dist/src/cache/worker-html-cache.d.ts +43 -0
- package/dist/src/index.d.ts +3 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -94,6 +94,7 @@ __export(index_exports, {
|
|
|
94
94
|
ThemeFont: () => ThemeFont,
|
|
95
95
|
ThemeForm: () => ThemeForm,
|
|
96
96
|
ThemeFormErrors: () => ThemeFormErrors,
|
|
97
|
+
WorkerHtmlCache: () => WorkerHtmlCache,
|
|
97
98
|
adaptShopifyFontData: () => adaptShopifyFontData,
|
|
98
99
|
adaptShopifyFormData: () => adaptShopifyFormData,
|
|
99
100
|
adaptShopifyMenuData: () => adaptShopifyMenuData,
|
|
@@ -160,72 +161,6 @@ var import_qs2 = __toESM(require("qs"), 1);
|
|
|
160
161
|
var import_keyv = require("keyv");
|
|
161
162
|
var import_cache_manager = require("cache-manager");
|
|
162
163
|
|
|
163
|
-
// src/cache/cf-worker-kv-keyv-adapter.ts
|
|
164
|
-
var CFWorkerKVKeyvAdapter = class {
|
|
165
|
-
store;
|
|
166
|
-
namespace;
|
|
167
|
-
// magically passed in from Keyv
|
|
168
|
-
opts;
|
|
169
|
-
constructor(store) {
|
|
170
|
-
this.store = store;
|
|
171
|
-
this.opts = null;
|
|
172
|
-
this.namespace = "dummy";
|
|
173
|
-
}
|
|
174
|
-
async has(key) {
|
|
175
|
-
const stream = await this.store.get(key, "stream");
|
|
176
|
-
if (stream !== null) {
|
|
177
|
-
await stream.cancel();
|
|
178
|
-
return true;
|
|
179
|
-
}
|
|
180
|
-
return false;
|
|
181
|
-
}
|
|
182
|
-
async get(key) {
|
|
183
|
-
const value = await this.store.get(key);
|
|
184
|
-
return value !== null ? value : void 0;
|
|
185
|
-
}
|
|
186
|
-
set(key, value, ttl) {
|
|
187
|
-
if (typeof ttl === "number") {
|
|
188
|
-
ttl = Math.max(60, ttl / 1e3);
|
|
189
|
-
}
|
|
190
|
-
return this.store.put(key, value, { expirationTtl: ttl });
|
|
191
|
-
}
|
|
192
|
-
async delete(key) {
|
|
193
|
-
await this.store.delete(key);
|
|
194
|
-
return true;
|
|
195
|
-
}
|
|
196
|
-
async clear() {
|
|
197
|
-
let cursor = "";
|
|
198
|
-
let complete = false;
|
|
199
|
-
const prefix = `${this.namespace}:`;
|
|
200
|
-
do {
|
|
201
|
-
const response = await this.store.list({
|
|
202
|
-
prefix,
|
|
203
|
-
cursor: cursor || void 0
|
|
204
|
-
});
|
|
205
|
-
cursor = response.cursor ?? "";
|
|
206
|
-
complete = response.list_complete;
|
|
207
|
-
if (response.keys.length > 0) {
|
|
208
|
-
await Promise.all(
|
|
209
|
-
response.keys.map((key) => {
|
|
210
|
-
return this.store.delete(key.name);
|
|
211
|
-
})
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
} while (!complete);
|
|
215
|
-
}
|
|
216
|
-
on(_event, _listener) {
|
|
217
|
-
return this;
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
// src/utils/index.ts
|
|
222
|
-
var import_qs = __toESM(require("qs"), 1);
|
|
223
|
-
var import_lodash_es3 = require("lodash-es");
|
|
224
|
-
var import_json52 = __toESM(require("json5"), 1);
|
|
225
|
-
|
|
226
|
-
// src/resources.ts
|
|
227
|
-
var import_lodash_es2 = require("lodash-es");
|
|
228
|
-
|
|
229
164
|
// src/utils/logger.ts
|
|
230
165
|
var logLevels = {
|
|
231
166
|
error: 0,
|
|
@@ -317,6 +252,80 @@ function createTraceId(data) {
|
|
|
317
252
|
return (hash >>> 0).toString(16);
|
|
318
253
|
}
|
|
319
254
|
|
|
255
|
+
// src/cache/cf-worker-kv-keyv-adapter.ts
|
|
256
|
+
var CFWorkerKVKeyvAdapter = class {
|
|
257
|
+
store;
|
|
258
|
+
namespace;
|
|
259
|
+
// magically passed in from Keyv
|
|
260
|
+
opts;
|
|
261
|
+
constructor(store) {
|
|
262
|
+
this.store = store;
|
|
263
|
+
this.opts = null;
|
|
264
|
+
this.namespace = "dummy";
|
|
265
|
+
}
|
|
266
|
+
async has(key) {
|
|
267
|
+
const stream = await this.store.get(key, "stream");
|
|
268
|
+
if (stream !== null) {
|
|
269
|
+
await stream.cancel();
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
async get(key) {
|
|
275
|
+
const trace = createTraceId();
|
|
276
|
+
logger.debug("[SDK] kv.get", { key, trace });
|
|
277
|
+
const value = await this.store.get(key);
|
|
278
|
+
const result = value !== null ? value : void 0;
|
|
279
|
+
logger.debug(`[SDK] kv.get ${value !== null ? "HIT" : "MISS"}`, {
|
|
280
|
+
key,
|
|
281
|
+
trace
|
|
282
|
+
});
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
285
|
+
set(key, value, ttl) {
|
|
286
|
+
if (typeof ttl === "number") {
|
|
287
|
+
ttl = Math.max(60, ttl / 1e3);
|
|
288
|
+
}
|
|
289
|
+
logger.debug("[SDK] kv.set", { key });
|
|
290
|
+
return this.store.put(key, value, { expirationTtl: ttl });
|
|
291
|
+
}
|
|
292
|
+
async delete(key) {
|
|
293
|
+
await this.store.delete(key);
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
async clear() {
|
|
297
|
+
let cursor = "";
|
|
298
|
+
let complete = false;
|
|
299
|
+
const prefix = `${this.namespace}:`;
|
|
300
|
+
do {
|
|
301
|
+
const response = await this.store.list({
|
|
302
|
+
prefix,
|
|
303
|
+
cursor: cursor || void 0
|
|
304
|
+
});
|
|
305
|
+
cursor = response.cursor ?? "";
|
|
306
|
+
complete = response.list_complete;
|
|
307
|
+
if (response.keys.length > 0) {
|
|
308
|
+
await Promise.all(
|
|
309
|
+
response.keys.map((key) => {
|
|
310
|
+
return this.store.delete(key.name);
|
|
311
|
+
})
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
} while (!complete);
|
|
315
|
+
}
|
|
316
|
+
on(_event, _listener) {
|
|
317
|
+
return this;
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// src/utils/index.ts
|
|
322
|
+
var import_qs = __toESM(require("qs"), 1);
|
|
323
|
+
var import_lodash_es3 = require("lodash-es");
|
|
324
|
+
var import_json52 = __toESM(require("json5"), 1);
|
|
325
|
+
|
|
326
|
+
// src/resources.ts
|
|
327
|
+
var import_lodash_es2 = require("lodash-es");
|
|
328
|
+
|
|
320
329
|
// src/liquid/utils.ts
|
|
321
330
|
var import_liquidjs = require("liquidjs");
|
|
322
331
|
|
|
@@ -960,6 +969,7 @@ var SwellStorefrontCollection = class _SwellStorefrontCollection extends SwellSt
|
|
|
960
969
|
this._collection,
|
|
961
970
|
this._query,
|
|
962
971
|
this._swell.queryParams,
|
|
972
|
+
// TODO: consider to exlcude
|
|
963
973
|
this._getterHash
|
|
964
974
|
],
|
|
965
975
|
getter,
|
|
@@ -1088,6 +1098,7 @@ var SwellStorefrontRecord = class extends SwellStorefrontResource {
|
|
|
1088
1098
|
this._id,
|
|
1089
1099
|
this._query,
|
|
1090
1100
|
this._swell.queryParams,
|
|
1101
|
+
// TODO: consider to exlcude
|
|
1091
1102
|
this._getterHash
|
|
1092
1103
|
],
|
|
1093
1104
|
getter,
|
|
@@ -7316,8 +7327,6 @@ var Cache = class {
|
|
|
7316
7327
|
* This will always return the cached value immediately if exists
|
|
7317
7328
|
*/
|
|
7318
7329
|
async fetchSWR(key, fetchFn, ttl = DEFAULT_SWR_TTL, isCacheble = true) {
|
|
7319
|
-
const trace = createTraceId();
|
|
7320
|
-
logger.debug("[SDK] Cache fetch start", { key, trace });
|
|
7321
7330
|
const cacheValue = isCacheble ? await this.client.get(key) : void 0;
|
|
7322
7331
|
let promise = SWR_PROMISE_MAP.get(key);
|
|
7323
7332
|
if (promise === void 0) {
|
|
@@ -7325,7 +7334,6 @@ var Cache = class {
|
|
|
7325
7334
|
const isNull = value === null || value === void 0;
|
|
7326
7335
|
if (isCacheble) {
|
|
7327
7336
|
await this.client.set(key, isNull ? NULL_VALUE : value, ttl);
|
|
7328
|
-
logger.debug("[SDK] Cache update done", { key, trace });
|
|
7329
7337
|
}
|
|
7330
7338
|
return value;
|
|
7331
7339
|
}).finally(() => {
|
|
@@ -7337,12 +7345,9 @@ var Cache = class {
|
|
|
7337
7345
|
this.workerCtx.waitUntil(promise);
|
|
7338
7346
|
}
|
|
7339
7347
|
if (cacheValue !== void 0) {
|
|
7340
|
-
logger.debug("[SDK] Cache check done", { status: "HIT", key, trace });
|
|
7341
7348
|
return cacheValue === NULL_VALUE ? null : cacheValue;
|
|
7342
7349
|
}
|
|
7343
|
-
logger.debug("[SDK] Cache check done", { status: "MISS", key, trace });
|
|
7344
7350
|
const result = await promise;
|
|
7345
|
-
logger.debug("[SDK] Cache fetch end", { key, trace });
|
|
7346
7351
|
return result;
|
|
7347
7352
|
}
|
|
7348
7353
|
async get(key) {
|
|
@@ -7849,6 +7854,326 @@ var WorkerCacheProxy = class {
|
|
|
7849
7854
|
}
|
|
7850
7855
|
};
|
|
7851
7856
|
|
|
7857
|
+
// src/cache/worker-html-cache.ts
|
|
7858
|
+
var CACHE_NAME2 = "swell-html-v1";
|
|
7859
|
+
var CACHE_KEY_ORIGIN2 = "https://cache.swell.store";
|
|
7860
|
+
var TTL_CONFIG = {
|
|
7861
|
+
DEFAULT: 300,
|
|
7862
|
+
// 5 minutes
|
|
7863
|
+
DEFAULT_SWR: 3600,
|
|
7864
|
+
// 1 hour stale-while-revalidate
|
|
7865
|
+
HOME: 300,
|
|
7866
|
+
// 5 minutes
|
|
7867
|
+
PRODUCT: 600,
|
|
7868
|
+
// 10 minutes
|
|
7869
|
+
COLLECTION: 900,
|
|
7870
|
+
// 15 minutes
|
|
7871
|
+
PAGE: 3600,
|
|
7872
|
+
// 1 hour
|
|
7873
|
+
BLOG: 1800
|
|
7874
|
+
// 30 minutes
|
|
7875
|
+
};
|
|
7876
|
+
var WorkerHtmlCache = class {
|
|
7877
|
+
epoch;
|
|
7878
|
+
constructor(epoch) {
|
|
7879
|
+
this.epoch = epoch;
|
|
7880
|
+
}
|
|
7881
|
+
async get(request) {
|
|
7882
|
+
const trace = createTraceId();
|
|
7883
|
+
if (request.method !== "GET") {
|
|
7884
|
+
logger.debug("[SDK Html-cache] non-cacheable", { trace });
|
|
7885
|
+
return { found: false, cacheable: false };
|
|
7886
|
+
}
|
|
7887
|
+
if (!this.isCacheable(request)) {
|
|
7888
|
+
logger.debug("[SDK Html-cache] non-cacheable", { trace });
|
|
7889
|
+
return { found: false, cacheable: false };
|
|
7890
|
+
}
|
|
7891
|
+
try {
|
|
7892
|
+
const cache = await caches.open(CACHE_NAME2 + this.epoch);
|
|
7893
|
+
const cacheKey = this.buildCacheKey(request);
|
|
7894
|
+
const cached = await cache.match(cacheKey);
|
|
7895
|
+
if (!cached) {
|
|
7896
|
+
logger.debug("[SDK Html-cache] cacheable, MISS", { trace });
|
|
7897
|
+
return { found: false, cacheable: true };
|
|
7898
|
+
}
|
|
7899
|
+
const age = this.getResponseAge(cached);
|
|
7900
|
+
const ttl = parseInt(cached.headers.get("X-Original-TTL") || "") || this.getTTLForRequest(request);
|
|
7901
|
+
const swr = parseInt(cached.headers.get("X-Original-SWR") || "") || TTL_CONFIG.DEFAULT_SWR;
|
|
7902
|
+
const isStale = age >= ttl;
|
|
7903
|
+
const isExpired = age >= ttl + swr;
|
|
7904
|
+
if (!isExpired) {
|
|
7905
|
+
logger.debug("[SDK Html-cache] cacheable, HIT", {
|
|
7906
|
+
stale: isStale,
|
|
7907
|
+
age,
|
|
7908
|
+
trace
|
|
7909
|
+
});
|
|
7910
|
+
const clientResponse = this.buildClientResponse(
|
|
7911
|
+
cached,
|
|
7912
|
+
ttl,
|
|
7913
|
+
swr,
|
|
7914
|
+
isStale,
|
|
7915
|
+
age
|
|
7916
|
+
);
|
|
7917
|
+
return {
|
|
7918
|
+
found: true,
|
|
7919
|
+
stale: isStale,
|
|
7920
|
+
response: clientResponse,
|
|
7921
|
+
cacheable: true,
|
|
7922
|
+
age: Math.floor(age)
|
|
7923
|
+
};
|
|
7924
|
+
}
|
|
7925
|
+
logger.debug("[SDK Html-cache] cacheable, hit, expired", { trace });
|
|
7926
|
+
return { found: false, cacheable: true };
|
|
7927
|
+
} catch (_) {
|
|
7928
|
+
logger.warn("[SDK Html-cache] no get support", { trace });
|
|
7929
|
+
return null;
|
|
7930
|
+
}
|
|
7931
|
+
}
|
|
7932
|
+
async put(request, response) {
|
|
7933
|
+
const trace = createTraceId();
|
|
7934
|
+
if (request.method !== "GET" || !response.ok) {
|
|
7935
|
+
logger.debug("[SDK Html-cache] put skipped", { trace });
|
|
7936
|
+
return;
|
|
7937
|
+
}
|
|
7938
|
+
if (!this.isCacheable(request) || !this.isResponseCacheable(response)) {
|
|
7939
|
+
logger.debug("[SDK Html-cache] put skipped, non-cacheable", {
|
|
7940
|
+
trace
|
|
7941
|
+
});
|
|
7942
|
+
return;
|
|
7943
|
+
}
|
|
7944
|
+
try {
|
|
7945
|
+
const cache = await caches.open(CACHE_NAME2 + this.epoch);
|
|
7946
|
+
const cacheKey = this.buildCacheKey(request);
|
|
7947
|
+
const ttl = this.getTTLForRequest(request);
|
|
7948
|
+
const swr = TTL_CONFIG.DEFAULT_SWR;
|
|
7949
|
+
const headers = new Headers(response.headers);
|
|
7950
|
+
const existingCacheControl = response.headers.get("Cache-Control");
|
|
7951
|
+
if (!existingCacheControl || existingCacheControl === "public") {
|
|
7952
|
+
const internalMaxAge = ttl + swr;
|
|
7953
|
+
headers.set("Cache-Control", `public, max-age=${internalMaxAge}`);
|
|
7954
|
+
}
|
|
7955
|
+
headers.set("X-Cache-Time", (/* @__PURE__ */ new Date()).toISOString());
|
|
7956
|
+
headers.set("X-Original-TTL", ttl.toString());
|
|
7957
|
+
headers.set("X-Original-SWR", swr.toString());
|
|
7958
|
+
const cacheableResponse = new Response(response.body, {
|
|
7959
|
+
status: response.status,
|
|
7960
|
+
statusText: response.statusText,
|
|
7961
|
+
headers
|
|
7962
|
+
});
|
|
7963
|
+
await cache.put(cacheKey, cacheableResponse);
|
|
7964
|
+
logger.debug("[SDK Html-cache] put done", { trace });
|
|
7965
|
+
} catch (_) {
|
|
7966
|
+
logger.warn("[SDK Html-cache] no put support", { trace });
|
|
7967
|
+
}
|
|
7968
|
+
}
|
|
7969
|
+
/**
|
|
7970
|
+
* Build client response with correct headers
|
|
7971
|
+
*/
|
|
7972
|
+
buildClientResponse(cachedResponse, ttl, swr, isStale, age) {
|
|
7973
|
+
const headers = new Headers(cachedResponse.headers);
|
|
7974
|
+
headers.set(
|
|
7975
|
+
"Cache-Control",
|
|
7976
|
+
`public, max-age=${ttl}, stale-while-revalidate=${swr}`
|
|
7977
|
+
);
|
|
7978
|
+
headers.set("X-Cache-Status", isStale ? "STALE" : "HIT");
|
|
7979
|
+
headers.set("X-Cache-Age", Math.floor(age).toString());
|
|
7980
|
+
headers.delete("X-Original-TTL");
|
|
7981
|
+
headers.delete("X-Original-SWR");
|
|
7982
|
+
return new Response(cachedResponse.body, {
|
|
7983
|
+
status: cachedResponse.status,
|
|
7984
|
+
statusText: cachedResponse.statusText,
|
|
7985
|
+
headers
|
|
7986
|
+
});
|
|
7987
|
+
}
|
|
7988
|
+
/**
|
|
7989
|
+
* Build cache key from request using two-level structure
|
|
7990
|
+
*/
|
|
7991
|
+
buildCacheKey(request) {
|
|
7992
|
+
const url = new URL(request.url);
|
|
7993
|
+
const versionHash = this.generateVersionHash(request.headers);
|
|
7994
|
+
const normalizedQuery = this.normalizeSearchParams(url.searchParams);
|
|
7995
|
+
const cacheKeyPath = `${versionHash}${url.pathname}`;
|
|
7996
|
+
const keyUrl = new URL(`${CACHE_KEY_ORIGIN2}${cacheKeyPath}`);
|
|
7997
|
+
if (normalizedQuery) {
|
|
7998
|
+
keyUrl.search = `?${normalizedQuery}`;
|
|
7999
|
+
}
|
|
8000
|
+
const sanitizedHeaders = this.sanitizeHeaders(request.headers);
|
|
8001
|
+
return new Request(keyUrl.toString(), {
|
|
8002
|
+
method: "GET",
|
|
8003
|
+
headers: sanitizedHeaders
|
|
8004
|
+
});
|
|
8005
|
+
}
|
|
8006
|
+
/**
|
|
8007
|
+
* Sanitize headers for cache operations - minimal whitelist approach
|
|
8008
|
+
*/
|
|
8009
|
+
sanitizeHeaders(originalHeaders) {
|
|
8010
|
+
const CACHE_RELEVANT_HEADERS = [
|
|
8011
|
+
// Content negotiation (affects response format)
|
|
8012
|
+
"accept",
|
|
8013
|
+
"accept-encoding",
|
|
8014
|
+
"accept-language",
|
|
8015
|
+
// Cache control directives from client/proxy
|
|
8016
|
+
"cache-control",
|
|
8017
|
+
"pragma",
|
|
8018
|
+
// Legacy cache control
|
|
8019
|
+
// Conditional request headers (for 304 responses)
|
|
8020
|
+
"if-none-match",
|
|
8021
|
+
"if-modified-since"
|
|
8022
|
+
];
|
|
8023
|
+
const sanitized = new Headers();
|
|
8024
|
+
CACHE_RELEVANT_HEADERS.forEach((header) => {
|
|
8025
|
+
const value = originalHeaders.get(header);
|
|
8026
|
+
if (value) {
|
|
8027
|
+
sanitized.set(header, value);
|
|
8028
|
+
}
|
|
8029
|
+
});
|
|
8030
|
+
return sanitized;
|
|
8031
|
+
}
|
|
8032
|
+
/**
|
|
8033
|
+
* Generate version hash from headers and cookies
|
|
8034
|
+
*/
|
|
8035
|
+
generateVersionHash(headers) {
|
|
8036
|
+
const swellData = this.extractSwellData(headers);
|
|
8037
|
+
const versionFactors = {
|
|
8038
|
+
store: headers.get("swell-storefront-id") || "",
|
|
8039
|
+
auth: headers.get("swell-access-token") || "",
|
|
8040
|
+
theme: headers.get("swell-theme-version-hash") || "",
|
|
8041
|
+
currency: swellData["swell-currency"] || "USD",
|
|
8042
|
+
locale: headers.get("x-locale") || headers.get("accept-language")?.split(",")[0] || "default",
|
|
8043
|
+
context: headers.get("swell-storefront-context"),
|
|
8044
|
+
epoch: this.epoch
|
|
8045
|
+
};
|
|
8046
|
+
return md5(JSON.stringify(versionFactors));
|
|
8047
|
+
}
|
|
8048
|
+
/**
|
|
8049
|
+
* Extract swell-data from cookies
|
|
8050
|
+
*/
|
|
8051
|
+
extractSwellData(headers) {
|
|
8052
|
+
const cookie = headers.get("cookie");
|
|
8053
|
+
if (!cookie) return {};
|
|
8054
|
+
const swellDataMatch = cookie.match(/swell-data=([^;]+)/);
|
|
8055
|
+
if (!swellDataMatch) return {};
|
|
8056
|
+
try {
|
|
8057
|
+
const parsed = JSON.parse(decodeURIComponent(swellDataMatch[1]));
|
|
8058
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
8059
|
+
return parsed;
|
|
8060
|
+
}
|
|
8061
|
+
return {};
|
|
8062
|
+
} catch {
|
|
8063
|
+
return {};
|
|
8064
|
+
}
|
|
8065
|
+
}
|
|
8066
|
+
isCacheable(request) {
|
|
8067
|
+
const url = new URL(request.url);
|
|
8068
|
+
const headers = request.headers;
|
|
8069
|
+
if (headers.get("swell-deployment-mode") === "editor") {
|
|
8070
|
+
return false;
|
|
8071
|
+
}
|
|
8072
|
+
const skipPaths = ["/checkout"];
|
|
8073
|
+
if (skipPaths.some((path) => url.pathname.startsWith(path))) {
|
|
8074
|
+
return false;
|
|
8075
|
+
}
|
|
8076
|
+
if (headers.get("cache-control")?.includes("no-cache")) {
|
|
8077
|
+
return false;
|
|
8078
|
+
}
|
|
8079
|
+
return true;
|
|
8080
|
+
}
|
|
8081
|
+
isResponseCacheable(response) {
|
|
8082
|
+
const contentType = response.headers.get("content-type");
|
|
8083
|
+
if (!contentType?.includes("text/html")) {
|
|
8084
|
+
return false;
|
|
8085
|
+
}
|
|
8086
|
+
const cacheControl = response.headers.get("cache-control");
|
|
8087
|
+
if (cacheControl?.includes("no-store") || cacheControl?.includes("private")) {
|
|
8088
|
+
return false;
|
|
8089
|
+
}
|
|
8090
|
+
return true;
|
|
8091
|
+
}
|
|
8092
|
+
getTTLForRequest(request) {
|
|
8093
|
+
const url = new URL(request.url);
|
|
8094
|
+
const path = url.pathname;
|
|
8095
|
+
if (path === "/") {
|
|
8096
|
+
return TTL_CONFIG.HOME;
|
|
8097
|
+
}
|
|
8098
|
+
if (path.startsWith("/products/")) {
|
|
8099
|
+
return TTL_CONFIG.PRODUCT;
|
|
8100
|
+
}
|
|
8101
|
+
if (path.startsWith("/categories/")) {
|
|
8102
|
+
return TTL_CONFIG.COLLECTION;
|
|
8103
|
+
}
|
|
8104
|
+
if (path.startsWith("/pages/")) {
|
|
8105
|
+
return TTL_CONFIG.PAGE;
|
|
8106
|
+
}
|
|
8107
|
+
if (path.startsWith("/blogs/")) {
|
|
8108
|
+
return TTL_CONFIG.BLOG;
|
|
8109
|
+
}
|
|
8110
|
+
return TTL_CONFIG.DEFAULT;
|
|
8111
|
+
}
|
|
8112
|
+
getResponseAge(response) {
|
|
8113
|
+
const cacheTime = response.headers.get("X-Cache-Time");
|
|
8114
|
+
if (!cacheTime) {
|
|
8115
|
+
return Infinity;
|
|
8116
|
+
}
|
|
8117
|
+
const cacheDate = new Date(cacheTime);
|
|
8118
|
+
if (isNaN(cacheDate.getTime())) {
|
|
8119
|
+
return Infinity;
|
|
8120
|
+
}
|
|
8121
|
+
const age = (Date.now() - cacheDate.getTime()) / 1e3;
|
|
8122
|
+
return Math.max(0, age);
|
|
8123
|
+
}
|
|
8124
|
+
getMaxAge(response) {
|
|
8125
|
+
const cacheControl = response.headers.get("Cache-Control");
|
|
8126
|
+
if (!cacheControl) {
|
|
8127
|
+
return TTL_CONFIG.DEFAULT;
|
|
8128
|
+
}
|
|
8129
|
+
const maxAgeMatch = cacheControl.match(/max-age=(\d+)/);
|
|
8130
|
+
if (maxAgeMatch) {
|
|
8131
|
+
return parseInt(maxAgeMatch[1], 10);
|
|
8132
|
+
}
|
|
8133
|
+
return TTL_CONFIG.DEFAULT;
|
|
8134
|
+
}
|
|
8135
|
+
getStaleWindow(response) {
|
|
8136
|
+
const cacheControl = response.headers.get("Cache-Control");
|
|
8137
|
+
if (!cacheControl) {
|
|
8138
|
+
return TTL_CONFIG.DEFAULT_SWR;
|
|
8139
|
+
}
|
|
8140
|
+
const swrMatch = cacheControl.match(/stale-while-revalidate=(\d+)/);
|
|
8141
|
+
if (swrMatch) {
|
|
8142
|
+
return parseInt(swrMatch[1], 10);
|
|
8143
|
+
}
|
|
8144
|
+
return TTL_CONFIG.DEFAULT_SWR;
|
|
8145
|
+
}
|
|
8146
|
+
/**
|
|
8147
|
+
* Normalize search params for cache key
|
|
8148
|
+
*/
|
|
8149
|
+
normalizeSearchParams(searchParams) {
|
|
8150
|
+
const ignoredParams = [
|
|
8151
|
+
"utm_source",
|
|
8152
|
+
"utm_medium",
|
|
8153
|
+
"utm_campaign",
|
|
8154
|
+
"utm_content",
|
|
8155
|
+
"utm_term",
|
|
8156
|
+
"fbclid",
|
|
8157
|
+
"gclid",
|
|
8158
|
+
"gbraid",
|
|
8159
|
+
"wbraid",
|
|
8160
|
+
"ref",
|
|
8161
|
+
"source",
|
|
8162
|
+
"mc_cid",
|
|
8163
|
+
"mc_eid"
|
|
8164
|
+
];
|
|
8165
|
+
const relevantParams = [];
|
|
8166
|
+
searchParams.forEach((value, key) => {
|
|
8167
|
+
if (!ignoredParams.includes(key)) {
|
|
8168
|
+
relevantParams.push(
|
|
8169
|
+
`${encodeURIComponent(key)}=${encodeURIComponent(value)}`
|
|
8170
|
+
);
|
|
8171
|
+
}
|
|
8172
|
+
});
|
|
8173
|
+
return relevantParams.sort().join("&");
|
|
8174
|
+
}
|
|
8175
|
+
};
|
|
8176
|
+
|
|
7852
8177
|
// src/resources/addresses.ts
|
|
7853
8178
|
var SwellAddresses = class extends SwellStorefrontCollection {
|
|
7854
8179
|
constructor(swell, query) {
|
|
@@ -8676,13 +9001,19 @@ var Swell = class _Swell {
|
|
|
8676
9001
|
const storefrontRequest = storefront.request;
|
|
8677
9002
|
return (method, url, id, data, opt) => {
|
|
8678
9003
|
if (this.isStorefrontRequestCacheable(method, url, opt)) {
|
|
8679
|
-
|
|
8680
|
-
|
|
8681
|
-
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
9004
|
+
const key = getCacheKey("request", [
|
|
9005
|
+
this.instanceId,
|
|
9006
|
+
method,
|
|
9007
|
+
url,
|
|
9008
|
+
id,
|
|
9009
|
+
data,
|
|
9010
|
+
opt
|
|
9011
|
+
]);
|
|
9012
|
+
return this.getRequestCache().fetchSWR(key, () => {
|
|
9013
|
+
const requestUrl = id ? `${url}/${id}` : url;
|
|
9014
|
+
logger.debug("[SDK] Cacheable API request", { url: requestUrl, key });
|
|
9015
|
+
return storefrontRequest(method, url, id, data, opt);
|
|
9016
|
+
});
|
|
8686
9017
|
}
|
|
8687
9018
|
switch (method) {
|
|
8688
9019
|
case "delete":
|
|
@@ -8729,7 +9060,9 @@ var Swell = class _Swell {
|
|
|
8729
9060
|
};
|
|
8730
9061
|
function getCacheKey(key, args) {
|
|
8731
9062
|
if (Array.isArray(args) && args.length > 0) {
|
|
8732
|
-
|
|
9063
|
+
const fullKey = `${key}_${md5(JSON.stringify(args))}`;
|
|
9064
|
+
logger.debug(`[SDK] make cache key: ${fullKey}`);
|
|
9065
|
+
return fullKey;
|
|
8733
9066
|
}
|
|
8734
9067
|
return key;
|
|
8735
9068
|
}
|
|
@@ -22504,6 +22837,7 @@ function getResourceQuery(slug, query) {
|
|
|
22504
22837
|
ThemeFont,
|
|
22505
22838
|
ThemeForm,
|
|
22506
22839
|
ThemeFormErrors,
|
|
22840
|
+
WorkerHtmlCache,
|
|
22507
22841
|
adaptShopifyFontData,
|
|
22508
22842
|
adaptShopifyFormData,
|
|
22509
22843
|
adaptShopifyMenuData,
|