wenay-common2 1.0.45 → 1.0.46

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 (38) hide show
  1. package/lib/Common/Color.js +7 -3
  2. package/lib/Common/async/PromiseArrayListen.js +0 -1
  3. package/lib/Common/async/createIterableObject.js +1 -1
  4. package/lib/Common/async/waitRun.d.ts +1 -1
  5. package/lib/Common/async/waitRun.js +1 -1
  6. package/lib/Common/core/Decorator.js +2 -1
  7. package/lib/Common/core/DeepCompareKeys.js +4 -0
  8. package/lib/Common/core/MemoFunc.js +2 -2
  9. package/lib/Common/core/common.js +4 -4
  10. package/lib/Common/data/ByteStream.js +10 -19
  11. package/lib/Common/data/List.d.ts +1 -1
  12. package/lib/Common/data/List.js +15 -2
  13. package/lib/Common/data/ListNodeAnd.js +1 -1
  14. package/lib/Common/events/SocketBuffer.js +1 -0
  15. package/lib/Common/events/event.js +17 -6
  16. package/lib/Common/events/joinListens.js +10 -3
  17. package/lib/Common/funcTimeWait.d.ts +0 -2
  18. package/lib/Common/funcTimeWait.js +2 -20
  19. package/lib/Common/id-pool.js +12 -2
  20. package/lib/Common/inputAutoStep.js +2 -2
  21. package/lib/Common/math/Math.d.ts +1 -0
  22. package/lib/Common/math/Math.js +7 -1
  23. package/lib/Common/math/other.js +2 -1
  24. package/lib/Common/math/scoreLana.js +3 -2
  25. package/lib/Common/rcp/listen-deep.js +1 -6
  26. package/lib/Common/rcp/test.d.ts +1 -0
  27. package/lib/Common/rcp/test.js +78 -0
  28. package/lib/Exchange/Bars.js +5 -3
  29. package/lib/Exchange/CParams.js +1 -1
  30. package/lib/Exchange/MarketData.js +1 -1
  31. package/lib/server/WebHook3.d.ts +1 -0
  32. package/lib/server/WebHook3.js +23 -7
  33. package/lib/server/fsKeyVolume.js +20 -3
  34. package/lib/toError/myThrow.d.ts +20 -1
  35. package/lib/toError/myThrow.js +32 -19
  36. package/package.json +1 -1
  37. package/lib/Common/Error/myThrow.d.ts +0 -5
  38. package/lib/Common/Error/myThrow.js +0 -23
@@ -69,7 +69,7 @@ function* colorGenerator2(data) {
69
69
  }
70
70
  function colorGeneratorByCount2(value = 180, count = 100, index = 1) {
71
71
  const step = Math.floor(value * 6 * index / count);
72
- const p = Math.floor(step / value);
72
+ const p = Math.floor(step / value) % 6;
73
73
  const z = Math.floor(step % value);
74
74
  const r = (p == 0 || p == 5) ? value : (p == 1) ? value - z : (p == 4) ? z : 0;
75
75
  const g = (p == 1 || p == 2) ? value : (p == 3) ? value - z : (p == 0) ? z : 0;
@@ -108,8 +108,12 @@ function isValidAlphaValue(value) {
108
108
  function toColorString(str) { if (colorStringToRGBA(str))
109
109
  return str; throw `the string '${str}' is not valid 'rgb' or 'rgba' string`; }
110
110
  function isSimilarColors(color1, color2, maxDelta = 32) {
111
- let [r1, g1, b1] = typeof color1 == "string" ? colorStringToRGBA(color1) : color1;
112
- let [r2, g2, b2] = typeof color2 == "string" ? colorStringToRGBA(color2) : color2;
111
+ let c1 = typeof color1 == "string" ? colorStringToRGBA(color1) : color1;
112
+ let c2 = typeof color2 == "string" ? colorStringToRGBA(color2) : color2;
113
+ if (!c1 || !c2)
114
+ return false;
115
+ let [r1, g1, b1] = c1;
116
+ let [r2, g2, b2] = c2;
113
117
  let delta = Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2);
114
118
  return delta <= maxDelta;
115
119
  }
@@ -14,7 +14,6 @@ function PromiseArrayListen(array) {
14
14
  const b = (error, i) => {
15
15
  ++errorCount;
16
16
  c[0](error, i, ok, errorCount, count);
17
- throw error;
18
17
  };
19
18
  const arr = array.map((e, i) => e instanceof Promise ? e.then(r => a(r, i)).catch((er) => b(er, i))
20
19
  : () => (async () => e())().then(r => a(r, i)).catch((er) => b(er, i)));
@@ -12,7 +12,7 @@ function createIterableObject(options) {
12
12
  },
13
13
  set(_, key, value) {
14
14
  if (!onChange || typeof key !== "string")
15
- return false;
15
+ return true;
16
16
  onChange("set", key, value);
17
17
  return true;
18
18
  },
@@ -10,7 +10,7 @@ export declare function createAsyncQueue(concurrency?: number): {
10
10
  export declare function enhancedQueueRun(maxParallelTasks?: number): {
11
11
  readonly queueSize: number;
12
12
  enqueue: (task: () => Promise<any>) => void;
13
- enqueueAndRun: (task: () => Promise<any>) => void;
13
+ enqueueAndRun: (task: () => Promise<any>) => Promise<any>;
14
14
  runAll: () => Promise<void>;
15
15
  };
16
16
  export declare function waitRun(): {
@@ -74,7 +74,7 @@ function enhancedQueueRun(maxParallelTasks = 5) {
74
74
  return {
75
75
  get queueSize() { return q.getQueueSize(); },
76
76
  enqueue: (task) => { q.enqueue(task); },
77
- enqueueAndRun: (task) => { q.enqueue(task); },
77
+ enqueueAndRun: (task) => q.enqueue(task),
78
78
  runAll: () => q.onIdle(),
79
79
  };
80
80
  }
@@ -20,12 +20,13 @@ function enhancedDecorator(fn, opt) {
20
20
  })
21
21
  .catch((err) => {
22
22
  optAsync?.onCatch?.(err);
23
+ throw err;
23
24
  })
24
25
  .finally(() => optAsync?.onFinally?.());
25
26
  }
26
27
  else {
27
28
  opt?.onResult?.(rawResult);
28
- return opt?.modifyResult?.(rawResult) || rawResult;
29
+ return opt?.modifyResult?.(rawResult) ?? rawResult;
29
30
  }
30
31
  };
31
32
  }
