@grvt/client 1.5.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/ws/interfaces.d.ts +1 -1
- package/ws/ws.d.ts +3 -4
- package/ws/ws.js +61 -75
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grvt/client",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Node.js & JavaScript client for GRVT REST APIs & WebSockets",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"test": "nodemon dist/index.js"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"axios": "^1.
|
|
36
|
+
"axios": "^1.11.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
package/ws/interfaces.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ECandlestickInterval, ECandlestickType, IWSCandlestickFeedDataV1, IWSCandlestickFeedSelectorV1, IWSDepositFeedDataV1, IWSDepositFeedSelectorV1, IWSFillFeedDataV1, IWSFillFeedSelectorV1, IWSMiniTickerFeedDataV1, IWSMiniTickerFeedSelectorV1, IWSOrderFeedDataV1, IWSOrderFeedSelectorV1, IWSOrderGroupFeedDataV1, IWSOrderStateFeedDataV1, IWSOrderStateFeedSelectorV1, IWSOrderbookLevelsFeedDataV1, IWSOrderbookLevelsFeedSelectorV1, IWSPositionsFeedDataV1, IWSPositionsFeedSelectorV1, IWSTickerFeedDataV1, IWSTickerFeedSelectorV1, IWSTradeFeedDataV1, IWSTradeFeedSelectorV1, IWSTransferFeedDataV1, IWSTransferFeedSelectorV1, IWSWithdrawalFeedDataV1, IWSWithdrawalFeedSelectorV1 } from '../interfaces';
|
|
2
2
|
export declare enum EStream {
|
|
3
3
|
CANDLE = "candle",
|
|
4
4
|
MINI_DELTA = "mini.d",
|
package/ws/ws.d.ts
CHANGED
|
@@ -27,14 +27,13 @@ export declare class WS {
|
|
|
27
27
|
private _bindWebSocketListeners;
|
|
28
28
|
/**
|
|
29
29
|
* Only use for TDG
|
|
30
|
-
* Use for TEntities of
|
|
30
|
+
* Use for TEntities of DEPOSIT | TRANSFER | WITHDRAWAL streams
|
|
31
31
|
*/
|
|
32
|
-
private
|
|
32
|
+
private _getHistoryConsumers;
|
|
33
33
|
/**
|
|
34
34
|
* Use for MDG/TDG
|
|
35
|
-
* Use for TEntityHasInstrument
|
|
36
35
|
*/
|
|
37
|
-
private
|
|
36
|
+
private _getSelectorConsumers;
|
|
38
37
|
private _parseStream;
|
|
39
38
|
private _messageLiteToFull;
|
|
40
39
|
private _sendMessage;
|
package/ws/ws.js
CHANGED
|
@@ -149,7 +149,7 @@ class WS {
|
|
|
149
149
|
reconnect();
|
|
150
150
|
});
|
|
151
151
|
currentWs.addEventListener('message', (e) => {
|
|
152
|
-
var _a, _b, _c, _d, _e, _f
|
|
152
|
+
var _a, _b, _c, _d, _e, _f;
|
|
153
153
|
// only keep the latest ws
|
|
154
154
|
if (currentWs !== this.__ws) {
|
|
155
155
|
this._close(currentWs);
|
|
@@ -183,12 +183,13 @@ class WS {
|
|
|
183
183
|
return;
|
|
184
184
|
}
|
|
185
185
|
const stream = message.s = (_f = (_e = message.s) === null || _e === void 0 ? void 0 : _e.replace) === null || _f === void 0 ? void 0 : _f.call(_e, `${this._version}.`, '');
|
|
186
|
+
const selector = typeof message.s1 === 'string' ? message.s1 : '';
|
|
186
187
|
const result = this._messageLiteToFull(message);
|
|
187
188
|
// no entity found
|
|
188
|
-
if (!result) {
|
|
189
|
+
if (!selector || !result) {
|
|
189
190
|
// if no entity found and not a subscription message
|
|
190
|
-
if (
|
|
191
|
-
console.warn('Error:
|
|
191
|
+
if (typeof message.s1 === 'string') {
|
|
192
|
+
console.warn('Error: not found selector', message);
|
|
192
193
|
}
|
|
193
194
|
return;
|
|
194
195
|
}
|
|
@@ -196,13 +197,16 @@ class WS {
|
|
|
196
197
|
console.warn('Error: cannot parse stream or feed from message', message);
|
|
197
198
|
return;
|
|
198
199
|
}
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
200
|
+
const consumers = (() => {
|
|
201
|
+
switch (stream) {
|
|
202
|
+
case interfaces_1.EStream.DEPOSIT:
|
|
203
|
+
case interfaces_1.EStream.TRANSFER:
|
|
204
|
+
case interfaces_1.EStream.WITHDRAWAL:
|
|
205
|
+
return this._getHistoryConsumers({ stream, result });
|
|
206
|
+
default:
|
|
207
|
+
return this._getSelectorConsumers({ stream, selector });
|
|
208
|
+
}
|
|
209
|
+
})();
|
|
206
210
|
if (!(consumers === null || consumers === void 0 ? void 0 : consumers.length)) {
|
|
207
211
|
// There are delay in sending unsubscribe message so clients might receive messages after unsubscribing
|
|
208
212
|
// console.log('TODO: send unsubscribe with by message:', message, result)
|
|
@@ -244,9 +248,9 @@ class WS {
|
|
|
244
248
|
}
|
|
245
249
|
/**
|
|
246
250
|
* Only use for TDG
|
|
247
|
-
* Use for TEntities of
|
|
251
|
+
* Use for TEntities of DEPOSIT | TRANSFER | WITHDRAWAL streams
|
|
248
252
|
*/
|
|
249
|
-
|
|
253
|
+
_getHistoryConsumers({ result, stream }) {
|
|
250
254
|
return Object.entries(this._pairs).reduce((acc, [key, value]) => {
|
|
251
255
|
if (!key.startsWith(`${stream}__`)) {
|
|
252
256
|
return acc;
|
|
@@ -262,10 +266,6 @@ class WS {
|
|
|
262
266
|
].filter(Boolean).join('-');
|
|
263
267
|
const withdrawalFromAccountId = omitZeroStr(result.from_account_id);
|
|
264
268
|
switch (stream) {
|
|
265
|
-
case interfaces_1.EStream.GROUP:
|
|
266
|
-
return [...acc, ...Object.values(value)];
|
|
267
|
-
case interfaces_1.EStream.STATE:
|
|
268
|
-
return [...acc, ...Object.values(value)];
|
|
269
269
|
case interfaces_1.EStream.DEPOSIT:
|
|
270
270
|
if (depositDestinationAccountId && key.endsWith(depositDestinationAccountId)) {
|
|
271
271
|
return [...acc, ...Object.values(value)];
|
|
@@ -287,45 +287,18 @@ class WS {
|
|
|
287
287
|
}
|
|
288
288
|
/**
|
|
289
289
|
* Use for MDG/TDG
|
|
290
|
-
* Use for TEntityHasInstrument
|
|
291
290
|
*/
|
|
292
|
-
|
|
291
|
+
_getSelectorConsumers({ stream, selector }) {
|
|
292
|
+
const selectorPrimary = selector.split('@')[0];
|
|
293
293
|
return Object.entries(this._pairs).reduce((acc, [key, value]) => {
|
|
294
|
-
|
|
295
|
-
|
|
294
|
+
const pairPrefix = `${stream}__${selectorPrimary}`;
|
|
295
|
+
const isKeyMatch = key.includes('@')
|
|
296
|
+
? key.startsWith(pairPrefix)
|
|
297
|
+
: key === pairPrefix;
|
|
298
|
+
if (!isKeyMatch) {
|
|
296
299
|
return acc;
|
|
297
300
|
}
|
|
298
|
-
|
|
299
|
-
interfaces_1.EStream.ORDER,
|
|
300
|
-
// EStream.STATE,
|
|
301
|
-
interfaces_1.EStream.POSITION,
|
|
302
|
-
interfaces_1.EStream.FILL
|
|
303
|
-
// EStream.DEPOSIT,
|
|
304
|
-
// EStream.TRANSFER,
|
|
305
|
-
// EStream.WITHDRAWAL
|
|
306
|
-
].includes(stream);
|
|
307
|
-
// no sub account id handling
|
|
308
|
-
if (!hasSubAccountId) {
|
|
309
|
-
return key.startsWith(`${stream}__${instrument}`)
|
|
310
|
-
? [...acc, ...Object.values(value)]
|
|
311
|
-
: acc;
|
|
312
|
-
}
|
|
313
|
-
// has sub account id handling
|
|
314
|
-
const subAccountId = String((_a = result.sub_account_id) !== null && _a !== void 0 ? _a : '');
|
|
315
|
-
// const subAccountId = String((result as IPositions).sub_account_id)
|
|
316
|
-
// const subAccountId = String((result as IFill).sub_account_id)
|
|
317
|
-
const feed = (_b = this._parseStream({
|
|
318
|
-
stream: stream,
|
|
319
|
-
params: {
|
|
320
|
-
sub_account_id: omitZeroStr(subAccountId),
|
|
321
|
-
instrument
|
|
322
|
-
}
|
|
323
|
-
})) === null || _b === void 0 ? void 0 : _b.feed;
|
|
324
|
-
const tdgFeedPrefix = (_d = (_c = feed === null || feed === void 0 ? void 0 : feed[0]) === null || _c === void 0 ? void 0 : _c.split('@')) === null || _d === void 0 ? void 0 : _d[0];
|
|
325
|
-
if (tdgFeedPrefix && key.startsWith(`${stream}__${tdgFeedPrefix}`)) {
|
|
326
|
-
return [...acc, ...Object.values(value)];
|
|
327
|
-
}
|
|
328
|
-
return acc;
|
|
301
|
+
return [...acc, ...Object.values(value)];
|
|
329
302
|
}, []);
|
|
330
303
|
}
|
|
331
304
|
_parseStream(options) {
|
|
@@ -597,30 +570,45 @@ class WS {
|
|
|
597
570
|
this._pairs[pair][consumerKey] = onMessage;
|
|
598
571
|
return `${pair}__${consumerKey}`;
|
|
599
572
|
}
|
|
600
|
-
_removeConsumer(
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
const pairPrimary = pairKey.split('@')[0];
|
|
608
|
-
for (const key of Object.keys(this._pairs)) {
|
|
609
|
-
if (key.split('@')[0] !== pairPrimary) {
|
|
610
|
-
continue;
|
|
573
|
+
_removeConsumer(...pairedConsumerKeys) {
|
|
574
|
+
const toUnsubscribe = {};
|
|
575
|
+
for (const pairedConsumerKey of pairedConsumerKeys) {
|
|
576
|
+
const [stream, feed, consumerKey] = pairedConsumerKey.split('__');
|
|
577
|
+
const pairKey = this._getPair({ stream, feed });
|
|
578
|
+
if (!this._pairs[pairKey]) {
|
|
579
|
+
return;
|
|
611
580
|
}
|
|
612
|
-
|
|
613
|
-
const
|
|
614
|
-
this._pairs
|
|
615
|
-
|
|
616
|
-
|
|
581
|
+
let needUnsubscribe = true;
|
|
582
|
+
const pairPrimary = pairKey.split('@')[0];
|
|
583
|
+
for (const key of Object.keys(this._pairs)) {
|
|
584
|
+
if (key.split('@')[0] !== pairPrimary) {
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
const primaryGroup = this._pairs[key];
|
|
588
|
+
const _a = primaryGroup, _b = consumerKey, _ = _a[_b], keep = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
|
589
|
+
this._pairs[key] = keep;
|
|
590
|
+
if (Object.keys(keep).length) {
|
|
591
|
+
needUnsubscribe = false;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
if (needUnsubscribe) {
|
|
595
|
+
if (!toUnsubscribe[stream]) {
|
|
596
|
+
toUnsubscribe[stream] = [];
|
|
597
|
+
}
|
|
598
|
+
const primaryFeed = feed.split('@')[0];
|
|
599
|
+
if (!toUnsubscribe[stream].some((f) => f.startsWith(`${primaryFeed}@`))) {
|
|
600
|
+
toUnsubscribe[stream].push(feed);
|
|
601
|
+
}
|
|
617
602
|
}
|
|
618
603
|
}
|
|
619
|
-
|
|
604
|
+
/**
|
|
605
|
+
* Send unsubscribes
|
|
606
|
+
*/
|
|
607
|
+
for (const stream of Object.keys(toUnsubscribe)) {
|
|
620
608
|
this._sendMessage({
|
|
621
609
|
method: 'unsubscribe',
|
|
622
610
|
stream,
|
|
623
|
-
feed: [
|
|
611
|
+
feed: toUnsubscribe[stream]
|
|
624
612
|
});
|
|
625
613
|
}
|
|
626
614
|
}
|
|
@@ -692,7 +680,7 @@ class WS {
|
|
|
692
680
|
const onPaired = (e) => {
|
|
693
681
|
var _a, _b, _c;
|
|
694
682
|
const message = utils_1.JsonUtils.parse(e.data);
|
|
695
|
-
if (!(message === null || message === void 0 ? void 0 : message.s) || !((_a = message === null || message === void 0 ? void 0 : message.s1) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
683
|
+
if (!(message === null || message === void 0 ? void 0 : message.s) || !((_a = message === null || message === void 0 ? void 0 : message.s1) === null || _a === void 0 ? void 0 : _a.length) || typeof message.s1 === 'string') {
|
|
696
684
|
return;
|
|
697
685
|
}
|
|
698
686
|
const responseStream = (_c = (_b = message.s) === null || _b === void 0 ? void 0 : _b.replace) === null || _c === void 0 ? void 0 : _c.call(_b, `${this._version}.`, '');
|
|
@@ -775,7 +763,7 @@ class WS {
|
|
|
775
763
|
const onPaired = (e) => {
|
|
776
764
|
var _a, _b, _c;
|
|
777
765
|
const message = utils_1.JsonUtils.parse(e.data);
|
|
778
|
-
if (!(message === null || message === void 0 ? void 0 : message.s) || !((_a = message === null || message === void 0 ? void 0 : message.s1) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
766
|
+
if (!(message === null || message === void 0 ? void 0 : message.s) || !((_a = message === null || message === void 0 ? void 0 : message.s1) === null || _a === void 0 ? void 0 : _a.length) || typeof message.s1 === 'string') {
|
|
779
767
|
return;
|
|
780
768
|
}
|
|
781
769
|
const responseStream = (_c = (_b = message.s) === null || _b === void 0 ? void 0 : _b.replace) === null || _c === void 0 ? void 0 : _c.call(_b, `${this._version}.`, '');
|
|
@@ -814,9 +802,7 @@ class WS {
|
|
|
814
802
|
});
|
|
815
803
|
}
|
|
816
804
|
unsubscribe(...pairedConsumerKeys) {
|
|
817
|
-
|
|
818
|
-
this._removeConsumer(pairedConsumerKey);
|
|
819
|
-
}
|
|
805
|
+
this._removeConsumer(...pairedConsumerKeys);
|
|
820
806
|
return this;
|
|
821
807
|
}
|
|
822
808
|
connect() {
|