
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@coderule/qulite
Advanced tools
SQLite queue for outbox/synchronization: UPSERT, dedup, leases, transactions.
A minimalistic SQLite-based queue library for Node.js with UPSERT deduplication, atomic job claiming, and file system event coalescence.
npm install @coderule/qulite
import Database from 'better-sqlite3';
import { Qulite, Worker } from '@coderule/qulite';
// Create database and queue
const db = new Database('queue.db');
const queue = new Qulite(db);
// Enqueue a job with deduplication
const { id, upserted } = queue.upsertGeneric({
type: 'send-email',
dedupe_key: 'welcome-user-123', // Prevents duplicate emails
data: { to: 'user@example.com', template: 'welcome' }
});
// Create a worker to process jobs
const worker = new Worker({
queue,
type: 'send-email', // Only process send-email jobs
processor: async (job, ctx) => {
try {
// Process the job
await sendEmail(JSON.parse(job.data));
return { kind: 'ack' }; // Mark as complete
} catch (error) {
if (job.attempts < 3) {
return { kind: 'retry', delayMs: 5000 }; // Retry after 5s
}
return { kind: 'fail', error: error.message }; // Give up
}
}
});
// Start processing
await worker.start();
Qulite includes specialized support for file system event processing with intelligent coalescence:
import { enqueueFsEvent } from '@coderule/qulite';
// Enqueue file system events
enqueueFsEvent(queue, {
root_id: 'project-123',
rel_path: 'src/index.ts',
kind: 'modify',
size: 1024,
mtime_ns: Date.now() * 1000000,
sha256: 'abc123...'
});
// Multiple modify events for the same file are automatically coalesced
enqueueFsEvent(queue, {
root_id: 'project-123',
rel_path: 'src/index.ts',
kind: 'modify',
size: 1048,
mtime_ns: Date.now() * 1000000,
sha256: 'def456...'
});
// Only the latest event is kept
const worker = new Worker({
queue,
type: 'my-job-type', // Optional: only process specific job types
pollIntervalMs: 500, // How often to check for new jobs
logger: console, // Custom logger
processor: async (job, ctx) => {
// Access job data
console.log('Processing job:', job.id);
console.log('Attempt:', job.attempts);
// Use context methods
ctx.ack(); // Mark as complete
ctx.retry(1000); // Retry after 1 second
ctx.fail('error'); // Mark as failed
// Or return a result
return { kind: 'ack' };
}
});
const queue = new Qulite(db, {
defaultLeaseMs: 30000, // Default lease duration (30s)
defaultMaxAttempts: 25, // Maximum retry attempts
busyTimeoutMs: 5000, // SQLite busy timeout
logger: customLogger // Custom logger implementation
});
// Claim next available job
const job = queue.claimNext({
type: 'my-type', // Optional: filter by type
leaseOwner: 'worker-1', // Unique worker ID
leaseMs: 60000 // Lease duration
});
if (job) {
try {
// Process job...
queue.ack(job.id, 'worker-1');
} catch (error) {
queue.retry(job.id, 'worker-1', 5000); // Retry after 5s
}
}
// Requeue timed-out jobs
const requeuedCount = queue.requeueTimedOut();
// Get counts by status
const counts = queue.getCounts();
console.log('Pending:', counts.pending);
console.log('Processing:', counts.processing);
console.log('Done:', counts.done);
console.log('Failed:', counts.failed);
// Clean up old jobs
queue.cleanupDone(7 * 24 * 60 * 60 * 1000); // Remove jobs older than 7 days
queue.cleanupFailed(30 * 24 * 60 * 60 * 1000); // Remove failed jobs older than 30 days
// Run multiple workers for high throughput
const workers = [];
for (let i = 0; i < 4; i++) {
const worker = new Worker({
queue,
type: 'process-file',
processor: async (job) => {
// Process job...
return { kind: 'ack' };
}
});
workers.push(worker);
worker.start();
}
// Graceful shutdown
process.on('SIGTERM', async () => {
await Promise.all(workers.map(w => w.stop()));
db.close();
});
Qulite is designed for high throughput with SQLite:
Benchmark results (on a typical development machine):
Run benchmarks yourself:
npm run bench
constructor(db: Database, options?: QuliteOptions)upsertGeneric(params): { id: number, upserted: boolean }upsertFsEvent(params): { id: number, coalesced: boolean }claimNext(options?: ClaimOptions): PersistedJob | nullack(id: number, leaseOwner: string): booleanfail(id: number, leaseOwner: string, error?: string): booleanretry(id: number, leaseOwner: string, delayMs: number): booleanrequeueTimedOut(): numbergetCounts(): { pending, processing, done, failed }cleanupDone(olderThanMs: number): numbercleanupFailed(olderThanMs: number): numberconstructor(options: WorkerOptions)start(): Promise<void>stop(): Promise<void>interface PersistedJob {
id: number;
type: string;
status: JobStatus;
priority: number;
run_after: number;
created_at: number;
updated_at: number;
attempts: number;
max_attempts: number;
lease_owner?: string;
lease_expires_at?: number;
last_error?: string;
done_at?: number;
failed_at?: number;
dedupe_key?: string;
data?: string;
// File system specific fields
root_id?: string;
rel_path?: string;
kind?: FsEventKind;
to_path?: string;
size?: number;
mtime_ns?: number;
sha256?: string;
}
type ProcessResult =
| { kind: 'ack' }
| { kind: 'retry'; delayMs?: number }
| { kind: 'fail'; error?: string };
MIT
Contributions are welcome! Please feel free to submit a Pull Request.
For issues and feature requests, please use the GitHub issue tracker.
FAQs
SQLite queue for outbox/synchronization: UPSERT, dedup, leases, transactions.
We found that @coderule/qulite demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.