firstock 1.0.8 → 1.1.0

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/Readme.md CHANGED
@@ -5,7 +5,7 @@ To communicate with the Firstock Developer API using Nodejs, you can use the off
5
5
  Licensed under the MIT License.
6
6
 
7
7
 
8
- [Version - 1.0.7](https://www.npmjs.com/package/firstock)
8
+ [Version - 1.0.9](https://www.npmjs.com/package/firstock)
9
9
 
10
10
 
11
11
  ## Documentation
@@ -229,5 +229,35 @@ declare abstract class AFirstock {
229
229
  abstract getExpiry(params: GetExpiryParams, callBack: (error: Error | string | null, result: Response | null) => void): void;
230
230
  abstract brokerageCalculator(params: BrokerageCalculatorParams, callBack: (error: Error | string | null, result: Response | null) => void): void;
231
231
  abstract getHoldingsDetails(params: GetHoldingsParams, callBack: (error: Error | null, result: Response | null) => void): void;
232
+ abstract initializeWebsockets(userId: string, model: any, config?: any): Promise<[any | null, {
233
+ error: {
234
+ message: string;
235
+ };
236
+ } | null]>;
237
+ abstract closeWebsocket(ws: any | null): Promise<{
238
+ error: {
239
+ message: string;
240
+ };
241
+ } | null>;
242
+ abstract subscribe(ws: any | null, tokens: string[]): Promise<{
243
+ error: {
244
+ message: string;
245
+ };
246
+ } | null>;
247
+ abstract unsubscribe(ws: any | null, tokens: string[]): Promise<{
248
+ error: {
249
+ message: string;
250
+ };
251
+ } | null>;
252
+ abstract subscribeOptionGreeks(ws: any | null, tokens: string[]): Promise<{
253
+ error: {
254
+ message: string;
255
+ };
256
+ } | null>;
257
+ abstract unsubscribeOptionGreeks(ws: any | null, tokens: string[]): Promise<{
258
+ error: {
259
+ message: string;
260
+ };
261
+ } | null>;
232
262
  }
233
263
  export default AFirstock;
@@ -1,4 +1,7 @@
1
+ import WebSocket from "ws";
1
2
  import AFirstock from "./AFirstock";
3
+ import { FirstockWebSocket } from "../websockets/websockets";
4
+ import { Config } from "../websockets/websocket_functions";
2
5
  interface Response {
3
6
  data: {
4
7
  [key: string]: any;
@@ -932,5 +935,84 @@ export declare class Firstock extends AFirstock {
932
935
  * - `result`: Parsed response containing holdings information if successful.
933
936
  */
934
937
  getHoldingsDetails({ userId }: GetHoldingsParams, callBack: (error: Error | null, result: Response | null) => void): void;
938
+ /**
939
+ * Initializes a WebSocket connection to Firstock for real-time market data streaming.
940
+ *
941
+ * @param {string} userId - The user ID for authentication.
942
+ * @param {FirstockWebSocket} model - WebSocket model containing tokens and subscriptions.
943
+ * @param {Config} [config] - Optional configuration for WebSocket connection.
944
+ * @returns {Promise<[WebSocket | null, { error: { message: string } } | null]>}
945
+ * A promise that resolves to a tuple containing the WebSocket instance (or null on error)
946
+ * and an error object (or null on success).
947
+ */
948
+ initializeWebsockets(userId: string, model: FirstockWebSocket, config?: Config): Promise<[WebSocket | null, {
949
+ error: {
950
+ message: string;
951
+ };
952
+ } | null]>;
953
+ /**
954
+ * Closes an active WebSocket connection.
955
+ *
956
+ * @param {WebSocket | null} ws - The WebSocket instance to close.
957
+ * @returns {Promise<{ error: { message: string } } | null>}
958
+ * A promise that resolves to an error object if closure fails, or null on success.
959
+ */
960
+ closeWebsocket(ws: WebSocket | null): Promise<{
961
+ error: {
962
+ message: string;
963
+ };
964
+ } | null>;
965
+ /**
966
+ * Subscribes to market data for specified tokens.
967
+ *
968
+ * @param {WebSocket | null} ws - The WebSocket instance.
969
+ * @param {string[]} tokens - Array of token strings to subscribe to.
970
+ * @returns {Promise<{ error: { message: string } } | null>}
971
+ * A promise that resolves to an error object on failure, or null on success.
972
+ */
973
+ subscribe(ws: WebSocket | null, tokens: string[]): Promise<{
974
+ error: {
975
+ message: string;
976
+ };
977
+ } | null>;
978
+ /**
979
+ * Unsubscribes from market data for specified tokens.
980
+ *
981
+ * @param {WebSocket | null} ws - The WebSocket instance.
982
+ * @param {string[]} tokens - Array of token strings to unsubscribe from.
983
+ * @returns {Promise<{ error: { message: string } } | null>}
984
+ * A promise that resolves to an error object on failure, or null on success.
985
+ */
986
+ unsubscribe(ws: WebSocket | null, tokens: string[]): Promise<{
987
+ error: {
988
+ message: string;
989
+ };
990
+ } | null>;
991
+ /**
992
+ * Subscribes to option Greeks data for specified tokens.
993
+ *
994
+ * @param {WebSocket | null} ws - The WebSocket instance.
995
+ * @param {string[]} tokens - Array of option token strings to subscribe to.
996
+ * @returns {Promise<{ error: { message: string } } | null>}
997
+ * A promise that resolves to an error object on failure, or null on success.
998
+ */
999
+ subscribeOptionGreeks(ws: WebSocket | null, tokens: string[]): Promise<{
1000
+ error: {
1001
+ message: string;
1002
+ };
1003
+ } | null>;
1004
+ /**
1005
+ * Unsubscribes from option Greeks data for specified tokens.
1006
+ *
1007
+ * @param {WebSocket | null} ws - The WebSocket instance.
1008
+ * @param {string[]} tokens - Array of option token strings to unsubscribe from.
1009
+ * @returns {Promise<{ error: { message: string } } | null>}
1010
+ * A promise that resolves to an error object on failure, or null on success.
1011
+ */
1012
+ unsubscribeOptionGreeks(ws: WebSocket | null, tokens: string[]): Promise<{
1013
+ error: {
1014
+ message: string;
1015
+ };
1016
+ } | null>;
935
1017
  }
936
1018
  export {};
@@ -32,6 +32,15 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
35
44
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
45
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
46
  };
@@ -39,9 +48,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
48
  exports.Firstock = void 0;
40
49
  const axios_1 = __importDefault(require("axios"));
41
50
  const sha256 = __importStar(require("sha256"));
51
+ const ws_1 = __importDefault(require("ws"));
42
52
  const AFirstock_1 = __importDefault(require("./AFirstock"));
43
53
  const commonFunction_1 = require("../shared/commonFunction");
44
54
  const constant_1 = require("../shared/constant");
55
+ const websocket_functions_1 = require("../websockets/websocket_functions");
56
+ // interface Config {
57
+ // scheme?: string;
58
+ // host?: string;
59
+ // path?: string;
60
+ // source?: string;
61
+ // accept_encoding?: string;
62
+ // accept_language?: string;
63
+ // origin?: string;
64
+ // max_websocket_connection_retries?: number;
65
+ // time_interval?: number;
66
+ // [key: string]: any;
67
+ // }
45
68
  const axiosInterceptor = axios_1.default.create({
46
69
  baseURL: constant_1.API_LINK,
47
70
  });
@@ -1821,5 +1844,209 @@ class Firstock extends AFirstock_1.default {
1821
1844
  }
1822
1845
  });
1823
1846
  }
