wenay-common2 1.0.33 → 1.0.36
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/Common/rcp/createRpcServerAutoWithProtocolDetection.d.ts +2 -1
- package/lib/Common/rcp/createRpcServerAutoWithProtocolDetection.js +92 -57
- package/lib/Common/rcp/rpc-client.js +6 -1
- package/lib/Common/rcp/rpc-clientHub.js +8 -2
- package/lib/Common/rcp/rpc-server.js +2 -2
- package/lib/Common/rcp/rpc-walk.d.ts +2 -0
- package/lib/Common/rcp/rpc-walk.js +51 -3
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@ export declare function createRpcServerAuto2<T extends object>({ socket, object:
|
|
|
15
15
|
onProtocolDetect?: (protocol: 'v2' | 'legacy') => void;
|
|
16
16
|
}): {
|
|
17
17
|
getProtocol: () => ClientProtocol;
|
|
18
|
-
|
|
18
|
+
getLegacySchema: () => any;
|
|
19
|
+
getResolved: () => any;
|
|
19
20
|
};
|
|
20
21
|
export {};
|
|
@@ -6,7 +6,9 @@ const listen_socket_1 = require("./listen-socket");
|
|
|
6
6
|
const rpc_server_1 = require("./rpc-server");
|
|
7
7
|
const rpc_protocol_1 = require("./rpc-protocol");
|
|
8
8
|
const old_ommonsServerMini_1 = require("./old\u0421ommonsServerMini");
|
|
9
|
-
|
|
9
|
+
const rpc_dynamic_1 = require("./rpc-dynamic");
|
|
10
|
+
const rpc_limits_1 = require("./rpc-limits");
|
|
11
|
+
function createRpcServerAuto({ socket, object: target, socketKey: key, debug, hooks, disconnectListen, limits }) {
|
|
10
12
|
const cache = new WeakMap();
|
|
11
13
|
function getListenSocket(parent, disconnectListen) {
|
|
12
14
|
let result = cache.get(parent);
|
|
@@ -44,14 +46,21 @@ function createRpcServerAuto2({ socket, object: target, socketKey: key, debug =
|
|
|
44
46
|
return getListenSocket(obj);
|
|
45
47
|
}
|
|
46
48
|
function transformTree(obj) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
let current = obj;
|
|
50
|
+
if (!(0, rpc_dynamic_1.isNoStrict)(current)) {
|
|
51
|
+
current = resolveTransform(current);
|
|
52
|
+
}
|
|
53
|
+
if (current == null || typeof current !== 'object' || (0, rpc_dynamic_1.isNoStrict)(current))
|
|
54
|
+
return current;
|
|
52
55
|
const out = {};
|
|
53
|
-
for (const k of Object.keys(
|
|
54
|
-
|
|
56
|
+
for (const k of Object.keys(current)) {
|
|
57
|
+
if (!(0, rpc_limits_1.isSafeKey)(k))
|
|
58
|
+
continue;
|
|
59
|
+
const v = current[k];
|
|
60
|
+
if ((0, rpc_dynamic_1.isNoStrict)(v)) {
|
|
61
|
+
out[k] = v;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
55
64
|
out[k] = typeof v === 'function' ? v : (v != null && typeof v === 'object') ? transformTree(v) : v;
|
|
56
65
|
}
|
|
57
66
|
return out;
|
|
@@ -59,35 +68,49 @@ function createRpcServerAuto2({ socket, object: target, socketKey: key, debug =
|
|
|
59
68
|
function serialize(obj) {
|
|
60
69
|
const out = {};
|
|
61
70
|
for (const k of Object.keys(obj)) {
|
|
71
|
+
if (!(0, rpc_limits_1.isSafeKey)(k))
|
|
72
|
+
continue;
|
|
62
73
|
const v = obj[k];
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
switch (true) {
|
|
75
|
+
case v == null:
|
|
76
|
+
out[k] = 'null';
|
|
77
|
+
break;
|
|
78
|
+
case (0, rpc_dynamic_1.isNoStrict)(v):
|
|
79
|
+
out[k] = 'dynamic';
|
|
80
|
+
break;
|
|
81
|
+
case typeof v === 'function':
|
|
82
|
+
out[k] = 'func';
|
|
83
|
+
break;
|
|
84
|
+
case typeof v === 'object':
|
|
85
|
+
out[k] = serialize(v);
|
|
86
|
+
break;
|
|
87
|
+
default:
|
|
88
|
+
out[k] = 'unknown';
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
71
91
|
}
|
|
72
92
|
return out;
|
|
73
93
|
}
|
|
74
94
|
const resolved = transformTree(target);
|
|
75
|
-
const
|
|
95
|
+
const legacySchema = serialize(resolved);
|
|
76
96
|
let protocol = null;
|
|
77
97
|
let v2Handler = null;
|
|
78
98
|
let legacyHandler = null;
|
|
99
|
+
function isLegacyStrictRequest(msg) {
|
|
100
|
+
return msg === '___STRICTLY';
|
|
101
|
+
}
|
|
79
102
|
function isLegacyMessage(msg) {
|
|
80
103
|
return (typeof msg === 'object' &&
|
|
81
104
|
msg !== null &&
|
|
82
105
|
!Array.isArray(msg) &&
|
|
83
|
-
typeof msg.mapId === 'number'
|
|
84
|
-
(msg.data !== undefined || msg.error !== undefined));
|
|
85
|
-
}
|
|
86
|
-
function isLegacyStrictRequest(msg) {
|
|
87
|
-
return msg === '___STRICTLY';
|
|
106
|
+
typeof msg.mapId === 'number');
|
|
88
107
|
}
|
|
89
108
|
function isV2Message(msg) {
|
|
90
|
-
|
|
109
|
+
if (msg === rpc_protocol_1.Pkt.STRICT)
|
|
110
|
+
return true;
|
|
111
|
+
if (Array.isArray(msg) && (msg[0] === rpc_protocol_1.Pkt.CALL || msg[0] === rpc_protocol_1.Pkt.PIPE))
|
|
112
|
+
return true;
|
|
113
|
+
return false;
|
|
91
114
|
}
|
|
92
115
|
function initLegacy() {
|
|
93
116
|
if (legacyHandler)
|
|
@@ -97,7 +120,11 @@ function createRpcServerAuto2({ socket, object: target, socketKey: key, debug =
|
|
|
97
120
|
sendMessage: (msg) => socket.emit(key, msg),
|
|
98
121
|
api: ({ onMessage }) => { onMessageCb = onMessage; },
|
|
99
122
|
}, resolved);
|
|
100
|
-
legacyHandler = (msg) =>
|
|
123
|
+
legacyHandler = (msg) => {
|
|
124
|
+
if (!onMessageCb)
|
|
125
|
+
return;
|
|
126
|
+
onMessageCb(msg);
|
|
127
|
+
};
|
|
101
128
|
}
|
|
102
129
|
function initV2() {
|
|
103
130
|
if (v2Handler)
|
|
@@ -108,64 +135,72 @@ function createRpcServerAuto2({ socket, object: target, socketKey: key, debug =
|
|
|
108
135
|
on: (e, cb) => { if (e === key)
|
|
109
136
|
onMsgCb = cb; },
|
|
110
137
|
};
|
|
111
|
-
if (debug) {
|
|
112
|
-
const origOn = innerSocket.on.bind(innerSocket);
|
|
113
|
-
innerSocket.on = (e, cb) => origOn(e, (d) => { console.log('[RPC IN]', typeof d === 'object' ? JSON.stringify(d) : d); cb(d); });
|
|
114
|
-
}
|
|
115
138
|
(0, rpc_server_1.createRpcServer)({
|
|
116
139
|
socket: innerSocket,
|
|
117
140
|
object: target,
|
|
118
141
|
socketKey: key,
|
|
119
|
-
debug
|
|
142
|
+
debug,
|
|
120
143
|
limits,
|
|
121
144
|
hooks: {
|
|
122
145
|
...hooks,
|
|
123
146
|
resolveTransform,
|
|
124
147
|
},
|
|
125
148
|
});
|
|
126
|
-
v2Handler = (msg) =>
|
|
149
|
+
v2Handler = (msg) => {
|
|
150
|
+
if (!onMsgCb)
|
|
151
|
+
return;
|
|
152
|
+
onMsgCb(msg);
|
|
153
|
+
};
|
|
127
154
|
}
|
|
128
155
|
socket.on(key, (msg) => {
|
|
129
156
|
if (debug) {
|
|
130
|
-
console.log('[RPC-AUTO2]', typeof msg === 'object' ? JSON.stringify(msg) : msg);
|
|
157
|
+
console.log('[RPC-AUTO2 IN]', typeof msg === 'object' ? JSON.stringify(msg) : msg);
|
|
131
158
|
}
|
|
132
|
-
if (protocol ===
|
|
159
|
+
if (protocol === 'legacy') {
|
|
133
160
|
if (isLegacyStrictRequest(msg)) {
|
|
134
|
-
|
|
135
|
-
onProtocolDetect?.('legacy');
|
|
136
|
-
socket.emit(key, { STRICTLY: strictSchema });
|
|
137
|
-
initLegacy();
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
if (isLegacyMessage(msg)) {
|
|
141
|
-
protocol = 'legacy';
|
|
142
|
-
onProtocolDetect?.('legacy');
|
|
143
|
-
initLegacy();
|
|
144
|
-
legacyHandler(msg);
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
if (isV2Message(msg)) {
|
|
148
|
-
protocol = 'v2';
|
|
149
|
-
onProtocolDetect?.('v2');
|
|
150
|
-
initV2();
|
|
151
|
-
v2Handler(msg);
|
|
161
|
+
socket.emit(key, { STRICTLY: legacySchema });
|
|
152
162
|
return;
|
|
153
163
|
}
|
|
164
|
+
legacyHandler(msg);
|
|
154
165
|
return;
|
|
155
166
|
}
|
|
156
|
-
if (protocol === '
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
167
|
+
if (protocol === 'v2') {
|
|
168
|
+
v2Handler(msg);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (isLegacyStrictRequest(msg)) {
|
|
172
|
+
protocol = 'legacy';
|
|
173
|
+
if (debug)
|
|
174
|
+
console.log('[RPC-AUTO2] Protocol detected: legacy (___STRICTLY)');
|
|
175
|
+
onProtocolDetect?.('legacy');
|
|
176
|
+
initLegacy();
|
|
177
|
+
socket.emit(key, { STRICTLY: legacySchema });
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (isLegacyMessage(msg)) {
|
|
181
|
+
protocol = 'legacy';
|
|
182
|
+
if (debug)
|
|
183
|
+
console.log('[RPC-AUTO2] Protocol detected: legacy (mapId message)');
|
|
184
|
+
onProtocolDetect?.('legacy');
|
|
185
|
+
initLegacy();
|
|
161
186
|
legacyHandler(msg);
|
|
187
|
+
return;
|
|
162
188
|
}
|
|
163
|
-
|
|
189
|
+
if (isV2Message(msg)) {
|
|
190
|
+
protocol = 'v2';
|
|
191
|
+
if (debug)
|
|
192
|
+
console.log('[RPC-AUTO2] Protocol detected: v2');
|
|
193
|
+
onProtocolDetect?.('v2');
|
|
194
|
+
initV2();
|
|
164
195
|
v2Handler(msg);
|
|
196
|
+
return;
|
|
165
197
|
}
|
|
198
|
+
if (debug)
|
|
199
|
+
console.warn('[RPC-AUTO2] Unknown message format, ignoring:', msg);
|
|
166
200
|
});
|
|
167
201
|
return {
|
|
168
202
|
getProtocol: () => protocol,
|
|
169
|
-
|
|
203
|
+
getLegacySchema: () => legacySchema,
|
|
204
|
+
getResolved: () => resolved,
|
|
170
205
|
};
|
|
171
206
|
}
|
|
@@ -14,6 +14,11 @@ function createClient(socket, key, opts) {
|
|
|
14
14
|
let strictData = {};
|
|
15
15
|
let strictWaiters = [];
|
|
16
16
|
let debug = false;
|
|
17
|
+
const unpackResult = (v) => {
|
|
18
|
+
if (!v)
|
|
19
|
+
return v;
|
|
20
|
+
return v;
|
|
21
|
+
};
|
|
17
22
|
socket.on(key, (msg) => {
|
|
18
23
|
if (!Array.isArray(msg))
|
|
19
24
|
return;
|
|
@@ -28,7 +33,7 @@ function createClient(socket, key, opts) {
|
|
|
28
33
|
callbacks.delete(cbId);
|
|
29
34
|
pool.release(cbId);
|
|
30
35
|
}
|
|
31
|
-
msg[3] ? req.fail(msg[3]) : req.ok(msg[2]);
|
|
36
|
+
msg[3] ? req.fail(msg[3]) : req.ok(unpackResult(msg[2]));
|
|
32
37
|
break;
|
|
33
38
|
}
|
|
34
39
|
case rpc_protocol_1.Pkt.CB: {
|
|
@@ -23,12 +23,18 @@ function createRpcClientHub(createSocket, schemaBuilder) {
|
|
|
23
23
|
const targetSocketKey = schema[key].socketKey || key;
|
|
24
24
|
const client = (0, rpc_client_1.createRpcClient)({ socketKey: targetSocketKey, socket });
|
|
25
25
|
facade[key] = client;
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
}
|
|
27
|
+
function hi() {
|
|
28
|
+
for (const key in schema) {
|
|
29
|
+
const client = facade[key];
|
|
30
|
+
if (client && typeof client.initStrict === "function") {
|
|
31
|
+
client.initStrict();
|
|
32
|
+
}
|
|
28
33
|
}
|
|
29
34
|
}
|
|
30
35
|
socket?.on("connect", () => {
|
|
31
36
|
connectCount++;
|
|
37
|
+
hi();
|
|
32
38
|
onConnectCb?.(connectCount);
|
|
33
39
|
if (resolveFunc) {
|
|
34
40
|
const a = resolveFunc;
|
|
@@ -186,13 +186,13 @@ function createServer(socket, key, target, hooks, limits) {
|
|
|
186
186
|
current = await current;
|
|
187
187
|
}
|
|
188
188
|
if (wait)
|
|
189
|
-
send([rpc_protocol_1.Pkt.RESP, reqId, current]);
|
|
189
|
+
send([rpc_protocol_1.Pkt.RESP, reqId, (0, rpc_walk_1.packResult)(current)]);
|
|
190
190
|
}
|
|
191
191
|
else {
|
|
192
192
|
const args = (0, rpc_walk_1.unpack)(rawArgsOrSteps, (cbId, cbArgs) => send([rpc_protocol_1.Pkt.CB, cbId, cbArgs]), (cbId) => send([rpc_protocol_1.Pkt.CB_END, cbId]), lim);
|
|
193
193
|
const res = await fn.apply(ctx, args);
|
|
194
194
|
if (wait)
|
|
195
|
-
send([rpc_protocol_1.Pkt.RESP, reqId, res]);
|
|
195
|
+
send([rpc_protocol_1.Pkt.RESP, reqId, (0, rpc_walk_1.packResult)(res)]);
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
catch (e) {
|
|
@@ -2,7 +2,9 @@ import { idPool } from "../id-pool";
|
|
|
2
2
|
import { type RpcLimits } from "./rpc-limits";
|
|
3
3
|
export declare function walk(val: any, onLeaf: (v: any) => any, lim?: Required<RpcLimits>, depth?: number): any;
|
|
4
4
|
export declare function pack(args: any[], pool: idPool, cbStore: Map<number, Function>, cbIds: number[]): any[];
|
|
5
|
+
export declare function packResult(value: any): any;
|
|
5
6
|
export declare function rpcEndCallback(fn: Function): void;
|
|
6
7
|
export declare function unpack(args: any[], sender: (id: number, a: any[]) => void, onEnd: (id: number) => void, lim?: Required<RpcLimits>): any[];
|
|
8
|
+
export declare function unpackResult(value: any, lim?: Required<RpcLimits>): any;
|
|
7
9
|
export declare const errToObj: (e: any) => any;
|
|
8
10
|
export declare const resolveCA: (path: string[], args: any[]) => [string[], any[]];
|
|
@@ -3,10 +3,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.resolveCA = exports.errToObj = void 0;
|
|
4
4
|
exports.walk = walk;
|
|
5
5
|
exports.pack = pack;
|
|
6
|
+
exports.packResult = packResult;
|
|
6
7
|
exports.rpcEndCallback = rpcEndCallback;
|
|
7
8
|
exports.unpack = unpack;
|
|
9
|
+
exports.unpackResult = unpackResult;
|
|
8
10
|
const rpc_limits_1 = require("./rpc-limits");
|
|
9
11
|
const FN_MARKER = "$_f";
|
|
12
|
+
const DATE_MARKER = "$_d";
|
|
13
|
+
const MAP_MARKER = "$_m";
|
|
14
|
+
const SET_MARKER = "$_s";
|
|
15
|
+
const REGEXP_MARKER = "$_r";
|
|
16
|
+
const BIGINT_MARKER = "$_b";
|
|
17
|
+
const ALL_MARKERS = new Set([FN_MARKER, DATE_MARKER, MAP_MARKER, SET_MARKER, REGEXP_MARKER, BIGINT_MARKER]);
|
|
18
|
+
const DESERIALIZERS = {
|
|
19
|
+
[DATE_MARKER]: (v) => new Date(v),
|
|
20
|
+
[MAP_MARKER]: (v) => new Map(v),
|
|
21
|
+
[SET_MARKER]: (v) => new Set(v),
|
|
22
|
+
[REGEXP_MARKER]: (v) => new RegExp(v.source, v.flags),
|
|
23
|
+
[BIGINT_MARKER]: (v) => BigInt(v),
|
|
24
|
+
};
|
|
25
|
+
const SERIALIZERS = [
|
|
26
|
+
(v) => v instanceof Date ? [DATE_MARKER, v.valueOf()] : null,
|
|
27
|
+
(v) => v instanceof Map ? [MAP_MARKER, Array.from(v.entries())] : null,
|
|
28
|
+
(v) => v instanceof Set ? [SET_MARKER, Array.from(v.values())] : null,
|
|
29
|
+
(v) => v instanceof RegExp ? [REGEXP_MARKER, { source: v.source, flags: v.flags }] : null,
|
|
30
|
+
(v) => typeof v === "bigint" ? [BIGINT_MARKER, v.toString()] : null,
|
|
31
|
+
];
|
|
10
32
|
function walk(val, onLeaf, lim, depth = 0) {
|
|
11
33
|
if (lim) {
|
|
12
34
|
if (depth > lim.maxDepth)
|
|
@@ -16,7 +38,7 @@ function walk(val, onLeaf, lim, depth = 0) {
|
|
|
16
38
|
}
|
|
17
39
|
if (val == null || typeof val !== "object")
|
|
18
40
|
return onLeaf(val);
|
|
19
|
-
if (val[
|
|
41
|
+
if (ALL_MARKERS.has(Object.keys(val)[0]))
|
|
20
42
|
return onLeaf(val);
|
|
21
43
|
if (Array.isArray(val)) {
|
|
22
44
|
if (lim && val.length > lim.maxArrayLen)
|
|
@@ -32,6 +54,26 @@ function walk(val, onLeaf, lim, depth = 0) {
|
|
|
32
54
|
o[k] = walk(val[k], onLeaf, lim, depth + 1);
|
|
33
55
|
return o;
|
|
34
56
|
}
|
|
57
|
+
function deserializeLeaf(leaf, onCallback) {
|
|
58
|
+
if (leaf == null || typeof leaf !== "object")
|
|
59
|
+
return leaf;
|
|
60
|
+
const key = Object.keys(leaf)[0];
|
|
61
|
+
if (!key)
|
|
62
|
+
return leaf;
|
|
63
|
+
if (key === FN_MARKER) {
|
|
64
|
+
return onCallback?.(leaf[FN_MARKER]) ?? leaf;
|
|
65
|
+
}
|
|
66
|
+
const deserialize = DESERIALIZERS[key];
|
|
67
|
+
return deserialize ? deserialize(leaf[key]) : leaf;
|
|
68
|
+
}
|
|
69
|
+
function serializeLeaf(leaf) {
|
|
70
|
+
for (const serializer of SERIALIZERS) {
|
|
71
|
+
const result = serializer(leaf);
|
|
72
|
+
if (result)
|
|
73
|
+
return { [result[0]]: result[1] };
|
|
74
|
+
}
|
|
75
|
+
return leaf;
|
|
76
|
+
}
|
|
35
77
|
function pack(args, pool, cbStore, cbIds) {
|
|
36
78
|
return args.map(v => walk(v, leaf => {
|
|
37
79
|
if (typeof leaf == "function") {
|
|
@@ -40,9 +82,12 @@ function pack(args, pool, cbStore, cbIds) {
|
|
|
40
82
|
cbIds.push(id);
|
|
41
83
|
return { [FN_MARKER]: id };
|
|
42
84
|
}
|
|
43
|
-
return leaf;
|
|
85
|
+
return serializeLeaf(leaf);
|
|
44
86
|
}));
|
|
45
87
|
}
|
|
88
|
+
function packResult(value) {
|
|
89
|
+
return walk(value, leaf => serializeLeaf(leaf));
|
|
90
|
+
}
|
|
46
91
|
const _stopRegistry = new WeakMap();
|
|
47
92
|
function rpcEndCallback(fn) {
|
|
48
93
|
_stopRegistry.get(fn)?.();
|
|
@@ -66,9 +111,12 @@ function unpack(args, sender, onEnd, lim) {
|
|
|
66
111
|
_stopRegistry.set(wrapper, () => onEnd(id));
|
|
67
112
|
return wrapper;
|
|
68
113
|
}
|
|
69
|
-
return leaf;
|
|
114
|
+
return deserializeLeaf(leaf);
|
|
70
115
|
}, lim));
|
|
71
116
|
}
|
|
117
|
+
function unpackResult(value, lim) {
|
|
118
|
+
return walk(value, leaf => deserializeLeaf(leaf), lim);
|
|
119
|
+
}
|
|
72
120
|
const errToObj = (e) => e instanceof Error ? { name: e.name, message: e.message, stack: e.stack } : e;
|
|
73
121
|
exports.errToObj = errToObj;
|
|
74
122
|
const resolveCA = (path, args) => {
|