@aouda/client 0.1.8 → 0.1.9

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.
@@ -421,7 +421,7 @@ var import_node_url = require("url");
421
421
  // package.json
422
422
  var package_default = {
423
423
  name: "@aouda/client",
424
- version: "0.1.8",
424
+ version: "0.1.9",
425
425
  description: "Official TypeScript/JavaScript client library for Aouda",
426
426
  type: "module",
427
427
  main: "./dist/index.cjs",
@@ -536,12 +536,13 @@ var AoudaResponseError = class extends AoudaError {
536
536
  }
537
537
  };
538
538
  var AoudaApiError = class extends AoudaError {
539
- constructor(message, code, statusCode, details, requestId) {
539
+ constructor(message, code, statusCode, details, requestId, retryAfterSeconds) {
540
540
  super(message);
541
541
  this.code = code;
542
542
  this.statusCode = statusCode;
543
543
  this.details = details;
544
544
  this.requestId = requestId;
545
+ this.retryAfterSeconds = retryAfterSeconds;
545
546
  this.name = "AoudaApiError";
546
547
  }
547
548
  };
@@ -564,8 +565,8 @@ var AoudaValidationError = class extends AoudaApiError {
564
565
  }
565
566
  };
566
567
  var AoudaServerError = class extends AoudaApiError {
567
- constructor(message, code, statusCode, details, requestId) {
568
- super(message, code, statusCode, details, requestId);
568
+ constructor(message, code, statusCode, details, requestId, retryAfterSeconds) {
569
+ super(message, code, statusCode, details, requestId, retryAfterSeconds);
569
570
  this.name = "AoudaServerError";
570
571
  }
571
572
  };
@@ -1504,6 +1505,8 @@ var ERROR_CODE_MAP = {
1504
1505
  SERVICE_UNAVAILABLE: AoudaServerError,
1505
1506
  TIMEOUT: AoudaServerError,
1506
1507
  OVERLOADED: AoudaServerError,
1508
+ MEMORY_BUDGET_EXCEEDED: AoudaServerError,
1509
+ WAL_CAPACITY_EXCEEDED: AoudaServerError,
1507
1510
  AUTH_TOKEN_MISSING: AoudaAuthenticationError,
1508
1511
  AUTH_TOKEN_EXPIRED: AoudaAuthenticationError,
1509
1512
  AUTH_TOKEN_INVALID: AoudaAuthenticationError,
@@ -1531,13 +1534,22 @@ function createComposedAbortController(...signals) {
1531
1534
  }
1532
1535
  return controller;
1533
1536
  }
1534
- function createApiError(statusCode, statusText, body) {
1537
+ function parseRetryAfterSeconds(header) {
1538
+ if (header == null || header.trim() === "") return void 0;
1539
+ const trimmed = header.trim();
1540
+ if (!/^\d+$/.test(trimmed)) return void 0;
1541
+ const n = Number.parseInt(trimmed, 10);
1542
+ if (!Number.isFinite(n) || n < 0) return void 0;
1543
+ return n;
1544
+ }
1545
+ function createApiError(statusCode, statusText, body, retryAfterHeader) {
1535
1546
  const message = body.error ?? `${statusCode} ${statusText}`;
1536
1547
  const code = body.code ?? "UNKNOWN";
1537
1548
  const details = body.details;
1538
1549
  const requestId = body.requestId;
1550
+ const retryAfterSeconds = parseRetryAfterSeconds(retryAfterHeader ?? null);
1539
1551
  const Ctor = ERROR_CODE_MAP[code] ?? AoudaApiError;
1540
- return new Ctor(message, code, statusCode, details, requestId);
1552
+ return new Ctor(message, code, statusCode, details, requestId, retryAfterSeconds);
1541
1553
  }
1542
1554
  var HttpTransport = class {
1543
1555
  constructor(options) {
@@ -1630,7 +1642,8 @@ var HttpTransport = class {
1630
1642
  throw createApiError(
1631
1643
  response.status,
1632
1644
  response.statusText,
1633
- errorBody
1645
+ errorBody,
1646
+ response.headers.get("Retry-After")
1634
1647
  );
1635
1648
  }
1636
1649
  throw new AoudaResponseError(
@@ -1740,7 +1753,8 @@ var HttpTransport = class {
1740
1753
  throw createApiError(
1741
1754
  response.status,
1742
1755
  response.statusText,
1743
- errorBody
1756
+ errorBody,
1757
+ response.headers.get("Retry-After")
1744
1758
  );
1745
1759
  }
1746
1760
  throw new AoudaResponseError(
@@ -2086,6 +2100,17 @@ var CIRCUIT_BREAKER_POLICY_DISABLED = {
2086
2100
 
2087
2101
  // src/resilience/resilient-transport.ts
2088
2102
  var REQUEST_ID_HEADER3 = "X-Request-Id";
2103
+ function isCapacityBackPressure(error) {
2104
+ return error instanceof AoudaApiError && (error.code === "MEMORY_BUDGET_EXCEEDED" || error.code === "WAL_CAPACITY_EXCEEDED");
2105
+ }
2106
+ function retryDelayMs(retryPolicy, attempt, error) {
2107
+ const backoff = calculateDelay(retryPolicy, attempt);
2108
+ if (!isCapacityBackPressure(error) || !(error instanceof AoudaApiError)) {
2109
+ return backoff;
2110
+ }
2111
+ const headerMs = error.retryAfterSeconds != null ? error.retryAfterSeconds * 1e3 : 0;
2112
+ return Math.max(backoff, headerMs);
2113
+ }
2089
2114
  function delayMs(ms, signal) {
2090
2115
  if (ms <= 0) return Promise.resolve();
2091
2116
  return new Promise((resolve4, reject) => {
@@ -2140,7 +2165,7 @@ var ResilientTransport = class {
2140
2165
  } catch (error) {
2141
2166
  lastError = error;
2142
2167
  const retryable = isRetryable(error);
2143
- if (retryable) {
2168
+ if (retryable && !isCapacityBackPressure(error)) {
2144
2169
  this.circuitBreaker.recordFailure(error);
2145
2170
  }
2146
2171
  if (!retryable) {
@@ -2150,7 +2175,7 @@ var ResilientTransport = class {
2150
2175
  if (attempt > this.retryPolicy.maxRetries) {
2151
2176
  throw error;
2152
2177
  }
2153
- const delay = calculateDelay(this.retryPolicy, attempt);
2178
+ const delay = retryDelayMs(this.retryPolicy, attempt, error);
2154
2179
  try {
2155
2180
  await delayMs(delay, config.signal);
2156
2181
  } catch {
@@ -2186,7 +2211,7 @@ var ResilientTransport = class {
2186
2211
  } catch (error) {
2187
2212
  lastError = error;
2188
2213
  const retryable = isRetryable(error);
2189
- if (retryable) {
2214
+ if (retryable && !isCapacityBackPressure(error)) {
2190
2215
  this.circuitBreaker.recordFailure(error);
2191
2216
  }
2192
2217
  if (!retryable) {
@@ -2196,7 +2221,7 @@ var ResilientTransport = class {
2196
2221
  if (attempt > this.retryPolicy.maxRetries) {
2197
2222
  throw error;
2198
2223
  }
2199
- const delay = calculateDelay(this.retryPolicy, attempt);
2224
+ const delay = retryDelayMs(this.retryPolicy, attempt, error);
2200
2225
  try {
2201
2226
  await delayMs(delay, config.signal);
2202
2227
  } catch {