@adaptic/utils 0.0.380 → 0.0.382
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 +110 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +110 -31
- package/dist/index.mjs.map +1 -1
- package/dist/test.js +110 -31
- package/dist/test.js.map +1 -1
- package/dist/types/alpaca-market-data-api.d.ts +7 -7
- package/dist/types/alpaca-market-data-api.d.ts.map +1 -1
- package/dist/types/types/alpaca-types.d.ts +32 -37
- package/dist/types/types/alpaca-types.d.ts.map +1 -1
- package/package.json +2 -1
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: []
|
|
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
|
-
|
|
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
|
-
|
|
11566
|
-
|
|
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
|
-
|
|
11600
|
-
|
|
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
|
|
11643
|
+
if (subscriptions.trades.length > 0) {
|
|
11604
11644
|
subMessagePayload.trades = subscriptions.trades;
|
|
11605
11645
|
}
|
|
11606
|
-
if (subscriptions.quotes
|
|
11646
|
+
if (subscriptions.quotes.length > 0) {
|
|
11607
11647
|
subMessagePayload.quotes = subscriptions.quotes;
|
|
11608
11648
|
}
|
|
11609
|
-
if (subscriptions.bars
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|