shoonya-sdk 0.5.0 → 0.5.1

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.
@@ -84,6 +84,7 @@ var Logger = class {
84
84
  logPath = "";
85
85
  maxSize = 0;
86
86
  fileName = "";
87
+ logging = false;
87
88
  /**
88
89
  *
89
90
  * @param logFileName name to prepend the logs file with
@@ -96,6 +97,8 @@ var Logger = class {
96
97
  this.checkPathExistance();
97
98
  }
98
99
  log(msg, logType = "DEBUG") {
100
+ if (!this.logging)
101
+ return;
99
102
  const content = `${logType}:[${(/* @__PURE__ */ new Date()).toISOString()}]:${msg}
100
103
  `;
101
104
  (0, import_node_fs.appendFileSync)(this.logPath, content);
@@ -252,6 +255,7 @@ var RetryManager = class extends import_events.EventEmitter {
252
255
  };
253
256
 
254
257
  // src/shoonya-sdk.ts
258
+ var import_promises = require("timers/promises");
255
259
  var Shoonya = class extends RetryManager {
256
260
  static {
257
261
  __name(this, "Shoonya");
@@ -259,7 +263,6 @@ var Shoonya = class extends RetryManager {
259
263
  accessToken;
260
264
  userId;
261
265
  logger;
262
- logging = false;
263
266
  httpBaseUrl = "https://api.shoonya.com/NorenWClientTP/";
264
267
  wsBaseUrl = "wss://api.shoonya.com/NorenWSTP/";
265
268
  ws;
@@ -286,7 +289,6 @@ var Shoonya = class extends RetryManager {
286
289
  this.userId = "";
287
290
  this.accessToken = "";
288
291
  this.accountId = this.userId;
289
- this.logging = logging;
290
292
  this.reconnectTimeout = { timer: null, timeout: reconnectTimeout };
291
293
  this.heartbeatTimeout = { timer: null, timeout: heartbeatTimeout };
292
294
  if (logging) {
@@ -295,29 +297,65 @@ var Shoonya = class extends RetryManager {
295
297
  1024 * 100
296
298
  //1KB * 100 = 100KB
297
299
  );
300
+ this.logger.logging = logging;
298
301
  }
299
- this.on("resub", (token) => {
300
- this.subscribeUnsafe([token]);
302
+ this.on("resub", async (token) => {
303
+ for (let i = this.scripList.length - 1; i >= 0; i--) {
304
+ const t = this.scripList[i];
305
+ if (t === token) {
306
+ this.unsubscribe([token]);
307
+ this.scripList.splice(i, 1);
308
+ await this.login({
309
+ apiKey: this.apiKey,
310
+ password: this.password,
311
+ twoFa: this.twoFa,
312
+ userId: this.userId
313
+ });
314
+ const msg = {
315
+ t: "c",
316
+ uid: this.userId,
317
+ actid: this.accountId,
318
+ source: "API",
319
+ susertoken: this.accessToken
320
+ };
321
+ this.ws.send(JSON.stringify(msg));
322
+ await (0, import_promises.setTimeout)(100);
323
+ this.subscribe([token]);
324
+ this.logger.log("Resubscribed to" + token);
325
+ break;
326
+ }
327
+ }
301
328
  });
302
329
  }
303
330
  async request(path, body) {
304
331
  const jData = `jData=${JSON.stringify(body.data)}${body.key ? "&jKey=" + body.key : ""}`;
305
332
  try {
306
- const data = await fetch(this.httpBaseUrl + paths[path], {
333
+ const req = await fetch(this.httpBaseUrl + paths[path], {
307
334
  method: "POST",
308
335
  body: jData,
309
- keepalive: true
310
- }).then((res) => {
311
- return res.json();
336
+ keepalive: false
312
337
  });
338
+ let data = await req.json();
339
+ if ("emsg" in data && data.emsg.includes("Session Expired")) {
340
+ await this.login({
341
+ apiKey: this.apiKey,
342
+ password: this.password,
343
+ twoFa: this.twoFa,
344
+ userId: this.userId
345
+ });
346
+ const newJData = `jData=${JSON.stringify(body.data)}${body.key ? "&jKey=" + this.accessToken : ""}`;
347
+ const newReq = await fetch(this.httpBaseUrl + paths[path], {
348
+ method: "POST",
349
+ body: newJData,
350
+ keepalive: false
351
+ });
352
+ data = await newReq.json();
353
+ }
313
354
  return data;
314
355
  } catch (err) {
315
- if (this.logging) {
316
- const errMessage = "Failed to fetch data from api while performing: " + path;
317
- this.logger.log(errMessage, "ERROR");
318
- console.error(errMessage);
319
- }
320
- console.error(err);
356
+ const errMessage = `Error: ${err?.message} in ${path}`;
357
+ this.logger.log(errMessage, "ERROR");
358
+ console.error(errMessage);
321
359
  }
322
360
  }
323
361
  // Rest API
@@ -347,12 +385,10 @@ var Shoonya = class extends RetryManager {
347
385
  this.twoFa = rawCred.twoFa;
348
386
  return req;
349
387
  } catch (err) {
350
- if (this.logging) {
351
- const fallBackMessage = "Attempted to login but it failed";
352
- const errMessage = err?.message || fallBackMessage;
353
- this.logger.log(errMessage, "ERROR");
354
- console.error(errMessage);
355
- }
388
+ const fallBackMessage = "Attempted to login but it failed";
389
+ const errMessage = err?.message || fallBackMessage;
390
+ this.logger.log(errMessage, "ERROR");
391
+ console.error(errMessage);
356
392
  console.error("Login Failed", err);
357
393
  }
358
394
  }
@@ -730,11 +766,11 @@ var Shoonya = class extends RetryManager {
730
766
  await this.login(cred);
731
767
  this.connectWS();
732
768
  this.emit("open", "opened ws connection");
733
- this.logging && this.logger.log("Token Refreshed");
769
+ this.logger.log("Token successfully refreshed");
734
770
  } catch (err) {
735
771
  console.error(err);
736
772
  const errMessage = `Token refreshing failed. ERR: ${err.message}`;
737
- this.logging && this.logger.log(errMessage, "ERROR");
773
+ this.logger.log(errMessage, "ERROR");
738
774
  this.getWSState().OPEN && this.ws.close();
739
775
  this.emit("stopped", errMessage);
740
776
  }
@@ -746,7 +782,7 @@ var Shoonya = class extends RetryManager {
746
782
  const result = JSON.parse(e.data.toString());
747
783
  this.lastWsMsgAt = /* @__PURE__ */ new Date();
748
784
  if (result.t === "dk") {
749
- this.logging && this.logger.log(`Subscribed to ${result.ts}. Listening...`);
785
+ this.logger.log(`Subscribed to ${result.ts}. Listening...`);
750
786
  }
751
787
  if (result.lp && result.t === "df") {
752
788
  this.resetTimerForToken(result.tk, result.e);
@@ -759,7 +795,7 @@ var Shoonya = class extends RetryManager {
759
795
  clearTimeout(this.connectTimer);
760
796
  this.connectTimer = setTimeout(() => {
761
797
  this.emit("connect", e);
762
- this.logging && this.logger.log("Connected with Shoonya API! Streaming Data...");
798
+ this.logger.log("Connected with Shoonya API! Streaming Data...");
763
799
  this.subscribeAgain(this.scripList);
764
800
  }, 3e3);
765
801
  return;
@@ -783,13 +819,13 @@ var Shoonya = class extends RetryManager {
783
819
  if (day in [5, 6])
784
820
  return;
785
821
  const err = "API have stopped to respond! there could be a problem with API or market has closed";
786
- this.logging && this.logger.log(err, "WARN");
822
+ this.logger.log(err, "WARN");
787
823
  this.emit("stopped", err);
788
824
  this.getWSState().OPEN && this.ws.close();
789
825
  }, 6e4 * 60 * 18 - 1e4);
790
826
  });
791
827
  this.ws.addEventListener("error", (e) => {
792
- this.logging && this.logger.log("some error in ws");
828
+ this.logger.log("some error in ws");
793
829
  this.emit("error", e);
794
830
  this.getWSState().OPEN && this.ws.close();
795
831
  });
@@ -834,6 +870,7 @@ var Shoonya = class extends RetryManager {
834
870
  for (const val of distinctScrips) {
835
871
  this.scripList.push(val);
836
872
  }
873
+ this.logger.log(JSON.stringify(msg));
837
874
  this.ws && this.ws.send(JSON.stringify(msg));
838
875
  }
839
876
  unsubscribe(scripList) {
@@ -849,6 +886,13 @@ var Shoonya = class extends RetryManager {
849
886
  }
850
887
  }
851
888
  }
889
+ /**
890
+ * Unsubscribe All while removing the tokens from this.scripList
891
+ */
892
+ unsubscribeAllWhileClearing() {
893
+ this.unsubscribe(this.scripList);
894
+ return this.scripList.splice(0);
895
+ }
852
896
  /**
853
897
  * This method will not check if token is already subscribed or not before sending subscribe request
854
898
  *
@@ -888,7 +932,7 @@ var Shoonya = class extends RetryManager {
888
932
  if (this.getWSState().OPEN || this.getWSState().CONNECTING) {
889
933
  clearInterval(this.heartbeatTimeout.timer);
890
934
  this.ws.close();
891
- this.logging && this.logger.log("Websocket Connection with Shoonya API is now closed!");
935
+ this.logger.log("Websocket Connection with Shoonya API is now closed!");
892
936
  this.emit("close");
893
937
  }
894
938
  }
@@ -280,6 +280,7 @@ declare class Logger {
280
280
  logPath: string;
281
281
  maxSize: number;
282
282
  fileName: string;
283
+ logging: boolean;
283
284
  /**
284
285
  *
285
286
  * @param logFileName name to prepend the logs file with
@@ -340,7 +341,6 @@ declare class Shoonya extends RetryManager {
340
341
  accessToken: string;
341
342
  userId: string;
342
343
  logger: Logger;
343
- private logging;
344
344
  private readonly httpBaseUrl;
345
345
  private readonly wsBaseUrl;
346
346
  private ws;
@@ -507,6 +507,10 @@ declare class Shoonya extends RetryManager {
507
507
  */
508
508
  subscribe(scripList: string[]): void;
509
509
  unsubscribe(scripList: string[]): void;
510
+ /**
511
+ * Unsubscribe All while removing the tokens from this.scripList
512
+ */
513
+ unsubscribeAllWhileClearing(): string[];
510
514
  /**
511
515
  * This method will not check if token is already subscribed or not before sending subscribe request
512
516
  *
@@ -280,6 +280,7 @@ declare class Logger {
280
280
  logPath: string;
281
281
  maxSize: number;
282
282
  fileName: string;
283
+ logging: boolean;
283
284
  /**
284
285
  *
285
286
  * @param logFileName name to prepend the logs file with
@@ -340,7 +341,6 @@ declare class Shoonya extends RetryManager {
340
341
  accessToken: string;
341
342
  userId: string;
342
343
  logger: Logger;
343
- private logging;
344
344
  private readonly httpBaseUrl;
345
345
  private readonly wsBaseUrl;
346
346
  private ws;
@@ -507,6 +507,10 @@ declare class Shoonya extends RetryManager {
507
507
  */
508
508
  subscribe(scripList: string[]): void;
509
509
  unsubscribe(scripList: string[]): void;
510
+ /**
511
+ * Unsubscribe All while removing the tokens from this.scripList
512
+ */
513
+ unsubscribeAllWhileClearing(): string[];
510
514
  /**
511
515
  * This method will not check if token is already subscribed or not before sending subscribe request
512
516
  *
@@ -58,6 +58,7 @@ var Logger = class {
58
58
  logPath = "";
59
59
  maxSize = 0;
60
60
  fileName = "";
61
+ logging = false;
61
62
  /**
62
63
  *
63
64
  * @param logFileName name to prepend the logs file with
@@ -70,6 +71,8 @@ var Logger = class {
70
71
  this.checkPathExistance();
71
72
  }
72
73
  log(msg, logType = "DEBUG") {
74
+ if (!this.logging)
75
+ return;
73
76
  const content = `${logType}:[${(/* @__PURE__ */ new Date()).toISOString()}]:${msg}
