@adaptic/utils 0.0.960 → 0.0.962

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import adaptic$1, { setTokenProvider, getApolloClient } from '@adaptic/backend-legacy';
1
+ import adaptic$1, { stopClient, setTokenProvider, getApolloClient } from '@adaptic/backend-legacy';
2
2
  import { format, sub, set, add, startOfDay, endOfDay, isBefore, differenceInMilliseconds } from 'date-fns';
3
3
  import { formatInTimeZone, toZonedTime, fromZonedTime } from 'date-fns-tz';
4
4
  import require$$0$4, { EventEmitter } from 'events';
@@ -307,6 +307,22 @@ const fetchAssetOverview = async (symbol) => {
307
307
  };
308
308
  }
309
309
  };
310
+ /**
311
+ * Gracefully disconnects the shared Apollo client and releases its resources.
312
+ * Call this during process shutdown to close keep-alive HTTP connections
313
+ * and drain in-flight operations.
314
+ *
315
+ * After calling `disconnectClient()`, the next call to `getSharedApolloClient()`
316
+ * will create a fresh instance.
317
+ */
318
+ const disconnectClient = () => {
319
+ if (apolloClientInstance) {
320
+ apolloClientInstance = null;
321
+ getLogger().info("[adaptic] Shared Apollo client reference cleared");
322
+ }
323
+ // Delegate to backend-legacy's stopClient() which calls .stop() on the underlying singleton
324
+ stopClient();
325
+ };
310
326
 
311
327
  const ANSI_BACKGROUND_OFFSET = 10;
312
328
 
@@ -8000,8 +8016,9 @@ const fetchTickerInfo = async (symbol, options) => {
8000
8016
  apiKey,
8001
8017
  });
