@quantform/core 0.7.22 → 0.7.25

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 (195) hide show
  1. package/lib/app.d.ts +12 -0
  2. package/lib/app.d.ts.map +1 -0
  3. package/lib/app.js +35 -0
  4. package/lib/cli/build.d.ts.map +1 -1
  5. package/lib/cli/build.js +8 -18
  6. package/lib/cli/index.js +3 -12
  7. package/lib/cli/internal/script.d.ts +1 -1
  8. package/lib/cli/internal/script.d.ts.map +1 -1
  9. package/lib/cli/internal/script.js +8 -28
  10. package/lib/cli/live.js +10 -22
  11. package/lib/cli/paper.js +10 -22
  12. package/lib/cli/replay.d.ts.map +1 -1
  13. package/lib/cli/replay.js +15 -26
  14. package/lib/index.d.ts +1 -6
  15. package/lib/index.d.ts.map +1 -1
  16. package/lib/index.js +1 -6
  17. package/lib/make-test-module.d.ts +1 -6
  18. package/lib/make-test-module.d.ts.map +1 -1
  19. package/lib/make-test-module.js +19 -30
  20. package/lib/module.d.ts.map +1 -1
  21. package/lib/module.js +9 -24
  22. package/lib/module.spec.js +8 -17
  23. package/lib/replay/use-replay-options.d.ts +5 -4
  24. package/lib/replay/use-replay-options.d.ts.map +1 -1
  25. package/lib/replay/use-replay-options.js +5 -1
  26. package/lib/replay/use-replay-scheduler.d.ts +7 -6
  27. package/lib/replay/use-replay-scheduler.d.ts.map +1 -1
  28. package/lib/replay/use-replay-scheduler.js +64 -70
  29. package/lib/replay/use-replay-storage-buffer.d.ts +3 -2
  30. package/lib/replay/use-replay-storage-buffer.d.ts.map +1 -1
  31. package/lib/replay/use-replay-storage-buffer.js +12 -23
  32. package/lib/replay/use-replay-storage-cursor.d.ts +9 -8
  33. package/lib/replay/use-replay-storage-cursor.d.ts.map +1 -1
  34. package/lib/replay/use-replay-storage-cursor.js +17 -25
  35. package/lib/replay/use-replay-storage.d.ts +5 -4
  36. package/lib/replay/use-replay-storage.d.ts.map +1 -1
  37. package/lib/replay/use-replay-storage.js +32 -39
  38. package/lib/session/use-session-storage.d.ts +1 -1
  39. package/lib/session/use-session-storage.d.ts.map +1 -1
  40. package/lib/session/use-session-storage.js +8 -5
  41. package/lib/shared/environment.js +1 -1
  42. package/lib/shared/index.d.ts +0 -1
  43. package/lib/shared/index.d.ts.map +1 -1
  44. package/lib/shared/index.js +0 -1
  45. package/lib/simulator/use-simulator.spec.js +17 -30
  46. package/lib/storage/in-memory/in-memory-storage.d.ts.map +1 -1
  47. package/lib/storage/in-memory/in-memory-storage.factory.js +2 -2
  48. package/lib/storage/in-memory/in-memory-storage.js +56 -55
  49. package/lib/storage/in-memory/in-memory-storage.spec.js +90 -100
  50. package/lib/storage/storage.d.ts +9 -8
  51. package/lib/storage/storage.d.ts.map +1 -1
  52. package/lib/storage/storage.js +8 -2
  53. package/lib/storage/use-cache.d.ts +1 -1
  54. package/lib/storage/use-cache.d.ts.map +1 -1
  55. package/lib/storage/use-cache.js +5 -5
  56. package/lib/storage/use-cache.spec.js +14 -25
  57. package/lib/storage/use-storage.d.ts +1 -1
  58. package/lib/storage/use-storage.d.ts.map +1 -1
  59. package/lib/storage/use-storage.js +9 -6
  60. package/lib/use-execution-mode.js +2 -2
  61. package/lib/use-hash.spec.js +3 -6
  62. package/lib/use-logger.d.ts +1 -1
  63. package/lib/use-logger.d.ts.map +1 -1
  64. package/lib/use-logger.js +10 -7
  65. package/lib/use-memo.spec.js +14 -25
  66. package/lib/use-socket.d.ts +3 -2
  67. package/lib/use-socket.d.ts.map +1 -1
  68. package/lib/use-socket.js +2 -2
  69. package/lib/use-timestamp.d.ts +14 -1
  70. package/lib/use-timestamp.d.ts.map +1 -1
  71. package/lib/use-timestamp.js +30 -3
  72. package/lib/with-request.d.ts +2 -1
  73. package/lib/with-request.d.ts.map +1 -1
  74. package/lib/with-request.js +4 -13
  75. package/package.json +6 -10
  76. package/src/app.ts +52 -0
  77. package/src/cli/build.ts +11 -6
  78. package/src/cli/internal/script.ts +25 -54
  79. package/src/cli/replay.ts +13 -2
  80. package/src/index.ts +1 -6
  81. package/src/make-test-module.ts +13 -21
  82. package/src/module.ts +0 -3
  83. package/src/replay/use-replay-options.ts +7 -3
  84. package/src/replay/use-replay-scheduler.ts +75 -67
  85. package/src/replay/use-replay-storage-buffer.ts +2 -1
  86. package/src/replay/use-replay-storage-cursor.ts +33 -28
  87. package/src/replay/use-replay-storage.ts +36 -27
  88. package/src/session/use-session-storage.ts +7 -5
  89. package/src/shared/index.ts +0 -1
  90. package/src/storage/in-memory/in-memory-storage.spec.ts +55 -54
  91. package/src/storage/in-memory/in-memory-storage.ts +24 -7
  92. package/src/storage/storage.ts +16 -7
  93. package/src/storage/use-cache.ts +4 -4
  94. package/src/storage/use-storage.ts +8 -6
  95. package/src/use-hash.spec.ts +3 -6
  96. package/src/use-logger.ts +9 -6
  97. package/src/use-socket.ts +5 -5
  98. package/src/use-timestamp.ts +41 -3
  99. package/src/with-request.ts +3 -3
  100. package/lib/asset/asset.d.ts +0 -41
  101. package/lib/asset/asset.d.ts.map +0 -1
  102. package/lib/asset/asset.js +0 -76
  103. package/lib/asset/asset.spec.d.ts +0 -2
  104. package/lib/asset/asset.spec.d.ts.map +0 -1
  105. package/lib/asset/asset.spec.js +0 -54
  106. package/lib/asset/index.d.ts +0 -2
  107. package/lib/asset/index.d.ts.map +0 -1
  108. package/lib/asset/index.js +0 -17
  109. package/lib/component/distinct-until-timesamp-changed.d.ts +0 -5
  110. package/lib/component/distinct-until-timesamp-changed.d.ts.map +0 -1
  111. package/lib/component/distinct-until-timesamp-changed.js +0 -9
  112. package/lib/component/error.d.ts +0 -17
  113. package/lib/component/error.d.ts.map +0 -1
  114. package/lib/component/error.js +0 -33
  115. package/lib/component/index.d.ts +0 -8
  116. package/lib/component/index.d.ts.map +0 -1
  117. package/lib/component/index.js +0 -23
  118. package/lib/component/ohlc-operator.d.ts +0 -11
  119. package/lib/component/ohlc-operator.d.ts.map +0 -1
  120. package/lib/component/ohlc-operator.js +0 -69
  121. package/lib/component/ohlc-operator.spec.d.ts +0 -2
  122. package/lib/component/ohlc-operator.spec.d.ts.map +0 -1
  123. package/lib/component/ohlc-operator.spec.js +0 -110
  124. package/lib/component/ohlc.d.ts +0 -12
  125. package/lib/component/ohlc.d.ts.map +0 -1
  126. package/lib/component/ohlc.js +0 -20
  127. package/lib/component/ohlc.spec.d.ts +0 -2
  128. package/lib/component/ohlc.spec.d.ts.map +0 -1
  129. package/lib/component/ohlc.spec.js +0 -25
  130. package/lib/component/timeframe.d.ts +0 -15
  131. package/lib/component/timeframe.d.ts.map +0 -1
  132. package/lib/component/timeframe.js +0 -21
  133. package/lib/core.d.ts +0 -3
  134. package/lib/core.d.ts.map +0 -1
  135. package/lib/core.js +0 -17
  136. package/lib/instrument/commission/commission.d.ts +0 -16
  137. package/lib/instrument/commission/commission.d.ts.map +0 -1
  138. package/lib/instrument/commission/commission.js +0 -28
  139. package/lib/instrument/commission/commission.spec.d.ts +0 -2
  140. package/lib/instrument/commission/commission.spec.d.ts.map +0 -1
  141. package/lib/instrument/commission/commission.spec.js +0 -30
  142. package/lib/instrument/index.d.ts +0 -3
  143. package/lib/instrument/index.d.ts.map +0 -1
  144. package/lib/instrument/index.js +0 -18
  145. package/lib/instrument/instrument.d.ts +0 -28
  146. package/lib/instrument/instrument.d.ts.map +0 -1
  147. package/lib/instrument/instrument.js +0 -53
  148. package/lib/instrument/instrument.spec.d.ts +0 -2
  149. package/lib/instrument/instrument.spec.d.ts.map +0 -1
  150. package/lib/instrument/instrument.spec.js +0 -51
  151. package/lib/operators.d.ts +0 -5
  152. package/lib/operators.d.ts.map +0 -1
  153. package/lib/operators.js +0 -16
  154. package/lib/shared/datetime.d.ts +0 -3
  155. package/lib/shared/datetime.d.ts.map +0 -1
  156. package/lib/shared/datetime.js +0 -7
  157. package/lib/strategy.d.ts +0 -15
  158. package/lib/strategy.d.ts.map +0 -1
  159. package/lib/strategy.js +0 -26
  160. package/lib/strategy.spec.d.ts +0 -2
  161. package/lib/strategy.spec.d.ts.map +0 -1
  162. package/lib/strategy.spec.js +0 -34
  163. package/lib/when-socket.d.ts +0 -8
  164. package/lib/when-socket.d.ts.map +0 -1
  165. package/lib/when-socket.js +0 -53
  166. package/lib/with-memo.d.ts +0 -5
  167. package/lib/with-memo.d.ts.map +0 -1
  168. package/lib/with-memo.js +0 -20
  169. package/lib/with-memo.spec.d.ts +0 -2
  170. package/lib/with-memo.spec.d.ts.map +0 -1
  171. package/lib/with-memo.spec.js +0 -47
  172. package/src/asset/asset.spec.ts +0 -70
  173. package/src/asset/asset.ts +0 -89
  174. package/src/asset/index.ts +0 -1
  175. package/src/component/distinct-until-timesamp-changed.ts +0 -11
  176. package/src/component/error.ts +0 -32
  177. package/src/component/index.ts +0 -7
  178. package/src/component/ohlc-operator.spec.ts +0 -125
  179. package/src/component/ohlc-operator.ts +0 -122
  180. package/src/component/ohlc.spec.ts +0 -30
  181. package/src/component/ohlc.ts +0 -18
  182. package/src/component/timeframe.ts +0 -17
  183. package/src/core.ts +0 -16
  184. package/src/instrument/commission/commission.spec.ts +0 -35
  185. package/src/instrument/commission/commission.ts +0 -27
  186. package/src/instrument/index.ts +0 -2
  187. package/src/instrument/instrument.spec.ts +0 -76
  188. package/src/instrument/instrument.ts +0 -65
  189. package/src/operators.ts +0 -18
  190. package/src/shared/datetime.ts +0 -5
  191. package/src/strategy.spec.ts +0 -42
  192. package/src/strategy.ts +0 -36
  193. package/src/when-socket.ts +0 -61
  194. package/src/with-memo.spec.ts +0 -46
  195. package/src/with-memo.ts +0 -33
