ā” DeepBase IndexedDB - browser storage driver
npm install deepbase-indexeddbBrowser-based persistence using IndexedDB
The IndexedDB driver allows you to use DeepBase in browser environments with full offline capabilities. Perfect for Progressive Web Apps (PWAs), single-page applications, and any web app that needs reliable client-side storage.
- š Browser-native: Uses IndexedDB API built into modern browsers
- š“ Offline-first: Works without network connectivity
- š¾ Large storage: Can store much more data than localStorage (typically hundreds of MBs)
- š Concurrency-safe: Built-in operation queuing prevents race conditions
- š Fast: Asynchronous operations with IndexedDB transactions
- š PWA-ready: Perfect for Progressive Web Apps
- š”ļø Type-safe: Full support for nested objects and arrays
- šÆ Same API: Use the exact same DeepBase API in browser and Node.js
``bash`
npm install deepbase deepbase-indexeddb
Or via CDN:
`html`
When using the published NPM packages:
`javascript
import DeepBase from 'deepbase';
import IndexedDBDriver from 'deepbase-indexeddb';
// Create database instance
const db = new DeepBase(new IndexedDBDriver({
name: 'myapp', // Database name
version: 1, // Database version
storeName: 'store' // Object store name (optional)
}));
// Connect to database
await db.connect();
// Store data
await db.set('users', 'alice', {
name: 'Alice',
email: 'alice@example.com',
settings: {
theme: 'dark',
notifications: true
}
});
// Retrieve data
const alice = await db.get('users', 'alice');
console.log(alice.settings.theme); // 'dark'
// Update nested values
await db.set('users', 'alice', 'settings', 'theme', 'light');
// Delete data
await db.del('users', 'alice');
// Disconnect when done
await db.disconnect();
`
For browser applications using a bundler, you can import normally:
`javascript
import DeepBase from 'deepbase';
import IndexedDBDriver from 'deepbase-indexeddb';
const db = new DeepBase(new IndexedDBDriver({
name: 'myapp',
version: 1
}));
await db.connect();
// ... your code
`
Good news! DeepBase now works directly in the browser thanks to dynamic imports:
`html`
Or via CDN (once published):
`html`
Note: The full DeepBase class now works in browsers! You get all features including multi-driver support, timeouts, and advanced operations.
`javascript
import DeepBase from 'deepbase';
import IndexedDBDriver from 'deepbase-indexeddb';
class TodoApp {
constructor() {
this.db = new DeepBase(new IndexedDBDriver({
name: 'todoapp',
version: 1
}));
}
async init() {
await this.db.connect();
// Initialize default data if needed
const todos = await this.db.get('todos');
if (!todos) {
await this.db.set('todos', {});
}
}
async addTodo(text) {
const todoPath = await this.db.add('todos', {
text,
completed: false,
createdAt: Date.now()
});
return todoPath[1]; // Return the auto-generated ID
}
async toggleTodo(id) {
await this.db.upd('todos', id, 'completed', val => !val);
}
async getTodos() {
return await this.db.get('todos');
}
async deleteTodo(id) {
await this.db.del('todos', id);
}
}
// Usage
const app = new TodoApp();
await app.init();
const id = await app.addTodo('Learn DeepBase');
console.log('Created todo:', id);
await app.toggleTodo(id);
const todos = await app.getTodos();
console.log('All todos:', todos);
`
`javascript`
new IndexedDBDriver({
name: 'mydb', // Database name (default: 'deepbase')
version: 1, // Database version (default: 1)
storeName: 'store', // Object store name (default: 'store')
// Inherited from DeepBaseDriver:
nidAlphabet: 'ABC...', // Custom alphabet for auto-generated IDs
nidLength: 10 // Length of auto-generated IDs
})
The IndexedDB driver supports all standard DeepBase operations:
`javascript
// Get value at path
const value = await db.get('path', 'to', 'value');
// Set value at path
await db.set('path', 'to', 'value', 'hello');
// Delete value at path
await db.del('path', 'to', 'value');
`
`javascript
// Add item with auto-generated ID
const path = await db.add('items', { name: 'Item 1' });
// Returns: ['items', 'aB3xK9mL2n']
// Pop last item from array
const item = await db.pop('myArray');
// Shift first item from array
const first = await db.shift('myArray');
`
`javascript
// Increment number
await db.inc('counter', 1);
// Decrement number
await db.dec('counter', 1);
`
`javascript`
// Update value using a function
await db.upd('user', 'name', name => name.toUpperCase());
`javascript
// Get keys
const keys = await db.keys('users');
// Get values
const values = await db.values('users');
// Get entries
const entries = await db.entries('users');
`
The IndexedDB driver includes built-in operation queuing to prevent race conditions:
`javascript
// These operations are safely serialized
await Promise.all([
db.inc('counter', 1),
db.inc('counter', 1),
db.inc('counter', 1)
]);
const counter = await db.get('counter');
console.log(counter); // Always 3, never less
`
The IndexedDB driver works in all modern browsers that support IndexedDB:
- ā
Chrome 24+
- ā
Firefox 16+
- ā
Safari 10+
- ā
Edge (all versions)
- ā
Opera 15+
- ā
Mobile browsers (iOS Safari, Chrome Mobile, etc.)
`javascript
// Store user preferences
await db.set('preferences', {
theme: 'dark',
language: 'en',
notifications: true
});
// Cache API responses
await db.set('cache', 'users', apiResponse);
`
`javascript
// Queue operations while offline
if (!navigator.onLine) {
await db.add('syncQueue', {
action: 'updateUser',
data: userData,
timestamp: Date.now()
});
}
// Sync when back online
window.addEventListener('online', async () => {
const queue = await db.get('syncQueue');
// Process queue...
await db.del('syncQueue');
});
`
`javascript
// Store application state
await db.set('app', 'state', {
currentUser: userId,
openModals: ['settings'],
cart: [item1, item2]
});
// Restore state on page load
const state = await db.get('app', 'state');
`
`javascript
// Auto-save form data
document.querySelector('#myForm').addEventListener('input', async (e) => {
await db.set('forms', 'contact', e.target.form.id, e.target.value);
});
// Restore form data
const savedData = await db.get('forms', 'contact');
`
Combine IndexedDB with other drivers for advanced scenarios:
`javascript
import DeepBase from 'deepbase';
import IndexedDBDriver from 'deepbase-indexeddb';
import JsonDriver from 'deepbase-json';
// Browser: Use IndexedDB
// Node.js: Use JSON files
const db = new DeepBase(
typeof window !== 'undefined'
? new IndexedDBDriver({ name: 'myapp' })
: new JsonDriver({ path: './data', name: 'myapp' })
);
await db.connect();
// Same code works in both environments!
`
`javascript
// Upgrade database version when schema changes
const db = new DeepBase(new IndexedDBDriver({
name: 'myapp',
version: 2 // Increment version number
}));
// IndexedDB will automatically handle the upgrade
await db.connect();
`
`javascript
// Create separate stores for different data types
const usersDB = new DeepBase(new IndexedDBDriver({
name: 'myapp',
storeName: 'users'
}));
const postsDB = new DeepBase(new IndexedDBDriver({
name: 'myapp',
storeName: 'posts'
}));
await usersDB.connect();
await postsDB.connect();
`
`javascript
const db = new DeepBase(new IndexedDBDriver({
name: 'myapp',
nidAlphabet: '0123456789', // Numbers only
nidLength: 6 // 6 digits
}));
const path = await db.add('items', { name: 'Item' });
// ID will be something like: ['items', '123456']
`
- Browser-only: This driver only works in browser environments with IndexedDB support
- Storage limits: Browser-dependent (typically 50-100MB, but can be more)
- Same-origin policy: Data is isolated per domain
- Not suitable for: Node.js, server-side rendering (SSR) initial render
For Node.js environments, use:
- deepbase-json for developmentdeepbase-sqlite
- for productiondeepbase-mongodb
- for scalabilitydeepbase-redis
- for caching
1. Open Chrome DevTools
2. Go to "Application" tab
3. Expand "IndexedDB" in the sidebar
4. Find your database name
5. Inspect stored data
Error: "IndexedDB is not available"
- This driver requires a browser environment
- Check that you're not running in Node.js
- Ensure browser supports IndexedDB
Data not persisting
- Make sure to call await db.connect() before operations
- Check browser storage settings/permissions
- Verify you're not in private/incognito mode (some browsers restrict storage)
`typescript
import DeepBase from 'deepbase';
import IndexedDBDriver from 'deepbase-indexeddb';
interface User {
name: string;
email: string;
settings: {
theme: 'light' | 'dark';
notifications: boolean;
};
}
const db = new DeepBase(new IndexedDBDriver({
name: 'myapp'
}));
await db.connect();
// TypeScript will infer types
await db.set('users', 'alice', {
name: 'Alice',
email: 'alice@example.com',
settings: {
theme: 'dark',
notifications: true
}
} as User);
const alice = await db.get('users', 'alice') as User;
``
Found a bug or want to contribute? Check out the main repository.
MIT License - Copyright (c) Martin Clasen
- Main Documentation
- GitHub Repository
- Report Issues
- Other Drivers
---
š Build amazing offline-first web apps with DeepBase + IndexedDB!