swpp-backends 0.0.1-alpha
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/LICENSE +661 -0
- package/README.md +5 -0
- package/dist/SwppConfig.js +2 -0
- package/dist/UpdateJsonBuilder.js +281 -0
- package/dist/VersionAnalyzer.js +62 -0
- package/dist/fileAnalyzer.js +448 -0
- package/dist/index.js +35 -0
- package/dist/resources/sw-dom.js +51 -0
- package/dist/resources/sw-template.js +257 -0
- package/dist/serviceWorkerBuilder.js +152 -0
- package/dist/swppRules.js +117 -0
- package/dist/utils.js +188 -0
- package/package.json +37 -0
- package/types/SwppConfig.d.ts +125 -0
- package/types/UpdateJsonBuilder.d.ts +50 -0
- package/types/VersionAnalyzer.d.ts +29 -0
- package/types/fileAnalyzer.d.ts +147 -0
- package/types/index.d.ts +54 -0
- package/types/serviceWorkerBuilder.d.ts +7 -0
- package/types/swppRules.d.ts +101 -0
- package/types/utils.d.ts +41 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getShorthand = exports.buildNewInfo = exports.readUpdateJson = exports.loadUpdateJson = exports.submitChange = void 0;
|
|
4
|
+
const FileAnalyzer_1 = require("./FileAnalyzer");
|
|
5
|
+
const SwppRules_1 = require("./SwppRules");
|
|
6
|
+
const Utils_1 = require("./Utils");
|
|
7
|
+
let _oldJson = undefined;
|
|
8
|
+
const externalChange = [];
|
|
9
|
+
/** 提交修改 */
|
|
10
|
+
function submitChange(...change) {
|
|
11
|
+
externalChange.push(...change);
|
|
12
|
+
}
|
|
13
|
+
exports.submitChange = submitChange;
|
|
14
|
+
/**
|
|
15
|
+
* 加载版本文件
|
|
16
|
+
*
|
|
17
|
+
* + **调用该函数前必须调用过 [loadRules]**
|
|
18
|
+
*/
|
|
19
|
+
async function loadUpdateJson(url) {
|
|
20
|
+
if (_oldJson !== undefined)
|
|
21
|
+
return _oldJson;
|
|
22
|
+
const response = await (0, Utils_1.fetchFile)(url);
|
|
23
|
+
if (response.status === 404) {
|
|
24
|
+
(0, Utils_1.warn)('LoadUpdateJson', `拉取 ${url} 时出现 404 错误,如果您是第一次构建请忽略这个警告。`);
|
|
25
|
+
return _oldJson = null;
|
|
26
|
+
}
|
|
27
|
+
return _oldJson = (await response.json());
|
|
28
|
+
}
|
|
29
|
+
exports.loadUpdateJson = loadUpdateJson;
|
|
30
|
+
/**
|
|
31
|
+
* 读取最后一次加载的版本文件
|
|
32
|
+
*
|
|
33
|
+
* + **调用该函数前必须调用过 [loadRules]**
|
|
34
|
+
* + **调用该函数前必须调用过 [loadUpdateJson]**
|
|
35
|
+
*/
|
|
36
|
+
function readUpdateJson() {
|
|
37
|
+
if (_oldJson === undefined)
|
|
38
|
+
throw 'UpdateJson 未初始化';
|
|
39
|
+
return _oldJson;
|
|
40
|
+
}
|
|
41
|
+
exports.readUpdateJson = readUpdateJson;
|
|
42
|
+
/**
|
|
43
|
+
* 构建新的 update json
|
|
44
|
+
*
|
|
45
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
46
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
47
|
+
* + **执行该函数前必须调用过 [buildVersionJson]**
|
|
48
|
+
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
49
|
+
*
|
|
50
|
+
* @param root 网站根路径(包括网络协议)
|
|
51
|
+
* @param dif 网站文件变化
|
|
52
|
+
*/
|
|
53
|
+
function buildNewInfo(root, dif) {
|
|
54
|
+
const config = (0, SwppRules_1.readRules)().config.json;
|
|
55
|
+
if (!config)
|
|
56
|
+
throw '功能未开启';
|
|
57
|
+
const old = readUpdateJson();
|
|
58
|
+
let global = old?.global ?? 0;
|
|
59
|
+
if (dif.force)
|
|
60
|
+
return {
|
|
61
|
+
global: global + 1,
|
|
62
|
+
info: [{
|
|
63
|
+
version: old ? old.info[0].version + 1 : 0
|
|
64
|
+
}]
|
|
65
|
+
};
|
|
66
|
+
const change = [];
|
|
67
|
+
const info = {
|
|
68
|
+
version: old ? old.info[0].version + 1 : 0,
|
|
69
|
+
change
|
|
70
|
+
};
|
|
71
|
+
const list = [...dif.refresh, ...dif.deleted, ...dif.variational, ...dif.rules.remove];
|
|
72
|
+
const records = {
|
|
73
|
+
merge: new Set(),
|
|
74
|
+
html: new Set()
|
|
75
|
+
};
|
|
76
|
+
for (let url of list) {
|
|
77
|
+
if (url.startsWith('/')) {
|
|
78
|
+
// 本地链接
|
|
79
|
+
const merge = config.merge.find(it => url.startsWith(`/${it}/`));
|
|
80
|
+
if (merge) {
|
|
81
|
+
records.merge.add(merge);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
url = root + url;
|
|
85
|
+
}
|
|
86
|
+
if (/(\/|\.html)$/.test(url)) { // is html
|
|
87
|
+
records.html.add(getShorthand(url, 1));
|
|
88
|
+
}
|
|
89
|
+
else { // not html
|
|
90
|
+
change.push({
|
|
91
|
+
flag: 'end',
|
|
92
|
+
value: getShorthand(url)
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (records.html.size !== 0) {
|
|
97
|
+
if (records.html.size > config.maxHtml) {
|
|
98
|
+
change.push({ flag: 'html' });
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
change.push({
|
|
102
|
+
flag: 'end',
|
|
103
|
+
value: Array.from(records.html)
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (records.merge.size !== 0) {
|
|
108
|
+
change.push({
|
|
109
|
+
flag: 'begin',
|
|
110
|
+
value: Array.from(records.merge).map(it => `/${it}/`)
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
change.push(...externalChange);
|
|
114
|
+
return zipJson({
|
|
115
|
+
global,
|
|
116
|
+
info: [info, ...(old?.info ?? [])]
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
exports.buildNewInfo = buildNewInfo;
|
|
120
|
+
function zipJson(json) {
|
|
121
|
+
const record = new Map();
|
|
122
|
+
/** 合并同名项目 */
|
|
123
|
+
function merge(info) {
|
|
124
|
+
const localRecord = new Map();
|
|
125
|
+
if (!info.change)
|
|
126
|
+
return;
|
|
127
|
+
for (let exp of info.change) {
|
|
128
|
+
const value = exp.value;
|
|
129
|
+
if (!localRecord.has(exp.flag))
|
|
130
|
+
localRecord.set(exp.flag, new Set());
|
|
131
|
+
if (!value)
|
|
132
|
+
continue;
|
|
133
|
+
const set = localRecord.get(exp.flag);
|
|
134
|
+
if (typeof value === 'string') {
|
|
135
|
+
set.add(value);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
value.forEach(it => set.add(it));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
info.change = Array.from(localRecord)
|
|
142
|
+
.map(it => {
|
|
143
|
+
if (it[0] === 'html')
|
|
144
|
+
return [it[0], []];
|
|
145
|
+
const values = Array.from(it[1]);
|
|
146
|
+
if (it[0] === 'str' || it[0] === 'reg')
|
|
147
|
+
return [it[0], values];
|
|
148
|
+
const filtered = values.filter((value, index) => {
|
|
149
|
+
if (it[0] === 'end' && record.has('html') && /(\/|\.html)$/.test(value))
|
|
150
|
+
return false;
|
|
151
|
+
for (let i = 0; i < values.length; i++) {
|
|
152
|
+
if (i === index)
|
|
153
|
+
continue;
|
|
154
|
+
const that = values[i];
|
|
155
|
+
switch (it[0]) {
|
|
156
|
+
case 'end':
|
|
157
|
+
if (value.endsWith(that))
|
|
158
|
+
return false;
|
|
159
|
+
break;
|
|
160
|
+
case 'begin':
|
|
161
|
+
if (value.startsWith(that))
|
|
162
|
+
return false;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
});
|
|
168
|
+
return [it[0], filtered];
|
|
169
|
+
}).filter(it => it[1].length !== 0 || it[0] === 'html')
|
|
170
|
+
.map(it => {
|
|
171
|
+
record.set(it[0], it[1]);
|
|
172
|
+
if (it[1].length === 0)
|
|
173
|
+
return { flag: it[0] };
|
|
174
|
+
return {
|
|
175
|
+
flag: it[0],
|
|
176
|
+
value: it[1].length === 1 ? it[1][0] : it[1]
|
|
177
|
+
};
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/** 移除不可达的表达式 */
|
|
181
|
+
function deleteUnreachableExp(list) {
|
|
182
|
+
for (let i = list.length - 1; i > 0; i--) {
|
|
183
|
+
const info = list[i];
|
|
184
|
+
let change = info.change;
|
|
185
|
+
if (!change)
|
|
186
|
+
continue;
|
|
187
|
+
for (let k = 0; k < change.length; k++) {
|
|
188
|
+
const exp = change[k];
|
|
189
|
+
const top = record.get(exp.flag);
|
|
190
|
+
if (exp.flag === 'html') {
|
|
191
|
+
change.splice(k--, 1);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
let array = typeof exp.value === 'string' ? [exp.value] : exp.value;
|
|
195
|
+
const find = (test) => {
|
|
196
|
+
if (!top)
|
|
197
|
+
return false;
|
|
198
|
+
return top.find(test);
|
|
199
|
+
};
|
|
200
|
+
switch (exp.flag) {
|
|
201
|
+
case 'end':
|
|
202
|
+
array = array.filter(value => {
|
|
203
|
+
if (/(\/|\.html)$/.test(value) && record.has('html'))
|
|
204
|
+
return false;
|
|
205
|
+
if (!top)
|
|
206
|
+
return true;
|
|
207
|
+
return !find(it => value.endsWith(it));
|
|
208
|
+
});
|
|
209
|
+
break;
|
|
210
|
+
case 'begin':
|
|
211
|
+
array = array.filter(value => !find(it => value.startsWith(it)));
|
|
212
|
+
break;
|
|
213
|
+
case 'str':
|
|
214
|
+
array = array.filter(value => !find(it => value.includes(it)));
|
|
215
|
+
break;
|
|
216
|
+
case 'reg':
|
|
217
|
+
array = array.filter(value => !top?.includes(value));
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
switch (array.length) {
|
|
221
|
+
case 0:
|
|
222
|
+
change.splice(k--, 1);
|
|
223
|
+
break;
|
|
224
|
+
case 1:
|
|
225
|
+
exp.value = array[0];
|
|
226
|
+
break;
|
|
227
|
+
default:
|
|
228
|
+
exp.value = array;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (change.length === 0)
|
|
233
|
+
delete info.change;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
merge(json.info[0]);
|
|
237
|
+
deleteUnreachableExp(json.info);
|
|
238
|
+
return json;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* 获取 URL 的缩写形式
|
|
242
|
+
*
|
|
243
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
244
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
245
|
+
* + **执行该函数前必须调用过 [buildVersionJson]**
|
|
246
|
+
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
247
|
+
*/
|
|
248
|
+
function getShorthand(url, offset = 0) {
|
|
249
|
+
const map = (0, FileAnalyzer_1.readMergeVersionMap)();
|
|
250
|
+
let collide = new Set();
|
|
251
|
+
for (let mapKey in map) {
|
|
252
|
+
collide.add(mapKey);
|
|
253
|
+
}
|
|
254
|
+
let index = Math.max(url.lastIndexOf('/', url.length - offset - 1), url.length - 20);
|
|
255
|
+
let result;
|
|
256
|
+
while (true) {
|
|
257
|
+
result = url.substring(index);
|
|
258
|
+
let count = 0;
|
|
259
|
+
const removeSet = new Set();
|
|
260
|
+
for (let url of collide) {
|
|
261
|
+
if (url.endsWith(result)) {
|
|
262
|
+
++count;
|
|
263
|
+
if (count === 2)
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
removeSet.add(url);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
switch (count) {
|
|
271
|
+
case 1: return result;
|
|
272
|
+
case 2:
|
|
273
|
+
--index;
|
|
274
|
+
removeSet.forEach(it => collide.delete(it));
|
|
275
|
+
break;
|
|
276
|
+
default:
|
|
277
|
+
throw '意料之外的错误:' + count;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
exports.getShorthand = getShorthand;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.refreshUrl = exports.analyzer = void 0;
|
|
4
|
+
const FileAnalyzer_1 = require("./FileAnalyzer");
|
|
5
|
+
const extraUrl = new Set();
|
|
6
|
+
/**
|
|
7
|
+
* 分析两个版本信息的不同
|
|
8
|
+
*
|
|
9
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
10
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
11
|
+
*
|
|
12
|
+
* @param version 新的版本信息
|
|
13
|
+
*/
|
|
14
|
+
function analyzer(version) {
|
|
15
|
+
const oldVersion = (0, FileAnalyzer_1.readOldVersionJson)();
|
|
16
|
+
const result = {
|
|
17
|
+
force: false,
|
|
18
|
+
deleted: [],
|
|
19
|
+
variational: [],
|
|
20
|
+
refresh: [],
|
|
21
|
+
rules: {
|
|
22
|
+
add: [],
|
|
23
|
+
remove: []
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
if (version.version !== oldVersion.version) {
|
|
27
|
+
result.force = true;
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
for (let url in oldVersion.list) {
|
|
31
|
+
if (extraUrl.has(url)) {
|
|
32
|
+
result.refresh.push(url);
|
|
33
|
+
extraUrl.delete(url);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const oldValue = oldVersion.list[url];
|
|
37
|
+
const newValue = version.list[url];
|
|
38
|
+
if (!newValue) {
|
|
39
|
+
result.deleted.push(url);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const oldType = typeof oldValue;
|
|
43
|
+
const newType = typeof newValue;
|
|
44
|
+
if (oldType !== newType) {
|
|
45
|
+
if (newType === 'string')
|
|
46
|
+
result.rules.remove.push(url);
|
|
47
|
+
else
|
|
48
|
+
result.rules.add.push(url);
|
|
49
|
+
}
|
|
50
|
+
else if (oldType === 'string' && newValue !== oldValue) {
|
|
51
|
+
result.variational.push(url);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
extraUrl.forEach(url => result.refresh.push(url));
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
exports.analyzer = analyzer;
|
|
58
|
+
/** 手动添加一个要刷新的 URL */
|
|
59
|
+
function refreshUrl(url) {
|
|
60
|
+
extraUrl.add(url);
|
|
61
|
+
}
|
|
62
|
+
exports.refreshUrl = refreshUrl;
|