@@ -1,5 +1,6 @@
1
1
  import { d } from '@lib/shared';
2
2
  import { eq, gt, lt, Storage } from '@lib/storage';
3
+ import { ns } from '@lib/use-timestamp';
3
4
 
4
5
  import { InMemoryStorage } from './in-memory-storage';
5
6
 
@@ -27,26 +28,26 @@ describe(InMemoryStorage.name, () => {
27
28
  const { sut } = fixtures;
28
29
 
29
30
  const pricing = Storage.createObject('pricing', {
30
- timestamp: 'number',
31
+ timestamp: 'bigint',
31
32
  rate: 'decimal'
32
33
  });
33
34
 
34
35
  await sut.save(pricing, [
35
- { timestamp: 1, rate: d(1) },
36
- { timestamp: 2, rate: d(2) },
37
- { timestamp: 3, rate: d(3) },
38
- { timestamp: 4, rate: d(4) },
39
- { timestamp: 5, rate: d(5) }
36
+ { timestamp: ns(1), rate: d(1) },
37
+ { timestamp: ns(2), rate: d(2) },
38
+ { timestamp: ns(3), rate: d(3) },
39
+ { timestamp: ns(4), rate: d(4) },
40
+ { timestamp: ns(5), rate: d(5) }
40
41
  ]);
41
42
 
42
43
  const set = await sut.query(pricing, {});
43
44
 
44
45
  expect(set).toEqual([
45
- { timestamp: 1, rate: d(1) },
46
- { timestamp: 2, rate: d(2) },
47
- { timestamp: 3, rate: d(3) },
48
- { timestamp: 4, rate: d(4) },
49
- { timestamp: 5, rate: d(5) }
46
+ { timestamp: ns(1), rate: d(1) },
47
+ { timestamp: ns(2), rate: d(2) },
48
+ { timestamp: ns(3), rate: d(3) },
49
+ { timestamp: ns(4), rate: d(4) },
50
+ { timestamp: ns(5), rate: d(5) }
50
51
  ]);
51
52
  });
