senderwolf-queue-local
v1.0.0
Published
Zero-config persistent SQLite bulk queue for senderwolf
Readme
@senderwolf/plugin-queue-local
The official zero-configuration local SQLite queue plugin for the Senderwolf SMTP Library.
By default, senderwolf manages queued semantics (such as delay, sendAt, and retries) via in-memory promises. This creates an extremely simple and portable API but leaves delayed emails vulnerable to being lost if the Node.js process crashes, stops, or restarts.
The @senderwolf/plugin-queue-local is an offline persistent queue that shifts Senderwolf from an in-memory queue to an asynchronous Producer-Consumer model.
Features
- Zero configuration: Driven entirely by
better-sqlite3. No Redis, no external processes, no external database dependencies. Connects via a local.senderwolf_jobs.dbfile. - Crash Recovery: Emails failing or currently heavily retrying survive gracefully through power outages or PM2 restarts.
- Background Dispatcher: Concurrently processes messages under configured concurrency limits without choking the main event thread.
- Auto-Retry & Delayed Scheduling: Respects Senderwolf's existing standard
delayandsendAtrules perfectly.
Installation
npm install senderwolf @senderwolf/plugin-queue-localNote: This plugin compiles
better-sqlite3which requires python and standard C++ compilation tools (node-gyp) available on your system.
Usage
Simply instantiate the LocalQueueStore once when your app starts, and pass it directly inside sendEmail:
import { sendEmail, senderwolfEvents } from 'senderwolf';
import { LocalQueueStore } from '@senderwolf/plugin-queue-local';
// Setup local offline plugin
const localQueue = new LocalQueueStore({
dbPath: './data/jobs.db', // Your save location
pollIntervalMs: 2000, // Check DB every 2s
batchSize: 10 // Concurrency limit
});
async function main() {
// 1. Sending an email
const result = await sendEmail({
smtp: { /* ... */ },
mail: {
to: '[email protected]',
subject: 'Invoice 19929',
text: 'Your email text here'
},
retry: { maxRetries: 3 },
queue: { store: localQueue } // Enables Local SQLite Producer flow!
});
console.log(result);
// { success: true, queueJobId: 1, queued: true, attempts: 0 }
// Notice how sendEmail returned instantly? The worker thread
// is now securely managing the SMTP lifecycle.
}
main();
// Hook into background execution anywhere in your app:
senderwolfEvents.on('sent', (info) => console.log('✅ Delivered!', info.queueJobId));
senderwolfEvents.on('retrying', (info) => console.warn('⚠️ Retrying...', info));
senderwolfEvents.on('failed', (info) => console.error('❌ Failed permanently!', info));Disconnecting Gracefully
The worker loop catches SIGINT and SIGTERM on its own. It finishes its current batch and closes the database automatically when your Node app gracefully shuts down.
You can also suspend the worker manually at any time if you don't want your app polling for jobs:
await localQueue.stopWorker();Options Configuration
| Property | Default | Description |
| ---- | ---- | ---- |
| dbPath | .senderwolf_jobs.db | The relative path to store SQLite database files. |
| pollIntervalMs | 5000 | How often the background loop scans the SQLite jobs table. |
| batchSize | 10 | The bulk threshold of messages it extracts and locks in memory per interval tick. |
| lockDurationMs | 300000 | Job memory lock timeout (in case process crashes while actively inside sendMail(), defaults to 5mins). |
| autoStart | true | When true, automatically initializes the background worker interval as soon as instantiated. |
License
MIT © Chandraprakash
