alemonjs 2.1.41 → 2.1.43
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/lib/app/define/define-children.d.ts +8 -0
- package/lib/app/define/define-children.js +25 -0
- package/lib/app/define/define-middleware.d.ts +2 -0
- package/lib/app/define/define-middleware.js +8 -0
- package/lib/app/define/define-platform.d.ts +13 -0
- package/lib/app/define/define-platform.js +40 -0
- package/lib/app/define/define-response.d.ts +2 -0
- package/lib/app/define/define-response.js +8 -0
- package/lib/app/define/define-router.d.ts +17 -0
- package/lib/app/define/define-router.js +34 -0
- package/lib/app/event/event-group.d.ts +9 -0
- package/lib/app/event/event-group.js +29 -0
- package/lib/app/event/event-middleware.d.ts +23 -0
- package/lib/app/event/event-middleware.js +44 -0
- package/lib/app/event/event-response.d.ts +16 -0
- package/lib/app/event/event-response.js +23 -0
- package/lib/app/event/event-selects.d.ts +13 -0
- package/lib/app/event/event-selects.js +15 -0
- package/lib/app/event-processor/event-processor-callHandler.d.ts +1 -0
- package/lib/app/event-processor/event-processor-callHandler.js +43 -0
- package/lib/app/event-processor/event-processor-cycle.d.ts +14 -0
- package/lib/app/event-processor/event-processor-cycle.js +97 -0
- package/lib/app/event-processor/event-processor-cycleFiles.d.ts +11 -0
- package/lib/app/event-processor/event-processor-cycleFiles.js +147 -0
- package/lib/app/event-processor/event-processor-cycleRoute.d.ts +10 -0
- package/lib/app/event-processor/event-processor-cycleRoute.js +133 -0
- package/lib/app/event-processor/event-processor-event.d.ts +24 -0
- package/lib/app/event-processor/event-processor-event.js +41 -0
- package/lib/app/event-processor/event-processor-middleware.d.ts +14 -0
- package/lib/app/event-processor/event-processor-middleware.js +31 -0
- package/lib/app/event-processor/event-processor-subscribe.d.ts +35 -0
- package/lib/app/event-processor/event-processor-subscribe.js +115 -0
- package/lib/app/event-processor/event-processor.d.ts +17 -0
- package/lib/app/event-processor/event-processor.js +207 -0
- package/lib/app/hook-use/hook-use-api.d.ts +6 -0
- package/lib/app/hook-use/hook-use-api.js +22 -0
- package/lib/app/hook-use/hook-use-channel.d.ts +8 -0
- package/lib/app/hook-use/hook-use-channel.js +33 -0
- package/lib/app/hook-use/hook-use-client.d.ts +7 -0
- package/lib/app/hook-use/hook-use-client.js +27 -0
- package/lib/app/hook-use/hook-use-me.d.ts +8 -0
- package/lib/app/hook-use/hook-use-me.js +45 -0
- package/lib/app/hook-use/hook-use-menber.d.ts +8 -0
- package/lib/app/hook-use/hook-use-menber.js +59 -0
- package/lib/app/hook-use/hook-use-mention.d.ts +23 -0
- package/lib/app/hook-use/hook-use-mention.js +105 -0
- package/lib/app/hook-use/hook-use-message.d.ts +29 -0
- package/lib/app/hook-use/hook-use-message.js +88 -0
- package/lib/app/hook-use/hook-use-state.d.ts +30 -0
- package/lib/app/hook-use/hook-use-state.js +101 -0
- package/lib/app/hook-use/hook-use-subscribe.d.ts +46 -0
- package/lib/app/hook-use/hook-use-subscribe.js +143 -0
- package/lib/app/hook-use-api.d.ts +1 -3
- package/lib/app/hook-use-api.js +3 -3
- package/lib/app/index.js +1 -1
- package/lib/app/message/message-api.d.ts +69 -0
- package/lib/app/message/message-api.js +105 -0
- package/lib/app/message/message-format-old.d.ts +143 -0
- package/lib/app/message/message-format-old.js +359 -0
- package/lib/app/message/message-format.d.ts +215 -0
- package/lib/app/message/message-format.js +382 -0
- package/lib/app/message-api.d.ts +13 -0
- package/lib/app/message-api.js +45 -1
- package/lib/app/message-format.old.d.ts +50 -0
- package/lib/app/message-format.old.js +217 -0
- package/lib/cbp/connects/platform.js +3 -3
- package/lib/cbp/processor/actions.js +5 -4
- package/lib/cbp/processor/api.js +5 -4
- package/lib/cbp/processor/handle.d.ts +3 -0
- package/lib/cbp/processor/handle.js +32 -0
- package/lib/core/index.js +1 -1
- package/lib/core/utils.d.ts +1 -0
- package/lib/core/utils.js +5 -1
- package/lib/index.js +2 -2
- package/lib/jsx/index.d.ts +105 -0
- package/lib/jsx/index.js +211 -0
- package/lib/jsx/jsx-dev-runtime.d.ts +2 -0
- package/lib/jsx/jsx-dev-runtime.js +1 -0
- package/lib/jsx/jsx-runtime.d.ts +18 -0
- package/lib/jsx/jsx-runtime.js +24 -0
- package/lib/process/client.js +109 -0
- package/lib/process/direct-channel.js +3 -1
- package/lib/process/ipc-bridge.js +10 -4
- package/lib/store/SinglyLinkedList.d.ts +22 -0
- package/lib/store/SinglyLinkedList.js +97 -0
- package/lib/store/store.d.ts +127 -0
- package/lib/store/store.js +443 -0
- package/package.json +1 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Next, Events, EventKeys, ResponseRoute } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* 创建路由处理调用函数
|
|
4
|
+
* @param valueEvent
|
|
5
|
+
* @param select
|
|
6
|
+
* @param nextCycle
|
|
7
|
+
* @param callHandler
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
export declare const createRouteProcessChildren: <T extends EventKeys>(valueEvent: Events[T], select: T, nextCycle: Next, callHandler: (currents: any, nextEvent: any) => void) => (nodes: ResponseRoute[], middleware: any, next: () => Promise<void> | void) => void;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { EventMessageText } from '../../core/variable.js';
|
|
2
|
+
import { getCachedRegExp, showErrorModule } from '../../core/utils.js';
|
|
3
|
+
|
|
4
|
+
// 缓存 AsyncFunction 构造函数 — 避免每次调用创建匿名 async 函数
|
|
5
|
+
const AsyncFunction = (async () => { }).constructor;
|
|
6
|
+
function isAsyncFunction(fn) {
|
|
7
|
+
return fn instanceof AsyncFunction;
|
|
8
|
+
}
|
|
9
|
+
function isFunction(value) {
|
|
10
|
+
return isAsyncFunction(value) || typeof value === 'function' || value instanceof Function;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 创建路由处理调用函数
|
|
14
|
+
* @param valueEvent
|
|
15
|
+
* @param select
|
|
16
|
+
* @param nextCycle
|
|
17
|
+
* @param callHandler
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
const createRouteProcessChildren = (valueEvent, select, nextCycle, callHandler) => {
|
|
21
|
+
// 开始处理 handler
|
|
22
|
+
const processChildren = (nodes, middleware, next) => {
|
|
23
|
+
if (!nodes || nodes.length === 0) {
|
|
24
|
+
void next();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
let idx = 0;
|
|
28
|
+
const nextNode = async () => {
|
|
29
|
+
idx++;
|
|
30
|
+
if (idx > nodes.length) {
|
|
31
|
+
void next();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const node = nodes[idx - 1];
|
|
35
|
+
if (node?.selects) {
|
|
36
|
+
const selects = Array.isArray(node.selects) ? node.selects : [node.selects];
|
|
37
|
+
if (!selects.includes(select)) {
|
|
38
|
+
void nextNode();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// 文本匹配(按性能从高到低:exact > prefix > regular)
|
|
43
|
+
if (EventMessageText.includes(select)) {
|
|
44
|
+
const text = valueEvent['MessageText'] ?? '';
|
|
45
|
+
// 精确匹配(最快,O(1) 字符串比较)
|
|
46
|
+
if (node.exact !== undefined) {
|
|
47
|
+
if (text !== node.exact) {
|
|
48
|
+
void nextNode();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// 前缀匹配(快,O(n) startsWith)
|
|
53
|
+
if (node.prefix !== undefined) {
|
|
54
|
+
if (!text.startsWith(node.prefix)) {
|
|
55
|
+
void nextNode();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// 正则匹配(使用缓存,避免每条消息重编译)
|
|
60
|
+
if (node.regular) {
|
|
61
|
+
if (!getCachedRegExp(node.regular).test(text)) {
|
|
62
|
+
void nextNode();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (!node.handler) {
|
|
68
|
+
void nextNode();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// 递归:如果有children,继续递归下去
|
|
72
|
+
if (node.children && node.children.length > 0) {
|
|
73
|
+
// push/pop 回溯 — 避免每层递归 spread 创建新数组
|
|
74
|
+
middleware.push(node.handler);
|
|
75
|
+
processChildren(node.children, middleware, () => {
|
|
76
|
+
middleware.pop();
|
|
77
|
+
void nextNode();
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// 没有children,直接处理handler — 临时拼接,无需 spread
|
|
82
|
+
middleware.push(node.handler);
|
|
83
|
+
const currentsAndMiddleware = middleware;
|
|
84
|
+
// node.handler 是一个异步函数。函数执行的结果是 { current: Current[] | Current, select: xxx }
|
|
85
|
+
try {
|
|
86
|
+
const currents = [];
|
|
87
|
+
for (const item of currentsAndMiddleware) {
|
|
88
|
+
const app = await item();
|
|
89
|
+
// 没有 default。因为是 import x from './';
|
|
90
|
+
if (isFunction(app)) {
|
|
91
|
+
// 纯异步函数
|
|
92
|
+
currents.push(app);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
// 中间件也有 selects。
|
|
96
|
+
// 如果 发现 和当前要处理的 selects 不匹配。
|
|
97
|
+
// 只要是一个不匹配。则说明处理还不是最终想要执行结果。
|
|
98
|
+
const selects = Array.isArray(app.select) ? app.select : [app.select];
|
|
99
|
+
// 没有匹配到
|
|
100
|
+
if (!selects.includes(select)) {
|
|
101
|
+
// 回溯 pop,避免中间件泄漏
|
|
102
|
+
middleware.pop();
|
|
103
|
+
void nextNode();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// 可能是数组。也可能不是数组
|
|
107
|
+
const currentsItem = Array.isArray(app.current) ? app.current : [app.current];
|
|
108
|
+
currents.push(...currentsItem);
|
|
109
|
+
}
|
|
110
|
+
// 回溯 pop 当前 handler
|
|
111
|
+
middleware.pop();
|
|
112
|
+
// 要把二维数组拍平
|
|
113
|
+
callHandler(currents, (cn, ...cns) => {
|
|
114
|
+
if (cn) {
|
|
115
|
+
// 这里的 next 要加 true。
|
|
116
|
+
// 因为下一层是旧版本逻辑。不加一层。会出现处理了没有完全结束周期
|
|
117
|
+
nextCycle(true, ...cns);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
void nextNode();
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
middleware.pop();
|
|
125
|
+
showErrorModule(err);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
void nextNode();
|
|
129
|
+
};
|
|
130
|
+
return processChildren;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export { createRouteProcessChildren };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 消息处理快
|
|
3
|
+
* 登录模块向核心模块发送数据
|
|
4
|
+
* 核心模块调用模块索引
|
|
5
|
+
* @module processor
|
|
6
|
+
* @author ningmengchongshui
|
|
7
|
+
*/
|
|
8
|
+
import { Next, Events, EventKeys } from '../../types';
|
|
9
|
+
/**
|
|
10
|
+
* todo:
|
|
11
|
+
* 当前的局部中间件算法有问题
|
|
12
|
+
* ****
|
|
13
|
+
* 当前仅仅是简单的记录。被关闭的中间件。
|
|
14
|
+
* ****
|
|
15
|
+
* 在一个指令匹配多个 res 的情况下。
|
|
16
|
+
* 会出现多次计算同一个中间件的结果。即 bad case
|
|
17
|
+
* 需要一个缓存机制。
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* 消息体处理机制
|
|
21
|
+
* @param event
|
|
22
|
+
* @param key
|
|
23
|
+
*/
|
|
24
|
+
export declare const expendEvent: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next) => void;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Response, ResponseRouter } from '../../store/store.js';
|
|
2
|
+
import { createCallHandler } from './event-processor-callHandler.js';
|
|
3
|
+
import { createNextStep } from './event-processor-cycleFiles.js';
|
|
4
|
+
import { createRouteProcessChildren } from './event-processor-cycleRoute.js';
|
|
5
|
+
|
|
6
|
+
// 单例,避免每次事件处理都创建新对象
|
|
7
|
+
const responseSingleton = new Response();
|
|
8
|
+
const responseRouterSingleton = new ResponseRouter();
|
|
9
|
+
/**
|
|
10
|
+
* todo:
|
|
11
|
+
* 当前的局部中间件算法有问题
|
|
12
|
+
* ****
|
|
13
|
+
* 当前仅仅是简单的记录。被关闭的中间件。
|
|
14
|
+
* ****
|
|
15
|
+
* 在一个指令匹配多个 res 的情况下。
|
|
16
|
+
* 会出现多次计算同一个中间件的结果。即 bad case
|
|
17
|
+
* 需要一个缓存机制。
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* 消息体处理机制
|
|
21
|
+
* @param event
|
|
22
|
+
* @param key
|
|
23
|
+
*/
|
|
24
|
+
const expendEvent = (valueEvent, select, next) => {
|
|
25
|
+
// 得到所有响应体(文件)
|
|
26
|
+
const StoreResponse = responseSingleton.value;
|
|
27
|
+
// 创建调用函数(文件)
|
|
28
|
+
const callHandler = createCallHandler(valueEvent);
|
|
29
|
+
// 创建next函数(文件)
|
|
30
|
+
const nextEvent = createNextStep(valueEvent, select, next, StoreResponse, callHandler);
|
|
31
|
+
// 得到所有响应体(路由)
|
|
32
|
+
const routes = responseRouterSingleton.value;
|
|
33
|
+
// 创建调用函数(路由)
|
|
34
|
+
const callRouteHandler = createCallHandler(valueEvent);
|
|
35
|
+
// 创建 children 处理函数(路由)
|
|
36
|
+
const processChildren = createRouteProcessChildren(valueEvent, select, nextEvent, callRouteHandler);
|
|
37
|
+
// 开始先处理 路由系统,再到 文件系统
|
|
38
|
+
void processChildren(routes, [], nextEvent);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export { expendEvent };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 消息处理快
|
|
3
|
+
* 登录模块向核心模块发送数据
|
|
4
|
+
* 核心模块调用模块索引
|
|
5
|
+
* @module processor
|
|
6
|
+
* @author ningmengchongshui
|
|
7
|
+
*/
|
|
8
|
+
import { Next, Events, EventKeys } from '../../types';
|
|
9
|
+
/**
|
|
10
|
+
* 处理中间件
|
|
11
|
+
* @param event
|
|
12
|
+
* @param select
|
|
13
|
+
*/
|
|
14
|
+
export declare const expendMiddleware: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next) => void;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Middleware, MiddlewareRouter } from '../../store/store.js';
|
|
2
|
+
import { createCallHandler } from './event-processor-callHandler.js';
|
|
3
|
+
import { createNextStep } from './event-processor-cycleFiles.js';
|
|
4
|
+
import { createRouteProcessChildren } from './event-processor-cycleRoute.js';
|
|
5
|
+
|
|
6
|
+
// 单例,避免每次事件处理都创建新对象
|
|
7
|
+
const middlewareSingleton = new Middleware();
|
|
8
|
+
const middlewareRouterSingleton = new MiddlewareRouter();
|
|
9
|
+
/**
|
|
10
|
+
* 处理中间件
|
|
11
|
+
* @param event
|
|
12
|
+
* @param select
|
|
13
|
+
*/
|
|
14
|
+
const expendMiddleware = (valueEvent, select, next) => {
|
|
15
|
+
// 所有中间件(文件)
|
|
16
|
+
const mwFiles = middlewareSingleton.value;
|
|
17
|
+
// 创建处理函数(文件)
|
|
18
|
+
const callHandler = createCallHandler(valueEvent);
|
|
19
|
+
// 创建 next 处理函数(文件)
|
|
20
|
+
const nextMiddleware = createNextStep(valueEvent, select, next, mwFiles, callHandler);
|
|
21
|
+
// 所有中间件(路由)
|
|
22
|
+
const routes = middlewareRouterSingleton.value;
|
|
23
|
+
// 创建处理函数(路由)
|
|
24
|
+
const callRouteHandler = createCallHandler(valueEvent);
|
|
25
|
+
// 创建 children 处理函数(路由)
|
|
26
|
+
const processChildren = createRouteProcessChildren(valueEvent, select, nextMiddleware, callRouteHandler);
|
|
27
|
+
// 优先route系统。再到files系统
|
|
28
|
+
void processChildren(routes, [], nextMiddleware);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export { expendMiddleware };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 观察者
|
|
3
|
+
* @module processor
|
|
4
|
+
* @author ningmengchongshui
|
|
5
|
+
*/
|
|
6
|
+
import { Next, Events, EventCycleEnum, EventKeys } from '../../types';
|
|
7
|
+
/**
|
|
8
|
+
* 处理订阅
|
|
9
|
+
* @param valueEvent
|
|
10
|
+
* @param select
|
|
11
|
+
* @param next
|
|
12
|
+
* @param choose
|
|
13
|
+
*/
|
|
14
|
+
export declare const expendSubscribe: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next, choose: EventCycleEnum) => void;
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param valueEvent
|
|
18
|
+
* @param select
|
|
19
|
+
* @param next
|
|
20
|
+
*/
|
|
21
|
+
export declare const expendSubscribeCreate: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next) => void;
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @param valueEvent
|
|
25
|
+
* @param select
|
|
26
|
+
* @param next
|
|
27
|
+
*/
|
|
28
|
+
export declare const expendSubscribeMount: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next) => void;
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param valueEvent
|
|
32
|
+
* @param select
|
|
33
|
+
* @param next
|
|
34
|
+
*/
|
|
35
|
+
export declare const expendSubscribeUnmount: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next) => void;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { getSubscribeList } from '../../store/store.js';
|
|
2
|
+
import { SubscribeStatus } from '../config.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 处理订阅
|
|
6
|
+
* @param valueEvent
|
|
7
|
+
* @param select
|
|
8
|
+
* @param next
|
|
9
|
+
* @param choose
|
|
10
|
+
*/
|
|
11
|
+
const expendSubscribe = (valueEvent, select, next, choose) => {
|
|
12
|
+
const subListValue = getSubscribeList(choose, select);
|
|
13
|
+
subListValue.resetCursor();
|
|
14
|
+
/**
|
|
15
|
+
* 观察者下一步
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
const nextObserver = (cn, ...cns) => {
|
|
19
|
+
if (cn) {
|
|
20
|
+
next(...cns);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const item = subListValue.popNext(); // 弹出下一个节点
|
|
24
|
+
// 这里代表没有 下一个节点,应该进入下一个周期
|
|
25
|
+
if (!item) {
|
|
26
|
+
// 下一个节点
|
|
27
|
+
nextObserver(true);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const selects = item.data.selects; // 订阅的 selects
|
|
31
|
+
const ID = item.data.id; // 订阅的 ID
|
|
32
|
+
// 查看是否激活,如果不激活,移除并继续下一个
|
|
33
|
+
if (item.data.status === SubscribeStatus.paused) {
|
|
34
|
+
subListValue.removeCurrent(); // 移除当前节点
|
|
35
|
+
// 下一个节点
|
|
36
|
+
nextObserver();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// 检查 keys
|
|
40
|
+
for (const key in item.data.keys) {
|
|
41
|
+
// 只要发现不符合的,就继续
|
|
42
|
+
if (item.data.keys[key] !== valueEvent[key]) {
|
|
43
|
+
// 下一个节点
|
|
44
|
+
nextObserver();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// 恢复(循环替代递归 — 避免深链表栈溢出风险)
|
|
49
|
+
const onActive = () => {
|
|
50
|
+
for (const select of selects) {
|
|
51
|
+
const subListVal = getSubscribeList(choose, select);
|
|
52
|
+
subListVal.forEach(node => {
|
|
53
|
+
if (node.data.id === ID) {
|
|
54
|
+
node.data.status = SubscribeStatus.active;
|
|
55
|
+
return true; // break
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const onPaused = () => {
|
|
61
|
+
for (const select of selects) {
|
|
62
|
+
const subListVal = getSubscribeList(choose, select);
|
|
63
|
+
subListVal.forEach(node => {
|
|
64
|
+
if (node.data.id === ID) {
|
|
65
|
+
node.data.status = SubscribeStatus.paused;
|
|
66
|
+
return true; // break
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
// 订阅是执行则销毁
|
|
72
|
+
onPaused();
|
|
73
|
+
const Continue = (cn, ...cns) => {
|
|
74
|
+
// 重新注册。
|
|
75
|
+
onActive();
|
|
76
|
+
// true
|
|
77
|
+
if (cn) {
|
|
78
|
+
// 下一个节点 next(true)
|
|
79
|
+
nextObserver(...cns);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
item.data.current(valueEvent, Continue);
|
|
83
|
+
};
|
|
84
|
+
// 先从观察者开始
|
|
85
|
+
nextObserver();
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
*
|
|
89
|
+
* @param valueEvent
|
|
90
|
+
* @param select
|
|
91
|
+
* @param next
|
|
92
|
+
*/
|
|
93
|
+
const expendSubscribeCreate = (valueEvent, select, next) => {
|
|
94
|
+
expendSubscribe(valueEvent, select, next, 'create');
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* @param valueEvent
|
|
99
|
+
* @param select
|
|
100
|
+
* @param next
|
|
101
|
+
*/
|
|
102
|
+
const expendSubscribeMount = (valueEvent, select, next) => {
|
|
103
|
+
expendSubscribe(valueEvent, select, next, 'mount');
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
*
|
|
107
|
+
* @param valueEvent
|
|
108
|
+
* @param select
|
|
109
|
+
* @param next
|
|
110
|
+
*/
|
|
111
|
+
const expendSubscribeUnmount = (valueEvent, select, next) => {
|
|
112
|
+
expendSubscribe(valueEvent, select, next, 'unmount');
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export { expendSubscribe, expendSubscribeCreate, expendSubscribeMount, expendSubscribeUnmount };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EventKeys, Events } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* 消息处理器
|
|
4
|
+
* @param name
|
|
5
|
+
* @param event
|
|
6
|
+
* @param data
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export declare const onProcessor: <T extends EventKeys>(name: T, event: Events[T], data?: any) => void;
|
|
10
|
+
/**
|
|
11
|
+
* 消息处理器
|
|
12
|
+
* @param event
|
|
13
|
+
* @param name
|
|
14
|
+
* @deprecated 该方法已被弃用,请使用 onProcessor() 替代。
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
export declare const OnProcessor: <T extends EventKeys>(event: Events[T], name: T) => void;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { getConfigValue } from '../../core/config.js';
|
|
2
|
+
import { processorRepeatedClearTimeMin, processorRepeatedClearTimeMax, processorRepeatedEventTime, processorRepeatedUserTime, processorRepeatedClearSize, processorMaxMapSize } from '../../core/variable.js';
|
|
3
|
+
import { expendCycle } from './event-processor-cycle.js';
|
|
4
|
+
import { ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap } from '../../store/store.js';
|
|
5
|
+
import { getCachedRegExp, fastHash } from '../../core/utils.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 过滤掉重复消息
|
|
9
|
+
* @param param0
|
|
10
|
+
* @param MessageId
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
const filter = ({ Now, store, INTERVAL }, MessageId) => {
|
|
14
|
+
if (store.has(MessageId)) {
|
|
15
|
+
const time = store.get(MessageId);
|
|
16
|
+
if (Now - time < INTERVAL) {
|
|
17
|
+
// 1s内重复消息
|
|
18
|
+
store.set(MessageId, Date.now());
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// 防止 Map 无限增长导致内存泄漏
|
|
23
|
+
if (store.size >= processorMaxMapSize) {
|
|
24
|
+
cleanupStore({ Now, store, INTERVAL });
|
|
25
|
+
// 清理后仍然超限,删除最早的条目
|
|
26
|
+
if (store.size >= processorMaxMapSize) {
|
|
27
|
+
const firstKey = store.keys().next().value;
|
|
28
|
+
if (firstKey !== undefined) {
|
|
29
|
+
store.delete(firstKey);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
store.set(MessageId, Date.now());
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* 清理旧消息(带预算限制,避免大 Map 阻塞 Event Loop)
|
|
37
|
+
* @returns 是否全部清理完毕
|
|
38
|
+
*/
|
|
39
|
+
const CLEANUP_BUDGET = 1000;
|
|
40
|
+
const cleanupStore = ({ Now, store, INTERVAL }) => {
|
|
41
|
+
let cleaned = 0;
|
|
42
|
+
for (const [ID, timestamp] of store.entries()) {
|
|
43
|
+
if (cleaned >= CLEANUP_BUDGET) {
|
|
44
|
+
return false; // 预算用尽,下次继续
|
|
45
|
+
}
|
|
46
|
+
// 超过时间间隔
|
|
47
|
+
if (Now - timestamp > INTERVAL) {
|
|
48
|
+
store.delete(ID);
|
|
49
|
+
cleaned++;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* 清理所有消息
|
|
56
|
+
*/
|
|
57
|
+
const cleanupStoreAll = () => {
|
|
58
|
+
const Now = Date.now();
|
|
59
|
+
const value = getConfigValue();
|
|
60
|
+
const EVENT_INTERVAL = value?.event?.repeated_event_time ?? value?.processor?.repeated_event_time ?? processorRepeatedEventTime;
|
|
61
|
+
const USER_INTERVAL = value?.event?.repeated_user_time ?? value?.processor?.repeated_user_time ?? processorRepeatedUserTime;
|
|
62
|
+
const a = cleanupStore({ Now, INTERVAL: EVENT_INTERVAL, store: ProcessorEventAutoClearMap });
|
|
63
|
+
const b = cleanupStore({ Now, INTERVAL: USER_INTERVAL, store: ProcessorEventUserAutoClearMap });
|
|
64
|
+
return a && b;
|
|
65
|
+
};
|
|
66
|
+
// 清理消息
|
|
67
|
+
const callback = () => {
|
|
68
|
+
const allDone = cleanupStoreAll();
|
|
69
|
+
// 如果预算用尽未清完,立即调度下一轮
|
|
70
|
+
if (!allDone) {
|
|
71
|
+
setImmediate(callback);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// 下一次清理的时间,应该随着长度的增加而减少
|
|
75
|
+
const length = ProcessorEventAutoClearMap.size + ProcessorEventUserAutoClearMap.size;
|
|
76
|
+
// 长度控制在37个以内
|
|
77
|
+
const time = length > processorRepeatedClearSize ? processorRepeatedClearTimeMin : processorRepeatedClearTimeMax;
|
|
78
|
+
setTimeout(callback, time);
|
|
79
|
+
};
|
|
80
|
+
setTimeout(callback, processorRepeatedClearTimeMin);
|
|
81
|
+
/**
|
|
82
|
+
* 消息处理器
|
|
83
|
+
* @param name
|
|
84
|
+
* @param event
|
|
85
|
+
* @param data
|
|
86
|
+
* @returns
|
|
87
|
+
*/
|
|
88
|
+
const onProcessor = (name, event, data) => {
|
|
89
|
+
// 禁用规则设置
|
|
90
|
+
const value = getConfigValue();
|
|
91
|
+
const disabledTextRegular = value?.event?.disabled?.text_regular ?? value?.disabled_text_regular;
|
|
92
|
+
// 检查文本禁用规则
|
|
93
|
+
if (disabledTextRegular && event['MessageText']) {
|
|
94
|
+
if (getCachedRegExp(disabledTextRegular).test(event['MessageText'])) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const disabledSelects = value?.event?.disabled?.selects ?? value?.disabled_selects ?? {};
|
|
99
|
+
// 检查事件禁用规则
|
|
100
|
+
if (disabledSelects[name]) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const disabledUserId = value?.event?.disabled?.user_id ?? value?.disabled_user_id ?? {};
|
|
104
|
+
// 检查用户禁用规则
|
|
105
|
+
if (event['UserId'] && disabledUserId[event['UserId']]) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const disabledUserKey = value?.event?.disabled?.user_key ?? value?.disabled_user_key ?? {};
|
|
109
|
+
// 检查用户禁用规则
|
|
110
|
+
if (event['UserKey'] && disabledUserKey[event['UserKey']]) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// 文本转换规则(合并 event.transforms + 旧的 redirect + mapping_text)
|
|
114
|
+
if (event['MessageText']) {
|
|
115
|
+
const transforms = value?.event?.transforms;
|
|
116
|
+
if (transforms && transforms.length > 0) {
|
|
117
|
+
// 新格式:event.transforms 数组
|
|
118
|
+
for (const rule of transforms) {
|
|
119
|
+
const { pattern, target } = rule ?? {};
|
|
120
|
+
if (!pattern) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const cachedReg = getCachedRegExp(pattern);
|
|
124
|
+
if (cachedReg.test(event['MessageText'])) {
|
|
125
|
+
event['MessageText'] = event['MessageText'].replace(cachedReg, target);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// 旧格式兼容:redirect_* + mapping_text
|
|
131
|
+
const redirectRegular = value?.redirect_regular ?? value?.redirect_text_regular;
|
|
132
|
+
const redirectTarget = value?.redirect_target ?? value?.redirect_text_target;
|
|
133
|
+
if (redirectRegular && redirectTarget) {
|
|
134
|
+
const cachedReg = getCachedRegExp(redirectRegular);
|
|
135
|
+
if (cachedReg.test(event['MessageText'])) {
|
|
136
|
+
event['MessageText'] = event['MessageText'].replace(cachedReg, redirectTarget);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const mappingText = value?.mapping_text ?? [];
|
|
140
|
+
for (const mapping of mappingText) {
|
|
141
|
+
const { regular, target } = mapping ?? {};
|
|
142
|
+
if (!regular) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const cachedReg = getCachedRegExp(regular);
|
|
146
|
+
if (cachedReg.test(event['MessageText'])) {
|
|
147
|
+
event['MessageText'] = event['MessageText'].replace(cachedReg, target);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const masterId = value?.auth?.master?.id ?? value?.master_id ?? {};
|
|
153
|
+
const masterKey = value?.auth?.master?.key ?? value?.master_key ?? {};
|
|
154
|
+
// 检查是否是 master
|
|
155
|
+
if (event['UserId'] && masterId[event['UserId']]) {
|
|
156
|
+
event['isMaster'] = true;
|
|
157
|
+
}
|
|
158
|
+
else if (event['UserKey'] && masterKey[event['UserKey']]) {
|
|
159
|
+
event['isMaster'] = true;
|
|
160
|
+
}
|
|
161
|
+
const botId = value?.auth?.bot?.id ?? value?.bot_id ?? {};
|
|
162
|
+
const botKey = value?.auth?.bot?.key ?? value?.bot_key ?? {};
|
|
163
|
+
// 检查是否是 bot
|
|
164
|
+
if (event['UserId'] && botId[event['UserId']]) {
|
|
165
|
+
event['isBot'] = true;
|
|
166
|
+
}
|
|
167
|
+
else if (event['UserKey'] && botKey[event['UserKey']]) {
|
|
168
|
+
event['isBot'] = true;
|
|
169
|
+
}
|
|
170
|
+
const Now = Date.now();
|
|
171
|
+
const EVENT_INTERVAL = value?.event?.repeated_event_time ?? value?.processor?.repeated_event_time ?? processorRepeatedEventTime;
|
|
172
|
+
if (event['MessageId']) {
|
|
173
|
+
// FNV-1a 快速哈希 — 比 SHA-256 快 ~30-50x
|
|
174
|
+
const MessageId = fastHash(event['MessageId']);
|
|
175
|
+
// 重复消息
|
|
176
|
+
if (filter({ Now, INTERVAL: EVENT_INTERVAL, store: ProcessorEventAutoClearMap }, MessageId)) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const USER_INTERVAL = value?.event?.repeated_user_time ?? value?.processor?.repeated_user_time ?? processorRepeatedUserTime;
|
|
181
|
+
if (event['UserId']) {
|
|
182
|
+
// FNV-1a 快速哈希
|
|
183
|
+
const UserId = fastHash(event['UserId']);
|
|
184
|
+
// 频繁操作
|
|
185
|
+
if (filter({ Now, INTERVAL: USER_INTERVAL, store: ProcessorEventUserAutoClearMap }, UserId)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (data) {
|
|
190
|
+
// 直接赋值 — 避免 defineProperty 破坏 V8 Hidden Class 优化
|
|
191
|
+
event['value'] = data;
|
|
192
|
+
}
|
|
193
|
+
event['name'] = name;
|
|
194
|
+
expendCycle(event, name, value);
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* 消息处理器
|
|
198
|
+
* @param event
|
|
199
|
+
* @param name
|
|
200
|
+
* @deprecated 该方法已被弃用,请使用 onProcessor() 替代。
|
|
201
|
+
* @returns
|
|
202
|
+
*/
|
|
203
|
+
const OnProcessor = (event, name) => {
|
|
204
|
+
onProcessor(name, event);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
export { OnProcessor, onProcessor };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ResultCode } from '../../core/variable.js';
|
|
2
|
+
import { ChildrenApp } from '../../store/store.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 卸载模块
|
|
6
|
+
* @param name
|
|
7
|
+
* @throws {Error} - 如果 name 无效,抛出错误。
|
|
8
|
+
*/
|
|
9
|
+
const unChildren = (name = 'main') => {
|
|
10
|
+
if (!name || typeof name !== 'string') {
|
|
11
|
+
logger.error({
|
|
12
|
+
code: ResultCode.FailParams,
|
|
13
|
+
message: 'Invalid name: name must be a string',
|
|
14
|
+
data: null
|
|
15
|
+
});
|
|
16
|
+
throw new Error('Invalid name: name must be a string');
|
|
17
|
+
}
|
|
18
|
+
const app = new ChildrenApp(name);
|
|
19
|
+
app.un();
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { unChildren };
|