@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.cjs
CHANGED
|
@@ -149,31 +149,44 @@ var import_cache_manager = require("cache-manager");
|
|
|
149
149
|
|
|
150
150
|
// src/cache/cf-worker-kv-keyv-adapter.ts
|
|
151
151
|
var CFWorkerKVKeyvAdapter = class {
|
|
152
|
+
store;
|
|
152
153
|
namespace;
|
|
153
154
|
// magically passed in from Keyv
|
|
154
|
-
|
|
155
|
+
opts;
|
|
155
156
|
constructor(store) {
|
|
156
157
|
this.store = store;
|
|
158
|
+
this.opts = null;
|
|
157
159
|
this.namespace = "dummy";
|
|
158
160
|
}
|
|
159
161
|
async has(key) {
|
|
160
|
-
|
|
162
|
+
const stream = await this.store.get(key, "stream");
|
|
163
|
+
if (stream !== null) {
|
|
164
|
+
await stream.cancel();
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
161
168
|
}
|
|
162
169
|
async get(key) {
|
|
163
|
-
|
|
170
|
+
const value = await this.store.get(key);
|
|
171
|
+
return value !== null ? value : void 0;
|
|
164
172
|
}
|
|
165
|
-
|
|
166
|
-
|
|
173
|
+
set(key, value, ttl) {
|
|
174
|
+
if (typeof ttl === "number") {
|
|
175
|
+
ttl = Math.max(60, ttl / 1e3);
|
|
176
|
+
}
|
|
177
|
+
return this.store.put(key, value, { expirationTtl: ttl });
|
|
167
178
|
}
|
|
168
179
|
async delete(key) {
|
|
169
180
|
await this.store.delete(key);
|
|
181
|
+
return true;
|
|
170
182
|
}
|
|
171
183
|
async clear() {
|
|
172
184
|
let cursor = "";
|
|
173
185
|
let complete = false;
|
|
174
|
-
|
|
186
|
+
const prefix = `${this.namespace}:`;
|
|
187
|
+
do {
|
|
175
188
|
const response = await this.store.list({
|
|
176
|
-
prefix
|
|
189
|
+
prefix,
|
|
177
190
|
cursor: cursor || void 0
|
|
178
191
|
});
|
|
179
192
|
cursor = response.cursor ?? "";
|
|
@@ -185,7 +198,10 @@ var CFWorkerKVKeyvAdapter = class {
|
|
|
185
198
|
})
|
|
186
199
|
);
|
|
187
200
|
}
|
|
188
|
-
}
|
|
201
|
+
} while (!complete);
|
|
202
|
+
}
|
|
203
|
+
on(_event, _listener) {
|
|
204
|
+
return this;
|
|
189
205
|
}
|
|
190
206
|
};
|
|
191
207
|
|
|
@@ -7089,23 +7105,25 @@ var Cache = class {
|
|
|
7089
7105
|
...options
|
|
7090
7106
|
});
|
|
7091
7107
|
}
|
|
7092
|
-
async fetch(key, fetchFn) {
|
|
7093
|
-
return this.client.wrap(key, fetchFn);
|
|
7108
|
+
async fetch(key, fetchFn, ttl) {
|
|
7109
|
+
return this.client.wrap(key, fetchFn, ttl);
|
|
7094
7110
|
}
|
|
7095
|
-
|
|
7096
|
-
|
|
7111
|
+
/**
|
|
7112
|
+
* Fetch cache using SWR (stale-while-revalidate)
|
|
7113
|
+
*
|
|
7114
|
+
* This will always return the cached value immediately if exists
|
|
7115
|
+
*/
|
|
7097
7116
|
async fetchSWR(key, fetchFn, ttl = DEFAULT_SWR_TTL) {
|
|
7098
7117
|
const cacheValue = await this.client.get(key);
|
|
7099
|
-
const promiseValue = Promise.resolve().then(
|
|
7118
|
+
const promiseValue = Promise.resolve().then(fetchFn).then(resolveAsyncResources).then(async (value) => {
|
|
7100
7119
|
const isNull = value === null || value === void 0;
|
|
7101
|
-
|
|
7102
|
-
await this.client.set(key, isNull ? NULL_VALUE : valueResolved, ttl);
|
|
7120
|
+
await this.client.set(key, isNull ? NULL_VALUE : value, ttl);
|
|
7103
7121
|
return value;
|
|
7104
7122
|
});
|
|
7105
7123
|
if (this.workerCtx?.waitUntil) {
|
|
7106
7124
|
this.workerCtx.waitUntil(promiseValue);
|
|
7107
7125
|
}
|
|
7108
|
-
if (cacheValue !==
|
|
7126
|
+
if (cacheValue !== void 0) {
|
|
7109
7127
|
return cacheValue === NULL_VALUE ? null : cacheValue;
|
|
7110
7128
|
}
|
|
7111
7129
|
const result = await promiseValue;
|
|
@@ -7122,8 +7140,9 @@ var Cache = class {
|
|
|
7122
7140
|
}
|
|
7123
7141
|
/**
|
|
7124
7142
|
* Flushes the entire cache.
|
|
7125
|
-
*
|
|
7126
|
-
*
|
|
7143
|
+
*
|
|
7144
|
+
* __WARNING__: If the cache store is shared among many cache clients,
|
|
7145
|
+
* this will flush entries for other clients.
|
|
7127
7146
|
*/
|
|
7128
7147
|
async flushAll() {
|
|
7129
7148
|
await this.client.clear();
|
|
@@ -7166,7 +7185,7 @@ var ResourceCache = class extends Cache {
|
|
|
7166
7185
|
function buildStores2() {
|
|
7167
7186
|
return [
|
|
7168
7187
|
new import_keyv2.Keyv({
|
|
7169
|
-
// Disabling serialization allows for pure
|
|
7188
|
+
// Disabling serialization allows for pure memoization of class instances
|
|
7170
7189
|
// at the tradeoff of no support for compression.
|
|
7171
7190
|
serialize: void 0,
|
|
7172
7191
|
deserialize: void 0
|
|
@@ -18236,10 +18255,10 @@ var svgs = {
|
|
|
18236
18255
|
src: "https://cdn.swell.store/schema/685ef581b79e3e0012cf3222/fba884c7fe8122c472e130355fb52db7/collection-6.png"
|
|
18237
18256
|
},
|
|
18238
18257
|
"lifestyle-1": {
|
|
18239
|
-
src: "https://cdn.swell.store/schema/
|
|
18258
|
+
src: "https://cdn.swell.store/schema/6870eddc1657130012643fc6/1777bcff40736610093833ef858b5936/lifestyle-1.png"
|
|
18240
18259
|
},
|
|
18241
18260
|
"lifestyle-2": {
|
|
18242
|
-
src: "https://cdn.swell.store/schema/
|
|
18261
|
+
src: "https://cdn.swell.store/schema/6870eddc1657130012643fcb/4d29197e3fa0b6d8255c1b7770f8dc12/lifestyle-2.png"
|
|
18243
18262
|
},
|
|
18244
18263
|
"product-apparel-1": {
|
|
18245
18264
|
src: "https://cdn.swell.store/schema/685ef58eb79e3e0012cf3276/37c3c973a01287a580ab9db2e05dd36d/product-apparel-1.png"
|
|
@@ -18837,12 +18856,11 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18837
18856
|
this.configPaths = [];
|
|
18838
18857
|
}
|
|
18839
18858
|
async init(themeConfigs) {
|
|
18840
|
-
const { swellHeaders } = this.swell;
|
|
18841
18859
|
if (themeConfigs) {
|
|
18842
18860
|
this.setConfigs(themeConfigs);
|
|
18843
18861
|
return;
|
|
18844
18862
|
}
|
|
18845
|
-
if (!
|
|
18863
|
+
if (!this.getThemeId()) {
|
|
18846
18864
|
return;
|
|
18847
18865
|
}
|
|
18848
18866
|
await this.fetchManifest();
|
|
@@ -18881,25 +18899,45 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18881
18899
|
*/
|
|
18882
18900
|
setConfigs(themeConfigs) {
|
|
18883
18901
|
this.configs = new Map(themeConfigs);
|
|
18902
|
+
this.manifest = /* @__PURE__ */ new Map();
|
|
18903
|
+
for (const { file_path, hash } of this.configs.values()) {
|
|
18904
|
+
this.manifest.set(file_path, hash);
|
|
18905
|
+
}
|
|
18884
18906
|
this.configPaths = Array.from(this.configs.keys());
|
|
18885
|
-
this.manifest = this.configPaths.reduce((manifest, path) => {
|
|
18886
|
-
manifest[path] = this.configs.get(path)?.hash;
|
|
18887
|
-
return manifest;
|
|
18888
|
-
}, {});
|
|
18889
18907
|
}
|
|
18890
18908
|
/**
|
|
18891
18909
|
* Preloads a theme version and configs. This is used to optimize initial theme load.
|
|
18892
18910
|
*/
|
|
18893
|
-
async preloadTheme(
|
|
18911
|
+
async preloadTheme(payload) {
|
|
18912
|
+
const { version, configs } = payload;
|
|
18894
18913
|
console.log(
|
|
18895
18914
|
`ThemeLoader.preloadTheme${version?.hash ? ` - manifest: ${version.hash}` : ""}${configs?.length ? ` - configs: ${configs.length}` : ""}`
|
|
18896
18915
|
);
|
|
18897
|
-
|
|
18898
|
-
|
|
18899
|
-
|
|
18900
|
-
|
|
18901
|
-
|
|
18902
|
-
|
|
18916
|
+
const promises = [];
|
|
18917
|
+
if (version) {
|
|
18918
|
+
promises.push(this.cacheManifest(version));
|
|
18919
|
+
}
|
|
18920
|
+
if (configs) {
|
|
18921
|
+
const themeId = this.getThemeId();
|
|
18922
|
+
promises.push(
|
|
18923
|
+
Promise2.map(
|
|
18924
|
+
configs,
|
|
18925
|
+
async (config) => {
|
|
18926
|
+
const promises2 = [
|
|
18927
|
+
this.cacheThemeConfig(config)
|
|
18928
|
+
];
|
|
18929
|
+
if (themeId && config.file?.url) {
|
|
18930
|
+
promises2.push(
|
|
18931
|
+
this.cacheThemeFileUrl(themeId, config.hash, config.file.url)
|
|
18932
|
+
);
|
|
18933
|
+
}
|
|
18934
|
+
await Promise2.all(promises2);
|
|
18935
|
+
},
|
|
18936
|
+
{ concurrency: 10 }
|
|
18937
|
+
)
|
|
18938
|
+
);
|
|
18939
|
+
}
|
|
18940
|
+
await Promise2.all(promises);
|
|
18903
18941
|
}
|
|
18904
18942
|
/**
|
|
18905
18943
|
* Fetches a theme config by file path.
|
|
@@ -18909,18 +18947,28 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18909
18947
|
if (config !== void 0) {
|
|
18910
18948
|
return config;
|
|
18911
18949
|
}
|
|
18912
|
-
const hash = this.manifest?.
|
|
18913
|
-
if (hash) {
|
|
18914
|
-
|
|
18915
|
-
|
|
18916
|
-
|
|
18917
|
-
|
|
18918
|
-
|
|
18919
|
-
|
|
18950
|
+
const hash = this.manifest?.get(filePath);
|
|
18951
|
+
if (!hash) {
|
|
18952
|
+
return null;
|
|
18953
|
+
}
|
|
18954
|
+
const cache = this.getCache();
|
|
18955
|
+
const themeId = this.getThemeId();
|
|
18956
|
+
const [themeConfig, fileUrl] = await Promise2.all([
|
|
18957
|
+
cache.get(`config:${hash}`),
|
|
18958
|
+
themeId ? cache.get(`file:${themeId}:${hash}`) : void 0
|
|
18959
|
+
]);
|
|
18960
|
+
if (themeConfig) {
|
|
18961
|
+
let config2 = themeConfig;
|
|
18962
|
+
if (fileUrl && themeConfig.file?.url) {
|
|
18963
|
+
config2 = {
|
|
18964
|
+
...themeConfig,
|
|
18965
|
+
file: { ...themeConfig.file, url: fileUrl }
|
|
18966
|
+
};
|
|
18920
18967
|
}
|
|
18921
|
-
|
|
18968
|
+
this.configs.set(filePath, config2);
|
|
18969
|
+
return config2;
|
|
18922
18970
|
}
|
|
18923
|
-
return
|
|
18971
|
+
return this.fetchThemeConfigsFromSourceByPath(filePath, hash);
|
|
18924
18972
|
}
|
|
18925
18973
|
async fetchThemeConfigsByPath(pathPrefix, pathSuffix) {
|
|
18926
18974
|
const paths = this.configPaths.filter(
|
|
@@ -18929,9 +18977,7 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18929
18977
|
const configs = await Promise2.map(
|
|
18930
18978
|
paths,
|
|
18931
18979
|
(path) => this.fetchThemeConfig(path),
|
|
18932
|
-
{
|
|
18933
|
-
concurrency: 10
|
|
18934
|
-
}
|
|
18980
|
+
{ concurrency: 10 }
|
|
18935
18981
|
);
|
|
18936
18982
|
return configs.filter((config) => config !== null);
|
|
18937
18983
|
}
|
|
@@ -18964,17 +19010,28 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18964
19010
|
}
|
|
18965
19011
|
const configHashesUnresolved = [];
|
|
18966
19012
|
const configsByHash = /* @__PURE__ */ new Map();
|
|
19013
|
+
const themeId = this.getThemeId();
|
|
19014
|
+
const cache = this.getCache();
|
|
18967
19015
|
await Promise2.map(
|
|
18968
|
-
|
|
18969
|
-
(configHash) => {
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
}
|
|
19016
|
+
manifest.values(),
|
|
19017
|
+
async (configHash) => {
|
|
19018
|
+
const [themeConfig, fileUrl] = await Promise2.all([
|
|
19019
|
+
cache.get(`config:${configHash}`),
|
|
19020
|
+
themeId ? cache.get(`file:${themeId}:${configHash}`) : void 0
|
|
19021
|
+
]);
|
|
19022
|
+
if (!themeConfig) {
|
|
19023
|
+
configHashesUnresolved.push(configHash);
|
|
19024
|
+
return;
|
|
19025
|
+
}
|
|
19026
|
+
let config = themeConfig;
|
|
19027
|
+
if (fileUrl && themeConfig.file?.url) {
|
|
19028
|
+
config = {
|
|
19029
|
+
...themeConfig,
|
|
19030
|
+
file: { ...themeConfig.file, url: fileUrl }
|
|
19031
|
+
};
|
|
19032
|
+
}
|
|
19033
|
+
configsByHash.set(config.hash, config);
|
|
19034
|
+
this.configs.set(config.file_path, config);
|
|
18978
19035
|
},
|
|
18979
19036
|
{ concurrency: 10 }
|
|
18980
19037
|
);
|
|
@@ -18989,9 +19046,19 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
18989
19046
|
configsByHash.set(config.hash, config);
|
|
18990
19047
|
this.configs.set(config.file_path, config);
|
|
18991
19048
|
}
|
|
18992
|
-
await Promise2.map(
|
|
18993
|
-
|
|
18994
|
-
|
|
19049
|
+
await Promise2.map(
|
|
19050
|
+
newConfigs,
|
|
19051
|
+
async (config) => {
|
|
19052
|
+
const promises = [this.cacheThemeConfig(config)];
|
|
19053
|
+
if (themeId && config.file?.url) {
|
|
19054
|
+
promises.push(
|
|
19055
|
+
this.cacheThemeFileUrl(themeId, config.hash, config.file.url)
|
|
19056
|
+
);
|
|
19057
|
+
}
|
|
19058
|
+
await Promise2.all(promises);
|
|
19059
|
+
},
|
|
19060
|
+
{ concurrency: 10 }
|
|
19061
|
+
);
|
|
18995
19062
|
}
|
|
18996
19063
|
return Array.from(configsByHash.values());
|
|
18997
19064
|
}
|
|
@@ -19011,6 +19078,12 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
19011
19078
|
await this.getCache().set(`config:${config.hash}`, config);
|
|
19012
19079
|
}
|
|
19013
19080
|
}
|
|
19081
|
+
/**
|
|
19082
|
+
* Caches a CDN file url by config hash.
|
|
19083
|
+
*/
|
|
19084
|
+
async cacheThemeFileUrl(themeId, configHash, fileUrl) {
|
|
19085
|
+
await this.getCache().set(`file:${themeId}:${configHash}`, fileUrl);
|
|
19086
|
+
}
|
|
19014
19087
|
/**
|
|
19015
19088
|
* Fetches the manifest (set of config hashes) for a theme version.
|
|
19016
19089
|
*/
|
|
@@ -19034,8 +19107,10 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
19034
19107
|
manifest = themeVersion.manifest;
|
|
19035
19108
|
}
|
|
19036
19109
|
}
|
|
19037
|
-
|
|
19038
|
-
|
|
19110
|
+
if (manifest) {
|
|
19111
|
+
this.manifest = new Map(Object.entries(manifest));
|
|
19112
|
+
this.configPaths = [...this.manifest.keys()];
|
|
19113
|
+
}
|
|
19039
19114
|
return this.manifest;
|
|
19040
19115
|
}
|
|
19041
19116
|
/**
|
|
@@ -19053,7 +19128,7 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
19053
19128
|
"/:themes:configs",
|
|
19054
19129
|
{
|
|
19055
19130
|
...this.themeVersionQueryFilter(),
|
|
19056
|
-
...fetchAll ?
|
|
19131
|
+
...fetchAll ? void 0 : { hash: { $in: configHashes } },
|
|
19057
19132
|
// TODO: paginate to support more than 1000 configs
|
|
19058
19133
|
limit: 1e3,
|
|
19059
19134
|
type: "theme",
|
|
@@ -19089,10 +19164,20 @@ var ThemeLoader = class _ThemeLoader {
|
|
|
19089
19164
|
if (hash) {
|
|
19090
19165
|
config.hash = hash;
|
|
19091
19166
|
}
|
|
19092
|
-
|
|
19167
|
+
const themeId = this.getThemeId();
|
|
19168
|
+
const promises = [this.cacheThemeConfig(config)];
|
|
19169
|
+
if (themeId && config.file?.url) {
|
|
19170
|
+
promises.push(
|
|
19171
|
+
this.cacheThemeFileUrl(themeId, config.hash, config.file.url)
|
|
19172
|
+
);
|
|
19173
|
+
}
|
|
19174
|
+
await Promise2.all(promises);
|
|
19093
19175
|
}
|
|
19094
19176
|
return config ?? null;
|
|
19095
19177
|
}
|
|
19178
|
+
getThemeId() {
|
|
19179
|
+
return this.swell.swellHeaders["theme-id"];
|
|
19180
|
+
}
|
|
19096
19181
|
/**
|
|
19097
19182
|
* Generates a Swell API query filter for this theme version.
|
|
19098
19183
|
*/
|
|
@@ -19327,13 +19412,15 @@ var SwellTheme3 = class {
|
|
|
19327
19412
|
const [cart, account] = await Promise.all([
|
|
19328
19413
|
this.fetchSingletonResourceCached(
|
|
19329
19414
|
"cart",
|
|
19415
|
+
// The cached cart may be null, but we need the StorefrontResource
|
|
19330
19416
|
() => this.fetchCart(),
|
|
19331
|
-
|
|
19417
|
+
// Default value (always StorefrontResource)
|
|
19418
|
+
() => this.fetchCart()
|
|
19332
19419
|
),
|
|
19333
19420
|
this.fetchSingletonResourceCached(
|
|
19334
19421
|
"account",
|
|
19335
19422
|
() => this.fetchAccount(),
|
|
19336
|
-
null
|
|
19423
|
+
() => null
|
|
19337
19424
|
)
|
|
19338
19425
|
]);
|
|
19339
19426
|
if (!cart) {
|
|
@@ -19356,13 +19443,14 @@ var SwellTheme3 = class {
|
|
|
19356
19443
|
async fetchSingletonResourceCached(key, handler, defaultValue) {
|
|
19357
19444
|
const cacheKey = this.swell.storefront.session.getCookie();
|
|
19358
19445
|
if (!cacheKey) {
|
|
19359
|
-
return defaultValue;
|
|
19446
|
+
return defaultValue();
|
|
19360
19447
|
}
|
|
19361
|
-
|
|
19448
|
+
const result = await this.swell.getCachedResource(
|
|
19362
19449
|
`${key}-${cacheKey}`,
|
|
19363
19450
|
[],
|
|
19364
|
-
|
|
19451
|
+
handler
|
|
19365
19452
|
);
|
|
19453
|
+
return result ?? defaultValue();
|
|
19366
19454
|
}
|
|
19367
19455
|
async fetchCart() {
|
|
19368
19456
|
const CartResource = this.resources?.singletons?.cart;
|
|
@@ -19703,8 +19791,8 @@ var SwellTheme3 = class {
|
|
|
19703
19791
|
/**
|
|
19704
19792
|
* Preloads updated theme configs. Used to optimize initial theme load.
|
|
19705
19793
|
*/
|
|
19706
|
-
async preloadThemeConfigs(
|
|
19707
|
-
await this.themeLoader.preloadTheme(
|
|
19794
|
+
async preloadThemeConfigs(payload) {
|
|
19795
|
+
await this.themeLoader.preloadTheme(payload);
|
|
19708
19796
|
}
|
|
19709
19797
|
getPageConfigPath(pageId, altTemplate) {
|
|
19710
19798
|
if (this.shopifyCompatibility) {
|