@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grvt/client",
3
- "version": "1.5.0",
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.8.2"
36
+ "axios": "^1.11.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@typescript-eslint/eslint-plugin": "^6.10.0",
@@ -1,4 +1,4 @@
1
- import { type ECandlestickInterval, type ECandlestickType, type IWSCandlestickFeedDataV1, type IWSCandlestickFeedSelectorV1, type IWSDepositFeedDataV1, type IWSDepositFeedSelectorV1, type IWSFillFeedDataV1, type IWSFillFeedSelectorV1, type IWSMiniTickerFeedDataV1, type IWSMiniTickerFeedSelectorV1, type IWSOrderFeedDataV1, type IWSOrderFeedSelectorV1, type IWSOrderGroupFeedDataV1, type IWSOrderStateFeedDataV1, type IWSOrderStateFeedSelectorV1, type IWSOrderbookLevelsFeedDataV1, type IWSOrderbookLevelsFeedSelectorV1, type IWSPositionsFeedDataV1, type IWSPositionsFeedSelectorV1, type IWSTickerFeedDataV1, type IWSTickerFeedSelectorV1, type IWSTradeFeedDataV1, type IWSTradeFeedSelectorV1, type IWSTransferFeedDataV1, type IWSTransferFeedSelectorV1, type IWSWithdrawalFeedDataV1, type IWSWithdrawalFeedSelectorV1 } from '../interfaces';
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 GROUP | STATE | DEPOSIT | TRANSFER | WITHDRAWAL streams
30
+ * Use for TEntities of DEPOSIT | TRANSFER | WITHDRAWAL streams
31
31
  */
32
- private _getNonInstrumentConsumers;
32
+ private _getHistoryConsumers;
33
33
  /**
34
34
  * Use for MDG/TDG
35
- * Use for TEntityHasInstrument
36
35
  */
37
- private _getInstrumentConsumers;
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, _g, _h, _j, _k;
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 (!((_g = message.s1) === null || _g === void 0 ? void 0 : _g.length)) {
191
- console.warn('Error: something went wrong with message', message);
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 instrument = (_k = (_j = (_h = result === null || result === void 0 ? void 0 : result.legs) === null || _h === void 0 ? void 0 : _h[0]) === null || _j === void 0 ? void 0 : _j.instrument) !== null && _k !== void 0 ? _k : result === null || result === void 0 ? void 0 : result.instrument;
200
- /**
201
- * Handle subscriptions with instrument
202
- */
203
- const consumers = instrument
204
- ? this._getInstrumentConsumers({ stream, instrument, result })
205
- : this._getNonInstrumentConsumers({ stream, result });
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 GROUP | STATE | DEPOSIT | TRANSFER | WITHDRAWAL streams
251
+ * Use for TEntities of DEPOSIT | TRANSFER | WITHDRAWAL streams
248
252
  */
249
- _getNonInstrumentConsumers({ result, stream }) {
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
- _getInstrumentConsumers({ result, stream, instrument }) {
291
+ _getSelectorConsumers({ stream, selector }) {
292
+ const selectorPrimary = selector.split('@')[0];
293
293
  return Object.entries(this._pairs).reduce((acc, [key, value]) => {
294
- var _a, _b, _c, _d;
295
- if (!key.startsWith(`${stream}__`)) {
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
- const hasSubAccountId = [
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(pairedConsumerKey) {
601
- const [stream, feed, consumerKey] = pairedConsumerKey.split('__');
602
- const pairKey = this._getPair({ stream, feed });
603
- if (!this._pairs[pairKey]) {
604
- return;
605
- }
606
- let needUnsubscribe = true;
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
- const primaryGroup = this._pairs[key];
613
- const _a = primaryGroup, _b = consumerKey, _ = _a[_b], keep = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
614
- this._pairs[key] = keep;
615
- if (Object.keys(keep).length) {
616
- needUnsubscribe = false;
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
- if (needUnsubscribe) {
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: [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
- for (const pairedConsumerKey of pairedConsumerKeys) {
818
- this._removeConsumer(pairedConsumerKey);
819
- }
805
+ this._removeConsumer(...pairedConsumerKeys);
820
806
  return this;
821
807
  }
822
808
  connect() {