@codingaryan/smoothapi 1.1.0 → 1.2.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @codingaryan/smoothapi
2
2
 
3
- API resilience library for TypeScript/JavaScript. It wraps the native `fetch` API with **exponential backoff, full jitter, and a finite-state machine circuit breaker** to protect against cascading failures.
3
+ API protection library for TypeScript/JavaScript. It wraps the native `fetch` API with state of the art protections like **exponential backoff, full jitter, and a finite-state machine circuit breaker** to protect against cascading failures.
4
4
 
5
5
  Zero dependencies. Small bundle size. Built for modern ESM.
6
6
 
@@ -16,19 +16,19 @@ npm install @codingaryan/smoothapi
16
16
  - **Circuit Breaker (FSM):** Isolated per-domain state machine (`CLOSED` → `OPEN` → `HALF_OPEN`).
17
17
  - **Smart Retries:** Automatically retries on specific HTTP status codes (e.g., 429, 500, 502, 503, 504) while throwing immediately on client errors (400, 401, 404).
18
18
  - **Graceful Fallbacks:** Optionally serve cached or default data instantly when the circuit is `OPEN`.
19
- - **Request Deduplication:** Automatically coalesce concurrent identical requests into a single network call.
19
+ - **Request Deduplication:** Automatically couples concurrent identical requests into a single network call.
20
20
 
21
21
  ## Usage
22
22
 
23
23
  ### Basic Usage (Defaults)
24
24
 
25
- If you don't need custom configurations, you can instantiate the resilient fetch with its defaults by simply passing an empty object.
25
+ If you don't need custom configurations, you can use the smooth fetch with its defaults by simply passing an empty object.
26
26
 
27
27
  ```typescript
28
- import { createResilientFetch } from '@codingaryan/smoothapi';
28
+ import { createSmoothFetch } from '@codingaryan/smoothapi';
29
29
 
30
30
  // Create it with default settings
31
- const fetchWithRetry = createResilientFetch({});
31
+ const fetchWithRetry = createSmoothFetch({});
32
32
 
33
33
  async function main() {
34
34
  try {
@@ -54,9 +54,9 @@ async function main() {
54
54
  You can override any of the defaults to suit your application's needs, such as adding a fallback object.
55
55
 
56
56
  ```typescript
57
- import { createResilientFetch } from '@codingaryan/smoothapi';
57
+ import { createSmoothFetch } from '@codingaryan/smoothapi';
58
58
 
