@adaptic/utils 0.0.380 → 0.0.381

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/test.js CHANGED
@@ -6153,7 +6153,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
6153
6153
  cryptoWs = null;
6154
6154
  stockSubscriptions = { trades: [], quotes: [], bars: [] };
6155
6155
  optionSubscriptions = { trades: [], quotes: [], bars: [] };
6156
- cryptoSubscriptions = { trades: [], quotes: [], bars: [], dailyBars: [], updatedBars: [], orderbooks: [] };
6156
+ cryptoSubscriptions = { trades: [], quotes: [], bars: [] };
6157
6157
  setMode(mode = 'production') {
6158
6158
  if (mode === 'sandbox') { // sandbox mode
6159
6159
  this.stockStreamUrl = 'wss://stream.data.sandbox.alpaca.markets/v2/sip';
@@ -6210,7 +6210,16 @@ class AlpacaMarketDataAPI extends EventEmitter {
6210
6210
  return super.emit(event, ...args);
6211
6211
  }
6212
6212
  connect(streamType) {
6213
- const url = streamType === 'stock' ? this.stockStreamUrl : streamType === 'option' ? this.optionStreamUrl : this.cryptoStreamUrl;
6213
+ let url;
6214
+ if (streamType === 'stock') {
6215
+ url = this.stockStreamUrl;
6216
+ }
6217
+ else if (streamType === 'option') {
6218
+ url = this.optionStreamUrl;
6219
+ }
6220
+ else {
6221
+ url = this.cryptoStreamUrl;
6222
+ }
6214
6223
  const ws = new WebSocket(url);
6215
6224
  if (streamType === 'stock') {
6216
6225
  this.stockWs = ws;
@@ -6231,20 +6240,36 @@ class AlpacaMarketDataAPI extends EventEmitter {
6231
6240
  ws.send(JSON.stringify(authMessage));
6232
6241
  });
6233
6242
  ws.on('message', (data) => {
6234
- //log(`RAW MESSASGE: ${data.toString()}`);
6235
- const messages = JSON.parse(data.toString());
6243
+ const rawData = data.toString();
6244
+ let messages;
6245
+ try {
6246
+ messages = JSON.parse(rawData);
6247
+ }
6248
+ catch (e) {
6249
+ log$1(`${streamType} stream received invalid JSON: ${rawData.substring(0, 200)}`, { type: 'error' });
6250
+ return;
6251
+ }
6236
6252
  for (const message of messages) {
6237
6253
  if (message.T === 'success' && message.msg === 'authenticated') {
6238
6254
  log$1(`${streamType} stream authenticated`, { type: 'info' });
6239
6255
  this.sendSubscription(streamType);
6240
6256
  }
6257
+ else if (message.T === 'success' && message.msg === 'connected') {
6258
+ log$1(`${streamType} stream connected message received`, { type: 'debug' });
6259
+ }
6260
+ else if (message.T === 'subscription') {
6261
+ log$1(`${streamType} subscription confirmed: trades=${message.trades?.length || 0}, quotes=${message.quotes?.length || 0}, bars=${message.bars?.length || 0}`, { type: 'info' });
6262
+ }
6241
6263
  else if (message.T === 'error') {
6242
- log$1(`${streamType} stream error: ${message.msg}`, { type: 'error' });
6264
+ log$1(`${streamType} stream error: ${message.msg} (code: ${message.code}, raw: ${JSON.stringify(message)})`, { type: 'error' });
6243
6265
  }
6244
6266
  else if (message.S) {
6245
6267
  super.emit(`${streamType}-${message.T}`, message);
6246
6268
  super.emit(`${streamType}-data`, message);
6247
6269
  }
6270
+ else {
6271
+ log$1(`${streamType} received unknown message type: ${JSON.stringify(message)}`, { type: 'debug' });
6272
+ }
6248
6273
  }
6249
6274
  });
6250
6275
  ws.on('close', () => {
@@ -6265,39 +6290,50 @@ class AlpacaMarketDataAPI extends EventEmitter {
6265
6290
  });
6266
6291
  }
6267
6292
  sendSubscription(streamType) {
6268
- const ws = streamType === 'stock' ? this.stockWs : streamType === 'option' ? this.optionWs : this.cryptoWs;
6269
- const subscriptions = streamType === 'stock' ? this.stockSubscriptions : streamType === 'option' ? this.optionSubscriptions : this.cryptoSubscriptions;
6293
+ let ws;
6294
+ let subscriptions;
6295
+ if (streamType === 'stock') {
6296
+ ws = this.stockWs;
6297
+ subscriptions = this.stockSubscriptions;
6298
+ }
6299
+ else if (streamType === 'option') {
6300
+ ws = this.optionWs;
6301
+ subscriptions = this.optionSubscriptions;
6302
+ }
6303
+ else {
6304
+ ws = this.cryptoWs;
6305
+ subscriptions = this.cryptoSubscriptions;
6306
+ }
6307
+ log$1(`sendSubscription called for ${streamType} (wsReady=${ws?.readyState === WebSocket.OPEN}, trades=${subscriptions.trades?.length || 0}, quotes=${subscriptions.quotes?.length || 0}, bars=${subscriptions.bars?.length || 0})`, {
6308
+ type: 'debug',
6309
+ });
6270
6310
  if (ws && ws.readyState === WebSocket.OPEN) {
6271
6311
  const subMessagePayload = {};
6272
- if (subscriptions.trades && subscriptions.trades.length > 0) {
6312
+ if (subscriptions.trades.length > 0) {
6273
6313
  subMessagePayload.trades = subscriptions.trades;
6274
6314
  }
6275
- if (subscriptions.quotes && subscriptions.quotes.length > 0) {
6315
+ if (subscriptions.quotes.length > 0) {
6276
6316
  subMessagePayload.quotes = subscriptions.quotes;
6277
6317
  }
6278
- if (subscriptions.bars && subscriptions.bars.length > 0) {
6318
+ if (subscriptions.bars.length > 0) {
6279
6319
  subMessagePayload.bars = subscriptions.bars;
6280
6320
  }
6281
- // Crypto-specific subscription types
6282
- if (streamType === 'crypto') {
6283
- if (subscriptions.dailyBars && subscriptions.dailyBars.length > 0) {
6284
- subMessagePayload.dailyBars = subscriptions.dailyBars;
6285
- }
6286
- if (subscriptions.updatedBars && subscriptions.updatedBars.length > 0) {
6287
- subMessagePayload.updatedBars = subscriptions.updatedBars;
6288
- }
6289
- if (subscriptions.orderbooks && subscriptions.orderbooks.length > 0) {
6290
- subMessagePayload.orderbooks = subscriptions.orderbooks;
6291
- }
6292
- }
6293
6321
  if (Object.keys(subMessagePayload).length > 0) {
6294
6322
  const subMessage = {
6295
6323
  action: 'subscribe',
6296
6324
  ...subMessagePayload,
6297
6325
  };
6298
- ws.send(JSON.stringify(subMessage));
6326
+ const messageJson = JSON.stringify(subMessage);
6327
+ log$1(`Sending ${streamType} subscription: ${messageJson}`, { type: 'info' });
6328
+ ws.send(messageJson);
6329
+ }
6330
+ else {
6331
+ log$1(`No ${streamType} subscriptions to send (all arrays empty)`, { type: 'debug' });
6299
6332
  }
6300
6333
  }
6334
+ else {
6335
+ log$1(`Cannot send ${streamType} subscription: WebSocket not ready`, { type: 'warn' });
6336
+ }
6301
6337
  }
6302
6338
  connectStockStream() {
6303
6339
  if (!this.stockWs) {
@@ -6309,6 +6345,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
6309
6345
  this.connect('option');
6310
6346
  }
6311
6347
  }
6348
+ connectCryptoStream() {
6349
+ if (!this.cryptoWs) {
6350
+ this.connect('crypto');
6351
+ }
6352
+ }
6312
6353
  disconnectStockStream() {
6313
6354
  if (this.stockWs) {
6314
6355
  this.stockWs.close();
@@ -6319,18 +6360,38 @@ class AlpacaMarketDataAPI extends EventEmitter {
6319
6360
  this.optionWs.close();
6320
6361
  }
6321
6362
  }
6322
- connectCryptoStream() {
6323
- if (!this.cryptoWs) {
6324
- this.connect('crypto');
6325
- }
6326
- }
6327
6363
  disconnectCryptoStream() {
6328
6364
  if (this.cryptoWs) {
6329
6365
  this.cryptoWs.close();
6330
6366
  }
6331
6367
  }
6368
+ /**
6369
+ * Check if a specific stream is connected
6370
+ * @param streamType - The type of stream to check
6371
+ * @returns True if the stream is connected
6372
+ */
6373
+ isStreamConnected(streamType) {
6374
+ if (streamType === 'stock') {
6375
+ return this.stockWs !== null && this.stockWs.readyState === WebSocket.OPEN;
6376
+ }
6377
+ else if (streamType === 'option') {
6378
+ return this.optionWs !== null && this.optionWs.readyState === WebSocket.OPEN;
6379
+ }
6380
+ else {
6381
+ return this.cryptoWs !== null && this.cryptoWs.readyState === WebSocket.OPEN;
6382
+ }
6383
+ }
6332
6384
  subscribe(streamType, subscriptions) {
6333
- const currentSubscriptions = streamType === 'stock' ? this.stockSubscriptions : streamType === 'option' ? this.optionSubscriptions : this.cryptoSubscriptions;
6385
+ let currentSubscriptions;
6386
+ if (streamType === 'stock') {
6387
+ currentSubscriptions = this.stockSubscriptions;
6388
+ }
6389
+ else if (streamType === 'option') {
6390
+ currentSubscriptions = this.optionSubscriptions;
6391
+ }
6392
+ else {
6393
+ currentSubscriptions = this.cryptoSubscriptions;
6394
+ }
6334
6395
  Object.entries(subscriptions).forEach(([key, value]) => {
6335
6396
  if (value) {
6336
6397
  currentSubscriptions[key] = [...new Set([...(currentSubscriptions[key] || []), ...value])];
@@ -6339,7 +6400,16 @@ class AlpacaMarketDataAPI extends EventEmitter {
6339
6400
  this.sendSubscription(streamType);
6340
6401
  }
6341
6402
  unsubscribe(streamType, subscriptions) {
6342
- const currentSubscriptions = streamType === 'stock' ? this.stockSubscriptions : streamType === 'option' ? this.optionSubscriptions : this.cryptoSubscriptions;
6403
+ let currentSubscriptions;
6404
+ if (streamType === 'stock') {
6405
+ currentSubscriptions = this.stockSubscriptions;
6406
+ }
6407
+ else if (streamType === 'option') {
6408
+ currentSubscriptions = this.optionSubscriptions;
6409
+ }
6410
+ else {
6411
+ currentSubscriptions = this.cryptoSubscriptions;
6412
+ }
6343
6413
  Object.entries(subscriptions).forEach(([key, value]) => {
6344
6414
  if (value) {
6345
6415
  currentSubscriptions[key] = (currentSubscriptions[key] || []).filter(s => !value.includes(s));
@@ -6349,7 +6419,16 @@ class AlpacaMarketDataAPI extends EventEmitter {
6349
6419
  action: 'unsubscribe',
6350
6420
  ...subscriptions,
6351
6421
  };
6352
- const ws = streamType === 'stock' ? this.stockWs : streamType === 'option' ? this.optionWs : this.cryptoWs;
6422
+ let ws;
6423
+ if (streamType === 'stock') {
6424
+ ws = this.stockWs;
6425
+ }
6426
+ else if (streamType === 'option') {
6427
+ ws = this.optionWs;
6428
+ }
6429
+ else {
6430
+ ws = this.cryptoWs;
6431
+ }
6353
6432
  if (ws && ws.readyState === WebSocket.OPEN) {
6354
6433
  ws.send(JSON.stringify(unsubMessage));
6355
6434
  }