52
53
 
@@ -54,24 +55,24 @@ describe(InMemoryStorage.name, () => {
54
55
  const { sut } = fixtures;
55
56
 
56
57
  const pricing = Storage.createObject('pricing', {
57
- timestamp: 'number',
58
+ timestamp: 'bigint',
58
59
  rate: 'decimal'
59
60
  });
60
61
 
61
62
  await sut.save(pricing, [
62
- { timestamp: 1, rate: d(1) },
63
- { timestamp: 2, rate: d(2) },
64
- { timestamp: 3, rate: d(3) },
65
- { timestamp: 4, rate: d(4) },
66
- { timestamp: 5, rate: d(5) }
63
+ { timestamp: ns(1), rate: d(1) },
64
+ { timestamp: ns(2), rate: d(2) },
65
+ { timestamp: ns(3), rate: d(3) },
66
+ { timestamp: ns(4), rate: d(4) },
67
+ { timestamp: ns(5), rate: d(5) }
67
68
  ]);
68
69
 
69
70
  const set = await sut.query(pricing, { limit: 3 });
70
71
 
71
72
  expect(set).toEqual([
72
- { timestamp: 1, rate: d(1) },
73
- { timestamp: 2, rate: d(2) },
74
- { timestamp: 3, rate: d(3) }
73
+ { timestamp: ns(1), rate: d(1) },
74
+ { timestamp: ns(2), rate: d(2) },
75
+ { timestamp: ns(3), rate: d(3) }
75
76
  ]);
76
77
  });
