@mikestools/usedatabase
v0.0.2
Published
Vue 3 composable for normalized relational data management with automatic denormalization, transactions, undo/redo, and persistence
Downloads
386
Maintainers
Readme
@mikestools/usedatabase
Vue 3 composable for normalized relational data management with automatic denormalization
Features
- 🔗 Normalized Storage - Automatically normalizes nested data into flat tables
- 🔄 Auto Denormalization - Query results automatically hydrated with relations
- 📝 Staging & Transactions - Stage changes before committing with rollback support
- ↩️ Undo/Redo History - Built-in history management with configurable limits
- 🔍 Query Builder - Fluent API with filtering, sorting, pagination, aggregations
- 💾 Persistence Ready - Built-in localStorage adapter, custom adapters supported
- 🔔 Subscriptions - Granular event callbacks for data changes
- 🎯 Type-Safe - Full TypeScript support with generic schema types
- 📦 Zero Dependencies - Only requires Vue 3
Installation
npm install @mikestools/usedatabase vueQuick Start
import { useDatabase, type Entity } from '@mikestools/usedatabase'
// Define your entity types (all must include id: string)
interface User extends Entity {
id: string
name: string
posts?: Post[]
}
interface Post extends Entity {
id: string
title: string
}
// Create database
const db = useDatabase<{ users: User; posts: Post }>()
// Stage nested data - relations auto-detected
db.stage({
users: [{
id: 'u1',
name: 'Alice',
posts: [{ id: 'p1', title: 'Hello World' }]
}]
})
db.commit()
// Query with auto-hydration
const user = db.query('users').find('u1')
// user.posts = [{ id: 'p1', title: 'Hello World' }]API Reference
useDatabase Options
| Option | Type | Default | Description |
|----------------|-----------------------------------|---------------------|-----------------------------------|
| adapter | PersistenceAdapter | undefined | Persistence adapter for save/load |
| idGenerator | () => string | crypto.randomUUID | Custom ID generator function |
| historyLimit | number | 50 | Maximum undo/redo history entries |
| cascades | Record<string, CascadeConfig[]> | {} | Cascade delete configuration |
Core Methods
| Method | Returns | Description |
|----------------|-------------------------|-------------------------------------|
| stage(data) | void | Stage changes for commit |
| commit() | void | Commit staged changes to main store |
| rollback() | void | Discard staged changes |
| insert(data) | number | Insert records (returns count) |
| update(data) | number | Update records (returns count) |
| upsert(data) | { inserted, updated } | Insert or update records |
| remove(data) | number | Remove records (returns count) |
| query(table) | QueryBuilder | Get fluent query builder |
| undo() | boolean | Undo last commit |
| redo() | boolean | Redo undone change |
| save() | Promise<void> | Save to persistence adapter |
| load() | Promise<void> | Load from persistence adapter |
Reactive Queries
| Method | Returns | Description |
|-----------------------------------|-------------------------------|-----------------------------|
| reactiveAll(table) | ComputedRef<T[]> | All entities (auto-updates) |
| reactiveWhere(table, predicate) | ComputedRef<T[]> | Filtered entities |
| reactiveFind(table, id) | ComputedRef<T \| null> | Single entity by ID |
| reactiveCount(table) | ComputedRef<number> | Entity count |
| reactiveFirst(table) | ComputedRef<T \| undefined> | First entity |
State Objects
| Property | Type | Description |
|--------------------------------|-----------------------|--------------------------------|
| transactionState.isActive | Ref<boolean> | Has staged changes |
| transactionState.changeCount | Ref<number> | Number of staged changes |
| dirtyState.isDirty | Ref<boolean> | Has uncommitted changes |
| dirtyState.stagedChanges | Ref<StagedChange[]> | List of staged changes |
| historyState.canUndo | Ref<boolean> | Can undo |
| historyState.canRedo | Ref<boolean> | Can redo |
| version | Ref<number> | Version counter for reactivity |
Examples
See the showcase for interactive examples including:
- Task Manager - Comprehensive CRUD, filtering, sorting, persistence
- Basic CRUD - Simple create, read, update, delete operations
- Nested Relations - Automatic relationship handling
- Query Builder - Filtering, sorting, pagination, aggregations
- Staging & Transactions - Form editing with commit/rollback
- Undo/Redo - History management
- Reactive Queries - Auto-updating computed queries
- Persistence - LocalStorage integration
- Subscriptions - Event callbacks
Design Philosophy
| Principle | Description |
|-----------------------|----------------------------------------|
| Zero Dependencies | Only Vue 3 and browser APIs |
| String IDs Only | Consistent with DOM, JSON, URLs |
| Strict TypeScript | No any, no assertions, readonly refs |
| Staging First | All changes staged before commit |
| Auto-Hydration | Query results include related entities |
Requirements
- Vue 3.3.0 or higher
- Modern browsers with
crypto.randomUUID()support
Development
npm install # Install dependencies
npm run dev # Start dev server
npm test # Run tests
npm run check # Type check
npm run build # Build libraryLicense
MIT © Mike Garcia
