This guide covers the additional storage adapters available for NebulaDB.
The SQLite Adapter persists data to a SQLite database file, providing a robust storage solution for Node.js applications.
npm install @nebula/adapter-sqlite
import { createDb } from '@nebula/core';
import { SQLiteAdapter } from '@nebula/adapter-sqlite';
import path from 'path';
// Create a database with SQLite adapter
const db = createDb({
adapter: new SQLiteAdapter(path.join(__dirname, 'data.sqlite'))
});
// Use the database normally
const users = db.collection('users');
await users.insert({ name: 'Alice', age: 30 });
The SQLite adapter accepts the following options:
// With options
const adapter = new SQLiteAdapter(
'data.sqlite', // Database file path
{
readonly: false, // Open database in read-only mode
fileMustExist: false, // Throw error if database doesn't exist
timeout: 5000, // Timeout for acquiring a database lock (ms)
verbose: console.log // Function for SQLite's verbose mode
}
);
The Redis Adapter persists data to a Redis server, providing a fast and scalable storage solution.
npm install @nebula/adapter-redis
import { createDb } from '@nebula/core';
import { RedisAdapter } from '@nebula/adapter-redis';
// Create a database with Redis adapter
const db = createDb({
adapter: new RedisAdapter(
{
host: 'localhost',
port: 6379,
password: 'your-password'
},
'nebula:' // Key prefix
)
});
// Use the database normally
const users = db.collection('users');
await users.insert({ name: 'Alice', age: 30 });
// Don't forget to close the connection when done
await db.adapter.close();
The Redis adapter accepts all options supported by ioredis:
// With more options
const adapter = new RedisAdapter({
host: 'redis-server',
port: 6379,
password: 'your-password',
db: 0, // Redis database index
keyPrefix: 'app:', // Key prefix for all Redis keys
retryStrategy: (times) => Math.min(times * 50, 2000), // Retry strategy
connectTimeout: 10000, // Connection timeout
maxRetriesPerRequest: 3 // Max retries per request
});
Feature | Memory | LocalStorage | IndexedDB | FileSystem | SQLite | Redis |
---|---|---|---|---|---|---|
Persistence | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
Browser Support | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Node.js Support | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ |
Edge Support | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Transaction Support | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ |
Scalability | Low | Low | Medium | Medium | Medium | High |
Speed | Very Fast | Fast | Medium | Medium | Fast | Very Fast |
Size Limit | Memory | ~5MB | Large | Disk | Disk | Memory |
External Dependencies | None | None | None | None | None | Redis Server |
You can create your own adapters by implementing the Adapter
interface:
import { Adapter, Document } from '@nebula/core';
class CustomAdapter implements Adapter {
async load(): Promise<Record<string, Document[]>> {
// Load data from your storage mechanism
// Return an object where keys are collection names and values are arrays of documents
}
async save(data: Record<string, Document[]>): Promise<void> {
// Save data to your storage mechanism
// 'data' is an object where keys are collection names and values are arrays of documents
}
}
import { Adapter, Document } from '@nebula/core';
import { MongoClient, Db } from 'mongodb';
export class MongoDBAdapter implements Adapter {
private client: MongoClient;
private db: Db | null = null;
private dbName: string;
constructor(uri: string, dbName: string) {
this.client = new MongoClient(uri);
this.dbName = dbName;
}
private async connect(): Promise<Db> {
if (!this.db) {
await this.client.connect();
this.db = this.client.db(this.dbName);
}
return this.db;
}
async load(): Promise<Record<string, Document[]>> {
const db = await this.connect();
const result: Record<string, Document[]> = {};
// Get all collections
const collections = await db.listCollections().toArray();
// For each collection, get all documents
for (const collection of collections) {
const collectionName = collection.name;
if (collectionName.startsWith('system.')) continue;
const docs = await db.collection(collectionName).find().toArray();
result[collectionName] = docs.map(doc => {
const { _id, ...rest } = doc;
return { id: _id.toString(), ...rest };
});
}
return result;
}
async save(data: Record<string, Document[]>): Promise<void> {
const db = await this.connect();
// For each collection
for (const [collectionName, documents] of Object.entries(data)) {
const collection = db.collection(collectionName);
// Clear existing data
await collection.deleteMany({});
// Insert new documents
if (documents.length > 0) {
await collection.insertMany(documents);
}
}
}
async close(): Promise<void> {
if (this.client) {
await this.client.close();
}
}
}