@adaptic/utils 0.0.904 → 0.0.906

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.
Files changed (32) hide show
  1. package/dist/index.cjs +52 -35
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.mjs +52 -35
  4. package/dist/index.mjs.map +1 -1
  5. package/dist/test.js +38 -6
  6. package/dist/test.js.map +1 -1
  7. package/dist/types/adaptic.d.ts +4 -4
  8. package/dist/types/adaptic.d.ts.map +1 -1
  9. package/dist/types/alpaca/crypto/data.d.ts.map +1 -1
  10. package/dist/types/alpaca/crypto/orders.d.ts.map +1 -1
  11. package/dist/types/alpaca/index.d.ts.map +1 -1
  12. package/dist/types/alpaca/market-data/bars.d.ts.map +1 -1
  13. package/dist/types/alpaca/market-data/news.d.ts.map +1 -1
  14. package/dist/types/alpaca/market-data/quotes.d.ts.map +1 -1
  15. package/dist/types/alpaca/market-data/trades.d.ts.map +1 -1
  16. package/dist/types/alpaca/streams/crypto-stream.d.ts.map +1 -1
  17. package/dist/types/alpaca/streams/option-stream.d.ts.map +1 -1
  18. package/dist/types/alpaca/streams/stock-stream.d.ts.map +1 -1
  19. package/dist/types/alpaca/trading/account.d.ts.map +1 -1
  20. package/dist/types/alpaca/trading/oco-orders.d.ts.map +1 -1
  21. package/dist/types/alpaca/trading/order-utils.d.ts.map +1 -1
  22. package/dist/types/alpaca/trading/orders.d.ts.map +1 -1
  23. package/dist/types/alpaca/trading/oto-orders.d.ts.map +1 -1
  24. package/dist/types/alpaca/trading/trailing-stops.d.ts.map +1 -1
  25. package/dist/types/alpaca-market-data-api.d.ts +3 -0
  26. package/dist/types/alpaca-market-data-api.d.ts.map +1 -1
  27. package/dist/types/index.d.ts +2 -2
  28. package/dist/types/index.d.ts.map +1 -1
  29. package/dist/types/schemas/polygon-schemas.d.ts +6 -6
  30. package/dist/types/types/alpaca-types.d.ts +18 -1
  31. package/dist/types/types/alpaca-types.d.ts.map +1 -1
  32. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -214,7 +214,7 @@ const isAuthConfigured = () => {
214
214
  * Returns a shared Apollo client instance with connection pooling.
215
215
  * This should be used for all @adaptic/backend-legacy operations.
216
216
  *
217
- * @returns {Promise<ApolloClientType>} The shared Apollo client instance.
217
+ * @returns {Promise<ApolloClientInstance>} The shared Apollo client instance.
218
218
  */
219
219
  const getSharedApolloClient = async () => {
220
220
  if (!apolloClientInstance) {
@@ -12359,6 +12359,8 @@ class AlpacaMarketDataAPI extends require$$0$4.EventEmitter {
12359
12359
  quotes: [],
12360
12360
  bars: [],
12361
12361
  };
12362
+ reconnectAttempts = {};
12363
+ reconnectTimers = {};
12362
12364
  setMode(mode = "production") {
12363
12365
  if (mode === "sandbox") {
12364
12366
  // sandbox mode
@@ -12397,7 +12399,7 @@ class AlpacaMarketDataAPI extends require$$0$4.EventEmitter {
12397
12399
  // when env vars are not available. Features will be unavailable until
12398
12400
  // credentials are provided at runtime.
12399
12401
  const apiKey = process.env.ALPACA_API_KEY || "";
12400
- const apiSecret = process.env.ALPACA_SECRET_KEY || "";
12402
+ const apiSecret = process.env.ALPACA_API_SECRET || process.env.ALPACA_SECRET_KEY || "";
12401
12403
  this.credentialsValid = validateAlpacaCredentials({
12402
12404
  apiKey,
12403
12405
  apiSecret,
@@ -12439,6 +12441,12 @@ class AlpacaMarketDataAPI extends require$$0$4.EventEmitter {
12439
12441
  else {
12440
12442
  url = this.cryptoStreamUrl;
12441
12443
  }
12444
+ const apiKey = process.env.ALPACA_API_KEY || "";
12445
+ const apiSecret = process.env.ALPACA_API_SECRET || process.env.ALPACA_SECRET_KEY || "";
12446
+ if (!apiKey || !apiSecret) {
12447
+ log$l(`Cannot connect ${streamType} stream: missing Alpaca credentials (ALPACA_API_KEY=${apiKey ? "set" : "MISSING"}, ALPACA_API_SECRET/ALPACA_SECRET_KEY=${apiSecret ? "set" : "MISSING"})`, { type: "error" });
12448
+ return;
12449
+ }
12442
12450
  const ws = new WebSocket(url);
12443
12451
  if (streamType === "stock") {
12444
12452
  this.stockWs = ws;
@@ -12453,8 +12461,8 @@ class AlpacaMarketDataAPI extends require$$0$4.EventEmitter {
12453
12461
  log$l(`${streamType} stream connected`, { type: "info" });
12454
12462
  const authMessage = {
12455
12463
  action: "auth",
12456
- key: process.env.ALPACA_API_KEY,
12457
- secret: process.env.ALPACA_SECRET_KEY,
12464
+ key: apiKey,
12465
+ secret: apiSecret,
12458
12466
  };
12459
12467
  ws.send(JSON.stringify(authMessage));
12460
12468
  });
@@ -12471,6 +12479,7 @@ class AlpacaMarketDataAPI extends require$$0$4.EventEmitter {
12471
12479
  for (const message of messages) {
12472
12480
  if (message.T === "success" && message.msg === "authenticated") {
12473
12481
  log$l(`${streamType} stream authenticated`, { type: "info" });
12482
+ this.reconnectAttempts[streamType] = 0;
12474
12483
  this.sendSubscription(streamType);
12475
12484
  }
12476
12485
  else if (message.T === "success" && message.msg === "connected") {
@@ -12493,8 +12502,8 @@ class AlpacaMarketDataAPI extends require$$0$4.EventEmitter {
12493
12502
  }
12494
12503
  }
12495
12504
  });
12496
- ws.on("close", () => {
12497
- log$l(`${streamType} stream disconnected`, { type: "warn" });
12505
+ ws.on("close", (code) => {
12506
+ log$l(`${streamType} stream disconnected (code: ${code})`, { type: "warn" });
12498
12507
  if (streamType === "stock") {
12499
12508
  this.stockWs = null;
12500
12509
  }
@@ -12504,12 +12513,35 @@ class AlpacaMarketDataAPI extends require$$0$4.EventEmitter {
12504
12513
  else {
12505
12514
  this.cryptoWs = null;
12506
12515
  }
12507
- // Optional: implement reconnect logic
12516
+ // Reconnect with exponential backoff (unless intentionally closed with code 1000)
12517
+ if (code !== 1000) {
12518
+ this.scheduleReconnect(streamType);
12519
+ }
12508
12520
  });
12509
12521
  ws.on("error", (error) => {
12510
12522
  log$l(`${streamType} stream error: ${error.message}`, { type: "error" });
12511
12523
  });
12512
12524
  }
12525
+ scheduleReconnect(streamType) {
12526
+ const attempts = this.reconnectAttempts[streamType] ?? 0;
12527
+ const maxAttempts = 10;
12528
+ if (attempts >= maxAttempts) {
12529
+ log$l(`${streamType} stream: max reconnect attempts (${maxAttempts}) reached, giving up`, { type: "error" });
12530
+ return;
12531
+ }
12532
+ // Exponential backoff: 1s, 2s, 4s, 8s, 16s, 30s (capped)
12533
+ const delayMs = Math.min(1000 * Math.pow(2, attempts), 30000);
12534
+ this.reconnectAttempts[streamType] = attempts + 1;
12535
+ log$l(`${streamType} stream: scheduling reconnect attempt ${attempts + 1}/${maxAttempts} in ${delayMs}ms`, { type: "info" });
12536
+ // Clear any existing reconnect timer for this stream
12537
+ if (this.reconnectTimers[streamType]) {
12538
+ clearTimeout(this.reconnectTimers[streamType]);
12539
+ }
12540
+ this.reconnectTimers[streamType] = setTimeout(() => {
12541
+ log$l(`${streamType} stream: reconnecting (attempt ${attempts + 1}/${maxAttempts})`, { type: "info" });
12542
+ this.connect(streamType);
12543
+ }, delayMs);
12544
+ }
12513
12545
  sendSubscription(streamType) {
12514
12546
  let ws;
12515
12547
  let subscriptions;
@@ -53813,7 +53845,6 @@ async function getPortfolioHistory(client, params) {
53813
53845
  log$i(`Fetching portfolio history with period: ${params.period || "default"}, timeframe: ${params.timeframe || "default"}`);
53814
53846
  try {
53815
53847
  const sdk = client.getSDK();
53816
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
53817
53848
  const history = await sdk.getPortfolioHistory(params);
53818
53849
  log$i(`Portfolio history fetched successfully with ${history.equity?.length || 0} data points`);
53819
53850
  return history;
@@ -55553,7 +55584,6 @@ async function getOpenTrailingStops(client, symbol) {
55553
55584
  if (symbol) {
55554
55585
  queryParams.symbols = symbol.toUpperCase();
55555
55586
  }
55556
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
55557
55587
  const orders = (await sdk.getOrders(queryParams));
55558
55588
  // Filter to only trailing stop orders
55559
55589
  const trailingStops = orders.filter((order) => order.type === "trailing_stop");
@@ -55791,12 +55821,11 @@ async function createOCOOrder(client, params) {
55791
55821
  limit_price: roundPriceForAlpaca$2(takeProfit.limitPrice).toString(),
55792
55822
  stop_loss: {
55793
55823
  stop_price: roundPriceForAlpaca$2(stopLoss.stopPrice).toString(),
55824
+ ...(stopLoss.limitPrice !== undefined
55825
+ ? { limit_price: roundPriceForAlpaca$2(stopLoss.limitPrice).toString() }
55826
+ : {}),
55794
55827
  },
55795
55828
  };
55796
- // Add stop-limit price if provided
55797
- if (stopLoss.limitPrice !== undefined) {
55798
- orderRequest.stop_loss.limit_price = roundPriceForAlpaca$2(stopLoss.limitPrice).toString();
55799
- }
55800
55829
  log$f(`Submitting OCO order request: ${JSON.stringify(orderRequest)}`, {
55801
55830
  symbol,
55802
55831
  type: "debug",
@@ -56211,14 +56240,14 @@ async function createOTOOrder(client, params) {
56211
56240
  }
56212
56241
  else if (dependent.type === "trailing_stop") {
56213
56242
  // Trailing stop order
56214
- orderRequest.stop_loss = {};
56243
+ const trailingStop = {};
56215
56244
  if (dependent.trailPercent !== undefined) {
56216
- orderRequest.stop_loss.trail_percent =
56217
- dependent.trailPercent.toString();
56245
+ trailingStop.trail_percent = dependent.trailPercent.toString();
56218
56246
  }
56219
56247
  if (dependent.trailPrice !== undefined) {
56220
- orderRequest.stop_loss.trail_price = roundPriceForAlpaca$1(dependent.trailPrice).toString();
56248
+ trailingStop.trail_price = roundPriceForAlpaca$1(dependent.trailPrice).toString();
56221
56249
  }
56250
+ orderRequest.stop_loss = trailingStop;
56222
56251
  }
56223
56252
  log$e(`Submitting OTO order request: ${JSON.stringify(orderRequest)}`, {
56224
56253
  symbol,
@@ -56639,7 +56668,6 @@ async function getLatestQuote(client, symbol, feed) {
56639
56668
  const config = client.getConfig();
56640
56669
  const dataFeed = feed || config.dataFeed || "iex";
56641
56670
  // Use SDK's getLatestQuote method
56642
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
56643
56671
  const response = await sdk.getLatestQuote(normalizedSymbol, {
56644
56672
  feed: dataFeed,
56645
56673
  });
@@ -56697,7 +56725,6 @@ async function getLatestQuotes(client, symbols, feed) {
56697
56725
  const config = client.getConfig();
56698
56726
  const dataFeed = feed || config.dataFeed || "iex";
56699
56727
  // Use SDK's getLatestQuotes method
56700
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
56701
56728
  const response = await sdk.getLatestQuotes(normalizedSymbols, {
56702
56729
  feed: dataFeed,
56703
56730
  });
@@ -56953,7 +56980,6 @@ async function getLatestBars(client, symbols) {
56953
56980
  const sdk = client.getSDK();
56954
56981
  const config = client.getConfig();
56955
56982
  const dataFeed = config.dataFeed || "iex";
56956
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
56957
56983
  const response = await sdk.getLatestBars(normalizedSymbols, {
56958
56984
  feed: dataFeed,
56959
56985
  });
@@ -57244,7 +57270,6 @@ async function getLatestTrade(client, symbol, feed) {
57244
57270
  const config = client.getConfig();
57245
57271
  const dataFeed = feed || config.dataFeed || "iex";
57246
57272
  // Use SDK's getLatestTrade method
57247
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57248
57273
  const response = await sdk.getLatestTrade(normalizedSymbol, {
57249
57274
  feed: dataFeed,
57250
57275
  });
@@ -57300,7 +57325,6 @@ async function getLatestTrades(client, symbols, feed) {
57300
57325
  const config = client.getConfig();
57301
57326
  const dataFeed = feed || config.dataFeed || "iex";
57302
57327
  // Use SDK's getLatestTrades method
57303
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57304
57328
  const response = await sdk.getLatestTrades(normalizedSymbols, {
57305
57329
  feed: dataFeed,
57306
57330
  });
@@ -57415,7 +57439,6 @@ async function getCurrentPrice(client, symbol, feed) {
57415
57439
  const dataFeed = feed || config.dataFeed || "iex";
57416
57440
  // Try to get quote first for mid-point price
57417
57441
  try {
57418
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57419
57442
  const quote = await sdk.getLatestQuote(normalizedSymbol, {
57420
57443
  feed: dataFeed,
57421
57444
  });
@@ -57850,7 +57873,6 @@ async function getNews(client, params = {}) {
57850
57873
  // The SDK returns a slightly different structure, so we map the fields
57851
57874
  const articles = response.map((article) => {
57852
57875
  // SDK returns properties in different format
57853
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57854
57876
  const sdkArticle = article;
57855
57877
  // Normalize to our expected format
57856
57878
  const normalizedArticle = {
@@ -61516,7 +61538,6 @@ async function getOpenCryptoOrders(client, symbols) {
61516
61538
  ? symbols.map(normalizeCryptoSymbol$1).join(",")
61517
61539
  : undefined,
61518
61540
  };
61519
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
61520
61541
  const orders = (await sdk.getOrders(queryParams));
61521
61542
  // Filter to only crypto orders (asset_class === 'crypto')
61522
61543
  const cryptoOrders = orders.filter((order) => order.asset_class === "crypto");
@@ -61718,9 +61739,7 @@ async function getCryptoBars(client, params) {
61718
61739
  result.set(symbol, []);
61719
61740
  }
61720
61741
  // Use SDK's getCryptoBars method
61721
- // The SDK may return an async iterator or a Promise depending on the version;
61722
- // cast to any so TypeScript does not constrain the runtime duck-typing below.
61723
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
61742
+ // The SDK may return an async iterator or a Promise depending on the version
61724
61743
  const barsResponse = sdk.getCryptoBars(normalizedSymbols, options);
61725
61744
  // Handle both async iterator and direct response formats
61726
61745
  if (barsResponse &&
@@ -61741,8 +61760,8 @@ async function getCryptoBars(client, params) {
61741
61760
  result.set(symbol, existingBars);
61742
61761
  }
61743
61762
  }
61744
- else if (barsResponse && barsResponse.then) {
61745
- // Handle Promise response
61763
+ else if (barsResponse && "then" in barsResponse) {
61764
+ // Handle Promise response (SDK returns thenable in some versions)
61746
61765
  const response = await barsResponse;
61747
61766
  if (response && response.bars) {
61748
61767
  for (const [symbol, bars] of Object.entries(response.bars)) {
@@ -62056,9 +62075,7 @@ async function getCryptoTrades(client, symbol, start, end, limit) {
62056
62075
  options.limit = limit;
62057
62076
  }
62058
62077
  const trades = [];
62059
- // The SDK may return an async iterator or a Promise depending on the version;
62060
- // cast to any so TypeScript does not constrain the runtime duck-typing below.
62061
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
62078
+ // The SDK may return an async iterator or a Promise depending on the version
62062
62079
  const tradesResponse = sdk.getCryptoTrades(normalizedSymbol, options);
62063
62080
  // Handle both async iterator and direct response formats
62064
62081
  if (tradesResponse &&
@@ -62077,8 +62094,8 @@ async function getCryptoTrades(client, symbol, start, end, limit) {
62077
62094
  }
62078
62095
  }
62079
62096
  }
62080
- else if (tradesResponse && tradesResponse.then) {
62081
- // Handle Promise response
62097
+ else if (tradesResponse && "then" in tradesResponse) {
62098
+ // Handle Promise response (SDK returns thenable in some versions)
62082
62099
  const response = await tradesResponse;
62083
62100
  if (response && response.trades) {
62084
62101
  const tradeArray = response.trades;