chore(): misc cleaning

This commit is contained in:
tiagosiebler
2025-01-21 15:22:43 +00:00
parent fcffd852cc
commit 39ce4c4929
4 changed files with 71 additions and 115 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "bybit-api", "name": "bybit-api",
"version": "3.10.28", "version": "3.10.29",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "bybit-api", "name": "bybit-api",
"version": "3.10.28", "version": "3.10.29",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"axios": "^1.6.6", "axios": "^1.6.6",

View File

@@ -132,8 +132,6 @@ export abstract class BaseWebsocketClient<
private timeOffsetMs: number = 0; private timeOffsetMs: number = 0;
// private pendingTopicsSubscriptionsOld: TopicsPendingSubscriptions[] = [];
private pendingTopicSubscriptionRequests: { private pendingTopicSubscriptionRequests: {
[key in TWSKey]?: { [key in TWSKey]?: {
[requestKey: string]: [requestKey: string]:
@@ -259,52 +257,32 @@ export abstract class BaseWebsocketClient<
params: any, params: any,
): Promise<unknown>; ): Promise<unknown>;
protected getTimeOffsetMs() { public getTimeOffsetMs() {
return this.timeOffsetMs; return this.timeOffsetMs;
} }
protected setTimeOffsetMs(newOffset: number) { public setTimeOffsetMs(newOffset: number) {
this.timeOffsetMs = newOffset; this.timeOffsetMs = newOffset;
} }
// protected upsertPendingTopicsSubscriptionsOld( private getWsKeyPendingSubscriptionStore(wsKey: TWSKey) {
// wsKey: string, if (!this.pendingTopicSubscriptionRequests[wsKey]) {
// topicKey: string, this.pendingTopicSubscriptionRequests[wsKey] = {};
// resolver: TopicsPendingSubscriptionsResolver, }
// rejector: TopicsPendingSubscriptionsRejector,
// ) {
// const existingWsKeyPendingSubscriptions =
// this.pendingTopicsSubscriptionsOld.find((s) => s.wsKey === wsKey);
// if (!existingWsKeyPendingSubscriptions) { return this.pendingTopicSubscriptionRequests[wsKey]!;
// this.pendingTopicsSubscriptionsOld.push({ }
// wsKey,
// resolver,
// rejector,
// failedTopicsSubscriptions: new Set(),
// pendingTopicsSubscriptions: new Set([topicKey]),
// });
// return;
// }
// existingWsKeyPendingSubscriptions.pendingTopicsSubscriptions.add(topicKey);
// }
protected upsertPendingTopicSubscribeRequests( protected upsertPendingTopicSubscribeRequests(
wsKey: TWSKey, wsKey: TWSKey,
requestData: MidflightWsRequestEvent<TWSRequestEvent>, requestData: MidflightWsRequestEvent<TWSRequestEvent>,
) { ) {
if (!this.pendingTopicSubscriptionRequests[wsKey]) {
this.pendingTopicSubscriptionRequests[wsKey] = {};
}
const existingWsKeyPendingRequests =
this.pendingTopicSubscriptionRequests[wsKey]!;
// a unique identifier for this subscription request (e.g. csv of topics, or request id, etc) // a unique identifier for this subscription request (e.g. csv of topics, or request id, etc)
const requestKey = requestData.requestKey; const requestKey = requestData.requestKey;
// Should not be possible to see a requestKey collision in the current design, since the req ID increments automatically with every request, so this should never be true, but just in case a future mistake happens... // Should not be possible to see a requestKey collision in the current design, since the req ID increments automatically with every request, so this should never be true, but just in case a future mistake happens...
const existingWsKeyPendingRequests =
this.getWsKeyPendingSubscriptionStore(wsKey);
if (existingWsKeyPendingRequests[requestKey]) { if (existingWsKeyPendingRequests[requestKey]) {
throw new Error( throw new Error(
'Implementation error: attempted to upsert pending topics with duplicate request ID!', 'Implementation error: attempted to upsert pending topics with duplicate request ID!',
@@ -316,10 +294,8 @@ export abstract class BaseWebsocketClient<
resolver: TopicsPendingSubscriptionsResolver<TWSRequestEvent>, resolver: TopicsPendingSubscriptionsResolver<TWSRequestEvent>,
rejector: TopicsPendingSubscriptionsRejector<TWSRequestEvent>, rejector: TopicsPendingSubscriptionsRejector<TWSRequestEvent>,
) => { ) => {
if (!this.pendingTopicSubscriptionRequests[wsKey]) { const store = this.getWsKeyPendingSubscriptionStore(wsKey);
this.pendingTopicSubscriptionRequests[wsKey] = {}; store[requestKey] = {
}
this.pendingTopicSubscriptionRequests[wsKey][requestKey] = {
requestData: requestData.requestEvent, requestData: requestData.requestEvent,
resolver, resolver,
rejector, rejector,
@@ -329,11 +305,8 @@ export abstract class BaseWebsocketClient<
} }
protected removeTopicPendingSubscription(wsKey: TWSKey, requestKey: string) { protected removeTopicPendingSubscription(wsKey: TWSKey, requestKey: string) {
if (!this.pendingTopicSubscriptionRequests[wsKey]) { const store = this.getWsKeyPendingSubscriptionStore(wsKey);
this.pendingTopicSubscriptionRequests[wsKey] = {}; delete store[requestKey];
}
delete this.pendingTopicSubscriptionRequests[wsKey][requestKey];
} }
private clearTopicsPendingSubscriptions( private clearTopicsPendingSubscriptions(
@@ -342,13 +315,9 @@ export abstract class BaseWebsocketClient<
rejectReason: string, rejectReason: string,
) { ) {
if (rejectAll) { if (rejectAll) {
if (!this.pendingTopicSubscriptionRequests[wsKey]) { const wsKeyPendingRequests = this.getWsKeyPendingSubscriptionStore(wsKey);
this.pendingTopicSubscriptionRequests[wsKey] = {}; for (const requestKey in wsKeyPendingRequests) {
} const request = wsKeyPendingRequests[requestKey];
const requests = this.pendingTopicSubscriptionRequests[wsKey]!;
for (const requestKey in requests) {
const request = requests[requestKey];
request?.rejector(request.requestData, rejectReason); request?.rejector(request.requestData, rejectReason);
} }
} }
@@ -367,21 +336,16 @@ export abstract class BaseWebsocketClient<
msg: object, msg: object,
isTopicSubscriptionSuccessEvent: boolean, isTopicSubscriptionSuccessEvent: boolean,
) { ) {
if (!this.pendingTopicSubscriptionRequests[wsKey]) { const wsKeyPendingRequests = this.getWsKeyPendingSubscriptionStore(wsKey);
if (!wsKeyPendingRequests) {
return; return;
} }
const pendingSubscriptionRequest = const pendingSubscriptionRequest = wsKeyPendingRequests[requestKey];
this.pendingTopicSubscriptionRequests[wsKey][requestKey];
if (!pendingSubscriptionRequest) { if (!pendingSubscriptionRequest) {
return; return;
} }
console.log('updatePendingTopicSubscriptionStatus', {
isTopicSubscriptionSuccessEvent,
msg,
});
if (isTopicSubscriptionSuccessEvent) { if (isTopicSubscriptionSuccessEvent) {
pendingSubscriptionRequest.resolver( pendingSubscriptionRequest.resolver(
pendingSubscriptionRequest.requestData, pendingSubscriptionRequest.requestData,
@@ -413,7 +377,6 @@ export abstract class BaseWebsocketClient<
wsTopicRequests: WsTopicRequestOrStringTopic<string>[], wsTopicRequests: WsTopicRequestOrStringTopic<string>[],
wsKey: TWSKey, wsKey: TWSKey,
) { ) {
console.log('subscribeTopicsForWsKey: ', { wsTopicRequests, wsKey });
const normalisedTopicRequests = getNormalisedTopicRequests(wsTopicRequests); const normalisedTopicRequests = getNormalisedTopicRequests(wsTopicRequests);
// Store topics, so future automation (post-auth, post-reconnect) has everything needed to resubscribe automatically // Store topics, so future automation (post-auth, post-reconnect) has everything needed to resubscribe automatically

View File

@@ -45,6 +45,46 @@ import {
const WS_LOGGER_CATEGORY = { category: 'bybit-ws' }; const WS_LOGGER_CATEGORY = { category: 'bybit-ws' };
/**
* Groups topics in request into per-wsKey groups
* @param normalisedTopicRequests
* @param wsKey
* @param isPrivateTopic
* @returns
*/
function getTopicsPerWSKey(
normalisedTopicRequests: WsTopicRequest[],
wsKey?: WsKey,
isPrivateTopic?: boolean,
): {
[key in WsKey]?: WsTopicRequest<WsTopic>[];
} {
const perWsKeyTopics: { [key in WsKey]?: WsTopicRequest<WsTopic>[] } = {};
// Sort into per wsKey arrays, in case topics are mixed together for different wsKeys
for (const topicRequest of normalisedTopicRequests) {
const derivedWsKey =
wsKey ||
getWsKeyForTopic(
this.options.market,
topicRequest.topic,
isPrivateTopic,
topicRequest.category,
);
if (
!perWsKeyTopics[derivedWsKey] ||
!Array.isArray(perWsKeyTopics[derivedWsKey])
) {
perWsKeyTopics[derivedWsKey] = [];
}
perWsKeyTopics[derivedWsKey]!.push(topicRequest);
}
return perWsKeyTopics;
}
// export class WebsocketClient extends EventEmitter { // export class WebsocketClient extends EventEmitter {
export class WebsocketClient extends BaseWebsocketClient< export class WebsocketClient extends BaseWebsocketClient<
WsKey, WsKey,
@@ -183,12 +223,12 @@ export class WebsocketClient extends BaseWebsocketClient<
category: CategoryV5, category: CategoryV5,
isPrivateTopic?: boolean, isPrivateTopic?: boolean,
): Promise<unknown>[] { ): Promise<unknown>[] {
const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics]; const topicRequests = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
const perWsKeyTopics: { [key in WsKey]?: WsTopicRequest<WsTopic>[] } = {}; const perWsKeyTopics: { [key in WsKey]?: WsTopicRequest<WsTopic>[] } = {};
// Sort into per-WsKey batches, in case there is a mix of topics here // Sort into per-WsKey batches, in case there is a mix of topics here
for (const topic of topics) { for (const topic of topicRequests) {
const derivedWsKey = getWsKeyForTopic( const derivedWsKey = getWsKeyForTopic(
this.options.market, this.options.market,
topic, topic,
@@ -208,7 +248,7 @@ export class WebsocketClient extends BaseWebsocketClient<
perWsKeyTopics[derivedWsKey] = []; perWsKeyTopics[derivedWsKey] = [];
} }
perWsKeyTopics[derivedWsKey].push(wsRequest); perWsKeyTopics[derivedWsKey]!.push(wsRequest);
} }
const promises: Promise<unknown>[] = []; const promises: Promise<unknown>[] = [];
@@ -245,12 +285,12 @@ export class WebsocketClient extends BaseWebsocketClient<
category: CategoryV5, category: CategoryV5,
isPrivateTopic?: boolean, isPrivateTopic?: boolean,
): Promise<unknown>[] { ): Promise<unknown>[] {
const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics]; const topicRequests = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
const perWsKeyTopics: { [key in WsKey]?: WsTopicRequest<WsTopic>[] } = {}; const perWsKeyTopics: { [key in WsKey]?: WsTopicRequest<WsTopic>[] } = {};
// Sort into per-WsKey batches, in case there is a mix of topics here // Sort into per-WsKey batches, in case there is a mix of topics here
for (const topic of topics) { for (const topic of topicRequests) {
const derivedWsKey = getWsKeyForTopic( const derivedWsKey = getWsKeyForTopic(
this.options.market, this.options.market,
topic, topic,
@@ -270,7 +310,7 @@ export class WebsocketClient extends BaseWebsocketClient<
perWsKeyTopics[derivedWsKey] = []; perWsKeyTopics[derivedWsKey] = [];
} }
perWsKeyTopics[derivedWsKey].push(wsRequest); perWsKeyTopics[derivedWsKey]!.push(wsRequest);
} }
const promises: Promise<unknown>[] = []; const promises: Promise<unknown>[] = [];
@@ -315,30 +355,7 @@ export class WebsocketClient extends BaseWebsocketClient<
const topicRequests = Array.isArray(requests) ? requests : [requests]; const topicRequests = Array.isArray(requests) ? requests : [requests];
const normalisedTopicRequests = getNormalisedTopicRequests(topicRequests); const normalisedTopicRequests = getNormalisedTopicRequests(topicRequests);
const isPrivateTopic = undefined; const perWsKeyTopics = getTopicsPerWSKey(normalisedTopicRequests, wsKey);
const perWsKeyTopics: { [key in WsKey]?: WsTopicRequest<WsTopic>[] } = {};
// Sort into per wsKey arrays, in case topics are mixed together for different wsKeys
for (const topicRequest of normalisedTopicRequests) {
const derivedWsKey =
wsKey ||
getWsKeyForTopic(
this.options.market,
topicRequest.topic,
isPrivateTopic,
topicRequest.category,
);
if (
!perWsKeyTopics[derivedWsKey] ||
!Array.isArray(perWsKeyTopics[derivedWsKey])
) {
perWsKeyTopics[derivedWsKey] = [];
}
perWsKeyTopics[derivedWsKey].push(topicRequest);
}
// Batch sub topics per ws key // Batch sub topics per ws key
for (const wsKey in perWsKeyTopics) { for (const wsKey in perWsKeyTopics) {
@@ -364,30 +381,7 @@ export class WebsocketClient extends BaseWebsocketClient<
const topicRequests = Array.isArray(requests) ? requests : [requests]; const topicRequests = Array.isArray(requests) ? requests : [requests];
const normalisedTopicRequests = getNormalisedTopicRequests(topicRequests); const normalisedTopicRequests = getNormalisedTopicRequests(topicRequests);
const isPrivateTopic = undefined; const perWsKeyTopics = getTopicsPerWSKey(normalisedTopicRequests, wsKey);
const perWsKeyTopics: { [key in WsKey]?: WsTopicRequest<WsTopic>[] } = {};
// Sort into per wsKey arrays, in case topics are mixed together for different wsKeys
for (const topicRequest of normalisedTopicRequests) {
const derivedWsKey =
wsKey ||
getWsKeyForTopic(
this.options.market,
topicRequest.topic,
isPrivateTopic,
topicRequest.category,
);
if (
!perWsKeyTopics[derivedWsKey] ||
!Array.isArray(perWsKeyTopics[derivedWsKey])
) {
perWsKeyTopics[derivedWsKey] = [];
}
perWsKeyTopics[derivedWsKey].push(topicRequest);
}
// Batch sub topics per ws key // Batch sub topics per ws key
for (const wsKey in perWsKeyTopics) { for (const wsKey in perWsKeyTopics) {
@@ -811,7 +805,6 @@ export class WebsocketClient extends BaseWebsocketClient<
// WS API Exception // WS API Exception
if (isError) { if (isError) {
// console.log('wsAPI error: ', parsed);
try { try {
this.getWsStore().rejectDeferredPromise( this.getWsStore().rejectDeferredPromise(
wsKey, wsKey,

View File

@@ -17,6 +17,6 @@
"baseUrl": ".", "baseUrl": ".",
"outDir": "./lib" "outDir": "./lib"
}, },
"include": ["src/**/*", "src/.ts"], "include": ["src/**/*"],
"exclude": ["node_modules", "**/node_modules/*", "coverage", "doc"] "exclude": ["node_modules", "**/node_modules/*", "coverage", "doc"]
} }