@waelio/realdb
v0.1.0
Published
A local-first, reactive database for JavaScript & TypeScript. Works in browsers, Node.js, and edge runtimes.
Maintainers
Readme
@waelio/realdb
A local-first, reactive database for JavaScript & TypeScript.
Works in browsers, Node.js, and edge runtimes — no native dependencies.
import { RealDB } from '@waelio/realdb'
interface Task { title: string; done: boolean }
const db = new RealDB({ name: 'myApp' })
await db.open()
const tasks = db.collection<Task>('tasks')
const task = await tasks.insert({ title: 'Build realdb', done: false })
await tasks.update(task.id, { done: true })
tasks.subscribe((event) => {
console.log(event.type, event.document)
})Features
- 🔷 Fully typed — generics flow end-to-end, from schema to query results
- ⚡ Reactive — subscribe to collection changes with
collection.subscribe() - 🔌 Pluggable adapters — swap storage without changing your app code
- 🧪 Testable —
MemoryAdapteris the default, perfect for unit tests - 🌐 Universal — runs anywhere that speaks ES2020+
Installation
npm install @waelio/realdbQuick Start
import { RealDB, LocalStorageAdapter } from '@waelio/realdb'
interface Note { text: string; pinned: boolean }
// Use LocalStorage in the browser
const db = new RealDB({
name: 'notes-app',
adapter: new LocalStorageAdapter('notes-app'),
})
await db.open()
const notes = db.collection<Note>('notes')
// Insert
const note = await notes.insert({ text: 'Hello realdb', pinned: false })
// Find with filters
const pinned = await notes.find({
filter: [{ field: 'pinned', op: 'eq', value: true }],
sort: [{ field: 'createdAt', direction: 'desc' }],
limit: 10,
})
// Update
await notes.update(note.id, { pinned: true })
// Delete
await notes.delete(note.id)
// Subscribe to changes
const sub = notes.subscribe((event) => {
console.log(`[${event.type}]`, event.document)
})
sub.unsubscribe() // stop listeningStorage Adapters
| Adapter | Import | Persists? | Best For |
|---------|--------|-----------|----------|
| MemoryAdapter | 'realdb' | ❌ No | Tests, SSR, edge runtimes |
| LocalStorageAdapter | 'realdb' | ✅ Yes | Browser apps |
Bring your own by implementing the StorageAdapter interface:
import type { StorageAdapter } from '@waelio/realdb'
class MyAdapter implements StorageAdapter {
name = 'my-adapter'
async init(collection: string) { /* ... */ }
async getAll(collection: string) { /* ... */ }
async getById(collection: string, id: string) { /* ... */ }
async put(collection: string, doc: unknown) { /* ... */ }
async delete(collection: string, id: string) { /* ... */ }
async clear(collection: string) { /* ... */ }
async destroy() { /* ... */ }
}Query API
Filters
await tasks.find({
filter: [
{ field: 'done', op: 'eq', value: false },
{ field: 'priority', op: 'gte', value: 2 },
{ field: 'title', op: 'contains', value: 'realdb' },
],
})| Operator | Description |
|----------|-------------|
| eq / neq | Equal / not equal |
| gt / gte / lt / lte | Numeric comparisons |
| in / nin | Value in / not in array |
| contains | String contains |
| startsWith / endsWith | String prefix / suffix |
Sort, Limit, Offset
await tasks.find({
sort: [{ field: 'priority', direction: 'desc' }],
limit: 20,
offset: 40,
})Reactive Subscriptions
const sub = tasks.subscribe((event) => {
// event.type → 'insert' | 'update' | 'delete'
// event.document → the new/current document
// event.previous → the old document (update/delete only)
})
sub.unsubscribe()API Reference
RealDB
| Method / Property | Description |
|---|---|
| new RealDB(config) | Create a database instance |
| db.open() | Open the database (call once) |
| db.close() | Shut down and free resources |
| db.collection<T>(name, schema?) | Get or create a collection |
| db.collectionNames | Array of registered collection names |
| db.isOpen | Whether the DB is open |
| db.name | Database name |
| db.adapterName | Active adapter's name |
Collection<T>
| Method | Description |
|---|---|
| insert(data) | Create a new document |
| insertMany(items) | Create multiple documents |
| findById(id) | Find one by ID |
| find(options?) | Find with filter/sort/limit/offset |
| findAll() | All documents, newest first |
| count(options?) | Count matching documents |
| update(id, patch) | Partial update |
| replace(id, data) | Full replace |
| delete(id) | Delete one |
| deleteMany(options?) | Delete matching |
| clear() | Wipe collection |
| subscribe(callback) | Watch for changes |
License
MIT © Peace Marshal