77
78
 
@@ -79,26 +80,26 @@ describe(InMemoryStorage.name, () => {
79
80
  const { sut } = fixtures;
80
81
 
81
82
  const pricing = Storage.createObject('pricing', {
82
- timestamp: 'number',
83
+ timestamp: 'bigint',
83
84
  rate: 'decimal'
84
85
  });
85
86
 
86
87
  await sut.save(pricing, [
87
- { timestamp: 1, rate: d(1) },
88
- { timestamp: 2, rate: d(2) },
89
- { timestamp: 3, rate: d(3) },
90
- { timestamp: 4, rate: d(4) },
91
- { timestamp: 5, rate: d(5) }
88
+ { timestamp: ns(1), rate: d(1) },
89
+ { timestamp: ns(2), rate: d(2) },
90
+ { timestamp: ns(3), rate: d(3) },
91
+ { timestamp: ns(4), rate: d(4) },
92
+ { timestamp: ns(5), rate: d(5) }
92
93
  ]);
93
94
 
94
95
  const set = await sut.query(pricing, { orderBy: 'DESC' });
95
96
 
96
97
  expect(set).toEqual([
97
- { timestamp: 5, rate: d(5) },
98
- { timestamp: 4, rate: d(4) },
99
- { timestamp: 3, rate: d(3) },
100
- { timestamp: 2, rate: d(2) },
101
- { timestamp: 1, rate: d(1) }
98
+ { timestamp: ns(5), rate: d(5) },
99
+ { timestamp: ns(4), rate: d(4) },
100
+ { timestamp: ns(3), rate: d(3) },
101
+ { timestamp: ns(2), rate: d(2) },
102
+ { timestamp: ns(1), rate: d(1) }
102
103
  ]);
103
104
  });
104
105
 
