🚀 Installation
rezilia works seamlessly across all modern Node.js and Bun package managers:
Quick Start
import { SmartCache, SmartLogger, retry } from 'rezilia';
// 1. Cache: 1000 concurrent calls collapse into exactly 1 database fetch
const cache = new SmartCache({ defaultTtl: 60_000 });
const user = await cache.get('user:42', () => db.findUser(42));
// 2. Logger: Context & requestId auto-propagate across all async boundaries
const logger = new SmartLogger({ serviceName: 'payment-service' });
logger.runWithContext({ requestId: req.id }, async () => {
logger.info('Processing transaction'); // contains requestId automatically!
});
// 3. Retry: Exponential backoff + Circuit breaker protection
const data = await retry(() => paymentGateway.charge(order), {
attempts: 4,
timeout: 5_000,
circuitBreaker: { threshold: 5, resetAfter: 30_000 }
});
Play CDN
No bundler, no npm install, no build step. Drop a single <script> tag into any plain HTML page and rezilia attaches itself to window.rezilia — ready to use immediately.
Quick Start (Plain HTML)
<script src="https://cdn.jsdelivr.net/npm/rezilia/dist/browser/rezilia.min.js"></script>
<script>
const { SmartRetry, SmartCache, BrowserLogger } = window.rezilia;
// Structured logging — no bundler required
const logger = new BrowserLogger({ service: 'landing-page', pretty: true });
logger.setContext({ userId: 'u_42' });
// Retry with exponential backoff + circuit breaker
const retry = new SmartRetry({ attempts: 3, baseDelay: 500 });
// Singleflight cache — dedupes concurrent fetches, in-memory
const cache = new SmartCache({ defaultTtl: 60_000 });
async function loadUser() {
logger.info('Fetching user profile');
const user = await cache.get('user:42', () =>
retry.execute(() => fetch('/api/user/42').then(r => r.json()))
);
logger.info('User loaded', { user });
}
loadUser();
</script>
What's Included in the CDN Build
The browser bundle only ships APIs that run without Node.js internals (no AsyncLocalStorage, no ioredis). It is built from src/browser/index.ts, which re-exports a browser-safe subset of the toolkit:
🎯 Problems rezilia Solves
Every production Node.js backend eventually runs into the same three catastrophic walls:
| Failure Mode | Without rezilia | With rezilia |
|---|---|---|
| Cache Stampede | 1,000 requests hit your database simultaneously the moment a TTL expires, causing severe query latency and DB lockouts. | Singleflight Mutex — exactly 1 query executes; the other 999 callers await and share the identical result in memory. |
| Lost Context Logs | requestId disappears as soon as code awaits an external microservice or timer, leaving disjointed log files. |
AsyncLocalStorage — requestId and correlation tags flow through all nested async calls automatically with zero manual parameter passing. |
| Cascading Outages | A slow downstream partner API backs up thread queues and crashes your entire microservice mesh. | Circuit Breaker — trips OPEN on consecutive failures, immediately failing fast to protect server health until the provider recovers. |
1. 🔄 SmartRetry & Circuit Breaker
Resilient retries with exponential backoff, randomized jitter, individual attempt timeouts, and an integrated 3-state Circuit Breaker.
SmartRetry Options Reference
| Attribute | Type | Default | Allowed Values / Range | Description |
|---|---|---|---|---|
attempts |
number | 3 |
1 to 20 |
Maximum total execution attempts (initial try + retries) before throwing error. |
baseDelay |
number (ms) | 500 |
50 to 10000 |
Initial wait time before the first retry attempt. |
maxDelay |
number (ms) | 30000 |
1000 to 120000 |
Ceiling limit for exponential backoff delay to avoid infinite stalls. |
jitter |
number | 0.2 |
0.0 (0%) to 1.0 (100%) |
Randomized delay variance (+/- percentage) preventing synchronized thundering herds. |
timeout |
number (ms) | 10000 |
0 (disabled) or > 0 |
Per-attempt execution timeout. If an attempt hangs, it is aborted and retried. |
circuitBreaker |
object | undefined |
{ threshold, resetAfter, halfOpenSuccesses } |
Configuration object enabling the stateful Circuit Breaker. |
shouldRetry |
(err: Error) => boolean | () => true |
Custom predicate function | Inspects errors to skip retries on 4xx client issues and only retry on 5xx/network errors. |
2. 📦 SmartCache & Singleflight
Two-tier caching engine with Singleflight deduplication to eradicate cache stampedes, plus Stale-While-Revalidate (SWR) for zero latency spikes.
SmartCache Options Reference
| Attribute | Type | Default | Allowed Values / Range | Description |
|---|---|---|---|---|
defaultTtl |
number (ms) | 60000 (1m) |
1000 to 86400000 |
Default expiration lifetime for stored cache items. |
jitterFactor |
number | 0.1 (10%) |
0.0 to 0.5 |
Applies +/- randomness to TTL to prevent simultaneous mass cache eviction. |
staleWhileRevalidate |
boolean | false |
true | false |
If enabled, serves expired data immediately while fetching fresh data in the background. |
staleTtl |
number (ms) | 5000 (5s) |
1000 to 60000 |
Maximum time window allowed to serve stale data while revalidation finishes. |
store |
CacheStore | MemoryStore |
MemoryStore | RedisStore | Storage backend adapter. Supports optional Redis clustering via ioredis. |
3. 📝 SmartLogger & Context Propagation
Zero-overhead structured JSON logger powered by Node.js AsyncLocalStorage. Auto-redacts sensitive secrets and carries correlation IDs across async boundaries.
import { SmartLogger } from 'rezilia/logger';
const logger = new SmartLogger({ serviceName: 'billing-api' });
// Context flows automatically into every nested function call
logger.runWithContext({ requestId: 'req_981a', userId: 'usr_42' }, async () => {
logger.info('Initiating payment');
await chargeCustomer();
logger.info('Charge complete');
});
// Automatic Secret Redaction
logger.info('User auth', { apiKey: 'sk_live_990182', password: 'hunter2' });
// Output: { "apiKey": "[REDACTED]", "password": "[REDACTED]" }
SmartLogger Options Reference
| Attribute | Type | Default | Allowed Values | Description |
|---|---|---|---|---|
serviceName |
string | Required | e.g. 'order-api' |
Service name injected into every emitted JSON log record. |
minLevel |
string | 'info' |
'debug' | 'info' | 'warn' | 'error' | 'silent' |
Minimum threshold required for a log message to be output. |
redactKeys |
string[] | [password, token, apiKey, secret, authorization, ...] |
Array of keys | List of sensitive key names that are automatically replaced with "[REDACTED]". |
4. 📟 BrowserLogger & Live Demo CDN
The drop-in logger for plain HTML/JS projects — a lightweight sibling of SmartLogger that swaps AsyncLocalStorage for a simple context object and process.stdout for console.*. Same structured-JSON output, same automatic secret redaction, zero Node.js dependency.
Watch exactly what appears in your browser console as each log call runs — press ▶ Replay Animation to see it again:
Sample Code
import { BrowserLogger } from 'rezilia/browser'; // or window.rezilia via CDN
const logger = new BrowserLogger({
service: 'checkout-widget',
pretty: true, // human-readable console output (default: JSON)
timeFormat: 'time', // 'iso' | 'full' | 'time'
});
// Context merges into every subsequent log call
logger.setContext({ requestId: 'req_981a', userId: 'u_42' });
logger.debug('Widget mounted');
logger.info('Fetching cart', { cartId: 'cart_77' });
logger.warn('Coupon expired', { code: 'SAVE10' });
// Automatic secret redaction — sensitive keys become '***'
logger.info('User authenticated', { token: 'sk_live_990182', password: 'hunter2' });
// → { ..., "token": "***", "password": "***" }
logger.error('Payment failed', { reason: 'card_declined' });
BrowserLogger Options Reference
| Attribute | Type | Default | Allowed Values | Description |
|---|---|---|---|---|
service |
string | 'app' |
e.g. 'checkout-widget' |
Service name stamped onto every log entry. |
level |
LogLevel | 'info' |
'debug' | 'info' | 'warn' | 'error' |
Minimum level emitted — anything below this threshold is silently dropped. |
pretty |
boolean | false |
true | false |
When true, emits human-readable [time] [LEVEL] [service] message lines instead of raw JSON. |
redact |
string[] | [password, token, secret, authorization] |
Array of field names | Field names replaced with '***' before being logged, matched case-insensitively. |
timeFormat |
string | 'iso' |
'iso' | 'full' | 'time' |
Timestamp style used in pretty mode — ISO string, full date-time, or local time only. |
🌳 Tree-Shakeable Imports
rezilia is engineered for minimal bundle footprint. You can import only the specific sub-modules your service requires:
import { SmartCache } from 'rezilia/cache'; // Cache only
import { SmartLogger } from 'rezilia/logger'; // Logger only
import { retry } from 'rezilia/retry'; // Retry only
import { SmartCache, SmartLogger, retry } from 'rezilia'; // All utilities
// CommonJS is fully supported
const { SmartCache } = require('rezilia/cache');
🏆 Why rezilia vs Alternatives
A feature-by-feature comparison with common standalone libraries in the Node.js ecosystem:
| Capability | rezilia | node-cache | winston | axios-retry |
|---|---|---|---|---|
| Singleflight Stampede Protection | ✓ Built-in | ✗ No | ✗ No | ✗ No |
| Stale-While-Revalidate (SWR) | ✓ Built-in | ✗ No | ✗ No | ✗ No |
| AsyncLocalStorage Auto-Context | ✓ Built-in | ✗ No | ✗ Manual | ✗ No |
| Automatic Secret Redaction | ✓ Built-in | ✗ No | ∼ Plugin | ✗ No |
| Circuit Breaker Protection | ✓ Built-in | ✗ No | ✗ No | ∼ Partial |
| Per-Attempt Timeouts | ✓ Built-in | ✗ No | ✗ No | ✗ No |
| Runtime Dependencies | 0 Dependencies | 0 | 12+ | 1 |
| Bun Compatible | ✓ Native | ✓ Yes | ✓ Yes | ✓ Yes |
🔗 Project Resources
Access the source code, package registry, production documentation, and community channels:
window.rezilia — SmartRetry, SmartCache & BrowserLogger for plain HTML/JS.