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
|
@@ -8,7 +8,17 @@ const RuntimeKeyValueDatabase_1 = require("./RuntimeKeyValueDatabase");
|
|
|
8
8
|
*/
|
|
9
9
|
class CrossDepCode extends RuntimeKeyValueDatabase_1.RuntimeKeyValueDatabase {
|
|
10
10
|
constructor() {
|
|
11
|
-
super(buildCommon())
|
|
11
|
+
super('CrossDepCode', buildCommon(), (key, value) => {
|
|
12
|
+
if (typeof value != 'object') {
|
|
13
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidVarType, `crossDep[${key}] 返回的内容应当为一个 object`, { value });
|
|
14
|
+
}
|
|
15
|
+
if (!('runOnNode' in value)) {
|
|
16
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidVarType, `crossDep[${key}] 返回的对象应当包含 {runOnNode} 字段`, { value });
|
|
17
|
+
}
|
|
18
|
+
if (!('runOnBrowser' in value)) {
|
|
19
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidVarType, `crossDep[${key}] 返回的对象应当包含 {runOnBrowser} 字段`, { value });
|
|
20
|
+
}
|
|
21
|
+
});
|
|
12
22
|
}
|
|
13
23
|
/** 构建 JS 源代码 */
|
|
14
24
|
buildJsSource() {
|
|
@@ -28,6 +38,22 @@ function buildCommon() {
|
|
|
28
38
|
}
|
|
29
39
|
})
|
|
30
40
|
},
|
|
41
|
+
/** 归一化 URL */
|
|
42
|
+
normalizeUrl: {
|
|
43
|
+
default: buildFunction({
|
|
44
|
+
runOnBrowser: (url) => {
|
|
45
|
+
if (url.endsWith('/index.html'))
|
|
46
|
+
return url.substring(0, url.length - 10);
|
|
47
|
+
if (url.endsWith('.html'))
|
|
48
|
+
return url.substring(0, url.length - 5);
|
|
49
|
+
else
|
|
50
|
+
return url;
|
|
51
|
+
},
|
|
52
|
+
runOnNode(url) {
|
|
53
|
+
return this.runOnBrowser(url);
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
},
|
|
31
57
|
/** 匹配缓存更新规则 */
|
|
32
58
|
matchUpdateRule: {
|
|
33
59
|
default: buildFunction({
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.CrossEnv = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const ConfigCluster_1 = require("../config/ConfigCluster");
|
|
4
9
|
const untils_1 = require("../untils");
|
|
5
10
|
const KeyValueDatabase_1 = require("./KeyValueDatabase");
|
|
6
11
|
const RuntimeKeyValueDatabase_1 = require("./RuntimeKeyValueDatabase");
|
|
@@ -11,7 +16,11 @@ function isLegalHeaderName(name) {
|
|
|
11
16
|
/** 环境变量存储器 */
|
|
12
17
|
class CrossEnv extends RuntimeKeyValueDatabase_1.RuntimeKeyValueDatabase {
|
|
13
18
|
constructor() {
|
|
14
|
-
super(buildCommon())
|
|
19
|
+
super('CrossEnv', buildCommon(), (key, value) => {
|
|
20
|
+
if (typeof value === 'function') {
|
|
21
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidVarType, `crossEnv[${key}] 应当返回一个非函数`, { value: value.toString() });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
15
24
|
}
|
|
16
25
|
/** 构建 JS 源代码 */
|
|
17
26
|
buildJsSource() {
|
|
@@ -60,7 +69,15 @@ function buildCommon() {
|
|
|
60
69
|
}),
|
|
61
70
|
/** 版本文件所在目录 */
|
|
62
71
|
UPDATE_JSON_URL: (0, KeyValueDatabase_1.buildEnv)({
|
|
63
|
-
default:
|
|
72
|
+
default: (0, ConfigCluster_1.defineLazyInitConfig)((_, compilation) => {
|
|
73
|
+
const info = compilation.compilationEnv.read('SWPP_JSON_FILE');
|
|
74
|
+
return path_1.default.posix.join(info.swppPath, info.versionPath);
|
|
75
|
+
}),
|
|
76
|
+
checker(value) {
|
|
77
|
+
if (this.manual)
|
|
78
|
+
return { value, message: '不应当手动设置该项!' };
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
64
81
|
}),
|
|
65
82
|
/** 检查更新的最短时间间隔 */
|
|
66
83
|
UPDATE_CD: (0, KeyValueDatabase_1.buildEnv)({
|
|
@@ -6,6 +6,9 @@ export declare class DomCode extends RuntimeKeyValueDatabase<any, COMMON_TYPE_DO
|
|
|
6
6
|
buildInnerSource(): string;
|
|
7
7
|
}
|
|
8
8
|
declare function buildCommon(): {
|
|
9
|
+
readonly registry: {
|
|
10
|
+
readonly default: import("../config/SpecialConfig").LazyInitConfig<string>;
|
|
11
|
+
};
|
|
9
12
|
readonly postMessage2Sw: {
|
|
10
13
|
readonly default: (type: string) => void;
|
|
11
14
|
};
|
|
@@ -22,7 +25,7 @@ declare function buildCommon(): {
|
|
|
22
25
|
readonly default: () => void;
|
|
23
26
|
};
|
|
24
27
|
readonly messageEvent: {
|
|
25
|
-
readonly default: (event: MessageEvent) =>
|
|
28
|
+
readonly default: (event: MessageEvent) => void;
|
|
26
29
|
};
|
|
27
30
|
};
|
|
28
31
|
export {};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DomCode = 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
|
class DomCode extends RuntimeKeyValueDatabase_1.RuntimeKeyValueDatabase {
|
|
7
8
|
constructor() {
|
|
8
|
-
super(buildCommon());
|
|
9
|
+
super('DomCode', buildCommon());
|
|
9
10
|
}
|
|
10
11
|
buildJsSource() {
|
|
11
12
|
return `
|
|
@@ -16,9 +17,10 @@ class DomCode extends RuntimeKeyValueDatabase_1.RuntimeKeyValueDatabase {
|
|
|
16
17
|
}
|
|
17
18
|
buildInnerSource() {
|
|
18
19
|
const map = this.entries();
|
|
20
|
+
delete map['registry'];
|
|
19
21
|
const inlineCode = Object.keys(map)
|
|
20
22
|
.filter(it => it.startsWith('_inline'))
|
|
21
|
-
.map(it =>
|
|
23
|
+
.map(it => `(${it.toString()})()`);
|
|
22
24
|
return `
|
|
23
25
|
const controller = navigator.serviceWorker?.controller
|
|
24
26
|
if (!controller) return
|
|
@@ -31,15 +33,42 @@ class DomCode extends RuntimeKeyValueDatabase_1.RuntimeKeyValueDatabase {
|
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
exports.DomCode = DomCode;
|
|
34
|
-
let controller;
|
|
35
36
|
let SESSION_KEY;
|
|
36
37
|
let onSuccess;
|
|
37
38
|
let pjaxUpdate;
|
|
38
39
|
let postMessage2Sw;
|
|
39
40
|
function buildCommon() {
|
|
40
41
|
return {
|
|
42
|
+
registry: {
|
|
43
|
+
default: (0, ConfigCluster_1.defineLazyInitConfig)((_, compilation) => {
|
|
44
|
+
const value = (() => {
|
|
45
|
+
const sw = navigator.serviceWorker;
|
|
46
|
+
if (sw) {
|
|
47
|
+
sw.register('$$sw.js')
|
|
48
|
+
.then(async (registration) => {
|
|
49
|
+
console.log('SWPP 注册成功');
|
|
50
|
+
try {
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
await registration.periodicSync.register("update", {
|
|
53
|
+
minInterval: 24 * 60 * 60 * 1000
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
console.warn('Periodic Sync 注册失败', e);
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
.catch(err => console.error('SWPP 注册失败', err));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
console.warn('当前浏览器不支持 SW');
|
|
64
|
+
}
|
|
65
|
+
}).toString();
|
|
66
|
+
const path = compilation.compilationEnv.read('SERVICE_WORKER');
|
|
67
|
+
return value.replace(`'$$sw.js'`, path + '.js');
|
|
68
|
+
})
|
|
69
|
+
},
|
|
41
70
|
postMessage2Sw: {
|
|
42
|
-
default: (type) => controller.postMessage(type)
|
|
71
|
+
default: (type) => navigator.serviceWorker.controller.postMessage(type)
|
|
43
72
|
},
|
|
44
73
|
pjaxUpdate: {
|
|
45
74
|
default: (url) => {
|
|
@@ -76,7 +105,7 @@ function buildCommon() {
|
|
|
76
105
|
}
|
|
77
106
|
},
|
|
78
107
|
messageEvent: {
|
|
79
|
-
default:
|
|
108
|
+
default: (event) => {
|
|
80
109
|
const data = event.data;
|
|
81
110
|
sessionStorage.setItem(SESSION_KEY, data.type);
|
|
82
111
|
const list = data.data?.filter((url) => /\.(js|css)$/.test(url));
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { RuntimeSpecialConfig } from '../config/SpecialConfig';
|
|
2
|
+
import { CompilationData, RuntimeData } from '../SwCompiler';
|
|
3
|
+
/** 键值对存储器 */
|
|
4
|
+
export declare class KeyValueDatabase<T, CONTAINER extends Record<string, DatabaseValue<T>>> {
|
|
5
|
+
readonly namespace: string;
|
|
6
|
+
private readonly globalChecker?;
|
|
7
|
+
private dataValues;
|
|
8
|
+
private valueCaches;
|
|
9
|
+
private _runtime;
|
|
10
|
+
private _compilation;
|
|
11
|
+
/**
|
|
12
|
+
* @param namespace 命名空间
|
|
13
|
+
* @param map 默认值
|
|
14
|
+
* @param globalChecker 全局检查器(优先于每个属性设置的 checker 执行),遇到问题直接抛出异常
|
|
15
|
+
*/
|
|
16
|
+
constructor(namespace: string, map?: CONTAINER, globalChecker?: ((key: string, value: T) => void) | undefined);
|
|
17
|
+
/** 延迟初始化 */
|
|
18
|
+
protected lazyInit(map: CONTAINER): void;
|
|
19
|
+
/** 初始化各项数据 */
|
|
20
|
+
initRuntimeAndCompilation(runtime: RuntimeData, compilation: CompilationData): void;
|
|
21
|
+
/**
|
|
22
|
+
* 读取指定键对应的值。
|
|
23
|
+
*
|
|
24
|
+
* 注意:允许被缓存的值返回后是不允许被修改的,不缓存的值是允许修改的。
|
|
25
|
+
*/
|
|
26
|
+
read<K extends keyof CONTAINER | string>(_key: K): K extends keyof CONTAINER ? Exclude<CONTAINER[K]['default'], RuntimeSpecialConfig<any>> : T;
|
|
27
|
+
/** 读取默认配置 */
|
|
28
|
+
readDefault<K extends keyof CONTAINER | string>(_key: K): K extends keyof CONTAINER ? CONTAINER[K]['default'] : T;
|
|
29
|
+
/**
|
|
30
|
+
* 设置指定键对应的值
|
|
31
|
+
*/
|
|
32
|
+
update<K extends keyof CONTAINER | string>(key: K, manual: T | RuntimeSpecialConfig<T>): void;
|
|
33
|
+
/**
|
|
34
|
+
* 追加键值对
|
|
35
|
+
*/
|
|
36
|
+
append(key: string, env: DatabaseValue<T>): void;
|
|
37
|
+
/** 判断是否存在指定的环境变量 */
|
|
38
|
+
hasKey<K extends keyof CONTAINER | string>(key: K): (K extends keyof CONTAINER ? true : boolean);
|
|
39
|
+
/** 判断指定键对应的环境变量是否存在用户设置的值 */
|
|
40
|
+
hasValue<K extends keyof CONTAINER | string>(key: K): boolean;
|
|
41
|
+
/** 获取所有键值对 */
|
|
42
|
+
entries(): Record<string, T>;
|
|
43
|
+
/** 冻结 KV 库,冻结后无法再添加和修改内容 */
|
|
44
|
+
freeze(): void;
|
|
45
|
+
protected get runtime(): RuntimeData;
|
|
46
|
+
protected get compilation(): CompilationData;
|
|
47
|
+
private set runtime(value);
|
|
48
|
+
private set compilation(value);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 为优化 IDE 的类型推断提供的函数,直接返回传入的值
|
|
52
|
+
* @param env
|
|
53
|
+
*/
|
|
54
|
+
export declare function buildEnv<T>(env: DatabaseValue<T>): DatabaseValue<T>;
|
|
55
|
+
/**
|
|
56
|
+
* 读取指定对象中的指定字段。
|
|
57
|
+
*
|
|
58
|
+
* 由于配置文件中允许同时写入 T 或 `Runtime<T>`,当在配置项中使用 `this` 时,需要先判定 `this` 是哪一个类型
|
|
59
|
+
*/
|
|
60
|
+
export declare function readThisValue<T extends RuntimeSpecialConfig<object> | object, K extends keyof (T extends RuntimeSpecialConfig<any> ? ReturnType<T['get']> : T)>(obj: T, key: K): T extends RuntimeSpecialConfig<any> ? ReturnType<T['get']>[K] : T[K];
|
|
61
|
+
export interface DatabaseValue<T> {
|
|
62
|
+
/** 缺省值 */
|
|
63
|
+
default: T | RuntimeSpecialConfig<T>;
|
|
64
|
+
/** 用户填入的值 */
|
|
65
|
+
manual?: T | RuntimeSpecialConfig<T>;
|
|
66
|
+
/** 检查器,返回 false 表示无错误 */
|
|
67
|
+
checker?: (value: T) => false | RuntimeEnvErrorTemplate<T>;
|
|
68
|
+
}
|
|
69
|
+
export interface RuntimeEnvErrorTemplate<T> {
|
|
70
|
+
value: T;
|
|
71
|
+
message: string;
|
|
72
|
+
}
|
|
@@ -2,69 +2,156 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.KeyValueDatabase = void 0;
|
|
4
4
|
exports.buildEnv = buildEnv;
|
|
5
|
+
exports.readThisValue = readThisValue;
|
|
6
|
+
const SpecialConfig_1 = require("../config/SpecialConfig");
|
|
7
|
+
const untils_1 = require("../untils");
|
|
5
8
|
/** 键值对存储器 */
|
|
6
9
|
class KeyValueDatabase {
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @param namespace 命名空间
|
|
12
|
+
* @param map 默认值
|
|
13
|
+
* @param globalChecker 全局检查器(优先于每个属性设置的 checker 执行),遇到问题直接抛出异常
|
|
14
|
+
*/
|
|
15
|
+
constructor(namespace, map, globalChecker) {
|
|
16
|
+
this.namespace = namespace;
|
|
17
|
+
this.globalChecker = globalChecker;
|
|
18
|
+
this.dataValues = {};
|
|
19
|
+
this.valueCaches = {};
|
|
20
|
+
this._runtime = null;
|
|
21
|
+
this._compilation = null;
|
|
9
22
|
if (map) {
|
|
10
|
-
Object.assign(this.
|
|
23
|
+
Object.assign(this.dataValues, map);
|
|
11
24
|
}
|
|
12
25
|
}
|
|
13
26
|
/** 延迟初始化 */
|
|
14
27
|
lazyInit(map) {
|
|
15
|
-
Object.assign(this.
|
|
28
|
+
Object.assign(this.dataValues, map);
|
|
29
|
+
}
|
|
30
|
+
/** 初始化各项数据 */
|
|
31
|
+
initRuntimeAndCompilation(runtime, compilation) {
|
|
32
|
+
this.runtime = runtime;
|
|
33
|
+
this.compilation = compilation;
|
|
16
34
|
}
|
|
17
35
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
36
|
+
* 读取指定键对应的值。
|
|
37
|
+
*
|
|
38
|
+
* 注意:允许被缓存的值返回后是不允许被修改的,不缓存的值是允许修改的。
|
|
20
39
|
*/
|
|
21
|
-
read(
|
|
22
|
-
const
|
|
40
|
+
read(_key) {
|
|
41
|
+
const key = _key;
|
|
42
|
+
if (key in this.valueCaches) {
|
|
43
|
+
return this.valueCaches[key];
|
|
44
|
+
}
|
|
45
|
+
const item = this.dataValues[key];
|
|
23
46
|
if (!item)
|
|
24
|
-
throw
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
47
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidKey, `输入的 key[${key}] 不存在`);
|
|
48
|
+
// 获取真实值
|
|
49
|
+
let value = item.default;
|
|
50
|
+
let isNoCache = false;
|
|
51
|
+
if (item.manual) {
|
|
52
|
+
if (SpecialConfig_1.SpecialConfig.isSpecialConfig(item.manual)) {
|
|
53
|
+
this.runtime.debugCallChain.push(this.namespace, key);
|
|
54
|
+
value = item.manual.get(this.runtime, this.compilation);
|
|
55
|
+
this.runtime.debugCallChain.pop(this.namespace, key);
|
|
56
|
+
if (SpecialConfig_1.SpecialConfig.isNoCacheConfig(item.manual)) {
|
|
57
|
+
isNoCache = true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
value = item.manual;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// 进行类型预检
|
|
65
|
+
if (!(value === null || value === undefined) && typeof value != typeof item.default) {
|
|
66
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidValue, '用户传入的值类型与缺省值类型不统一', { default: item.default, value });
|
|
67
|
+
}
|
|
68
|
+
// 执行全局检查
|
|
69
|
+
this.globalChecker?.(key, value);
|
|
70
|
+
// 执行用户数据检查
|
|
28
71
|
const checkResult = item.checker?.(value);
|
|
29
|
-
if (checkResult)
|
|
30
|
-
throw { key, ...checkResult };
|
|
31
|
-
|
|
72
|
+
if (checkResult) {
|
|
73
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidValue, `设置的值非法`, { key, ...checkResult });
|
|
74
|
+
}
|
|
75
|
+
// 如果不需要缓存直接返回,否则存入缓存后返回
|
|
76
|
+
if (isNoCache)
|
|
77
|
+
return value;
|
|
78
|
+
return this.valueCaches[key] = value;
|
|
79
|
+
}
|
|
80
|
+
/** 读取默认配置 */
|
|
81
|
+
readDefault(_key) {
|
|
82
|
+
const key = _key;
|
|
83
|
+
const item = this.dataValues[key];
|
|
84
|
+
if (!item)
|
|
85
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidKey, `传入的 key[${key}] 不存在`);
|
|
86
|
+
return item.default;
|
|
32
87
|
}
|
|
33
88
|
/**
|
|
34
89
|
* 设置指定键对应的值
|
|
35
|
-
* @throws RuntimeEnvException
|
|
36
90
|
*/
|
|
37
|
-
update(key,
|
|
38
|
-
if (!(key in this.
|
|
39
|
-
throw
|
|
40
|
-
this.
|
|
91
|
+
update(key, manual) {
|
|
92
|
+
if (!(key in this.dataValues))
|
|
93
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidKey, `传入的 key[${key}] 不存在`);
|
|
94
|
+
this.dataValues[key].manual = manual;
|
|
95
|
+
delete this.valueCaches[key];
|
|
41
96
|
}
|
|
42
97
|
/**
|
|
43
98
|
* 追加键值对
|
|
44
|
-
* @throws RuntimeEnvException
|
|
45
99
|
*/
|
|
46
100
|
append(key, env) {
|
|
47
|
-
if (key in this.
|
|
48
|
-
throw
|
|
49
|
-
|
|
101
|
+
if (key in this.dataValues)
|
|
102
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidKey, `追加的 key[${key}] 已存在`);
|
|
103
|
+
if ('manual' in env)
|
|
104
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.invalidValue, `追加的属性中不应当包含 getter 字段`);
|
|
105
|
+
this.dataValues[key] = env;
|
|
50
106
|
}
|
|
51
107
|
/** 判断是否存在指定的环境变量 */
|
|
52
108
|
hasKey(key) {
|
|
53
109
|
// @ts-ignore
|
|
54
|
-
return key in this.
|
|
110
|
+
return key in this.dataValues;
|
|
55
111
|
}
|
|
56
112
|
/** 判断指定键对应的环境变量是否存在用户设置的值 */
|
|
57
113
|
hasValue(key) {
|
|
58
|
-
return this.hasKey(key) && !!this.
|
|
114
|
+
return this.hasKey(key) && !!this.dataValues[key].manual;
|
|
59
115
|
}
|
|
60
116
|
/** 获取所有键值对 */
|
|
61
117
|
entries() {
|
|
62
118
|
const result = {};
|
|
63
|
-
for (let key in this.
|
|
119
|
+
for (let key in this.dataValues) {
|
|
64
120
|
result[key] = this.read(key);
|
|
65
121
|
}
|
|
66
122
|
return result;
|
|
67
123
|
}
|
|
124
|
+
/** 冻结 KV 库,冻结后无法再添加和修改内容 */
|
|
125
|
+
freeze() {
|
|
126
|
+
if (Object.isFrozen(this.dataValues))
|
|
127
|
+
return;
|
|
128
|
+
this.dataValues = new Proxy(Object.freeze(this.dataValues), {
|
|
129
|
+
set() {
|
|
130
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.isFrozen, 'KV 库已经被冻结无法修改');
|
|
131
|
+
},
|
|
132
|
+
setPrototypeOf() {
|
|
133
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.isFrozen, 'KV 库已经被冻结无法修改');
|
|
134
|
+
},
|
|
135
|
+
deleteProperty() {
|
|
136
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.isFrozen, 'KV 库已经被冻结无法修改');
|
|
137
|
+
},
|
|
138
|
+
defineProperty() {
|
|
139
|
+
throw new untils_1.RuntimeException(untils_1.exceptionNames.isFrozen, 'KV 库已经被冻结无法修改');
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
get runtime() {
|
|
144
|
+
return this._runtime;
|
|
145
|
+
}
|
|
146
|
+
get compilation() {
|
|
147
|
+
return this._compilation;
|
|
148
|
+
}
|
|
149
|
+
set runtime(value) {
|
|
150
|
+
this._runtime = value;
|
|
151
|
+
}
|
|
152
|
+
set compilation(value) {
|
|
153
|
+
this._compilation = value;
|
|
154
|
+
}
|
|
68
155
|
}
|
|
69
156
|
exports.KeyValueDatabase = KeyValueDatabase;
|
|
70
157
|
/**
|
|
@@ -74,3 +161,11 @@ exports.KeyValueDatabase = KeyValueDatabase;
|
|
|
74
161
|
function buildEnv(env) {
|
|
75
162
|
return env;
|
|
76
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* 读取指定对象中的指定字段。
|
|
166
|
+
*
|
|
167
|
+
* 由于配置文件中允许同时写入 T 或 `Runtime<T>`,当在配置项中使用 `this` 时,需要先判定 `this` 是哪一个类型
|
|
168
|
+
*/
|
|
169
|
+
function readThisValue(obj, key) {
|
|
170
|
+
return obj[key];
|
|
171
|
+
}
|
|
@@ -5,7 +5,7 @@ export type COMMON_TYPE_RUNTIME_CORE = ReturnType<typeof buildCommon>;
|
|
|
5
5
|
/**
|
|
6
6
|
* 运行时核心功能代码
|
|
7
7
|
*/
|
|
8
|
-
export declare class RuntimeCoreCode extends RuntimeKeyValueDatabase<FunctionInBrowser<any, any> | null, COMMON_TYPE_RUNTIME_CORE> {
|
|
8
|
+
export declare class RuntimeCoreCode extends RuntimeKeyValueDatabase<FunctionInBrowser<any[], any> | null, COMMON_TYPE_RUNTIME_CORE> {
|
|
9
9
|
constructor();
|
|
10
10
|
/** 构建 JS 源代码 */
|
|
11
11
|
buildJsSource(): string;
|
|
@@ -23,6 +23,7 @@ declare function buildCommon(): {
|
|
|
23
23
|
readonly handleUpdate: {
|
|
24
24
|
readonly default: (oldVersion: BrowserVersion | undefined, force?: boolean) => Promise<1 | -1 | 2 | undefined | null | void | string[]>;
|
|
25
25
|
};
|
|
26
|
+
/** 处理网络请求事件 */
|
|
26
27
|
readonly handleFetchEvent: {
|
|
27
28
|
readonly default: (event: Event) => any;
|
|
28
29
|
};
|
|
@@ -29,7 +29,7 @@ let matchUpdateRule;
|
|
|
29
29
|
*/
|
|
30
30
|
class RuntimeCoreCode extends RuntimeKeyValueDatabase_1.RuntimeKeyValueDatabase {
|
|
31
31
|
constructor() {
|
|
32
|
-
super(buildCommon());
|
|
32
|
+
super('RuntimeCoreCode', buildCommon());
|
|
33
33
|
}
|
|
34
34
|
/** 构建 JS 源代码 */
|
|
35
35
|
buildJsSource() {
|
|
@@ -41,13 +41,13 @@ function buildCommon() {
|
|
|
41
41
|
return {
|
|
42
42
|
/** 逃生门功能实现 */
|
|
43
43
|
handleEscape: {
|
|
44
|
-
default: () =>
|
|
45
|
-
|
|
46
|
-
if (oldVersion && oldVersion.escape !== ESCAPE) {
|
|
44
|
+
default: async () => {
|
|
45
|
+
const oldVersion = await readVersion();
|
|
46
|
+
if (ESCAPE && oldVersion && oldVersion.escape !== ESCAPE) {
|
|
47
47
|
await caches.delete(CACHE_NAME);
|
|
48
48
|
await postMessage('escape', null);
|
|
49
49
|
}
|
|
50
|
-
}
|
|
50
|
+
}
|
|
51
51
|
},
|
|
52
52
|
/**
|
|
53
53
|
* 缓存增量更新功能实现
|
|
@@ -103,6 +103,7 @@ function buildCommon() {
|
|
|
103
103
|
return 2;
|
|
104
104
|
}
|
|
105
105
|
},
|
|
106
|
+
/** 处理网络请求事件 */
|
|
106
107
|
handleFetchEvent: {
|
|
107
108
|
default: (event) => {
|
|
108
109
|
// @ts-ignore
|
|
@@ -5,10 +5,8 @@ import { RuntimeKeyValueDatabase } from './RuntimeKeyValueDatabase';
|
|
|
5
5
|
export type FunctionInBrowser<Args extends any[], R> = (...args: Args) => R;
|
|
6
6
|
export type COMMON_KEY_RUNTIME_DEP = ReturnType<typeof buildCommon>;
|
|
7
7
|
/** 运行时依赖代码 */
|
|
8
|
-
export declare class RuntimeDepCode extends RuntimeKeyValueDatabase<FunctionInBrowser<any, any> | null, COMMON_KEY_RUNTIME_DEP> {
|
|
8
|
+
export declare class RuntimeDepCode extends RuntimeKeyValueDatabase<FunctionInBrowser<any[], any> | null, COMMON_KEY_RUNTIME_DEP> {
|
|
9
9
|
constructor();
|
|
10
|
-
/** 修正函数 */
|
|
11
|
-
fixDepFunction(): void;
|
|
12
10
|
/** 构建 JS 源代码 */
|
|
13
11
|
buildJsSource(): string;
|
|
14
12
|
}
|
|
@@ -32,7 +30,7 @@ declare function buildCommon(): {
|
|
|
32
30
|
};
|
|
33
31
|
/** 判断指定的缓存是否是有效缓存 */
|
|
34
32
|
readonly isValidCache: {
|
|
35
|
-
readonly default: (response: Response, rule: number
|
|
33
|
+
readonly default: (response: Response, rule: number) => boolean;
|
|
36
34
|
};
|
|
37
35
|
/** 读取版本号 */
|
|
38
36
|
readonly readVersion: {
|
|
@@ -65,13 +63,13 @@ declare function buildCommon(): {
|
|
|
65
63
|
};
|
|
66
64
|
/** 获取竞速列表 */
|
|
67
65
|
readonly getFastestRequests: {
|
|
68
|
-
readonly default: null;
|
|
69
|
-
readonly checker: (value: FunctionInBrowser<any, any> | null) => false | RuntimeEnvErrorTemplate<FunctionInBrowser<any[], any>>;
|
|
66
|
+
readonly default: FunctionInBrowser<any[], any> | null;
|
|
67
|
+
readonly checker: (value: FunctionInBrowser<any[], any> | null) => false | RuntimeEnvErrorTemplate<FunctionInBrowser<any[], any>>;
|
|
70
68
|
};
|
|
71
69
|
/** 获取备用 URL 列表 */
|
|
72
70
|
readonly getStandbyRequests: {
|
|
73
|
-
readonly default: null;
|
|
74
|
-
readonly checker: (value: FunctionInBrowser<any, any> | null) => false | RuntimeEnvErrorTemplate<FunctionInBrowser<any[], any>>;
|
|
71
|
+
readonly default: FunctionInBrowser<any[], any> | null;
|
|
72
|
+
readonly checker: (value: FunctionInBrowser<any[], any> | null) => false | RuntimeEnvErrorTemplate<FunctionInBrowser<any[], any>>;
|
|
75
73
|
};
|
|
76
74
|
/** URL 竞速拉取 */
|
|
77
75
|
readonly fetchFastest: {
|
|
@@ -81,16 +79,12 @@ declare function buildCommon(): {
|
|
|
81
79
|
readonly fetchStandby: {
|
|
82
80
|
readonly default: (request: Request, standbyRequests: {
|
|
83
81
|
t: number;
|
|
84
|
-
l: Request[];
|
|
82
|
+
l: () => Request[];
|
|
85
83
|
}, optional?: RequestInit) => Promise<Response>;
|
|
86
84
|
};
|
|
87
85
|
/** 拉取文件 */
|
|
88
86
|
readonly fetchFile: {
|
|
89
|
-
readonly default: (
|
|
90
|
-
};
|
|
91
|
-
/** 归一化 URL */
|
|
92
|
-
readonly normalizeUrl: {
|
|
93
|
-
readonly default: (url: string) => string;
|
|
87
|
+
readonly default: import("../config/SpecialConfig").LazyInitConfig<(requestOrUrl: RequestInfo | URL, optional?: RequestInit) => Promise<Response>>;
|
|
94
88
|
};
|
|
95
89
|
/** 是否阻断请求 */
|
|
96
90
|
readonly isBlockRequest: {
|