@swell/apps-sdk 1.0.138 → 1.0.140
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 +159 -71
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +159 -71
- package/dist/index.js.map +3 -3
- package/dist/index.mjs +159 -71
- package/dist/index.mjs.map +3 -3
- package/dist/src/cache/cache.d.ts +10 -5
- package/dist/src/cache/cf-worker-kv-keyv-adapter.d.ts +8 -5
- package/dist/src/cache/index.d.ts +4 -5
- package/dist/src/cache/request-cache.d.ts +1 -2
- package/dist/src/theme/theme-loader.d.ts +8 -3
- package/dist/src/theme.d.ts +3 -3
- package/dist/types/swell.d.ts +22 -7
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -16,31 +16,44 @@ import {
|
|
|
16
16
|
|
|
17
17
|
// src/cache/cf-worker-kv-keyv-adapter.ts
|
|
18
18
|
var CFWorkerKVKeyvAdapter = class {
|
|
19
|
+
store;
|
|
19
20
|
namespace;
|
|
20
21
|
// magically passed in from Keyv
|
|
21
|
-
|
|
22
|
+
opts;
|
|
22
23
|
constructor(store) {
|
|
23
24
|
this.store = store;
|
|
25
|
+
this.opts = null;
|
|
24
26
|
this.namespace = "dummy";
|
|
25
27
|
}
|
|
26
28
|
async has(key) {
|
|
27
|
-
|
|
29
|
+
const stream = await this.store.get(key, "stream");
|
|
30
|
+
if (stream !== null) {
|
|
31
|
+
await stream.cancel();
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
28
35
|
}
|
|
29
36
|
async get(key) {
|
|
30
|
-
|
|
37
|
+
const value = await this.store.get(key);
|
|
38
|
+
return value !== null ? value : void 0;
|
|
31
39
|
}
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
set(key, value, ttl) {
|
|
41
|
+
if (typeof ttl === "number") {
|
|
42
|
+
ttl = Math.max(60, ttl / 1e3);
|
|
43
|
+
}
|
|
44
|
+
return this.store.put(key, value, { expirationTtl: ttl });
|
|
34
45
|
}
|
|
35
46
|
async delete(key) {
|
|
36
47
|
await this.store.delete(key);
|
|
48
|
+
return true;
|
|
37
49
|
}
|
|
38
50
|
async clear() {
|
|
39
51
|
let cursor = "";
|
|
40
52
|
let complete = false;
|
|
41
|
-
|
|
53
|
+
const prefix = `${this.namespace}:`;
|
|
54
|
+
do {
|
|
42
55
|
const response = await this.store.list({
|
|
43
|
-
prefix
|
|
56
|
+
prefix,
|
|
44
57
|
cursor: cursor || void 0
|
|
45
58
|
});
|
|
46
59
|
cursor = response.cursor ?? "";
|
|
@@ -52,7 +65,10 @@ var CFWorkerKVKeyvAdapter = class {
|
|
|
52
65
|
})
|
|
53
66
|
);
|
|
54
67
|
}
|
|
55
|
-
}
|
|
68
|
+
} while (!complete);
|
|
69
|
+
}
|
|
70
|
+
on(_event, _listener) {
|
|
71
|
+
return this;
|
|
56
72
|
}
|
|
57
73
|
};
|
|
58
74
|
|
|
@@ -6956,23 +6972,25 @@ var Cache = class {
|
|
|
6956
6972
|
...options
|
|
6957
6973
|
});
|
|
6958
6974
|
}
|
|
6959
|
-
async fetch(key, fetchFn) {
|
|
6960
|
-
return this.client.wrap(key, fetchFn);
|
|
6975
|
+
async fetch(key, fetchFn, ttl) {
|
|
6976
|
+
return this.client.wrap(key, fetchFn, ttl);
|
|
6961
6977
|
}
|
|
6962
|
-
|
|
6963
|
-
|
|
6978
|
+
/**
|
|
6979
|
+
* Fetch cache using SWR (stale-while-revalidate)
|
|
6980
|
+
*
|
|
6981
|
+
* This will always return the cached value immediately if exists
|
|
6982
|
+
*/
|
|
6964
6983
|
async fetchSWR(key, fetchFn, ttl = DEFAULT_SWR_TTL) {
|
|
6965
6984
|
const cacheValue = await this.client.get(key);
|
|
6966
|
-
const promiseValue = Promise.resolve().then(
|
|
6985
|
+
const promiseValue = Promise.resolve().then(fetchFn).then(resolveAsyncResources).then(async (value) => {
|
|
6967
6986
|
const isNull = value === null || value === void 0;
|
|
6968
|
-
|
|
6969
|
-
await this.client.set(key, isNull ? NULL_VALUE : valueResolved, ttl);
|
|
6987
|
+
await this.client.set(key, isNull ? NULL_VALUE : value, ttl);
|
|
6970
6988
|
return value;
|
|
6971
6989
|
});
|
|
6972
6990
|
if (this.workerCtx?.waitUntil) {
|
|
6973
6991
|
this.workerCtx.waitUntil(promiseValue);
|
|
6974
6992
|
}
|
|
6975
|
-
if (cacheValue !==
|
|
6993
|
+
if (cacheValue !== void 0) {
|
|
6976
6994
|
return cacheValue === NULL_VALUE ? null : cacheValue;
|
|
6977
6995
|
}
|
|
6978
6996
|
const result = await promiseValue;
|
|
@@ -6989,8 +7007,9 @@ var Cache = class {
|
|
|
6989
7007
|
}
|
|
6990
7008
|
/**
|
|
6991
7009
|
* Flushes the entire cache.
|
|
6992
|
-
*
|
|
6993
|
-
*
|
|
7010
|
+
*
|
|
7011
|
+
* __WARNING__: If the cache store is shared among many cache clients,
|
|
7012
|
+
* this will flush entries for other clients.
|
|
6994
7013
|
*/
|
|
6995
7014
|
async flushAll() {
|
|
6996
7015
|
await this.client.clear();
|
|
@@ -7033,7 +7052,7 @@ var ResourceCache = class extends Cache {
|
|
|
7033
7052
|
function buildStores2() {
|
|
7034
7053
|
return [
|
|
7035
7054
|
new Keyv2({
|
|
7036
|
-
// Disabling serialization allows for pure
|
|
7055
|
+
// Disabling serialization allows for pure memoization of class instances
|
|
7037
7056
|
// at the tradeoff of no support for compression.
|
|
7038
7057
|
serialize: void 0,
|
|
7039
7058
|
deserialize: void 0
|
|
@@ -18111,10 +18130,10 @@ var svgs = {
|
|
|
18111
18130
|
src: "https://cdn.swell.store/schema/685ef581b79e3e0012cf3222/fba884c7fe8122c472e130355fb52db7/collection-6.png"
|
|
18112
18131
|
},
|
|
18113
18132
|
"lifestyle-1": {
|
|
18114
|
-
src: "https://cdn.swell.store/schema/
|
|
18133
|
+
src: "https://cdn.swell.store/schema/6870eddc1657130012643fc6/1777bcff40736610093833ef858b5936/lifestyle-1.png"
|
|
18115
18134
|
},
|
|
18116
18135
|
"lifestyle-2": {
|
|
18117
|
-
src: "https://cdn.swell.store/schema/
|
|
18136
|
+
src: "https://cdn.swell.store/schema/6870eddc1657130012643fcb/4d29197e3fa0b6d8255c1b7770f8dc12/lifestyle-2.png"
|
|
18118
18137
|
},
|
|
18119
18138
|
"product-apparel-1": {
|
|
18120
18139
|
src: "https://cdn.swell.store/schema/685ef58eb79e3e0012cf3276/37c3c973a01287a580ab9db2e05dd36d/product-apparel-1.png"
|
|
@@ -18712,12 +18731,11 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18712
18731
|
this.configPaths = [];
|
|
18713
18732
|
}
|
|
18714
18733
|
async init(themeConfigs) {
|
|
18715
|
-
const { swellHeaders } = this.swell;
|
|
18716
18734
|
if (themeConfigs) {
|
|
18717
18735
|
this.setConfigs(themeConfigs);
|
|
18718
18736
|
return;
|
|
18719
18737
|
}
|
|
18720
|
-
if (!
|
|
18738
|
+
if (!this.getThemeId()) {
|
|
18721
18739
|
return;
|
|
18722
18740
|
}
|
|
18723
18741
|
await this.fetchManifest();
|
|
@@ -18756,25 +18774,45 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18756
18774
|
*/
|
|
18757
18775
|
setConfigs(themeConfigs) {
|
|
18758
18776
|
this.configs = new Map(themeConfigs);
|
|
18777
|
+
this.manifest = /* @__PURE__ */ new Map();
|
|
18778
|
+
for (const { file_path, hash } of this.configs.values()) {
|
|
18779
|
+
this.manifest.set(file_path, hash);
|
|
18780
|
+
}
|
|
18759
18781
|
this.configPaths = Array.from(this.configs.keys());
|
|
18760
|
-
this.manifest = this.configPaths.reduce((manifest, path) => {
|
|
18761
|
-
manifest[path] = this.configs.get(path)?.hash;
|
|
18762
|
-
return manifest;
|
|
18763
|
-
}, {});
|
|
18764
18782
|
}
|
|
18765
18783
|
/**
|
|
18766
18784
|
* Preloads a theme version and configs. This is used to optimize initial theme load.
|
|
18767
18785
|
*/
|
|
18768
|
-
async preloadTheme(
|
|
18786
|
+
async preloadTheme(payload) {
|
|
18787
|
+
const { version, configs } = payload;
|
|
18769
18788
|
console.log(
|
|
18770
18789
|
`ThemeLoader.preloadTheme${version?.hash ? ` - manifest: ${version.hash}` : ""}${configs?.length ? ` - configs: ${configs.length}` : ""}`
|
|
18771
18790
|
);
|
|
18772
|
-
|
|
18773
|
-
|
|
18774
|
-
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18791
|
+
const promises = [];
|
|
18792
|
+
if (version) {
|
|
18793
|
+
promises.push(this.cacheManifest(version));
|
|
18794
|
+
}
|
|
18795
|
+
if (configs) {
|
|
18796
|
+
const themeId = this.getThemeId();
|
|
18797
|
+
promises.push(
|
|
18798
|
+
Promise2.map(
|
|
18799
|
+
configs,
|
|
18800
|
+
async (config) => {
|
|
18801
|
+
const promises2 = [
|
|
18802
|
+
this.cacheThemeConfig(config)
|
|
18803
|
+
];
|
|
18804
|
+
if (themeId && config.file?.url) {
|
|
18805
|
+
promises2.push(
|
|
18806
|
+
this.cacheThemeFileUrl(themeId, config.hash, config.file.url)
|
|
18807
|
+
);
|
|
18808
|
+
}
|
|
18809
|
+
await Promise2.all(promises2);
|
|
18810
|
+
},
|
|
18811
|
+
{ concurrency: 10 }
|
|
18812
|
+
)
|
|
18813
|
+
);
|
|
18814
|
+
}
|
|
18815
|
+
await Promise2.all(promises);
|
|
18778
18816
|
}
|
|
18779
18817
|
/**
|
|
18780
18818
|
* Fetches a theme config by file path.
|
|
@@ -18784,18 +18822,28 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18784
18822
|
if (config !== void 0) {
|
|
18785
18823
|
return config;
|
|
18786
18824
|
}
|
|
18787
|
-
const hash = this.manifest?.
|
|
18788
|
-
if (hash) {
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
|
|
18792
|
-
|
|
18793
|
-
|
|
18794
|
-
|
|
18825
|
+
const hash = this.manifest?.get(filePath);
|
|
18826
|
+
if (!hash) {
|
|
18827
|
+
return null;
|
|
18828
|
+
}
|
|
18829
|
+
const cache = this.getCache();
|
|
18830
|
+
const themeId = this.getThemeId();
|
|
18831
|
+
const [themeConfig, fileUrl] = await Promise2.all([
|
|
18832
|
+
cache.get(`config:${hash}`),
|
|
18833
|
+
themeId ? cache.get(`file:${themeId}:${hash}`) : void 0
|
|
18834
|
+
]);
|
|
18835
|
+
if (themeConfig) {
|
|
18836
|
+
let config2 = themeConfig;
|
|
18837
|
+
if (fileUrl && themeConfig.file?.url) {
|
|
18838
|
+
config2 = {
|
|
18839
|
+
...themeConfig,
|
|
18840
|
+
file: { ...themeConfig.file, url: fileUrl }
|
|
18841
|
+
};
|
|
18795
18842
|
}
|
|
18796
|
-
|
|
18843
|
+
this.configs.set(filePath, config2);
|
|
18844
|
+
return config2;
|
|
18797
18845
|
}
|
|
18798
|
-
return
|
|
18846
|
+
return this.fetchThemeConfigsFromSourceByPath(filePath, hash);
|
|
18799
18847
|
}
|
|
18800
18848
|
async fetchThemeConfigsByPath(pathPrefix, pathSuffix) {
|
|
18801
18849
|
const paths = this.configPaths.filter(
|
|
@@ -18804,9 +18852,7 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18804
18852
|
const configs = await Promise2.map(
|
|
18805
18853
|
paths,
|
|
18806
18854
|
(path) => this.fetchThemeConfig(path),
|
|
18807
|
-
{
|
|
18808
|
-
concurrency: 10
|
|
18809
|
-
}
|
|
18855
|
+
{ concurrency: 10 }
|
|
18810
18856
|
);
|
|
18811
18857
|
return configs.filter((config) => config !== null);
|
|
18812
18858
|
}
|
|
@@ -18839,17 +18885,28 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18839
18885
|
}
|
|
18840
18886
|
const configHashesUnresolved = [];
|
|
18841
18887
|
const configsByHash = /* @__PURE__ */ new Map();
|
|
18888
|
+
const themeId = this.getThemeId();
|
|
18889
|
+
const cache = this.getCache();
|
|
18842
18890
|
await Promise2.map(
|
|
18843
|
-
|
|
18844
|
-
(configHash) => {
|
|
18845
|
-
|
|
18846
|
-
|
|
18847
|
-
|
|
18848
|
-
|
|
18849
|
-
|
|
18850
|
-
|
|
18851
|
-
|
|
18852
|
-
}
|
|
18891
|
+
manifest.values(),
|
|
18892
|
+
async (configHash) => {
|
|
18893
|
+
const [themeConfig, fileUrl] = await Promise2.all([
|
|
18894
|
+
cache.get(`config:${configHash}`),
|
|
18895
|
+
themeId ? cache.get(`file:${themeId}:${configHash}`) : void 0
|
|
18896
|
+
]);
|
|
18897
|
+
if (!themeConfig) {
|
|
18898
|
+
configHashesUnresolved.push(configHash);
|
|
18899
|
+
return;
|
|
18900
|
+
}
|
|
18901
|
+
let config = themeConfig;
|
|
18902
|
+
if (fileUrl && themeConfig.file?.url) {
|
|
18903
|
+
config = {
|
|
18904
|
+
...themeConfig,
|
|
18905
|
+
file: { ...themeConfig.file, url: fileUrl }
|
|
18906
|
+
};
|
|
18907
|
+
}
|
|
18908
|
+
configsByHash.set(config.hash, config);
|
|
18909
|
+
this.configs.set(config.file_path, config);
|
|
18853
18910
|
},
|
|
18854
18911
|
{ concurrency: 10 }
|
|
18855
18912
|
);
|
|
@@ -18864,9 +18921,19 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18864
18921
|
configsByHash.set(config.hash, config);
|
|
18865
18922
|
this.configs.set(config.file_path, config);
|
|
18866
18923
|
}
|
|
18867
|
-
await Promise2.map(
|
|
18868
|
-
|
|
18869
|
-
|
|
18924
|
+
await Promise2.map(
|
|
18925
|
+
newConfigs,
|
|
18926
|
+
async (config) => {
|
|
18927
|
+
const promises = [this.cacheThemeConfig(config)];
|
|
18928
|
+
if (themeId && config.file?.url) {
|
|
18929
|
+
promises.push(
|
|
18930
|
+
this.cacheThemeFileUrl(themeId, config.hash, config.file.url)
|
|
18931
|
+
);
|
|
18932
|
+
}
|
|
18933
|
+
await Promise2.all(promises);
|
|
18934
|
+
},
|
|
18935
|
+
{ concurrency: 10 }
|
|
18936
|
+
);
|
|
18870
18937
|
}
|
|
18871
18938
|
return Array.from(configsByHash.values());
|
|
18872
18939
|
}
|
|
@@ -18886,6 +18953,12 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18886
18953
|
await this.getCache().set(`config:${config.hash}`, config);
|
|
18887
18954
|
}
|
|
18888
18955
|
}
|
|
18956
|
+
/**
|
|
18957
|
+
* Caches a CDN file url by config hash.
|
|
18958
|
+
*/
|
|
18959
|
+
async cacheThemeFileUrl(themeId, configHash, fileUrl) {
|
|
18960
|
+
await this.getCache().set(`file:${themeId}:${configHash}`, fileUrl);
|
|
18961
|
+
}
|
|
18889
18962
|
/**
|
|
18890
18963
|
* Fetches the manifest (set of config hashes) for a theme version.
|
|
18891
18964
|
*/
|
|
@@ -18909,8 +18982,10 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18909
18982
|
manifest = themeVersion.manifest;
|
|
18910
18983
|
}
|
|
18911
18984
|
}
|
|
18912
|
-
|
|
18913
|
-
|
|
18985
|
+
if (manifest) {
|
|
18986
|
+
this.manifest = new Map(Object.entries(manifest));
|
|
18987
|
+
this.configPaths = [...this.manifest.keys()];
|
|
18988
|
+
}
|
|
18914
18989
|
return this.manifest;
|
|
18915
18990
|
}
|
|
18916
18991
|
/**
|
|
@@ -18928,7 +19003,7 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18928
19003
|
"/:themes:configs",
|
|
18929
19004
|
{
|
|
18930
19005
|
...this.themeVersionQueryFilter(),
|
|
18931
|
-
...fetchAll ?
|
|
19006
|
+
...fetchAll ? void 0 : { hash: { $in: configHashes } },
|
|
18932
19007
|
// TODO: paginate to support more than 1000 configs
|
|
18933
19008
|
limit: 1e3,
|
|
18934
19009
|
type: "theme",
|
|
@@ -18964,10 +19039,20 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18964
19039
|
if (hash) {
|
|
18965
19040
|
config.hash = hash;
|
|
18966
19041
|
}
|
|
18967
|
-
|
|
19042
|
+
const themeId = this.getThemeId();
|
|
19043
|
+
const promises = [this.cacheThemeConfig(config)];
|
|
19044
|
+
if (themeId && config.file?.url) {
|
|
19045
|
+
promises.push(
|
|
19046
|
+
this.cacheThemeFileUrl(themeId, config.hash, config.file.url)
|
|
19047
|
+
);
|
|
19048
|
+
}
|
|
19049
|
+
await Promise2.all(promises);
|
|
18968
19050
|
}
|
|
18969
19051
|
return config ?? null;
|
|
18970
19052
|
}
|
|
19053
|
+
getThemeId() {
|
|
19054
|
+
return this.swell.swellHeaders["theme-id"];
|
|
19055
|
+
}
|
|
18971
19056
|
/**
|
|
18972
19057
|
* Generates a Swell API query filter for this theme version.
|
|
18973
19058
|
*/
|
|
@@ -19202,13 +19287,15 @@ var SwellTheme3 = class {
|
|
|
19202
19287
|
const [cart, account] = await Promise.all([
|
|
19203
19288
|
this.fetchSingletonResourceCached(
|
|
19204
19289
|
"cart",
|
|
19290
|
+
// The cached cart may be null, but we need the StorefrontResource
|
|
19205
19291
|
() => this.fetchCart(),
|
|
19206
|
-
|
|
19292
|
+
// Default value (always StorefrontResource)
|
|
19293
|
+
() => this.fetchCart()
|
|
19207
19294
|
),
|
|
19208
19295
|
this.fetchSingletonResourceCached(
|
|
19209
19296
|
"account",
|
|
19210
19297
|
() => this.fetchAccount(),
|
|
19211
|
-
null
|
|
19298
|
+
() => null
|
|
19212
19299
|
)
|
|
19213
19300
|
]);
|
|
19214
19301
|
if (!cart) {
|
|
@@ -19231,13 +19318,14 @@ var SwellTheme3 = class {
|
|
|
19231
19318
|
async fetchSingletonResourceCached(key, handler, defaultValue) {
|
|
19232
19319
|
const cacheKey = this.swell.storefront.session.getCookie();
|
|
19233
19320
|
if (!cacheKey) {
|
|
19234
|
-
return defaultValue;
|
|
19321
|
+
return defaultValue();
|
|
19235
19322
|
}
|
|
19236
|
-
|
|
19323
|
+
const result = await this.swell.getCachedResource(
|
|
19237
19324
|
`${key}-${cacheKey}`,
|
|
19238
19325
|
[],
|
|
19239
|
-
|
|
19326
|
+
handler
|
|
19240
19327
|
);
|
|
19328
|
+
return result ?? defaultValue();
|
|
19241
19329
|
}
|
|
19242
19330
|
async fetchCart() {
|
|
19243
19331
|
const CartResource = this.resources?.singletons?.cart;
|
|
@@ -19578,8 +19666,8 @@ var SwellTheme3 = class {
|
|
|
19578
19666
|
/**
|
|
19579
19667
|
* Preloads updated theme configs. Used to optimize initial theme load.
|
|
19580
19668
|
*/
|
|
19581
|
-
async preloadThemeConfigs(
|
|
19582
|
-
await this.themeLoader.preloadTheme(
|
|
19669
|
+
async preloadThemeConfigs(payload) {
|
|
19670
|
+
await this.themeLoader.preloadTheme(payload);
|
|
19583
19671
|
}
|
|
19584
19672
|
getPageConfigPath(pageId, altTemplate) {
|
|
19585
19673
|
if (this.shopifyCompatibility) {
|