@swell/apps-sdk 1.0.157 → 1.0.159
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 +81 -164
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +81 -164
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +81 -164
- package/dist/index.mjs.map +4 -4
- package/dist/src/theme/theme-loader.d.ts +9 -0
- package/dist/types/shopify.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -139,7 +139,7 @@ var CFWorkerKVKeyvAdapter = class {
|
|
|
139
139
|
if (typeof ttl === "number") {
|
|
140
140
|
ttl = Math.max(60, ttl / 1e3);
|
|
141
141
|
}
|
|
142
|
-
logger.debug("[SDK] kv.set", { key });
|
|
142
|
+
logger.debug("[SDK] kv.set", { key, ttl });
|
|
143
143
|
return this.store.put(key, value, { expirationTtl: ttl });
|
|
144
144
|
}
|
|
145
145
|
async delete(key) {
|
|
@@ -718,7 +718,6 @@ var RESOURCE_CLONE_PROPS = Object.freeze([
|
|
|
718
718
|
"_getResourceObject",
|
|
719
719
|
"_collection",
|
|
720
720
|
"_swell",
|
|
721
|
-
"_query",
|
|
722
721
|
"_params",
|
|
723
722
|
"_id",
|
|
724
723
|
"_resourceName"
|
|
@@ -7282,6 +7281,14 @@ function buildStores2() {
|
|
|
7282
7281
|
|
|
7283
7282
|
// src/cache/theme-cache.ts
|
|
7284
7283
|
var TTL = 90 * 24 * 60 * 60 * 1e3;
|
|
7284
|
+
var ThemeCache = class extends Cache {
|
|
7285
|
+
constructor(options) {
|
|
7286
|
+
super({
|
|
7287
|
+
ttl: TTL,
|
|
7288
|
+
...options
|
|
7289
|
+
});
|
|
7290
|
+
}
|
|
7291
|
+
};
|
|
7285
7292
|
|
|
7286
7293
|
// src/cache/theme-file-storage.ts
|
|
7287
7294
|
import bluebird2 from "bluebird";
|
|
@@ -7623,139 +7630,29 @@ var MINUTE = 60 * SECOND;
|
|
|
7623
7630
|
var HOUR = 60 * MINUTE;
|
|
7624
7631
|
var DAY = 24 * HOUR;
|
|
7625
7632
|
var YEAR = 365 * DAY;
|
|
7626
|
-
var MAX_TTL = YEAR;
|
|
7627
7633
|
var SHORT_TTL = 5 * SECOND;
|
|
7628
7634
|
|
|
7629
|
-
// src/cache/worker-cache-proxy.ts
|
|
7630
|
-
var CACHE_NAME = "swell-cache-v011";
|
|
7631
|
-
var CACHE_KEY_ORIGIN = "https://cache.swell.store";
|
|
7632
|
-
var WorkerCacheProxy = class {
|
|
7633
|
-
swell;
|
|
7634
|
-
constructor(swell) {
|
|
7635
|
-
this.swell = swell;
|
|
7636
|
-
}
|
|
7637
|
-
/**
|
|
7638
|
-
* Reads a JSON value from Worker Cache using a key built from path+query.
|
|
7639
|
-
* Returns null on miss or if running outside of a Worker environment.
|
|
7640
|
-
*/
|
|
7641
|
-
async get(path, query, opts) {
|
|
7642
|
-
if (typeof caches === "undefined") {
|
|
7643
|
-
return null;
|
|
7644
|
-
}
|
|
7645
|
-
const { keyUrl } = await this.buildKeyUrl(path, query, opts?.version);
|
|
7646
|
-
try {
|
|
7647
|
-
const cache = await caches.open(CACHE_NAME);
|
|
7648
|
-
const match = await cache.match(keyUrl);
|
|
7649
|
-
if (!match) return null;
|
|
7650
|
-
const data = await match.json();
|
|
7651
|
-
return data;
|
|
7652
|
-
} catch {
|
|
7653
|
-
return null;
|
|
7654
|
-
}
|
|
7655
|
-
}
|
|
7656
|
-
/**
|
|
7657
|
-
* Stores a JSON value in Worker Cache under key built from path+query.
|
|
7658
|
-
* No-ops outside of a Worker environment.
|
|
7659
|
-
*/
|
|
7660
|
-
async put(path, query, value, opts) {
|
|
7661
|
-
if (typeof caches === "undefined") {
|
|
7662
|
-
return;
|
|
7663
|
-
}
|
|
7664
|
-
const { keyUrl, hasVersion } = await this.buildKeyUrl(
|
|
7665
|
-
path,
|
|
7666
|
-
query,
|
|
7667
|
-
opts?.version
|
|
7668
|
-
);
|
|
7669
|
-
const ttlMs = hasVersion ? MAX_TTL : SHORT_TTL;
|
|
7670
|
-
try {
|
|
7671
|
-
const cache = await caches.open(CACHE_NAME);
|
|
7672
|
-
const response = new Response(JSON.stringify(value), {
|
|
7673
|
-
headers: {
|
|
7674
|
-
"Content-Type": "application/json",
|
|
7675
|
-
"Cache-Control": `public, max-age=${Math.floor(ttlMs / 1e3)}`
|
|
7676
|
-
}
|
|
7677
|
-
});
|
|
7678
|
-
await cache.put(keyUrl, response);
|
|
7679
|
-
logger.debug("[SDK] cache put done", { keyUrl });
|
|
7680
|
-
} catch {
|
|
7681
|
-
}
|
|
7682
|
-
}
|
|
7683
|
-
/**
|
|
7684
|
-
* Builds a deterministic key URL for Worker Cache from the backend API URL
|
|
7685
|
-
* composed using path and query. Includes tenant and auth isolation and an
|
|
7686
|
-
* optional version segment.
|
|
7687
|
-
*/
|
|
7688
|
-
async buildKeyUrl(path, query, explicitVersion) {
|
|
7689
|
-
const apiHost = this.swell.backend?.apiHost;
|
|
7690
|
-
const endpointPath = String(path).startsWith("/") ? String(path).substring(1) : String(path);
|
|
7691
|
-
let queryString = "";
|
|
7692
|
-
if (query && this.swell.backend) {
|
|
7693
|
-
queryString = this.swell.backend.stringifyQuery(query);
|
|
7694
|
-
}
|
|
7695
|
-
const fullUrl = `${apiHost}/${endpointPath}${queryString ? `?${queryString}` : ""}`;
|
|
7696
|
-
const instanceId = this.swell.instanceId || "";
|
|
7697
|
-
const authKey = String(this.swell.swellHeaders?.["swell-auth-key"] || "");
|
|
7698
|
-
const tenantHash = await this.sha256Hex(`${instanceId}|${authKey}`);
|
|
7699
|
-
const version = explicitVersion !== void 0 ? explicitVersion : this.swell.swellHeaders?.["theme-version-hash"] || null;
|
|
7700
|
-
const hasVersion = Boolean(version);
|
|
7701
|
-
const versionHash = hasVersion ? await this.sha256Hex(String(version)) : null;
|
|
7702
|
-
const urlHash = await this.sha256Hex(fullUrl);
|
|
7703
|
-
const keyUrl = versionHash ? `${CACHE_KEY_ORIGIN}/v1/${tenantHash}/${versionHash}/${urlHash}` : `${CACHE_KEY_ORIGIN}/v1/${tenantHash}/${urlHash}`;
|
|
7704
|
-
return { keyUrl, hasVersion };
|
|
7705
|
-
}
|
|
7706
|
-
/**
|
|
7707
|
-
* SHA-256 digest with hex encoding. Requires Worker crypto; callers
|
|
7708
|
-
* should avoid invoking this outside of Worker code paths.
|
|
7709
|
-
*/
|
|
7710
|
-
async sha256Hex(input) {
|
|
7711
|
-
if (typeof crypto !== "undefined" && crypto.subtle && crypto.subtle.digest) {
|
|
7712
|
-
const encoder = new TextEncoder();
|
|
7713
|
-
const digest = await crypto.subtle.digest(
|
|
7714
|
-
"SHA-256",
|
|
7715
|
-
encoder.encode(input)
|
|
7716
|
-
);
|
|
7717
|
-
const bytes = new Uint8Array(digest);
|
|
7718
|
-
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
7719
|
-
}
|
|
7720
|
-
return md5(input);
|
|
7721
|
-
}
|
|
7722
|
-
};
|
|
7723
|
-
|
|
7724
7635
|
// src/cache/worker-html-cache.ts
|
|
7725
|
-
var
|
|
7726
|
-
var
|
|
7636
|
+
var CACHE_NAME = "swell-html-v0";
|
|
7637
|
+
var CACHE_KEY_ORIGIN = "https://cache.swell.store";
|
|
7727
7638
|
var TTL_CONFIG = {
|
|
7728
7639
|
LIVE: {
|
|
7729
|
-
DEFAULT:
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
// 15 minutes
|
|
7737
|
-
PAGE: 3600,
|
|
7738
|
-
// 1 hour
|
|
7739
|
-
BLOG: 1800,
|
|
7740
|
-
// 30 minutes
|
|
7741
|
-
SWR: 3600
|
|
7742
|
-
// 1 hour stale-while-revalidate
|
|
7640
|
+
DEFAULT: 20,
|
|
7641
|
+
HOME: 20,
|
|
7642
|
+
PRODUCT: 20,
|
|
7643
|
+
COLLECTION: 20,
|
|
7644
|
+
PAGE: 20,
|
|
7645
|
+
BLOG: 20,
|
|
7646
|
+
SWR: 180
|
|
7743
7647
|
},
|
|
7744
7648
|
PREVIEW: {
|
|
7745
|
-
DEFAULT:
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
// 3 minutes
|
|
7753
|
-
PAGE: 5,
|
|
7754
|
-
// 5 minutes
|
|
7755
|
-
BLOG: 5,
|
|
7756
|
-
// 5 minutes
|
|
7757
|
-
SWR: 600
|
|
7758
|
-
// 10 minutes stale-while-revalidate
|
|
7649
|
+
DEFAULT: 20,
|
|
7650
|
+
HOME: 20,
|
|
7651
|
+
PRODUCT: 20,
|
|
7652
|
+
COLLECTION: 20,
|
|
7653
|
+
PAGE: 20,
|
|
7654
|
+
BLOG: 20,
|
|
7655
|
+
SWR: 180
|
|
7759
7656
|
}
|
|
7760
7657
|
};
|
|
7761
7658
|
var WorkerHtmlCache = class {
|
|
@@ -7774,7 +7671,7 @@ var WorkerHtmlCache = class {
|
|
|
7774
7671
|
return { found: false, cacheable: false };
|
|
7775
7672
|
}
|
|
7776
7673
|
try {
|
|
7777
|
-
const cache = await caches.open(
|
|
7674
|
+
const cache = await caches.open(CACHE_NAME + this.epoch);
|
|
7778
7675
|
const cacheKey = this.buildCacheKey(request);
|
|
7779
7676
|
const cached = await cache.match(cacheKey);
|
|
7780
7677
|
if (!cached) {
|
|
@@ -7877,7 +7774,7 @@ var WorkerHtmlCache = class {
|
|
|
7877
7774
|
return;
|
|
7878
7775
|
}
|
|
7879
7776
|
try {
|
|
7880
|
-
const cache = await caches.open(
|
|
7777
|
+
const cache = await caches.open(CACHE_NAME + this.epoch);
|
|
7881
7778
|
const cacheKey = this.buildCacheKey(request);
|
|
7882
7779
|
await cache.delete(cacheKey);
|
|
7883
7780
|
const ttl = this.getTTLForRequest(request);
|
|
@@ -7937,7 +7834,7 @@ var WorkerHtmlCache = class {
|
|
|
7937
7834
|
const versionHash = this.generateVersionHash(request.headers);
|
|
7938
7835
|
const normalizedQuery = this.normalizeSearchParams(url.searchParams);
|
|
7939
7836
|
const cacheKeyPath = `${versionHash}${url.pathname}`;
|
|
7940
|
-
const keyUrl = new URL(`${
|
|
7837
|
+
const keyUrl = new URL(`${CACHE_KEY_ORIGIN}${cacheKeyPath}`);
|
|
7941
7838
|
if (normalizedQuery) {
|
|
7942
7839
|
keyUrl.search = `?${normalizedQuery}`;
|
|
7943
7840
|
}
|
|
@@ -15266,15 +15163,32 @@ function ShopifyBlog(instance, blogCategory) {
|
|
|
15266
15163
|
return new ShopifyResource({
|
|
15267
15164
|
all_tags: allTags,
|
|
15268
15165
|
articles: deferWith(blogCategory, (blogCategory2) => {
|
|
15269
|
-
|
|
15270
|
-
|
|
15271
|
-
|
|
15272
|
-
|
|
15273
|
-
|
|
15274
|
-
|
|
15275
|
-
|
|
15166
|
+
const { page, limit: limit2 } = instance.swell.queryParams;
|
|
15167
|
+
const categoryBlogs = new SwellStorefrontCollection(
|
|
15168
|
+
instance.swell,
|
|
15169
|
+
"content/blogs",
|
|
15170
|
+
{
|
|
15171
|
+
page,
|
|
15172
|
+
limit: limit2,
|
|
15173
|
+
category_id: blogCategory2.id,
|
|
15174
|
+
expand: "author"
|
|
15175
|
+
},
|
|
15176
|
+
async function() {
|
|
15177
|
+
return this._defaultGetter().call(this);
|
|
15276
15178
|
}
|
|
15277
|
-
)
|
|
15179
|
+
);
|
|
15180
|
+
return categoryBlogs._cloneWithCompatibilityResult((blogs) => {
|
|
15181
|
+
return {
|
|
15182
|
+
...blogs,
|
|
15183
|
+
results: blogs?.results?.map(
|
|
15184
|
+
(blog) => ShopifyArticle(
|
|
15185
|
+
instance,
|
|
15186
|
+
blog,
|
|
15187
|
+
blogCategory2
|
|
15188
|
+
)
|
|
15189
|
+
)
|
|
15190
|
+
};
|
|
15191
|
+
}) || [];
|
|
15278
15192
|
}),
|
|
15279
15193
|
articles_count: deferWith(blogCategory.blogs, (blogs) => blogs?.count || 0),
|
|
15280
15194
|
handle: defer(() => blogCategory.slug),
|
|
@@ -20443,7 +20357,8 @@ function getLiquidFS(getThemeConfig, extName) {
|
|
|
20443
20357
|
|
|
20444
20358
|
// src/theme/theme-loader.ts
|
|
20445
20359
|
var MAX_INDIVIDUAL_CONFIGS_TO_FETCH = 50;
|
|
20446
|
-
var ThemeLoader = class {
|
|
20360
|
+
var ThemeLoader = class _ThemeLoader {
|
|
20361
|
+
static cache = null;
|
|
20447
20362
|
swell;
|
|
20448
20363
|
configs;
|
|
20449
20364
|
constructor(swell) {
|
|
@@ -20584,24 +20499,14 @@ var ThemeLoader = class {
|
|
|
20584
20499
|
limit: 1e3,
|
|
20585
20500
|
type: "theme",
|
|
20586
20501
|
fields: "id, name, type, file, file_path, hash"
|
|
20587
|
-
// NO file_data
|
|
20588
20502
|
};
|
|
20589
|
-
const cache = new WorkerCacheProxy(this.swell);
|
|
20590
20503
|
const versionHash = this.swell.swellHeaders["theme-version-hash"];
|
|
20591
|
-
|
|
20592
|
-
|
|
20593
|
-
|
|
20594
|
-
|
|
20595
|
-
|
|
20596
|
-
|
|
20597
|
-
}
|
|
20598
|
-
);
|
|
20599
|
-
if (cached) {
|
|
20600
|
-
logger.debug("[ThemeLoader] Config metadata cache hit");
|
|
20601
|
-
return cached;
|
|
20602
|
-
}
|
|
20603
|
-
} catch (err) {
|
|
20604
|
-
logger.warn("[ThemeLoader] Cache read failed, fetching from API", err);
|
|
20504
|
+
const cacheKey = this.buildMetadataCacheKey(versionHash, query);
|
|
20505
|
+
const cache = this.getCache();
|
|
20506
|
+
const cached = await cache.get(cacheKey);
|
|
20507
|
+
if (cached) {
|
|
20508
|
+
logger.debug("[ThemeLoader] Config metadata cache hit");
|
|
20509
|
+
return cached;
|
|
20605
20510
|
}
|
|
20606
20511
|
logger.debug("[ThemeLoader] Fetching config metadata from API");
|
|
20607
20512
|
const response = await this.swell.get(
|
|
@@ -20609,14 +20514,7 @@ var ThemeLoader = class {
|
|
|
20609
20514
|
query
|
|
20610
20515
|
);
|
|
20611
20516
|
const configs = response?.results || [];
|
|
20612
|
-
|
|
20613
|
-
if (ctx && typeof ctx.waitUntil === "function") {
|
|
20614
|
-
ctx.waitUntil(
|
|
20615
|
-
cache.put("/:themes:configs", query, configs, {
|
|
20616
|
-
version: versionHash || null
|
|
20617
|
-
})
|
|
20618
|
-
);
|
|
20619
|
-
}
|
|
20517
|
+
await cache.set(cacheKey, configs);
|
|
20620
20518
|
return configs;
|
|
20621
20519
|
}
|
|
20622
20520
|
/**
|
|
@@ -20721,6 +20619,25 @@ var ThemeLoader = class {
|
|
|
20721
20619
|
preview: swellHeaders["deployment-mode"] === "editor" || swellHeaders["deployment-mode"] === "preview" ? true : { $ne: true }
|
|
20722
20620
|
};
|
|
20723
20621
|
}
|
|
20622
|
+
/**
|
|
20623
|
+
* Build cache key with tenant isolation for metadata
|
|
20624
|
+
*/
|
|
20625
|
+
buildMetadataCacheKey(version, query) {
|
|
20626
|
+
const args = [this.swell.instanceId, version || "default", query];
|
|
20627
|
+
return `theme_configs:${md5(JSON.stringify(args))}`;
|
|
20628
|
+
}
|
|
20629
|
+
/**
|
|
20630
|
+
* Get or create the theme cache instance
|
|
20631
|
+
*/
|
|
20632
|
+
getCache() {
|
|
20633
|
+
if (!_ThemeLoader.cache) {
|
|
20634
|
+
_ThemeLoader.cache = new ThemeCache({
|
|
20635
|
+
kvStore: this.swell.workerEnv?.THEME,
|
|
20636
|
+
workerCtx: this.swell.workerCtx
|
|
20637
|
+
});
|
|
20638
|
+
}
|
|
20639
|
+
return _ThemeLoader.cache;
|
|
20640
|
+
}
|
|
20724
20641
|
};
|
|
20725
20642
|
|
|
20726
20643
|
// src/globals.ts
|