wenay-common2 1.0.46 → 1.0.49

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.
Files changed (86) hide show
  1. package/README.md +51 -37
  2. package/lib/Common/Color.d.ts +3 -0
  3. package/lib/Common/Color.js +4 -0
  4. package/lib/Common/ObserveAll2/index.d.ts +2 -0
  5. package/lib/Common/ObserveAll2/index.js +18 -0
  6. package/lib/Common/ObserveAll2/reactive2.d.ts +33 -0
  7. package/lib/Common/ObserveAll2/reactive2.js +254 -0
  8. package/lib/Common/ObserveAll2/store.d.ts +98 -0
  9. package/lib/Common/ObserveAll2/store.js +381 -0
  10. package/lib/Common/Time.d.ts +8 -0
  11. package/lib/Common/Time.js +41 -14
  12. package/lib/Common/async/PromiseArrayListen.d.ts +3 -3
  13. package/lib/Common/async/PromiseArrayListen.js +10 -13
  14. package/lib/Common/async/createIterableObject.js +1 -1
  15. package/lib/Common/async/waitRun.d.ts +11 -4
  16. package/lib/Common/async/waitRun.js +74 -44
  17. package/lib/Common/core/Decorator.d.ts +3 -1
  18. package/lib/Common/core/Decorator.js +5 -2
  19. package/lib/Common/core/common.d.ts +25 -7
  20. package/lib/Common/core/common.js +114 -34
  21. package/lib/Common/data/ByteStream.d.ts +1 -1
  22. package/lib/Common/data/ByteStream.js +21 -8
  23. package/lib/Common/data/List.d.ts +5 -0
  24. package/lib/Common/data/List.js +13 -4
  25. package/lib/Common/data/ListNodeAnd.js +2 -2
  26. package/lib/Common/data/objectPath.d.ts +4 -0
  27. package/lib/Common/data/objectPath.js +8 -3
  28. package/lib/Common/events/Listen.d.ts +1 -55
  29. package/lib/Common/events/Listen.js +15 -154
  30. package/lib/Common/events/Listen2.d.ts +1 -0
  31. package/lib/Common/events/Listen2.js +17 -0
  32. package/lib/Common/events/Listen3.d.ts +197 -0
  33. package/lib/Common/events/Listen3.js +249 -0
  34. package/lib/Common/events/SocketBuffer.d.ts +14 -9
  35. package/lib/Common/events/SocketServerHook.d.ts +26 -13
  36. package/lib/Common/events/SocketServerHook.js +2 -1
  37. package/lib/Common/events/UseListenTransform.d.ts +10 -5
  38. package/lib/Common/events/event.d.ts +12 -0
  39. package/lib/Common/events/event.js +10 -6
  40. package/lib/Common/events/joinListens.d.ts +2 -0
  41. package/lib/Common/events/joinListens.js +13 -12
  42. package/lib/Common/funcTimeWait.d.ts +28 -0
  43. package/lib/Common/funcTimeWait.js +18 -1
  44. package/lib/Common/isProxy.d.ts +1 -0
  45. package/lib/Common/isProxy.js +2 -0
  46. package/lib/Common/node_console.d.ts +2 -0
  47. package/lib/Common/node_console.js +3 -76
  48. package/lib/Common/rcp/createRpcServerAutoWithProtocolDetection.d.ts +2 -0
  49. package/lib/Common/rcp/createRpcServerAutoWithProtocolDetection.js +63 -30
  50. package/lib/Common/rcp/listen-deep.d.ts +13 -5
  51. package/lib/Common/rcp/listen-socket.d.ts +21 -3
  52. package/lib/Common/rcp/listen-socket.js +126 -17
  53. package/lib/Common/rcp/oldCommonsServer.d.ts +1 -1
  54. package/lib/Common/rcp/oldCommonsServer.js +15 -1
  55. package/lib/Common/rcp/old/320/241ommonsServerMini.js +1 -0
  56. package/lib/Common/rcp/rpc-caps.d.ts +10 -0
  57. package/lib/Common/rcp/rpc-caps.js +16 -0
  58. package/lib/Common/rcp/rpc-client.d.ts +23 -1
  59. package/lib/Common/rcp/rpc-client.js +306 -25
  60. package/lib/Common/rcp/rpc-clientHub.d.ts +7 -1
  61. package/lib/Common/rcp/rpc-clientHub.js +25 -2
  62. package/lib/Common/rcp/rpc-index.d.ts +3 -0
  63. package/lib/Common/rcp/rpc-index.js +3 -0
  64. package/lib/Common/rcp/rpc-inproc.d.ts +17 -0
  65. package/lib/Common/rcp/rpc-inproc.js +30 -0
  66. package/lib/Common/rcp/rpc-off.d.ts +10 -0
  67. package/lib/Common/rcp/rpc-off.js +22 -0
  68. package/lib/Common/rcp/rpc-protocol.d.ts +6 -0
  69. package/lib/Common/rcp/rpc-protocol.js +4 -2
  70. package/lib/Common/rcp/rpc-server-auto.d.ts +14 -3
  71. package/lib/Common/rcp/rpc-server-auto.js +81 -6
  72. package/lib/Common/rcp/rpc-server.d.ts +17 -2
  73. package/lib/Common/rcp/rpc-server.js +127 -31
  74. package/lib/Common/rcp/rpc-shape.d.ts +17 -0
  75. package/lib/Common/rcp/rpc-shape.js +42 -0
  76. package/lib/Common/rcp/rpc-walk.js +29 -11
  77. package/lib/Exchange/Bars.d.ts +3 -0
  78. package/lib/Exchange/Bars.js +4 -1
  79. package/lib/Exchange/CParams.d.ts +2 -0
  80. package/lib/Exchange/CParams.js +21 -14
  81. package/lib/Exchange/MarketData.d.ts +6 -0
  82. package/lib/Exchange/MarketData.js +4 -0
  83. package/lib/index.d.ts +2 -0
  84. package/lib/index.js +3 -1
  85. package/lib/server/WebHook3.js +22 -9
  86. package/package.json +3 -1
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.endCallback = void 0;
4
+ exports.makeOff = makeOff;
5
+ const rpc_walk_1 = require("./rpc-walk");
6
+ exports.endCallback = rpc_walk_1.rpcEndCallback;
7
+ function makeOff(promise, stop, extra) {
8
+ let done = false;
9
+ function off() {
10
+ if (done)
11
+ return;
12
+ done = true;
13
+ stop();
14
+ }
15
+ const handle = off;
16
+ handle.then = promise.then.bind(promise);
17
+ handle.catch = promise.catch.bind(promise);
18
+ handle.finally = promise.finally.bind(promise);
19
+ if (extra)
20
+ Object.assign(handle, extra);
21
+ return handle;
22
+ }
@@ -6,7 +6,13 @@ export declare const Pkt: {
6
6
  readonly STRICT: 4;
7
7
  readonly CB_END: 5;
8
8
  readonly PIPE: 6;
9
+ readonly HELLO: 7;
10
+ readonly SHAPE: 8;
11
+ readonly CBV: 9;
12
+ readonly CAPS: 10;
9
13
  };
