swpp-backends 1.2.3 → 2.0.1

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.
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildDomJs = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const Utils_1 = require("./Utils");
10
+ const Variant_1 = require("./Variant");
11
+ /**
12
+ * 构建 DOM 端的 JS 文件
13
+ *
14
+ * + **执行该函数前必须调用过 [loadRules]**
15
+ */
16
+ function buildDomJs() {
17
+ const config = (0, Variant_1.readRules)().config.dom;
18
+ if (!config) {
19
+ (0, Utils_1.error)('DomJsBuilder', '该配置项未开启');
20
+ throw '功能未开启';
21
+ }
22
+ let template = fs_1.default.readFileSync(path_1.default.resolve('./', module.path, 'resources/sw-dom.js'), 'utf-8');
23
+ if (config.onsuccess)
24
+ template = template.replaceAll('// ${onSuccess}', `(${config.onsuccess.toString()})()`);
25
+ return template;
26
+ }
27
+ exports.buildDomJs = buildDomJs;
@@ -26,15 +26,94 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.replaceRequest = exports.findCache = exports.eachAllLinkInUrl = exports.findFileHandler = exports.registryFileHandler = exports.buildVersionJson = exports.readMergeVersionMap = exports.readNewVersionJson = exports.readOldVersionJson = exports.submitExternalUrl = exports.submitCacheInfo = exports.loadVersionJson = exports.isStable = exports.isExclude = void 0;
29
+ exports.replaceRequest = exports.findCache = exports.eachAllLinkInUrl = exports.findFileHandler = exports.registryFileHandler = exports.submitExternalUrl = exports.submitCacheInfo = exports.loadVersionJson = exports.isStable = exports.isExclude = exports.buildVersionJson = void 0;
30
30
  const fs_1 = __importDefault(require("fs"));
31
31
  const path_1 = __importDefault(require("path"));
32
32
  const node_fetch_1 = require("node-fetch");
33
- const SwppRules_1 = require("./SwppRules");
34
33
  const crypto = __importStar(require("crypto"));
35
34
  const buffer_1 = require("buffer");
36
35
  const fast_html_parser_1 = __importDefault(require("fast-html-parser"));
37
36
  const Utils_1 = require("./Utils");