1847
+ // WebSocket methods
1848
+ /**
1849
+ * Initializes a WebSocket connection to Firstock for real-time market data streaming.
1850
+ *
1851
+ * @param {string} userId - The user ID for authentication.
1852
+ * @param {FirstockWebSocket} model - WebSocket model containing tokens and subscriptions.
1853
+ * @param {Config} [config] - Optional configuration for WebSocket connection.
1854
+ * @returns {Promise<[WebSocket | null, { error: { message: string } } | null]>}
1855
+ * A promise that resolves to a tuple containing the WebSocket instance (or null on error)
1856
+ * and an error object (or null on success).
1857
+ */
1858
+ initializeWebsockets(userId, model, config) {
1859
+ return __awaiter(this, void 0, void 0, function* () {
1860
+ const finalConfig = Object.assign({ scheme: 'wss', host: 'socket.firstock.in', path: '/ws', source: 'developer-api', accept_encoding: 'gzip, deflate, br', accept_language: 'en-US,en;q=0.9', origin: 'https://firstock.in', max_websocket_connection_retries: 3, time_interval: 5 }, config);
1861
+ const [baseUrl, headers, err] = (0, websocket_functions_1.getUrlAndHeaderData)(userId, finalConfig);
1862
+ if (err) {
1863
+ return [null, { error: { message: err.message } }];
1864
+ }
1865
+ try {
1866
+ const ws = new ws_1.default(baseUrl, { headers });
1867
+ yield new Promise((resolve, reject) => {
1868
+ const timeout = setTimeout(() => {
1869
+ reject(new Error('Connection timeout'));
1870
+ }, 10000);
1871
+ ws.once('open', () => {
1872
+ clearTimeout(timeout);
1873
+ resolve();
1874
+ });
1875
+ ws.once('error', (error) => {
1876
+ clearTimeout(timeout);
1877
+ reject(error);
1878
+ });
1879
+ });
1880
+ yield websocket_functions_1.connections.addConnection(ws);
1881
+ const msg = yield new Promise((resolve, reject) => {
1882
+ const timeout = setTimeout(() => {
1883
+ reject(new Error('Authentication timeout'));
1884
+ }, 5000);
1885
+ ws.once('message', (data) => {
1886
+ clearTimeout(timeout);
1887
+ resolve(data.toString());
1888
+ });
1889
+ ws.once('error', (error) => {
1890
+ clearTimeout(timeout);
1891
+ reject(error);
1892
+ });
1893
+ });
1894
+ if (msg.includes("Authentication successful")) {
1895
+ yield new Promise(resolve => setTimeout(resolve, 500));
1896
+ const modelDict = model.toDict();
1897
+ (0, websocket_functions_1.readMessage)(userId, ws, modelDict, finalConfig);
1898
+ yield new Promise(resolve => setTimeout(resolve, 500));
1899
+ if (model.tokens && model.tokens.length > 0) {
1900
+ const subscribeErr = yield (0, websocket_functions_1.subscribe)(ws, model.tokens);
1901
+ if (subscribeErr) {
1902
+ }
1903
+ }
1904
+ if (model.option_greeks_tokens && model.option_greeks_tokens.length > 0) {
1905
+ const subscribeErr = yield (0, websocket_functions_1.subscribeOptionGreeks)(ws, model.option_greeks_tokens);
1906
+ if (subscribeErr) {
1907
+ }
1908
+ }
1909
+ return [ws, null];
1910
+ }
1911
+ else if (msg.includes("Maximum sessions limit")) {
1912
+ yield websocket_functions_1.connections.deleteConnection(ws);
1913
+ return [null, { error: { message: msg } }];
1914
+ }
1915
+ else {
1916
+ yield websocket_functions_1.connections.deleteConnection(ws);
1917
+ return [null, { error: { message: `Unexpected authentication response: ${msg}` } }];
1918
+ }
1919
+ }
1920
+ catch (e) {
1921
+ return [null, { error: { message: e.message } }];
1922
+ }
1923
+ });
1924
+ }
1925
+ /**
1926
+ * Closes an active WebSocket connection.
1927
+ *
1928
+ * @param {WebSocket | null} ws - The WebSocket instance to close.
1929
+ * @returns {Promise<{ error: { message: string } } | null>}
1930
+ * A promise that resolves to an error object if closure fails, or null on success.
1931
+ */
1932
+ closeWebsocket(ws) {
1933
+ return __awaiter(this, void 0, void 0, function* () {
1934
+ if (ws === null) {
1935
+ return {
1936
+ error: {
1937
+ message: "Connection does not exist"
1938
+ }
1939
+ };
1940
+ }
1941
+ if (yield websocket_functions_1.connections.checkIfConnectionExists(ws)) {
1942
+ try {
1943
+ ws.close();
1944
+ yield websocket_functions_1.connections.deleteConnection(ws);
1945
+ return null;
1946
+ }
1947
+ catch (e) {
1948
+ const errorMsg = e.message.toLowerCase();
1949
+ if (!errorMsg.includes("closed")) {
1950
+ return {
1951
+ error: {
1952
+ message: e.message
1953
+ }
1954
+ };
1955
+ }
1956
+ else {
1957
+ yield websocket_functions_1.connections.deleteConnection(ws);
1958
+ return null;
1959
+ }
1960
+ }
1961
+ }
1962
+ else {
1963
+ return {
1964
+ error: {
1965
+ message: "Connection does not exist"
1966
+ }
1967
+ };
1968
+ }
1969
+ });
1970
+ }
1971
+ /**
1972
+ * Subscribes to market data for specified tokens.
1973
+ *
1974
+ * @param {WebSocket | null} ws - The WebSocket instance.
1975
+ * @param {string[]} tokens - Array of token strings to subscribe to.
1976
+ * @returns {Promise<{ error: { message: string } } | null>}
1977
+ * A promise that resolves to an error object on failure, or null on success.
1978
+ */
1979
+ subscribe(ws, tokens) {
1980
+ return __awaiter(this, void 0, void 0, function* () {
1981
+ if (ws === null) {
1982
+ return {
1983
+ error: {
1984
+ message: "Connection does not exist"
1985
+ }
1986
+ };
1987
+ }
1988
+ return (0, websocket_functions_1.subscribe)(ws, tokens);
1989
+ });
1990
+ }
1991
+ /**
1992
+ * Unsubscribes from market data for specified tokens.
1993
+ *
1994
+ * @param {WebSocket | null} ws - The WebSocket instance.
1995
+ * @param {string[]} tokens - Array of token strings to unsubscribe from.
1996
+ * @returns {Promise<{ error: { message: string } } | null>}
1997
+ * A promise that resolves to an error object on failure, or null on success.
1998
+ */
1999
+ unsubscribe(ws, tokens) {
2000
+ return __awaiter(this, void 0, void 0, function* () {
2001
+ if (ws === null) {
2002
+ return {
2003
+ error: {
2004
+ message: "Connection does not exist"
2005
+ }
2006
+ };
2007
+ }
2008
+ return (0, websocket_functions_1.unsubscribe)(ws, tokens);
2009
+ });
2010
+ }
2011
+ /**
2012
+ * Subscribes to option Greeks data for specified tokens.
2013
+ *
2014
+ * @param {WebSocket | null} ws - The WebSocket instance.
2015
+ * @param {string[]} tokens - Array of option token strings to subscribe to.
2016
+ * @returns {Promise<{ error: { message: string } } | null>}
2017
+ * A promise that resolves to an error object on failure, or null on success.
2018
+ */
2019
+ subscribeOptionGreeks(ws, tokens) {
2020
+ return __awaiter(this, void 0, void 0, function* () {
2021
+ if (ws === null) {
2022
+ return {
2023
+ error: {
2024
+ message: "Connection does not exist"
2025
+ }
2026
+ };
2027
+ }
2028
+ return (0, websocket_functions_1.subscribeOptionGreeks)(ws, tokens);
2029
+ });
2030
+ }
2031
+ /**
2032
+ * Unsubscribes from option Greeks data for specified tokens.
2033
+ *
2034
+ * @param {WebSocket | null} ws - The WebSocket instance.
2035
+ * @param {string[]} tokens - Array of option token strings to unsubscribe from.
2036
+ * @returns {Promise<{ error: { message: string } } | null>}
2037
+ * A promise that resolves to an error object on failure, or null on success.
2038
+ */
2039
+ unsubscribeOptionGreeks(ws, tokens) {
2040
+ return __awaiter(this, void 0, void 0, function* () {
2041
+ if (ws === null) {
2042
+ return {
2043
+ error: {
2044
+ message: "Connection does not exist"
2045
+ }
2046
+ };
2047
+ }
2048
+ return (0, websocket_functions_1.unsubscribeOptionGreeks)(ws, tokens);
2049
+ });
2050
+ }
1824
2051
  }
