flowshield 1.0.1 → 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/CHANGELOG.md +21 -26
- package/README.md +28 -0
- package/dist/cjs/policies/hedge.js +4 -2
- package/dist/cjs/policies/hedge.js.map +1 -1
- package/dist/esm/policies/hedge.js +4 -2
- package/dist/esm/policies/hedge.js.map +1 -1
- package/dist/types/policies/hedge.d.ts.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,30 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
All notable changes to **flowshield** will be documented in this file.
|
|
4
|
+
|
|
5
|
+
Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) | Versioning: [SemVer](https://semver.org/)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
### Planned
|
|
12
|
+
- Adaptive retry strategies
|
|
13
|
+
- Metrics/observability hooks
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
3
17
|
## [1.0.0] - 2026-03-30
|
|
4
18
|
|
|
5
|
-
###
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- **Fallback** — Type-safe fallback values or async fallback functions with `shouldFallback` predicate.
|
|
13
|
-
- **Rate Limiter** — Token bucket algorithm with configurable tokens per interval, reject-on-limit mode, and manual reset.
|
|
14
|
-
- **Hedge** — Hedged requests pattern — sends a parallel request after a configurable delay; first to resolve wins.
|
|
15
|
-
- **Cache** — TTL-based memoization with stale-while-revalidate, custom key generation, and eviction callbacks.
|
|
16
|
-
|
|
17
|
-
#### Composition
|
|
18
|
-
- **`pipe(...policies)`** — Compose policies left-to-right (outermost first).
|
|
19
|
-
- **`wrap(outer, inner)`** — Nest an inner policy within an outer policy.
|
|
20
|
-
|
|
21
|
-
#### Error Types
|
|
22
|
-
- `FlowShieldError` — Base error class with cause support.
|
|
23
|
-
- `TimeoutError`, `CircuitOpenError`, `BulkheadRejectedError`, `RateLimitExceededError`, `RetryExhaustedError`.
|
|
24
|
-
|
|
25
|
-
#### Infrastructure
|
|
26
|
-
- Zero dependencies.
|
|
27
|
-
- Dual ESM/CJS output with TypeScript declarations.
|
|
28
|
-
- 100% test coverage (statements, branches, functions, lines).
|
|
29
|
-
- Tree-shakable — only import what you use.
|
|
30
|
-
- Node.js ≥ 18.0.0, compatible with Bun, Deno, and edge runtimes.
|
|
19
|
+
### Added
|
|
20
|
+
- Initial release
|
|
21
|
+
- Retry with exponential backoff
|
|
22
|
+
- Circuit Breaker pattern
|
|
23
|
+
- Fault tolerance composables
|
|
24
|
+
- Edge runtime support (Node.js, Bun, Deno, Cloudflare Workers)
|
|
25
|
+
- Zero-dependency, TypeScript-first
|
package/README.md
CHANGED
|
@@ -270,3 +270,31 @@ try {
|
|
|
270
270
|
## 📄 License
|
|
271
271
|
|
|
272
272
|
[MIT](./LICENSE) © [Avinash Velu](https://github.com/Avinashvelu03)
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 💖 Support FlowShield
|
|
277
|
+
|
|
278
|
+
<div align="center">
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
282
|
+
│ │
|
|
283
|
+
│ FlowShield guards your async ops — 24/7, no breaks. │
|
|
284
|
+
│ If it's saved you from a cascading failure at 3 AM, │
|
|
285
|
+
│ consider buying the developer a coffee. ☕ │
|
|
286
|
+
│ │
|
|
287
|
+
└─────────────────────────────────────────────────────────────┘
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
> *Open-source resilience infrastructure. Built alone. Maintained with care.*
|
|
291
|
+
|
|
292
|
+
[](https://ko-fi.com/avinashvelu)
|
|
293
|
+
[](https://github.com/sponsors/Avinashvelu03)
|
|
294
|
+
|
|
295
|
+
**Other ways to keep this shield standing:**
|
|
296
|
+
- ⭐ Star [flowshield](https://github.com/Avinashvelu03/flowshield) — costs nothing, means everything
|
|
297
|
+
- 🐛 File issues or request missing fault-tolerance patterns
|
|
298
|
+
- 📢 Share FlowShield with your team or in your tech community
|
|
299
|
+
|
|
300
|
+
</div>
|
|
@@ -43,7 +43,8 @@ function hedge(options = {}) {
|
|
|
43
43
|
const doLaunchHedge = () => {
|
|
44
44
|
hedgeLaunched = true;
|
|
45
45
|
const hedgeRequest = fn();
|
|
46
|
-
|
|
46
|
+
// Use void to explicitly discard the promise and prevent unhandled rejection
|
|
47
|
+
void hedgeRequest.then((value) => trySettle(value), () => {
|
|
47
48
|
hedgeDone = true;
|
|
48
49
|
if (!primaryDone && !settled) {
|
|
49
50
|
return;
|
|
@@ -53,7 +54,8 @@ function hedge(options = {}) {
|
|
|
53
54
|
};
|
|
54
55
|
// Primary request
|
|
55
56
|
const primary = fn();
|
|
56
|
-
|
|
57
|
+
// Use void to explicitly discard the promise and prevent unhandled rejection
|
|
58
|
+
void primary.then((value) => trySettle(value), (err) => {
|
|
57
59
|
primaryDone = true;
|
|
58
60
|
primaryError = err;
|
|
59
61
|
if (!hedgeLaunched) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hedge.js","sourceRoot":"","sources":["../../../src/policies/hedge.ts"],"names":[],"mappings":";;AAmBA,
|
|
1
|
+
{"version":3,"file":"hedge.js","sourceRoot":"","sources":["../../../src/policies/hedge.ts"],"names":[],"mappings":";;AAmBA,sBAsEC;AAxFD,0CAA6C;AAE7C,MAAM,QAAQ,GAAG;IACf,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,SAAgB,KAAK,CAAC,UAAwB,EAAE;IAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAC;IAE7D,IAAA,yBAAc,EAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAEzC,OAAO,KAAK,EAAK,EAAoB,EAAc,EAAE;QACnD,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,IAAI,YAAqB,CAAC;YAC1B,IAAI,aAAa,GAAG,KAAK,CAAC;YAE1B,MAAM,SAAS,GAAG,CAAC,KAAQ,EAAE,EAAE;gBAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,GAAG,IAAI,CAAC;oBACf,YAAY,CAAC,UAAU,CAAC,CAAC;oBACzB,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,aAAa,GAAG,GAAG,EAAE;gBACzB,IAAI,WAAW,IAAI,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;oBACzC,OAAO,GAAG,IAAI,CAAC;oBACf,MAAM,CAAC,YAAY,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,aAAa,GAAG,GAAG,EAAE;gBACzB,aAAa,GAAG,IAAI,CAAC;gBACrB,MAAM,YAAY,GAAG,EAAE,EAAE,CAAC;gBAC1B,6EAA6E;gBAC7E,KAAK,YAAY,CAAC,IAAI,CACpB,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAC3B,GAAG,EAAE;oBACH,SAAS,GAAG,IAAI,CAAC;oBACjB,IAAI,CAAC,WAAW,IAAI,CAAC,OAAO,EAAE,CAAC;wBAC7B,OAAO;oBACT,CAAC;oBACD,aAAa,EAAE,CAAC;gBAClB,CAAC,CACF,CAAC;YACJ,CAAC,CAAC;YAEF,kBAAkB;YAClB,MAAM,OAAO,GAAG,EAAE,EAAE,CAAC;YACrB,6EAA6E;YAC7E,KAAK,OAAO,CAAC,IAAI,CACf,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAC3B,CAAC,GAAY,EAAE,EAAE;gBACf,WAAW,GAAG,IAAI,CAAC;gBACnB,YAAY,GAAG,GAAG,CAAC;gBAEnB,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,YAAY,CAAC,UAAU,CAAC,CAAC;oBACzB,aAAa,EAAE,CAAC;gBAClB,CAAC;gBAED,aAAa,EAAE,CAAC;YAClB,CAAC,CACF,CAAC;YAEF,0BAA0B;YAC1B,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;gBACjC,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,aAAa,EAAE,CAAC;gBAClB,CAAC;YACH,CAAC,EAAE,UAAU,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -40,7 +40,8 @@ export function hedge(options = {}) {
|
|
|
40
40
|
const doLaunchHedge = () => {
|
|
41
41
|
hedgeLaunched = true;
|
|
42
42
|
const hedgeRequest = fn();
|
|
43
|
-
|
|
43
|
+
// Use void to explicitly discard the promise and prevent unhandled rejection
|
|
44
|
+
void hedgeRequest.then((value) => trySettle(value), () => {
|
|
44
45
|
hedgeDone = true;
|
|
45
46
|
if (!primaryDone && !settled) {
|
|
46
47
|
return;
|
|
@@ -50,7 +51,8 @@ export function hedge(options = {}) {
|
|
|
50
51
|
};
|
|
51
52
|
// Primary request
|
|
52
53
|
const primary = fn();
|
|
53
|
-
|
|
54
|
+
// Use void to explicitly discard the promise and prevent unhandled rejection
|
|
55
|
+
void primary.then((value) => trySettle(value), (err) => {
|
|
54
56
|
primaryDone = true;
|
|
55
57
|
primaryError = err;
|
|
56
58
|
if (!hedgeLaunched) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hedge.js","sourceRoot":"","sources":["../../../src/policies/hedge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,QAAQ,GAAG;IACf,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,KAAK,CAAC,UAAwB,EAAE;IAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAC;IAE7D,cAAc,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAEzC,OAAO,KAAK,EAAK,EAAoB,EAAc,EAAE;QACnD,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,IAAI,YAAqB,CAAC;YAC1B,IAAI,aAAa,GAAG,KAAK,CAAC;YAE1B,MAAM,SAAS,GAAG,CAAC,KAAQ,EAAE,EAAE;gBAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,GAAG,IAAI,CAAC;oBACf,YAAY,CAAC,UAAU,CAAC,CAAC;oBACzB,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,aAAa,GAAG,GAAG,EAAE;gBACzB,IAAI,WAAW,IAAI,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;oBACzC,OAAO,GAAG,IAAI,CAAC;oBACf,MAAM,CAAC,YAAY,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,aAAa,GAAG,GAAG,EAAE;gBACzB,aAAa,GAAG,IAAI,CAAC;gBACrB,MAAM,YAAY,GAAG,EAAE,EAAE,CAAC;gBAC1B,YAAY,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"hedge.js","sourceRoot":"","sources":["../../../src/policies/hedge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,QAAQ,GAAG;IACf,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,KAAK,CAAC,UAAwB,EAAE;IAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAC;IAE7D,cAAc,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAEzC,OAAO,KAAK,EAAK,EAAoB,EAAc,EAAE;QACnD,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,IAAI,YAAqB,CAAC;YAC1B,IAAI,aAAa,GAAG,KAAK,CAAC;YAE1B,MAAM,SAAS,GAAG,CAAC,KAAQ,EAAE,EAAE;gBAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,GAAG,IAAI,CAAC;oBACf,YAAY,CAAC,UAAU,CAAC,CAAC;oBACzB,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,aAAa,GAAG,GAAG,EAAE;gBACzB,IAAI,WAAW,IAAI,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;oBACzC,OAAO,GAAG,IAAI,CAAC;oBACf,MAAM,CAAC,YAAY,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,aAAa,GAAG,GAAG,EAAE;gBACzB,aAAa,GAAG,IAAI,CAAC;gBACrB,MAAM,YAAY,GAAG,EAAE,EAAE,CAAC;gBAC1B,6EAA6E;gBAC7E,KAAK,YAAY,CAAC,IAAI,CACpB,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAC3B,GAAG,EAAE;oBACH,SAAS,GAAG,IAAI,CAAC;oBACjB,IAAI,CAAC,WAAW,IAAI,CAAC,OAAO,EAAE,CAAC;wBAC7B,OAAO;oBACT,CAAC;oBACD,aAAa,EAAE,CAAC;gBAClB,CAAC,CACF,CAAC;YACJ,CAAC,CAAC;YAEF,kBAAkB;YAClB,MAAM,OAAO,GAAG,EAAE,EAAE,CAAC;YACrB,6EAA6E;YAC7E,KAAK,OAAO,CAAC,IAAI,CACf,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAC3B,CAAC,GAAY,EAAE,EAAE;gBACf,WAAW,GAAG,IAAI,CAAC;gBACnB,YAAY,GAAG,GAAG,CAAC;gBAEnB,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,YAAY,CAAC,UAAU,CAAC,CAAC;oBACzB,aAAa,EAAE,CAAC;gBAClB,CAAC;gBAED,aAAa,EAAE,CAAC;YAClB,CAAC,CACF,CAAC;YAEF,0BAA0B;YAC1B,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;gBACjC,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,aAAa,EAAE,CAAC;gBAClB,CAAC;YACH,CAAC,EAAE,UAAU,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hedge.d.ts","sourceRoot":"","sources":["../../../src/policies/hedge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAOhD;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,IAKhC,CAAC,EAAE,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"hedge.d.ts","sourceRoot":"","sources":["../../../src/policies/hedge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAOhD;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,IAKhC,CAAC,EAAE,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAAC,CAiEnD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowshield",
|
|
3
|
-
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Zero-dependency, TypeScript-first resilience & fault-tolerance toolkit. Composable policies: retry, circuit breaker, timeout, bulkhead, fallback, rate limiter, hedge, cache.",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"test:coverage": "vitest run --coverage",
|
|
31
31
|
"lint": "eslint src/ --ext .ts",
|
|
32
32
|
"typecheck": "tsc --noEmit",
|
|
33
|
-
"prepublishOnly": "npm run build"
|
|
33
|
+
"prepublishOnly": "npm run lint && npm run typecheck && npm run test:coverage && npm run build"
|
|
34
34
|
},
|
|
35
35
|
"keywords": [
|
|
36
36
|
"resilience",
|