74
77
  `;
75
78
  appendFileSync(this.logPath, content);
@@ -226,6 +229,7 @@ var RetryManager = class extends EventEmitter {
226
229
  };
227
230
 
228
231
  // src/shoonya-sdk.ts
232
+ import { setTimeout as wait } from "timers/promises";
229
233
  var Shoonya = class extends RetryManager {
230
234
  static {
231
235
  __name(this, "Shoonya");
@@ -233,7 +237,6 @@ var Shoonya = class extends RetryManager {
233
237
  accessToken;
234
238
  userId;
235
239
  logger;
236
- logging = false;
237
240
  httpBaseUrl = "https://api.shoonya.com/NorenWClientTP/";
238
241
  wsBaseUrl = "wss://api.shoonya.com/NorenWSTP/";
239
242
  ws;
@@ -260,7 +263,6 @@ var Shoonya = class extends RetryManager {
260
263
  this.userId = "";
261
264
  this.accessToken = "";
262
265
  this.accountId = this.userId;
263
- this.logging = logging;
264
266
  this.reconnectTimeout = { timer: null, timeout: reconnectTimeout };
265
267
  this.heartbeatTimeout = { timer: null, timeout: heartbeatTimeout };
266
268
  if (logging) {
@@ -269,29 +271,65 @@ var Shoonya = class extends RetryManager {
269
271
  1024 * 100
270
272
  //1KB * 100 = 100KB
271
273
  );
274
+ this.logger.logging = logging;
272
275
  }
273
- this.on("resub", (token) => {
274
- this.subscribeUnsafe([token]);
276
+ this.on("resub", async (token) => {
277
+ for (let i = this.scripList.length - 1; i >= 0; i--) {
278
+ const t = this.scripList[i];
279
+ if (t === token) {
280
+ this.unsubscribe([token]);
281
+ this.scripList.splice(i, 1);
282
+ await this.login({
283
+ apiKey: this.apiKey,
284
+ password: this.password,
285
+ twoFa: this.twoFa,
286
+ userId: this.userId
287
+ });
288
+ const msg = {
289
+ t: "c",
290
+ uid: this.userId,
291
+ actid: this.accountId,
292
+ source: "API",
293
+ susertoken: this.accessToken
294
+ };
295
+ this.ws.send(JSON.stringify(msg));
296
+ await wait(100);
297
+ this.subscribe([token]);
298
+ this.logger.log("Resubscribed to" + token);
299
+ break;
300
+ }
301
+ }
275
302
  });
276
303
  }
277
304
  async request(path, body) {
278
305
  const jData = `jData=${JSON.stringify(body.data)}${body.key ? "&jKey=" + body.key : ""}`;
279
306
  try {
280
- const data = await fetch(this.httpBaseUrl + paths[path], {
307
+ const req = await fetch(this.httpBaseUrl + paths[path], {
281
308
  method: "POST",
282
309
  body: jData,
283
- keepalive: true
284
- }).then((res) => {
285
- return res.json();
310
+ keepalive: false
286
311
  });
312
+ let data = await req.json();
313
+ if ("emsg" in data && data.emsg.includes("Session Expired")) {
314
+ await this.login({
315
+ apiKey: this.apiKey,
316
+ password: this.password,
317
+ twoFa: this.twoFa,
318
+ userId: this.userId
319
+ });
320
+ const newJData = `jData=${JSON.stringify(body.data)}${body.key ? "&jKey=" + this.accessToken : ""}`;
321
+ const newReq = await fetch(this.httpBaseUrl + paths[path], {
322
+ method: "POST",
323
+ body: newJData,
324
+ keepalive: false
325
+ });
326
+ data = await newReq.json();
327
+ }
287
328
  return data;
288
329
  } catch (err) {
289
- if (this.logging) {
290
- const errMessage = "Failed to fetch data from api while performing: " + path;
291
- this.logger.log(errMessage, "ERROR");
292
- console.error(errMessage);
293
- }
294
- console.error(err);
330
+ const errMessage = `Error: ${err?.message} in ${path}`;
331
+ this.logger.log(errMessage, "ERROR");
332
+ console.error(errMessage);
295
333
  }
296
334
  }
297
335
  // Rest API
@@ -321,12 +359,10 @@ var Shoonya = class extends RetryManager {
321
359
  this.twoFa = rawCred.twoFa;
322
360
  return req;
323
361
  } catch (err) {
324
- if (this.logging) {
325
- const fallBackMessage = "Attempted to login but it failed";
326
- const errMessage = err?.message || fallBackMessage;
327
- this.logger.log(errMessage, "ERROR");
328
- console.error(errMessage);
329
- }
362
+ const fallBackMessage = "Attempted to login but it failed";
363
+ const errMessage = err?.message || fallBackMessage;
364
+ this.logger.log(errMessage, "ERROR");
365
+ console.error(errMessage);
330
366
  console.error("Login Failed", err);
331
367
  }
332
368
  }
@@ -704,11 +740,11 @@ var Shoonya = class extends RetryManager {
704
740
  await this.login(cred);
705
741
  this.connectWS();
706
742
  this.emit("open", "opened ws connection");
707
- this.logging && this.logger.log("Token Refreshed");
743
+ this.logger.log("Token successfully refreshed");
708
744
  } catch (err) {
709
745
  console.error(err);
710
746
  const errMessage = `Token refreshing failed. ERR: ${err.message}`;
711
- this.logging && this.logger.log(errMessage, "ERROR");
747
+ this.logger.log(errMessage, "ERROR");
712
748
  this.getWSState().OPEN && this.ws.close();
713
749
  this.emit("stopped", errMessage);
714
750
  }
@@ -720,7 +756,7 @@ var Shoonya = class extends RetryManager {
720
756
  const result = JSON.parse(e.data.toString());
721
757
  this.lastWsMsgAt = /* @__PURE__ */ new Date();
722
758
  if (result.t === "dk") {
723
- this.logging && this.logger.log(`Subscribed to ${result.ts}. Listening...`);
759
+ this.logger.log(`Subscribed to ${result.ts}. Listening...`);
724
760
  }
725
761
  if (result.lp && result.t === "df") {
726
762
  this.resetTimerForToken(result.tk, result.e);
@@ -733,7 +769,7 @@ var Shoonya = class extends RetryManager {
733
769
  clearTimeout(this.connectTimer);
734
770
  this.connectTimer = setTimeout(() => {
735
771
  this.emit("connect", e);
736
- this.logging && this.logger.log("Connected with Shoonya API! Streaming Data...");
772
+ this.logger.log("Connected with Shoonya API! Streaming Data...");
737
773
  this.subscribeAgain(this.scripList);
738
774
  }, 3e3);
739
775
  return;
@@ -757,13 +793,13 @@ var Shoonya = class extends RetryManager {
757
793
  if (day in [5, 6])
758
794
  return;
759
795
  const err = "API have stopped to respond! there could be a problem with API or market has closed";
760
- this.logging && this.logger.log(err, "WARN");
796
+ this.logger.log(err, "WARN");
761
797
  this.emit("stopped", err);
762
798
  this.getWSState().OPEN && this.ws.close();
763
799
  }, 6e4 * 60 * 18 - 1e4);
764
800
  });
765
801
  this.ws.addEventListener("error", (e) => {
766
- this.logging && this.logger.log("some error in ws");
802
+ this.logger.log("some error in ws");
767
803
  this.emit("error", e);
768
804
  this.getWSState().OPEN && this.ws.close();
769
805
  });
@@ -808,6 +844,7 @@ var Shoonya = class extends RetryManager {
808
844
  for (const val of distinctScrips) {
809
845
  this.scripList.push(val);
810
846
  }
847
+ this.logger.log(JSON.stringify(msg));
811
848
  this.ws && this.ws.send(JSON.stringify(msg));
812
849
  }
813
850
  unsubscribe(scripList) {
@@ -823,6 +860,13 @@ var Shoonya = class extends RetryManager {
823
860
  }
824
861
  }
825
862
  }
863
+ /**
864
+ * Unsubscribe All while removing the tokens from this.scripList
865
+ */
866
+ unsubscribeAllWhileClearing() {
867
+ this.unsubscribe(this.scripList);
868
+ return this.scripList.splice(0);
869
+ }
826
870
  /**
827
871
  * This method will not check if token is already subscribed or not before sending subscribe request
828
872
  *
@@ -862,7 +906,7 @@ var Shoonya = class extends RetryManager {
862
906
  if (this.getWSState().OPEN || this.getWSState().CONNECTING) {
863
907
  clearInterval(this.heartbeatTimeout.timer);
864
908
  this.ws.close();
865
- this.logging && this.logger.log("Websocket Connection with Shoonya API is now closed!");
909
+ this.logger.log("Websocket Connection with Shoonya API is now closed!");
866
910
  this.emit("close");
867
911
  }
868
912
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shoonya-sdk",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Wrapper around Shoonya API",
5
5
  "main": "dist/shoonya-sdk.js",
6
6
  "module": "dist/shoonya-sdk.mjs",