@@ -106,16 +107,16 @@ describe(InMemoryStorage.name, () => {
106
107
  const { sut } = fixtures;
107
108
 
108
109
  const pricing = Storage.createObject('pricing', {
109
- timestamp: 'number',
110
+ timestamp: 'bigint',
110
111
  rate: 'decimal'
111
112
  });
112
113
 
113
114
  await sut.save(pricing, [
114
- { timestamp: 1, rate: d(1) },
115
- { timestamp: 2, rate: d(2) },
116
- { timestamp: 3, rate: d(3) },
117
- { timestamp: 4, rate: d(4) },
118
- { timestamp: 5, rate: d(5) }
115
+ { timestamp: ns(1), rate: d(1) },
116
+ { timestamp: ns(2), rate: d(2) },
117
+ { timestamp: ns(3), rate: d(3) },
118
+ { timestamp: ns(4), rate: d(4) },
119
+ { timestamp: ns(5), rate: d(5) }
119
120
  ]);
120
121
 
121
122
  const set = await sut.query(pricing, {
@@ -124,23 +125,23 @@ describe(InMemoryStorage.name, () => {
124
125
  }
125
126
  });
126
127
 
127
- expect(set).toEqual([{ timestamp: 4, rate: d(4) }]);
128
+ expect(set).toEqual([{ timestamp: ns(4), rate: d(4) }]);
128
129
  });
129
130
 
130
131
  test('save and read filtered lt data', async () => {
131
132
  const { sut } = fixtures;
132
133
 
133
134
  const pricing = Storage.createObject('pricing', {
134
- timestamp: 'number',
135
+ timestamp: 'bigint',
135
136
  rate: 'decimal'
136
137
  });
137
138
 
138
139
  await sut.save(pricing, [
139
- { timestamp: 1, rate: d(1) },
140
- { timestamp: 2, rate: d(2) },
141
- { timestamp: 3, rate: d(3) },
142
- { timestamp: 4, rate: d(4) },
143
- { timestamp: 5, rate: d(5) }
140
+ { timestamp: ns(1), rate: d(1) },
141
+ { timestamp: ns(2), rate: d(2) },
142
+ { timestamp: ns(3), rate: d(3) },
143
+ { timestamp: ns(4), rate: d(4) },
144
+ { timestamp: ns(5), rate: d(5) }
144
145
  ]);
145
146
 
146
147
  const set = await sut.query(pricing, {
@@ -150,8 +151,8 @@ describe(InMemoryStorage.name, () => {
150
151
  });
151
152
 
152
153
  expect(set).toEqual([
153
- { timestamp: 1, rate: d(1) },
154
- { timestamp: 2, rate: d(2) }
154
+ { timestamp: ns(1), rate: d(1) },
155
+ { timestamp: ns(2), rate: d(2) }
155
156
  ]);
156
157
  });
157
158
 
@@ -159,16 +160,16 @@ describe(InMemoryStorage.name, () => {
159
160
  const { sut } = fixtures;
160
161
 
161
162
  const pricing = Storage.createObject('pricing', {
162
- timestamp: 'number',
163
+ timestamp: 'bigint',
163
164
  rate: 'decimal'
164
165
  });
165
166
 
166
167
  await sut.save(pricing, [
167
- { timestamp: 1, rate: d(1) },
168
- { timestamp: 2, rate: d(2) },
169
- { timestamp: 3, rate: d(3) },
170
- { timestamp: 4, rate: d(4) },
171
- { timestamp: 5, rate: d(5) }
168
+ { timestamp: ns(1), rate: d(1) },
169
+ { timestamp: ns(2), rate: d(2) },
170
+ { timestamp: ns(3), rate: d(3) },
171
+ { timestamp: ns(4), rate: d(4) },
172
+ { timestamp: ns(5), rate: d(5) }
172
173
  ]);
173
174
 
174
175
  const set = await sut.query(pricing, {
@@ -178,8 +179,8 @@ describe(InMemoryStorage.name, () => {
178
179
  });
179
180
 
180
181
  expect(set).toEqual([
181
- { timestamp: 4, rate: d(4) },
182
- { timestamp: 5, rate: d(5) }
182
+ { timestamp: ns(4), rate: d(4) },
183
+ { timestamp: ns(5), rate: d(5) }
183
184
  ]);
184
185
  });
185
186
  });
@@ -29,18 +29,35 @@ export class InMemoryStorage implements Storage {
29
29
 
30
30
  switch (expression?.type) {
31
31
  case 'eq':
32
- set = set.filter(it => it[prop] === expression.value);
32
+ set = set.filter(it => it[prop] == expression.value);
33
33
  break;
34
34
  case 'gt':
35
- set = set.filter(it => +it[prop] > expression.value);
35
+ set = set.filter(it => {
36
+ const value = it[prop];
37
+
38
+ return typeof value === 'bigint'
39
+ ? BigInt(value) > expression.value
40
+ : Number(value) > Number(expression.value);
41
+ });
36
42
  break;
37
43
  case 'lt':
38
- set = set.filter(it => +it[prop] < expression.value);
44
+ set = set.filter(it => {
45
+ const value = it[prop];
46
+
47
+ return typeof value === 'bigint'
48
+ ? BigInt(value) < expression.value
49
+ : Number(value) < Number(expression.value);
50
+ });
39
51
  break;
40
52
  case 'between':
41
- set = set.filter(
42
- it => +it[prop] > expression.min && +it[prop] < expression.max
43
- );
53
+ set = set.filter(it => {
54
+ const value = it[prop];
55
+
56
+ return typeof value === 'bigint'
57
+ ? BigInt(value) > expression.min && BigInt(value) < expression.max
58
+ : Number(value) > Number(expression.min) &&
59
+ Number(value) < Number(expression.max);
60
+ });
44
61
  break;
45
62
  }
46
63
  }
@@ -71,7 +88,7 @@ export class InMemoryStorage implements Storage {
71
88
  buffer.push(document);
72
89
  }
73
90
 
74
- buffer.sort((lhs, rhs) => lhs.timestamp - rhs.timestamp);
91
+ buffer.sort((lhs, rhs) => Number(lhs.timestamp - rhs.timestamp));
75
92
  }
76
93
 
77
94
  clear() {
@@ -1,17 +1,24 @@
1
1
  import { decimal } from '@lib/shared';
2
+ import { Timestamp } from '@lib/use-timestamp';
2
3
 
3
- type Types = string | number | decimal;
4
+ type Types = string | number | bigint | decimal;
4
5
 
5
6
  export const eq = <T extends Types>(value: T) => ({ type: 'eq' as const, value });
6
- export const gt = <T extends number>(value: T) => ({ type: 'gt' as const, value });
7
- export const lt = <T extends number>(value: T) => ({ type: 'lt' as const, value });
8
- export const between = <T extends number>(min: T, max: T) => ({
7
+ export const gt = <T extends number | bigint>(value: T) => ({
8
+ type: 'gt' as const,
9
+ value
10
+ });
11
+ export const lt = <T extends number | bigint>(value: T) => ({
12
+ type: 'lt' as const,
13
+ value
14
+ });
15
+ export const between = <T extends number | bigint>(min: T, max: T) => ({
9
16
  type: 'between' as const,
10
17
  min,
11
18
  max
12
19
  });
13
20
 
14
- export type QueryObject = Record<string, Types> & { timestamp: number };
21
+ export type QueryObject = Record<string, Types> & { timestamp: Timestamp<'ns'> };
15
22
  export type QueryObjectType<T extends QueryObject> = {
16
23
  discriminator: string;
17
24
  type: {
@@ -34,17 +41,19 @@ export type Query<T extends QueryObject> = {
34
41
  offset?: number;
35
42
  };
36
43
 
37
- export type QueryMappingType = 'number' | 'string' | 'decimal';
44
+ export type QueryMappingType = 'number' | 'bigint' | 'string' | 'decimal';
38
45
  export type InferQueryObject<T> = T extends QueryObjectType<infer U>
39
46
  ? {
40
47
  [key in keyof T['type']]: T['type'][key] extends 'number'
41
48
  ? number
49
+ : T['type'][key] extends 'bigint'
50
+ ? bigint
42
51
  : T['type'][key] extends 'string'
43
52
  ? string
44
53
  : T['type'][key] extends 'decimal'
45
54
  ? decimal
46
55
  : never;
47
- } & { timestamp: number }
56
+ } & { timestamp: Timestamp<'ns'> }
48
57
  : never;
49
58
 
50
59
  export abstract class Storage {
@@ -1,13 +1,13 @@
1
1
  import { from, map, Observable, of, switchMap } from 'rxjs';
2
2
 
3
- import { now } from '@lib/shared';
4
3
  import { useStorage } from '@lib/storage/use-storage';
5
4
  import { dependency, useHash } from '@lib/use-hash';
5
+ import { now } from '@lib/use-timestamp';
6
6
 
7
7
  import { eq, gt, Storage } from './storage';
8
8
 
9
9
  const object = Storage.createObject('keyValue', {
10
- timestamp: 'number',
10
+ timestamp: 'bigint',
11
11
  forKey: 'string',
12
12
  rawJson: 'string'
13
13
  });
@@ -15,7 +15,7 @@ const object = Storage.createObject('keyValue', {
15
15
  export const useCache = <T>(
16
16
  calculateValue: Observable<T>,
17
17
  dependencies: dependency[],
18
- ttl: number = 60 * 60 * 24 * 1000
18
+ ttl = BigInt(60 * 60 * 24 * 1000000)
19
19
  ): Observable<T> => {
20
20
  const storage = useStorage(['cache']);
21
21
  const key = useHash(dependencies);
@@ -24,7 +24,7 @@ export const useCache = <T>(
24
24
  return from(
25
25
  storage.query(object, {
26
26
  where: {
27
- timestamp: gt(timestamp - ttl),
27
+ timestamp: gt(timestamp - BigInt(ttl)),
28
28
  forKey: eq(key)
29
29
  },
30
30
  limit: 1,
@@ -1,11 +1,13 @@
1
1
  import { dependency, useHash } from '@lib/use-hash';
2
- import { withMemo } from '@lib/with-memo';
2
+ import { useMemo } from '@lib/use-memo';
3
3
 
4
4
  import { useStorageFactory } from './use-storage-factory';
5
5
 
6
- export const useStorage = withMemo((dependencies: dependency[]) => {
7
- const key = useHash(dependencies);
8
- const factory = useStorageFactory();
6
+ export function useStorage(dependencies: dependency[]) {
7
+ return useMemo(() => {
8
+ const key = useHash(dependencies);
9
+ const factory = useStorageFactory();
9
10
 
10
- return factory.for(key);
11
- });
11
+ return factory.for(key);
12
+ }, [dependencies]);
13
+ }
@@ -1,13 +1,10 @@
1
- import { assetOf } from './asset';
2
- import { instrumentOf } from './instrument';
3
1
  import { dependency, useHash } from './use-hash';
4
2
 
5
3
  describe(useHash.name, () => {
6
4
  it.each<[dependency[], string]>([
7
- [[assetOf('binance:btc')], 'binance:btc'],
8
- [[assetOf('binance:btc'), 'test'], 'binance:btc/test'],
9
- [[instrumentOf('binance:btc-usdt')], 'binance:btc-usdt'],
10
- [[instrumentOf('binance:btc-usdt'), 123], 'binance:btc-usdt/123']
5
+ [['binance:btc'], 'binance:btc'],
6
+ [['binance:btc', 'test'], 'binance:btc/test'],
7
+ [['binance:btc-usdt', 123], 'binance:btc-usdt/123']
11
8
  ])('hash list of dependencies from %p to %p', (dependencies, hashed) => {
12
9
  const hash = useHash(dependencies);
13
10
 
package/src/use-logger.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import chalk from 'chalk';
2
2
 
3
3
  import { Dependency, useContext } from './module';
4
- import { useTimestamp } from './use-timestamp';
5
- import { withMemo } from './with-memo';
4
+ import { useMemo } from './use-memo';
5
+ import { convert, useTimestamp } from './use-timestamp';
6
6
 
7
7
  const token = Symbol('logger');
8
8
 
@@ -28,7 +28,7 @@ export class ConsoleLoggerFactory implements ILoggerFactory {
28
28
  for(context: string, tint?: string): ILogger {
29
29
  const prefix = () =>
30
30
  `${chalk.hex(tint ?? this.colorize(context))(
31
- new Date(useTimestamp()).toISOString()
31
+ new Date(Number(convert(useTimestamp().timestamp, 'ns', 'ms'))).toISOString()
32
32
  )} ${chalk.hex(tint ?? this.colorize(context))(context)}`;
33
33
 
34
34
  return {
@@ -69,6 +69,9 @@ export class ConsoleLoggerFactory implements ILoggerFactory {
69
69
  /**
70
70
  *
71
71
  */
72
- export const useLogger = withMemo((context: string, tint?: string) =>
73
- useContext<ILoggerFactory>(token).for(context, tint)
74
- );
72
+ export function useLogger(context: string, tint?: string) {
73
+ return useMemo(
74
+ () => useContext<ILoggerFactory>(token).for(context, tint),
75
+ [context, tint]
76
+ );
77
+ }
package/src/use-socket.ts CHANGED
@@ -2,7 +2,7 @@ import { defer, Observable, of, ReplaySubject } from 'rxjs';
2
2
  import { WebSocket } from 'ws';
3
3
 
4
4
  import { useLogger } from './use-logger';
5
- import { useTimestamp } from './use-timestamp';
5
+ import { Timestamp, useTimestamp } from './use-timestamp';
6
6
 
7
7
  export function useSocket(
8
8
  url: string,
@@ -32,14 +32,14 @@ export function useSocket(
32
32
  * Observes socket events and handles connection health monitoring via ping/pong
33
33
  * @returns observable emitting message events with timestamps and parsed payloads
34
34
  */
35
- watch(): Observable<{ timestamp: number; payload: unknown }> {
35
+ watch(): Observable<{ timestamp: Timestamp<'ns'>; payload: unknown }> {
36
36
  let isAlive = false;
37
37
  let interval: NodeJS.Timeout | undefined;
38
38
 
39
39
  return new Observable(stream => {
40
40
  socket.onmessage = it =>
41
41
  stream.next({
42
- timestamp: useTimestamp(),
42
+ ...useTimestamp(),
43
43
  payload: JSON.parse(it.data as string)
44
44
  });
45
45
  socket.onerror = it => {
@@ -80,13 +80,13 @@ export function useSocket(
80
80
  });
81
81
  },
82
82
 
83
- send(message: { payload: unknown }): Observable<{ timestamp: number }> {
83
+ send(message: { payload: unknown }): Observable<{ timestamp: Timestamp<'ns'> }> {
84
84
  return defer(() => {
85
85
  debug('sent', url, message.payload);
86
86
 
87
87
  socket.send(JSON.stringify(message.payload));
88
88
 
89
- return of({ timestamp: useTimestamp() });
89
+ return of(useTimestamp());
90
90
  });
91
91
  },
92
92
 
@@ -2,12 +2,50 @@ import { useExecutionMode } from '@lib/use-execution-mode';
2
2
 
3
3
  import { useReplayScheduler } from './replay';
4
4
 
5
- export function useTimestamp() {
5
+ export type Unit = 'ns' | 'us' | 'ms' | 's';
6
+
7
+ export type Timestamp<Unit> = bigint & { readonly __unit: Unit };
8
+
9
+ export function now(): Timestamp<'ns'> {
10
+ return process.hrtime.bigint() as Timestamp<'ns'>;
11
+ }
12
+
13
+ export const ns = (value: bigint | number): Timestamp<'ns'> =>
14
+ BigInt(value) as Timestamp<'ns'>;
15
+ export const us = (value: bigint | number): Timestamp<'us'> =>
16
+ BigInt(value) as Timestamp<'us'>;
17
+ export const ms = (value: bigint | number): Timestamp<'ms'> =>
18
+ BigInt(value) as Timestamp<'ms'>;
19
+ export const s = (value: bigint | number): Timestamp<'s'> =>
20
+ BigInt(value) as Timestamp<'s'>;
21
+
22
+ const factors = {
23
+ ns: 1n,
24
+ us: 1_000n,
25
+ ms: 1_000_000n,
26
+ s: 1_000_000_000n
27
+ } as const;
28
+
29
+ export function convert<F extends Unit, T extends Unit>(
30
+ value: Timestamp<F>,
31
+ from: F,
32
+ to: T
33
+ ): Timestamp<T> {
34
+ const ns = BigInt(value) * factors[from];
35
+
36
+ return BigInt(ns / factors[to]) as Timestamp<T>;
37
+ }
38
+
39
+ export function add<U extends Unit>(a: Timestamp<U>, b: Timestamp<U>): Timestamp<U> {
40
+ return (a + b) as Timestamp<U>;
41
+ }
42
+
43
+ export function useTimestamp(): { timestamp: Timestamp<'ns'> } {
6
44
  const { isReplay } = useExecutionMode();
7
45
 
8
46
  if (isReplay) {
9
- return useReplayScheduler().timestamp();
47
+ return { timestamp: useReplayScheduler().timestamp() };
10
48
  }
11
49
 
12
- return Date.now();
50
+ return { timestamp: now() };
13
51
  }
@@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
3
3
  import { request } from 'undici';
4
4
 
5
5
  import { useLogger } from './use-logger';
6
- import { useTimestamp } from './use-timestamp';
6
+ import { Timestamp, useTimestamp } from './use-timestamp';
7
7
 
8
8
  export type RequestMethod =
9
9
  | 'GET'
@@ -35,7 +35,7 @@ export function withRequest({
35
35
  }) {
36
36
  const { error, debug } = useLogger(withRequest.name);
37
37
 
38
- return new Observable<{ timestamp: number; payload: unknown }>(subscriber => {
38
+ return new Observable<{ timestamp: Timestamp<'ns'>; payload: unknown }>(subscriber => {
39
39
  const correlationId = randomUUID();
40
40
 
41
41
  debug('requesting', { correlationId, method, url, headers, body });
@@ -64,7 +64,7 @@ export function withRequest({
64
64
 
65
65
  subscriber.error(new RequestNetworkError(statusCode));
66
66
  } else {
67
- subscriber.next({ timestamp: useTimestamp(), payload: json });
67
+ subscriber.next({ ...useTimestamp(), payload: json });
68
68
  }
69
69
  })
70
70
  .catch((e: Error) => {
@@ -1,41 +0,0 @@
1
- import { decimal } from '../shared';
2
- export declare const AssetSelectorSeparator = ":";
3
- export declare class MissingAssetError extends Error {
4
- constructor(asset: AssetSelector);
5
- }
6
- /**
7
- * Supposed to query specific @see Asset based on string notation.
8
- */
9
- export declare class AssetSelector {
10
- readonly id: string;
11
- readonly name: string;
12
- readonly adapterName: string;
13
- constructor(name: string, adapterName: string);
14
- toString(): string;
15
- }
16
- /**
17
- * Creates @see AssetSelector based on unified string notation.
18
- */
19
- export declare function assetOf(selector: string): AssetSelector;
20
- /**
21
- * Represents a security that you can trade or hold in your wallet.
22
- * For example, you can combine two trading assets to create a trading instrument.
23
- */
24
- export declare class Asset extends AssetSelector {
25
- readonly scale: number;
26
- readonly tickSize: decimal;
27
- constructor(name: string, adapterName: string, scale: number);
28
- /**
29
- * Formats a number to string with fixed number of decimal places.
30
- */
31
- fixed(number: decimal): string;
32
- /**
33
- * Rounds down a number to the asset precision.
34
- */
35
- floor(number: decimal): decimal;
36
- /**
37
- * Rounds up a number to the asset precision.
38
- */
39
- ceil(number: decimal): decimal;
40
- }
41
- //# sourceMappingURL=asset.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../../src/asset/asset.ts"],"names":[],"mappings":"AACA,OAAO,EAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAEzC,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,KAAK,EAAE,aAAa;CAGjC;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAc7C,QAAQ;CAGT;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAQvD;AAED;;;GAGG;AACH,qBAAa,KAAM,SAAQ,aAAa;aAGyB,KAAK,EAAE,MAAM;IAF5E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;gBAEf,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAkB,KAAK,EAAE,MAAM;IAU5E;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM;IAI9B;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;IAI/B;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAG/B"}
@@ -1,76 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Asset = exports.assetOf = exports.AssetSelector = exports.MissingAssetError = exports.AssetSelectorSeparator = void 0;
4
- const component_1 = require("../component");
5
- const shared_1 = require("../shared");
6
- exports.AssetSelectorSeparator = ':';
7
- class MissingAssetError extends Error {
8
- constructor(asset) {
9
- super(`Missing asset: ${asset}`);
10
- }
11
- }
12
- exports.MissingAssetError = MissingAssetError;
13
- /**
14
- * Supposed to query specific @see Asset based on string notation.
15
- */
16
- class AssetSelector {
17
- constructor(name, adapterName) {
18
- if (!(name === null || name === void 0 ? void 0 : name.length)) {
19
- throw new component_1.InvalidArgumentsError({ name });
20
- }
21
- if (!(adapterName === null || adapterName === void 0 ? void 0 : adapterName.length)) {
22
- throw new component_1.InvalidArgumentsError({ adapterName });
23
- }
24
- this.name = name.toLowerCase();
25
- this.adapterName = adapterName.toLowerCase();
26
- this.id = `${this.adapterName}${exports.AssetSelectorSeparator}${this.name}`;
27
- }
28
- toString() {
29
- return this.id;
30
- }
31
- }
32
- exports.AssetSelector = AssetSelector;
33
- /**
34
- * Creates @see AssetSelector based on unified string notation.
35
- */
36
- function assetOf(selector) {
37
- const [adapterName, name, ...rest] = selector.split(exports.AssetSelectorSeparator);
38
- if (!adapterName || !name || rest.length) {
39
- throw new component_1.InvalidAssetSelectorError(selector);
40
- }
41
- return new AssetSelector(name, adapterName);
42
- }
43
- exports.assetOf = assetOf;
44
- /**
45
- * Represents a security that you can trade or hold in your wallet.
46
- * For example, you can combine two trading assets to create a trading instrument.
47
- */
48
- class Asset extends AssetSelector {
49
- constructor(name, adapterName, scale) {
50
- super(name, adapterName);
51
- this.scale = scale;
52
- if (scale && (scale < 0 || Number.isNaN(scale))) {
53
- throw new component_1.InvalidArgumentsError({ scale });
54
- }
55
- this.tickSize = (0, shared_1.d)(1.0).div(Math.pow(10, this.scale));
56
- }
57
- /**
58
- * Formats a number to string with fixed number of decimal places.
59
- */
60
- fixed(number) {
61
- return number.toFixed(this.scale);
62
- }
63
- /**
64
- * Rounds down a number to the asset precision.
65
- */
66
- floor(number) {
67
- return number.toFloor(this.scale);
68
- }
69
- /**
70
- * Rounds up a number to the asset precision.
71
- */
72
- ceil(number) {
73
- return number.toCeil(this.scale);
74
- }
75
- }
76
- exports.Asset = Asset;
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=asset.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"asset.spec.d.ts","sourceRoot":"","sources":["../../src/asset/asset.spec.ts"],"names":[],"mappings":""}