floe-guard 0.6.0 → 0.7.0

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.cjs CHANGED
@@ -29,7 +29,8 @@ __export(index_exports, {
29
29
  budgetGuardMiddleware: () => budgetGuardMiddleware,
30
30
  priceTokens: () => priceTokens,
31
31
  pricing: () => pricing_exports,
32
- resolvePrice: () => resolvePrice
32
+ resolvePrice: () => resolvePrice,
33
+ withBudgetRetry: () => withBudgetRetry
33
34
  });
34
35
  module.exports = __toCommonJS(index_exports);
35
36
 
@@ -1653,6 +1654,42 @@ function budgetGuardMiddleware(guard) {
1653
1654
  }
1654
1655
  };
1655
1656
  }
1657
+
1658
+ // src/retry.ts
1659
+ function defaultRetryIf(error) {
1660
+ return !(error instanceof BudgetExceeded);
1661
+ }
1662
+ async function withBudgetRetry(guard, call, options = {}) {
1663
+ const maxAttempts = options.maxAttempts ?? 2;
1664
+ if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {
1665
+ throw new RangeError(`maxAttempts must be an integer >= 1, got ${maxAttempts}`);
1666
+ }
1667
+ const retryIf = options.retryIf ?? defaultRetryIf;
1668
+ let plan = { call, estimatedCost: options.estimatedCost };
1669
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
1670
+ try {
1671
+ return await plan.call();
1672
+ } catch (error) {
1673
+ if (attempt >= maxAttempts || !retryIf(error)) {
1674
+ throw error;
1675
+ }
1676
+ plan = await nextPlan(guard, error, plan, options.onDegrade);
1677
+ }
1678
+ }
1679
+ throw new Error("unreachable");
1680
+ }
1681
+ async function nextPlan(guard, error, current, onDegrade) {
1682
+ const advisory = guard.advisory();
1683
+ if (advisory.nearLimit && onDegrade !== void 0) {
1684
+ const degraded = await onDegrade(error, advisory);
1685
+ if (degraded !== void 0) {
1686
+ guard.check(degraded.estimatedCost);
1687
+ return degraded;
1688
+ }
1689
+ }
1690
+ guard.check(current.estimatedCost);
1691
+ return current;
1692
+ }
1656
1693
  // Annotate the CommonJS export names for ESM import in node:
1657
1694
  0 && (module.exports = {
1658
1695
  BudgetExceeded,
@@ -1664,6 +1701,7 @@ function budgetGuardMiddleware(guard) {
1664
1701
  budgetGuardMiddleware,
1665
1702
  priceTokens,
1666
1703
  pricing,
1667
- resolvePrice
1704
+ resolvePrice,
1705
+ withBudgetRetry
1668
1706
  });
1669
1707
  //# sourceMappingURL=index.cjs.map