@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/index.cjs CHANGED
@@ -11484,7 +11484,7 @@ class AlpacaMarketDataAPI extends require$$0$3.EventEmitter {
11484
11484
  cryptoWs = null;
11485
11485
  stockSubscriptions = { trades: [], quotes: [], bars: [] };
11486
11486
  optionSubscriptions = { trades: [], quotes: [], bars: [] };
11487
- cryptoSubscriptions = { trades: [], quotes: [], bars: [], dailyBars: [], updatedBars: [], orderbooks: [] };
11487
+ cryptoSubscriptions = { trades: [], quotes: [], bars: [] };
11488
11488
  setMode(mode = 'production') {
11489
11489
  if (mode === 'sandbox') { // sandbox mode
11490
11490
  this.stockStreamUrl = 'wss://stream.data.sandbox.alpaca.markets/v2/sip';
@@ -11541,7 +11541,16 @@ class AlpacaMarketDataAPI extends require$$0$3.EventEmitter {
11541
11541
  return super.emit(event, ...args);
11542
11542
  }
11543
11543
  connect(streamType) {
11544
- const url = streamType === 'stock' ? this.stockStreamUrl : streamType === 'option' ? this.optionStreamUrl : this.cryptoStreamUrl;
11544
+ let url;
11545
+ if (streamType === 'stock') {
11546
+ url = this.stockStreamUrl;
11547
+ }
11548
+ else if (streamType === 'option') {
11549
+ url = this.optionStreamUrl;
11550
+ }
11551
+ else {
11552
+ url = this.cryptoStreamUrl;
11553
+ }
11545
11554
  const ws = new WebSocket(url);
11546
11555
  if (streamType === 'stock') {
11547
11556
  this.stockWs = ws;
@@ -11562,20 +11571,36 @@ class AlpacaMarketDataAPI extends require$$0$3.EventEmitter {
11562
11571
  ws.send(JSON.stringify(authMessage));
11563
11572
  });
11564
11573
  ws.on('message', (data) => {
11565
- //log(`RAW MESSASGE: ${data.toString()}`);
11566
- const messages = JSON.parse(data.toString());
11574
+ const rawData = data.toString();
11575
+ let messages;
11576
+ try {
11577
+ messages = JSON.parse(rawData);
11578
+ }
11579
+ catch (e) {
11580
+ log(`${streamType} stream received invalid JSON: ${rawData.substring(0, 200)}`, { type: 'error' });
11581
+ return;
11582
+ }
11567
11583
  for (const message of messages) {
11568
11584
  if (message.T === 'success' && message.msg === 'authenticated') {
11569
11585
  log(`${streamType} stream authenticated`, { type: 'info' });
11570
11586
  this.sendSubscription(streamType);
11571
11587
  }
11588
+ else if (message.T === 'success' && message.msg === 'connected') {
11589
+ log(`${streamType} stream connected message received`, { type: 'debug' });
11590
+ }
11591
+ else if (message.T === 'subscription') {
11592
+ log(`${streamType} subscription confirmed: trades=${message.trades?.length || 0}, quotes=${message.quotes?.length || 0}, bars=${message.bars?.length || 0}`, { type: 'info' });
11593
+ }
11572
11594
  else if (message.T === 'error') {
11573
- log(`${streamType} stream error: ${message.msg}`, { type: 'error' });
11595
+ log(`${streamType} stream error: ${message.msg} (code: ${message.code}, raw: ${JSON.stringify(message)})`, { type: 'error' });
11574
11596
  }
11575
11597
  else if (message.S) {
11576
11598
  super.emit(`${streamType}-${message.T}`, message);
11577
11599
  super.emit(`${streamType}-data`, message);
11578
11600
  }
11601
+ else {
11602
+ log(`${streamType} received unknown message type: ${JSON.stringify(message)}`, { type: 'debug' });
11603
+ }
11579
11604
  }
11580
11605
  });
11581
11606
  ws.on('close', () => {
@@ -11596,38 +11621,49 @@ class AlpacaMarketDataAPI extends require$$0$3.EventEmitter {
11596
11621
  });
11597
11622
  }
11598
11623
  sendSubscription(streamType) {
11599
- const ws = streamType === 'stock' ? this.stockWs : streamType === 'option' ? this.optionWs : this.cryptoWs;
11600
- const subscriptions = streamType === 'stock' ? this.stockSubscriptions : streamType === 'option' ? this.optionSubscriptions : this.cryptoSubscriptions;
11624
+ let ws;
11625
+ let subscriptions;
11626
+ if (streamType === 'stock') {
11627
+ ws = this.stockWs;
11628
+ subscriptions = this.stockSubscriptions;
11629
+ }
11630
+ else if (streamType === 'option') {
11631
+ ws = this.optionWs;
11632
+ subscriptions = this.optionSubscriptions;
11633
+ }
11634
+ else {
11635
+ ws = this.cryptoWs;
11636
+ subscriptions = this.cryptoSubscriptions;
11637
+ }
11638
+ log(`sendSubscription called for ${streamType} (wsReady=${ws?.readyState === WebSocket.OPEN}, trades=${subscriptions.trades?.length || 0}, quotes=${subscriptions.quotes?.length || 0}, bars=${subscriptions.bars?.length || 0})`, {
11639
+ type: 'debug',
11640
+ });
11601
11641
  if (ws && ws.readyState === WebSocket.OPEN) {
11602
11642
  const subMessagePayload = {};
11603
- if (subscriptions.trades && subscriptions.trades.length > 0) {
11643
+ if (subscriptions.trades.length > 0) {
11604
11644
  subMessagePayload.trades = subscriptions.trades;
11605
11645
  }
11606
- if (subscriptions.quotes && subscriptions.quotes.length > 0) {
11646
+ if (subscriptions.quotes.length > 0) {
11607
11647
  subMessagePayload.quotes = subscriptions.quotes;
11608
11648
  }
11609
- if (subscriptions.bars && subscriptions.bars.length > 0) {
11649
+ if (subscriptions.bars.length > 0) {
11610
11650
  subMessagePayload.bars = subscriptions.bars;
11611
11651
  }
11612
- // Crypto-specific subscription types
11613
- if (streamType === 'crypto') {
11614
- if (subscriptions.dailyBars && subscriptions.dailyBars.length > 0) {
11615
- subMessagePayload.dailyBars = subscriptions.dailyBars;
11616
- }
11617
- if (subscriptions.updatedBars && subscriptions.updatedBars.length > 0) {
11618
- subMessagePayload.updatedBars = subscriptions.updatedBars;
11619
- }
11620
- if (subscriptions.orderbooks && subscriptions.orderbooks.length > 0) {
11621
- subMessagePayload.orderbooks = subscriptions.orderbooks;
11622
- }
11623
- }
11624
11652
  if (Object.keys(subMessagePayload).length > 0) {
11625
11653
  const subMessage = {
11626
11654
  action: 'subscribe',
11627
11655
  ...subMessagePayload,
11628
11656
  };
11629
- ws.send(JSON.stringify(subMessage));
11657
+ const messageJson = JSON.stringify(subMessage);
11658
+ log(`Sending ${streamType} subscription: ${messageJson}`, { type: 'info' });
11659
+ ws.send(messageJson);
11630
11660
  }
11661
+ else {
11662
+ log(`No ${streamType} subscriptions to send (all arrays empty)`, { type: 'debug' });
11663
+ }
11664
+ }
11665
+ else {
11666
+ log(`Cannot send ${streamType} subscription: WebSocket not ready`, { type: 'warn' });
11631
11667
  }
11632
11668
  }
11633
11669
  connectStockStream() {
@@ -11640,6 +11676,11 @@ class AlpacaMarketDataAPI extends require$$0$3.EventEmitter {
11640
11676
  this.connect('option');
11641
11677
  }
11642
11678
  }
11679
+ connectCryptoStream() {
11680
+ if (!this.cryptoWs) {
11681
+ this.connect('crypto');
11682
+ }
11683
+ }
11643
11684
  disconnectStockStream() {
11644
11685
  if (this.stockWs) {
11645
11686
  this.stockWs.close();
@@ -11650,18 +11691,38 @@ class AlpacaMarketDataAPI extends require$$0$3.EventEmitter {
11650
11691
  this.optionWs.close();
11651
11692
  }
11652
11693
  }
11653
- connectCryptoStream() {
11654
- if (!this.cryptoWs) {
11655
- this.connect('crypto');
11656
- }
11657
- }
11658
11694
  disconnectCryptoStream() {
11659
11695
  if (this.cryptoWs) {
11660
11696
  this.cryptoWs.close();
11661
11697
  }
11662
11698
  }
11699
+ /**
11700
+ * Check if a specific stream is connected
11701
+ * @param streamType - The type of stream to check
11702
+ * @returns True if the stream is connected
11703
+ */
11704
+ isStreamConnected(streamType) {
11705
+ if (streamType === 'stock') {
11706
+ return this.stockWs !== null && this.stockWs.readyState === WebSocket.OPEN;
11707
+ }
11708
+ else if (streamType === 'option') {
11709
+ return this.optionWs !== null && this.optionWs.readyState === WebSocket.OPEN;
11710
+ }
11711
+ else {
11712
+ return this.cryptoWs !== null && this.cryptoWs.readyState === WebSocket.OPEN;
11713
+ }
11714
+ }
11663
11715
  subscribe(streamType, subscriptions) {
11664
- const currentSubscriptions = streamType === 'stock' ? this.stockSubscriptions : streamType === 'option' ? this.optionSubscriptions : this.cryptoSubscriptions;
11716
+ let currentSubscriptions;
11717
+ if (streamType === 'stock') {
11718
+ currentSubscriptions = this.stockSubscriptions;
11719
+ }
11720
+ else if (streamType === 'option') {
11721
+ currentSubscriptions = this.optionSubscriptions;
11722
+ }
11723
+ else {
11724
+ currentSubscriptions = this.cryptoSubscriptions;
11725
+ }
11665
11726
  Object.entries(subscriptions).forEach(([key, value]) => {
11666
11727
  if (value) {
11667
11728
  currentSubscriptions[key] = [...new Set([...(currentSubscriptions[key] || []), ...value])];
@@ -11670,7 +11731,16 @@ class AlpacaMarketDataAPI extends require$$0$3.EventEmitter {
11670
11731
  this.sendSubscription(streamType);
11671
11732
  }
11672
11733
  unsubscribe(streamType, subscriptions) {
11673
- const currentSubscriptions = streamType === 'stock' ? this.stockSubscriptions : streamType === 'option' ? this.optionSubscriptions : this.cryptoSubscriptions;
11734
+ let currentSubscriptions;
11735
+ if (streamType === 'stock') {
11736
+ currentSubscriptions = this.stockSubscriptions;
11737
+ }
11738
+ else if (streamType === 'option') {
11739
+ currentSubscriptions = this.optionSubscriptions;
11740
+ }
11741
+ else {
11742
+ currentSubscriptions = this.cryptoSubscriptions;
11743
+ }
11674
11744
  Object.entries(subscriptions).forEach(([key, value]) => {
11675
11745
  if (value) {
11676
11746
  currentSubscriptions[key] = (currentSubscriptions[key] || []).filter(s => !value.includes(s));
@@ -11680,7 +11750,16 @@ class AlpacaMarketDataAPI extends require$$0$3.EventEmitter {
11680
11750
  action: 'unsubscribe',
11681
11751
  ...subscriptions,
11682
11752
  };
11683
- const ws = streamType === 'stock' ? this.stockWs : streamType === 'option' ? this.optionWs : this.cryptoWs;
11753
+ let ws;
11754
+ if (streamType === 'stock') {
11755
+ ws = this.stockWs;
11756
+ }
11757
+ else if (streamType === 'option') {
11758
+ ws = this.optionWs;
11759
+ }
11760
+ else {
11761
+ ws = this.cryptoWs;
11762
+ }
11684
11763
  if (ws && ws.readyState === WebSocket.OPEN) {
11685
11764
  ws.send(JSON.stringify(unsubMessage));
11686
11765
  }