alemonjs 2.1.16 → 2.1.18
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/README_CONFIG.md +0 -1
- package/lib/app/SinglyLinkedList.d.ts +1 -0
- package/lib/app/SinglyLinkedList.js +12 -6
- package/lib/app/config.d.ts +4 -0
- package/lib/app/config.js +6 -0
- package/lib/app/define-platform.d.ts +1 -0
- package/lib/app/define-platform.js +3 -2
- package/lib/app/event-processor-callHandler.js +5 -15
- package/lib/app/event-processor-cycleFiles.d.ts +1 -0
- package/lib/app/event-processor-cycleFiles.js +19 -2
- package/lib/app/event-processor-cycleRoute.js +1 -2
- package/lib/app/event-processor-event.js +4 -4
- package/lib/app/event-processor-middleware.js +4 -4
- package/lib/app/event-processor-subscribe.d.ts +1 -1
- package/lib/app/event-processor-subscribe.js +36 -22
- package/lib/app/event-processor.js +15 -6
- package/lib/app/hook-use-subscribe.js +10 -5
- package/lib/app/index.js +1 -1
- package/lib/app/load_modules/loadChild.js +5 -5
- package/lib/app/store.d.ts +3 -3
- package/lib/app/store.js +9 -9
- package/lib/cbp/connects/base.d.ts +15 -0
- package/lib/cbp/connects/base.js +77 -0
- package/lib/cbp/connects/client.js +13 -65
- package/lib/cbp/connects/platform.js +11 -63
- package/lib/cbp/processor/handle.d.ts +3 -0
- package/lib/cbp/processor/handle.js +32 -0
- package/lib/cbp/server/main.js +5 -25
- package/lib/client.js +0 -1
- package/lib/core/config.js +17 -8
- package/lib/core/variable.d.ts +2 -1
- package/lib/core/variable.js +3 -2
- package/lib/index.js +1 -1
- package/lib/types/subscribe/index.d.ts +2 -1
- package/package.json +1 -1
package/README_CONFIG.md
CHANGED
|
@@ -8,10 +8,12 @@ class ListNode {
|
|
|
8
8
|
}
|
|
9
9
|
class SinglyLinkedList {
|
|
10
10
|
head;
|
|
11
|
+
tail;
|
|
11
12
|
size;
|
|
12
13
|
current;
|
|
13
14
|
constructor(initialValues) {
|
|
14
15
|
this.head = null;
|
|
16
|
+
this.tail = null;
|
|
15
17
|
this.size = 0;
|
|
16
18
|
this.current = null;
|
|
17
19
|
if (initialValues) {
|
|
@@ -22,13 +24,11 @@ class SinglyLinkedList {
|
|
|
22
24
|
const newNode = new ListNode(data);
|
|
23
25
|
if (!this.head) {
|
|
24
26
|
this.head = newNode;
|
|
27
|
+
this.tail = newNode;
|
|
25
28
|
}
|
|
26
29
|
else {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
current = current.next;
|
|
30
|
-
}
|
|
31
|
-
current.next = newNode;
|
|
30
|
+
this.tail.next = newNode;
|
|
31
|
+
this.tail = newNode;
|
|
32
32
|
}
|
|
33
33
|
this.size++;
|
|
34
34
|
}
|
|
@@ -42,11 +42,14 @@ class SinglyLinkedList {
|
|
|
42
42
|
return this.current;
|
|
43
43
|
}
|
|
44
44
|
removeCurrent() {
|
|
45
|
-
if (!this.head) {
|
|
45
|
+
if (!this.head || !this.current) {
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
if (this.current === this.head) {
|
|
49
49
|
this.head = this.head.next;
|
|
50
|
+
if (!this.head) {
|
|
51
|
+
this.tail = null;
|
|
52
|
+
}
|
|
50
53
|
this.current = null;
|
|
51
54
|
this.size--;
|
|
52
55
|
return;
|
|
@@ -57,6 +60,9 @@ class SinglyLinkedList {
|
|
|
57
60
|
}
|
|
58
61
|
if (previous && this.current) {
|
|
59
62
|
previous.next = this.current.next;
|
|
63
|
+
if (this.current === this.tail) {
|
|
64
|
+
this.tail = previous;
|
|
65
|
+
}
|
|
60
66
|
this.current = null;
|
|
61
67
|
this.size--;
|
|
62
68
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
const definePlatform = (options) => {
|
|
2
|
+
const platformName = options.name || process.env.platform || 'unknown';
|
|
2
3
|
const mainProcess = () => {
|
|
3
4
|
['SIGINT', 'SIGTERM', 'SIGQUIT', 'disconnect'].forEach(sig => {
|
|
4
5
|
process?.on?.(sig, () => {
|
|
5
|
-
logger.info?.(`[
|
|
6
|
+
logger.info?.(`[${platformName}][${sig}] 收到信号,正在关闭...`);
|
|
6
7
|
setImmediate(() => process.exit(0));
|
|
7
8
|
});
|
|
8
9
|
});
|
|
9
10
|
process?.on?.('exit', code => {
|
|
10
|
-
logger.info?.(`[
|
|
11
|
+
logger.info?.(`[${platformName}][exit] 进程退出,code=${code}`);
|
|
11
12
|
});
|
|
12
13
|
process.on('message', msg => {
|
|
13
14
|
try {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { isAsyncFunction } from 'util/types';
|
|
2
1
|
import 'fs';
|
|
3
2
|
import 'path';
|
|
4
3
|
import 'yaml';
|
|
@@ -42,20 +41,11 @@ const createCallHandler = valueEvent => {
|
|
|
42
41
|
return;
|
|
43
42
|
}
|
|
44
43
|
try {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
onRes(res);
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
const res = currents[index](valueEvent, (...cns) => {
|
|
54
|
-
isNext = true;
|
|
55
|
-
nextEvent(...cns);
|
|
56
|
-
});
|
|
57
|
-
onRes(res);
|
|
58
|
-
}
|
|
44
|
+
const res = await currents[index](valueEvent, (...cns) => {
|
|
45
|
+
isNext = true;
|
|
46
|
+
nextEvent(...cns);
|
|
47
|
+
});
|
|
48
|
+
onRes(res);
|
|
59
49
|
}
|
|
60
50
|
catch (err) {
|
|
61
51
|
showErrorModule(err);
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { Next, Events, EventKeys, StoreResponseItem } from '../types';
|
|
2
|
+
export declare const clearModuleCache: (path?: string) => void;
|
|
2
3
|
export declare const createNextStep: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next, files: StoreResponseItem[], callHandler: (currents: any, nextEvent: any) => void) => Next;
|
|
@@ -3,9 +3,26 @@ import { showErrorModule } from '../core/utils.js';
|
|
|
3
3
|
import { EventMessageText } from '../core/variable.js';
|
|
4
4
|
import { ResponseMiddleware } from './store.js';
|
|
5
5
|
|
|
6
|
+
const moduleCache = new Map();
|
|
7
|
+
const clearModuleCache = (path) => {
|
|
8
|
+
if (path) {
|
|
9
|
+
moduleCache.delete(path);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
moduleCache.clear();
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const loadModule = async (filePath) => {
|
|
16
|
+
if (moduleCache.has(filePath)) {
|
|
17
|
+
return moduleCache.get(filePath);
|
|
18
|
+
}
|
|
19
|
+
const mod = await import(`file://${filePath}`);
|
|
20
|
+
moduleCache.set(filePath, mod);
|
|
21
|
+
return mod;
|
|
22
|
+
};
|
|
6
23
|
const callHandlerFile = async (valueEvent, select, file, nextStep, callback) => {
|
|
7
24
|
try {
|
|
8
|
-
const app = await
|
|
25
|
+
const app = await loadModule(file.path);
|
|
9
26
|
if (!app?.default?.current || !app?.default?.select) {
|
|
10
27
|
nextStep();
|
|
11
28
|
return;
|
|
@@ -88,4 +105,4 @@ const createNextStep = (valueEvent, select, next, files, callHandler) => {
|
|
|
88
105
|
return nextStep;
|
|
89
106
|
};
|
|
90
107
|
|
|
91
|
-
export { createNextStep };
|
|
108
|
+
export { clearModuleCache, createNextStep };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { isAsyncFunction } from 'util/types';
|
|
2
1
|
import { EventMessageText } from '../core/variable.js';
|
|
3
2
|
import 'fs';
|
|
4
3
|
import 'path';
|
|
@@ -45,7 +44,7 @@ const createRouteProcessChildren = (valueEvent, select, nextCycle, callHandler)
|
|
|
45
44
|
try {
|
|
46
45
|
const currents = [];
|
|
47
46
|
for (const item of currentsAndMiddleware) {
|
|
48
|
-
const app =
|
|
47
|
+
const app = await item();
|
|
49
48
|
const selects = Array.isArray(app.select) ? app.select : [app.select];
|
|
50
49
|
if (!selects.includes(select)) {
|
|
51
50
|
void nextNode();
|
|
@@ -3,13 +3,13 @@ import { createCallHandler } from './event-processor-callHandler.js';
|
|
|
3
3
|
import { createNextStep } from './event-processor-cycleFiles.js';
|
|
4
4
|
import { createRouteProcessChildren } from './event-processor-cycleRoute.js';
|
|
5
5
|
|
|
6
|
+
const responseSingleton = new Response();
|
|
7
|
+
const responseRouterSingleton = new ResponseRouter();
|
|
6
8
|
const expendEvent = (valueEvent, select, next) => {
|
|
7
|
-
const
|
|
8
|
-
const StoreResponse = res.value;
|
|
9
|
+
const StoreResponse = responseSingleton.value;
|
|
9
10
|
const callHandler = createCallHandler(valueEvent);
|
|
10
11
|
const nextEvent = createNextStep(valueEvent, select, next, StoreResponse, callHandler);
|
|
11
|
-
const
|
|
12
|
-
const routes = resRoute.value;
|
|
12
|
+
const routes = responseRouterSingleton.value;
|
|
13
13
|
const callRouteHandler = createCallHandler(valueEvent);
|
|
14
14
|
const processChildren = createRouteProcessChildren(valueEvent, select, nextEvent, callRouteHandler);
|
|
15
15
|
void processChildren(routes, [], nextEvent);
|
|
@@ -3,13 +3,13 @@ import { createCallHandler } from './event-processor-callHandler.js';
|
|
|
3
3
|
import { createNextStep } from './event-processor-cycleFiles.js';
|
|
4
4
|
import { createRouteProcessChildren } from './event-processor-cycleRoute.js';
|
|
5
5
|
|
|
6
|
+
const middlewareSingleton = new Middleware();
|
|
7
|
+
const middlewareRouterSingleton = new MiddlewareRouter();
|
|
6
8
|
const expendMiddleware = (valueEvent, select, next) => {
|
|
7
|
-
const
|
|
8
|
-
const mwFiles = mw.value;
|
|
9
|
+
const mwFiles = middlewareSingleton.value;
|
|
9
10
|
const callHandler = createCallHandler(valueEvent);
|
|
10
11
|
const nextMiddleware = createNextStep(valueEvent, select, next, mwFiles, callHandler);
|
|
11
|
-
const
|
|
12
|
-
const routes = resRoute.value;
|
|
12
|
+
const routes = middlewareRouterSingleton.value;
|
|
13
13
|
const callRouteHandler = createCallHandler(valueEvent);
|
|
14
14
|
const processChildren = createRouteProcessChildren(valueEvent, select, nextMiddleware, callRouteHandler);
|
|
15
15
|
void processChildren(routes, [], nextMiddleware);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Next, Events, EventCycleEnum, EventKeys } from '../types';
|
|
2
|
-
export declare const expendSubscribe: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next,
|
|
2
|
+
export declare const expendSubscribe: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next, choose: EventCycleEnum) => void;
|
|
3
3
|
export declare const expendSubscribeCreate: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next) => void;
|
|
4
4
|
export declare const expendSubscribeMount: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next) => void;
|
|
5
5
|
export declare const expendSubscribeUnmount: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next) => void;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { SubscribeList } from './store.js';
|
|
2
|
+
import { SubscribeStatus } from './config.js';
|
|
2
3
|
|
|
3
|
-
const expendSubscribe = (valueEvent, select, next,
|
|
4
|
-
const subList = new SubscribeList(
|
|
4
|
+
const expendSubscribe = (valueEvent, select, next, choose) => {
|
|
5
|
+
const subList = new SubscribeList(choose, select);
|
|
5
6
|
const nextObserver = (cn, ...cns) => {
|
|
6
7
|
if (cn) {
|
|
7
8
|
next(...cns);
|
|
@@ -12,45 +13,58 @@ const expendSubscribe = (valueEvent, select, next, chioce) => {
|
|
|
12
13
|
nextObserver(true);
|
|
13
14
|
return;
|
|
14
15
|
}
|
|
16
|
+
const selects = item.data.selects;
|
|
17
|
+
const ID = item.data.id;
|
|
18
|
+
if (item.data.status === SubscribeStatus.paused) {
|
|
19
|
+
subList.value.removeCurrent();
|
|
20
|
+
nextObserver();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
15
23
|
for (const key in item.data.keys) {
|
|
16
24
|
if (item.data.keys[key] !== valueEvent[key]) {
|
|
17
25
|
nextObserver();
|
|
18
26
|
return;
|
|
19
27
|
}
|
|
20
28
|
}
|
|
21
|
-
const
|
|
22
|
-
const selects = item.data.selects;
|
|
23
|
-
const ID = item.data.id;
|
|
29
|
+
const onActive = () => {
|
|
24
30
|
for (const select of selects) {
|
|
25
|
-
const subList = new SubscribeList(
|
|
26
|
-
const
|
|
31
|
+
const subList = new SubscribeList(choose, select);
|
|
32
|
+
const find = () => {
|
|
27
33
|
const item = subList.value.popNext();
|
|
28
|
-
if (!item
|
|
29
|
-
|
|
34
|
+
if (!item) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (item.data.id !== ID) {
|
|
38
|
+
find();
|
|
30
39
|
return;
|
|
31
40
|
}
|
|
32
|
-
|
|
41
|
+
item.data.status = SubscribeStatus.active;
|
|
33
42
|
};
|
|
34
|
-
|
|
43
|
+
find();
|
|
35
44
|
}
|
|
36
45
|
};
|
|
37
|
-
const
|
|
38
|
-
const selects = item.data.selects;
|
|
46
|
+
const onPaused = () => {
|
|
39
47
|
for (const select of selects) {
|
|
40
|
-
const subList = new SubscribeList(
|
|
41
|
-
|
|
48
|
+
const subList = new SubscribeList(choose, select);
|
|
49
|
+
const find = () => {
|
|
50
|
+
const item = subList.value.popNext();
|
|
51
|
+
if (!item) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (item.data.id !== ID) {
|
|
55
|
+
find();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
item.data.status = SubscribeStatus.paused;
|
|
59
|
+
};
|
|
60
|
+
find();
|
|
42
61
|
}
|
|
43
62
|
};
|
|
44
|
-
|
|
63
|
+
onPaused();
|
|
45
64
|
const Continue = (cn, ...cns) => {
|
|
46
|
-
|
|
65
|
+
onActive();
|
|
47
66
|
if (cn) {
|
|
48
67
|
nextObserver(...cns);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
if (typeof cn === 'boolean') {
|
|
52
|
-
clear();
|
|
53
|
-
nextObserver(...cns);
|
|
54
68
|
}
|
|
55
69
|
};
|
|
56
70
|
item.data.current(valueEvent, Continue);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getConfigValue } from '../core/config.js';
|
|
2
|
-
import { processorRepeatedClearTimeMin, processorRepeatedClearTimeMax, processorRepeatedEventTime, processorRepeatedUserTime,
|
|
2
|
+
import { processorRepeatedClearTimeMin, processorRepeatedClearTimeMax, processorRepeatedEventTime, processorRepeatedUserTime, processorRepeatedClearSize, processorMaxMapSize } from '../core/variable.js';
|
|
3
3
|
import { expendCycle } from './event-processor-cycle.js';
|
|
4
|
-
import { ProcessorEventAutoClearMap,
|
|
4
|
+
import { ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap } from './store.js';
|
|
5
5
|
import { createHash } from '../core/utils.js';
|
|
6
6
|
|
|
7
7
|
const filter = ({ Now, store, INTERVAL }, MessageId) => {
|
|
@@ -12,6 +12,15 @@ const filter = ({ Now, store, INTERVAL }, MessageId) => {
|
|
|
12
12
|
return true;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
if (store.size >= processorMaxMapSize) {
|
|
16
|
+
cleanupStore({ Now, store, INTERVAL });
|
|
17
|
+
if (store.size >= processorMaxMapSize) {
|
|
18
|
+
const firstKey = store.keys().next().value;
|
|
19
|
+
if (firstKey !== undefined) {
|
|
20
|
+
store.delete(firstKey);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
15
24
|
store.set(MessageId, Date.now());
|
|
16
25
|
};
|
|
17
26
|
const cleanupStore = ({ Now, store, INTERVAL }) => {
|
|
@@ -27,12 +36,12 @@ const cleanupStoreAll = () => {
|
|
|
27
36
|
const EVENT_INTERVAL = value?.processor?.repeated_event_time ?? processorRepeatedEventTime;
|
|
28
37
|
const USER_INTERVAL = value?.processor?.repeated_user_time ?? processorRepeatedUserTime;
|
|
29
38
|
cleanupStore({ Now, INTERVAL: EVENT_INTERVAL, store: ProcessorEventAutoClearMap });
|
|
30
|
-
cleanupStore({ Now, INTERVAL: USER_INTERVAL, store:
|
|
39
|
+
cleanupStore({ Now, INTERVAL: USER_INTERVAL, store: ProcessorEventUserAutoClearMap });
|
|
31
40
|
};
|
|
32
41
|
const callback = () => {
|
|
33
42
|
cleanupStoreAll();
|
|
34
|
-
const length = ProcessorEventAutoClearMap.size +
|
|
35
|
-
const time = length >
|
|
43
|
+
const length = ProcessorEventAutoClearMap.size + ProcessorEventUserAutoClearMap.size;
|
|
44
|
+
const time = length > processorRepeatedClearSize ? processorRepeatedClearTimeMin : processorRepeatedClearTimeMax;
|
|
36
45
|
setTimeout(callback, time);
|
|
37
46
|
};
|
|
38
47
|
setTimeout(callback, processorRepeatedClearTimeMin);
|
|
@@ -103,7 +112,7 @@ const onProcessor = (name, event, data) => {
|
|
|
103
112
|
const USER_INTERVAL = value?.processor?.repeated_user_time ?? processorRepeatedUserTime;
|
|
104
113
|
if (event['UserId']) {
|
|
105
114
|
const UserId = createHash(event['UserId']);
|
|
106
|
-
if (filter({ Now, INTERVAL: USER_INTERVAL, store:
|
|
115
|
+
if (filter({ Now, INTERVAL: USER_INTERVAL, store: ProcessorEventUserAutoClearMap }, UserId)) {
|
|
107
116
|
return;
|
|
108
117
|
}
|
|
109
118
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ResultCode } from '../core/variable.js';
|
|
2
2
|
import { SubscribeList } from './store.js';
|
|
3
|
+
import { SubscribeStatus } from './config.js';
|
|
3
4
|
|
|
4
5
|
const useSubscribe = (event, selects) => {
|
|
5
6
|
if (typeof event !== 'object') {
|
|
@@ -44,6 +45,7 @@ const useSubscribe = (event, selects) => {
|
|
|
44
45
|
selects: curSelects,
|
|
45
46
|
keys: values,
|
|
46
47
|
current: callback,
|
|
48
|
+
status: SubscribeStatus.active,
|
|
47
49
|
id: ID
|
|
48
50
|
});
|
|
49
51
|
}
|
|
@@ -67,15 +69,18 @@ const useSubscribe = (event, selects) => {
|
|
|
67
69
|
const ID = value.id;
|
|
68
70
|
for (const select of selects) {
|
|
69
71
|
const subList = new SubscribeList(value.choose, select);
|
|
70
|
-
const
|
|
72
|
+
const find = () => {
|
|
71
73
|
const item = subList.value.popNext();
|
|
72
|
-
if (!item
|
|
73
|
-
remove();
|
|
74
|
+
if (!item) {
|
|
74
75
|
return;
|
|
75
76
|
}
|
|
76
|
-
|
|
77
|
+
if (item.data.id !== ID) {
|
|
78
|
+
find();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
item.data.status = SubscribeStatus.paused;
|
|
77
82
|
};
|
|
78
|
-
|
|
83
|
+
find();
|
|
79
84
|
}
|
|
80
85
|
};
|
|
81
86
|
const subscribe = {
|
package/lib/app/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, ProcessorEventAutoClearMap,
|
|
1
|
+
export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap, Response, ResponseMiddleware, ResponseRouter, State, StateSubscribe, SubscribeList, core, logger } from './store.js';
|
|
2
2
|
export { loadModels, run } from './load_modules/load.js';
|
|
3
3
|
export { loadChildren, loadChildrenFile } from './load_modules/loadChild.js';
|
|
4
4
|
export { defineChildren } from './define-children.js';
|
|
@@ -40,7 +40,7 @@ const loadChildren = async (mainPath, appName) => {
|
|
|
40
40
|
else {
|
|
41
41
|
app = await moduleApp.default.callback();
|
|
42
42
|
}
|
|
43
|
-
App.
|
|
43
|
+
App.pushCycle(app);
|
|
44
44
|
const unMounted = async (e) => {
|
|
45
45
|
showErrorModule(e);
|
|
46
46
|
App.un();
|
|
@@ -87,7 +87,7 @@ const loadChildren = async (mainPath, appName) => {
|
|
|
87
87
|
for (const file of files) {
|
|
88
88
|
const url = file.path.replace(mainDir, '');
|
|
89
89
|
const stateKey = createEventName(url, appName);
|
|
90
|
-
const
|
|
90
|
+
const responseItem = {
|
|
91
91
|
input: mainDir,
|
|
92
92
|
dir: dirname(file.path),
|
|
93
93
|
path: file.path,
|
|
@@ -95,7 +95,7 @@ const loadChildren = async (mainPath, appName) => {
|
|
|
95
95
|
stateKey,
|
|
96
96
|
appName: appName
|
|
97
97
|
};
|
|
98
|
-
resData.push(
|
|
98
|
+
resData.push(responseItem);
|
|
99
99
|
}
|
|
100
100
|
App.pushResponse(resData);
|
|
101
101
|
const responseAndMiddlewareFiles = getRecursiveDirFiles(responseDir, item => fileSuffixMiddleware.test(item.name));
|
|
@@ -103,7 +103,7 @@ const loadChildren = async (mainPath, appName) => {
|
|
|
103
103
|
for (const file of responseAndMiddlewareFiles) {
|
|
104
104
|
const url = file.path.replace(mainDir, '');
|
|
105
105
|
const stateKey = createEventName(url, appName);
|
|
106
|
-
const
|
|
106
|
+
const responseItem = {
|
|
107
107
|
input: mainDir,
|
|
108
108
|
dir: dirname(file.path),
|
|
109
109
|
path: file.path,
|
|
@@ -111,7 +111,7 @@ const loadChildren = async (mainPath, appName) => {
|
|
|
111
111
|
stateKey,
|
|
112
112
|
appName: appName
|
|
113
113
|
};
|
|
114
|
-
resAndMwData[stateKey] =
|
|
114
|
+
resAndMwData[stateKey] = responseItem;
|
|
115
115
|
}
|
|
116
116
|
App.pushResponseMiddleware(resAndMwData);
|
|
117
117
|
const mwDir = join(mainDir, 'middleware');
|
package/lib/app/store.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export declare class Middleware {
|
|
|
33
33
|
}
|
|
34
34
|
export declare class SubscribeList<T extends EventKeys> {
|
|
35
35
|
#private;
|
|
36
|
-
constructor(
|
|
36
|
+
constructor(choice: EventCycleEnum, select: T);
|
|
37
37
|
get value(): SinglyLinkedList<SubscribeValue>;
|
|
38
38
|
}
|
|
39
39
|
export declare class StateSubscribe {
|
|
@@ -58,13 +58,13 @@ export declare class ChildrenApp {
|
|
|
58
58
|
[key: string]: StoreResponseItem;
|
|
59
59
|
}): void;
|
|
60
60
|
pushMiddleware(data: StoreMiddlewareItem[]): void;
|
|
61
|
-
|
|
61
|
+
pushCycle(data: ChildrenCycle): void;
|
|
62
62
|
on(): void;
|
|
63
63
|
un(): void;
|
|
64
64
|
get value(): import("..").StoreChildrenApp;
|
|
65
65
|
}
|
|
66
66
|
export declare const ProcessorEventAutoClearMap: Map<any, any>;
|
|
67
|
-
export declare const
|
|
67
|
+
export declare const ProcessorEventUserAutoClearMap: Map<any, any>;
|
|
68
68
|
export declare const logger: any;
|
|
69
69
|
export declare const core: {
|
|
70
70
|
storeState: import("..").ResponseState;
|
package/lib/app/store.js
CHANGED
|
@@ -178,16 +178,16 @@ class Middleware {
|
|
|
178
178
|
}
|
|
179
179
|
class SubscribeList {
|
|
180
180
|
#select;
|
|
181
|
-
#
|
|
182
|
-
constructor(
|
|
181
|
+
#choice;
|
|
182
|
+
constructor(choice, select) {
|
|
183
183
|
this.#select = select;
|
|
184
|
-
this.#
|
|
185
|
-
if (!alemonjsCore.storeSubscribeList[this.#
|
|
186
|
-
alemonjsCore.storeSubscribeList[this.#
|
|
184
|
+
this.#choice = choice;
|
|
185
|
+
if (!alemonjsCore.storeSubscribeList[this.#choice].has(this.#select)) {
|
|
186
|
+
alemonjsCore.storeSubscribeList[this.#choice].set(this.#select, new SinglyLinkedList());
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
get value() {
|
|
190
|
-
return alemonjsCore.storeSubscribeList[this.#
|
|
190
|
+
return alemonjsCore.storeSubscribeList[this.#choice].get(this.#select);
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
class StateSubscribe {
|
|
@@ -269,7 +269,7 @@ class ChildrenApp {
|
|
|
269
269
|
pushMiddleware(data) {
|
|
270
270
|
this.#middleware = this.#middleware.concat(data);
|
|
271
271
|
}
|
|
272
|
-
|
|
272
|
+
pushCycle(data) {
|
|
273
273
|
this.#cycle = data;
|
|
274
274
|
}
|
|
275
275
|
on() {
|
|
@@ -293,7 +293,7 @@ class ChildrenApp {
|
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
const ProcessorEventAutoClearMap = new Map();
|
|
296
|
-
const
|
|
296
|
+
const ProcessorEventUserAutoClearMap = new Map();
|
|
297
297
|
const logger = new Logger().value;
|
|
298
298
|
const core = new Core().value;
|
|
299
299
|
['SIGINT', 'SIGTERM', 'SIGQUIT', 'disconnect'].forEach(sig => {
|
|
@@ -305,4 +305,4 @@ process?.on?.('exit', code => {
|
|
|
305
305
|
logger.info?.(`[alemonjs][exit] 进程退出,code=${code}`);
|
|
306
306
|
});
|
|
307
307
|
|
|
308
|
-
export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, ProcessorEventAutoClearMap,
|
|
308
|
+
export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap, Response, ResponseMiddleware, ResponseRouter, State, StateSubscribe, SubscribeList, core, logger };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type WSConnectorOptions = {
|
|
2
|
+
url: string;
|
|
3
|
+
role: 'client' | 'platform';
|
|
4
|
+
onOpen?: () => void;
|
|
5
|
+
onMessage: (message: string) => void;
|
|
6
|
+
extraHeaders?: Record<string, string>;
|
|
7
|
+
globalKey: 'chatbotClient' | 'chatbotPlatform';
|
|
8
|
+
};
|
|
9
|
+
export declare const createWSConnector: (options: WSConnectorOptions) => {
|
|
10
|
+
heartbeatControl: {
|
|
11
|
+
start: () => void;
|
|
12
|
+
stop: () => void;
|
|
13
|
+
pong: () => void;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { WebSocket } from 'ws';
|
|
2
|
+
import { ResultCode } from '../../core/variable.js';
|
|
3
|
+
import 'fs';
|
|
4
|
+
import 'path';
|
|
5
|
+
import 'yaml';
|
|
6
|
+
import '../../core/utils.js';
|
|
7
|
+
import { deviceId, DEVICE_ID_HEADER, USER_AGENT_HEADER, reconnectInterval } from '../processor/config.js';
|
|
8
|
+
import { useHeartbeat } from './connect.js';
|
|
9
|
+
|
|
10
|
+
const createWSConnector = (options) => {
|
|
11
|
+
const { url, role, onOpen, onMessage, extraHeaders = {}, globalKey } = options;
|
|
12
|
+
if (global[globalKey]) {
|
|
13
|
+
delete global[globalKey];
|
|
14
|
+
}
|
|
15
|
+
const [heartbeatControl] = useHeartbeat({
|
|
16
|
+
ping: () => {
|
|
17
|
+
global?.[globalKey]?.ping?.();
|
|
18
|
+
},
|
|
19
|
+
isConnected: () => {
|
|
20
|
+
return global?.[globalKey] && global?.[globalKey]?.readyState === WebSocket.OPEN;
|
|
21
|
+
},
|
|
22
|
+
terminate: () => {
|
|
23
|
+
try {
|
|
24
|
+
global?.[globalKey]?.terminate?.();
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
logger.debug({
|
|
28
|
+
code: ResultCode.Fail,
|
|
29
|
+
message: '强制断开连接失败',
|
|
30
|
+
data: error
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const start = () => {
|
|
36
|
+
global[globalKey] = new WebSocket(url, {
|
|
37
|
+
headers: {
|
|
38
|
+
[USER_AGENT_HEADER]: role,
|
|
39
|
+
[DEVICE_ID_HEADER]: deviceId,
|
|
40
|
+
...extraHeaders
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
global[globalKey].on('open', () => {
|
|
44
|
+
onOpen?.();
|
|
45
|
+
heartbeatControl.start();
|
|
46
|
+
});
|
|
47
|
+
global[globalKey].on('pong', () => {
|
|
48
|
+
heartbeatControl.pong();
|
|
49
|
+
});
|
|
50
|
+
global[globalKey].on('message', (message) => {
|
|
51
|
+
onMessage(message.toString());
|
|
52
|
+
});
|
|
53
|
+
global[globalKey].on('close', (code) => {
|
|
54
|
+
heartbeatControl.stop();
|
|
55
|
+
logger.warn({
|
|
56
|
+
code: ResultCode.Fail,
|
|
57
|
+
message: `${role} 连接关闭,尝试重新连接...`,
|
|
58
|
+
data: code
|
|
59
|
+
});
|
|
60
|
+
delete global[globalKey];
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
start();
|
|
63
|
+
}, reconnectInterval);
|
|
64
|
+
});
|
|
65
|
+
global[globalKey].on('error', (err) => {
|
|
66
|
+
logger.error({
|
|
67
|
+
code: ResultCode.Fail,
|
|
68
|
+
message: `${role} 端错误`,
|
|
69
|
+
data: err
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
start();
|
|
74
|
+
return { heartbeatControl };
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export { createWSConnector };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { WebSocket } from 'ws';
|
|
2
1
|
import * as flattedJSON from 'flatted';
|
|
3
2
|
import '../../app/store.js';
|
|
4
3
|
import 'fs';
|
|
@@ -13,57 +12,26 @@ import '../../app/event-group.js';
|
|
|
13
12
|
import '../../app/event-middleware.js';
|
|
14
13
|
import { onProcessor } from '../../app/event-processor.js';
|
|
15
14
|
import '../../app/event-response.js';
|
|
16
|
-
import 'util/types';
|
|
17
15
|
import { createResult } from '../../core/utils.js';
|
|
18
16
|
import '../../app/hook-use-api.js';
|
|
19
17
|
import '../../app/message-api.js';
|
|
20
18
|
import '../../app/message-format.js';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
19
|
+
import { apiResolves, apiTimeouts, actionResolves, actionTimeouts, FULL_RECEIVE_HEADER } from '../processor/config.js';
|
|
20
|
+
import { createWSConnector } from './base.js';
|
|
23
21
|
|
|
24
22
|
const cbpClient = (url, options = {}) => {
|
|
25
|
-
if (global.chatbotClient) {
|
|
26
|
-
delete global.chatbotClient;
|
|
27
|
-
}
|
|
28
23
|
const { open = () => { }, isFullReceive = true } = options;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
createWSConnector({
|
|
25
|
+
url,
|
|
26
|
+
role: 'client',
|
|
27
|
+
globalKey: 'chatbotClient',
|
|
28
|
+
extraHeaders: {
|
|
29
|
+
[FULL_RECEIVE_HEADER]: isFullReceive ? '1' : '0'
|
|
32
30
|
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
terminate: () => {
|
|
31
|
+
onOpen: open,
|
|
32
|
+
onMessage: (messageStr) => {
|
|
37
33
|
try {
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
logger.debug({
|
|
42
|
-
code: ResultCode.Fail,
|
|
43
|
-
message: '强制断开连接失败',
|
|
44
|
-
data: error
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
const start = () => {
|
|
50
|
-
global.chatbotClient = new WebSocket(url, {
|
|
51
|
-
headers: {
|
|
52
|
-
[USER_AGENT_HEADER]: 'client',
|
|
53
|
-
[DEVICE_ID_HEADER]: deviceId,
|
|
54
|
-
[FULL_RECEIVE_HEADER]: isFullReceive ? '1' : '0'
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
global.chatbotClient.on('open', () => {
|
|
58
|
-
open();
|
|
59
|
-
heartbeatControl.start();
|
|
60
|
-
});
|
|
61
|
-
global.chatbotClient.on('pong', () => {
|
|
62
|
-
heartbeatControl.pong();
|
|
63
|
-
});
|
|
64
|
-
global.chatbotClient.on('message', message => {
|
|
65
|
-
try {
|
|
66
|
-
const parsedMessage = flattedJSON.parse(message.toString());
|
|
34
|
+
const parsedMessage = flattedJSON.parse(messageStr);
|
|
67
35
|
if (parsedMessage?.activeId) {
|
|
68
36
|
if (parsedMessage.active === 'sync') {
|
|
69
37
|
const configs = parsedMessage.payload;
|
|
@@ -118,28 +86,8 @@ const cbpClient = (url, options = {}) => {
|
|
|
118
86
|
data: error
|
|
119
87
|
});
|
|
120
88
|
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
heartbeatControl.stop();
|
|
124
|
-
logger.warn({
|
|
125
|
-
code: ResultCode.Fail,
|
|
126
|
-
message: '连接关闭,尝试重新连接...',
|
|
127
|
-
data: null
|
|
128
|
-
});
|
|
129
|
-
delete global.chatbotClient;
|
|
130
|
-
setTimeout(() => {
|
|
131
|
-
start();
|
|
132
|
-
}, reconnectInterval);
|
|
133
|
-
});
|
|
134
|
-
global.chatbotClient.on('error', err => {
|
|
135
|
-
logger.error({
|
|
136
|
-
code: ResultCode.Fail,
|
|
137
|
-
message: '客户端错误',
|
|
138
|
-
data: err
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
};
|
|
142
|
-
start();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
143
91
|
};
|
|
144
92
|
|
|
145
93
|
export { cbpClient };
|
|
@@ -1,40 +1,17 @@
|
|
|
1
1
|
import * as flattedJSON from 'flatted';
|
|
2
2
|
import { WebSocket } from 'ws';
|
|
3
|
-
import { deviceId
|
|
3
|
+
import { deviceId } from '../processor/config.js';
|
|
4
4
|
import { ResultCode } from '../../core/variable.js';
|
|
5
5
|
import 'fs';
|
|
6
6
|
import 'path';
|
|
7
7
|
import 'yaml';
|
|
8
8
|
import '../../core/utils.js';
|
|
9
|
-
import {
|
|
9
|
+
import { createWSConnector } from './base.js';
|
|
10
10
|
|
|
11
11
|
const cbpPlatform = (url, options = {
|
|
12
12
|
open: () => { }
|
|
13
13
|
}) => {
|
|
14
|
-
if (global.chatbotPlatform) {
|
|
15
|
-
delete global.chatbotPlatform;
|
|
16
|
-
}
|
|
17
14
|
const { open = () => { } } = options;
|
|
18
|
-
const [heartbeatControl] = useHeartbeat({
|
|
19
|
-
ping: () => {
|
|
20
|
-
global?.chatbotPlatform?.ping?.();
|
|
21
|
-
},
|
|
22
|
-
isConnected: () => {
|
|
23
|
-
return global?.chatbotPlatform && global?.chatbotPlatform?.readyState === WebSocket.OPEN;
|
|
24
|
-
},
|
|
25
|
-
terminate: () => {
|
|
26
|
-
try {
|
|
27
|
-
global?.chatbotPlatform?.terminate?.();
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
logger.debug({
|
|
31
|
-
code: ResultCode.Fail,
|
|
32
|
-
message: '强制断开连接失败',
|
|
33
|
-
data: error
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
15
|
const send = (data) => {
|
|
39
16
|
if (global.chatbotPlatform && global.chatbotPlatform.readyState === WebSocket.OPEN) {
|
|
40
17
|
data.DeviceId = deviceId;
|
|
@@ -69,23 +46,14 @@ const cbpPlatform = (url, options = {
|
|
|
69
46
|
const onapis = (reply) => {
|
|
70
47
|
apiReplys.push(reply);
|
|
71
48
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
79
|
-
global.chatbotPlatform.on('open', () => {
|
|
80
|
-
open();
|
|
81
|
-
heartbeatControl.start();
|
|
82
|
-
});
|
|
83
|
-
global.chatbotPlatform.on('pong', () => {
|
|
84
|
-
heartbeatControl.pong();
|
|
85
|
-
});
|
|
86
|
-
global.chatbotPlatform.on('message', message => {
|
|
49
|
+
createWSConnector({
|
|
50
|
+
url,
|
|
51
|
+
role: 'platform',
|
|
52
|
+
globalKey: 'chatbotPlatform',
|
|
53
|
+
onOpen: open,
|
|
54
|
+
onMessage: (messageStr) => {
|
|
87
55
|
try {
|
|
88
|
-
const data = flattedJSON.parse(
|
|
56
|
+
const data = flattedJSON.parse(messageStr);
|
|
89
57
|
if (data.apiId) {
|
|
90
58
|
for (const cb of apiReplys) {
|
|
91
59
|
void cb(data, val => replyApi(data, val));
|
|
@@ -104,28 +72,8 @@ const cbpPlatform = (url, options = {
|
|
|
104
72
|
data: error
|
|
105
73
|
});
|
|
106
74
|
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
heartbeatControl.stop();
|
|
110
|
-
logger.warn({
|
|
111
|
-
code: ResultCode.Fail,
|
|
112
|
-
message: '平台端连接关闭,尝试重新连接...',
|
|
113
|
-
data: err
|
|
114
|
-
});
|
|
115
|
-
delete global.chatbotPlatform;
|
|
116
|
-
setTimeout(() => {
|
|
117
|
-
start();
|
|
118
|
-
}, reconnectInterval);
|
|
119
|
-
});
|
|
120
|
-
global.chatbotPlatform.on('error', err => {
|
|
121
|
-
logger.error({
|
|
122
|
-
code: ResultCode.Fail,
|
|
123
|
-
message: '平台端错误',
|
|
124
|
-
data: err
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
start();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
129
77
|
const client = {
|
|
130
78
|
send,
|
|
131
79
|
onactions,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ResultCode } from '../../core/variable.js';
|
|
2
|
+
import 'fs';
|
|
3
|
+
import 'path';
|
|
4
|
+
import 'yaml';
|
|
5
|
+
import { createResult } from '../../core/utils.js';
|
|
6
|
+
import { generateUniqueId, deviceId, apiResolves, apiTimeouts, timeoutTime } from './config.js';
|
|
7
|
+
import * as flattedJSON from 'flatted';
|
|
8
|
+
|
|
9
|
+
const sendAPI = (data) => {
|
|
10
|
+
const ApiId = generateUniqueId();
|
|
11
|
+
return new Promise(resolve => {
|
|
12
|
+
if (!global.chatbotClient?.send) {
|
|
13
|
+
resolve([createResult(ResultCode.Fail, 'Chatbot client is not available', null)]);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
data.apiId = ApiId;
|
|
17
|
+
data.DeviceId = deviceId;
|
|
18
|
+
global.chatbotClient?.send(flattedJSON.stringify(data));
|
|
19
|
+
apiResolves.set(ApiId, resolve);
|
|
20
|
+
const timeout = setTimeout(() => {
|
|
21
|
+
if (!apiResolves.has(ApiId) || !apiTimeouts.has(ApiId)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
apiResolves.delete(ApiId);
|
|
25
|
+
apiTimeouts.delete(ApiId);
|
|
26
|
+
resolve([createResult(ResultCode.Fail, '接口超时', null)]);
|
|
27
|
+
}, timeoutTime);
|
|
28
|
+
apiTimeouts.set(ApiId, timeout);
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { sendAPI };
|
package/lib/cbp/server/main.js
CHANGED
|
@@ -11,27 +11,7 @@ import '../../core/utils.js';
|
|
|
11
11
|
import { USER_AGENT_HEADER, USER_AGENT_HEADER_VALUE_MAP, DEVICE_ID_HEADER, FULL_RECEIVE_HEADER, platformClient, childrenClient, fullClient, childrenBind } from '../processor/config.js';
|
|
12
12
|
import { createTestOneController } from './testone.js';
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
if (childrenClient.has(DeviceId)) {
|
|
16
|
-
const clientWs = childrenClient.get(DeviceId);
|
|
17
|
-
if (clientWs && clientWs.readyState === WebSocket.OPEN) {
|
|
18
|
-
clientWs.send(message);
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
childrenClient.delete(DeviceId);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
else if (fullClient.has(DeviceId)) {
|
|
25
|
-
const clientWs = fullClient.get(DeviceId);
|
|
26
|
-
if (clientWs && clientWs.readyState === WebSocket.OPEN) {
|
|
27
|
-
clientWs.send(message);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
fullClient.delete(DeviceId);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
const handleAction = (DeviceId, message) => {
|
|
14
|
+
const routeMessageToDevice = (DeviceId, message) => {
|
|
35
15
|
if (childrenClient.has(DeviceId)) {
|
|
36
16
|
const clientWs = childrenClient.get(DeviceId);
|
|
37
17
|
if (clientWs && clientWs.readyState === WebSocket.OPEN) {
|
|
@@ -209,11 +189,11 @@ const setPlatformClient = (originId, ws) => {
|
|
|
209
189
|
});
|
|
210
190
|
if (parsedMessage.apiId) {
|
|
211
191
|
const DeviceId = parsedMessage.DeviceId;
|
|
212
|
-
|
|
192
|
+
routeMessageToDevice(DeviceId, message);
|
|
213
193
|
}
|
|
214
194
|
else if (parsedMessage?.actionId) {
|
|
215
195
|
const DeviceId = parsedMessage.DeviceId;
|
|
216
|
-
|
|
196
|
+
routeMessageToDevice(DeviceId, message);
|
|
217
197
|
}
|
|
218
198
|
else if (parsedMessage?.name) {
|
|
219
199
|
const ID = parsedMessage.ChannelId || parsedMessage.GuildId || parsedMessage.DeviceId;
|
|
@@ -260,11 +240,11 @@ const setTestOnePlatformClient = (ws) => {
|
|
|
260
240
|
});
|
|
261
241
|
if (parsedMessage.apiId) {
|
|
262
242
|
const DeviceId = parsedMessage.DeviceId;
|
|
263
|
-
|
|
243
|
+
routeMessageToDevice(DeviceId, message);
|
|
264
244
|
}
|
|
265
245
|
else if (parsedMessage?.actionId) {
|
|
266
246
|
const DeviceId = parsedMessage.DeviceId;
|
|
267
|
-
|
|
247
|
+
routeMessageToDevice(DeviceId, message);
|
|
268
248
|
}
|
|
269
249
|
else if (parsedMessage?.name) {
|
|
270
250
|
const ID = parsedMessage.ChannelId || parsedMessage.GuildId || parsedMessage.DeviceId;
|
package/lib/client.js
CHANGED
|
@@ -23,7 +23,6 @@ import './app/event-group.js';
|
|
|
23
23
|
import './app/event-middleware.js';
|
|
24
24
|
import './app/event-processor.js';
|
|
25
25
|
import './app/event-response.js';
|
|
26
|
-
import 'util/types';
|
|
27
26
|
import './app/hook-use-api.js';
|
|
28
27
|
import './app/message-api.js';
|
|
29
28
|
import './app/message-format.js';
|
package/lib/core/config.js
CHANGED
|
@@ -6,6 +6,8 @@ import { ResultCode } from './variable.js';
|
|
|
6
6
|
class ConfigCore {
|
|
7
7
|
#dir = null;
|
|
8
8
|
#value = null;
|
|
9
|
+
#mergedValue = null;
|
|
10
|
+
#watcher = null;
|
|
9
11
|
#initValue = {
|
|
10
12
|
gui: {
|
|
11
13
|
port: 17127
|
|
@@ -14,6 +16,9 @@ class ConfigCore {
|
|
|
14
16
|
constructor(dir) {
|
|
15
17
|
this.#dir = dir;
|
|
16
18
|
}
|
|
19
|
+
#invalidateMergedCache() {
|
|
20
|
+
this.#mergedValue = null;
|
|
21
|
+
}
|
|
17
22
|
#update() {
|
|
18
23
|
if (!this.#dir) {
|
|
19
24
|
return this.#value;
|
|
@@ -27,6 +32,7 @@ class ConfigCore {
|
|
|
27
32
|
const data = readFileSync(dir, 'utf-8');
|
|
28
33
|
const d = YAML.parse(data);
|
|
29
34
|
this.#value = d;
|
|
35
|
+
this.#invalidateMergedCache();
|
|
30
36
|
}
|
|
31
37
|
catch (err) {
|
|
32
38
|
logger.error({
|
|
@@ -34,13 +40,17 @@ class ConfigCore {
|
|
|
34
40
|
message: 'Config file parse error',
|
|
35
41
|
data: err
|
|
36
42
|
});
|
|
37
|
-
process.cwd();
|
|
38
43
|
}
|
|
39
|
-
|
|
44
|
+
if (this.#watcher) {
|
|
45
|
+
this.#watcher.close();
|
|
46
|
+
this.#watcher = null;
|
|
47
|
+
}
|
|
48
|
+
this.#watcher = watch(dir, () => {
|
|
40
49
|
try {
|
|
41
50
|
const data = readFileSync(dir, 'utf-8');
|
|
42
51
|
const d = YAML.parse(data);
|
|
43
52
|
this.#value = d;
|
|
53
|
+
this.#invalidateMergedCache();
|
|
44
54
|
}
|
|
45
55
|
catch (err) {
|
|
46
56
|
logger.error({
|
|
@@ -48,7 +58,6 @@ class ConfigCore {
|
|
|
48
58
|
message: 'Config file parse error',
|
|
49
59
|
data: err
|
|
50
60
|
});
|
|
51
|
-
process.cwd();
|
|
52
61
|
}
|
|
53
62
|
});
|
|
54
63
|
return this.#value;
|
|
@@ -56,15 +65,15 @@ class ConfigCore {
|
|
|
56
65
|
get value() {
|
|
57
66
|
if (!this.#value) {
|
|
58
67
|
this.#update();
|
|
59
|
-
return {
|
|
60
|
-
...(this.#value || {}),
|
|
61
|
-
...(global?.__options || {})
|
|
62
|
-
};
|
|
63
68
|
}
|
|
64
|
-
|
|
69
|
+
if (this.#mergedValue) {
|
|
70
|
+
return this.#mergedValue;
|
|
71
|
+
}
|
|
72
|
+
this.#mergedValue = {
|
|
65
73
|
...(this.#value || {}),
|
|
66
74
|
...(global?.__options || {})
|
|
67
75
|
};
|
|
76
|
+
return this.#mergedValue;
|
|
68
77
|
}
|
|
69
78
|
saveValue(value) {
|
|
70
79
|
if (!this.#dir) {
|
package/lib/core/variable.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ export declare const processorRepeatedEventTime: number;
|
|
|
3
3
|
export declare const processorRepeatedUserTime: number;
|
|
4
4
|
export declare const processorRepeatedClearTimeMin: number;
|
|
5
5
|
export declare const processorRepeatedClearTimeMax: number;
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const processorRepeatedClearSize = 37;
|
|
7
|
+
export declare const processorMaxMapSize = 10000;
|
|
7
8
|
export declare const fileSuffixMiddleware: RegExp;
|
|
8
9
|
export declare const fileSuffixResponse: RegExp;
|
|
9
10
|
export declare const filePrefixCommon: RegExp;
|
package/lib/core/variable.js
CHANGED
|
@@ -2,7 +2,8 @@ const processorRepeatedEventTime = 1000 * 60;
|
|
|
2
2
|
const processorRepeatedUserTime = 1000 * 1;
|
|
3
3
|
const processorRepeatedClearTimeMin = 1000 * 3;
|
|
4
4
|
const processorRepeatedClearTimeMax = 1000 * 10;
|
|
5
|
-
const
|
|
5
|
+
const processorRepeatedClearSize = 37;
|
|
6
|
+
const processorMaxMapSize = 10000;
|
|
6
7
|
const fileSuffixMiddleware = /^mw(\.|\..*\.)(js|ts|jsx|tsx)$/;
|
|
7
8
|
const fileSuffixResponse = /^res(\.|\..*\.)(js|ts|jsx|tsx)$/;
|
|
8
9
|
const filePrefixCommon = /^(@alemonjs\/|alemonjs-)/;
|
|
@@ -26,4 +27,4 @@ const ResultCode = {
|
|
|
26
27
|
FailInternal
|
|
27
28
|
};
|
|
28
29
|
|
|
29
|
-
export { EventMessageText, Fail, FailAuth, FailInternal, FailParams, Ok, ResultCode, Warn, defaultLogin, defaultPlatformCommonPrefix, defaultPlatformPrefix, defaultPort, filePrefixCommon, fileSuffixMiddleware, fileSuffixResponse,
|
|
30
|
+
export { EventMessageText, Fail, FailAuth, FailInternal, FailParams, Ok, ResultCode, Warn, defaultLogin, defaultPlatformCommonPrefix, defaultPlatformPrefix, defaultPort, filePrefixCommon, fileSuffixMiddleware, fileSuffixResponse, processorMaxMapSize, processorRepeatedClearSize, processorRepeatedClearTimeMax, processorRepeatedClearTimeMin, processorRepeatedEventTime, processorRepeatedUserTime };
|
package/lib/index.js
CHANGED
|
@@ -5,7 +5,7 @@ export { createEventName, createHash, createResult, getInputExportPath, getRecur
|
|
|
5
5
|
export { cbpClient } from './cbp/connects/client.js';
|
|
6
6
|
export { cbpPlatform } from './cbp/connects/platform.js';
|
|
7
7
|
export { cbpServer } from './cbp/server/main.js';
|
|
8
|
-
export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, ProcessorEventAutoClearMap,
|
|
8
|
+
export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap, Response, ResponseMiddleware, ResponseRouter, State, StateSubscribe, SubscribeList, core, logger } from './app/store.js';
|
|
9
9
|
export { loadModels, run } from './app/load_modules/load.js';
|
|
10
10
|
export { loadChildren, loadChildrenFile } from './app/load_modules/loadChild.js';
|
|
11
11
|
export { defineChildren } from './app/define-children.js';
|
|
@@ -7,7 +7,8 @@ export type SubscribeValue = {
|
|
|
7
7
|
keys: {
|
|
8
8
|
[key: string]: string | number | boolean;
|
|
9
9
|
};
|
|
10
|
-
|
|
10
|
+
status?: 'active' | 'paused';
|
|
11
|
+
current: (...arg: any[]) => any;
|
|
11
12
|
id: string;
|
|
12
13
|
};
|
|
13
14
|
export type SubscribeMap = Map<string, SinglyLinkedList<SubscribeValue>>;
|