8002
8018
  return massiveLimit(async () => {
8019
+ await rateLimiters.massive.acquire();
8003
8020
  try {
8004
- const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
8021
+ const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
8005
8022
  const data = await response.json();
8006
8023
  // Check for "NOT_FOUND" status and return null
8007
8024
  if (data.status === "NOT_FOUND") {
@@ -8112,8 +8129,9 @@ const fetchLastTradeImpl = async (symbol, options) => {
8112
8129
  order: "desc",
8113
8130
  });
8114
8131
  return massiveLimit(async () => {
8132
+ await rateLimiters.massive.acquire();
8115
8133
  try {
8116
- const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
8134
+ const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
8117
8135
  const data = (await response.json());
8118
8136
  if ("message" in data) {
8119
8137
  throw new Error(`Massive.com API error: ${data.message}`);
@@ -8182,8 +8200,9 @@ const fetchLastQuote = async (symbol, options) => {
8182
8200
  order: "desc",
8183
8201
  });
8184
8202
  return massiveLimit(async () => {
8203
+ await rateLimiters.massive.acquire();
8185
8204
  try {
8186
- const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
8205
+ const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
8187
8206
  const data = (await response.json());
8188
8207
  if ("message" in data) {
8189
8208
  throw new Error(`Massive.com API error: ${data.message}`);
@@ -8266,7 +8285,7 @@ const fetchPrices = async (params, options) => {
8266
8285
  while (nextUrl) {
8267
8286
  //getLogger().info(`Debug: Fetching ${nextUrl}`);
8268
8287
  await rateLimiters.massive.acquire();
8269
- const response = await fetchWithRetry(nextUrl, {}, 3, 1000);
8288
+ const response = await fetchWithRetry(nextUrl, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
8270
8289
  const data = await response.json();
8271
8290
  if (!MASSIVE_VALID_STATUSES.has(data.status)) {
8272
8291
  throw new Error(`Massive.com API responded with status: ${data.status}`);
@@ -8387,8 +8406,9 @@ const fetchGroupedDaily = async (date, options) => {
8387
8406
  include_otc: options?.includeOTC ? "true" : "false",
8388
8407
  });
8389
8408
  return massiveLimit(async () => {
8409
+ await rateLimiters.massive.acquire();
8390
8410
  try {
8391
- const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
8411
+ const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
8392
8412
  const data = await response.json();
8393
8413
  if (!MASSIVE_VALID_STATUSES.has(data.status)) {
8394
8414
  throw new Error(`Massive.com API responded with status: ${data.status}`);
@@ -8480,12 +8500,20 @@ symbol, date = new Date(), options) => {
8480
8500
  adjusted: (options?.adjusted ?? true).toString(),
8481
8501
  });
8482
8502
  return massiveLimit(async () => {
8483
- const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
8484
- const data = await response.json();
8485
- if (!MASSIVE_VALID_STATUSES.has(data.status)) {
8486
- throw new Error(`Failed to fetch daily open/close data for ${symbol}: ${data.status}`);
8503
+ await rateLimiters.massive.acquire();
8504
+ try {
8505
+ const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
8506
+ const data = await response.json();
8507
+ if (!MASSIVE_VALID_STATUSES.has(data.status)) {
8508
+ throw new Error(`Failed to fetch daily open/close data for ${symbol}: ${data.status}`);
8509
+ }
8510
+ return data;
8511
+ }
8512
+ catch (error) {
8513
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
8514
+ getLogger().error(`Error fetching daily open/close for ${symbol}: ${errorMessage}`);
8515
+ throw error;
8487
8516
  }
8488
- return data;
8489
8517
  });
8490
8518
  };
8491
8519
  /**
@@ -8546,10 +8574,11 @@ const fetchTrades = async (symbol, options) => {
8546
8574
  if (options?.sort)
8547
8575
  params.append("sort", options.sort);
8548
8576
  return massiveLimit(async () => {
8577
+ await rateLimiters.massive.acquire();
8549
8578
  const url = `${baseUrl}?${params.toString()}`;
8550
8579
  try {
8551
8580
  logIfDebug(`Fetching trades for ${symbol} from ${url}`);
8552
- const response = await fetchWithRetry(url, {}, 3, 1000);
8581
+ const response = await fetchWithRetry(url, { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 1000);
8553
8582
  const data = (await response.json());
8554
8583
  if ("message" in data) {
8555
8584
  // This is an error response
@@ -8625,8 +8654,9 @@ const fetchIndicesAggregates = async (params, options) => {
8625
8654
  }
8626
8655
  url.search = queryParams.toString();
8627
8656
  return massiveIndicesLimit(async () => {
8657
+ await rateLimiters.massive.acquire();
8628
8658
  try {
8629
- const response = await fetchWithRetry(url.toString(), {}, 3, 300);
8659
+ const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
8630
8660
  const data = await response.json();
8631
8661
  if (data.status === "ERROR") {
8632
8662
  throw new Error(`Massive API Error: ${data.error}`);
@@ -8654,8 +8684,9 @@ const fetchIndicesPreviousClose = async (indicesTicker, options) => {
8654
8684
  queryParams.append("apiKey", apiKey);
8655
8685
  url.search = queryParams.toString();
8656
8686
  return massiveIndicesLimit(async () => {
8687
+ await rateLimiters.massive.acquire();
8657
8688
  try {
8658
- const response = await fetchWithRetry(url.toString(), {}, 3, 300);
8689
+ const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
8659
8690
  const data = await response.json();
8660
8691
  if (data.status === "ERROR") {
8661
8692
  throw new Error(`Massive API Error: ${data.error}`);
@@ -8684,8 +8715,9 @@ const fetchIndicesDailyOpenClose = async (indicesTicker, date, options) => {
8684
8715
  queryParams.append("apiKey", apiKey);
8685
8716
  url.search = queryParams.toString();
8686
8717
  return massiveIndicesLimit(async () => {
8718
+ await rateLimiters.massive.acquire();
8687
8719
  try {
8688
- const response = await fetchWithRetry(url.toString(), {}, 3, 300);
8720
+ const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
8689
8721
  const data = await response.json();
8690
8722
  if (data.status === "ERROR") {
8691
8723
  throw new Error(`Massive API Error: ${data.error}`);
@@ -8725,8 +8757,9 @@ const fetchIndicesSnapshot = async (params, options) => {
8725
8757
  }
8726
8758
  url.search = queryParams.toString();
8727
8759
  return massiveIndicesLimit(async () => {
8760
+ await rateLimiters.massive.acquire();
8728
8761
  try {
8729
- const response = await fetchWithRetry(url.toString(), {}, 3, 300);
8762
+ const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
8730
8763
  const data = await response.json();
8731
8764
  if (data.status === "ERROR") {
8732
8765
  throw new Error(`Massive API Error: ${data.error}`);
@@ -8773,8 +8806,9 @@ const fetchUniversalSnapshot = async (tickers, options) => {
8773
8806
  }
8774
8807
  url.search = queryParams.toString();
8775
8808
  return massiveIndicesLimit(async () => {
8809
+ await rateLimiters.massive.acquire();
8776
8810
  try {
8777
- const response = await fetchWithRetry(url.toString(), {}, 3, 300);
8811
+ const response = await fetchWithRetry(url.toString(), { signal: createTimeoutSignal(DEFAULT_TIMEOUTS.MASSIVE_API) }, 3, 300);
8778
8812
  const data = await response.json();
8779
8813
  if (data.status === "ERROR") {
8780
8814
  throw new Error(`Massive API Error: ${data.error}`);
@@ -8838,10 +8872,11 @@ const calculateFees = async (action, trade, alpacaAccount) => {
8838
8872
  };
8839
8873
  const computeTotalFees = async (trade) => {
8840
8874
  let totalFees = 0;
8841
- // fetch alpaca account details using adaptic.alpacaAccount.get({id: trade.alpacaAccountId})
8875
+ // Use the shared singleton Apollo client to avoid creating orphaned connections
8876
+ const client = await getSharedApolloClient();
8842
8877
  const alpacaAccount = (await adaptic$1.alpacaAccount.get({
8843
8878
  id: trade.alpacaAccountId,
8844
- }));
8879
+ }, client));
8845
8880
  if (!alpacaAccount)
8846
8881
  return totalFees;
8847
8882
  const feePromises = trade?.actions?.map((action) => calculateFees(action, trade, alpacaAccount));
@@ -48962,6 +48997,25 @@ class AlpacaClient {
48962
48997
  isPaper() {
48963
48998
  return this.config.accountType === "PAPER";
48964
48999
  }
49000
+ /**
49001
+ * Execute an Alpaca SDK operation with rate limiting and retry.
49002
+ * Use this for all SDK calls to prevent rate limit breaches and handle
49003
+ * transient failures during market hours.
49004
+ *
49005
+ * @param operation - Async function that calls the SDK
49006
+ * @param label - Human-readable label for logging
49007
+ * @returns Result of the operation
49008
+ */
49009
+ async executeWithRateLimit(operation, label) {
49010
+ await rateLimiters.alpaca.acquire();
49011
+ return withRetry(operation, {
49012
+ maxRetries: 2,
49013
+ baseDelayMs: 1000,
49014
+ maxDelayMs: 10000,
49015
+ retryableStatusCodes: [429, 500, 502, 503, 504],
49016
+ retryOnNetworkError: true,
49017
+ }, `Alpaca SDK: ${label}`);
49018
+ }
48965
49019
  /**
48966
49020
  * Validate credentials by fetching account info
48967
49021
  */
@@ -49012,6 +49066,7 @@ class AlpacaClient {
49012
49066
  * @returns Response data
49013
49067
  */
49014
49068
  async makeRequest(endpoint, method = "GET", body) {
49069
+ await rateLimiters.alpaca.acquire();
49015
49070
  const url = `${this.apiBaseUrl}${endpoint}`;
49016
49071
  const options = {
49017
49072
  method,
@@ -49020,14 +49075,26 @@ class AlpacaClient {
49020
49075
  if (body && (method === "POST" || method === "PUT")) {
49021
49076
  options.body = JSON.stringify(body);
49022
49077
  }
49023
- try {
49078
+ return withRetry(async () => {
49024
49079
  const response = await fetch(url, {
49025
49080
  ...options,
49026
49081
  signal: createTimeoutSignal(DEFAULT_TIMEOUTS.ALPACA_API),
49027
49082
  });
49028
49083
  if (!response.ok) {
49029
49084
  const errorText = await response.text();
49030
- throw new Error(`API request failed (${response.status}): ${errorText}`);
49085
+ const statusCode = response.status;
49086
+ // Classify error for retry logic
49087
+ if (statusCode === 429) {
49088
+ const retryAfter = response.headers.get("Retry-After");
49089
+ throw new Error(`RATE_LIMIT: ${statusCode}${retryAfter ? `:${parseInt(retryAfter, 10) * 1000}` : ""}`);
49090
+ }
49091
+ if ([500, 502, 503, 504].includes(statusCode)) {
49092
+ throw new Error(`SERVER_ERROR: ${statusCode}`);
49093
+ }
49094
+ if ([401, 403].includes(statusCode)) {
49095
+ throw new Error(`AUTH_ERROR: ${statusCode}: ${errorText}`);
49096
+ }
49097
+ throw new Error(`CLIENT_ERROR: ${statusCode}: ${errorText}`);
49031
49098
  }
49032
49099
  // Handle empty responses (e.g., DELETE requests)
49033
49100
  const contentType = response.headers.get("content-type");
@@ -49036,14 +49103,13 @@ class AlpacaClient {
49036
49103
  return emptyObj;
49037
49104
  }
49038
49105
  return (await response.json());
49039
- }
49040
- catch (error) {
49041
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
49042
- log$k(`API request to ${endpoint} failed: ${errorMessage}`, {
49043
- type: "error",
49044
- });
49045
- throw error;
49046
- }
49106
+ }, {
49107
+ maxRetries: 2,
49108
+ baseDelayMs: 1000,
49109
+ maxDelayMs: 10000,
49110
+ retryableStatusCodes: [429, 500, 502, 503, 504],
49111
+ retryOnNetworkError: true,
49112
+ }, `Alpaca ${method} ${endpoint}`);
49047
49113
  }
49048
49114
  }
49049
49115
  // Client cache for connection pooling
@@ -49380,7 +49446,7 @@ async function getAccountDetails(client) {
49380
49446
  log$i("Fetching account details");
49381
49447
  try {
49382
49448
  const sdk = client.getSDK();
49383
- const account = await sdk.getAccount();
49449
+ const account = await client.executeWithRateLimit(() => sdk.getAccount(), "getAccount");
49384
49450
  log$i(`Account details fetched successfully for account ${account.account_number}`);
49385
49451
  return account;
49386
49452
  }
@@ -49399,7 +49465,7 @@ async function getAccountConfiguration(client) {
49399
49465
  log$i("Fetching account configuration");
49400
49466
  try {
49401
49467
  const sdk = client.getSDK();
49402
- const config = await sdk.getAccountConfigurations();
49468
+ const config = await client.executeWithRateLimit(() => sdk.getAccountConfigurations(), "getAccountConfigurations");
49403
49469
  log$i("Account configuration fetched successfully");
49404
49470
  return config;
49405
49471
  }
@@ -49421,7 +49487,7 @@ async function updateAccountConfiguration(client, config) {
49421
49487
  log$i("Updating account configuration");
49422
49488
  try {
49423
49489
  const sdk = client.getSDK();
49424
- const updatedConfig = await sdk.updateAccountConfigurations(config);
49490
+ const updatedConfig = await client.executeWithRateLimit(() => sdk.updateAccountConfigurations(config), "updateAccountConfigurations");
49425
49491
  log$i("Account configuration updated successfully");
49426
49492
  return updatedConfig;
49427
49493
  }
@@ -49443,7 +49509,7 @@ async function getPortfolioHistory(client, params) {
49443
49509
  log$i(`Fetching portfolio history with period: ${params.period || "default"}, timeframe: ${params.timeframe || "default"}`);
49444
49510
  try {
49445
49511
  const sdk = client.getSDK();
49446
- const history = await sdk.getPortfolioHistory(params);
49512
+ const history = await client.executeWithRateLimit(() => sdk.getPortfolioHistory(params), "getPortfolioHistory");
49447
49513
  log$i(`Portfolio history fetched successfully with ${history.equity?.length || 0} data points`);
49448
49514
  return history;
49449
49515
  }
@@ -52159,7 +52225,7 @@ async function getAlpacaClock(client) {
52159
52225
  log$d("Fetching market clock");
52160
52226
  try {
52161
52227
  const sdk = client.getSDK();
52162
- const clock = await sdk.getClock();
52228
+ const clock = await client.executeWithRateLimit(() => sdk.getClock(), "getClock");
52163
52229
  log$d(`Market clock fetched: is_open=${clock.is_open}, next_open=${clock.next_open}`);
52164
52230
  return clock;
52165
52231
  }
@@ -52204,10 +52270,10 @@ async function getAlpacaCalendar(client, options) {
52204
52270
  log$d(`Fetching market calendar${startStr ? ` from ${startStr}` : ""}${endStr ? ` to ${endStr}` : ""}`);
52205
52271
  try {
52206
52272
  const sdk = client.getSDK();
52207
- const calendar = await sdk.getCalendar({
52273
+ const calendar = await client.executeWithRateLimit(() => sdk.getCalendar({
52208
52274
  start: startStr,
52209
52275
  end: endStr,
52210
- });
52276
+ }), "getCalendar");
52211
52277
  log$d(`Market calendar fetched: ${calendar.length} trading days`);
52212
52278
  return calendar;
52213
52279
  }
@@ -52266,9 +52332,9 @@ async function getLatestQuote(client, symbol, feed) {
52266
52332
  const config = client.getConfig();
52267
52333
  const dataFeed = feed || config.dataFeed || "iex";
52268
52334
  // Use SDK's getLatestQuote method
52269
- const response = await sdk.getLatestQuote(normalizedSymbol, {
52335
+ const response = await client.executeWithRateLimit(() => sdk.getLatestQuote(normalizedSymbol, {
52270
52336
  feed: dataFeed,
52271
- });
52337
+ }), "getLatestQuote");
52272
52338
  if (!response) {
52273
52339
  throw new QuoteError(`No quote data returned for ${normalizedSymbol}`, "NO_DATA", normalizedSymbol);
52274
52340
  }
@@ -52323,9 +52389,9 @@ async function getLatestQuotes(client, symbols, feed) {
52323
52389
  const config = client.getConfig();
52324
52390
  const dataFeed = feed || config.dataFeed || "iex";
52325
52391
  // Use SDK's getLatestQuotes method
52326
- const response = await sdk.getLatestQuotes(normalizedSymbols, {
52392
+ const response = await client.executeWithRateLimit(() => sdk.getLatestQuotes(normalizedSymbols, {
52327
52393
  feed: dataFeed,
52328
- });
52394
+ }), "getLatestQuotes");
52329
52395
  if (!response) {
52330
52396
  throw new QuoteError("No quote data returned", "NO_DATA");
52331
52397
  }
@@ -52528,7 +52594,8 @@ async function getBars(client, params) {
52528
52594
  for (const symbol of normalizedSymbols) {
52529
52595
  result.set(symbol, []);
52530
52596
  }
52531
- // Fetch bars - the SDK handles pagination internally via async iterator
52597
+ // Acquire rate limit token before starting the async iterator
52598
+ await client.executeWithRateLimit(() => Promise.resolve(), "getBarsV2");
52532
52599
  const barsIterator = sdk.getBarsV2(normalizedSymbols.join(","), options);
52533
52600
  for await (const bar of barsIterator) {
52534
52601
  const symbol = bar.Symbol;
@@ -52578,9 +52645,9 @@ async function getLatestBars(client, symbols) {
52578
52645
  const sdk = client.getSDK();
52579
52646
  const config = client.getConfig();
52580
52647
  const dataFeed = config.dataFeed || "iex";
52581
- const response = await sdk.getLatestBars(normalizedSymbols, {
52648
+ const response = await client.executeWithRateLimit(() => sdk.getLatestBars(normalizedSymbols, {
52582
52649
  feed: dataFeed,
52583
- });
52650
+ }), "getLatestBars");
52584
52651
  const result = new Map();
52585
52652
  for (const [symbol, bar] of Object.entries(response)) {
52586
52653
  const b = bar;
@@ -52868,9 +52935,9 @@ async function getLatestTrade(client, symbol, feed) {
52868
52935
  const config = client.getConfig();
52869
52936
  const dataFeed = feed || config.dataFeed || "iex";
52870
52937
  // Use SDK's getLatestTrade method
52871
- const response = await sdk.getLatestTrade(normalizedSymbol, {
52938
+ const response = await client.executeWithRateLimit(() => sdk.getLatestTrade(normalizedSymbol, {
52872
52939
  feed: dataFeed,
52873
- });
52940
+ }), "getLatestTrade");
52874
52941
  if (!response) {
52875
52942
  throw new TradeError(`No trade data returned for ${normalizedSymbol}`, "NO_DATA", normalizedSymbol);
52876
52943
  }
@@ -52923,9 +52990,9 @@ async function getLatestTrades(client, symbols, feed) {
52923
52990
  const config = client.getConfig();
52924
52991
  const dataFeed = feed || config.dataFeed || "iex";
52925
52992
  // Use SDK's getLatestTrades method
52926
- const response = await sdk.getLatestTrades(normalizedSymbols, {
52993
+ const response = await client.executeWithRateLimit(() => sdk.getLatestTrades(normalizedSymbols, {
52927
52994
  feed: dataFeed,
52928
- });
52995
+ }), "getLatestTrades");
52929
52996
  if (!response) {
52930
52997
  throw new TradeError("No trade data returned", "NO_DATA");
52931
52998
  }
@@ -52987,7 +53054,8 @@ async function getHistoricalTrades(client, params) {
52987
53054
  options.limit = limit;
52988
53055
  }
52989
53056
  const trades = [];
52990
- // Use SDK's getTradesV2 method with pagination (async iterator)
53057
+ // Acquire rate limit token before starting the async iterator
53058
+ await client.executeWithRateLimit(() => Promise.resolve(), "getTradesV2");
52991
53059
  const tradesIterator = sdk.getTradesV2(normalizedSymbol, options);
52992
53060
  for await (const trade of tradesIterator) {
52993
53061
  trades.push({
@@ -53462,7 +53530,7 @@ async function getNews(client, params = {}) {
53462
53530
  options.include_content = true;
53463
53531
  }
53464
53532
  // Use SDK's getNews method
53465
- const response = await sdk.getNews(options);
53533
+ const response = await client.executeWithRateLimit(() => sdk.getNews(options), "getNews");
53466
53534
  if (!response || !Array.isArray(response)) {
53467
53535
  log$9("No news data returned", { type: "debug" });
53468
53536
  return [];
@@ -55273,7 +55341,7 @@ async function createOrder(client, params) {
55273
55341
  });
55274
55342
  try {
55275
55343
  const sdk = client.getSDK();
55276
- const order = await sdk.createOrder(params);
55344
+ const order = await client.executeWithRateLimit(() => sdk.createOrder(params), `createOrder ${symbol}`);
55277
55345
  log$6(`Order created successfully: ${order.id}`, {
55278
55346
  type: "info",
55279
55347
  symbol,
@@ -55312,7 +55380,7 @@ async function getOrder(client, orderId) {
55312
55380
  log$6(`Fetching order: ${orderId}`, { type: "debug" });
55313
55381
  try {
55314
55382
  const sdk = client.getSDK();
55315
- const order = await sdk.getOrder(orderId);
55383
+ const order = await client.executeWithRateLimit(() => sdk.getOrder(orderId), `getOrder ${orderId}`);
55316
55384
  log$6(`Order retrieved: ${orderId} (${order.status})`, {
55317
55385
  type: "debug",
55318
55386
  symbol: order.symbol,
@@ -55375,7 +55443,7 @@ async function getOrders(client, params = {}) {
55375
55443
  }
55376
55444
  if (params.side)
55377
55445
  queryParams.side = params.side;
55378
- const orders = await sdk.getOrders(queryParams);
55446
+ const orders = await client.executeWithRateLimit(() => sdk.getOrders(queryParams), "getOrders");
55379
55447
  log$6(`Retrieved ${orders.length} orders`, {
55380
55448
  type: "debug",
55381
55449
  metadata: { count: orders.length, status: filterDescription },
@@ -55404,7 +55472,7 @@ async function cancelOrder(client, orderId) {
55404
55472
  log$6(`Canceling order: ${orderId}`, { type: "info" });
55405
55473
  try {
55406
55474
  const sdk = client.getSDK();
55407
- await sdk.cancelOrder(orderId);
55475
+ await client.executeWithRateLimit(() => sdk.cancelOrder(orderId), "cancelOrder");
55408
55476
  log$6(`Order canceled successfully: ${orderId}`, { type: "info" });
55409
55477
  }
55410
55478
  catch (error) {
@@ -55446,7 +55514,7 @@ async function cancelAllOrders(client) {
55446
55514
  log$6("Canceling all open orders", { type: "info" });
55447
55515
  try {
55448
55516
  const sdk = client.getSDK();
55449
- const result = await sdk.cancelAllOrders();
55517
+ const result = await client.executeWithRateLimit(() => sdk.cancelAllOrders(), "cancelAllOrders");
55450
55518
  // The SDK returns an array of canceled order statuses
55451
55519
  const canceled = Array.isArray(result) ? result.length : 0;
55452
55520
  const failed = [];
@@ -55506,7 +55574,7 @@ async function replaceOrder(client, orderId, params) {
55506
55574
  });
55507
55575
  try {
55508
55576
  const sdk = client.getSDK();
55509
- const newOrder = await sdk.replaceOrder(orderId, params);
55577
+ const newOrder = await client.executeWithRateLimit(() => sdk.replaceOrder(orderId, params), "replaceOrder");
55510
55578
  log$6(`Order replaced successfully: ${orderId} -> ${newOrder.id}`, {
55511
55579
  type: "info",
55512
55580
  symbol: newOrder.symbol,
@@ -55611,7 +55679,7 @@ async function getOrderByClientId(client, clientOrderId) {
55611
55679
  log$6(`Fetching order by client_order_id: ${clientOrderId}`, { type: "debug" });
55612
55680
  try {
55613
55681
  const sdk = client.getSDK();
55614
- const order = await sdk.getOrderByClientId(clientOrderId);
55682
+ const order = await client.executeWithRateLimit(() => sdk.getOrderByClientId(clientOrderId), "getOrderByClientId");
55615
55683
  log$6(`Order retrieved by client_order_id: ${clientOrderId} -> ${order.id}`, {
55616
55684
  type: "debug",
55617
55685
  symbol: order.symbol,
@@ -58552,7 +58620,7 @@ async function getPositions(client) {
58552
58620
  log("Fetching all open positions", { type: "debug" });
58553
58621
  try {
58554
58622
  const sdk = client.getSDK();
58555
- const positions = (await sdk.getPositions());
58623
+ const positions = (await client.executeWithRateLimit(() => sdk.getPositions(), "getPositions"));
58556
58624
  log(`Retrieved ${positions.length} positions`, { type: "info" });
58557
58625
  return positions;
58558
58626
  }
@@ -58606,7 +58674,7 @@ async function getPosition(client, symbol) {
58606
58674
  log(`Fetching position for symbol: ${symbol}`, { type: "debug", symbol });
58607
58675
  try {
58608
58676
  const sdk = client.getSDK();
58609
- const position = (await sdk.getPosition(symbol));
58677
+ const position = (await client.executeWithRateLimit(() => sdk.getPosition(symbol), "getPosition"));
58610
58678
  log(`Found position for ${symbol}: ${position.qty} shares`, {
58611
58679
  type: "info",
58612
58680
  symbol,
@@ -58753,10 +58821,10 @@ async function closePosition(client, symbol, options) {
58753
58821
  let order;
58754
58822
  if (Object.keys(queryParams).length > 0) {
58755
58823
  // SDK doesn't support params, use sendRequest directly
58756
- order = (await sdk.sendRequest(`/positions/${encodeURIComponent(normalizedSymbol)}`, queryParams, null, "DELETE"));
58824
+ order = (await client.executeWithRateLimit(() => sdk.sendRequest(`/positions/${encodeURIComponent(normalizedSymbol)}`, queryParams, null, "DELETE"), "closePosition"));
58757
58825
  }
58758
58826
  else {
58759
- order = (await sdk.closePosition(normalizedSymbol));
58827
+ order = (await client.executeWithRateLimit(() => sdk.closePosition(normalizedSymbol), "closePosition"));
58760
58828
  }
58761
58829
  log(`Position close order created for ${normalizedSymbol}: ${order.id}`, {
58762
58830
  type: "info",
@@ -58797,7 +58865,7 @@ async function closeAllPositions(client, options) {
58797
58865
  cancel_orders: cancelOrders.toString(),
58798
58866
  };
58799
58867
  // Use sendRequest to pass the cancel_orders parameter
58800
- const response = await sdk.sendRequest("/positions", queryParams, null, "DELETE");
58868
+ const response = await client.executeWithRateLimit(() => sdk.sendRequest("/positions", queryParams, null, "DELETE"), "closeAllPositions");
58801
58869
  // The SDK returns an array of objects with order info
58802
58870
  const orders = Array.isArray(response) ? response : [];
58803
58871
  log(`Closed ${orders.length} positions`, { type: "info" });
@@ -58832,7 +58900,7 @@ async function closeAllPositionsAfterHours(client, options) {
58832
58900
  return [];
58833
58901
  }
58834
58902
  // First cancel all open orders
58835
- await sdk.cancelAllOrders();
58903
+ await client.executeWithRateLimit(() => sdk.cancelAllOrders(), "cancelAllOrders");
58836
58904
  log("Cancelled all open orders", { type: "info" });
58837
58905
  const orders = [];
58838
58906
  const offsetMultiplier = limitPriceOffset / 100;
@@ -58853,7 +58921,7 @@ async function closeAllPositionsAfterHours(client, options) {
58853
58921
  : roundPriceForAlpaca(currentPrice * (1 + offsetMultiplier));
58854
58922
  log(`Creating limit order to close ${position.symbol}: ${side} ${qty} shares at $${limitPrice.toFixed(2)}`, { type: "info", symbol: position.symbol });
58855
58923
  try {
58856
- const order = (await sdk.createOrder({
58924
+ const order = (await client.executeWithRateLimit(() => sdk.createOrder({
58857
58925
  symbol: position.symbol,
58858
58926
  qty: qty,
58859
58927
  side: side,
@@ -58861,7 +58929,7 @@ async function closeAllPositionsAfterHours(client, options) {
58861
58929
  time_in_force: "day",
58862
58930
  limit_price: limitPrice,
58863
58931
  extended_hours: true,
58864
- }));
58932
+ }), `createOrder ${position.symbol}`));
58865
58933
  orders.push(order);
58866
58934
  }
58867
58935
  catch (orderError) {
@@ -67896,6 +67964,7 @@ const adaptic = {
67896
67964
  getApolloClient: getSharedApolloClient,
67897
67965
  configureAuth: configureAuth,
67898
67966
  isAuthConfigured: isAuthConfigured,
67967
+ disconnectClient: disconnectClient,
67899
67968
  },
67900
67969
  alpaca: {
67901
67970
  // New SDK-based client factory (RECOMMENDED)