@oldwhisper/resilience 1.0.3
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 +100 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +199 -0
- package/dist/index.js.map +1 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Resilience
|
|
2
|
+
|
|
3
|
+
Small resilience wrapper with metrics hooks.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install resilience
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { WrapperInit } from "resilience";
|
|
15
|
+
|
|
16
|
+
function greet(x: number, y: number) {
|
|
17
|
+
return x + y;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const metrics = new WrapperInit();
|
|
21
|
+
const resilientGreet = metrics.wrap(greet)
|
|
22
|
+
|
|
23
|
+
const result = resilientGreet(1, 2);
|
|
24
|
+
console.log(result);
|
|
25
|
+
console.log(metrics.functionCalls, metrics.f_store);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Core API
|
|
29
|
+
|
|
30
|
+
### withResilience(fn, config)
|
|
31
|
+
|
|
32
|
+
Wrap any function with retry, timeout, backoff, and circuit breaker support.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { withResilience } from "resilience";
|
|
36
|
+
|
|
37
|
+
const resilient = withResilience(fetchData, {
|
|
38
|
+
name: "fetchData",
|
|
39
|
+
retries: 3,
|
|
40
|
+
timeoutMs: 1000,
|
|
41
|
+
backoff: { type: "fixed", delayMs: 100 },
|
|
42
|
+
hooks: {
|
|
43
|
+
onAttempt: ({ name, attempt }) => console.log(name, attempt),
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
await resilient();
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### WrapperInit
|
|
51
|
+
|
|
52
|
+
Metrics adapter that exposes hooks and a convenience `wrap()` helper.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
const metrics = new WrapperInit();
|
|
56
|
+
const wrapped = metrics.wrap(task, { retries: 1, timeoutMs: 500 });
|
|
57
|
+
await wrapped();
|
|
58
|
+
|
|
59
|
+
console.log(metrics.functionCalls);
|
|
60
|
+
console.log(metrics.f_store.get("task"));
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Config
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
type BackoffStrategy =
|
|
67
|
+
| { type: "fixed"; delayMs: number }
|
|
68
|
+
| { type: "exponential"; baseDelayMs: number; maxDelayMs: number; jitter?: boolean }
|
|
69
|
+
|
|
70
|
+
type CircuitBreakerConfig = {
|
|
71
|
+
failureThreshold: number
|
|
72
|
+
resetTimeoutMs: number
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type ResilienceHooks = {
|
|
76
|
+
onAttempt?: (info: { name: string; attempt: number }) => void
|
|
77
|
+
onSuccess?: (info: { name: string; attempt: number; timeMs: number }) => void
|
|
78
|
+
onFailure?: (info: { name: string; attempt: number; timeMs: number; error: unknown }) => void
|
|
79
|
+
onRetry?: (info: { name: string; attempt: number; delayMs: number; error: unknown }) => void
|
|
80
|
+
onCircuitOpen?: (info: { name: string }) => void
|
|
81
|
+
onCircuitHalfOpen?: (info: { name: string }) => void
|
|
82
|
+
onCircuitClosed?: (info: { name: string }) => void
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type ResilienceConfig = {
|
|
86
|
+
name?: string
|
|
87
|
+
timeoutMs?: number
|
|
88
|
+
retries?: number
|
|
89
|
+
backoff?: BackoffStrategy
|
|
90
|
+
retryOn?: (err: unknown) => boolean
|
|
91
|
+
circuitBreaker?: CircuitBreakerConfig
|
|
92
|
+
hooks?: ResilienceHooks
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Notes
|
|
97
|
+
|
|
98
|
+
- `withResilience` returns an async function, even if the original function is sync.
|
|
99
|
+
- Metrics are collected via hooks.
|
|
100
|
+
- If `useAbortSignal: true`, `sleep()` and `resilientFetch()` will be cancelled automatically on timeout.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function withResilience<Fn extends (...args: any[]) => any>(fn: Fn, config?: Resilience.ResilienceConfig): (...args: Parameters<Fn>) => Promise<Awaited<ReturnType<Fn>>>;
|
|
2
|
+
export declare const sleep: (ms: number, signal?: AbortSignal | undefined) => Promise<void>;
|
|
3
|
+
export declare const resilientFetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
4
|
+
export declare class WrapperInit {
|
|
5
|
+
functionCalls: number;
|
|
6
|
+
f_store: Map<string, number>;
|
|
7
|
+
record(name: string): void;
|
|
8
|
+
hooks(): Resilience.ResilienceHooks;
|
|
9
|
+
wrap<Fn extends (...args: any[]) => any>(fn: Fn, config?: Omit<Resilience.ResilienceConfig, "hooks" | "name"> & {
|
|
10
|
+
name?: string;
|
|
11
|
+
}): (...args: Parameters<Fn>) => Promise<Awaited<ReturnType<Fn>>>;
|
|
12
|
+
run<Fn extends (...args: any[]) => any>(fn: Fn, ...args: Parameters<Fn>): ReturnType<Fn>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA0FA,wBAAgB,cAAc,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAC7D,EAAE,EAAE,EAAE,EACN,MAAM,GAAE,UAAU,CAAC,gBAAqB,GACzC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAoD/D;AAED,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,EAAE,SAAQ,WAAW,GAAG,SAAwB,kBAmB1E,CAAC;AAEP,eAAO,MAAM,cAAc,GAAI,OAAO,WAAW,GAAG,GAAG,EAAE,OAAO,WAAW,sBAI1E,CAAC;AAGF,qBAAa,WAAW;IACpB,aAAa,EAAE,MAAM,CAAI;IACzB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAa;IAEzC,MAAM,CAAC,IAAI,EAAE,MAAM;IAMnB,KAAK,IAAI,UAAU,CAAC,eAAe;IAQnC,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACnC,EAAE,EAAE,EAAE,EACN,MAAM,GAAE,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,OAAO,GAAG,MAAM,CAAC,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO;IASxF,GAAG,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC;CAW3F"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/// <reference path="./global.d.ts" />
|
|
2
|
+
let activeSignal;
|
|
3
|
+
async function runWithActiveSignal(signal, fn) {
|
|
4
|
+
const prev = activeSignal;
|
|
5
|
+
activeSignal = signal;
|
|
6
|
+
try {
|
|
7
|
+
return await fn();
|
|
8
|
+
}
|
|
9
|
+
finally {
|
|
10
|
+
activeSignal = prev;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
class CircuitBreaker {
|
|
14
|
+
cfg;
|
|
15
|
+
hooks;
|
|
16
|
+
name;
|
|
17
|
+
state = "CLOSED";
|
|
18
|
+
failures = 0;
|
|
19
|
+
openedAt = 0;
|
|
20
|
+
constructor(cfg, hooks, name = "fn") {
|
|
21
|
+
this.cfg = cfg;
|
|
22
|
+
this.hooks = hooks;
|
|
23
|
+
this.name = name;
|
|
24
|
+
}
|
|
25
|
+
canAttempt() {
|
|
26
|
+
if (this.state === "CLOSED")
|
|
27
|
+
return true;
|
|
28
|
+
const now = Date.now();
|
|
29
|
+
if (this.state === "OPEN" && now - this.openedAt >= this.cfg.resetTimeoutMs) {
|
|
30
|
+
this.state = "HALF_OPEN";
|
|
31
|
+
this.hooks?.onCircuitHalfOpen?.({ name: this.name });
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return this.state === "HALF_OPEN";
|
|
35
|
+
}
|
|
36
|
+
onSuccess() {
|
|
37
|
+
if (this.state !== "CLOSED") {
|
|
38
|
+
this.state = "CLOSED";
|
|
39
|
+
this.hooks?.onCircuitClosed?.({ name: this.name });
|
|
40
|
+
}
|
|
41
|
+
this.failures = 0;
|
|
42
|
+
}
|
|
43
|
+
onFailure() {
|
|
44
|
+
this.failures += 1;
|
|
45
|
+
if (this.failures >= this.cfg.failureThreshold) {
|
|
46
|
+
this.state = "OPEN";
|
|
47
|
+
this.openedAt = Date.now();
|
|
48
|
+
this.hooks?.onCircuitOpen?.({ name: this.name });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function computeBackoffMs(strategy, attempt) {
|
|
53
|
+
if (!strategy)
|
|
54
|
+
return 0;
|
|
55
|
+
if (strategy.type === "fixed")
|
|
56
|
+
return strategy.delayMs;
|
|
57
|
+
const raw = strategy.baseDelayMs * Math.pow(2, Math.max(0, attempt - 1));
|
|
58
|
+
const capped = Math.min(raw, strategy.maxDelayMs);
|
|
59
|
+
if (!strategy.jitter)
|
|
60
|
+
return capped;
|
|
61
|
+
return Math.floor(Math.random() * capped);
|
|
62
|
+
}
|
|
63
|
+
function delay(ms) {
|
|
64
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
65
|
+
}
|
|
66
|
+
async function withTimeout(p, timeoutMs, controller) {
|
|
67
|
+
if (!timeoutMs)
|
|
68
|
+
return p;
|
|
69
|
+
return await Promise.race([
|
|
70
|
+
p,
|
|
71
|
+
new Promise((_, reject) => setTimeout(() => {
|
|
72
|
+
controller?.abort();
|
|
73
|
+
reject(new Error("TimeoutError"));
|
|
74
|
+
}, timeoutMs)),
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
export function withResilience(fn, config = {}) {
|
|
78
|
+
const name = config.name ?? fn.name ?? "anonymous";
|
|
79
|
+
const retries = config.retries ?? 0;
|
|
80
|
+
const retryOn = config.retryOn ?? (() => true);
|
|
81
|
+
const hooks = config.hooks;
|
|
82
|
+
const breaker = config.circuitBreaker
|
|
83
|
+
? new CircuitBreaker(config.circuitBreaker, hooks, name)
|
|
84
|
+
: null;
|
|
85
|
+
return (async (...args) => {
|
|
86
|
+
let lastErr = undefined;
|
|
87
|
+
for (let attempt = 1; attempt <= retries + 1; attempt++) {
|
|
88
|
+
hooks?.onAttempt?.({ name, attempt });
|
|
89
|
+
if (breaker && !breaker.canAttempt()) {
|
|
90
|
+
const e = new Error(`CircuitOpenError: ${name}`);
|
|
91
|
+
lastErr = e;
|
|
92
|
+
throw e;
|
|
93
|
+
}
|
|
94
|
+
const start = Date.now();
|
|
95
|
+
try {
|
|
96
|
+
const controller = config.useAbortSignal ? new AbortController() : undefined;
|
|
97
|
+
const result = await runWithActiveSignal(controller?.signal, async () => {
|
|
98
|
+
const execPromise = Promise.resolve(fn(...args));
|
|
99
|
+
return await withTimeout(execPromise, config.timeoutMs, controller);
|
|
100
|
+
});
|
|
101
|
+
const timeMs = Date.now() - start;
|
|
102
|
+
breaker?.onSuccess();
|
|
103
|
+
hooks?.onSuccess?.({ name, attempt, timeMs });
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
const timeMs = Date.now() - start;
|
|
108
|
+
lastErr = err;
|
|
109
|
+
breaker?.onFailure();
|
|
110
|
+
hooks?.onFailure?.({ name, attempt, timeMs, error: err });
|
|
111
|
+
const shouldRetry = attempt <= retries && retryOn(err);
|
|
112
|
+
if (!shouldRetry)
|
|
113
|
+
throw err;
|
|
114
|
+
const waitMs = computeBackoffMs(config.backoff, attempt);
|
|
115
|
+
hooks?.onRetry?.({ name, attempt, delayMs: waitMs, error: err });
|
|
116
|
+
if (waitMs > 0)
|
|
117
|
+
await delay(waitMs);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
throw lastErr ?? new Error("UnknownError");
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
export const sleep = (ms, signal = activeSignal) => new Promise((resolve, reject) => {
|
|
124
|
+
const id = setTimeout(resolve, ms);
|
|
125
|
+
if (!signal)
|
|
126
|
+
return;
|
|
127
|
+
if (signal.aborted) {
|
|
128
|
+
clearTimeout(id);
|
|
129
|
+
reject(new Error("Aborted"));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
signal.addEventListener("abort", () => {
|
|
133
|
+
clearTimeout(id);
|
|
134
|
+
reject(new Error("Aborted"));
|
|
135
|
+
}, { once: true });
|
|
136
|
+
});
|
|
137
|
+
export const resilientFetch = (input, init) => {
|
|
138
|
+
const signal = init?.signal ?? activeSignal;
|
|
139
|
+
if (!signal)
|
|
140
|
+
return fetch(input, init);
|
|
141
|
+
return fetch(input, { ...init, signal });
|
|
142
|
+
};
|
|
143
|
+
export class WrapperInit {
|
|
144
|
+
functionCalls = 0;
|
|
145
|
+
f_store = new Map();
|
|
146
|
+
record(name) {
|
|
147
|
+
const prev = this.f_store.get(name) ?? 0;
|
|
148
|
+
this.f_store.set(name, prev + 1);
|
|
149
|
+
this.functionCalls++;
|
|
150
|
+
}
|
|
151
|
+
hooks() {
|
|
152
|
+
return {
|
|
153
|
+
onAttempt: ({ name }) => {
|
|
154
|
+
this.record(name);
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
wrap(fn, config = {}) {
|
|
159
|
+
return withResilience(fn, {
|
|
160
|
+
...config,
|
|
161
|
+
name: config.name ?? fn.name ?? "anonymous",
|
|
162
|
+
hooks: this.hooks(),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
run(fn, ...args) {
|
|
166
|
+
const wf = new WrappedFunction(fn, ...args);
|
|
167
|
+
if (!this.f_store.has(wf.name)) {
|
|
168
|
+
this.f_store.set(wf.name, 0);
|
|
169
|
+
}
|
|
170
|
+
const val = wf.run();
|
|
171
|
+
const cur_count = this.f_store.get(wf.name);
|
|
172
|
+
this.f_store.set(wf.name, cur_count + 1);
|
|
173
|
+
this.functionCalls++;
|
|
174
|
+
return val.returnValue;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
class WrappedFunction {
|
|
178
|
+
fn;
|
|
179
|
+
args;
|
|
180
|
+
name;
|
|
181
|
+
constructor(fnPtr, ...args) {
|
|
182
|
+
this.fn = fnPtr;
|
|
183
|
+
this.args = args;
|
|
184
|
+
this.name = fnPtr.name;
|
|
185
|
+
}
|
|
186
|
+
run() {
|
|
187
|
+
const start = Date.now();
|
|
188
|
+
const r_val = this.fn(...this.args);
|
|
189
|
+
const end = Date.now();
|
|
190
|
+
const dif = end - start;
|
|
191
|
+
const res = {
|
|
192
|
+
time: dif,
|
|
193
|
+
returnValue: r_val,
|
|
194
|
+
inputsCount: this.args.length,
|
|
195
|
+
};
|
|
196
|
+
return res;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@oldwhisper/resilience",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "Resilience wrappers with retries, timeouts, backoff, circuit breaker, and metrics hooks.",
|
|
5
|
+
"main": "./dist/index.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.json",
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
20
|
+
"test": "node -e \"console.log('add tests')\"",
|
|
21
|
+
"start": "node src/index.ts"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [],
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"typescript": "^5.9.3"
|
|
29
|
+
}
|
|
30
|
+
}
|