@discomedia/utils 1.0.21 → 1.0.22

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.22",
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;
@@ -13620,7 +13623,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13620
13623
  ? `${earliestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })} to ${latestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })}`
13621
13624
  : 'unknown range';
13622
13625
  log(`Page ${pageCount}: Fetched ${pageBarsCount.toLocaleString()} bars (total: ${totalBarsCount.toLocaleString()}) for ${symbolsStr}, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
13623
- type: 'info'
13626
+ type: 'info',
13624
13627
  });
13625
13628
  // Prevent infinite loops
13626
13629
  if (pageCount > 1000) {
@@ -13629,9 +13632,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
13629
13632
  }
13630
13633
  }
13631
13634
  // Final summary
13632
- const symbolCounts = Object.entries(allBars).map(([symbol, bars]) => `${symbol}: ${bars.length}`).join(', ');
13635
+ const symbolCounts = Object.entries(allBars)
13636
+ .map(([symbol, bars]) => `${symbol}: ${bars.length}`)
13637
+ .join(', ');
13633
13638
  log(`Historical bars fetch complete: ${totalBarsCount.toLocaleString()} total bars across ${pageCount} pages (${symbolCounts})`, {
13634
- type: 'info'
13639
+ type: 'info',
13635
13640
  });
13636
13641
  return {
13637
13642
  bars: allBars,
@@ -13899,11 +13904,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
13899
13904
  let totalBarsCount = 0;
13900
13905
  let pageCount = 0;
13901
13906
  // Initialize bar arrays for each symbol
13902
- symbols.forEach(symbol => {
13907
+ symbols.forEach((symbol) => {
13903
13908
  allBars[symbol] = [];
13904
13909
  });
13905
- log(`Starting historical options bars fetch for ${symbolsStr} (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
13906
- type: 'info'
13910
+ log(`Starting historical options bars fetch for ${symbolsStr.length} symbols (${params.timeframe}, ${params.start || 'no start'} to ${params.end || 'no end'})`, {
13911
+ type: 'info',
13907
13912
  });
13908
13913
  while (hasMorePages) {
13909
13914
  pageCount++;
@@ -13913,7 +13918,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13913
13918
  };
13914
13919
  const response = await this.makeRequest('/options/bars', 'GET', requestParams, 'v1beta1');
13915
13920
  if (!response.bars) {
13916
- log(`No options bars data found in response for ${symbolsStr}`, { type: 'warn' });
13921
+ log(`No options bars data found in response for ${symbolsStr.length} symbols`, { type: 'warn' });
13917
13922
  break;
13918
13923
  }
13919
13924
  // Combine bars for each symbol
@@ -13925,7 +13930,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13925
13930
  allBars[symbol] = [...allBars[symbol], ...bars];
13926
13931
  pageBarsCount += bars.length;
13927
13932
  // Track date range for this page
13928
- bars.forEach(bar => {
13933
+ bars.forEach((bar) => {
13929
13934
  const barDate = new Date(bar.t);
13930
13935
  if (!earliestTimestamp || barDate < earliestTimestamp) {
13931
13936
  earliestTimestamp = barDate;
@@ -13944,7 +13949,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13944
13949
  ? `${earliestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })} to ${latestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })}`
13945
13950
  : 'unknown range';
13946
13951
  log(`Page ${pageCount}: Fetched ${pageBarsCount.toLocaleString()} option bars (total: ${totalBarsCount.toLocaleString()}) for ${symbolsStr}, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
13947
- type: 'info'
13952
+ type: 'info',
13948
13953
  });
13949
13954
  // Prevent infinite loops
13950
13955
  if (pageCount > 1000) {
@@ -13953,9 +13958,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
13953
13958
  }
13954
13959
  }
13955
13960
  // Final summary
13956
- const symbolCounts = Object.entries(allBars).map(([symbol, bars]) => `${symbol}: ${bars.length}`).join(', ');
13961
+ const symbolCounts = Object.entries(allBars)
13962
+ .map(([symbol, bars]) => `${symbol}: ${bars.length}`)
13963
+ .join(', ');
13957
13964
  log(`Historical options bars fetch complete: ${totalBarsCount.toLocaleString()} total bars across ${pageCount} pages (${symbolCounts})`, {
13958
- type: 'info'
13965
+ type: 'info',
13959
13966
  });
13960
13967
  return {
13961
13968
  bars: allBars,
@@ -13979,11 +13986,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
13979
13986
  let totalTradesCount = 0;
13980
13987
  let pageCount = 0;
13981
13988
  // Initialize trades arrays for each symbol
13982
- symbols.forEach(symbol => {
13989
+ symbols.forEach((symbol) => {
13983
13990
  allTrades[symbol] = [];
13984
13991
  });
13985
- log(`Starting historical options trades fetch for ${symbolsStr} (${params.start || 'no start'} to ${params.end || 'no end'})`, {
13986
- type: 'info'
13992
+ log(`Starting historical options trades fetch for ${symbolsStr.length} symbols (${params.start || 'no start'} to ${params.end || 'no end'})`, {
13993
+ type: 'info',
13987
13994
  });
13988
13995
  while (hasMorePages) {
13989
13996
  pageCount++;
@@ -13993,7 +14000,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
13993
14000
  };
13994
14001
  const response = await this.makeRequest('/options/trades', 'GET', requestParams, 'v1beta1');
13995
14002
  if (!response.trades) {
13996
- log(`No options trades data found in response for ${symbolsStr}`, { type: 'warn' });
14003
+ log(`No options trades data found in response for ${symbolsStr.length} symbols`, { type: 'warn' });
13997
14004
  break;
13998
14005
  }
13999
14006
  // Combine trades for each symbol
@@ -14005,7 +14012,7 @@ class AlpacaMarketDataAPI extends EventEmitter {
14005
14012
  allTrades[symbol] = [...allTrades[symbol], ...trades];
14006
14013
  pageTradesCount += trades.length;
14007
14014
  // Track date range for this page
14008
- trades.forEach(trade => {
14015
+ trades.forEach((trade) => {
14009
14016
  const tradeDate = new Date(trade.t);
14010
14017
  if (!earliestTimestamp || tradeDate < earliestTimestamp) {
14011
14018
  earliestTimestamp = tradeDate;
@@ -14023,8 +14030,8 @@ class AlpacaMarketDataAPI extends EventEmitter {
14023
14030
  const dateRangeStr = earliestTimestamp && latestTimestamp
14024
14031
  ? `${earliestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })} to ${latestTimestamp.toLocaleDateString('en-US', { timeZone: 'America/New_York' })}`
14025
14032
  : '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'
14033
+ log(`Page ${pageCount}: Fetched ${pageTradesCount.toLocaleString()} option trades (total: ${totalTradesCount.toLocaleString()}) for ${symbolsStr.length} symbols, date range: ${dateRangeStr}${hasMorePages ? ', more pages available' : ', complete'}`, {
14034
+ type: 'info',
14028
14035
  });
14029
14036
  // Prevent infinite loops
14030
14037
  if (pageCount > 1000) {
@@ -14033,9 +14040,11 @@ class AlpacaMarketDataAPI extends EventEmitter {
14033
14040
  }
14034
14041
  }
14035
14042
  // Final summary
14036
- const symbolCounts = Object.entries(allTrades).map(([symbol, trades]) => `${symbol}: ${trades.length}`).join(', ');
14043
+ const symbolCounts = Object.entries(allTrades)
14044
+ .map(([symbol, trades]) => `${symbol}: ${trades.length}`)
14045
+ .join(', ');
14037
14046
  log(`Historical options trades fetch complete: ${totalTradesCount.toLocaleString()} total trades across ${pageCount} pages (${symbolCounts})`, {
14038
- type: 'info'
14047
+ type: 'info',
14039
14048
  });
14040
14049
  return {
14041
14050
  trades: allTrades,
@@ -14180,7 +14189,9 @@ class AlpacaMarketDataAPI extends EventEmitter {
14180
14189
  ...(symbol && { symbols: symbol }),
14181
14190
  ...(mergedParams.limit && { limit: Math.min(50, maxLimit - fetchedCount).toString() }),
14182
14191
  ...(mergedParams.sort && { sort: mergedParams.sort }),
14183
- ...(mergedParams.include_content !== undefined ? { include_content: mergedParams.include_content.toString() } : {}),
14192
+ ...(mergedParams.include_content !== undefined
14193
+ ? { include_content: mergedParams.include_content.toString() }
14194
+ : {}),
14184
14195
  ...(pageToken && { page_token: pageToken }),
14185
14196
  });
14186
14197
  const url = `${this.v1beta1url}/news?${queryParams}`;