@web-ts-toolkit/mongoose-rxdb
v0.36.0
Published
Mongoose-like Schema, Document, Query, Model, and Middleware proxy backed by RxDB (SQLite storage)
Downloads
786
Maintainers
Readme
@web-ts-toolkit/mongoose-rxdb
A Mongoose-like API (Schema, Document, Query, Model, Connection, pre/post middleware)
backed by RxDB so your data lives in local SQLite (or any RxDB storage).
It is a drop-in-shaped proxy: code that reads like Mongoose persists offline.
Installation
pnpm add @web-ts-toolkit/mongoose-rxdb
pnpm add rxdb rxjs
# Optional. For production-grade local SQLite storage:
pnpm add rxdb-premiumNo
sqlite3install is required on Node 22+: the built-innode:sqlitemodule is auto-detected and used by the free trial SQLite storage (subject to its limits). For older Node / non-Node runtimes, install npmsqlite3and it will be picked up.
Highlights
Schemawith type casting, defaults,required,enum,min,max,match, customvalidate.Documentwith dirty-path tracking (isModified,modifiedPaths), virtuals, instance methods,save()/remove().kareem-stylepre/postmiddleware engine forsave,validate,remove,updateOne,find, etc.- Thenable chainable
Querybuilder (.where().gt().limit().sort()) that compiles to RxDB Mango queries. Modelwithfind,findOne,findById,create,insertMany,updateOne/updateMany,deleteOne/deleteMany,findOneAndUpdate,findOneAndDelete,countDocuments, plusstatics.Connectionover an RxDB database. Storage is pluggable;@web-ts-toolkit/mongoose-rxdb/storageshipscreateMemoryDatabaseandcreateSqliteDatabase.
Quick Start
import { Schema, Connection } from '@web-ts-toolkit/mongoose-rxdb';
import { createSqliteDatabase } from '@web-ts-toolkit/mongoose-rxdb/storage';
const conn = new Connection();
await conn.connect(() => createSqliteDatabase({ filePath: './app.db' }));
const userSchema = new Schema(
{
name: { type: String, required: true },
age: { type: Number, default: 0, min: 0, max: 150 },
role: { type: String, enum: ['admin', 'user'], default: 'user' },
tags: [String],
},
{ timestamps: true },
);
userSchema.pre('save', function (next) {
console.log('about to save', this.name);
next();
});
userSchema.virtual('isAdmin').get(function () {
return this.role === 'admin';
});
const User = conn.model('User', userSchema);
const ada = await User.create({ name: 'Ada', age: 36, role: 'admin' });
console.log(ada.isAdmin); // true
const admins = await User.find().where('role').equals('admin').sort({ age: 1 }).exec();
await User.updateOne({ name: 'Ada' }, { $inc: { age: 1 } });
await User.deleteOne({ name: 'Ada' });
await conn.disconnect();Storage
The package is storage-agnostic. @web-ts-toolkit/mongoose-rxdb/storage exports:
createMemoryDatabase(opts?)— in-process memory storage (great for tests).createSqliteDatabase(opts?)— local SQLite. Resolution order is automatic:rxdb-premium'sgetRxStorageSqlite(production-grade; needs a license token at install).- RxDB's free trial
getRxStorageSQLiteTrialdriven by Node 22+'s built-innode:sqlite— writes a real file atopts.filePath, prints a warning each load, capped at ~500 docs/collection, no indexes. - Same trial but with npm
sqlite3(older Node / non-Node runtimes), if installed. - In-memory
getRxStorageMemoryas a last resort (logged to stderr) so consumer code never crashes when no SQLite backend is available.
On success a one-line
[mongoose-rxdb] createSqliteDatabase: using <backend> SQLite at <path>warning is printed (with the trial caveat for level 2 and 3). For real production SQLite, installrxdb-premium.
Pass any RxDB database factory to Connection#connect(factory).
Security: sanitizeFilter
Filters built from user input can leak Mango operators ($where, $func, ...). Use
sanitizeFilter to wrap nested non-whitelisted operator objects in { $eq: <value> }:
import { sanitizeFilter } from '@web-ts-toolkit/mongoose-rxdb';
const safe = sanitizeFilter(req.body.filter);
await User.find(safe);Only $and / $or / $nor (recursed) and the Mango per-field operators
($eq, $gt, $gte, $lt, $lte, $ne, $in, $nin, $exists, $regex, $options) pass
through; every other $-prefixed key is treated as an injection attempt and wrapped.
_id
Each document auto-generates a _id (UUID when globalThis.crypto.randomUUID is available,
otherwise a short random+timestamp string). You may pass an explicit _id in the constructor
data or Model.create(data). After construction _id is read-only: RxDB primary keys cannot
be changed after insert, so the field has no setter.
Status
Core MVP surface. Out of scope for now: populate, aggregate, indexes sync, sessions, discriminators, bulkWrite, cursors. These can be layered on as the design doc's pillars are extended.
Documentation
Full package documentation lives in website/docs/packages/mongoose-rxdb.md.
