@discomedia/utils 1.0.21 → 1.0.23

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.0.21",
6
+ "version": "1.0.23",
7
7
  "author": "Disco Media",
8
8
  "description": "Utility functions used in Disco Media apps",
9
9
  "always-build-npm": true,
package/dist/test.js CHANGED
@@ -13350,15 +13350,18 @@ class AlpacaMarketDataAPI extends EventEmitter {
13350
13350
  stockSubscriptions = { trades: [], quotes: [], bars: [] };
13351
13351
  optionSubscriptions = { trades: [], quotes: [], bars: [] };
13352
13352
  setMode(mode = 'production') {
13353
- if (mode === 'sandbox') { // sandbox mode
13353
+ if (mode === 'sandbox') {
13354
+ // sandbox mode
13354
13355
  this.stockStreamUrl = 'wss://stream.data.sandbox.alpaca.markets/v2/sip';
13355
13356
  this.optionStreamUrl = 'wss://stream.data.sandbox.alpaca.markets/v1beta3/options';
13356
13357
  }
13357
- else if (mode === 'test') { // test mode, can only use ticker FAKEPACA
13358
+ else if (mode === 'test') {
13359
+ // test mode, can only use ticker FAKEPACA
13358
13360
  this.stockStreamUrl = 'wss://stream.data.alpaca.markets/v2/test';
13359
13361
  this.optionStreamUrl = 'wss://stream.data.alpaca.markets/v1beta3/options'; // there's no test mode for options
13360
13362
  }
13361
- else { // production
13363
+ else {
13364
+ // production
13362
13365
  this.stockStreamUrl = 'wss://stream.data.alpaca.markets/v2/sip';
13363
13366
  this.optionStreamUrl = 'wss://stream.data.alpaca.markets/v1beta3/options';
13364
13367
  }
@@ -13506,7 +13509,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13506
13509
  const currentSubscriptions = streamType === 'stock' ? this.stockSubscriptions : this.optionSubscriptions;
13507
13510
  Object.entries(subscriptions).forEach(([key, value]) => {
13508
13511
  if (value) {
13509
- currentSubscriptions[key] = (currentSubscriptions[key] || []).filter(s => !value.includes(s));
13512
+ currentSubscriptions[key] = (currentSubscriptions[key] || []).filter((s) => !value.includes(s));
13510
13513
  }
13511
13514
  });
13512
13515
  const unsubMessage = {
@@ -13569,11 +13572,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
13569
13572
  let pageCount = 0;
13570
13573
  let currency = '';
13571
13574
  // Initialize bar arrays for each symbol
13572
- symbols.forEach(symbol => {
13575
+ symbols.forEach((symbol) => {
13573
13576
  allBars[symbol] = [];
13574
13577
  });
13575
- log(`Starting historical bars fetch for ${symbolsStr} (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
13576
- type: 'info'
13578
+ log(`Starting historical bars fetch for ${symbolsStr.length} symbols (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
13579
+ type: 'info',
13577
13580
  });
13578
13581
  while (hasMorePages) {
13579
13582
  pageCount++;
@@ -13585,7 +13588,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13585
13588
  };
13586
13589
  const response = await this.makeRequest('/stocks/bars', 'GET', requestParams);
13587
13590
  if (!response.bars) {
13588
- log(`No bars data found in response for ${symbolsStr}`, { type: 'warn' });
13591
+ log(`No bars data found in response for ${symbolsStr.length} symbols`, { type: 'warn' });
13589
13592
  break;
13590
13593
  }
13591
13594
  // Track currency from first response
@@ -13601,7 +13604,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13601
13604
  allBars[symbol] = [...allBars[symbol], ...bars];
13602
13605
  pageBarsCount += bars.length;
13603
13606
  // Track date range for this page
13604
- bars.forEach(bar => {
13607
+ bars.forEach((bar) => {
13605
13608
  const barDate = new Date(bar.t);
13606
13609
  if (!earliestTimestamp || barDate < earliestTimestamp) {
13607
13610
  earliestTimestamp = barDate;
@@ -13619,9 +13622,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13619
13622
  const dateRangeStr = earliestTimestamp && latestTimestamp
13620
13623
  ? `${earliestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })} to ${latestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })}`
13621
13624
  : 'unknown range';
13622
- log(`Page ${pageCount}: Fetched ${pageBarsCount.toLocaleString()} bars (total: ${totalBarsCount.toLocaleString()}) for ${symbolsStr}, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
13623
- type: 'info'
13624
- });
13625
+ log(`Page ${pageCount}: Fetched ${pageBarsCount.toLocaleString()} bars (total: ${totalBarsCount.toLocaleString()}) for ${symbols.length} symbols, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`);
13625
13626
  // Prevent infinite loops
13626
13627
  if (pageCount > 1000) {
13627
13628
  log(`Stopping pagination after ${pageCount} pages to prevent infinite loop`, { type: 'warn' });
@@ -13629,10 +13630,10 @@ class AlpacaMarketDataAPI extends EventEmitter {
13629
13630
  }
13630
13631
  }
13631
13632
  // Final summary
13632
- const symbolCounts = Object.entries(allBars).map(([symbol, bars]) => `${symbol}: ${bars.length}`).join(', ');
13633
- log(`Historical bars fetch complete: ${totalBarsCount.toLocaleString()} total bars across ${pageCount} pages (${symbolCounts})`, {
13634
- type: 'info'
13635
- });
13633
+ const symbolsJoined = Object.entries(allBars)
13634
+ .map(([symbol, bars]) => `${symbol}: ${bars.length}`)
13635
+ .join(', ');
13636
+ log(`Historical bars fetch complete: ${totalBarsCount.toLocaleString()} total bars across ${pageCount} pages for ${symbolsJoined.length} symbols'}`);
13636
13637
  return {
13637
13638
  bars: allBars,
13638
13639
  next_page_token: null, // Always null since we fetch all pages
@@ -13899,11 +13900,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
13899
13900
  let totalBarsCount = 0;
13900
13901
  let pageCount = 0;
13901
13902
  // Initialize bar arrays for each symbol
13902
- symbols.forEach(symbol => {
13903
+ symbols.forEach((symbol) => {
13903
13904
  allBars[symbol] = [];
13904
13905
  });
13905
- log(`Starting historical options bars fetch for ${symbolsStr} (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
13906
- type: 'info'
13906
+ log(`Starting historical options bars fetch for ${symbolsStr.length} symbols (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
13907
+ type: 'info',
13907
13908
  });
13908
13909
  while (hasMorePages) {
13909
13910
  pageCount++;
@@ -13913,7 +13914,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13913
13914
  };
13914
13915
  const response = await this.makeRequest('/options/bars', 'GET', requestParams, 'v1beta1');
13915
13916
  if (!response.bars) {
13916
- log(`No options bars data found in response for ${symbolsStr}`, { type: 'warn' });
13917
+ log(`No options bars data found in response for ${symbolsStr.length} symbols`, { type: 'warn' });
13917
13918
  break;
13918
13919
  }
13919
13920
  // Combine bars for each symbol
@@ -13925,7 +13926,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13925
13926
  allBars[symbol] = [...allBars[symbol], ...bars];
13926
13927
  pageBarsCount += bars.length;
13927
13928
  // Track date range for this page
13928
- bars.forEach(bar => {
13929
+ bars.forEach((bar) => {
13929
13930
  const barDate = new Date(bar.t);
13930
13931
  if (!earliestTimestamp || barDate < earliestTimestamp) {
13931
13932
  earliestTimestamp = barDate;
@@ -13944,7 +13945,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13944
13945
  ? `${earliestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })} to ${latestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })}`
13945
13946
  : 'unknown range';
13946
13947
  log(`Page ${pageCount}: Fetched ${pageBarsCount.toLocaleString()} option bars (total: ${totalBarsCount.toLocaleString()}) for ${symbolsStr}, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
13947
- type: 'info'
13948
+ type: 'info',
13948
13949
  });
13949
13950
  // Prevent infinite loops
13950
13951
  if (pageCount > 1000) {
@@ -13953,9 +13954,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
13953
13954
  }
13954
13955
  }
13955
13956
  // Final summary
13956
- const symbolCounts = Object.entries(allBars).map(([symbol, bars]) => `${symbol}: ${bars.length}`).join(', ');
13957
+ const symbolCounts = Object.entries(allBars)
13958
+ .map(([symbol, bars]) => `${symbol}: ${bars.length}`)
13959
+ .join(', ');
13957
13960
  log(`Historical options bars fetch complete: ${totalBarsCount.toLocaleString()} total bars across ${pageCount} pages (${symbolCounts})`, {
13958
- type: 'info'
13961
+ type: 'info',
13959
13962
  });
13960
13963
  return {
13961
13964
  bars: allBars,
@@ -13979,11 +13982,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
13979
13982
  let totalTradesCount = 0;
13980
13983
  let pageCount = 0;
13981
13984
  // Initialize trades arrays for each symbol
13982
- symbols.forEach(symbol => {
13985
+ symbols.forEach((symbol) => {
13983
13986
  allTrades[symbol] = [];
13984
13987
  });
13985
- log(`Starting historical options trades fetch for ${symbolsStr} (${params.start || 'no start'} to ${params.end || 'no end'})`, {
13986
- type: 'info'
13988
+ log(`Starting historical options trades fetch for ${symbolsStr.length} symbols (${params.start || 'no start'} to ${params.end || 'no end'})`, {
13989
+ type: 'info',
13987
13990
  });
13988
13991
  while (hasMorePages) {
13989
13992
  pageCount++;
@@ -13993,7 +13996,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13993
13996
  };
13994
13997
  const response = await this.makeRequest('/options/trades', 'GET', requestParams, 'v1beta1');
13995
13998
  if (!response.trades) {
13996
- log(`No options trades data found in response for ${symbolsStr}`, { type: 'warn' });
13999
+ log(`No options trades data found in response for ${symbolsStr.length} symbols`, { type: 'warn' });
13997
14000
  break;
13998
14001
  }
13999
14002
  // Combine trades for each symbol
@@ -14005,7 +14008,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
14005
14008
  allTrades[symbol] = [...allTrades[symbol], ...trades];
14006
14009
  pageTradesCount += trades.length;
14007
14010
  // Track date range for this page
14008
- trades.forEach(trade => {
14011
+ trades.forEach((trade) => {
14009
14012
  const tradeDate = new Date(trade.t);
14010
14013
  if (!earliestTimestamp || tradeDate < earliestTimestamp) {
14011
14014
  earliestTimestamp = tradeDate;
@@ -14023,8 +14026,8 @@ class AlpacaMarketDataAPI extends EventEmitter {
14023
14026
  const dateRangeStr = earliestTimestamp && latestTimestamp
14024
14027
  ? `${earliestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })} to ${latestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })}`
14025
14028
  : 'unknown range';
14026
- log(`Page ${pageCount}: Fetched ${pageTradesCount.toLocaleString()} option trades (total: ${totalTradesCount.toLocaleString()}) for ${symbolsStr}, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
14027
- type: 'info'
14029
+ log(`Page ${pageCount}: Fetched ${pageTradesCount.toLocaleString()} option trades (total: ${totalTradesCount.toLocaleString()}) for ${symbolsStr.length} symbols, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
14030
+ type: 'info',
14028
14031
  });
14029
14032
  // Prevent infinite loops
14030
14033
  if (pageCount > 1000) {
@@ -14033,9 +14036,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
14033
14036
  }
14034
14037
  }
14035
14038
  // Final summary
14036
- const symbolCounts = Object.entries(allTrades).map(([symbol, trades]) => `${symbol}: ${trades.length}`).join(', ');
14039
+ const symbolCounts = Object.entries(allTrades)
14040
+ .map(([symbol, trades]) => `${symbol}: ${trades.length}`)
14041
+ .join(', ');
14037
14042
  log(`Historical options trades fetch complete: ${totalTradesCount.toLocaleString()} total trades across ${pageCount} pages (${symbolCounts})`, {
14038
- type: 'info'
14043
+ type: 'info',
14039
14044
  });
14040
14045
  return {
14041
14046
  trades: allTrades,
@@ -14180,7 +14185,9 @@ class AlpacaMarketDataAPI extends EventEmitter {
14180
14185
  ...(symbol && { symbols: symbol }),
14181
14186
  ...(mergedParams.limit && { limit: Math.min(50, maxLimit - fetchedCount).toString() }),
14182
14187
  ...(mergedParams.sort && { sort: mergedParams.sort }),
14183
- ...(mergedParams.include_content !== undefined ? { include_content: mergedParams.include_content.toString() } : {}),
14188
+ ...(mergedParams.include_content !== undefined
14189
+ ? { include_content: mergedParams.include_content.toString() }
14190
+ : {}),
14184
14191
  ...(pageToken && { page_token: pageToken }),
14185
14192
  });
14186
14193
  const url = `${this.v1beta1url}/news?${queryParams}`;