swpp-backends 3.0.0-alpha.3 → 3.0.0-alpha.310
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/{types → dist}/index.d.ts +5 -4
- package/dist/index.js +25 -17
- package/{types → dist}/swpp/FileParser.d.ts +11 -6
- package/dist/swpp/FileParser.js +27 -13
- package/{types → dist}/swpp/JsonBuilder.d.ts +1 -3
- package/dist/swpp/JsonBuilder.js +3 -7
- package/dist/swpp/NetworkFileHandler.js +3 -3
- package/{types → dist}/swpp/ResourcesScanner.d.ts +11 -14
- package/dist/swpp/ResourcesScanner.js +94 -70
- package/{types → dist}/swpp/SwCompiler.d.ts +21 -8
- package/dist/swpp/SwCompiler.js +49 -15
- package/{types → dist}/swpp/config/ConfigCluster.d.ts +98 -63
- package/dist/swpp/config/ConfigCluster.js +60 -48
- package/dist/swpp/config/ConfigLoader.d.ts +78 -0
- package/dist/swpp/config/ConfigLoader.js +180 -89
- package/dist/swpp/config/SpecialConfig.d.ts +29 -0
- package/dist/swpp/config/SpecialConfig.js +53 -0
- package/{types → dist}/swpp/database/CompilationEnv.d.ts +19 -16
- package/dist/swpp/database/CompilationEnv.js +41 -197
- package/dist/swpp/database/CompilationFileParser.d.ts +81 -0
- package/dist/swpp/database/CompilationFileParser.js +267 -0
- package/{types → dist}/swpp/database/CrossDepCode.d.ts +4 -0
- package/dist/swpp/database/CrossDepCode.js +27 -1
- package/dist/swpp/database/CrossEnv.js +19 -2
- package/{types → dist}/swpp/database/DomCode.d.ts +4 -1
- package/dist/swpp/database/DomCode.js +34 -5
- package/dist/swpp/database/KeyValueDatabase.d.ts +72 -0
- package/dist/swpp/database/KeyValueDatabase.js +122 -27
- package/{types → dist}/swpp/database/RuntimeCoreCode.d.ts +2 -1
- package/dist/swpp/database/RuntimeCoreCode.js +6 -5
- package/{types → dist}/swpp/database/RuntimeDepCode.d.ts +8 -14
- package/dist/swpp/database/RuntimeDepCode.js +30 -50
- package/{types → dist}/swpp/database/RuntimeEventCode.d.ts +4 -0
- package/dist/swpp/database/RuntimeEventCode.js +8 -1
- package/{types → dist}/swpp/database/RuntimeKeyValueDatabase.d.ts +1 -1
- package/dist/swpp/database/RuntimeKeyValueDatabase.js +2 -2
- package/dist/swpp/debug/CallChainRecorder.d.ts +5 -0
- package/dist/swpp/debug/CallChainRecorder.js +29 -0
- package/{types → dist}/swpp/untils.d.ts +25 -18
- package/dist/swpp/untils.js +47 -53
- package/package.json +2 -2
- package/types/DomBuilder.d.ts +0 -6
- package/types/FileAnalyzer.d.ts +0 -96
- package/types/ServiceWorkerBuilder.d.ts +0 -7
- package/types/SwppConfig.d.ts +0 -139
- package/types/SwppRules.d.ts +0 -117
- package/types/UpdateJsonBuilder.d.ts +0 -44
- package/types/Utils.d.ts +0 -43
- package/types/Variant.d.ts +0 -58
- package/types/VersionAnalyzer.d.ts +0 -27
- package/types/browser/ServiceWorkerRuntimeTypes.d.ts +0 -18
- package/types/swpp/RuntimeEnv.d.ts +0 -39
- package/types/swpp/SwCodeInject.d.ts +0 -17
- package/types/swpp/config/ConfigLoader.d.ts +0 -53
- package/types/swpp/database/KeyValueDatabase.d.ts +0 -53
- package/types/swpp/database/RuntimeEnv.d.ts +0 -5
- /package/{types → dist}/swpp/NetworkFileHandler.d.ts +0 -0
- /package/{types → dist}/swpp/database/CrossEnv.d.ts +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RuntimeDepCode = void 0;
|
|
4
|
+
const ConfigCluster_1 = require("../config/ConfigCluster");
|
|
4
5
|
const untils_1 = require("../untils");
|
|
5
6
|
const RuntimeKeyValueDatabase_1 = require("./RuntimeKeyValueDatabase");
|
|
6
7
|
let CACHE_NAME;
|
|
@@ -19,31 +20,7 @@ let fetchFastest;
|
|
|
19
20
|
/** 运行时依赖代码 */
|
|
20
21
|
class RuntimeDepCode extends RuntimeKeyValueDatabase_1.RuntimeKeyValueDatabase {
|
|
21
22
|
constructor() {
|
|
22
|
-
super(buildCommon());
|
|
23
|
-
}
|
|
24
|
-
/** 修正函数 */
|
|
25
|
-
fixDepFunction() {
|
|
26
|
-
const emptyLambda = () => null;
|
|
27
|
-
const hasFastestRequests = this.hasValue('getFastestRequests');
|
|
28
|
-
const hasStandbyRequests = this.hasValue('getStandbyRequests');
|
|
29
|
-
const hasFetchFile = this.hasValue('fetchFile');
|
|
30
|
-
if (!hasFastestRequests) {
|
|
31
|
-
this.update('fetchFastest', emptyLambda);
|
|
32
|
-
}
|
|
33
|
-
if (!hasStandbyRequests) {
|
|
34
|
-
this.update('fetchStandby', emptyLambda);
|
|
35
|
-
}
|
|
36
|
-
if (!hasFetchFile) {
|
|
37
|
-
if (hasFastestRequests && hasStandbyRequests) {
|
|
38
|
-
this.update('fetchFile', () => fetchFastestAndStandbyRequests);
|
|
39
|
-
}
|
|
40
|
-
else if (hasFastestRequests) {
|
|
41
|
-
this.update('fetchFile', () => fetchFastestRequests);
|
|
42
|
-
}
|
|
43
|
-
else if (hasStandbyRequests) {
|
|
44
|
-
this.update('fetchFile', () => fetchStandbyRequests);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
23
|
+
super('RuntimeDepCode', buildCommon());
|
|
47
24
|
}
|
|
48
25
|
/** 构建 JS 源代码 */
|
|
49
26
|
buildJsSource() {
|
|
@@ -117,8 +94,6 @@ function buildCommon() {
|
|
|
117
94
|
/** 判断指定的缓存是否是有效缓存 */
|
|
118
95
|
isValidCache: {
|
|
119
96
|
default: (response, rule) => {
|
|
120
|
-
if (!rule)
|
|
121
|
-
return false;
|
|
122
97
|
const headers = response.headers;
|
|
123
98
|
if (headers.has(INVALID_KEY))
|
|
124
99
|
return false;
|
|
@@ -183,7 +158,7 @@ function buildCommon() {
|
|
|
183
158
|
},
|
|
184
159
|
/** 是否启用 cors */
|
|
185
160
|
isCors: {
|
|
186
|
-
default: (() =>
|
|
161
|
+
default: (() => false)
|
|
187
162
|
},
|
|
188
163
|
/** 获取竞速列表 */
|
|
189
164
|
getFastestRequests: {
|
|
@@ -213,7 +188,7 @@ function buildCommon() {
|
|
|
213
188
|
fetchFastest: {
|
|
214
189
|
default: async (list, optional) => {
|
|
215
190
|
const fallbackFetch = (request, controller) => {
|
|
216
|
-
return fetchWrapper(request, true,
|
|
191
|
+
return fetchWrapper(request, true, true, {
|
|
217
192
|
...optional,
|
|
218
193
|
signal: controller?.signal
|
|
219
194
|
});
|
|
@@ -238,7 +213,7 @@ function buildCommon() {
|
|
|
238
213
|
fetchStandby: {
|
|
239
214
|
default: async (request, standbyRequests, optional) => {
|
|
240
215
|
const fallbackFetch = (request, controller) => {
|
|
241
|
-
return fetchWrapper(request, true,
|
|
216
|
+
return fetchWrapper(request, true, true, {
|
|
242
217
|
...optional,
|
|
243
218
|
signal: controller?.signal
|
|
244
219
|
});
|
|
@@ -247,10 +222,10 @@ function buildCommon() {
|
|
|
247
222
|
let id, standbyResolve, standbyReject;
|
|
248
223
|
// 尝试封装 response
|
|
249
224
|
const resolveResponse = (index, response) => isFetchSuccessful(response) ? { i: index, r: response } : Promise.reject(response);
|
|
250
|
-
const { t: time, l:
|
|
251
|
-
const controllers = new Array(
|
|
225
|
+
const { t: time, l: listGetter } = standbyRequests;
|
|
226
|
+
const controllers = new Array(listGetter.length + 1);
|
|
252
227
|
// 尝试同时拉取 standbyRequests 中的所有 Request
|
|
253
|
-
const task = () => Promise.any(
|
|
228
|
+
const task = () => Promise.any(listGetter().map((it, index) => fallbackFetch(it, controllers[index + 1] = new AbortController())
|
|
254
229
|
.then(response => resolveResponse(index + 1, response)))).then(obj => standbyResolve(obj))
|
|
255
230
|
.catch(() => standbyReject());
|
|
256
231
|
// 尝试拉取初始 request
|
|
@@ -286,23 +261,28 @@ function buildCommon() {
|
|
|
286
261
|
},
|
|
287
262
|
/** 拉取文件 */
|
|
288
263
|
fetchFile: {
|
|
289
|
-
default: (
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
if (
|
|
300
|
-
return
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
264
|
+
default: (0, ConfigCluster_1.defineLazyInitConfig)((runtime) => {
|
|
265
|
+
const runtimeDep = runtime.runtimeDep;
|
|
266
|
+
const hasFastestRequests = runtimeDep.hasValue('getFastestRequests');
|
|
267
|
+
const hasStandbyRequests = runtimeDep.hasValue('getStandbyRequests');
|
|
268
|
+
if (hasFastestRequests && hasStandbyRequests) {
|
|
269
|
+
return fetchFastestAndStandbyRequests;
|
|
270
|
+
}
|
|
271
|
+
else if (hasFastestRequests) {
|
|
272
|
+
return fetchFastestRequests;
|
|
273
|
+
}
|
|
274
|
+
else if (hasStandbyRequests) {
|
|
275
|
+
return fetchStandbyRequests;
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
return (request, optional) => {
|
|
279
|
+
// @ts-ignore
|
|
280
|
+
if (!request.url)
|
|
281
|
+
request = new Request(request);
|
|
282
|
+
return fetchWrapper(request, true, true, optional);
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
})
|
|
306
286
|
},
|
|
307
287
|
/** 是否阻断请求 */
|
|
308
288
|
isBlockRequest: {
|
|
@@ -7,6 +7,10 @@ export declare class RuntimeEventCode extends RuntimeKeyValueDatabase<FunctionIn
|
|
|
7
7
|
buildJsSource(): string;
|
|
8
8
|
}
|
|
9
9
|
declare function buildCommon(): {
|
|
10
|
+
/** SW 注册后立即激活 */
|
|
11
|
+
readonly install: {
|
|
12
|
+
readonly default: (_event: Event) => void;
|
|
13
|
+
};
|
|
10
14
|
/** sw 激活后立即对所有页面生效,而非等待刷新 */
|
|
11
15
|
readonly activate: {
|
|
12
16
|
readonly default: (event: Event) => any;
|
|
@@ -8,7 +8,7 @@ let postMessage;
|
|
|
8
8
|
let readVersion;
|
|
9
9
|
class RuntimeEventCode extends RuntimeKeyValueDatabase_1.RuntimeKeyValueDatabase {
|
|
10
10
|
constructor() {
|
|
11
|
-
super(buildCommon());
|
|
11
|
+
super('RuntimeEventCode', buildCommon());
|
|
12
12
|
}
|
|
13
13
|
/** 构建 JS 源代码 */
|
|
14
14
|
buildJsSource() {
|
|
@@ -23,6 +23,13 @@ class RuntimeEventCode extends RuntimeKeyValueDatabase_1.RuntimeKeyValueDatabase
|
|
|
23
23
|
exports.RuntimeEventCode = RuntimeEventCode;
|
|
24
24
|
function buildCommon() {
|
|
25
25
|
return {
|
|
26
|
+
/** SW 注册后立即激活 */
|
|
27
|
+
install: {
|
|
28
|
+
default: (_event) => {
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
skipWaiting();
|
|
31
|
+
}
|
|
32
|
+
},
|
|
26
33
|
/** sw 激活后立即对所有页面生效,而非等待刷新 */
|
|
27
34
|
activate: {
|
|
28
35
|
// @ts-ignore
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DatabaseValue, KeyValueDatabase } from './KeyValueDatabase';
|
|
2
2
|
/** 运行时键值对存储器 */
|
|
3
3
|
export declare abstract class RuntimeKeyValueDatabase<T, C extends Record<string, DatabaseValue<T>>> extends KeyValueDatabase<T, C> {
|
|
4
|
-
protected constructor(map?: C);
|
|
4
|
+
protected constructor(namespace: string, map?: C, globalChecker?: (key: string, value: T) => void);
|
|
5
5
|
/** 构建运行时的 js 代码 */
|
|
6
6
|
abstract buildJsSource(): string;
|
|
7
7
|
}
|
|
@@ -4,8 +4,8 @@ exports.RuntimeKeyValueDatabase = void 0;
|
|
|
4
4
|
const KeyValueDatabase_1 = require("./KeyValueDatabase");
|
|
5
5
|
/** 运行时键值对存储器 */
|
|
6
6
|
class RuntimeKeyValueDatabase extends KeyValueDatabase_1.KeyValueDatabase {
|
|
7
|
-
constructor(map) {
|
|
8
|
-
super(map);
|
|
7
|
+
constructor(namespace, map, globalChecker) {
|
|
8
|
+
super(namespace, map, globalChecker);
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
exports.RuntimeKeyValueDatabase = RuntimeKeyValueDatabase;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CallChainRecorder = void 0;
|
|
4
|
+
const untils_1 = require("../untils");
|
|
5
|
+
class CallChainRecorder {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.chain = [];
|
|
8
|
+
}
|
|
9
|
+
push(namespace, key) {
|
|
10
|
+
const size = this.chain.push({ namespace, key });
|
|
11
|
+
const index1 = this.chain.findIndex(it => it.namespace === namespace && it.key === key);
|
|
12
|
+
if (index1 + 1 !== size) {
|
|
13
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.circularDependencies, '环境变量产生了循环依赖', {
|
|
14
|
+
chain: this.chain.map((it, index) => {
|
|
15
|
+
return `${it.namespace}::${it.key}${index % 5 == 4 ? '\n' : ''}`;
|
|
16
|
+
}).join(' -> ')
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
pop(namespace, key) {
|
|
21
|
+
const popValue = this.chain.pop();
|
|
22
|
+
if (!popValue || popValue.namespace !== namespace || popValue.key !== key) {
|
|
23
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.error, '调用链追踪错误', {
|
|
24
|
+
chain: this.chain, popValue, expected: { namespace, key }
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.CallChainRecorder = CallChainRecorder;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as crypto from 'node:crypto';
|
|
2
2
|
export type ValuesOf<T> = T[keyof T];
|
|
3
|
-
export declare const utils:
|
|
4
|
-
/** 将一个值封装为 lambda */
|
|
5
|
-
package<T>(value: T): () => T;
|
|
3
|
+
export declare const utils: {
|
|
6
4
|
/** 检查指定 URL 是否是合法的 URL */
|
|
7
5
|
checkUrl(url: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* 拼接链接
|
|
8
|
+
*/
|
|
9
|
+
splicingUrl(base: URL, ...values: string[]): URL;
|
|
8
10
|
/**
|
|
9
11
|
* 将任意的对象转化为 JS 源码
|
|
10
12
|
*
|
|
@@ -36,27 +38,20 @@ export declare const utils: Readonly<{
|
|
|
36
38
|
[p: string]: any;
|
|
37
39
|
}, includeEmptyValue?: boolean, writeAsVar?: "let" | "const"): string;
|
|
38
40
|
/** 判断指定链接的 host 是否为指定的 host */
|
|
39
|
-
isSameHost(path: string,
|
|
41
|
+
isSameHost(path: string, baseUrl: URL): boolean;
|
|
40
42
|
/** 计算字符串的哈希值 */
|
|
41
43
|
calcHash(content: crypto.BinaryLike): string;
|
|
42
44
|
time(): string;
|
|
43
45
|
printError(title: string, err: any): void;
|
|
44
|
-
printInfo(title: string, info: any): void;
|
|
45
46
|
printWarning(title: string, warning: any): void;
|
|
46
47
|
/**
|
|
47
48
|
* 将一个对象中的值都映射为另一个类型的值
|
|
48
49
|
* @param obj
|
|
49
50
|
* @param transfer
|
|
50
51
|
*/
|
|
51
|
-
objMap<T, R>(obj: {
|
|
52
|
-
[key: string]: T;
|
|
53
|
-
}, transfer: (item: T) => R): {
|
|
52
|
+
objMap<T, R>(obj: Readonly<Record<string, T>>, transfer: (item: T) => R): {
|
|
54
53
|
[key: string]: R;
|
|
55
54
|
};
|
|
56
|
-
/** 深度冻结一个对象 */
|
|
57
|
-
deepFreeze<T>(obj: T): Readonly<T>;
|
|
58
|
-
/** 二分查找 */
|
|
59
|
-
binarySearch<T>(array: T[], value: T, startInclude?: number, endExclude?: number, comparator?: (a: T, b: T) => number): number;
|
|
60
55
|
/**
|
|
61
56
|
* 在可迭代容器中查找满足指定条件的元素的下标
|
|
62
57
|
*/
|
|
@@ -64,18 +59,30 @@ export declare const utils: Readonly<{
|
|
|
64
59
|
index: number;
|
|
65
60
|
value: T;
|
|
66
61
|
}[];
|
|
67
|
-
|
|
62
|
+
/**
|
|
63
|
+
* 查找一个字符串中倒数第二次出现的子串的下标
|
|
64
|
+
*/
|
|
65
|
+
findSecondLastIndex(str: string, searchString: string, position?: number): number;
|
|
66
|
+
};
|
|
68
67
|
export declare const exceptionNames: {
|
|
68
|
+
/** 循环依赖 */
|
|
69
|
+
readonly circularDependencies: "circular_dependencies";
|
|
69
70
|
/** 无效的变量名 */
|
|
70
71
|
readonly invalidVarName: "invalid_var_name";
|
|
71
72
|
/** 无效的变量类型 */
|
|
72
73
|
readonly invalidVarType: "invalid_var_type";
|
|
73
74
|
/** 无效的插入键 */
|
|
74
75
|
readonly invalidKey: "invalid_key";
|
|
76
|
+
/** 无效的插入值 */
|
|
77
|
+
readonly invalidValue: "invalid_value";
|
|
78
|
+
/** KV 库已经被冻结无法修改 */
|
|
79
|
+
readonly isFrozen: "is_frozen";
|
|
75
80
|
/** 不支持的版本号 */
|
|
76
81
|
readonly unsupportedVersion: "unsupported_version";
|
|
77
82
|
/** 不支持的文件类型 */
|
|
78
83
|
readonly unsupportedFileType: "unsupported_file_type";
|
|
84
|
+
/** 不支持的操作 */
|
|
85
|
+
readonly unsupportedOperate: "unsupported_operate";
|
|
79
86
|
/** 空指针 */
|
|
80
87
|
readonly nullPoint: "null_point";
|
|
81
88
|
/** 配置文件已经完成构建 */
|
|
@@ -85,9 +92,9 @@ export declare const exceptionNames: {
|
|
|
85
92
|
/** 未知分类错误 */
|
|
86
93
|
readonly error: "error";
|
|
87
94
|
};
|
|
88
|
-
export
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
message: string;
|
|
95
|
+
export declare class RuntimeException extends Error {
|
|
96
|
+
readonly code: ValuesOf<typeof exceptionNames>;
|
|
97
|
+
readonly message: string;
|
|
98
|
+
readonly addOn?: any;
|
|
99
|
+
constructor(code: ValuesOf<typeof exceptionNames>, message: string, addOn?: any);
|
|
93
100
|
}
|
package/dist/swpp/untils.js
CHANGED
|
@@ -23,13 +23,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.exceptionNames = exports.utils = void 0;
|
|
26
|
+
exports.RuntimeException = exports.exceptionNames = exports.utils = void 0;
|
|
27
27
|
const crypto = __importStar(require("node:crypto"));
|
|
28
|
-
exports.utils =
|
|
29
|
-
/** 将一个值封装为 lambda */
|
|
30
|
-
package(value) {
|
|
31
|
-
return () => value;
|
|
32
|
-
},
|
|
28
|
+
exports.utils = {
|
|
33
29
|
/** 检查指定 URL 是否是合法的 URL */
|
|
34
30
|
checkUrl(url) {
|
|
35
31
|
try {
|
|
@@ -40,6 +36,12 @@ exports.utils = Object.freeze({
|
|
|
40
36
|
return false;
|
|
41
37
|
}
|
|
42
38
|
},
|
|
39
|
+
/**
|
|
40
|
+
* 拼接链接
|
|
41
|
+
*/
|
|
42
|
+
splicingUrl(base, ...values) {
|
|
43
|
+
return new URL(values.join('/').replaceAll(/(\/+)|\\/g, '/'), base);
|
|
44
|
+
},
|
|
43
45
|
/**
|
|
44
46
|
* 将任意的对象转化为 JS 源码
|
|
45
47
|
*
|
|
@@ -73,11 +75,9 @@ exports.utils = Object.freeze({
|
|
|
73
75
|
const resultList = [];
|
|
74
76
|
const pushToResult = (key, value) => {
|
|
75
77
|
if (writeAsVar) {
|
|
76
|
-
if (!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(key))
|
|
77
|
-
throw
|
|
78
|
-
|
|
79
|
-
message: '非法的变量名:' + key
|
|
80
|
-
};
|
|
78
|
+
if (!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(key)) {
|
|
79
|
+
throw new RuntimeException(exports.exceptionNames.invalidVarName, '非法的变量名:' + key);
|
|
80
|
+
}
|
|
81
81
|
resultList.push(`${writeAsVar} ${key} = ${value}`);
|
|
82
82
|
}
|
|
83
83
|
else if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(key)) {
|
|
@@ -142,25 +142,19 @@ exports.utils = Object.freeze({
|
|
|
142
142
|
break;
|
|
143
143
|
}
|
|
144
144
|
case "symbol":
|
|
145
|
-
throw
|
|
146
|
-
code: exports.exceptionNames.invalidVarType,
|
|
147
|
-
message: '非法的类型:symbol, key = ' + key
|
|
148
|
-
};
|
|
145
|
+
throw new RuntimeException(exports.exceptionNames.invalidVarType, '非法的类型:symbol, key = ' + key);
|
|
149
146
|
}
|
|
150
147
|
}
|
|
151
148
|
return writeAsVar ? resultList.join(';\n') : '{\n' + resultList.join(',\n') + '\n};';
|
|
152
149
|
},
|
|
153
150
|
/** 判断指定链接的 host 是否为指定的 host */
|
|
154
|
-
isSameHost(path,
|
|
151
|
+
isSameHost(path, baseUrl) {
|
|
155
152
|
try {
|
|
156
|
-
const url = new URL(path,
|
|
157
|
-
return
|
|
153
|
+
const url = new URL(path, baseUrl);
|
|
154
|
+
return baseUrl.hostname === url.hostname && baseUrl.pathname.startsWith(url.pathname);
|
|
158
155
|
}
|
|
159
|
-
catch (
|
|
160
|
-
throw {
|
|
161
|
-
value: `path: ${path}; host: ${host}`,
|
|
162
|
-
message: '传入的 path 或 host 不合法'
|
|
163
|
-
};
|
|
156
|
+
catch (e) {
|
|
157
|
+
throw new RuntimeException(exports.exceptionNames.error, `传入的 path[${path}] 不合法`, { cause: e });
|
|
164
158
|
}
|
|
165
159
|
},
|
|
166
160
|
/** 计算字符串的哈希值 */
|
|
@@ -179,9 +173,6 @@ exports.utils = Object.freeze({
|
|
|
179
173
|
printError(title, err) {
|
|
180
174
|
console.error(`[${this.time()}] [ERR] [SWPP] [${title}]: `, err);
|
|
181
175
|
},
|
|
182
|
-
printInfo(title, info) {
|
|
183
|
-
console.info(`[${this.time()}] [INFO] [SWPP] [${title}]: ${JSON.stringify(info, null, 2)}`);
|
|
184
|
-
},
|
|
185
176
|
printWarning(title, warning) {
|
|
186
177
|
console.warn(`[${this.time()}] [WARN] [SWPP] [${title}]: ${JSON.stringify(warning, null, 2)}`);
|
|
187
178
|
},
|
|
@@ -198,32 +189,6 @@ exports.utils = Object.freeze({
|
|
|
198
189
|
}
|
|
199
190
|
return result;
|
|
200
191
|
},
|
|
201
|
-
/** 深度冻结一个对象 */
|
|
202
|
-
deepFreeze(obj) {
|
|
203
|
-
const result = Object.freeze(obj);
|
|
204
|
-
for (let key in result) {
|
|
205
|
-
this.deepFreeze(obj[key]);
|
|
206
|
-
}
|
|
207
|
-
return result;
|
|
208
|
-
},
|
|
209
|
-
/** 二分查找 */
|
|
210
|
-
binarySearch(array, value, startInclude = 0, endExclude = array.length, comparator = (a, b) => a < b ? -1 : (a == b ? 0 : 1)) {
|
|
211
|
-
let left = startInclude, right = endExclude - 1;
|
|
212
|
-
while (left <= right) {
|
|
213
|
-
const midIndex = (left + right) >>> 1;
|
|
214
|
-
const cmp = comparator(array[midIndex], value);
|
|
215
|
-
if (cmp < 0) {
|
|
216
|
-
left = midIndex + 1;
|
|
217
|
-
}
|
|
218
|
-
else if (cmp > 0) {
|
|
219
|
-
right = midIndex - 1;
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
return midIndex;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return -left - 1;
|
|
226
|
-
},
|
|
227
192
|
/**
|
|
228
193
|
* 在可迭代容器中查找满足指定条件的元素的下标
|
|
229
194
|
*/
|
|
@@ -236,19 +201,36 @@ exports.utils = Object.freeze({
|
|
|
236
201
|
++index;
|
|
237
202
|
}
|
|
238
203
|
return result;
|
|
204
|
+
},
|
|
205
|
+
/**
|
|
206
|
+
* 查找一个字符串中倒数第二次出现的子串的下标
|
|
207
|
+
*/
|
|
208
|
+
findSecondLastIndex(str, searchString, position = str.length) {
|
|
209
|
+
const lastIndex = str.lastIndexOf(searchString, position);
|
|
210
|
+
if (lastIndex < 0)
|
|
211
|
+
return lastIndex;
|
|
212
|
+
return str.lastIndexOf(searchString, lastIndex - 1);
|
|
239
213
|
}
|
|
240
|
-
}
|
|
214
|
+
};
|
|
241
215
|
exports.exceptionNames = {
|
|
216
|
+
/** 循环依赖 */
|
|
217
|
+
circularDependencies: 'circular_dependencies',
|
|
242
218
|
/** 无效的变量名 */
|
|
243
219
|
invalidVarName: 'invalid_var_name',
|
|
244
220
|
/** 无效的变量类型 */
|
|
245
221
|
invalidVarType: 'invalid_var_type',
|
|
246
222
|
/** 无效的插入键 */
|
|
247
223
|
invalidKey: 'invalid_key',
|
|
224
|
+
/** 无效的插入值 */
|
|
225
|
+
invalidValue: 'invalid_value',
|
|
226
|
+
/** KV 库已经被冻结无法修改 */
|
|
227
|
+
isFrozen: 'is_frozen',
|
|
248
228
|
/** 不支持的版本号 */
|
|
249
229
|
unsupportedVersion: 'unsupported_version',
|
|
250
230
|
/** 不支持的文件类型 */
|
|
251
231
|
unsupportedFileType: 'unsupported_file_type',
|
|
232
|
+
/** 不支持的操作 */
|
|
233
|
+
unsupportedOperate: 'unsupported_operate',
|
|
252
234
|
/** 空指针 */
|
|
253
235
|
nullPoint: 'null_point',
|
|
254
236
|
/** 配置文件已经完成构建 */
|
|
@@ -258,3 +240,15 @@ exports.exceptionNames = {
|
|
|
258
240
|
/** 未知分类错误 */
|
|
259
241
|
error: 'error'
|
|
260
242
|
};
|
|
243
|
+
class RuntimeException extends Error {
|
|
244
|
+
constructor(code, message, addOn) {
|
|
245
|
+
super();
|
|
246
|
+
this.code = code;
|
|
247
|
+
this.message = message;
|
|
248
|
+
this.addOn = addOn;
|
|
249
|
+
this.name = 'top.kmar.swpp.RuntimeException';
|
|
250
|
+
this.message = '运行时发生异常 ' + JSON.stringify({ code, message, addOn }, null, 2);
|
|
251
|
+
Object.setPrototypeOf(this, RuntimeException.prototype);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
exports.RuntimeException = RuntimeException;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swpp-backends",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.310",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
|
-
"typings": "
|
|
5
|
+
"typings": "dist/index.d.ts",
|
|
6
6
|
"description": "Generate a powerful ServiceWorker for your website.",
|
|
7
7
|
"author": "kmar",
|
|
8
8
|
"license": "AGPL-3.0",
|
package/types/DomBuilder.d.ts
DELETED
package/types/FileAnalyzer.d.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { FileFetchModeLevel } from './SwppConfig';
|
|
2
|
-
/**
|
|
3
|
-
* 构建一个 version json
|
|
4
|
-
*
|
|
5
|
-
* + **执行该函数前必须调用过 [loadRules]**
|
|
6
|
-
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
7
|
-
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
8
|
-
*
|
|
9
|
-
* @param protocol 网站的网络协议
|
|
10
|
-
* @param domain 网站域名(包括二级域名)
|
|
11
|
-
* @param root 网页根目录(首页 index.html 所在目录)
|
|
12
|
-
*/
|
|
13
|
-
export declare function buildVersionJson(protocol: ('https://' | 'http://'), domain: string, root: string): Promise<VersionJson>;
|
|
14
|
-
/**
|
|
15
|
-
* 版本信息(可以用 JSON 序列化)
|
|
16
|
-
* @see VersionMap
|
|
17
|
-
*/
|
|
18
|
-
export interface VersionJson {
|
|
19
|
-
version: number;
|
|
20
|
-
list: VersionMap;
|
|
21
|
-
external: {
|
|
22
|
-
[propName: string]: any;
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* 版本列表
|
|
27
|
-
*
|
|
28
|
-
* + key 为文件的 URL
|
|
29
|
-
* + getter {string} 为 URL 对应文件的 md5 值
|
|
30
|
-
* + getter {string[]} 为 stable 文件其中包含的 URL
|
|
31
|
-
*/
|
|
32
|
-
export interface VersionMap {
|
|
33
|
-
[propName: string]: any;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* 判断指定 URL 是否排除
|
|
37
|
-
*
|
|
38
|
-
* + **执行该函数前必须调用过 [loadRules]**
|
|
39
|
-
*
|
|
40
|
-
* @param domain 网站域名
|
|
41
|
-
* @param url 要判断的 URL
|
|
42
|
-
*/
|
|
43
|
-
export declare function isExclude(domain: string, url: string): boolean;
|
|
44
|
-
/**
|
|
45
|
-
* 判断指定 URL 是否是 stable 的
|
|
46
|
-
*
|
|
47
|
-
* + **执行该函数前必须调用过 [loadRules]**
|
|
48
|
-
*/
|
|
49
|
-
export declare function isStable(url: string): boolean;
|
|
50
|
-
/**
|
|
51
|
-
* 从指定 URL 加载 version json
|
|
52
|
-
*
|
|
53
|
-
* + **执行该函数前必须调用过 [loadRules]**
|
|
54
|
-
*/
|
|
55
|
-
export declare function loadVersionJson(url: string, level?: FileFetchModeLevel): Promise<VersionJson | null>;
|
|
56
|
-
/** 提交要存储到 version json 的值 */
|
|
57
|
-
export declare function submitCacheInfo(key: string, value: any): void;
|
|
58
|
-
/** 添加一个要监听的 URL */
|
|
59
|
-
export declare function submitExternalUrl(url: string): void;
|
|
60
|
-
/** 注册一个文件处理器 */
|
|
61
|
-
export declare function registryFileHandler(handler: FileHandler): void;
|
|
62
|
-
/** 查询一个文件处理器 */
|
|
63
|
-
export declare function findFileHandler(url: string): FileHandler | undefined;
|
|
64
|
-
/**
|
|
65
|
-
* 检索一个 URL 指向的文件中所有地外部链接
|
|
66
|
-
*
|
|
67
|
-
* 该函数会处理该 URL 指向的文件和文件中直接或间接包含的所有 URL
|
|
68
|
-
*
|
|
69
|
-
* + **执行该函数前必须调用过 [loadRules]**
|
|
70
|
-
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
71
|
-
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
72
|
-
*
|
|
73
|
-
* @param domain 网站域名
|
|
74
|
-
* @param url 要检索的 URL
|
|
75
|
-
* @param result 存放结果的对象
|
|
76
|
-
* @param event 检索到一个 URL 时触发的事件
|
|
77
|
-
*/
|
|
78
|
-
export declare function eachAllLinkInUrl(domain: string, url: string, result: VersionMap, event?: (url: string) => void): Promise<void>;
|
|
79
|
-
/**
|
|
80
|
-
* 查询指定 URL 对应的缓存规则
|
|
81
|
-
*
|
|
82
|
-
* + **执行该函数前必须调用过 [loadRules]**
|
|
83
|
-
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
84
|
-
*/
|
|
85
|
-
export declare function findCache(url: URL | string): any | null;
|
|
86
|
-
/**
|
|
87
|
-
* 替换请求
|
|
88
|
-
*
|
|
89
|
-
* + **执行该函数前必须调用过 [loadRules]**
|
|
90
|
-
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
91
|
-
*/
|
|
92
|
-
export declare function replaceRequest(url: string): string;
|
|
93
|
-
export interface FileHandler {
|
|
94
|
-
match: (url: string) => boolean;
|
|
95
|
-
handle: (domain: string, url: string, content: string, result: VersionMap, event?: (url: string) => void) => Promise<any>;
|
|
96
|
-
}
|