@@ -24,6 +24,8 @@ function DeepCompareKeys2(obj1, keys, func) {
24
24
  return obj1;
25
25
  if (CompareKeys2(obj1, keys))
26
26
  return func(obj1);
27
+ if (Array.isArray(obj1))
28
+ return obj1.map((v) => DeepCompareKeys2(v, keys, func));
27
29
  return Object.fromEntries(Object.entries(obj1).map(([k, v]) => [k, DeepCompareKeys2(v, keys, func)]));
28
30
  }
29
31
  function DeepCompareKeys(obj1, obj2, func) {
@@ -32,5 +34,7 @@ function DeepCompareKeys(obj1, obj2, func) {
32
34
  const keys = Object.keys(obj2);
33
35
  if (CompareKeys2(obj1, keys))
34
36
  return func(obj1);
37
+ if (Array.isArray(obj1))
38
+ return obj1.map((v) => DeepCompareKeys2(v, keys, func));
35
39
  return Object.fromEntries(Object.entries(obj1).map(([k, v]) => [k, DeepCompareKeys2(v, keys, func)]));
36
40
  }
@@ -16,7 +16,7 @@ function MemoFunc(a) {
16
16
  eventUpdate?.();
17
17
  }
18
18
  function evictOldest(map) {
19
- const keep = Math.floor(maxLimits / 2);
19
+ const keep = Math.max(1, Math.floor(maxLimits / 2));
20
20
  const entries = [...map.entries()].sort((a, b) => a[1].time - b[1].time);
21
21
  const toRemove = entries.slice(0, entries.length - keep);
22
22
  for (const [key] of toRemove) {
@@ -25,7 +25,7 @@ function MemoFunc(a) {
25
25
  eventUpdate?.();
26
26
  }
27
27
  function evictOldestFuncs() {
28
- const keep = Math.floor(maxLimits / 2);
28
+ const keep = Math.max(1, Math.floor(maxLimits / 2));
29
29
  const entries = [...memo.entries()].sort((a, b) => {
30
30
  const maxTimeA = Math.max(...[...a[1].values()].map(e => e.time ?? 0));
31
31
  const maxTimeB = Math.max(...[...b[1].values()].map(e => e.time ?? 0));
@@ -290,9 +290,9 @@ function BSearchValueInRange(from, to, precision, compare, matchMode) {
290
290
  if (precision == 0)
291
291
  throw new Error("precision=0");
292
292
  let count = Math.round((to - from) / precision) + 1;
293
- const sortMode = count >= 0 ? 1 : -1;
293
+ const sortMode = precision > 0 ? E_SORTMODE.ASCEND : E_SORTMODE.DESCEND;
294
294
  count = Math.abs(count);
295
- let i = BSearchIndex(count, (index) => compare(from + precision * index), matchMode);
295
+ let i = BSearchIndex(count, (index) => compare(from + precision * index), matchMode, sortMode);
296
296
  if (i == -1)
297
297
  return null;
298
298
  return from + precision * i;
@@ -311,7 +311,7 @@ function _BSearchNearest(array, searchValue, arrayGetValue, maxDelta) {
311
311
  let indexes = [];
312
312
  if (i == -1)
313
313
  i = array.length - 1;
314
- else if (i >= 0)
314
+ else if (i > 0)
315
315
  indexes.push(i - 1);
316
316
  indexes.push(i);
317
317
  let delta = maxDelta ?? Number.MAX_VALUE;
@@ -506,7 +506,7 @@ class __MyMap {
506
506
  Set(key, value) { this.map[key.valueOf()] = { key, value }; this.keys = null; this.OnModify?.(key); }
507
507
  Get(key) { let pair = this.map[key.valueOf()]; return pair ? pair.value : undefined; }
508
508
  Contains(key) { return this.map[key.valueOf()] != undefined; }
509
- TryAdd(key, value) { if (!this.Contains(key))
509
+ TryAdd(key, value) { if (this.Contains(key))
510
510
  return false; this.Set(key, value); return true; }
511
511
  Add(key, value) { if (!this.TryAdd(key, value))
512
512
  throw new Error(`Key ${key} is already exists for ${typeof value}`); }
@@ -73,18 +73,9 @@ class ByteStreamW {
73
73
  }
74
74
  }
75
75
  }
76
- _setInt8(pos, value) { if ((value & 1 << 7) != 0)
77
- this._view.setInt8(pos, value);
78
- else
79
- this._view.setUint8(pos, value); }
80
- _setInt16(pos, value) { if ((value & 1 << 15) != 0)
81
- this._view.setInt16(pos, value);
82
- else
83
- this._view.setUint16(pos, value); }
84
- _setInt32(pos, value) { if ((value & 1 << 31) != 0)
85
- this._view.setInt32(pos, value);
86
- else
87
- this._view.setUint32(pos, value); }
76
+ _setInt8(pos, value) { this._view.setInt8(pos, value); }
77
+ _setInt16(pos, value) { this._view.setInt16(pos, value); }
78
+ _setInt32(pos, value) { this._view.setInt32(pos, value); }
88
79
  _push(value, bytes, isInteger) {
89
80
  let pos = this._pos;
90
81
  this._ensureAllocation(bytes);
@@ -110,11 +101,11 @@ class ByteStreamW {
110
101
  break;
111
102
  case 6:
112
103
  this._setInt32(pos, value);
113
- this._setInt16(pos + 4, value / 0x10000000);
104
+ this._setInt16(pos + 4, Math.floor(value / 0x100000000));
114
105
  break;
115
106
  case 8:
116
107
  this._setInt32(pos, value);
117
- this._setInt32(pos + 4, value / 0x10000000);
108
+ this._setInt32(pos + 4, Math.floor(value / 0x100000000));
118
109
  break;
119
110
  default: throw ("Wrong byte length: " + bytes);
120
111
  }
@@ -259,10 +250,10 @@ class ByteStreamR_ {
259
250
  switch (bytes) {
260
251
  case 1: return view.getInt8(pos);
261
252
  case 2: return view.getInt16(pos);
262
- case 3: return view.getInt16(pos) | (view.getInt8(pos + 2) << 16);
253
+ case 3: return view.getUint16(pos) + (view.getInt8(pos + 2) << 16);
263
254
  case 4: return view.getInt32(pos);
264
- case 6: return view.getInt32(pos) | view.getInt16(pos + 4) * 0x10000000;
265
- case 8: return view.getInt32(pos) | view.getInt32(pos + 4) * 0x10000000;
255
+ case 6: return view.getUint32(pos) + view.getInt16(pos + 4) * 0x100000000;
256
+ case 8: return view.getUint32(pos) + view.getInt32(pos + 4) * 0x100000000;
266
257
  }
267
258
  }
268
259
  else {
@@ -271,8 +262,8 @@ class ByteStreamR_ {
271
262
  case 2: return view.getUint16(pos);
272
263
  case 3: return view.getUint16(pos) | (view.getUint8(pos + 2) << 16);
273
264
  case 4: return view.getUint32(pos);
274
- case 6: return view.getUint32(pos) | view.getUint16(pos + 4) * 0x10000000;
275
- case 8: return view.getUint32(pos) | view.getUint32(pos + 4) * 0x10000000;
265
+ case 6: return view.getUint32(pos) + view.getUint16(pos + 4) * 0x100000000;
266
+ case 8: return view.getUint32(pos) + view.getUint32(pos + 4) * 0x100000000;
276
267
  }
277
268
  }
278
269
  }
@@ -30,7 +30,7 @@ export declare class CList<T, TNode extends ListNode<T> = ListNode<T>> implement
30
30
  values(): Generator<T, void, unknown>;
31
31
  reversedNodes(): Generator<TNode, void, unknown>;
32
32
  reversedValues(): Generator<T, void, unknown>;
33
- entries(): Generator<never, () => Generator<TNode, void, unknown>, unknown>;
33
+ entries(): Generator<readonly [number, T], void, unknown>;
34
34
  next(node: ListNode<T>): TNode | undefined;
35
35
  prev(node: ListNode<T>): TNode | undefined;
36
36
  find(value: T): TNode | undefined;
@@ -29,7 +29,8 @@ class CList {
29
29
  yield node; }
30
30
  *reversedValues() { for (let node of this.reversedNodes())
31
31
  yield node.value; }
32
- *entries() { return this.nodes; }
32
+ *entries() { let i = 0; for (let node of this.nodes())
33
+ yield [i++, node.value]; }
33
34
  next(node) { return this.validateNode(node) ? node.next : (() => { throw "Wrong node list"; })(); }
34
35
  ;
35
36
  prev(node) { return this.validateNode(node) ? node.prev : (() => { throw "Wrong node list"; })(); }
@@ -102,7 +103,16 @@ class CList {
102
103
  let newNode = this.newNode(value);
103
104
  newNode.next = node.next;
104
105
  newNode.prev = node.prev;
106
+ if (node.prev)
107
+ node.prev.next = newNode;
108
+ else
109
+ this._first = newNode;
110
+ if (node.next)
111
+ node.next.prev = newNode;
112
+ else
113
+ this._last = newNode;
105
114
  node.list = undefined;
115
+ node.next = node.prev = undefined;
106
116
  this._immutableList = undefined;
107
117
  return newNode;
108
118
  }
@@ -135,7 +145,10 @@ class CList {
135
145
  this.delete(this._last); }
136
146
  clear() {
137
147
  for (let node = this._first; node != null; node = node.next)
138
- this.delete(node);
148
+ node.list = undefined;
149
+ this._first = this._last = undefined;
150
+ this._count = 0;
151
+ this._immutableList = undefined;
139
152
  }
140
153
  validateNode(node) {
141
154
  if (!(node instanceof CListNode))
@@ -73,7 +73,7 @@ class CListNodeAnd extends CBaseList {
73
73
  AddEnd(a) { return this._stop ? this.AddPrev(a) : this._End().AddNext(a); }
74
74
  AddStart(a) { return this._stop ? this.AddNext(a) : this._First().AddPrev(a); }
75
75
  forEach(el) {
76
- for (let buf = this.First(); buf?.data && !buf.isForbidden();) {
76
+ for (let buf = this.First(); buf && !buf.isForbidden();) {
77
77
  let t = buf.Next();
78
78
  el(buf.data, buf);
79
79
  buf = t;
@@ -19,6 +19,7 @@ function funcListenCallbackSnapshot({ func, memo = {}, callbackSave, snapshot })
19
19
  if (type == "remove" && count == 0) {
20
20
  api.close();
21
21
  d?.();
22
+ d = null;
22
23
  }
23
24
  if (type == "add" && count == 1)
24
25
  api.run();
@@ -16,15 +16,20 @@ class CObjectEventsArr {
16
16
  }
17
17
  console.error("элемент уже был удален");
18
18
  console.trace();
19
- data.OnDel?.();
20
19
  console.log(this.count());
21
20
  };
22
21
  }
23
22
  AddStart(data) { this.data.unshift(data); this.setup(this.data[0]); }
24
23
  AddEnd(data) { this.setup(this.data[this.data.push(data) - 1]); }
25
24
  Add(data) { this.setup(this.data[this.data.push(data) - 1]); }
26
- OnEvent(data) { [...this.data].forEach((e) => { e.func?.(data); e.func2?.(data); }); }
27
- OnSpecEvent(f) { [...this.data].forEach((e) => { const l = e.func?.(); l && f(l); e.func2?.(); }); }
25
+ OnEvent(data) { [...this.data].forEach((e) => { e.func?.(data); if (e.func2) {
26
+ e.func2(data);
27
+ e.del?.();
28
+ } }); }
29
+ OnSpecEvent(f) { [...this.data].forEach((e) => { const l = e.func?.(); l && f(l); if (e.func2) {
30
+ e.func2();
31
+ e.del?.();
32
+ } }); }
28
33
  Clean() {
29
34
  const a = [...this.data];
30
35
  this.data = [];
@@ -62,10 +67,16 @@ class CObjectEventsList {
62
67
  AddStart(data) { this.setup(this.data.AddStart(data)); }
63
68
  AddEnd(data) { this.setup(this.data.AddEnd(data)); }
64
69
  Add(data) { this.setup(this.data.AddEnd(data)); }
65
- OnEvent(data) { this.data.forEach(e => { e.func?.(data); e.func2?.(data); }); }
66
- OnSpecEvent(f) { this.data.forEach((e) => { const l = e.func?.(); if (l) {
70
+ OnEvent(data) { const a = []; this.data.forEach(e => a.push(e)); a.forEach(e => { e.func?.(data); if (e.func2) {
71
+ e.func2(data);
72
+ e.del?.();
73
+ } }); }
74
+ OnSpecEvent(f) { const a = []; this.data.forEach(e => a.push(e)); a.forEach((e) => { const l = e.func?.(); if (l) {
67
75
  f(l);
68
- } e.func2?.(); }); }
76
+ } if (e.func2) {
77
+ e.func2();
78
+ e.del?.();
79
+ } }); }
69
80
  Clean() { let r = this.data.First(); while (r) {
70
81
  const buf = r;
71
82
  r = r?.Next();
@@ -21,14 +21,17 @@ function joinListens(listens, keyExtractor) {
21
21
  bucket.clear();
22
22
  set(result, tid);
23
23
  };
24
+ const unsubs = [];
24
25
  const bindPort = (portId, listener) => {
25
- listener.addListen((...data) => {
26
+ const cb = (...data) => {
26
27
  const tid = getKey(data[0]);
27
28
  if (!buckets.has(tid))
28
29
  buckets.set(tid, new Map());
29
30
  buckets.get(tid).set(portId, data.length <= 1 ? data[0] : data);
30
31
  tryFire(tid);
31
- });
32
+ };
33
+ listener.addListen(cb);
34
+ unsubs.push(() => listener.removeListen(cb));
32
35
  };
33
36
  for (const portId of keys) {
34
37
  bindPort(portId, map[portId]);
@@ -39,7 +42,11 @@ function joinListens(listens, keyExtractor) {
39
42
  clear: (tid) => {
40
43
  tid ? buckets.delete(tid) : buckets.clear();
41
44
  },
42
- destroy: (tid) => {
45
+ destroy: (_tid) => {
46
+ for (const u of unsubs)
47
+ u();
48
+ unsubs.length = 0;
49
+ buckets.clear();
43
50
  },
44
51
  addListen: (listener, key) => {
45
52
  const portId = isArray ? String(keys.length) : (key ?? String(keys.length));
@@ -13,7 +13,6 @@ export declare function funcTimeW(): {
13
13
  add(item: tFunc): void;
14
14
  cleanByTime(type: tType, ms?: number): void;
15
15
  weight(type: tType, ms?: number): number;
16
- weightNow(type: tType, ms?: number): number;
17
16
  byWeight(type: tType, weight?: number): number;
18
17
  byWeightTimeNow(type: tType, timeNow?: number, weight?: number): number;
19
18
  };
@@ -25,7 +24,6 @@ export declare const FuncTimeWait: {
25
24
  add(item: tFunc): void;
26
25
  cleanByTime(type: tType, ms?: number): void;
27
26
  weight(type: tType, ms?: number): number;
28
- weightNow(type: tType, ms?: number): number;
29
27
  byWeight(type: tType, weight?: number): number;
30
28
  byWeightTimeNow(type: tType, timeNow?: number, weight?: number): number;
31
29
  };
@@ -47,24 +47,6 @@ function funcTimeW() {
47
47
  }
48
48
  return sum;
49
49
  },
50
- weightNow(type, ms = 60 * 1000) {
51
- const arr = dStatic[type];
52
- if (!arr || arr.length === 0)
53
- return 0;
54
- const timeStamp = Date.now();
55
- let sum = 0;
56
- let i = arr.length - 1;
57
- for (; i >= 0; i--) {
58
- const [_time, _weight] = arr[i];
59
- if (_time < timeStamp - ms)
60
- break;
61
- sum += _weight;
62
- }
63
- if (i >= 0) {
64
- arr.splice(0, i + 1);
65
- }
66
- return sum;
67
- },
68
50
  byWeight(type, weight = 50000) {
69
51
  const arr = dStatic[type];
70
52
  if (!arr || arr.length === 0)
@@ -75,7 +57,7 @@ function funcTimeW() {
75
57
  for (; i >= 0; i--) {
76
58
  sum += arr[i][1];
77
59
  if (sum > weight) {
78
- result = arr[i + 1]?.[0] ?? 0;
60
+ result = arr[i + 1]?.[0] ?? arr[i][0];
79
61
  break;
80
62
  }
81
63
  }
@@ -100,7 +82,7 @@ function funcTimeW() {
100
82
  for (; i >= 0; i--) {
101
83
  sum += arr[i][1];
102
84
  if (sum > weight) {
103
- result = arr[i + 1]?.[0] ?? 0;
85
+ result = arr[i + 1]?.[0] ?? arr[i][0];
104
86
  break;
105
87
  }
106
88
  }
@@ -3,10 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createIdPool = void 0;
4
4
  const createIdPool = () => {
5
5
  const s = [];
6
+ const free = new Set();
6
7
  let n = 0;
7
8
  return {
8
- next: () => s.length > 0 ? s.pop() : ++n,
9
- release(id) { s.push(id); }
9
+ next: () => {
10
+ const id = s.length > 0 ? s.pop() : ++n;
11
+ free.delete(id);
12
+ return id;
13
+ },
14
+ release(id) {
15
+ if (id < 1 || id > n || free.has(id))
16
+ return;
17
+ free.add(id);
18
+ s.push(id);
19
+ }
10
20
  };
11
21
  };
12
22
  exports.createIdPool = createIdPool;
@@ -30,14 +30,14 @@ function SetAutoStepForElement(element, params = { maxStep: 1 }) {
30
30
  _digits = digits;
31
31
  _step = step;
32
32
  if (_min != null) {
33
- if (Math.abs(_min) % step != 0)
33
+ if (Math.abs(_min) % step > 1e-9 && step - Math.abs(_min) % step > 1e-9)
34
34
  _min = Math.floor(Math.abs(_min) / step) * step * Math.sign(minDefault);
35
35
  element.min = _min + "";
36
36
  }
37
37
  element.step = step + "";
38
38
  return step;
39
39
  }
40
- let modeAuto = !_step || (_step < 1 && Math.log10(_step - Math.trunc(_step)) % 1 == 0);
40
+ let modeAuto = !_step || (_step < 1 && Math.abs(Math.log10(_step) - Math.round(Math.log10(_step))) < 1e-9);
41
41
  const modeAuto0 = modeAuto;
42
42
  if (modeAuto) {
43
43
  calculateStep((_step ? (Math.round(parseFloat(element.value) / _step) * _step) : element.value) + "");
@@ -5,6 +5,7 @@ type tCorrelationByBuffer = {
5
5
  export declare function CorrelationRollingByBuffer(data: tCorrelationByBuffer): {
6
6
  init(data: tCorrelationByBuffer): void;
7
7
  clear(data?: tCorrelationByBuffer): void;
8
+ remove(key1: any, key2?: any): void;
8
9
  corr2(val1: number, val2: number, key1: any, key2: any): {
9
10
  corr: number;
10
11
  };
@@ -26,8 +26,14 @@ function CorrelationRollingByBuffer(data) {
26
26
  if (data)
27
27
  this.init(data);
28
28
  },
29
+ remove(key1, key2) {
30
+ if (key2 === undefined)
31
+ map.delete(key1);
32
+ else
33
+ map.get(key1)?.delete(key2);
34
+ },
29
35
  corr2(val1, val2, key1, key2) {
30
- const buffer = setting.bufferOn ? getBuffer(key1, key2) : defBuf();
36
+ const buffer = getBuffer(key1, key2);
31
37
  buffer.history1.push(val1);
32
38
  buffer.history2.push(val2);
33
39
  let dropped1 = 0;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  function PriceTOSumPercent(price) {
3
- return price.map(e => e / price[0]);
3
+ const base = price[0];
4
+ return base ? price.map(e => e / base) : price.map(() => 0);
4
5
  }
5
6
  function strategyStepOfStepAll(symbols_) {
6
7
  const symbols = symbols_.map(e => ({ price: PriceTOSumPercent(e.price), key: e.key }));
@@ -22,7 +22,8 @@ function strategyStepOfStepAllL(symbols) {
22
22
  return result;
23
23
  }
24
24
  function PriceTOSumPercentL(price) {
25
- return price.map(e => e / price[0]);
25
+ const base = price[0];
26
+ return base ? price.map(e => e / base) : price.map(() => 0);
26
27
  }
27
28
  function strategyStepOfStepL({ t1, t2, minK: _minK, percentM: _percentM, onlyBuy: _onlyBuy }) {
28
29
  const onlyBuy = !!_onlyBuy;
@@ -62,6 +63,6 @@ function strategyStepOfStepL({ t1, t2, minK: _minK, percentM: _percentM, onlyBuy
62
63
  }
63
64
  }
64
65
  const k1 = day.profitDays / result1.length;
65
- const k2 = day.profit / ((day.profit + day.loss) || 1);
66
+ const k2 = day.profit / ((day.profit + Math.abs(day.loss)) || 1);
66
67
  return k1 * k2;
67
68
  }
@@ -30,12 +30,7 @@ function deepMapByKeysList(obj1, keys, func) {
30
30
  return Object.fromEntries(Object.entries(obj1).map(([k, v]) => [k, deepMapByKeysList(v, keys, func)]));
31
31
  }
32
32
  function deepMapByKeys(obj1, obj2, func) {
33
- if (isLeafValue(obj1))
34
- return obj1;
35
- const keys = Object.keys(obj2);
36
- if (matchKeysList(obj1, keys))
37
- return func(obj1);
38
- return Object.fromEntries(Object.entries(obj1).map(([k, v]) => [k, deepMapByKeysList(v, keys, func)]));
33
+ return deepMapByKeysList(obj1, Object.keys(obj2), func);
39
34
  }
40
35
  const NOOP_LISTEN = (0, Listen_1.funcListenCallbackBase)((_e) => { });
41
36
  function deepListenFirst(obj, data) {
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1,79 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const express_1 = __importDefault(require("express"));
7
+ const http_1 = require("http");
8
+ const socket_io_1 = require("socket.io");
9
+ const socket_io_client_1 = require("socket.io-client");
10
+ const rpc_clientHub_1 = require("./rpc-clientHub");
11
+ const rpc_server_auto_1 = require("./rpc-server-auto");
12
+ const Listen_1 = require("../events/Listen");
13
+ const common_1 = require("../core/common");
14
+ const facade = () => {
15
+ return {
16
+ math: {
17
+ add: async (a, b) => a + b,
18
+ multiply: async (a, b) => a * b,
19
+ callback: async (a) => {
20
+ for (let i = 0; i < 100; i++) {
21
+ await (0, common_1.sleepAsync)(50);
22
+ a.callback({ a: new Date(), b: new Date(Date.now() - 100000) }, 43);
23
+ }
24
+ },
25
+ },
26
+ greet: async (name) => {
27
+ console.log('get ' + name);
28
+ return false;
29
+ },
30
+ date: async (date) => {
31
+ await (0, common_1.sleepAsync)(1000);
32
+ return ({ msg: `Hello!`, map: new Map([['ds', 43]]), youDate: date, now: new Date() });
33
+ },
34
+ };
35
+ };
36
+ async function startServer(port) {
37
+ const app = (0, express_1.default)();
38
+ const httpServer = (0, http_1.createServer)(app);
39
+ const ioServer = new socket_io_1.Server(httpServer);
40
+ ioServer.on('connection', (socket) => {
41
+ console.log('[server] клиент подключился');
42
+ const [disconnect, disconnectListen] = (0, Listen_1.UseListen)();
43
+ socket.on('disconnect', disconnect);
44
+ (0, rpc_server_auto_1.createRpcServerAuto)({
45
+ socket: {
46
+ emit: (key, data) => socket.emit(key, data),
47
+ on: (key, cb) => socket.on(key, cb),
48
+ },
49
+ socketKey: 'rpc',
50
+ object: facade(),
51
+ disconnectListen,
52
+ debug: true,
53
+ });
54
+ });
55
+ await new Promise((resolve) => httpServer.listen(port, resolve));
56
+ console.log(`[server] слушает :${port}`);
57
+ return httpServer;
58
+ }
59
+ async function startClient(port) {
60
+ const hub = (0, rpc_clientHub_1.createRpcClientHub)(() => (0, socket_io_client_1.io)(`http://localhost:${port}`, { transports: ['websocket'], forceNew: true }), (r) => ({ api: r('rpc') }));
61
+ const clients = await hub.setToken(null);
62
+ console.log('[client] подключились, ждём схему...');
63
+ clients.api.api.log(true);
64
+ await clients.api.readyStrict();
65
+ console.log('[client] схема получена, schema:', clients.api.schema());
66
+ return { hub, clients };
67
+ }
68
+ async function runTest() {
69
+ const PORT = 4020;
70
+ const httpServer = await startServer(PORT);
71
+ const { hub, clients } = await startClient(PORT);
72
+ const api = clients.api.func;
73
+ console.log('test World');
74
+ const greetResult = await api.greet('World');
75
+ console.log('[test] greet("World") =', greetResult);
76
+ hub.socket?.disconnect?.();
77
+ httpServer.close(() => console.log('[server] остановлен'));
78
+ }
79
+ runTest().catch(console.error);
@@ -159,7 +159,7 @@ class IBars {
159
159
  return;
160
160
  let ibar = timeStart ? this.indexOf(timeStart, "greatOrEqual") : 0;
161
161
  timeEnd ??= this.lastTime;
162
- for (let i = ibar; this.data[i].time <= timeEnd; i++)
162
+ for (let i = ibar; i < this.length && this.data[i].time <= timeEnd; i++)
163
163
  yield this.data[i];
164
164
  }
165
165
  getArray(startTime, lastTime) {
@@ -193,7 +193,7 @@ class IBars {
193
193
  let ilast = 0;
194
194
  let n = 0;
195
195
  for (let i = 1; i <= count; i++) {
196
- let bartime = i < count ? src.time(i) : new Date(2100, 1, 1);
196
+ let bartime = i < count ? src.time(i) : new Date(2100, 0, 1);
197
197
  if (endDayTime_s && bartime.valueOf() % Time_1.D1_MS >= endDayTime_s * 1000 % Time_1.D1_MS)
198
198
  continue;
199
199
  if (bartime >= nextPeriodTime) {
@@ -350,6 +350,8 @@ class CBarsMutableBase extends CBarsBase {
350
350
  this._data = [];
351
351
  Object.freeze(bar);
352
352
  this.data[i] = bar;
353
+ if (this._tickSizeAuto)
354
+ this._ticksize = 0;
353
355
  return true;
354
356
  }
355
357
  AddTicks(ticks) { for (let tick of ticks)
@@ -370,7 +372,7 @@ function CreateRandomBars(tf, startTime, endTimeOrCount, startPrice = 100, volat
370
372
  if (!tf || tf.msec == 0)
371
373
  return null;
372
374
  console.log("Creating bars with parameters: ", ...([...arguments].map(arg => arg instanceof Time_1.TF ? arg.name : arg)));
373
- const tickSizeNum = tickSize ?? 10 ** Math.min(Math.round(Math.log10(startPrice) - 4), 0);
375
+ const tickSizeNum = tickSize ?? 10 ** Math.min(Math.round(Math.log10(startPrice > 0 ? startPrice : 1) - 4), 0);
374
376
  let period = new Time_1.Period(tf);
375
377
  let count;
376
378
  if (typeof endTimeOrCount == "number")
@@ -37,7 +37,7 @@ function isSimpleParams2(params) {
37
37
  let t = false;
38
38
  for (let key in params) {
39
39
  const tr = params[key]["value"];
40
- if (!tr)
40
+ if (tr == null)
41
41
  return true;
42
42
  else {
43
43
  if (typeof tr == "object") {
@@ -256,7 +256,7 @@ class CQuotesHistoryMutable extends CQuotesHistory {
256
256
  let tf = Bars_1.TF.S1;
257
257
  let oldBars = this._GetBars(tf);
258
258
  let newbarsArr;
259
- if (oldBars && oldBars.count > 0 && Bars_1.Period.StartTime(tf, time) == oldBars.lastTime)
259
+ if (oldBars && oldBars.count > 0 && Bars_1.Period.StartTime(tf, time).valueOf() == oldBars.lastTime.valueOf())
260
260
  newbarsArr = [oldBars.last];
261
261
  let newbars = new Bars_1.CBarsMutable(tf, newbarsArr);
262
262
  if (!newbars.AddTicks(ticks))
@@ -12,6 +12,7 @@ interface WebhookClientOptions {
12
12
  renewIntervalMs?: number;
13
13
  app?: Express;
14
14
  }
15
+ export declare const buildSelfWebhookUrl: (clientIp: string, raw: unknown) => string | null;
15
16
  export declare const apiSaveData: {
16
17
  loadSubscribers: () => Map<string, Subscriber>;
17
18
  saveSubscribers: (subs: Map<string, Subscriber>) => void;
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.createWebhookClient = exports.createWebhookServer = exports.apiSaveData = void 0;
39
+ exports.createWebhookClient = exports.createWebhookServer = exports.apiSaveData = exports.buildSelfWebhookUrl = void 0;
40
40
  const express_1 = __importDefault(require("express"));
41
41
  const axios_1 = __importDefault(require("axios"));
42
42
  const fs = __importStar(require("fs"));
@@ -61,6 +61,19 @@ const saveSubscribers = (subs) => {
61
61
  Queue.enqueue(() => fs.promises.writeFile(SUBSCRIBERS_FILE, JSON.stringify(obj, null, 2), 'utf-8'));
62
62
  };
63
63
  const normalizeIP = (ip) => ip?.startsWith('::ffff:') ? ip.slice(7) : ip;
64
+ const buildSelfWebhookUrl = (clientIp, raw) => {
65
+ if (typeof raw !== 'string' || !raw)
66
+ return null;
67
+ let u;
68
+ try {
69
+ u = new URL('http://' + clientIp + raw);
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ return u.hostname === clientIp ? u.toString() : null;
75
+ };
76
+ exports.buildSelfWebhookUrl = buildSelfWebhookUrl;
64
77
  exports.apiSaveData = { loadSubscribers, saveSubscribers };
65
78
  const createWebhookServer = (params) => {
66
79
  const app = params.app ?? (0, express_1.default)();
@@ -90,24 +103,23 @@ const createWebhookServer = (params) => {
90
103
  const renewExpiry = () => new Date(Date.now() + 3 * 24 * 3600_000);
91
104
  app.post('/webHook_subscribe', checkAuth, (req, res) => {
92
105
  const { tag } = req.body;
93
- if (!req.body.url || typeof req.body.url !== 'string' || typeof tag !== 'string') {
106
+ const url = (0, exports.buildSelfWebhookUrl)(normalizeIP(req.ip ?? '127.0.0.1'), req.body.url);
107
+ if (!url || typeof tag !== 'string') {
94
108
  res.status(400).json({ error: 'Неверный запрос' });
95
109
  return;
96
110
  }
97
111
  purgeExpired();
98
- const url = new URL(clientAddr(req) + req.body.url).toString();
99
112
  subscribers.set(url, { url, tag, expireAt: renewExpiry() });
100
113
  file.saveSubscribers(subscribers);
101
114
  res.json({ message: 'Подписка оформлена' });
102
115
  });
103
116
  app.get('/webHook_status', checkAuth, (req, res) => {
104
- const rawUrl = req.query['url'];
105
- if (!rawUrl || typeof rawUrl !== 'string') {
117
+ const url = (0, exports.buildSelfWebhookUrl)(normalizeIP(req.ip ?? '127.0.0.1'), req.query['url']);
118
+ if (!url) {
106
119
  res.status(400).json({ error: 'Неверный запрос' });
107
120
  return;
108
121
  }
109
122
  purgeExpired();
110
- const url = new URL(clientAddr(req) + rawUrl).toString();
111
123
  const subscriber = Array.from(subscribers.values()).find(s => s.url === url);
112
124
  if (!subscriber) {
113
125
  res.json({ subscribed: false });
@@ -118,7 +130,11 @@ const createWebhookServer = (params) => {
118
130
  res.json({ subscribed: true, expireAt: subscriber.expireAt });
119
131
  });
120
132
  app.delete('/webHook_unsubscribe', checkAuth, (req, res) => {
121
- const url = new URL(clientAddr(req) + req.body.url).toString();
133
+ const url = (0, exports.buildSelfWebhookUrl)(normalizeIP(req.ip ?? '127.0.0.1'), req.body.url);
134
+ if (!url) {
135
+ res.status(400).json({ error: 'Неверный запрос' });
136
+ return;
137
+ }
122
138
  const key = Array.from(subscribers.keys()).find(k => subscribers.get(k)?.url === url);
123
139
  if (key && subscribers.delete(key)) {
124
140
  file.saveSubscribers(subscribers);
@@ -57,20 +57,37 @@ function saveKeyValue({ dirDef = "", key: _key = "" }) {
57
57
  .then(() => true)
58
58
  .catch(() => false);
59
59
  }
60
+ let _tmpSeq = 0;
60
61
  async function set({ key = _key, obj, path = "" }) {
61
62
  const filePath = await resolvePath(path, key);
62
- await fs.promises.writeFile(filePath, obj);
63
+ const tmp = `${filePath}.${++_tmpSeq}.tmp`;
64
+ await fs.promises.writeFile(tmp, obj);
65
+ await fs.promises.rename(tmp, filePath);
63
66
  }
64
67
  async function setElMap({ key = _key, keyEl, valueEl, path = "" }) {
65
68
  const exists = await has({ key, path });
66
- const data = exists ? JSON.parse(await get({ key, path })) : {};
69
+ let data = {};
70
+ if (exists) {
71
+ try {
72
+ data = JSON.parse(await get({ key, path }));
73
+ }
74
+ catch {
75
+ data = {};
76
+ }
77
+ }
67
78
  data[keyEl] = valueEl;
68
79
  await set({ key, obj: JSON.stringify(data), path });
69
80
  }
70
81
  async function delEl({ key = _key, keyEl, path = "" }) {
71
82
  if (!(await has({ key, path })))
72
83
  throw new Error(`Файл не найден: ${path}${key}`);
73
- const data = JSON.parse(await get({ key, path }));
84
+ let data = {};
85
+ try {
86
+ data = JSON.parse(await get({ key, path }));
87
+ }
88
+ catch {
89
+ data = {};
90
+ }
74
91
  delete data[keyEl];
75
92
  await set({ key, obj: JSON.stringify(data), path });
76
93
  return true;
@@ -1,5 +1,24 @@
1
+ export declare class MyError<D = unknown> extends Error {
2
+ readonly code: string;
3
+ readonly data: D;
4
+ name: string;
5
+ constructor(message: string, code?: string, data?: D, cause?: unknown);
6
+ toJSON(): {
7
+ name: string;
8
+ message: string;
9
+ code: string;
10
+ data: D;
11
+ stack: string | undefined;
12
+ };
13
+ static wrap(e: unknown): Error;
14
+ static fromWire<D>(w: tWire<D>): MyError<D> & {
15
+ name: string;
16
+ stack: string | undefined;
17
+ };
18
+ }
19
+ export type tWire<D = unknown> = ReturnType<MyError<D>['toJSON']>;
1
20
  export declare const toError: {
2
21
  convert: any;
3
- throw(e: any): never;
22
+ throw(e: any): void;
4
23
  convertToMsg(e: any): any;
5
24
  };
@@ -1,23 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toError = void 0;
4
- exports.toError = {
5
- set convert(e) {
6
- if (e instanceof Error) {
7
- throw e;
8
- }
9
- throw new Error(JSON.stringify(e));
10
- },
11
- throw(e) {
12
- if (e instanceof Error) {
13
- throw e;
14
- }
15
- throw new Error(JSON.stringify(e));
16
- },
17
- convertToMsg(e) {
18
- if (e instanceof Error) {
19
- return e;
20
- }
21
- return e;
3
+ exports.toError = exports.MyError = void 0;
4
+ class MyError extends Error {
5
+ code;
6
+ data;
7
+ name = 'MyError';
8
+ constructor(message, code = 'ERR', data = {}, cause) {
9
+ super(message);
10
+ this.code = code;
11
+ this.data = data;
12
+ if (cause != undefined)
13
+ this.cause = cause;
14
+ }
15
+ toJSON() {
16
+ const { name, message, code, data, stack } = this;
17
+ return { name, message, code, data, stack };
18
+ }
19
+ static wrap(e) {
20
+ return e instanceof Error ? e : new MyError(typeof e == 'string' ? e : JSON.stringify(e), 'ERR', { value: e });
22
21
  }
22
+ static fromWire(w) {
23
+ return Object.assign(new MyError(w.message, w.code, w.data), { name: w.name, stack: w.stack });
24
+ }
25
+ }
26
+ exports.MyError = MyError;
27
+ const legacyThrow = (e) => {
28
+ if (e instanceof Error)
29
+ throw e;
30
+ throw new Error(JSON.stringify(e));
31
+ };
32
+ exports.toError = {
33
+ set convert(e) { legacyThrow(e); },
34
+ throw(e) { legacyThrow(e); },
35
+ convertToMsg(e) { return e; },
23
36
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wenay-common2",
3
- "version": "1.0.45",
3
+ "version": "1.0.46",
4
4
  "description": "Common library",
5
5
  "strict": true,
6
6
  "main": "lib/index.js",
@@ -1,5 +0,0 @@
1
- export declare const toError: {
2
- convert: any;
3
- throw(e: any): never;
4
- convertToMsg(e: any): any;
5
- };
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toError = void 0;
4
- exports.toError = {
5
- set convert(e) {
6
- if (e instanceof Error) {
7
- throw e;
8
- }
9
- throw new Error(JSON.stringify(e));
10
- },
11
- throw(e) {
12
- if (e instanceof Error) {
13
- throw e;
14
- }
15
- throw new Error(JSON.stringify(e));
16
- },
17
- convertToMsg(e) {
18
- if (e instanceof Error) {
19
- return e;
20
- }
21
- return e;
22
- }
23
- };