@luoarch/baileys-store-core
Version:
Universal authentication state management for Baileys v7.0+ with Redis, MongoDB, and hybrid storage support
444 lines (326 loc) โข 14.6 kB
Markdown
# @luoarch/baileys-store-core
> โ ๏ธ **Release Candidate**: Currently at v1.0.0-rc.3. Stable v1.0.0 coming soon!
> ๐ฌ **Feedback Welcome**: [GitHub Discussions](https://github.com/luoarch/baileys-store-core/discussions)
Production-grade authentication state management for Baileys v7.0+ with Redis, MongoDB, and hybrid storage
[](https://www.npmjs.com/package/@luoarch/baileys-store-core)
[](https://www.npmjs.com/package/@luoarch/baileys-store-core)
[](https://github.com/luoarch/baileys-store-core/actions)
[](https://codecov.io/gh/luoarch/baileys-store-core)
[](https://opensource.org/licenses/MIT)
[](https://www.typescriptlang.org/)
[](https://nodejs.org/)
[]()
## Features
- โ
**Baileys v7.0.0-rc.6 Compatible** - Fixes critical serialization bugs
- ๐ **Hybrid Storage** - Redis (hot cache) + MongoDB (cold storage)
- ๐ **Production-Ready** - Circuit breaker, outbox pattern, mutex concurrency control
- ๐ **Prometheus Metrics** - 13 thread-safe metrics for observability
- ๐ **Type-Safe** - Strong Buffer typing, prevents RC.6 serialization errors
- โก **High Performance** - < 5ms read latency (Redis), async MongoDB writes
- ๐ก๏ธ **Fault Tolerant** - Graceful degradation, partial failure compensation
- ๐ฆ **Tree-Shakeable** - Granular exports, only import what you need
- ๐งช **Well-Tested** - 52 tests (unit + integration + E2E)
- โ๏ธ **Config Presets** - Development, Production, and Testing configurations out of the box
- ๐ **Well-Documented** - ADRs, SLA, Research documentation
## Installation
### Release Candidate (Recommended)
```bash
# Install both packages (required)
npm install @whiskeysockets/baileys@latest @luoarch/baileys-store-core@1.0.0-rc.3
# Or with Yarn
yarn add @whiskeysockets/baileys@latest @luoarch/baileys-store-core@1.0.0-rc.3
```
### Stable Version (Coming Soon)
```bash
# After stable release
npm install @whiskeysockets/baileys@latest @luoarch/baileys-store-core
# Or with Yarn
yarn add @whiskeysockets/baileys@latest @luoarch/baileys-store-core
```
> **โ ๏ธ Important:** You must install both `@whiskeysockets/baileys` and `@luoarch/baileys-store-core` as this library is a peer dependency of Baileys.
### Hybrid Storage with Config Presets (Recommended)
```typescript
import { makeWASocket } from '@whiskeysockets/baileys';
import {
useHybridAuthState,
createHybridConfigFromPreset,
} from '@luoarch/baileys-store-core/hybrid';
// Use PRODUCTION preset with minimal configuration
const config = createHybridConfigFromPreset('PRODUCTION', {
redisUrl: process.env.REDIS_URL || 'redis://localhost:6379',
mongoUrl: process.env.MONGO_URL || 'mongodb://localhost:27017',
mongoDatabase: 'whatsapp',
mongoCollection: 'auth',
masterKey: process.env.BAILEYS_MASTER_KEY, // 64-char hex key
});
const { state, saveCreds, store } = await useHybridAuthState({
sessionId: 'my-session',
hybrid: config,
});
const socket = makeWASocket({ auth: state });
socket.ev.on('creds.update', saveCreds);
socket.ev.on('connection.update', (update) => {
console.log('Connection:', update.connection);
});
```
### Redis Only
```typescript
import { useRedisAuthState } from '@luoarch/baileys-store-core/redis';
const { state, saveCreds, store } = await useRedisAuthState({
sessionId: 'redis-session',
redis: {
redisUrl: 'redis://localhost:6379',
ttl: {
defaultTtl: 30 * 24 * 60 * 60,
credsTtl: 30 * 24 * 60 * 60,
keysTtl: 30 * 24 * 60 * 60,
lockTtl: 5,
},
masterKey: process.env.BAILEYS_MASTER_KEY,
// ... other configs
},
});
```
### MongoDB Only
```typescript
import { useMongoAuthState } from '@luoarch/baileys-store-core/mongodb';
const { state, saveCreds, store } = await useMongoAuthState({
sessionId: 'mongo-session',
mongodb: {
mongoUrl: 'mongodb://localhost:27017',
database: 'whatsapp',
collection: 'auth',
ttl: {
defaultTtl: 30 * 24 * 60 * 60,
credsTtl: 30 * 24 * 60 * 60,
keysTtl: 30 * 24 * 60 * 60,
lockTtl: 5,
},
masterKey: process.env.BAILEYS_MASTER_KEY,
// ... other configs
},
});
```
## Advanced Features
### Circuit Breaker
Automatic MongoDB degradation when error rate exceeds threshold:
```typescript
// Check circuit breaker status
const isOpen = store.isMongoCircuitBreakerOpen();
const stats = store.getCircuitBreakerStats();
console.log('Circuit Breaker:', { isOpen, fires: stats.fires });
```
### Prometheus Metrics
```typescript
// Expose metrics for Prometheus scraping
import express from 'express';
const app = express();
app.get('/metrics', async (req, res) => {
const metricsText = await store.getMetricsText();
res.set('Content-Type', 'text/plain');
res.send(metricsText);
});
app.listen(9090);
```
**Available Metrics:**
- `baileys_store_redis_hits_total` - Redis cache hits
- `baileys_store_redis_misses_total` - Redis cache misses
- `baileys_store_mongo_fallbacks_total` - MongoDB fallback reads
- `baileys_store_circuit_breaker_open_total` - Circuit breaker activations
- `baileys_store_outbox_reconciler_latency_seconds` - Outbox reconciliation latency (histogram)
- And 8 more...
### Transactional Outbox
Ensure dual-write consistency with automatic reconciliation:
```typescript
const { store } = await useHybridAuthState({
sessionId: 'outbox-example',
hybrid: {
// ... config
enableWriteBehind: true,
queue: myQueueAdapter, // Inject your BullMQ/Kafka adapter
},
});
// Get outbox stats
const outboxStats = store.getOutboxStats();
console.log('Pending writes:', outboxStats.totalProcessed);
// Manually trigger reconciliation
await store.reconcileOutbox();
```
## Performance Benchmarks
| Operation | Latency (p50) | Latency (p99) |
| ----------------------- | ------------- | ------------- |
| Read (cached) | 3.2ms | 8.1ms |
| Read (MongoDB fallback) | 18.5ms | 45.2ms |
| Write (Redis sync) | 5.1ms | 12.3ms |
| Write (MongoDB async) | N/A (queued) | N/A |
**Test conditions:** 100 sessions, 1000 ops each, 10 concurrent
## Configuration Options
### TtlConfig
| Field | Type | Default | Description |
| ------------ | ------ | ------- | -------------------------------- |
| `defaultTtl` | number | 2592000 | Default TTL in seconds (30 days) |
| `credsTtl` | number | 2592000 | Credentials TTL |
| `keysTtl` | number | 2592000 | Keys TTL |
| `lockTtl` | number | 5 | Distributed lock TTL |
### SecurityConfig
| Field | Type | Description |
| ---------------------- | ----------------------------------------- | -------------------------------------------- |
| `enableEncryption` | boolean | Enable AES-256-GCM or Secretbox encryption |
| `enableCompression` | boolean | Enable Snappy or Gzip compression |
| `encryptionAlgorithm` | `'aes-256-gcm' \| 'secretbox'` | Encryption algorithm |
| `compressionAlgorithm` | `'snappy' \| 'gzip'` | Compression algorithm |
| `keyRotationDays` | number | Key rotation interval |
| `enableDebugLogging` | boolean | Enable debug logging (default: false) |
| `environment` | `'development' \| 'production' \| 'test'` | Environment for security controls |
| `logger` | `Logger` | Custom logger instance (default: NullLogger) |
### ResilienceConfig
| Field | Type | Description |
| ------------------ | ------ | ---------------------------------------- |
| `operationTimeout` | number | Timeout for storage operations (ms) |
| `maxRetries` | number | Max retry attempts for failed operations |
| `retryBaseDelay` | number | Base delay for exponential backoff (ms) |
| `retryMultiplier` | number | Multiplier for exponential backoff |
## Outbox Format
**Redis Hash:** `outbox:{sessionId}`
**Fields:** `{version}` โ OutboxEntry (JSON)
```typescript
interface OutboxEntry {
id: string; // "${sessionId}:${version}"
sessionId: string;
patch: AuthPatch;
version: number;
fencingToken?: number;
status: 'pending' | 'processing' | 'completed' | 'failed';
createdAt: number; // Unix timestamp
updatedAt: number;
attempts: number;
lastError?: string;
completedAt?: number;
}
```
**TTL:** 7 days (auto-cleanup)
## Documentation
- **[ARCHITECTURE.md](./ARCHITECTURE.md)** - Architecture Decision Records (ADRs) documenting key design decisions
- **[docs/SLA.md](./docs/SLA.md)** - Service Level Objectives (SLOs) and metrics
- **[docs/RESEARCH.md](./docs/RESEARCH.md)** - Research contributions and academic context
- **[docs/PAPER.md](./docs/PAPER.md)** - Full academic paper
- **[docs/LOAD_TESTING.md](./docs/LOAD_TESTING.md)** - Load testing guide with k6
- **[ROADMAP.md](./ROADMAP.md)** - Development roadmap and milestones
## Config Presets
Pre-configured presets for different environments:
### DEVELOPMENT
- Short TTLs (5 minutes) for rapid iteration
- Long timeouts (10s) for debugging
- Detailed logging enabled
- Encryption disabled
### PRODUCTION
- Optimized TTLs (1 hour default, 7 days for creds/keys)
- Aggressive timeouts (5s)
- Encryption mandatory (AES-256-GCM)
- Minimal logging
### TESTING
- Very short TTLs (30s) for quick tests
- Fast timeouts (2s)
- Encryption disabled
- Metrics disabled
```typescript
import { createHybridConfigFromPreset } from '@luoarch/baileys-store-core';
// Use PRODUCTION preset
const config = createHybridConfigFromPreset('PRODUCTION', {
mongoUrl: process.env.MONGO_URL!,
mongoDatabase: 'whatsapp',
mongoCollection: 'sessions',
masterKey: process.env.BAILEYS_MASTER_KEY!,
});
```
## Troubleshooting
### RC.6 Serialization Errors
If you see `ERR_INVALID_ARG_TYPE: The "value" argument must be of type Buffer`:
**Cause:** Baileys RC.6 serializes Buffers as `{type: 'Buffer', data: [...]}` instead of actual Buffers.
**Fix:** This library automatically revives Buffer-like objects via `deepBufferRevive()`. Ensure you're using v1.0.0+.
### MongoDB E11000 Duplicate Key
**Cause:** Concurrent writes to same session.
**Fix:** Built-in retry logic with exponential backoff handles this automatically. No action needed.
### Circuit Breaker Open
**Cause:** MongoDB error rate exceeded 50% over 10s window.
**Fix:** Library degrades gracefully, serving from Redis cache. MongoDB reconnects automatically after 30s cooldown.
## Monorepo Configuration
Add to your workspace `package.json`:
```json
{
"workspaces": ["packages/*"],
"resolutions": {
"@luoarch/baileys-store-core": "1.0.0-rc.1"
}
}
```
## API Reference
### Hooks
#### `useRedisAuthState(options): Promise<{ state, saveCreds, store }>`
#### `useMongoAuthState(options): Promise<{ state, saveCreds, store }>`
#### `useHybridAuthState(options): Promise<{ state, saveCreds, store }>`
**Returns:**
- `state: AuthenticationState` - Baileys-compatible auth state
- `saveCreds: () => Promise<void>` - Save credentials function
- `store: RedisAuthStore | MongoAuthStore | HybridAuthStore` - Direct store access
### HybridAuthStore Methods
- `get(sessionId): Promise<Versioned<AuthSnapshot> | null>`
- `set(sessionId, patch, expectedVersion?, fencingToken?): Promise<VersionedResult>`
- `delete(sessionId): Promise<void>`
- `touch(sessionId, ttlSeconds?): Promise<void>`
- `isHealthy(): Promise<boolean>`
- `isMongoCircuitBreakerOpen(): boolean`
- `getCircuitBreakerStats(): CircuitBreakerStats`
- `getMetricsText(): Promise<string>`
- `getMetricsRegistry(): Registry`
- `getOutboxStats(): OutboxReconcilerStats | null`
- `reconcileOutbox(): Promise<void>`
## Node.js Support Policy
This package supports **Active LTS versions** of Node.js:
| Version | Status | Support Until |
| ------------ | ------------- | ------------- |
| Node.js 20.x | โ
Active LTS | 2026-04-30 |
| Node.js 22.x | โ
Current | 2027-04-30 |
Older versions may work but are not officially tested or supported.
### Why Node >= 20?
- Native ESM support improvements
- Enhanced TypeScript compatibility (isolatedModules, moduleResolution: "bundler")
- Security updates and performance gains
- Alignment with modern ecosystem standards
- MongoDB driver 6.20+ requires Node >= 16.20.1
### Testing Matrix
Our CI pipeline tests on:
- Node.js 22.x (primary)
- Node.js 23.x (preview)
## Code Coverage
Current coverage: **75%+** (Progressive target: **80%**)
We maintain high test coverage with:
- Unit tests for core logic
- Integration tests with real Redis + MongoDB
- E2E tests simulating Baileys workflows
See [CONTRIBUTING.md](./CONTRIBUTING.md) for testing guidelines.
## Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
1. Fork the repo
2. Create feature branch: `git checkout -b feature/my-feature`
3. Run tests: `yarn test && yarn test:integration && yarn test:e2e`
4. Lint: `yarn lint && yarn typecheck`
5. Commit: `git commit -m "feat: my feature"`
6. Push: `git push origin feature/my-feature`
7. Create Pull Request
## License
MIT ยฉ Lucas Moraes
## Citation
For academic use, see [CITATION.cff](./CITATION.cff) or cite as:
```bibtex
@software{baileys_store_2025,
author = {Moraes, Lucas},
title = {@luoarch/baileys-store-core},
year = {2025},
url = {https://github.com/luoarch/baileys-store-core},
version = {1.0.0-rc.3}
}
```
Full academic paper: [docs/PAPER.md](./docs/PAPER.md)
---
**Made with โค๏ธ for the Baileys community**