@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/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: []
|
|
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
|
-
|
|
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
|
-
|
|
6235
|
-
|
|
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
|
-
|
|
6269
|
-
|
|
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
|
|
6312
|
+
if (subscriptions.trades.length > 0) {
|
|
6273
6313
|
subMessagePayload.trades = subscriptions.trades;
|
|
6274
6314
|
}
|
|
6275
|
-
if (subscriptions.quotes
|
|
6315
|
+
if (subscriptions.quotes.length > 0) {
|
|
6276
6316
|
subMessagePayload.quotes = subscriptions.quotes;
|
|
6277
6317
|
}
|
|
6278
|
-
if (subscriptions.bars
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|