Writing Plugins

This guide covers creating custom plugins to extend NebulaDB — cache, logger, migration, and more patterns.

Cache Plugin

The Cache Plugin improves query performance by caching query results.

Installation

npm install @nebula/plugin-cache

Usage

import { createDb } from '@nebula/core';
import { MemoryAdapter } from '@nebula/adapter-memory';
import { createCachePlugin } from '@nebula/plugin-cache';

const cachePlugin = createCachePlugin({
  maxCacheSize: 100,
  ttl: 60000,
  excludeCollections: ['logs'],
  cacheEmptyResults: true
});

const db = createDb({
  adapter: new MemoryAdapter(),
  plugins: [cachePlugin]
});

const users = db.collection('users');
const result1 = await users.find({ age: { $gt: 30 } }); // Executed
const result2 = await users.find({ age: { $gt: 30 } }); // From cache

How It Works

  1. When a query is executed, the plugin checks if the same query has been cached
  2. Cache hit: cached results returned without executing the query
  3. Cache miss: query is executed and results are cached
  4. When data changes (insert/update/delete), cache for that collection is invalidated
  5. Cache entries expire after the configured TTL

Logger Plugin

Installation

npm install @nebula/plugin-logger

Usage

import { createLoggerPlugin, LogLevel } from '@nebula/plugin-logger';

const loggerPlugin = createLoggerPlugin({
  level: LogLevel.DEBUG,
  logQueryParams: true,
  logDocuments: false,
  logPerformance: true
});

const db = createDb({
  adapter: new MemoryAdapter(),
  plugins: [loggerPlugin]
});
// All operations will be logged automatically

Custom Logger

import { createLoggerPlugin, Logger } from '@nebula/plugin-logger';

class MyCustomLogger implements Logger {
  debug(message: string, ...args: any[]): void { /* custom */ }
  info(message: string, ...args: any[]): void { /* custom */ }
  warn(message: string, ...args: any[]): void { /* custom */ }
  error(message: string, ...args: any[]): void { /* custom */ }
}

const loggerPlugin = createLoggerPlugin({ logger: new MyCustomLogger() });

Migration Plugin

Installation

npm install @nebula/plugin-migration

Usage

import { createMigrationPlugin } from '@nebula/plugin-migration';

const migrations = [
  {
    version: 1,
    name: 'Add email to users',
    async up(db) {
      const users = db.collection('users');
      const allUsers = await users.find();
      for (const user of allUsers) {
        if (!user.email) {
          await users.update(
            { id: user.id },
            { $set: { email: `${user.name.toLowerCase()}@example.com` } }
          );
        }
      }
    },
    async down(db) {
      const users = db.collection('users');
      await users.update({}, { $unset: { email: true } });
    }
  },
  {
    version: 2,
    name: 'Add createdAt to posts',
    async up(db) {
      const posts = db.collection('posts');
      const allPosts = await posts.find();
      for (const post of allPosts) {
        if (!post.createdAt) {
          await posts.update(
            { id: post.id },
            { $set: { createdAt: new Date().toISOString() } }
          );
        }
      }
    }
  }
];

const migrationPlugin = createMigrationPlugin({
  migrations,
  migrationCollection: '_migrations',
  autoApply: true,
  throwOnError: true
});

const db = createDb({
  adapter: new MemoryAdapter(),
  plugins: [migrationPlugin]
});

// Manual control:
// await migrationPlugin.applyMigrations();
// await migrationPlugin.revertMigrations();
// await migrationPlugin.revertMigrations(1); // Revert to version 1

Migration Structure

Each migration should have:

Benefits