1825
2052
  exports.Firstock = Firstock;
package/dist/test.js CHANGED
@@ -7,11 +7,11 @@ const index_1 = __importDefault(require("./index"));
7
7
  const firstock = new index_1.default();
8
8
  let orderNumber = "";
9
9
  const userDetails = {
10
- userId: "NP2997",
11
- password: "Skanda@2025",
12
- TOTP: "1997",
13
- vendorCode: "NP2997_API",
14
- apiKey: "e55eb28e18ee1337fc0b2705f9b82465",
10
+ userId: "CM2096",
11
+ password: "Leaveme@L0ne",
12
+ TOTP: "1996",
13
+ vendorCode: "FIRSTOCK_MST_KEY",
14
+ apiKey: "Nco@MS7K8t",
15
15
  };
16
16
  // const userDetails = {
17
17
  // userId: "",
@@ -21,17 +21,6 @@ exports.subscribeOptionGreeks = subscribeOptionGreeks;
21
21
  exports.unsubscribeOptionGreeks = unsubscribeOptionGreeks;
22
22
  const ws_1 = __importDefault(require("ws"));
23
23
  const fs_1 = require("fs");
24
- // Configure logging
25
- const logger = {
26
- debug: (msg) => console.debug(`${new Date().toISOString()} - ${msg}`),
27
- info: (msg) => console.info(`${new Date().toISOString()} - ${msg}`),
28
- warning: (msg) => console.warn(`${new Date().toISOString()} - ${msg}`),
29
- error: (msg, err) => {
30
- console.error(`[ERROR] ${new Date().toISOString()} - ${msg}`);
31
- if (err)
32
- console.error(err);
33
- }
34
- };
35
24
  var UpdateType;
36
25
  (function (UpdateType) {
37
26
  UpdateType["ORDER"] = "order";
@@ -85,14 +74,12 @@ class ConnectionManager {
85
74
  return __awaiter(this, void 0, void 0, function* () {
86
75
  yield this.acquireLock();
87
76
  if (this.indexMap.has(ws)) {
88
- logger.info("Connection already exists");
89
77
  this.releaseLock();
90
78
  return this.indexMap.get(ws);
91
79
  }
92
80
  const safe = new SafeConn(ws);
93
81
  this.connMap.set(safe, true);
94
82
  this.indexMap.set(ws, safe);
95
- logger.info("Connection added");
96
83
  this.releaseLock();
97
84
  return safe;
98
85
  });
@@ -135,7 +122,6 @@ class ConnectionManager {
135
122
  return __awaiter(this, void 0, void 0, function* () {
136
123
  yield this.acquireLock();
137
124
  if (this.indexMap.has(ws)) {
138
- // Set shutdown flag BEFORE closing
139
125
  _setShutdownFlag(ws);
140
126
  const safe = this.indexMap.get(ws);
141
127
  this.connMap.delete(safe);
@@ -148,13 +134,10 @@ class ConnectionManager {
148
134
  catch (e) {
149
135
  // Ignore errors during close
150
136
  }
151
- logger.info("Connection deleted");
152
- // Clear subscription tracking
153
137
  _clearTrackedSubscriptions(ws);
154
138
  this.releaseLock();
155
139
  return;
156
140
  }
157
- logger.info("Connection not found");
158
141
  this.releaseLock();
159
142
  });
160
143
  }
@@ -178,7 +161,6 @@ function _trackSubscription(ws, tokens, subscriptionType) {
178
161
  tracker[subscriptionType].push(token);
179
162
  }
180
163
  }
181
- logger.debug(`Tracked subscription: ${subscriptionType} - ${tokens.join(', ')}`);
182
164
  }
183
165
  function _untrackSubscription(ws, tokens, subscriptionType) {
184
166
  const wsId = _getWsId(ws);
@@ -191,7 +173,6 @@ function _untrackSubscription(ws, tokens, subscriptionType) {
191
173
  }
192
174
  }
193
175
  }
194
- logger.debug(`Untracked subscription: ${subscriptionType} - ${tokens.join(', ')}`);
195
176
  }