37
+ const Variant_1 = require("./Variant");
38
+ /**
39
+ * 构建一个 version json
40
+ *
41
+ * + **执行该函数前必须调用过 [loadRules]**
42
+ * + **调用该函数前必须调用过 [loadCacheJson]**
43
+ * + **执行该函数前必须调用过 [calcEjectValues]**
44
+ *
45
+ * @param protocol 网站的网络协议
46
+ * @param domain 网站域名(包括二级域名)
47
+ * @param root 网页根目录(首页 index.html 所在目录)
48
+ */
49
+ async function buildVersionJson(protocol, domain, root) {
50
+ const key = 'newVersionJson';
51
+ if ((0, Variant_1.readVariant)(key)) {
52
+ (0, Utils_1.error)('VersionJsonBuilder', '已经构建过一次版本文件');
53
+ throw '重复构建版本文件';
54
+ }
55
+ const rules = (0, Variant_1.readRules)();
56
+ const config = rules.config;
57
+ const list = {};
58
+ const cacheInfoMap = (0, Variant_1.readEvent)('submitCacheInfo');
59
+ const urlList = (0, Variant_1.readEvent)('submitExternalUrl');
60
+ (0, Variant_1.writeVariant)('submitCacheInfo', false);
61
+ (0, Variant_1.writeVariant)('submitExternalUrl', false);
62
+ // 遍历所有文件
63
+ await eachAllFile(root, async (path) => {
64
+ const endIndex = path.length - (/[\/\\]index\.html$/.test(path) ? 10 : 0);
65
+ const url = new URL(protocol + path_1.default.join(domain, path.substring(root.length, endIndex)));
66
+ const pathname = url.pathname;
67
+ if (isExclude(domain, pathname))
68
+ return;
69
+ let content = null;
70
+ if (findCache(url)) {
71
+ // 对于需要缓存的文件计算 MD5 值并存储
72
+ content = fs_1.default.readFileSync(path, 'utf-8');
73
+ const key = decodeURIComponent(url.pathname);
74
+ list[key] = crypto.createHash('md5').update(content).digest('hex');
75
+ }
76
+ if (!config.external)
77
+ return;
78
+ // 分析外部文件
79
+ const handler = findFileHandler(pathname);
80
+ if (handler) {
81
+ if (!content)
82
+ content = fs_1.default.readFileSync(path, 'utf-8');
83
+ await handler.handle(domain, url.href, content, list);
84
+ }
85
+ });
86
+ if (config.external) {
87
+ // 分析规则文件中通过 extraListenedUrls 导入的 URL
88
+ if ('extraListenedUrls' in rules) {
89
+ const urls = rules.extraListenedUrls;
90
+ if (typeof urls.forEach !== 'function') {
91
+ (0, Utils_1.error)('VersionJsonBuilder', `规则文件中的 extraListenedUrls 缺少 forEach 函数`);
92
+ throw 'extraListenedUrls 类型错误';
93
+ }
94
+ urls.forEach((it) => {
95
+ if (typeof it !== 'string') {
96
+ (0, Utils_1.error)('VersionJsonBuilder', 'extraListenedUrls 中应当存储 string 类型的值');
97
+ throw 'extraListenedUrls 元素类型错误';
98
+ }
99
+ urlList.add(it);
100
+ });
101
+ }
102
+ // 处理通过 API 提交的 URL
103
+ for (let url of urlList) {
104
+ await eachAllLinkInUrl(domain, url, list);
105
+ }
106
+ }
107
+ const external = {};
108
+ cacheInfoMap.forEach((value, key) => {
109
+ external[key] = value;
110
+ });
111
+ return (0, Variant_1.writeVariant)('newVersionJson', {
112
+ version: 3,
113
+ list, external
114
+ });
115
+ }
116
+ exports.buildVersionJson = buildVersionJson;
38
117
  /**
39
118
  * 遍历指定目录及其子目录中包含的所有文件(不遍历文件夹)
40
119
  * @param root 根目录
@@ -58,7 +137,7 @@ async function eachAllFile(root, cb) {
58
137
  * @param url 要判断的 URL
59
138
  */
