shoonya-sdk 1.1.0 → 1.1.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/dist/index.cjs +76 -43
- package/dist/index.d.cts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +76 -43
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -141,7 +141,7 @@ var Tokens = class {
|
|
|
141
141
|
}
|
|
142
142
|
};
|
|
143
143
|
var tokens = new Tokens();
|
|
144
|
-
async function refreshAccessToken() {
|
|
144
|
+
async function refreshAccessToken(retryCount = 3) {
|
|
145
145
|
const userCred = tokens.getCred();
|
|
146
146
|
const cred = {
|
|
147
147
|
apkversion: "1.0.0",
|
|
@@ -153,14 +153,23 @@ async function refreshAccessToken() {
|
|
|
153
153
|
imei: userCred?.imei || "api",
|
|
154
154
|
source: "API"
|
|
155
155
|
};
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
let errorMsg = "";
|
|
157
|
+
for (let i = 0; i < retryCount; i++) {
|
|
158
|
+
try {
|
|
159
|
+
const req = await request("login", { data: cred });
|
|
160
|
+
tokens.updateAccessToken(req.susertoken);
|
|
161
|
+
return;
|
|
162
|
+
} catch (err) {
|
|
163
|
+
let errMsg = "Couldn't Refresh the Access Token. ";
|
|
164
|
+
if (err instanceof Error) {
|
|
165
|
+
errMsg += `Error: ${err.message}`;
|
|
166
|
+
}
|
|
167
|
+
errorMsg += `${errMsg}, `;
|
|
168
|
+
}
|
|
163
169
|
}
|
|
170
|
+
throw new Error(
|
|
171
|
+
`Attempted to refresh access token ${retryCount} times. but failed. Errors: ${errorMsg}`
|
|
172
|
+
);
|
|
164
173
|
}
|
|
165
174
|
__name(refreshAccessToken, "refreshAccessToken");
|
|
166
175
|
|
|
@@ -754,10 +763,9 @@ var WebsocketClient = class extends import_events.EventEmitter {
|
|
|
754
763
|
}
|
|
755
764
|
wsBaseUrl = "wss://api.shoonya.com/NorenWSTP/";
|
|
756
765
|
ws;
|
|
757
|
-
reconnectInterval;
|
|
758
|
-
reconnectTimer;
|
|
759
766
|
subscribedTokens = [];
|
|
760
767
|
logger;
|
|
768
|
+
retryCount = 0;
|
|
761
769
|
maxRetryAttempt;
|
|
762
770
|
/**
|
|
763
771
|
*
|
|
@@ -767,14 +775,13 @@ var WebsocketClient = class extends import_events.EventEmitter {
|
|
|
767
775
|
constructor(params) {
|
|
768
776
|
super();
|
|
769
777
|
const {
|
|
770
|
-
|
|
771
|
-
dailyRefreshTime = "09:10+05:30",
|
|
778
|
+
dailyRefreshTime = "09:13+05:30",
|
|
772
779
|
cred,
|
|
773
780
|
logging = false,
|
|
774
781
|
logFileType = "SEPARATE",
|
|
775
|
-
|
|
782
|
+
maxRetryAttempt = 3
|
|
776
783
|
} = params || {};
|
|
777
|
-
this.maxRetryAttempt =
|
|
784
|
+
this.maxRetryAttempt = maxRetryAttempt;
|
|
778
785
|
this.logger = new logger_default(
|
|
779
786
|
"shoonya_ws-client",
|
|
780
787
|
1024 * 1024 * 10,
|
|
@@ -789,7 +796,6 @@ var WebsocketClient = class extends import_events.EventEmitter {
|
|
|
789
796
|
if (!storedCred.userId) {
|
|
790
797
|
tokens.updateCred(cred);
|
|
791
798
|
}
|
|
792
|
-
this.reconnectInterval = reconnectInterval;
|
|
793
799
|
if (this.validateTimezoneString(dailyRefreshTime)) {
|
|
794
800
|
const dt = this.parseDailyRefreshTime(dailyRefreshTime);
|
|
795
801
|
this.refreshEveryMorning(dt);
|
|
@@ -826,11 +832,11 @@ var WebsocketClient = class extends import_events.EventEmitter {
|
|
|
826
832
|
wsMessageEvent = (msg) => {
|
|
827
833
|
const result = JSON.parse(msg.toString());
|
|
828
834
|
if (result.t === "ck" && result.s.toLowerCase() === "ok") {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
835
|
+
setTimeout(() => {
|
|
836
|
+
this.logger.log("|WSClient| Connected with Shoonya WS.");
|
|
837
|
+
this.emit("connected");
|
|
838
|
+
this.resubscribe();
|
|
839
|
+
}, 3e3);
|
|
834
840
|
}
|
|
835
841
|
if (result.t === "dk") {
|
|
836
842
|
this.logger.log(`Subscribed to ${result.ts}.`);
|
|
@@ -844,6 +850,7 @@ var WebsocketClient = class extends import_events.EventEmitter {
|
|
|
844
850
|
this.emit("orderUpdate", result);
|
|
845
851
|
}
|
|
846
852
|
if (result.lp && result.t === "df") {
|
|
853
|
+
this.retryCount = 0;
|
|
847
854
|
const parsedResult = parseKeysToNumber(
|
|
848
855
|
result
|
|
849
856
|
);
|
|
@@ -856,38 +863,47 @@ var WebsocketClient = class extends import_events.EventEmitter {
|
|
|
856
863
|
this.emit("error", error);
|
|
857
864
|
this.ws.close(0);
|
|
858
865
|
};
|
|
859
|
-
wsCloseEvent = async (code) => {
|
|
866
|
+
wsCloseEvent = async (code, reason) => {
|
|
867
|
+
this.logger.log(
|
|
868
|
+
`WS Close Event: code: ${code}, reason: ${reason.toString()}`
|
|
869
|
+
);
|
|
870
|
+
if (code === 0) {
|
|
871
|
+
this.logger.log("Websocket closed gracefully");
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
860
874
|
if (code === 1) {
|
|
861
875
|
try {
|
|
876
|
+
this.logger.log("Trying to refresh the Access Token");
|
|
862
877
|
await refreshAccessToken();
|
|
863
878
|
this.logger.log("Access Token Refreshed");
|
|
864
879
|
} catch (err) {
|
|
865
|
-
err instanceof Error && this.logger.log(
|
|
880
|
+
err instanceof Error && this.logger.log(
|
|
881
|
+
`Failed to update access token. Err: ${err.message}`,
|
|
882
|
+
"ERROR"
|
|
883
|
+
);
|
|
884
|
+
console.error("Failed to refresh access token", err);
|
|
866
885
|
}
|
|
867
886
|
this.emit("tokenRefresh");
|
|
868
887
|
this.connect();
|
|
869
888
|
return;
|
|
870
889
|
}
|
|
871
|
-
if (
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
this.reconnectTimer = setInterval(() => {
|
|
875
|
-
retryAttempts++;
|
|
876
|
-
this.logger.log(
|
|
877
|
-
`Disconnected with error code ${code}. Attempt ${retryAttempts} to reconnect....`
|
|
878
|
-
);
|
|
879
|
-
this.connect();
|
|
880
|
-
if (this.maxRetryAttempt === retryAttempts) {
|
|
881
|
-
this.logger.log("Max Retry Attempt Reached. Stopped Retrying.");
|
|
882
|
-
clearInterval(this.reconnectInterval);
|
|
883
|
-
}
|
|
884
|
-
}, this.reconnectInterval);
|
|
890
|
+
if (this.retryCount === this.maxRetryAttempt) {
|
|
891
|
+
this.logger.log("Max retry attempt reached. closed the ws");
|
|
892
|
+
this.retryCount = 0;
|
|
885
893
|
return;
|
|
886
894
|
}
|
|
887
|
-
this.
|
|
888
|
-
this.
|
|
895
|
+
this.retryCount++;
|
|
896
|
+
this.logger.log(
|
|
897
|
+
`Disconnected due to ${reason.toString()} with error code ${code}. Attempting to reconnect`
|
|
898
|
+
);
|
|
899
|
+
console.log(`Attempt #${this.retryCount} to reconnect again`);
|
|
900
|
+
this.connect();
|
|
889
901
|
};
|
|
890
|
-
subscribe(scrips) {
|
|
902
|
+
subscribe(scrips, feedType = "Depth") {
|
|
903
|
+
const t = this.validateFeedType(feedType);
|
|
904
|
+
if (!t) {
|
|
905
|
+
return cc.red("Feed Type should be either Depth or Touchline");
|
|
906
|
+
}
|
|
891
907
|
const scripList = Array.isArray(scrips) ? scrips : [scrips];
|
|
892
908
|
const distinctScrips = checkTwoArrayOverlaps(
|
|
893
909
|
this.subscribedTokens,
|
|
@@ -914,9 +930,12 @@ var WebsocketClient = class extends import_events.EventEmitter {
|
|
|
914
930
|
);
|
|
915
931
|
this.send(msg);
|
|
916
932
|
}
|
|
933
|
+
close() {
|
|
934
|
+
this.ws.close(0);
|
|
935
|
+
}
|
|
917
936
|
resubscribe() {
|
|
918
937
|
if (this.subscribedTokens.length) {
|
|
919
|
-
const tokensToSub = this.subscribedTokens;
|
|
938
|
+
const tokensToSub = Array.from(new Set(this.subscribedTokens));
|
|
920
939
|
this.subscribedTokens = [];
|
|
921
940
|
this.subscribe(tokensToSub);
|
|
922
941
|
}
|
|
@@ -924,20 +943,28 @@ var WebsocketClient = class extends import_events.EventEmitter {
|
|
|
924
943
|
send(msg) {
|
|
925
944
|
if (this.ws && this.ws.readyState === this.ws.OPEN) {
|
|
926
945
|
this.ws.send(JSON.stringify(msg));
|
|
946
|
+
} else {
|
|
947
|
+
this.logger.log(
|
|
948
|
+
`didn't send the message ${JSON.stringify(
|
|
949
|
+
msg
|
|
950
|
+
)} due to ws connection being closed`
|
|
951
|
+
);
|
|
927
952
|
}
|
|
928
953
|
}
|
|
929
954
|
refreshEveryMorning = (dt) => {
|
|
930
955
|
const { hour, min } = dt;
|
|
931
956
|
let lastMin = -1;
|
|
957
|
+
this.logger.log("Initialized Infinite Loop");
|
|
932
958
|
setInterval(() => {
|
|
933
959
|
const date = /* @__PURE__ */ new Date();
|
|
934
960
|
const currentMin = date.getUTCMinutes();
|
|
935
961
|
const currentHour = date.getUTCHours();
|
|
936
962
|
if (lastMin !== min && hour === currentHour && min === currentMin) {
|
|
937
|
-
this.logger.log(
|
|
938
|
-
|
|
963
|
+
this.logger.log(
|
|
964
|
+
`refreshing access token at ${currentHour}:${currentMin} - ${lastMin}`
|
|
965
|
+
);
|
|
939
966
|
lastMin = min;
|
|
940
|
-
return;
|
|
967
|
+
return this.ws.close(1, "Reconnection");
|
|
941
968
|
}
|
|
942
969
|
lastMin = -1;
|
|
943
970
|
}, 5e4);
|
|
@@ -979,6 +1006,12 @@ var WebsocketClient = class extends import_events.EventEmitter {
|
|
|
979
1006
|
}
|
|
980
1007
|
return true;
|
|
981
1008
|
};
|
|
1009
|
+
validateFeedType(feedType) {
|
|
1010
|
+
if (feedType === "Depth" || feedType === "Touchline") {
|
|
1011
|
+
return feedType === "Depth" ? "d" : "t";
|
|
1012
|
+
}
|
|
1013
|
+
return null;
|
|
1014
|
+
}
|
|
982
1015
|
};
|
|
983
1016
|
// Annotate the CommonJS export names for ESM import in node:
|
|
984
1017
|
0 && (module.exports = {
|
package/dist/index.d.cts
CHANGED
|
@@ -882,6 +882,7 @@ declare class RestClient {
|
|
|
882
882
|
type LoggerType = "UNIFIED" | "SEPARATE";
|
|
883
883
|
|
|
884
884
|
type DailyTimeString = `${number}:${number}${"+" | "-"}${number}:${number}`;
|
|
885
|
+
type FeedType = "Touchline" | "Depth";
|
|
885
886
|
interface Events {
|
|
886
887
|
open: () => void;
|
|
887
888
|
connected: () => void;
|
|
@@ -903,10 +904,9 @@ declare interface WebsocketClient {
|
|
|
903
904
|
declare class WebsocketClient extends EventEmitter {
|
|
904
905
|
private wsBaseUrl;
|
|
905
906
|
private ws;
|
|
906
|
-
private reconnectInterval;
|
|
907
|
-
private reconnectTimer;
|
|
908
907
|
private subscribedTokens;
|
|
909
908
|
private logger;
|
|
909
|
+
private retryCount;
|
|
910
910
|
private maxRetryAttempt;
|
|
911
911
|
/**
|
|
912
912
|
*
|
|
@@ -919,20 +919,22 @@ declare class WebsocketClient extends EventEmitter {
|
|
|
919
919
|
logging?: boolean;
|
|
920
920
|
cred?: UserCred;
|
|
921
921
|
logFileType?: LoggerType;
|
|
922
|
-
|
|
922
|
+
maxRetryAttempt?: number;
|
|
923
923
|
});
|
|
924
924
|
connect(): void;
|
|
925
925
|
private wsOpenEvent;
|
|
926
926
|
private wsMessageEvent;
|
|
927
927
|
private wsErrorEvent;
|
|
928
928
|
private wsCloseEvent;
|
|
929
|
-
subscribe(scrips: string | string[]): void;
|
|
929
|
+
subscribe(scrips: string | string[], feedType?: FeedType): void;
|
|
930
930
|
unsubscribe(scrips: string | string[]): void;
|
|
931
|
+
close(): void;
|
|
931
932
|
private resubscribe;
|
|
932
933
|
private send;
|
|
933
934
|
private refreshEveryMorning;
|
|
934
935
|
private parseDailyRefreshTime;
|
|
935
936
|
private validateTimezoneString;
|
|
937
|
+
private validateFeedType;
|
|
936
938
|
}
|
|
937
939
|
|
|
938
|
-
export { AddScripToWatchlist, BaseType, BaseTypeFail, BaseTypeSuccess, BaseTypeWithoutTime, BasketMargin, CancelOrder, ChangePassword, DailyTimeString, DepthSubscriptionUpdate, ExchMessage, Exchange, ExitSNOOrder, ForgotPassword, GetClientDetails, GetHSToken, GetLimitsParam, GetListOfPredefinedMW, GetListOfPredefinedMWScrip, GetSecurityInfo, GetTokenExpiry, GetUserDetails, GetWatchlist, GetWatchlistNames, HistoricData, Holdings, IndexList, Limits, Login, LoginWithDevicePin, LogoutResponse, MakeKeysRequired, ModifyOrder, OptionChain, Order, OrderBook, OrderInput, OrderMargin, Path, PlaceOrder, PositionBook, ProductConversion, ProductType, RemoveScripFromWatchlist, RestClient, ScripInfo, SearchScrip, Segment, SetDevicePin, SingleOrderHistory, SingleOrderStatus, TopIndexList, TopIndexListNames, TradeBook, UserCred, ValidateHSToken, WebsocketClient, getQuotes, paths };
|
|
940
|
+
export { AddScripToWatchlist, BaseType, BaseTypeFail, BaseTypeSuccess, BaseTypeWithoutTime, BasketMargin, CancelOrder, ChangePassword, DailyTimeString, DepthSubscriptionUpdate, ExchMessage, Exchange, ExitSNOOrder, FeedType, ForgotPassword, GetClientDetails, GetHSToken, GetLimitsParam, GetListOfPredefinedMW, GetListOfPredefinedMWScrip, GetSecurityInfo, GetTokenExpiry, GetUserDetails, GetWatchlist, GetWatchlistNames, HistoricData, Holdings, IndexList, Limits, Login, LoginWithDevicePin, LogoutResponse, MakeKeysRequired, ModifyOrder, OptionChain, Order, OrderBook, OrderInput, OrderMargin, Path, PlaceOrder, PositionBook, ProductConversion, ProductType, RemoveScripFromWatchlist, RestClient, ScripInfo, SearchScrip, Segment, SetDevicePin, SingleOrderHistory, SingleOrderStatus, TopIndexList, TopIndexListNames, TradeBook, UserCred, ValidateHSToken, WebsocketClient, getQuotes, paths };
|
package/dist/index.d.ts
CHANGED
|
@@ -882,6 +882,7 @@ declare class RestClient {
|
|
|
882
882
|
type LoggerType = "UNIFIED" | "SEPARATE";
|
|
883
883
|
|
|
884
884
|
type DailyTimeString = `${number}:${number}${"+" | "-"}${number}:${number}`;
|
|
885
|
+
type FeedType = "Touchline" | "Depth";
|
|
885
886
|
interface Events {
|
|
886
887
|
open: () => void;
|
|
887
888
|
connected: () => void;
|
|
@@ -903,10 +904,9 @@ declare interface WebsocketClient {
|
|
|
903
904
|
declare class WebsocketClient extends EventEmitter {
|
|
904
905
|
private wsBaseUrl;
|
|
905
906
|
private ws;
|
|
906
|
-
private reconnectInterval;
|
|
907
|
-
private reconnectTimer;
|
|
908
907
|
private subscribedTokens;
|
|
909
908
|
private logger;
|
|
909
|
+
private retryCount;
|
|
910
910
|
private maxRetryAttempt;
|
|
911
911
|
/**
|
|
912
912
|
*
|
|
@@ -919,20 +919,22 @@ declare class WebsocketClient extends EventEmitter {
|
|
|
919
919
|
logging?: boolean;
|
|
920
920
|
cred?: UserCred;
|
|
921
921
|
logFileType?: LoggerType;
|
|
922
|
-
|
|
922
|
+
maxRetryAttempt?: number;
|
|
923
923
|
});
|
|
924
924
|
connect(): void;
|
|
925
925
|
private wsOpenEvent;
|
|
926
926
|
private wsMessageEvent;
|
|
927
927
|
private wsErrorEvent;
|
|
928
928
|
private wsCloseEvent;
|
|
929
|
-
subscribe(scrips: string | string[]): void;
|
|
929
|
+
subscribe(scrips: string | string[], feedType?: FeedType): void;
|
|
930
930
|
unsubscribe(scrips: string | string[]): void;
|
|
931
|
+
close(): void;
|
|
931
932
|
private resubscribe;
|
|
932
933
|
private send;
|
|
933
934
|
private refreshEveryMorning;
|
|
934
935
|
private parseDailyRefreshTime;
|
|
935
936
|
private validateTimezoneString;
|
|
937
|
+
private validateFeedType;
|
|
936
938
|
}
|
|
937
939
|
|
|
938
|
-
export { AddScripToWatchlist, BaseType, BaseTypeFail, BaseTypeSuccess, BaseTypeWithoutTime, BasketMargin, CancelOrder, ChangePassword, DailyTimeString, DepthSubscriptionUpdate, ExchMessage, Exchange, ExitSNOOrder, ForgotPassword, GetClientDetails, GetHSToken, GetLimitsParam, GetListOfPredefinedMW, GetListOfPredefinedMWScrip, GetSecurityInfo, GetTokenExpiry, GetUserDetails, GetWatchlist, GetWatchlistNames, HistoricData, Holdings, IndexList, Limits, Login, LoginWithDevicePin, LogoutResponse, MakeKeysRequired, ModifyOrder, OptionChain, Order, OrderBook, OrderInput, OrderMargin, Path, PlaceOrder, PositionBook, ProductConversion, ProductType, RemoveScripFromWatchlist, RestClient, ScripInfo, SearchScrip, Segment, SetDevicePin, SingleOrderHistory, SingleOrderStatus, TopIndexList, TopIndexListNames, TradeBook, UserCred, ValidateHSToken, WebsocketClient, getQuotes, paths };
|
|
940
|
+
export { AddScripToWatchlist, BaseType, BaseTypeFail, BaseTypeSuccess, BaseTypeWithoutTime, BasketMargin, CancelOrder, ChangePassword, DailyTimeString, DepthSubscriptionUpdate, ExchMessage, Exchange, ExitSNOOrder, FeedType, ForgotPassword, GetClientDetails, GetHSToken, GetLimitsParam, GetListOfPredefinedMW, GetListOfPredefinedMWScrip, GetSecurityInfo, GetTokenExpiry, GetUserDetails, GetWatchlist, GetWatchlistNames, HistoricData, Holdings, IndexList, Limits, Login, LoginWithDevicePin, LogoutResponse, MakeKeysRequired, ModifyOrder, OptionChain, Order, OrderBook, OrderInput, OrderMargin, Path, PlaceOrder, PositionBook, ProductConversion, ProductType, RemoveScripFromWatchlist, RestClient, ScripInfo, SearchScrip, Segment, SetDevicePin, SingleOrderHistory, SingleOrderStatus, TopIndexList, TopIndexListNames, TradeBook, UserCred, ValidateHSToken, WebsocketClient, getQuotes, paths };
|
package/dist/index.js
CHANGED
|
@@ -106,7 +106,7 @@ var Tokens = class {
|
|
|
106
106
|
}
|
|
107
107
|
};
|
|
108
108
|
var tokens = new Tokens();
|
|
109
|
-
async function refreshAccessToken() {
|
|
109
|
+
async function refreshAccessToken(retryCount = 3) {
|
|
110
110
|
const userCred = tokens.getCred();
|
|
111
111
|
const cred = {
|
|
112
112
|
apkversion: "1.0.0",
|
|
@@ -118,14 +118,23 @@ async function refreshAccessToken() {
|
|
|
118
118
|
imei: userCred?.imei || "api",
|
|
119
119
|
source: "API"
|
|
120
120
|
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
let errorMsg = "";
|
|
122
|
+
for (let i = 0; i < retryCount; i++) {
|
|
123
|
+
try {
|
|
124
|
+
const req = await request("login", { data: cred });
|
|
125
|
+
tokens.updateAccessToken(req.susertoken);
|
|
126
|
+
return;
|
|
127
|
+
} catch (err) {
|
|
128
|
+
let errMsg = "Couldn't Refresh the Access Token. ";
|
|
129
|
+
if (err instanceof Error) {
|
|
130
|
+
errMsg += `Error: ${err.message}`;
|
|
131
|
+
}
|
|
132
|
+
errorMsg += `${errMsg}, `;
|
|
133
|
+
}
|
|
128
134
|
}
|
|
135
|
+
throw new Error(
|
|
136
|
+
`Attempted to refresh access token ${retryCount} times. but failed. Errors: ${errorMsg}`
|
|
137
|
+
);
|
|
129
138
|
}
|
|
130
139
|
__name(refreshAccessToken, "refreshAccessToken");
|
|
131
140
|
|
|
@@ -726,10 +735,9 @@ var WebsocketClient = class extends EventEmitter {
|
|
|
726
735
|
}
|
|
727
736
|
wsBaseUrl = "wss://api.shoonya.com/NorenWSTP/";
|
|
728
737
|
ws;
|
|
729
|
-
reconnectInterval;
|
|
730
|
-
reconnectTimer;
|
|
731
738
|
subscribedTokens = [];
|
|
732
739
|
logger;
|
|
740
|
+
retryCount = 0;
|
|
733
741
|
maxRetryAttempt;
|
|
734
742
|
/**
|
|
735
743
|
*
|
|
@@ -739,14 +747,13 @@ var WebsocketClient = class extends EventEmitter {
|
|
|
739
747
|
constructor(params) {
|
|
740
748
|
super();
|
|
741
749
|
const {
|
|
742
|
-
|
|
743
|
-
dailyRefreshTime = "09:10+05:30",
|
|
750
|
+
dailyRefreshTime = "09:13+05:30",
|
|
744
751
|
cred,
|
|
745
752
|
logging = false,
|
|
746
753
|
logFileType = "SEPARATE",
|
|
747
|
-
|
|
754
|
+
maxRetryAttempt = 3
|
|
748
755
|
} = params || {};
|
|
749
|
-
this.maxRetryAttempt =
|
|
756
|
+
this.maxRetryAttempt = maxRetryAttempt;
|
|
750
757
|
this.logger = new logger_default(
|
|
751
758
|
"shoonya_ws-client",
|
|
752
759
|
1024 * 1024 * 10,
|
|
@@ -761,7 +768,6 @@ var WebsocketClient = class extends EventEmitter {
|
|
|
761
768
|
if (!storedCred.userId) {
|
|
762
769
|
tokens.updateCred(cred);
|
|
763
770
|
}
|
|
764
|
-
this.reconnectInterval = reconnectInterval;
|
|
765
771
|
if (this.validateTimezoneString(dailyRefreshTime)) {
|
|
766
772
|
const dt = this.parseDailyRefreshTime(dailyRefreshTime);
|
|
767
773
|
this.refreshEveryMorning(dt);
|
|
@@ -798,11 +804,11 @@ var WebsocketClient = class extends EventEmitter {
|
|
|
798
804
|
wsMessageEvent = (msg) => {
|
|
799
805
|
const result = JSON.parse(msg.toString());
|
|
800
806
|
if (result.t === "ck" && result.s.toLowerCase() === "ok") {
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
807
|
+
setTimeout(() => {
|
|
808
|
+
this.logger.log("|WSClient| Connected with Shoonya WS.");
|
|
809
|
+
this.emit("connected");
|
|
810
|
+
this.resubscribe();
|
|
811
|
+
}, 3e3);
|
|
806
812
|
}
|
|
807
813
|
if (result.t === "dk") {
|
|
808
814
|
this.logger.log(`Subscribed to ${result.ts}.`);
|
|
@@ -816,6 +822,7 @@ var WebsocketClient = class extends EventEmitter {
|
|
|
816
822
|
this.emit("orderUpdate", result);
|
|
817
823
|
}
|
|
818
824
|
if (result.lp && result.t === "df") {
|
|
825
|
+
this.retryCount = 0;
|
|
819
826
|
const parsedResult = parseKeysToNumber(
|
|
820
827
|
result
|
|
821
828
|
);
|
|
@@ -828,38 +835,47 @@ var WebsocketClient = class extends EventEmitter {
|
|
|
828
835
|
this.emit("error", error);
|
|
829
836
|
this.ws.close(0);
|
|
830
837
|
};
|
|
831
|
-
wsCloseEvent = async (code) => {
|
|
838
|
+
wsCloseEvent = async (code, reason) => {
|
|
839
|
+
this.logger.log(
|
|
840
|
+
`WS Close Event: code: ${code}, reason: ${reason.toString()}`
|
|
841
|
+
);
|
|
842
|
+
if (code === 0) {
|
|
843
|
+
this.logger.log("Websocket closed gracefully");
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
832
846
|
if (code === 1) {
|
|
833
847
|
try {
|
|
848
|
+
this.logger.log("Trying to refresh the Access Token");
|
|
834
849
|
await refreshAccessToken();
|
|
835
850
|
this.logger.log("Access Token Refreshed");
|
|
836
851
|
} catch (err) {
|
|
837
|
-
err instanceof Error && this.logger.log(
|
|
852
|
+
err instanceof Error && this.logger.log(
|
|
853
|
+
`Failed to update access token. Err: ${err.message}`,
|
|
854
|
+
"ERROR"
|
|
855
|
+
);
|
|
856
|
+
console.error("Failed to refresh access token", err);
|
|
838
857
|
}
|
|
839
858
|
this.emit("tokenRefresh");
|
|
840
859
|
this.connect();
|
|
841
860
|
return;
|
|
842
861
|
}
|
|
843
|
-
if (
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
this.reconnectTimer = setInterval(() => {
|
|
847
|
-
retryAttempts++;
|
|
848
|
-
this.logger.log(
|
|
849
|
-
`Disconnected with error code ${code}. Attempt ${retryAttempts} to reconnect....`
|
|
850
|
-
);
|
|
851
|
-
this.connect();
|
|
852
|
-
if (this.maxRetryAttempt === retryAttempts) {
|
|
853
|
-
this.logger.log("Max Retry Attempt Reached. Stopped Retrying.");
|
|
854
|
-
clearInterval(this.reconnectInterval);
|
|
855
|
-
}
|
|
856
|
-
}, this.reconnectInterval);
|
|
862
|
+
if (this.retryCount === this.maxRetryAttempt) {
|
|
863
|
+
this.logger.log("Max retry attempt reached. closed the ws");
|
|
864
|
+
this.retryCount = 0;
|
|
857
865
|
return;
|
|
858
866
|
}
|
|
859
|
-
this.
|
|
860
|
-
this.
|
|
867
|
+
this.retryCount++;
|
|
868
|
+
this.logger.log(
|
|
869
|
+
`Disconnected due to ${reason.toString()} with error code ${code}. Attempting to reconnect`
|
|
870
|
+
);
|
|
871
|
+
console.log(`Attempt #${this.retryCount} to reconnect again`);
|
|
872
|
+
this.connect();
|
|
861
873
|
};
|
|
862
|
-
subscribe(scrips) {
|
|
874
|
+
subscribe(scrips, feedType = "Depth") {
|
|
875
|
+
const t = this.validateFeedType(feedType);
|
|
876
|
+
if (!t) {
|
|
877
|
+
return cc.red("Feed Type should be either Depth or Touchline");
|
|
878
|
+
}
|
|
863
879
|
const scripList = Array.isArray(scrips) ? scrips : [scrips];
|
|
864
880
|
const distinctScrips = checkTwoArrayOverlaps(
|
|
865
881
|
this.subscribedTokens,
|
|
@@ -886,9 +902,12 @@ var WebsocketClient = class extends EventEmitter {
|
|
|
886
902
|
);
|
|
887
903
|
this.send(msg);
|
|
888
904
|
}
|
|
905
|
+
close() {
|
|
906
|
+
this.ws.close(0);
|
|
907
|
+
}
|
|
889
908
|
resubscribe() {
|
|
890
909
|
if (this.subscribedTokens.length) {
|
|
891
|
-
const tokensToSub = this.subscribedTokens;
|
|
910
|
+
const tokensToSub = Array.from(new Set(this.subscribedTokens));
|
|
892
911
|
this.subscribedTokens = [];
|
|
893
912
|
this.subscribe(tokensToSub);
|
|
894
913
|
}
|
|
@@ -896,20 +915,28 @@ var WebsocketClient = class extends EventEmitter {
|
|
|
896
915
|
send(msg) {
|
|
897
916
|
if (this.ws && this.ws.readyState === this.ws.OPEN) {
|
|
898
917
|
this.ws.send(JSON.stringify(msg));
|
|
918
|
+
} else {
|
|
919
|
+
this.logger.log(
|
|
920
|
+
`didn't send the message ${JSON.stringify(
|
|
921
|
+
msg
|
|
922
|
+
)} due to ws connection being closed`
|
|
923
|
+
);
|
|
899
924
|
}
|
|
900
925
|
}
|
|
901
926
|
refreshEveryMorning = (dt) => {
|
|
902
927
|
const { hour, min } = dt;
|
|
903
928
|
let lastMin = -1;
|
|
929
|
+
this.logger.log("Initialized Infinite Loop");
|
|
904
930
|
setInterval(() => {
|
|
905
931
|
const date = /* @__PURE__ */ new Date();
|
|
906
932
|
const currentMin = date.getUTCMinutes();
|
|
907
933
|
const currentHour = date.getUTCHours();
|
|
908
934
|
if (lastMin !== min && hour === currentHour && min === currentMin) {
|
|
909
|
-
this.logger.log(
|
|
910
|
-
|
|
935
|
+
this.logger.log(
|
|
936
|
+
`refreshing access token at ${currentHour}:${currentMin} - ${lastMin}`
|
|
937
|
+
);
|
|
911
938
|
lastMin = min;
|
|
912
|
-
return;
|
|
939
|
+
return this.ws.close(1, "Reconnection");
|
|
913
940
|
}
|
|
914
941
|
lastMin = -1;
|
|
915
942
|
}, 5e4);
|
|
@@ -951,6 +978,12 @@ var WebsocketClient = class extends EventEmitter {
|
|
|
951
978
|
}
|
|
952
979
|
return true;
|
|
953
980
|
};
|
|
981
|
+
validateFeedType(feedType) {
|
|
982
|
+
if (feedType === "Depth" || feedType === "Touchline") {
|
|
983
|
+
return feedType === "Depth" ? "d" : "t";
|
|
984
|
+
}
|
|
985
|
+
return null;
|
|
986
|
+
}
|
|
954
987
|
};
|
|
955
988
|
export {
|
|
956
989
|
RestClient,
|