14
+ export declare const RPC_STOP = "___STOP";
15
+ export declare const IS_RPC_LISTEN: unique symbol;
10
16
  export type SocketTmpl = {
11
17
  emit: (e: string, d: any) => void;
12
18
  on: (e: string, cb: (d: any) => void) => void;
@@ -1,4 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Pkt = void 0;
4
- exports.Pkt = { CALL: 0, RESP: 1, CB: 2, MAP: 3, STRICT: 4, CB_END: 5, PIPE: 6 };
3
+ exports.IS_RPC_LISTEN = exports.RPC_STOP = exports.Pkt = void 0;
4
+ exports.Pkt = { CALL: 0, RESP: 1, CB: 2, MAP: 3, STRICT: 4, CB_END: 5, PIPE: 6, HELLO: 7, SHAPE: 8, CBV: 9, CAPS: 10 };
5
+ exports.RPC_STOP = "___STOP";
6
+ exports.IS_RPC_LISTEN = Symbol.for("isRpcListen");
@@ -1,9 +1,9 @@
1
1
  import { funcListenCallbackBase } from "../events/Listen";
2
- import { type PromiseServerHooks, type RpcLimits } from "./rpc-server";
2
+ import { type PromiseServerHooks, type RpcLimits, type RpcServerAuth, type RpcOpt } from "./rpc-server";
3
3
  import { DeepSocketListen } from "./listen-deep";
4
4
  import { SocketTmpl } from "./rpc-protocol";
5
5
  type ListenCallbackBase<T extends any[] = any[]> = ReturnType<typeof funcListenCallbackBase<T>>;
6
- export declare function createRpcServerAuto<T extends object>({ socket, object: target, socketKey: key, debug, hooks, disconnectListen, limits }: {
6
+ export declare function createRpcServerAuto<T extends object>({ socket, object: target, socketKey: key, debug, hooks, disconnectListen, limits, auth, maxPerListen, throttle, opt }: {
7
7
  socket: SocketTmpl;
8
8
  object: T;
9
9
  socketKey: string;
@@ -11,5 +11,16 @@ export declare function createRpcServerAuto<T extends object>({ socket, object:
11
11
  hooks?: Omit<PromiseServerHooks<DeepSocketListen<T>>, "resolveTransform">;
12
12
  disconnectListen?: ListenCallbackBase<any>;
13
13
  limits?: RpcLimits;
14
- }): void;
14
+ auth?: RpcServerAuth;
15
+ maxPerListen?: number;
16
+ throttle?: number;
17
+ opt?: RpcOpt;
18
+ }): {
19
+ api: {
20
+ subscriptions: () => {
21
+ key: string;
22
+ consumers: number;
23
+ }[];
24
+ };
25
+ };
15
26
  export {};
@@ -4,25 +4,100 @@ exports.createRpcServerAuto = createRpcServerAuto;
4
4
  const Listen_1 = require("../events/Listen");
5
5
  const listen_socket_1 = require("./listen-socket");
6
6
  const rpc_server_1 = require("./rpc-server");
7
- function createRpcServerAuto({ socket, object: target, socketKey: key, debug, hooks, disconnectListen, limits }) {
7
+ const rpc_protocol_1 = require("./rpc-protocol");
8
+ function createRpcServerAuto({ socket, object: target, socketKey: key, debug, hooks, disconnectListen, limits, auth, maxPerListen, throttle, opt }) {
8
9
  const cache = new WeakMap();
10
+ const registry = new Map();
11
+ function unsubscribeAllActive() {
12
+ for (const { subs } of registry.values()) {
13
+ subs.forEach(w => w.removeCallback());
14
+ subs.clear();
15
+ }
16
+ registry.clear();
17
+ }
9
18
  function getListenSocket(parent, disconnectListen) {
10
19
  let result = cache.get(parent);
11
20
  if (!result) {
12
- result = (0, listen_socket_1.listenSocket)(parent, { addListenClose: disconnectListen });
21
+ const subs = new Map();
22
+ function subscribe(z) {
23
+ if (typeof z !== "function")
24
+ return Promise.reject(new TypeError("Listen callback expects a function"));
25
+ if (maxPerListen != null && subs.size >= maxPerListen)
26
+ return Promise.resolve();
27
+ if (!registry.has(parent))
28
+ registry.set(parent, { subs });
29
+ subs.get(z)?.removeCallback();
30
+ const w = (0, listen_socket_1.listenSocket)(parent, { addListenClose: disconnectListen, throttle });
31
+ subs.set(z, w);
32
+ const done = w.callback(z);
33
+ done.then(() => {
34
+ if (subs.get(z) == w)
35
+ subs.delete(z);
36
+ if (subs.size == 0)
37
+ registry.delete(parent);
38
+ });
39
+ return done;
40
+ }
41
+ function subscribeOnce(z) {
42
+ if (typeof z !== "function")
43
+ return Promise.reject(new TypeError("Listen once expects a function"));
44
+ if (maxPerListen != null && subs.size >= maxPerListen)
45
+ return Promise.resolve();
46
+ if (!registry.has(parent))
47
+ registry.set(parent, { subs });
48
+ subs.get(z)?.removeCallback();
49
+ const w = (0, listen_socket_1.listenSocket)(parent, { addListenClose: disconnectListen, throttle });
50
+ let fired = false;
51
+ const oneShot = (...a) => {
52
+ if (fired)
53
+ return;
54
+ fired = true;
55
+ try {
56
+ z(...a);
57
+ z(rpc_protocol_1.RPC_STOP);
58
+ }
59
+ finally {
60
+ w.removeCallback();
61
+ }
62
+ };
63
+ subs.set(z, w);
64
+ const done = w.callback(oneShot);
65
+ done.then(() => { if (subs.get(z) == w)
66
+ subs.delete(z); if (subs.size == 0)
67
+ registry.delete(parent); });
68
+ return done;
69
+ }
70
+ function unsubscribeAll() {
71
+ subs.forEach(w => w.removeCallback());
72
+ subs.clear();
73
+ registry.delete(parent);
74
+ return true;
75
+ }
76
+ result = { callback: subscribe, removeCallback: unsubscribeAll, on: subscribe, once: subscribeOnce, close: () => parent.close?.() };
77
+ result[rpc_protocol_1.IS_RPC_LISTEN] = true;
13
78
  cache.set(parent, result);
14
79
  }
15
80
  return result;
16
81
  }
82
+ const api = {
83
+ subscriptions: () => Array.from(registry, ([parent, e], i) => ({
84
+ key: parent?.constructor?.name ? `${parent.constructor.name}#${i}` : `listen#${i}`,
85
+ consumers: e.subs.size,
86
+ })),
87
+ };
17
88
  (0, rpc_server_1.createRpcServer)({
18
- socket, object: target, socketKey: key, debug, limits,
89
+ socket, object: target, socketKey: key, debug, limits, auth, opt,
19
90
  hooks: {
20
91
  ...hooks,
92
+ onDispose: () => { unsubscribeAllActive(); hooks?.onDispose?.(); },
21
93
  resolveTransform: (obj) => {
22
- if (!(0, Listen_1.isListenCallback)(obj))
23
- return obj;
24
- return getListenSocket(obj, disconnectListen);
94
+ if ((0, Listen_1.isListenCallback)(obj))
95
+ return getListenSocket(obj, disconnectListen);
96
+ if ((0, Listen_1.isListenOn)(obj))
97
+ return getListenSocket((0, Listen_1.getListenByOn)(obj), disconnectListen);
98
+ return obj;
25
99
  },
26
100
  },
27
101
  });
102
+ return { api };
28
103
  }
@@ -1,5 +1,6 @@
1
1
  import { type RpcLimits } from "./rpc-limits";
2
2
  import { type SocketTmpl } from "./rpc-protocol";
3
+ import { type RpcOpt } from "./rpc-caps";
3
4
  type Func = (...args: any[]) => any;
4
5
  type PromiseServerHooks<T> = {
5
6
  onRequest?: (ctx: {
@@ -15,13 +16,27 @@ type PromiseServerHooks<T> = {
15
16
  error?: any;
16
17
  }) => void | Promise<void>;
17
18
  resolveTransform?: (value: any) => any;
19
+ onDispose?: () => void;
18
20
  };
19
- export declare function createRpcServer<T extends object>({ socket, object: target, socketKey: key, debug, hooks, limits }: {
21
+ type RpcServerAuth = {
22
+ resolveAuth: (token: any) => {
23
+ object?: any;
24
+ ack?: any;
25
+ } | Promise<{
26
+ object?: any;
27
+ ack?: any;
28
+ }>;
29
+ gate?: boolean;
30
+ };
31
+ export declare function createRpcServer<T extends object>({ socket, object: target, socketKey: key, debug, hooks, limits, auth, opt }: {
20
32
  socket: SocketTmpl;
21
33
  object: T;
22
34
  socketKey: string;
23
35
  debug?: boolean;
24
36
  hooks?: PromiseServerHooks<T>;
25
37
  limits?: RpcLimits;
38
+ auth?: RpcServerAuth;
39
+ opt?: RpcOpt;
26
40
  }): void;
27
- export type { PromiseServerHooks, RpcLimits };
41
+ export type { PromiseServerHooks, RpcLimits, RpcServerAuth };
42
+ export type { RpcOpt } from "./rpc-caps";
@@ -4,12 +4,14 @@ exports.createRpcServer = createRpcServer;
4
4
  const rpc_dynamic_1 = require("./rpc-dynamic");
5
5
  const rpc_limits_1 = require("./rpc-limits");
6
6
  const rpc_walk_1 = require("./rpc-walk");
7
+ const rpc_shape_1 = require("./rpc-shape");
7
8
  const rpc_protocol_1 = require("./rpc-protocol");
8
- function createServer(socket, key, target, hooks, limits) {
9
+ const rpc_caps_1 = require("./rpc-caps");
10
+ const myThrow_1 = require("../../toError/myThrow");
11
+ const SERVERS = new WeakMap();
12
+ function createServer(socket, key, target, hooks, limits, auth, opt) {
9
13
  const lim = (0, rpc_limits_1.resolveLimits)(limits);
10
- const methods = [];
11
- const contexts = [];
12
- const routeMap = {};
14
+ const IS_RPC_PIPE = Symbol.for("isRpcPipe");
13
15
  function transformTree(obj) {
14
16
  let current = obj;
15
17
  if (hooks?.resolveTransform && !(0, rpc_dynamic_1.isNoStrict)(current)) {
@@ -18,6 +20,8 @@ function createServer(socket, key, target, hooks, limits) {
18
20
  if (current == null || typeof current != "object" || (0, rpc_dynamic_1.isNoStrict)(current))
19
21
  return current;
20
22
  const out = {};
23
+ if (current[rpc_protocol_1.IS_RPC_LISTEN])
24
+ out[rpc_protocol_1.IS_RPC_LISTEN] = true;
21
25
  for (const k of Object.keys(current)) {
22
26
  if (!(0, rpc_limits_1.isSafeKey)(k))
23
27
  continue;
@@ -26,27 +30,11 @@ function createServer(socket, key, target, hooks, limits) {
26
30
  out[k] = v;
27
31
  continue;
28
32
  }
29
- out[k] = typeof v == "function" ? v : v != null && typeof v == "object" ? transformTree(v) : v;
33
+ out[k] = typeof v == "function" ? (hooks?.resolveTransform ? hooks.resolveTransform(v) : v)
34
+ : v != null && typeof v == "object" ? transformTree(v) : v;
30
35
  }
31
36
  return out;
32
37
  }
33
- const resolved = transformTree(target);
34
- function index(obj, prefix) {
35
- for (const k of Object.keys(obj)) {
36
- if (!(0, rpc_limits_1.isSafeKey)(k))
37
- continue;
38
- const v = obj[k];
39
- const path = prefix ? prefix + "." + k : k;
40
- if (typeof v == "function") {
41
- routeMap[path] = methods.length;
42
- methods.push(v);
43
- contexts.push(obj);
44
- }
45
- else if (v && typeof v == "object" && !(0, rpc_dynamic_1.isNoStrict)(v))
46
- index(v, path);
47
- }
48
- }
49
- index(resolved, "");
50
38
  function serialize(obj) {
51
39
  const out = {};
52
40
  for (const k of Object.keys(obj)) {
@@ -73,13 +61,110 @@ function createServer(socket, key, target, hooks, limits) {
73
61
  }
74
62
  return out;
75
63
  }
76
- const strictSchema = serialize(resolved);
64
+ let methods = [];
65
+ let contexts = [];
66
+ let routeMap = {};
67
+ let listenPaths = [];
68
+ let strictSchema = {};
69
+ let currentTarget = target;
70
+ function buildDispatch(t) {
71
+ const m = [], cx = [], rm = {}, lp = [];
72
+ const resolved = transformTree(t);
73
+ (function index(obj, prefix) {
74
+ for (const k of Object.keys(obj)) {
75
+ if (!(0, rpc_limits_1.isSafeKey)(k))
76
+ continue;
77
+ const v = obj[k];
78
+ const path = prefix ? prefix + "." + k : k;
79
+ if (typeof v == "function") {
80
+ rm[path] = m.length;
81
+ m.push(v);
82
+ cx.push(obj);
83
+ }
84
+ else if (v && typeof v == "object" && !(0, rpc_dynamic_1.isNoStrict)(v)) {
85
+ if (v[rpc_protocol_1.IS_RPC_LISTEN])
86
+ lp.push(path);
87
+ index(v, path);
88
+ }
89
+ }
90
+ })(resolved, "");
91
+ methods = m;
92
+ contexts = cx;
93
+ routeMap = rm;
94
+ listenPaths = lp;
95
+ strictSchema = serialize(resolved);
96
+ currentTarget = t;
97
+ }
98
+ buildDispatch(target);
77
99
  const send = (d) => socket.emit(key, d);
78
- const IS_RPC_PIPE = Symbol.for("isRpcPipe");
79
- send([rpc_protocol_1.Pkt.MAP, routeMap, strictSchema]);
100
+ const serverCaps = (0, rpc_caps_1.optToCaps)(opt);
101
+ let peerCaps = 0;
102
+ const compactOn = () => (0, rpc_caps_1.hasCap)(serverCaps & peerCaps, rpc_caps_1.Caps.COMPACT);
103
+ const cbShapes = (0, rpc_shape_1.createCbShapeServer)();
104
+ const sendCb = (cbId, cbArgs) => {
105
+ if (compactOn() && cbArgs.length == 1 && (0, rpc_shape_1.isPlainObject)(cbArgs[0])) {
106
+ const obj = cbArgs[0];
107
+ const r = cbShapes.offer(cbId, obj);
108
+ if (r.mode == "register") {
109
+ send([rpc_protocol_1.Pkt.SHAPE, cbId, r.shapeId, r.keys]);
110
+ send([rpc_protocol_1.Pkt.CBV, cbId, r.shapeId, r.keys.map(k => (0, rpc_walk_1.packResult)(obj[k]))]);
111
+ return;
112
+ }
113
+ if (r.mode == "compact") {
114
+ send([rpc_protocol_1.Pkt.CBV, cbId, r.shapeId, r.keys.map(k => (0, rpc_walk_1.packResult)(obj[k]))]);
115
+ return;
116
+ }
117
+ }
118
+ send([rpc_protocol_1.Pkt.CB, cbId, cbArgs.map(rpc_walk_1.packResult)]);
119
+ };
120
+ const sendCbEnd = (cbId) => { cbShapes.drop(cbId); send([rpc_protocol_1.Pkt.CB_END, cbId]); };
121
+ let authed = !auth?.gate;
122
+ let authAck = undefined;
123
+ const sendMap = () => send(authAck !== undefined
124
+ ? [rpc_protocol_1.Pkt.MAP, routeMap, strictSchema, listenPaths, authAck]
125
+ : [rpc_protocol_1.Pkt.MAP, routeMap, strictSchema, listenPaths]);
126
+ sendMap();
127
+ if (serverCaps)
128
+ send([rpc_protocol_1.Pkt.CAPS, serverCaps]);
129
+ let detached = false;
130
+ let byKey = SERVERS.get(socket);
131
+ if (!byKey) {
132
+ byKey = new Map();
133
+ SERVERS.set(socket, byKey);
134
+ }
135
+ const detachPrev = byKey.get(key);
136
+ if (detachPrev) {
137
+ detachPrev();
138
+ console.warn(`[RPC] createRpcServer: повторная инициализация на socket+key "${key}" — предыдущий сервер отцеплен`);
139
+ }
140
+ byKey.set(key, () => { detached = true; hooks?.onDispose?.(); });
80
141
  socket.on(key, async (msg) => {
142
+ if (detached)
143
+ return;
81
144
  if (msg == rpc_protocol_1.Pkt.STRICT) {
82
- send([rpc_protocol_1.Pkt.MAP, routeMap, strictSchema]);
145
+ sendMap();
146
+ return;
147
+ }
148
+ if (Array.isArray(msg) && msg[0] === rpc_protocol_1.Pkt.CAPS) {
149
+ peerCaps = typeof msg[1] === "number" ? msg[1] : rpc_caps_1.Caps.COMPACT;
150
+ return;
151
+ }
152
+ if (Array.isArray(msg) && msg[0] === rpc_protocol_1.Pkt.HELLO) {
153
+ if (!auth?.resolveAuth) {
154
+ send([rpc_protocol_1.Pkt.MAP, routeMap, strictSchema, listenPaths, null]);
155
+ return;
156
+ }
157
+ try {
158
+ const r = await auth.resolveAuth(msg[1]);
159
+ if (r && r.object !== undefined)
160
+ buildDispatch(r.object);
161
+ authAck = r && r.ack !== undefined ? r.ack : { ok: true };
162
+ authed = authAck?.ok !== false;
163
+ sendMap();
164
+ }
165
+ catch (e) {
166
+ send([rpc_protocol_1.Pkt.MAP, routeMap, strictSchema, listenPaths, { ok: false, reason: e?.message ?? String(e) }]);
167
+ }
83
168
  return;
84
169
  }
85
170
  if (!Array.isArray(msg) || (msg[0] !== rpc_protocol_1.Pkt.CALL && msg[0] !== rpc_protocol_1.Pkt.PIPE))
@@ -91,6 +176,11 @@ function createServer(socket, key, target, hooks, limits) {
91
176
  hooks?.onInvalid?.({ reason: "invalid_payload", key: ref, request: rawArgsOrSteps, error: "reqId is not a valid number" });
92
177
  return;
93
178
  }
179
+ if (!authed) {
180
+ if (wait)
181
+ send([rpc_protocol_1.Pkt.RESP, reqId, null, (0, rpc_walk_1.errToObj)(new myThrow_1.MyError("Unauthorized", "E_UNAUTHORIZED"))]);
182
+ return;
183
+ }
94
184
  if (typeof ref !== "number" && !Array.isArray(ref)) {
95
185
  hooks?.onInvalid?.({ reason: "invalid_payload", key: ref, request: rawArgsOrSteps, error: "ref must be number or string[]" });
96
186
  if (wait)
@@ -116,13 +206,19 @@ function createServer(socket, key, target, hooks, limits) {
116
206
  send([rpc_protocol_1.Pkt.RESP, reqId, null, (0, rpc_walk_1.errToObj)(new Error("Forbidden path segment"))]);
117
207
  return;
118
208
  }
209
+ if (ref.length > lim.maxPathLen) {
210
+ hooks?.onInvalid?.({ reason: "invalid_payload", key: ref, request: rawArgsOrSteps, error: "path too long" });
211
+ if (wait)
212
+ send([rpc_protocol_1.Pkt.RESP, reqId, null, (0, rpc_walk_1.errToObj)(new rpc_limits_1.PayloadLimitError("path too long"))]);
213
+ return;
214
+ }
119
215
  const idx = routeMap[ref.join(".")];
120
216
  if (idx !== undefined) {
121
217
  fn = methods[idx];
122
218
  ctx = contexts[idx];
123
219
  }
124
220
  else {
125
- let curr = target;
221
+ let curr = currentTarget;
126
222
  for (let i = 0; i < ref.length - 1; i++) {
127
223
  const seg = ref[i];
128
224
  if (curr == null || typeof curr !== "object" || !(seg in curr)) {
@@ -178,7 +274,7 @@ function createServer(socket, key, target, hooks, limits) {
178
274
  else if (step.type === 'call') {
179
275
  if (typeof current !== "function")
180
276
  throw new Error("Attempted to call a non-function in pipe");
181
- const stepArgs = (0, rpc_walk_1.unpack)(step.args, (cbId, cbArgs) => send([rpc_protocol_1.Pkt.CB, cbId, cbArgs]), (cbId) => send([rpc_protocol_1.Pkt.CB_END, cbId]), lim);
277
+ const stepArgs = (0, rpc_walk_1.unpack)(step.args, sendCb, sendCbEnd, lim);
182
278
  current = current(...stepArgs);
183
279
  }
184
280
  }
@@ -189,7 +285,7 @@ function createServer(socket, key, target, hooks, limits) {
189
285
  send([rpc_protocol_1.Pkt.RESP, reqId, (0, rpc_walk_1.packResult)(current)]);
190
286
  }
191
287
  else {
192
- const args = (0, rpc_walk_1.unpack)(rawArgsOrSteps, (cbId, cbArgs) => send([rpc_protocol_1.Pkt.CB, cbId, cbArgs.map(rpc_walk_1.packResult)]), (cbId) => send([rpc_protocol_1.Pkt.CB_END, cbId]), lim);
288
+ const args = (0, rpc_walk_1.unpack)(rawArgsOrSteps, sendCb, sendCbEnd, lim);
193
289
  const res = await fn.apply(ctx, args);
194
290
  if (wait)
195
291
  send([rpc_protocol_1.Pkt.RESP, reqId, (0, rpc_walk_1.packResult)(res)]);
@@ -201,10 +297,10 @@ function createServer(socket, key, target, hooks, limits) {
201
297
  }
202
298
  });
203
299
  }
204
- function createRpcServer({ socket, object: target, socketKey: key, debug = false, hooks, limits }) {
300
+ function createRpcServer({ socket, object: target, socketKey: key, debug = false, hooks, limits, auth, opt }) {
205
301
  if (debug) {
206
302
  const origOn = socket.on.bind(socket);
207
303
  socket.on = (e, cb) => origOn(e, (d) => { console.log("[RPC IN]", typeof d == "object" ? JSON.stringify(d) : d); cb(d); });
208
304
  }
209
- createServer(socket, key, target, hooks, limits);
305
+ createServer(socket, key, target, hooks, limits, auth, opt);
210
306
  }
@@ -0,0 +1,17 @@
1
+ export declare function isPlainObject(v: any): boolean;
2
+ export declare function createCbShapeServer(threshold?: number, maxShapes?: number): {
3
+ offer: (cbId: number, obj: any) => {
4
+ mode: "compact";
5
+ shapeId: number;
6
+ keys: string[];
7
+ } | {
8
+ mode: "register";
9
+ shapeId: number;
10
+ keys: string[];
11
+ } | {
12
+ mode: "full";
13
+ shapeId?: undefined;
14
+ keys?: undefined;
15
+ };
16
+ drop: (cbId: number) => void;
17
+ };
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPlainObject = isPlainObject;
4
+ exports.createCbShapeServer = createCbShapeServer;
5
+ const THRESHOLD = 5;
6
+ const MAX_SHAPES = 5;
7
+ function isPlainObject(v) {
8
+ if (v == null || typeof v != "object")
9
+ return false;
10
+ if (Array.isArray(v) || v instanceof Date || v instanceof Map || v instanceof Set || v instanceof RegExp)
11
+ return false;
12
+ const p = Object.getPrototypeOf(v);
13
+ return p == null || p == Object.prototype;
14
+ }
15
+ function createCbShapeServer(threshold = THRESHOLD, maxShapes = MAX_SHAPES) {
16
+ const byCb = new Map();
17
+ function offer(cbId, obj) {
18
+ const keys = Object.keys(obj);
19
+ const sig = keys.slice().sort().join("\x00");
20
+ let st = byCb.get(cbId);
21
+ if (!st) {
22
+ st = { shapes: [], nextId: 0 };
23
+ byCb.set(cbId, st);
24
+ }
25
+ const sh = st.shapes.find(s => s.sig == sig);
26
+ if (sh) {
27
+ sh.count++;
28
+ if (sh.shapeId >= 0)
29
+ return { mode: "compact", shapeId: sh.shapeId, keys: sh.keys };
30
+ if (sh.count >= threshold) {
31
+ sh.shapeId = st.nextId++;
32
+ return { mode: "register", shapeId: sh.shapeId, keys: sh.keys };
33
+ }
34
+ return { mode: "full" };
35
+ }
36
+ if (st.shapes.length < maxShapes)
37
+ st.shapes.push({ sig, keys, count: 1, shapeId: -1 });
38
+ return { mode: "full" };
39
+ }
40
+ function drop(cbId) { byCb.delete(cbId); }
41
+ return { offer, drop };
42
+ }
@@ -8,6 +8,7 @@ exports.rpcEndCallback = rpcEndCallback;
8
8
  exports.unpack = unpack;
9
9
  exports.unpackResult = unpackResult;
10
10
  const rpc_limits_1 = require("./rpc-limits");
11
+ const rpc_protocol_1 = require("./rpc-protocol");
11
12
  const FN_MARKER = "$_f";
12
13
  const DATE_MARKER = "$_d";
13
14
  const MAP_MARKER = "$_m";
@@ -15,17 +16,19 @@ const SET_MARKER = "$_s";
15
16
  const REGEXP_MARKER = "$_r";
16
17
  const BIGINT_MARKER = "$_b";
17
18
  const ALL_MARKERS = new Set([FN_MARKER, DATE_MARKER, MAP_MARKER, SET_MARKER, REGEXP_MARKER, BIGINT_MARKER]);
19
+ const deepSerialize = (v) => walk(v, serializeLeaf);
20
+ const deepDeserialize = (v, lim) => walk(v, l => deserializeLeaf(l, undefined, lim), lim);
18
21
  const DESERIALIZERS = {
19
22
  [DATE_MARKER]: (v) => new Date(v),
20
- [MAP_MARKER]: (v) => new Map(v),
21
- [SET_MARKER]: (v) => new Set(v),
23
+ [MAP_MARKER]: (v, lim) => new Map(v.map(([k, val]) => [deepDeserialize(k, lim), deepDeserialize(val, lim)])),
24
+ [SET_MARKER]: (v, lim) => new Set(v.map((x) => deepDeserialize(x, lim))),
22
25
  [REGEXP_MARKER]: (v) => new RegExp(v.source, v.flags),
23
26
  [BIGINT_MARKER]: (v) => BigInt(v),
24
27
  };
25
28
  const SERIALIZERS = [
26
29
  (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,
30
+ (v) => v instanceof Map ? [MAP_MARKER, Array.from(v.entries(), ([k, val]) => [deepSerialize(k), deepSerialize(val)])] : null,
31
+ (v) => v instanceof Set ? [SET_MARKER, Array.from(v.values(), (x) => deepSerialize(x))] : null,
29
32
  (v) => v instanceof RegExp ? [REGEXP_MARKER, { source: v.source, flags: v.flags }] : null,
30
33
  (v) => typeof v === "bigint" ? [BIGINT_MARKER, v.toString()] : null,
31
34
  ];
@@ -40,7 +43,8 @@ function walk(val, onLeaf, lim, depth = 0) {
40
43
  return onLeaf(val);
41
44
  if (val instanceof Date || val instanceof Map || val instanceof Set || val instanceof RegExp)
42
45
  return onLeaf(val);
43
- if (ALL_MARKERS.has(Object.keys(val)[0]))
46
+ const ks0 = Object.keys(val);
47
+ if (ks0.length === 1 && ALL_MARKERS.has(ks0[0]))
44
48
  return onLeaf(val);
45
49
  if (Array.isArray(val)) {
46
50
  if (lim && val.length > lim.maxArrayLen)
@@ -56,7 +60,7 @@ function walk(val, onLeaf, lim, depth = 0) {
56
60
  o[k] = walk(val[k], onLeaf, lim, depth + 1);
57
61
  return o;
58
62
  }
59
- function deserializeLeaf(leaf, onCallback) {
63
+ function deserializeLeaf(leaf, onCallback, lim) {
60
64
  if (leaf == null || typeof leaf !== "object")
61
65
  return leaf;
62
66
  const key = Object.keys(leaf)[0];
@@ -66,7 +70,7 @@ function deserializeLeaf(leaf, onCallback) {
66
70
  return onCallback?.(leaf[FN_MARKER]) ?? leaf;
67
71
  }
68
72
  const deserialize = DESERIALIZERS[key];
69
- return deserialize ? deserialize(leaf[key]) : leaf;
73
+ return deserialize ? deserialize(leaf[key], lim) : leaf;
70
74
  }
71
75
  function serializeLeaf(leaf) {
72
76
  for (const serializer of SERIALIZERS) {
@@ -95,6 +99,8 @@ function rpcEndCallback(fn) {
95
99
  _stopRegistry.get(fn)?.();
96
100
  }
97
101
  function unpack(args, sender, onEnd, lim) {
102
+ if (lim && args.length > lim.maxArgs)
103
+ throw new rpc_limits_1.PayloadLimitError("too many args");
98
104
  let cbCount = 0;
99
105
  return args.map(v => walk(v, leaf => {
100
106
  if (leaf != null && typeof leaf == "object" && leaf[FN_MARKER] !== undefined) {
@@ -104,7 +110,7 @@ function unpack(args, sender, onEnd, lim) {
104
110
  if (typeof id !== "number" || !Number.isFinite(id))
105
111
  throw new rpc_limits_1.PayloadLimitError("invalid callback id");
106
112
  const wrapper = (...a) => {
107
- if (a[0] == "___STOP") {
113
+ if (a[0] == rpc_protocol_1.RPC_STOP) {
108
114
  onEnd(id);
109
115
  return;
110
116
  }
@@ -113,13 +119,25 @@ function unpack(args, sender, onEnd, lim) {
113
119
  _stopRegistry.set(wrapper, () => onEnd(id));
114
120
  return wrapper;
115
121
  }
116
- return deserializeLeaf(leaf);
122
+ return deserializeLeaf(leaf, undefined, lim);
117
123
  }, lim));
118
124
  }
119
125
  function unpackResult(value, lim) {
120
- return walk(value, leaf => deserializeLeaf(leaf), lim);
126
+ return walk(value, leaf => deserializeLeaf(leaf, undefined, lim), lim);
121
127
  }
122
- const errToObj = (e) => e instanceof Error ? { name: e.name, message: e.message, stack: e.stack } : e;
128
+ const errToObj = (e) => {
129
+ if (!(e instanceof Error))
130
+ return e;
131
+ const o = { name: e.name, message: e.message, stack: e.stack };
132
+ const { code, data, cause } = e;
133
+ if (code !== undefined)
134
+ o.code = code;
135
+ if (data !== undefined)
136
+ o.data = packResult(data);
137
+ if (cause !== undefined)
138
+ o.cause = (0, exports.errToObj)(cause);
139
+ return o;
140
+ };
123
141
  exports.errToObj = errToObj;
124
142
  const resolveCA = (path, args) => {
125
143
  const last = path[path.length - 1];
@@ -131,6 +131,8 @@ export declare abstract class CBarsMutableBase extends CBarsBase {
131
131
  updateLast(bar: CBar): void;
132
132
  AddTick(tick: ITick): boolean;
133
133
  AddTicks(ticks: readonly ITick[]): boolean;
134
+ addTick(tick: ITick): boolean;
135
+ addTicks(ticks: readonly ITick[]): boolean;
134
136
  }
135
137
  export declare class CBarsMutable extends CBarsMutableBase {
136
138
  readonly Mutable = true;
@@ -141,6 +143,7 @@ export declare class CBarsMutableExt extends CBarsMutable implements IBarsExt {
141
143
  }
142
144
  export declare function CreateRandomBars(tf: TF, startTime: const_Date, endTime: const_Date, startPrice?: number, volatility?: number | `${number}%`, ticksize?: number): CBars;
143
145
  export declare function CreateRandomBars(tf: TF, startTime: const_Date, barsCount: number, startPrice?: number, volatility?: number | `${number}%`, ticksize?: number): CBars;
146
+ export declare const createRandomBars: typeof CreateRandomBars;
144
147
  export type TimeValue<T> = {
145
148
  readonly time: const_Date;
146
149
  readonly value: T;
@@ -36,7 +36,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
36
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.CTimeSeries = exports.CTimeSeriesBase = exports.CBarsMutableExt = exports.CBarsMutable = exports.CBarsMutableBase = exports.CBars = exports.CBarsBase = exports.IBars = exports.CTick = exports.CBar = exports.CBarBase = exports.OHLC = void 0;
39
+ exports.CTimeSeries = exports.CTimeSeriesBase = exports.createRandomBars = exports.CBarsMutableExt = exports.CBarsMutable = exports.CBarsMutableBase = exports.CBars = exports.CBarsBase = exports.IBars = exports.CTick = exports.CBar = exports.CBarBase = exports.OHLC = void 0;
40
40
  exports.CreateRandomBars = CreateRandomBars;
41
41
  exports.findBarsShallow = findBarsShallow;
42
42
  const lib = __importStar(require("../Common/core/common"));
@@ -357,6 +357,8 @@ class CBarsMutableBase extends CBarsBase {
357
357
  AddTicks(ticks) { for (let tick of ticks)
358
358
  if (!this.AddTick(tick))
359
359
  return false; return true; }
360
+ addTick(tick) { return this.AddTick(tick); }
361
+ addTicks(ticks) { return this.AddTicks(ticks); }
360
362
  }
361
363
  exports.CBarsMutableBase = CBarsMutableBase;
362
364
  class CBarsMutable extends CBarsMutableBase {
@@ -403,6 +405,7 @@ function CreateRandomBars(tf, startTime, endTimeOrCount, startPrice = 100, volat
403
405
  }
404
406
  return new CBars(tf, bars);
405
407
  }
408
+ exports.createRandomBars = CreateRandomBars;
406
409
  class CTimeSeriesBase {
407
410
  time(i) { return this.points[i]?.time ?? (() => { throw "Wrong index i=" + i + " of " + this.length; })(); }
408
411
  value(i) { return this.points[i]?.value ?? (() => { throw "Wrong index i=" + i + " of " + this.length; })(); }