196
177
  function _getTrackedSubscriptions(ws) {
197
178
  const wsId = _getWsId(ws);
@@ -201,7 +182,6 @@ function _clearTrackedSubscriptions(ws) {
201
182
  const wsId = _getWsId(ws);
202
183
  if (subscriptionTracker.has(wsId)) {
203
184
  subscriptionTracker.delete(wsId);
204
- logger.debug(`Cleared subscription tracking for connection ${wsId}`);
205
185
  }
206
186
  }
207
187
  // Shutdown flags
@@ -209,7 +189,6 @@ const shutdownFlags = new Map();
209
189
  function _setShutdownFlag(ws) {
210
190
  const wsId = _getWsId(ws);
211
191
  shutdownFlags.set(wsId, true);
212
- logger.debug(`Shutdown flag set for connection ${wsId}`);
213
192
  }
214
193
  function _isShutdownRequested(ws) {
215
194
  const wsId = _getWsId(ws);
@@ -219,7 +198,6 @@ function _clearShutdownFlag(ws) {
219
198
  const wsId = _getWsId(ws);
220
199
  if (shutdownFlags.has(wsId)) {
221
200
  shutdownFlags.delete(wsId);
222
- logger.debug(`Shutdown flag cleared for connection ${wsId}`);
223
201
  }
224
202
  }
225
203
  function getUrlAndHeaderData(userId, config) {
@@ -231,7 +209,6 @@ function getUrlAndHeaderData(userId, config) {
231
209
  const acceptLanguage = config.accept_language || 'en-US,en;q=0.9';
232
210
  const origin = config.origin || '';
233
211
  const baseUrl = `${scheme}://${host}${path}`;
234
- logger.info(`Connecting to ${baseUrl}`);
235
212
  let configJson;
236
213
  try {
237
214
  const configFile = (0, fs_1.readFileSync)('config.json', 'utf-8');
@@ -240,7 +217,6 @@ function getUrlAndHeaderData(userId, config) {
240
217
  catch (e) {
241
218
  return ['', null, new Error('Failed to read config.json')];
242
219
  }
243
- // Use the userId parameter to get the jKey
244
220
  if (!configJson[userId]) {
245
221
  return ['', null, new Error(`User ID '${userId}' not found in config.json`)];
246
222
  }
@@ -279,11 +255,9 @@ function _identifyUpdateType(data) {
279
255
  }
280
256
  function _handleAuthenticationResponse(message) {
281
257
  if (message.includes("Authentication successful")) {
282
- logger.info("Authentication successful");
283
258
  return true;
284
259
  }
285
260
  else if (message.includes('"status":"failed"')) {
286
- logger.warning(`Authentication failed: ${message}`);
287
261
  return false;
288
262
  }
289
263
  return true;
@@ -292,25 +266,15 @@ function readMessage(userId, ws, model, config) {
292
266
  return __awaiter(this, void 0, void 0, function* () {
293
267
  const maxRetries = config.max_websocket_connection_retries || 3;
294
268
  const timeInterval = config.time_interval || 5;
295
- let messageCount = 0;
296
269
  let isAuthenticated = true;
297
- logger.info(`Starting message reader for user ${userId}`);
298
- logger.info(`Callbacks configured - Feed: ${model.subscribe_feed_data !== undefined}, ` +
299
- `Order: ${model.order_data !== undefined}, ` +
300
- `Position: ${model.position_data !== undefined}, ` +
301
- `Option Greeks: ${model.subscribe_option_greeks_data !== undefined}`);
302
270
  const messageHandler = (data) => __awaiter(this, void 0, void 0, function* () {
303
271
  if (!(yield exports.connections.checkIfConnectionExists(ws))) {
304
- logger.info("Connection no longer exists, stopping reader");
305
272
  _clearShutdownFlag(ws);
306
273
  return;
307
274
  }
308
275
  try {
309
276
  const message = data.toString();
310
- messageCount++;
311
- logger.debug(`Message #${messageCount}: ${message.substring(0, 200)}...`);
312
277
  if (!message) {
313
- logger.debug("Empty message received, skipping");
314
278
  return;
315
279
  }
316
280
  let parsedData;
@@ -318,14 +282,12 @@ function readMessage(userId, ws, model, config) {
318
282
  parsedData = JSON.parse(message);
319
283
  }
320
284
  catch (e) {
321
- logger.error(`JSON parse error: ${e.message}. Message: ${message.substring(0, 200)}`);
322
285
  return;
323
286
  }
324
287
  // Handle authentication responses
325
288
  if (parsedData.status && parsedData.message) {
326
289
  if (_handleAuthenticationResponse(message)) {
327
290
  isAuthenticated = true;
328
- logger.info("Re-authentication successful");
329
291
  }
330
292
  return;
331
293
  }
@@ -335,10 +297,9 @@ function readMessage(userId, ws, model, config) {
335
297
  if (model.order_data) {
336
298
  try {
337
299
  model.order_data(parsedData);
338
- logger.debug("Order callback invoked");
339
300
  }
340
301
  catch (e) {
341
- logger.error(`Error in order callback: ${e.message}`, e);
302
+ // Ignore callback errors
342
303
  }
343
304
  }
344
305
  }
@@ -346,10 +307,9 @@ function readMessage(userId, ws, model, config) {
346
307
  if (model.position_data) {
347
308
  try {
348
309
  model.position_data(parsedData);
349
- logger.debug("Position callback invoked");
350
310
  }
351
311
  catch (e) {
352
- logger.error(`Error in position callback: ${e.message}`, e);
312
+ // Ignore callback errors
353
313
  }
354
314
  }
355
315
  }
@@ -363,10 +323,9 @@ function readMessage(userId, ws, model, config) {
363
323
  }
364
324
  }
365
325
  }
366
- logger.debug("Option Greeks callback invoked");
367
326
  }
368
327
  catch (e) {
369
- logger.error(`Error in option Greeks callback: ${e.message}`, e);
328
+ // Ignore callback errors
370
329
  }
371
330
  }
372
331
  }
@@ -374,55 +333,39 @@ function readMessage(userId, ws, model, config) {
374
333
  if (model.subscribe_feed_data) {
375
334
  try {
376
335
  model.subscribe_feed_data(parsedData);
377
- logger.debug("Feed callback invoked");
378
336
  }
379
337
  catch (e) {
380
- logger.error(`Error in feed callback: ${e.message}`, e);
338
+ // Ignore callback errors
381
339
  }
382
340
  }
383
341
  }
384
342
  }
385
343
  catch (e) {
386
- logger.error(`Error processing message: ${e.message}`, e);
344
+ // Ignore processing errors
387
345
  }
388
346
  });
389
347
  const closeHandler = () => __awaiter(this, void 0, void 0, function* () {
390
- // Check if shutdown was requested
391
348
  if (_isShutdownRequested(ws)) {
392
- logger.info("Connection closed intentionally");
393
349
  _clearShutdownFlag(ws);
394
350
  return;
395
351
  }
396
- // Unexpected disconnection - attempt reconnection
397
- logger.warning("Unexpected disconnection");
398
- console.log("\n Connection lost");
399
- console.log("Attempting to reconnect...");
400
352
  if (!(yield exports.connections.checkIfConnectionExists(ws))) {
401
- logger.info("Connection no longer in manager, stopping reader");
402
353
  return;
403
354
  }
404
- // Attempt reconnection
405
355
  const newWs = yield _attemptReconnection(userId, ws, config, maxRetries, timeInterval, model);
406
356
  if (newWs === null) {
407
- logger.error("Failed to reconnect after all attempts");
408
- console.log("✗ Failed to reconnect. Please restart the application.");
409
357
  return;
410
358
  }
411
- logger.info("Reconnection successful, resuming message reading");
412
- // Call user's reconnection callback if provided
413
359
  if (model.on_reconnect) {
414
360
  try {
415
361
  model.on_reconnect(newWs);
416
- logger.info("User's on_reconnect callback executed");
417
362
  }
418
363
  catch (callbackError) {
419
- logger.error(`Error in on_reconnect callback: ${callbackError.message}`, callbackError);
364
+ // Ignore callback errors
420
365
  }
421
366
  }
422
367
  });
423
368
  const errorHandler = (error) => __awaiter(this, void 0, void 0, function* () {
424
- logger.error(`WebSocket error: ${error.message}`, error);
425
- // Trigger close handler for reconnection logic
426
369
  yield closeHandler();
427
370
  });
428
371
  ws.on('message', messageHandler);
@@ -432,28 +375,20 @@ function readMessage(userId, ws, model, config) {
432
375
  }
433
376
  function _attemptReconnection(userId, oldWs, config, maxRetries, timeInterval, model) {
434
377
  return __awaiter(this, void 0, void 0, function* () {
435
- // Get the actual tracked subscriptions
436
378
  const tracked = _getTrackedSubscriptions(oldWs);
437
379
  const allTokens = tracked.tokens;
438
380
  const allOptionGreeksTokens = tracked.option_greeks_tokens;
439
- logger.info(`Attempting reconnection. Will restore: ${allTokens.length} market tokens, ${allOptionGreeksTokens.length} option greeks tokens`);
440
381
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
441
382
  if (!(yield exports.connections.checkIfConnectionExists(oldWs))) {
442
- logger.info("Connection no longer exists in manager, stopping reconnection");
443
383
  return null;
444
384
  }
445
- logger.info(`Reconnection attempt ${attempt}/${maxRetries}...`);
446
- console.log(`Reconnection attempt ${attempt}/${maxRetries}...`);
447
385
  yield new Promise(resolve => setTimeout(resolve, timeInterval * 1000));
448
386
  try {
449
- // Create new connection
450
387
  const [baseUrl, headers, err] = getUrlAndHeaderData(userId, config);
451
388
  if (err) {
452
- logger.error(`Failed to get URL/headers: ${err.message}`);
453
389
  continue;
454
390
  }
455
391
  const newWs = new ws_1.default(baseUrl, { headers });
456
- // Wait for connection to open
457
392
  yield new Promise((resolve, reject) => {
458
393
  const timeout = setTimeout(() => {
459
394
  reject(new Error('Connection timeout'));
@@ -467,8 +402,6 @@ function _attemptReconnection(userId, oldWs, config, maxRetries, timeInterval, m
467
402
  reject(error);
468
403
  });
469
404
  });
470
- logger.info(`New WebSocket connection created (attempt ${attempt})`);
471
- // Wait for authentication message
472
405
  const authMessage = yield new Promise((resolve, reject) => {
473
406
  const timeout = setTimeout(() => {
474
407
  reject(new Error('Authentication timeout'));
@@ -482,13 +415,11 @@ function _attemptReconnection(userId, oldWs, config, maxRetries, timeInterval, m
482
415
  reject(error);
483
416
  });
484
417
  });
485
- logger.info(`Reconnection auth message: ${authMessage}`);
486
418
  if (!authMessage.includes("Authentication successful")) {
487
- logger.warning(`Authentication failed on reconnect: ${authMessage}`);
488
419
  newWs.close();
489
420
  continue;
490
421
  }
491
- // Transfer subscription tracking from old connection to new connection
422
+ // Transfer subscription tracking
492
423
  const oldWsId = _getWsId(oldWs);
493
424
  const newWsId = _getWsId(newWs);
494
425
  if (subscriptionTracker.has(oldWsId)) {
@@ -497,55 +428,29 @@ function _attemptReconnection(userId, oldWs, config, maxRetries, timeInterval, m
497
428
  tokens: [...oldTracker.tokens],
498
429
  option_greeks_tokens: [...oldTracker.option_greeks_tokens]
499
430
  });
500
- logger.debug(`Transferred subscription tracking from ${oldWsId} to ${newWsId}`);
501
431
  }
502
- // Update connection manager
503
432
  yield exports.connections.deleteConnection(oldWs);
504
433
  yield exports.connections.addConnection(newWs);
505
- logger.info("Connection manager updated with new connection");
506
- // Resubscribe to all tracked tokens
507
- logger.info("Resubscribing to previous subscriptions...");
508
- console.log("Resubscribing to previous feeds...");
509
434
  // Resubscribe to market feed tokens
510
435
  if (allTokens.length > 0) {
511
436
  yield new Promise(resolve => setTimeout(resolve, 500));
512
437
  const tokensStr = allTokens.join("|");
513
438
  const msg = JSON.stringify({ action: "subscribe", tokens: tokensStr });
514
- const error = yield exports.connections.writeMessage(newWs, msg);
515
- if (error) {
516
- logger.error(`Failed to resubscribe to market tokens: ${error}`);
517
- }
518
- else {
519
- logger.info(`Resubscribed to ${allTokens.length} market feed token(s): ${allTokens.join(', ')}`);
520
- console.log(`✓ Resubscribed to ${allTokens.length} market feed token(s)`);
521
- }
439
+ yield exports.connections.writeMessage(newWs, msg);
522
440
  }
441
+ // Resubscribe to option Greeks tokens
523
442
  if (allOptionGreeksTokens.length > 0) {
524
443
  yield new Promise(resolve => setTimeout(resolve, 500));
525
444
  const tokensStr = allOptionGreeksTokens.join("|");
526
445
  const msg = JSON.stringify({ action: "subscribe-option-greeks", tokens: tokensStr });
527
- const error = yield exports.connections.writeMessage(newWs, msg);
528
- if (error) {
529
- logger.error(`Failed to resubscribe to option Greeks: ${error}`);
530
- }
531
- else {
532
- logger.info(`Resubscribed to ${allOptionGreeksTokens.length} option Greeks token(s): ${allOptionGreeksTokens.join(', ')}`);
533
- console.log(`✓ Resubscribed to ${allOptionGreeksTokens.length} option Greeks token(s)`);
534
- }
446
+ yield exports.connections.writeMessage(newWs, msg);
535
447
  }
536
448
  yield new Promise(resolve => setTimeout(resolve, 1000));
537
- logger.info("Reconnection and resubscription successful!");
538
- console.log("✓ Reconnection complete - all subscriptions restored");
539
- // IMPORTANT: Restart the message reader for the new WebSocket
540
449
  readMessage(userId, newWs, model, config);
541
450
  return newWs;
542
451
  }
543
452
  catch (e) {
544
- logger.error(`Reconnection attempt ${attempt} failed: ${e.message}`, e);
545
- console.log(`✗ Attempt ${attempt} failed: ${e.message.substring(0, 100)}...`);
546
453
  if (attempt === maxRetries) {
547
- logger.error("Max reconnection attempts reached");
548
- console.log(`✗ All ${maxRetries} reconnection attempts failed`);
549
454
  return null;
550
455
  }
551
456
  }
@@ -574,12 +479,10 @@ function subscribe(ws, tokens) {
574
479
  action: "subscribe",
575
480
  tokens: tokensStr
576
481
  });
577
- logger.info(`Sending subscribe message: ${msg}`);
578
482
  const error = yield exports.connections.writeMessage(ws, msg);
579
483
  if (error) {
580
484
  return { error: { message: error } };
581
485
  }
582
- logger.info("Subscribe message sent successfully");
583
486
  return null;
584
487
  });
585
488
  }
@@ -598,7 +501,6 @@ function unsubscribe(ws, tokens) {
598
501
  action: "unsubscribe",
599
502
  tokens: tokensStr
600
503
  });
601
- logger.info(`Sending unsubscribe message: ${msg}`);
602
504
  const error = yield exports.connections.writeMessage(ws, msg);
603
505
  if (error) {
604
506
  return { error: { message: error } };
@@ -627,12 +529,10 @@ function subscribeOptionGreeks(ws, tokens) {
627
529
  action: "subscribe-option-greeks",
628
530
  tokens: tokensStr
629
531
  });
630
- logger.info(`Sending subscribe option greeks message: ${msg}`);
631
532
  const error = yield exports.connections.writeMessage(ws, msg);
632
533
  if (error) {
633
534
  return { error: { message: error } };
634
535
  }
635
- logger.info("Subscribe option greeks message sent successfully");
636
536
  return null;
637
537
  });
638
538
  }
@@ -657,12 +557,10 @@ function unsubscribeOptionGreeks(ws, tokens) {
657
557
  action: "unsubscribe-option-greeks",
658
558
  tokens: tokensStr
659
559
  });