60
139
  function isExclude(domain, url) {
61
- const exclude = (0, SwppRules_1.readRules)().config?.json?.exclude;
140
+ const exclude = (0, Variant_1.readRules)().config?.json?.exclude;
62
141
  if (!exclude)
63
142
  return false;
64
143
  const list = isExternalLink(domain, url) ? exclude.other : exclude.localhost;
@@ -75,7 +154,7 @@ exports.isExclude = isExclude;
75
154
  * + **执行该函数前必须调用过 [loadRules]**
76
155
  */
77
156
  function isStable(url) {
78
- const stable = (0, SwppRules_1.readRules)().config?.external?.stable;
157
+ const stable = (0, Variant_1.readRules)().config?.external?.stable;
79
158
  if (!stable)
80
159
  return false;
81
160
  for (let reg of stable) {
@@ -91,157 +170,54 @@ exports.isStable = isStable;
91
170
  * + **执行该函数前必须调用过 [loadRules]**
92
171
  */
93
172
  async function loadVersionJson(url) {
173
+ const key = 'oldVersionJson';
94
174
  const response = await (0, Utils_1.fetchFile)(url).catch(err => err);
95
175
  if (response?.status === 404 || response?.code === 'ENOTFOUND') {
96
176
  (0, Utils_1.warn)('LoadVersionJson', `拉取 ${url} 时出现 404 错误,如果您是第一次构建请忽略这个警告。`);
97
- return _oldVersionJson = null;
177
+ return (0, Variant_1.writeVariant)(key, null);
98
178
  }
99
179
  else {
100
- return _oldVersionJson = (await response.json());
180
+ return (0, Variant_1.writeVariant)(key, await response.json());
101
181
  }
102
182
  }
103
183
  exports.loadVersionJson = loadVersionJson;
104
- let _oldVersionJson = undefined;
105
- let _newVersionJson;
106
- let _mergeVersionMap;
107
- let cacheInfoMap = new Map();
108
- let urlList = new Set();
109
184
  /** 提交要存储到 version json 的值 */
110
185
  function submitCacheInfo(key, value) {
111
- if (!cacheInfoMap) {
112
- (0, Utils_1.error)('SubmitCacheInfo', 'version json 已经完成构建,调用该函数无意义!');
113
- throw 'submitCacheInfo 调用时机错误';
114
- }
186
+ const cacheInfoMap = (0, Variant_1.readEvent)('submitCacheInfo');
115
187
  cacheInfoMap.set(key, value);
116
188
  }
117
189
  exports.submitCacheInfo = submitCacheInfo;
118
190
  /** 添加一个要监听的 URL */
119
191
  function submitExternalUrl(url) {
120
- if (!urlList) {
121
- (0, Utils_1.error)('SubmitExternalUrl', 'version json 已经完成构建,调用该函数无意义!');
122
- throw 'submitExternalUrl 调用时机错误';
123
- }
124
- urlList.add(url);
192
+ (0, Variant_1.readEvent)('submitExternalUrl').add(url);
125
193
  }
126
194
  exports.submitExternalUrl = submitExternalUrl;
127
- /**
128
- * 读取最后一次加载的 version json
129
- *
130
- * + **执行该函数前必须调用过 [loadRules]**
131
- * + **调用该函数前必须调用过 [loadCacheJson]**
132
- */
133
- function readOldVersionJson() {
134
- if (_oldVersionJson === undefined) {
135
- (0, Utils_1.error)('OldVersionReader', 'version json 尚未初始化');
136
- throw 'version json 尚未初始化';
137
- }
138
- return _oldVersionJson;
139
- }
140
- exports.readOldVersionJson = readOldVersionJson;
141
- /**
142
- * 读取最后一次构建的 VersionJson
143
- *
144
- * + **执行该函数前必须调用过 [loadRules]**
145
- * + **调用该函数前必须调用过 [loadCacheJson]**
146
- * + **执行该函数前必须调用过 [buildVersionJson]**
147
- * + **执行该函数前必须调用过 [calcEjectValues]**
148
- */
149
- function readNewVersionJson() {
150
- if (!_newVersionJson) {
151
- (0, Utils_1.error)('NewVersionReader', 'version json 尚未初始化');
152
- throw 'version json 尚未初始化';
153
- }
154
- return _newVersionJson;
155
- }
156
- exports.readNewVersionJson = readNewVersionJson;
157
- /**
158
- * 读取新旧版本文件合并后的版本地图
159
- *
160
- * + **执行该函数前必须调用过 [loadRules]**
161
- * + **调用该函数前必须调用过 [loadCacheJson]**
162
- * + **执行该函数前必须调用过 [buildVersionJson]**
163
- * + **执行该函数前必须调用过 [calcEjectValues]**
164
- */
165
- function readMergeVersionMap() {
166
- if (_mergeVersionMap)
167
- return _mergeVersionMap;
168
- const map = {};
169
- Object.assign(map, readOldVersionJson()?.list ?? {});
170
- Object.assign(map, readNewVersionJson().list);
171
- return _mergeVersionMap = map;
172
- }
173
- exports.readMergeVersionMap = readMergeVersionMap;
174
- /**
175
- * 构建一个 version json
176
- *
177
- * + **执行该函数前必须调用过 [loadRules]**
178
- * + **调用该函数前必须调用过 [loadCacheJson]**
179
- * + **执行该函数前必须调用过 [calcEjectValues]**
180
- *
181
- * @param protocol 网站的网络协议
182
- * @param domain 网站域名(包括二级域名)
183
- * @param root 网页根目录(首页 index.html 所在目录)
184
- */
185
- async function buildVersionJson(protocol, domain, root) {
186
- const list = {};
187
- await eachAllFile(root, async (path) => {
188
- const endIndex = path.length - (/[\/\\]index\.html$/.test(path) ? 10 : 0);
189
- const url = new URL(protocol + path_1.default.join(domain, path.substring(root.length, endIndex)));
190
- const pathname = url.pathname;
191
- if (isExclude(domain, pathname))
192
- return;
193
- let content = null;
194
- if (findCache(url)) {
195
- content = fs_1.default.readFileSync(path, 'utf-8');
196
- const key = decodeURIComponent(url.pathname);
197
- list[key] = crypto.createHash('md5').update(content).digest('hex');
198
- }
199
- const handler = findFileHandler(pathname);
200
- if (handler) {
201
- if (!content)
202
- content = fs_1.default.readFileSync(path, 'utf-8');
203
- await handler.handle(domain, url.href, content, list);
204
- }
205
- });
206
- for (let url of urlList) {
207
- await eachAllLinkInUrl(domain, url, list);
208
- }
209
- const external = {};
210
- cacheInfoMap.forEach((value, key) => {
211
- external[key] = value;
212
- });
213
- urlList = cacheInfoMap = null;
214
- return _newVersionJson = {
215
- version: 3, list, external
216
- };
217
- }
218
- exports.buildVersionJson = buildVersionJson;
219
- const fileHandlers = [
195
+ (0, Variant_1.writeVariant)('submitCacheInfo', new Map());
196
+ (0, Variant_1.writeVariant)('submitExternalUrl', new Set());
197
+ (0, Variant_1.writeVariant)('registryFileHandler', []);
198
+ (0, Variant_1.readVariant)('registryFileHandler').push(...[
220
199
  {
221
- match: url => /(\/|\.html)$/.test(url),
200
+ match: (url) => /(\/|\.html)$/.test(url),
222
201
  handle: eachAllLinkInHtml
223
202
  },
224
203
  {
225
- match: url => url.endsWith('.css'),
204
+ match: (url) => url.endsWith('.css'),
226
205
  handle: eachAllLinkInCss
227
206
  },
228
207
  {
229
- match: url => url.endsWith('.js'),
208
+ match: (url) => url.endsWith('.js'),
230
209
  handle: eachAllLinkInJavaScript
231
210
  }
232
- ];
211
+ ]);
233
212
  /** 注册一个文件处理器 */
234
213
  function registryFileHandler(handler) {
235
- if (!urlList) {
236
- (0, Utils_1.error)('RegistryFileHandler', '文件已经扫描完毕,调用该函数无意义!');
237
- throw 'registryFileHandler 调用时机错误';
238
- }
239
- fileHandlers.push(handler);
214
+ // noinspection JSMismatchedCollectionQueryUpdate
215
+ (0, Variant_1.readEvent)('registryFileHandler').push(handler);
240
216
  }
241
217
  exports.registryFileHandler = registryFileHandler;
242
218
  /** 查询一个文件处理器 */
243
219
  function findFileHandler(url) {
244
- return fileHandlers.find(it => it.match(url));
220
+ return (0, Variant_1.readEvent)('registryFileHandler').find(it => it.match(url));
245
221
  }
246
222
  exports.findFileHandler = findFileHandler;
247
223
  /**
@@ -269,7 +245,7 @@ async function eachAllLinkInUrl(domain, url, result, event) {
269
245
  return;
270
246
  const stable = isStable(url);
271
247
  if (stable) {
272
- const old = readOldVersionJson()?.list;
248
+ const old = (0, Variant_1.readOldVersionJson)()?.list;
273
249
  if (Array.isArray(old?.[url])) {
274
250
  const copyTree = (key) => {
275
251
  const value = old[key];
@@ -417,6 +393,8 @@ async function eachAllLinkInCss(domain, url, content, result, event) {
417
393
  return 'http' + it;
418
394
  case it.startsWith('/'):
419
395
  return root + it;
396
+ case it.startsWith('./'):
397
+ return root + it.substring(1);
420
398
  default:
421
399
  return root + '/' + it;
422
400
  }
@@ -426,7 +404,7 @@ async function eachAllLinkInCss(domain, url, content, result, event) {
426
404
  }
427
405
  function eachAllLinkInJavaScript(domain, _, content, result, event) {
428
406
  const taskList = [];
429
- const ruleList = (0, SwppRules_1.readRules)().config?.external?.js;
407
+ const ruleList = (0, Variant_1.readRules)().config?.external?.js;
430
408
  if (!ruleList) {
431
409
  (0, Utils_1.error)('LinkItorInJS', '不应发生的异常');
432
410
  throw 'ruleList 为空';
@@ -478,7 +456,7 @@ function isExternalLink(domain, url) {
478
456
  * + **执行该函数前必须调用过 [calcEjectValues]**
479
457
  */
480
458
  function findCache(url) {
481
- const { cacheRules } = (0, SwppRules_1.readRules)();
459
+ const { cacheRules } = (0, Variant_1.readRules)();
482
460
  const eject = (0, Utils_1.readEjectData)();
483
461
  if (typeof url === 'string')
484
462
  url = new URL(url);
@@ -498,7 +476,7 @@ exports.findCache = findCache;
498
476
  * + **执行该函数前必须调用过 [calcEjectValues]**
499
477
  */
500
478
  function replaceRequest(url) {
501
- const rules = (0, SwppRules_1.readRules)();
479
+ const rules = (0, Variant_1.readRules)();
502
480
  if (!('modifyRequest' in rules))
503
481
  return url;
504
482
  const { modifyRequest } = rules;
@@ -4,10 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.buildServiceWorker = void 0;
7
- const SwppRules_1 = require("./SwppRules");
8
7
  const Utils_1 = require("./Utils");
9
8
  const fs_1 = __importDefault(require("fs"));
10
9
  const path_1 = __importDefault(require("path"));
10
+ const Variant_1 = require("./Variant");
11
11
  /**
12
12
  * 构建 sw
13
13
  *
@@ -15,9 +15,13 @@ const path_1 = __importDefault(require("path"));
15
15
  * + **执行该函数前必须调用过 [calcEjectValues]**
16
16
  */
17
17
  function buildServiceWorker() {
18
- const rules = (0, SwppRules_1.readRules)();
18
+ const rules = (0, Variant_1.readRules)();
19
19
  const eject = (0, Utils_1.readEjectData)();
20
20
  const { modifyRequest, fetchFile, getRaceUrls, getSpareUrls, blockRequest, config } = rules;
21
+ if (!config.serviceWorker) {
22
+ (0, Utils_1.error)('ServiceWorkerBuilder', '插件未开启该项');
23
+ throw '功能未开启';
24
+ }
21
25
  const serviceWorkerConfig = config.serviceWorker;
22
26
  const templatePath = path_1.default.resolve('./', module.path, 'resources/sw-template.js');
23
27
  // 获取拓展文件
package/dist/SwppRules.js CHANGED
@@ -3,78 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.loadRules = exports.addRulesMapEvent = exports.readRules = void 0;
6
+ exports.addRulesMapEvent = exports.loadRules = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const Utils_1 = require("./Utils");
10
- const defConfig = {
11
- serviceWorker: {
12
- escape: 0,
13
- cacheName: 'kmarBlogCache',
14
- debug: false
15
- },
16
- register: {
17
- onerror: () => console.error('Service Worker 注册失败!可能是由于您的浏览器不支持该功能!'),
18
- builder: (root, _, pluginConfig) => {
19
- const registerConfig = pluginConfig.register;
20
- const { onerror, onsuccess } = registerConfig;
21
- return `<script>
22
- (() => {
23
- let sw = navigator.serviceWorker
24
- let error = ${onerror.toString()}
25
- if (!sw?.register('${new URL(root).pathname}sw.js')
26
- ${onsuccess ? '?.then(' + onsuccess.toString() + ')' : ''}
27
- ?.catch(error)
28
- ) error()
29
- })()
30
- </script>`;
31
- }
32
- },
33
- dom: {},
34
- json: {
35
- maxHtml: 15,
36
- charLimit: 1024,
37
- merge: [],
38
- exclude: {
39
- localhost: [/^\/sw\.js$/],
40
- other: []
41
- }
42
- },
43
- external: {
44
- timeout: 5000,
45
- js: [],
46
- stable: [],
47
- replacer: it => it
48
- }
49
- };
50
- let eventList = [];
51
- let _rules;
52
- /**
53
- * 读取最后一次构建的 rules
54
- *
55
- * **执行该函数前必须调用过 [loadRules]**
56
- */
57
- function readRules() {
58
- if (!_rules) {
59
- (0, Utils_1.error)('RulesReader', 'rules 尚未初始化');
60
- throw 'rules 尚未初始化';
61
- }
62
- return _rules;
63
- }
64
- exports.readRules = readRules;
65
- /**
66
- * 添加一个 rules 映射事件,这个事件允许用户修改 rules 的内容
67
- *
68
- * 执行时按照注册的顺序执行
69
- */
70
- function addRulesMapEvent(mapper) {
71
- if (!eventList) {
72
- (0, Utils_1.error)('AddRulesMapEvent', '规则文件已经加载完成,调用该函数无意义!');
73
- throw 'addRulesMapEvent 调用时机错误';
74
- }
75
- eventList.push(mapper);
76
- }
77
- exports.addRulesMapEvent = addRulesMapEvent;
10
+ const Variant_1 = require("./Variant");
78
11
  /**
79
12
  * 加载 rules 文件
80
13
  * @param root 项目根目录
@@ -82,6 +15,8 @@ exports.addRulesMapEvent = addRulesMapEvent;
82
15
  * @param selects 附加的可选目录,优先级低于 [root]
83
16
  */
84
17
  function loadRules(root, fileName, selects) {
18
+ const eventList = (0, Variant_1.readEvent)('addRulesMapEvent');
19
+ (0, Variant_1.writeVariant)('addRulesMapEvent', false);
85
20
  // 支持的拓展名
86
21
  const extensions = ['cjs', 'js'];
87
22
  // 根目录下的 rules 文件
@@ -98,14 +33,15 @@ function loadRules(root, fileName, selects) {
98
33
  const config = rootRules.config ?? {};
99
34
  mergeConfig(config, selectRules.config ?? {});
100
35
  mergeConfig(config, defConfig);
101
- Object.assign(rootRules, selectRules);
36
+ for (let key in selectRules) {
37
+ if (!(key in rootRules))
38
+ rootRules[key] = selectRules[key];
39
+ }
102
40
  rootRules.config = config;
103
41
  for (let event of eventList) {
104
42
  event(rootRules);
105
43
  }
106
- eventList = null;
107
- (0, Utils_1.deepFreeze)(rootRules);
108
- return _rules = rootRules;
44
+ return (0, Variant_1.writeVariant)('swppRules', (0, Utils_1.deepFreeze)(rootRules));
109
45
  }
110
46
  exports.loadRules = loadRules;
111
47
  /** 合并配置项 */
@@ -126,3 +62,54 @@ function mergeConfig(dist, that) {
126
62
  }
127
63
  return dist;
128
64
  }
65
+ (0, Variant_1.writeVariant)('addRulesMapEvent', []);
66
+ /**
67
+ * 添加一个 rules 映射事件,这个事件允许用户修改 rules 的内容
68
+ *
69
+ * 执行时按照注册的顺序执行
70
+ */
71
+ function addRulesMapEvent(mapper) {
72
+ (0, Variant_1.readEvent)('addRulesMapEvent').push(mapper);
73
+ }
74
+ exports.addRulesMapEvent = addRulesMapEvent;
75
+ const defConfig = {
76
+ serviceWorker: {
77
+ escape: 0,
78
+ cacheName: 'kmarBlogCache',
79
+ debug: false
80
+ },
81
+ register: {
82
+ onerror: () => console.error('Service Worker 注册失败!可能是由于您的浏览器不支持该功能!'),
83
+ builder: (root, _, pluginConfig) => {
84
+ const registerConfig = pluginConfig.register;
85
+ const { onerror, onsuccess } = registerConfig;
86
+ return `<script>
87
+ (() => {
88
+ let sw = navigator.serviceWorker
89
+ let error = ${onerror.toString()}
90
+ if (!sw?.register('${new URL(root).pathname}sw.js')
91
+ ${onsuccess ? '?.then(' + onsuccess.toString() + ')' : ''}
92
+ ?.catch(error)
93
+ ) error()
94
+ })()
95
+ </script>`;
96
+ }
97
+ },
98
+ dom: {},
99
+ json: {
100
+ maxHtml: 15,
101
+ charLimit: 1024,
102
+ merge: [],
103
+ exclude: {
104
+ localhost: [/^\/sw\.js$/],
105
+ other: []
106
+ }
107
+ },
108
+ external: {
109
+ timeout: 5000,
110
+ concurrencyLimit: 100,
111
+ js: [],
112
+ stable: [],
113
+ replacer: (it) => it
114
+ }
115
+ };