59
- const fetchWithRetry = createResilientFetch({
59
+ const fetchWithRetry = createSmoothFetch({
60
60
  backoff: {
61
61
  baseDelay: 100, // ms to wait before first retry
62
62
  maxDelay: 30000, // cap on exponential growth
@@ -96,9 +96,9 @@ async function main() {
96
96
  By default, client errors (e.g. `400`, `401`, `403`, `404`, `405`) resolve immediately and bypass the retry loop. If you want to handle these errors gracefully and alert users:
97
97
 
98
98
  ```typescript
99
- import { createResilientFetch } from '@codingaryan/smoothapi';
99
+ import { createSmoothFetch } from '@codingaryan/smoothapi';
100
100
 
101
- const fetchWithRetry = createResilientFetch({
101
+ const fetchWithRetry = createSmoothFetch({
102
102
  fallbackOnNonRetryable: true,
103
103
  // Optional: Trigger custom UI logic when a client error happens
104
104
  onNonRetryableError: (status, message) => {
@@ -114,14 +114,14 @@ const fetchWithRetry = createResilientFetch({
114
114
 
115
115
  ### Request Deduplication
116
116
 
117
- When multiple identical requests are made concurrently, SmoothAPI can execute only one network call and share the result with all callers. This reduces unnecessary load on downstream services.
117
+ When multiple identical requests are made concurrently, SmoothAPI will execute only one network call and share the result with all callers. This reduces unnecessary load on downstream services and prevents exausting computing resources.
118
118
 
119
119
  **Enable with default key function** (deduplicates by URL):
120
120
 
121
121
  ```typescript
122
- import { createResilientFetch } from '@codingaryan/smoothapi';
122
+ import { createSmoothFetch } from '@codingaryan/smoothapi';
123
123
 
124
- const fetchWithRetry = createResilientFetch({
124
+ const fetchWithRetry = createSmoothFetch({
125
125
  deduplication: {} // Empty object activates deduplication
126
126
  });
127
127
 
@@ -136,7 +136,7 @@ const [a, b, c] = await Promise.all([
136
136
  **Custom key function** for advanced coalescing:
137
137
 
138
138
  ```typescript
139
- const fetchWithRetry = createResilientFetch({
139
+ const fetchWithRetry = createSmoothFetch({
140
140
  deduplication: {
141
141
  // Deduplicate by method + URL (ignores headers/body)
142
142
  keyFn: (url, options) => `${options?.method ?? 'GET'}:${url.toString()}`
@@ -147,7 +147,7 @@ const fetchWithRetry = createResilientFetch({
147
147
  **Opt out of deduplication** for specific requests:
148
148
 
149
149
  ```typescript
150
- const fetchWithRetry = createResilientFetch({
150
+ const fetchWithRetry = createSmoothFetch({
151
151
  deduplication: {
152
152
  keyFn: (url, options) => {
153
153
  // Skip dedup for POST requests
@@ -158,7 +158,7 @@ const fetchWithRetry = createResilientFetch({
158
158
  });
159
159
  ```
160
160
 
161
- * **Default Behavior**: Deduplicates by URL only (method-agnostic). Concurrent GETs to the same URL are coalesced.
161
+ * **Default Behavior**: Deduplicates by URL only (method-agnostic). Concurrent GETs to the same URL are merged.
162
162
  * **Error Propagation**: If the network call fails, all waiting callers receive the same error.
163
163
  * **Settlement**: Once a request completes, the next call to the same URL triggers a fresh network request.
164
164
 
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  import { ResilientFetchConfig } from "./types.js";
2
- export declare function createResilientFetch<T>(globalConfig: ResilientFetchConfig<T>): (url: string | URL, options?: RequestInit) => Promise<Response | T>;
2
+ export declare function createSmoothFetch<T>(globalConfig: ResilientFetchConfig<T>): (url: string | URL, options?: RequestInit) => Promise<Response | T>;
3
+ /** @deprecated use createSmoothFetch instead */
4
+ export declare const createResilientFetch: typeof createSmoothFetch;
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAWpE,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,YAAY,EAAE,oBAAoB,CAAC,CAAC,CAAC,IASzE,KAAK,MAAM,GAAG,GAAG,EACjB,UAAU,WAAW,KACpB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAuFzB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAWpE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,oBAAoB,CAAC,CAAC,CAAC,IAStE,KAAK,MAAM,GAAG,GAAG,EACjB,UAAU,WAAW,KACpB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAuFzB;AAED,gDAAgD;AAChD,eAAO,MAAM,oBAAoB,0BAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -8,14 +8,14 @@ const BACKOFF_DEFAULTS = {
8
8
  maxRetries: 3,
9
9
  };
10
10
  const DEFAULT_RETRY_ON = [429, 500, 502, 503, 504];
11
- export function createResilientFetch(globalConfig) {
11
+ export function createSmoothFetch(globalConfig) {
12
12
  const backoffConfig = { ...BACKOFF_DEFAULTS, ...globalConfig.backoff };
13
13
  const retryOn = globalConfig.retryOn ?? DEFAULT_RETRY_ON;
14
14
  const breaker = new CircuitBreakerState(globalConfig.circuitBreaker);
15
15
  const deduplicator = globalConfig.deduplication
16
16
  ? new RequestDeduplicator(globalConfig.deduplication.keyFn)
17
17
  : null;
18
- return async function resilientFetch(url, options) {
18
+ return async function smoothFetch(url, options) {
19
19
  const domain = new URL(url).hostname;
20
20
  // Block before any network IO if the circuit is OPEN.
21
21
  if (!breaker.canRequest(domain)) {
@@ -89,4 +89,6 @@ export function createResilientFetch(globalConfig) {
89
89
  return executeRequest();
90
90
  };
91
91
  }
92
+ /** @deprecated use createSmoothFetch instead */
93
+ export const createResilientFetch = createSmoothFetch;
92
94
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@codingaryan/smoothapi",
3
- "version": "1.1.0",
4
- "description": "API resilience library — exponential backoff and circuit breaker for fetch",
3
+ "version": "1.2.0",
4
+ "description": "API protection library — exponential backoff and circuit breaker for fetch",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",