@chaisser/circuit-breaker
v1.0.0
Published
Circuit breaker pattern implementation
Maintainers
Readme
⚡ @chaisser/circuit-breaker
Circuit breaker pattern implementation for resilient async operations
✨ Features
- ⚡ Circuit breaker pattern - Protect your services from cascading failures
- 🔄 Automatic state transitions - CLOSED → OPEN → HALF_OPEN cycle
- 🎯 Type-safe - Full TypeScript support with generics
- 📊 Statistics tracking - Monitor successes, failures, and rejections
- 🔔 State change callbacks - React to circuit state transitions
- 🛠️ Manual control - Force reset or trip the circuit
- ⏱️ Configurable thresholds - Custom failure threshold, reset timeout, and half-open requests
- 📈 Monitor interval - Optional background state monitoring
- 🪶 Zero dependencies - Lightweight and tree-shakeable
- 🏎️ ESM + CJS - Dual module format support
📦 Installation
npm install @chaisser/circuit-breaker
# or
yarn add @chaisser/circuit-breaker
# or
pnpm add @chaisser/circuit-breaker🚀 Quick Start
import { createCircuitBreaker } from '@chaisser/circuit-breaker';
const breaker = createCircuitBreaker({
failureThreshold: 5,
resetTimeout: 30000,
});
const data = await breaker.execute(() => fetch('/api/data').then(r => r.json()));📖 What It Does
This package provides a circuit breaker implementation for JavaScript and TypeScript. It wraps async operations and tracks failures, automatically opening the circuit when the failure threshold is reached. After a configurable timeout, it transitions to a half-open state to test recovery. Supports state change callbacks, statistics tracking, manual control, and configurable thresholds.
💡 Usage Examples
Basic Circuit Breaker
import { createCircuitBreaker } from '@chaisser/circuit-breaker';
const breaker = createCircuitBreaker({
failureThreshold: 5,
resetTimeout: 30000,
});
try {
const result = await breaker.execute(() => fetchData());
} catch (error) {
if (error instanceof CircuitOpenError) {
console.log('Circuit is open, service unavailable');
}
}With State Change Callback
import { CircuitBreaker, CircuitState } from '@chaisser/circuit-breaker';
const breaker = new CircuitBreaker({
failureThreshold: 3,
resetTimeout: 10000,
});
breaker.onStateChange((oldState, newState) => {
console.log(`Circuit: ${oldState} → ${newState}`);
if (newState === CircuitState.OPEN) {
alertTeam('Service is down!');
}
});Checking Circuit State
if (breaker.isCallAllowed()) {
const result = await breaker.execute(() => fetchData());
} else {
// Use fallback
return cachedData;
}Monitoring Statistics
const stats = breaker.getStats();
console.log(`Successes: ${stats.successes}`);
console.log(`Failures: ${stats.failures}`);
console.log(`Rejections: ${stats.rejections}`);
console.log(`Last failure: ${new Date(stats.lastFailureTime!)}`);Manual Control
// Force open the circuit
breaker.trip();
// Force close the circuit
breaker.reset();With Monitor Interval
const breaker = new CircuitBreaker({
failureThreshold: 5,
resetTimeout: 30000,
monitorInterval: 5000, // check every 5 seconds
});
// Clean up when done
breaker.shutdown();Half-Open Configuration
const breaker = new CircuitBreaker({
failureThreshold: 5,
resetTimeout: 30000,
halfOpenRequests: 3, // allow 3 test requests in half-open
});📚 API Reference
Classes
| Class | Description |
|---|---|
| CircuitBreaker | Main circuit breaker class |
| CircuitOpenError | Error thrown when circuit is open |
CircuitBreakerOptions
| Option | Type | Default | Description |
|---|---|---|---|
| failureThreshold | number | (required) | Consecutive failures before opening |
| resetTimeout | number | (required) | Ms before OPEN → HALF_OPEN |
| halfOpenRequests | number | 1 | Test requests allowed in HALF_OPEN |
| monitorInterval | number | — | Optional background check interval (ms) |
CircuitBreaker Methods
| Method | Signature | Description |
|---|---|---|
| execute(fn) | (fn: () => Promise<T>) → Promise<T> | Execute fn through the circuit breaker |
| getState() | () → CircuitState | Get current circuit state |
| getStats() | () → CircuitStats | Get success/failure/rejection counts |
| reset() | () → void | Force close the circuit |
| trip() | () → void | Force open the circuit |
| onStateChange(cb) | (cb) → void | Register state change callback |
| isCallAllowed() | () → boolean | Check if a call would be allowed |
| shutdown() | () → void | Stop monitor interval |
CircuitState Enum
| Value | Description |
|---|---|
| CLOSED | Normal operation — calls pass through |
| OPEN | Circuit tripped — calls are rejected |
| HALF_OPEN | Testing recovery — limited calls allowed |
CircuitStats
| Field | Type | Description |
|---|---|---|
| successes | number | Total successful calls |
| failures | number | Total failed calls |
| rejections | number | Calls rejected while OPEN |
| lastFailureTime | number \| null | Timestamp of last failure |
Factory Function
| Function | Signature | Description |
|---|---|---|
| createCircuitBreaker(options) | (CircuitBreakerOptions) → CircuitBreaker | Create a new circuit breaker |
🔗 Related Packages
Explore our other utility packages in the @chaisser namespace:
- @chaisser/circuit-breaker (this package) - Circuit breaker pattern implementation
- @chaisser/retry-async - Retry async functions with exponential backoff
- @chaisser/chunk-array - Split arrays into chunks
- @chaisser/string-wizard - Advanced string manipulation
- @chaisser/type-guard - Runtime type guards and validators
- @chaisser/uuid-v7 - Time-ordered UUID v7 generator
- @chaisser/wait-for - Promise-based wait utilities
- @chaisser/regex-humanizer - Regex to human-readable descriptions
- @chaisser/password-strength - Password strength checker
- @chaisser/human-time - Human-readable time formatting
- @chaisser/obj-path - Safe dot-notation object access
- @chaisser/debounce-throttle - Rate limiting utilities
- @chaisser/color-utils - Color conversion utilities
- @chaisser/deep-clone - Deep cloning functions
- @chaisser/array-group-by - Array grouping utilities
- @chaisser/merge-objects - Object merge utilities
- @chaisser/event-emitter - Typed event emitter
- @chaisser/unique-by - Array uniqueness utilities
- @chaisser/memoize - Function memoization
- @chaisser/base64-url - URL-safe base64 encoding
- @chaisser/ip-regex - IP address validation
🔒 License
MIT - Free to use in personal and commercial projects
👨 Developed by
Doruk Karaboncuk [email protected]
📄 Repository
- GitHub: @Chaisser
- NPM: @chaisser/circuit-breaker
🤝 Contributing
Contributions are welcome! Feel free to:
- Report bugs
- Suggest new features
- Submit pull requests
- Improve documentation
📞 Support
For issues, questions, or suggestions, please reach out through:
- Email: [email protected]
- GitHub Issues: Create an issue
Made with ❤️ by @chaisser