660
- logger.info(`Sending unsubscribe option greeks message: ${msg}`);
661
560
  const error = yield exports.connections.writeMessage(ws, msg);
662
561
  if (error) {
663
562
  return { error: { message: error } };
664
563
  }
665
- logger.info("Unsubscribe option greeks message sent successfully");
666
564
  return null;
667
565
  });
668
566
  }
@@ -1,5 +1,5 @@
1
1
  import WebSocket from 'ws';
2
- import { Config, WebSocketModel } from './websocket_functions';
2
+ import { WebSocketModel } from './websocket_functions';
3
3
  export declare class FirstockWebSocket {
4
4
  tokens?: string[];
5
5
  option_greeks_tokens?: string[];
@@ -19,35 +19,3 @@ export declare class FirstockWebSocket {
19
19
  });
20
20
  toDict(): WebSocketModel;
21
21
  }
22
- export declare class Firstock {
23
- static initializeWebsockets(userId: string, model: FirstockWebSocket, config?: Config): Promise<[WebSocket | null, {
24
- error: {
25
- message: string;
26
- };
27
- } | null]>;
28
- static closeWebsocket(ws: WebSocket | null): Promise<{
29
- error: {
30
- message: string;
31
- };
32
- } | null>;
33
- static subscribe(ws: WebSocket | null, tokens: string[]): Promise<{
34
- error: {
35
- message: string;
36
- };
37
- } | null>;
38
- static unsubscribe(ws: WebSocket | null, tokens: string[]): Promise<{
39
- error: {
40
- message: string;
41
- };
42
- } | null>;
43
- static subscribeOptionGreeks(ws: WebSocket | null, tokens: string[]): Promise<{
44
- error: {
45
- message: string;
46
- };
47
- } | null>;
48
- static unsubscribeOptionGreeks(ws: WebSocket | null, tokens: string[]): Promise<{
49
- error: {
50
- message: string;
51
- };
52
- } | null>;
53
- }
@@ -1,28 +1,6 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
2
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.Firstock = exports.FirstockWebSocket = void 0;
16
- const ws_1 = __importDefault(require("ws"));
17
- const websocket_functions_1 = require("./websocket_functions");
18
- const logger = {
19
- info: (msg) => console.info(`[INFO] ${new Date().toISOString()} - ${msg}`),
20
- error: (msg, err) => {
21
- console.error(`[ERROR] ${new Date().toISOString()} - ${msg}`);
22
- if (err)
23
- console.error(err);
24
- }
25
- };
3
+ exports.FirstockWebSocket = void 0;
26
4
  class FirstockWebSocket {
27
5
  constructor(options = {}) {
28
6
  this.tokens = options.tokens || [];
@@ -46,168 +24,176 @@ class FirstockWebSocket {
46
24
  }
47
25
  }
48
26
  exports.FirstockWebSocket = FirstockWebSocket;
49
- class Firstock {
50
- static initializeWebsockets(userId, model, config) {
51
- return __awaiter(this, void 0, void 0, function* () {
52
- const finalConfig = Object.assign({ scheme: 'wss', host: 'socket.firstock.in', path: '/ws', source: 'developer-api', accept_encoding: 'gzip, deflate, br', accept_language: 'en-US,en;q=0.9', origin: 'https://firstock.in', max_websocket_connection_retries: 3, time_interval: 5 }, config);
53
- const [baseUrl, headers, err] = (0, websocket_functions_1.getUrlAndHeaderData)(userId, finalConfig);
54
- if (err) {
55
- return [null, { error: { message: err.message } }];
56
- }
57
- try {
58
- const ws = new ws_1.default(baseUrl, { headers });
59
- yield new Promise((resolve, reject) => {
60
- const timeout = setTimeout(() => {
61
- reject(new Error('Connection timeout'));
62
- }, 10000);
63
- ws.once('open', () => {
64
- clearTimeout(timeout);
65
- resolve();
66
- });
67
- ws.once('error', (error) => {
68
- clearTimeout(timeout);
69
- reject(error);
70
- });
71
- });
72
- logger.info("WebSocket connection created");
73
- yield websocket_functions_1.connections.addConnection(ws);
74
- const msg = yield new Promise((resolve, reject) => {
75
- const timeout = setTimeout(() => {
76
- reject(new Error('Authentication timeout'));
77
- }, 5000);
78
- ws.once('message', (data) => {
79
- clearTimeout(timeout);
80
- resolve(data.toString());
81
- });
82
- ws.once('error', (error) => {
83
- clearTimeout(timeout);
84
- reject(error);
85
- });
86
- });
87
- logger.info(`Initial message received: ${msg}`);
88
- if (msg.includes("Authentication successful")) {
89
- logger.info("Authentication successful, starting message reader");
90
- yield new Promise(resolve => setTimeout(resolve, 500));
91
- const modelDict = model.toDict();
92
- (0, websocket_functions_1.readMessage)(userId, ws, modelDict, finalConfig);
93
- yield new Promise(resolve => setTimeout(resolve, 500));
94
- if (model.tokens && model.tokens.length > 0) {
95
- logger.info(`Subscribing to initial tokens: ${model.tokens.join(', ')}`);
96
- const subscribeErr = yield (0, websocket_functions_1.subscribe)(ws, model.tokens);
97
- if (subscribeErr) {
98
- logger.error(`Initial subscription error: ${JSON.stringify(subscribeErr)}`);
99
- }
100
- }
101
- if (model.option_greeks_tokens && model.option_greeks_tokens.length > 0) {
102
- logger.info(`Subscribing to option Greeks tokens: ${model.option_greeks_tokens.join(', ')}`);
103
- const subscribeErr = yield (0, websocket_functions_1.subscribeOptionGreeks)(ws, model.option_greeks_tokens);
104
- if (subscribeErr) {
105
- logger.error(`Initial option Greeks subscription error: ${JSON.stringify(subscribeErr)}`);
106
- }
107
- }
108
- return [ws, null];
109
- }
110
- else if (msg.includes("Maximum sessions limit")) {
111
- yield websocket_functions_1.connections.deleteConnection(ws);
112
- return [null, { error: { message: msg } }];
113
- }
114
- else {
115
- yield websocket_functions_1.connections.deleteConnection(ws);
116
- return [null, { error: { message: `Unexpected authentication response: ${msg}` } }];
117
- }
118
- }
119
- catch (e) {
120
- logger.error(`WebSocket initialization error: ${e.message}`, e);
121
- return [null, { error: { message: e.message } }];
122
- }
123
- });
124
- }
125
- static closeWebsocket(ws) {
126
- return __awaiter(this, void 0, void 0, function* () {
127
- if (ws === null) {
128
- return {
129
- error: {
130
- message: "Connection does not exist"
131
- }
132
- };
133
- }
134
- if (yield websocket_functions_1.connections.checkIfConnectionExists(ws)) {
135
- try {
136
- ws.close();
137
- yield websocket_functions_1.connections.deleteConnection(ws);
138
- return null;
139
- }
140
- catch (e) {
141
- const errorMsg = e.message.toLowerCase();
142
- if (!errorMsg.includes("closed")) {
143
- return {
144
- error: {
145
- message: e.message
146
- }
147
- };
148
- }
149
- else {
150
- yield websocket_functions_1.connections.deleteConnection(ws);
151
- return null;
152
- }
153
- }
154
- }
155
- else {
156
- return {
157
- error: {
158
- message: "Connection does not exist"
159
- }
160
- };
161
- }
162
- });
163
- }
164
- static subscribe(ws, tokens) {
165
- return __awaiter(this, void 0, void 0, function* () {
166
- if (ws === null) {
167
- return {
168
- error: {
169
- message: "Connection does not exist"
170
- }
171
- };
172
- }
173
- return (0, websocket_functions_1.subscribe)(ws, tokens);
174
- });
175
- }
176
- static unsubscribe(ws, tokens) {
177
- return __awaiter(this, void 0, void 0, function* () {
178
- if (ws === null) {
179
- return {
180
- error: {
181
- message: "Connection does not exist"
182
- }
183
- };
184
- }
185
- return (0, websocket_functions_1.unsubscribe)(ws, tokens);
186
- });
187
- }
188
- static subscribeOptionGreeks(ws, tokens) {
189
- return __awaiter(this, void 0, void 0, function* () {
190
- if (ws === null) {
191
- return {
192
- error: {
193
- message: "Connection does not exist"
194
- }
195
- };
196
- }
197
- return (0, websocket_functions_1.subscribeOptionGreeks)(ws, tokens);
198
- });
199
- }
200
- static unsubscribeOptionGreeks(ws, tokens) {
201
- return __awaiter(this, void 0, void 0, function* () {
202
- if (ws === null) {
203
- return {
204
- error: {
205
- message: "Connection does not exist"
206
- }
207
- };
208
- }
209
- return (0, websocket_functions_1.unsubscribeOptionGreeks)(ws, tokens);
210
- });
211
- }
212
- }
213
- exports.Firstock = Firstock;
27
+ // export class Firstock {
28
+ // static async initializeWebsockets(
29
+ // userId: string,
30
+ // model: FirstockWebSocket,
31
+ // config?: Config
32
+ // ): Promise<[WebSocket | null, { error: { message: string } } | null]> {
33
+ // const finalConfig: Config = {
34
+ // scheme: 'wss',
35
+ // host: 'socket.firstock.in',
36
+ // path: '/ws',
37
+ // source: 'developer-api',
38
+ // accept_encoding: 'gzip, deflate, br',
39
+ // accept_language: 'en-US,en;q=0.9',
40
+ // origin: 'https://firstock.in',
41
+ // max_websocket_connection_retries: 3,
42
+ // time_interval: 5,
43
+ // ...config
44
+ // };
45
+ // const [baseUrl, headers, err] = getUrlAndHeaderData(userId, finalConfig);
46
+ // if (err) {
47
+ // return [null, { error: { message: err.message } }];
48
+ // }
49
+ // try {
50
+ // const ws = new WebSocket(baseUrl, { headers });
51
+ // await new Promise<void>((resolve, reject) => {
52
+ // const timeout = setTimeout(() => {
53
+ // reject(new Error('Connection timeout'));
54
+ // }, 10000);
55
+ // ws.once('open', () => {
56
+ // clearTimeout(timeout);
57
+ // resolve();
58
+ // });
59
+ // ws.once('error', (error) => {
60
+ // clearTimeout(timeout);
61
+ // reject(error);
62
+ // });
63
+ // });
64
+ // logger.info("WebSocket connection created");
65
+ // await connections.addConnection(ws);
66
+ // const msg = await new Promise<string>((resolve, reject) => {
67
+ // const timeout = setTimeout(() => {
68
+ // reject(new Error('Authentication timeout'));
69
+ // }, 5000);
70
+ // ws.once('message', (data) => {
71
+ // clearTimeout(timeout);
72
+ // resolve(data.toString());
73
+ // });
74
+ // ws.once('error', (error) => {
75
+ // clearTimeout(timeout);
76
+ // reject(error);
77
+ // });
78
+ // });
79
+ // logger.info(`Initial message received: ${msg}`);
80
+ // if (msg.includes("Authentication successful")) {
81
+ // logger.info("Authentication successful, starting message reader");
82
+ // await new Promise(resolve => setTimeout(resolve, 500));
83
+ // const modelDict = model.toDict();
84
+ // readMessage(userId, ws, modelDict, finalConfig);
85
+ // await new Promise(resolve => setTimeout(resolve, 500));
86
+ // if (model.tokens && model.tokens.length > 0) {
87
+ // logger.info(`Subscribing to initial tokens: ${model.tokens.join(', ')}`);
88
+ // const subscribeErr = await subscribeHelper(ws, model.tokens);
89
+ // if (subscribeErr) {
90
+ // logger.error(`Initial subscription error: ${JSON.stringify(subscribeErr)}`);
91
+ // }
92
+ // }
93
+ // if (model.option_greeks_tokens && model.option_greeks_tokens.length > 0) {
94
+ // logger.info(`Subscribing to option Greeks tokens: ${model.option_greeks_tokens.join(', ')}`);
95
+ // const subscribeErr = await subscribeOptionGreeksHelper(ws, model.option_greeks_tokens);
96
+ // if (subscribeErr) {
97
+ // logger.error(`Initial option Greeks subscription error: ${JSON.stringify(subscribeErr)}`);
98
+ // }
99
+ // }
100
+ // return [ws, null];
101
+ // } else if (msg.includes("Maximum sessions limit")) {
102
+ // await connections.deleteConnection(ws);
103
+ // return [null, { error: { message: msg } }];
104
+ // } else {
105
+ // await connections.deleteConnection(ws);
106
+ // return [null, { error: { message: `Unexpected authentication response: ${msg}` } }];
107
+ // }
108
+ // } catch (e) {
109
+ // logger.error(`WebSocket initialization error: ${(e as Error).message}`, e as Error);
110
+ // return [null, { error: { message: (e as Error).message } }];
111
+ // }
112
+ // }
113
+ // static async closeWebsocket(ws: WebSocket | null): Promise<{ error: { message: string } } | null> {
114
+ // if (ws === null) {
115
+ // return {
116
+ // error: {
117
+ // message: "Connection does not exist"
118
+ // }
119
+ // };
120
+ // }
121
+ // if (await connections.checkIfConnectionExists(ws)) {
122
+ // try {
123
+ // ws.close();
124
+ // await connections.deleteConnection(ws);
125
+ // return null;
126
+ // } catch (e) {
127
+ // const errorMsg = (e as Error).message.toLowerCase();
128
+ // if (!errorMsg.includes("closed")) {
129
+ // return {
130
+ // error: {
131
+ // message: (e as Error).message
132
+ // }
133
+ // };
134
+ // } else {
135
+ // await connections.deleteConnection(ws);
136
+ // return null;
137
+ // }
138
+ // }
139
+ // } else {
140
+ // return {
141
+ // error: {
142
+ // message: "Connection does not exist"
143
+ // }
144
+ // };
145
+ // }
146
+ // }
147
+ // static async subscribe(
148
+ // ws: WebSocket | null,
149
+ // tokens: string[]
150
+ // ): Promise<{ error: { message: string } } | null> {
151
+ // if (ws === null) {
152
+ // return {
153
+ // error: {
154
+ // message: "Connection does not exist"
155
+ // }
156
+ // };
157
+ // }
158
+ // return subscribeHelper(ws, tokens);
159
+ // }
160
+ // static async unsubscribe(
161
+ // ws: WebSocket | null,
162
+ // tokens: string[]
163
+ // ): Promise<{ error: { message: string } } | null> {
164
+ // if (ws === null) {
165
+ // return {
166
+ // error: {
167
+ // message: "Connection does not exist"
168
+ // }
169
+ // };
170
+ // }
171
+ // return unsubscribeHelper(ws, tokens);
172
+ // }
173
+ // static async subscribeOptionGreeks(
174
+ // ws: WebSocket | null,
175
+ // tokens: string[]
176
+ // ): Promise<{ error: { message: string } } | null> {
177
+ // if (ws === null) {
178
+ // return {
179
+ // error: {
180
+ // message: "Connection does not exist"
181
+ // }
182
+ // };
183
+ // }
184
+ // return subscribeOptionGreeksHelper(ws, tokens);
185
+ // }
186
+ // static async unsubscribeOptionGreeks(
187
+ // ws: WebSocket | null,
188
+ // tokens: string[]
189
+ // ): Promise<{ error: { message: string } } | null> {
190
+ // if (ws === null) {
191
+ // return {
192
+ // error: {
193
+ // message: "Connection does not exist"
194
+ // }
195
+ // };
196
+ // }
197
+ // return unsubscribeOptionGreeksHelper(ws, tokens);
198
+ // }
199
+ // }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firstock",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "Node js package for using firstock developer apis",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,6 +11,7 @@
11
11
  "LICENSE"
12
12
  ],
13
13
  "scripts": {
14
+ "test:ws": "ts-node test_websockets.js",
14
15
  "build": "tsc",
15
16
  "prepublishOnly": "npm run build",
16
17
  "test": "echo \"Error: no test specified\" && exit 1"