CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-node-json-db

Database using JSON file as storage for Node.JS

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

adapters.mddocs/

Adapters and Configuration

Flexible configuration system with built-in file storage adapter and support for custom storage backends through the adapter pattern.

Capabilities

Configuration Classes

Config Class

Standard configuration class that uses file-based JSON storage with built-in adapters.

/**
 * Standard configuration using file-based storage
 * @param filename - Database filename (automatically adds .json if no extension)
 * @param saveOnPush - Whether to save automatically after each push operation (default: true)
 * @param humanReadable - Format JSON with indentation for readability (default: false)
 * @param separator - DataPath separator character (default: "/")
 * @param syncOnSave - Use synchronous file operations for guaranteed persistence (default: false)
 */
class Config implements JsonDBConfig {
  constructor(
    filename: string,
    saveOnPush?: boolean,
    humanReadable?: boolean,
    separator?: string,
    syncOnSave?: boolean
  );
  
  readonly filename: string;
  readonly adapter: IAdapter<any>;
  readonly saveOnPush: boolean;
  readonly separator: string;
}

Usage Examples:

import { JsonDB, Config } from "node-json-db";

// Basic configuration
const db1 = new JsonDB(new Config("database.json"));

// With custom settings
const db2 = new JsonDB(new Config(
  "users",              // filename (will become users.json)
  true,                 // saveOnPush - auto-save on changes
  true,                 // humanReadable - formatted JSON
  "/",                  // separator for DataPaths
  false                 // syncOnSave - async file operations
));

// Production config with sync saves for data integrity
const db3 = new JsonDB(new Config(
  "/var/data/production.json",
  true,   // auto-save
  false,  // compact JSON
  "/",    // standard separator
  true    // sync saves for guaranteed persistence
));

ConfigWithAdapter Class

Configuration class for use with custom adapters, providing full control over storage backend.

/**
 * Configuration with custom adapter
 * @param adapter - Custom storage adapter implementing IAdapter interface
 * @param saveOnPush - Whether to save automatically after each push operation (default: true)
 * @param separator - DataPath separator character (default: "/")
 */
class ConfigWithAdapter implements JsonDBConfig {
  constructor(
    adapter: IAdapter<any>,
    saveOnPush?: boolean,
    separator?: string
  );
  
  readonly adapter: IAdapter<any>;
  readonly saveOnPush: boolean;
  readonly separator: string;
}

Usage Examples:

import { JsonDB, ConfigWithAdapter, JsonAdapter, FileAdapter } from "node-json-db";

// Custom adapter configuration
const fileAdapter = new FileAdapter("/custom/path/data.json", true);
const jsonAdapter = new JsonAdapter(fileAdapter, true); // human readable
const config = new ConfigWithAdapter(jsonAdapter, false, "|"); // custom separator

const db = new JsonDB(config);

Adapter Interfaces

IAdapter Interface

Base interface for all storage adapters, defining the contract for reading and writing data.

/**
 * Base adapter interface for data storage
 * Use to read and write data of type T
 */
interface IAdapter<T> {
  /**
   * Read the data from the storage medium
   * @returns Promise resolving to data of type T or null if no data exists
   */
  readAsync(): Promise<T | null>;
  
  /**
   * Write data into the storage medium
   * @param data - Data to write to storage
   * @returns Promise that resolves when write operation completes
   */
  writeAsync(data: T): Promise<void>;
}

Built-in Adapters

JsonAdapter Class

Handles JSON serialization and deserialization, including automatic date parsing and formatting options.

/**
 * JSON serialization adapter with date handling and formatting options
 * @param adapter - Underlying string-based adapter (typically FileAdapter)
 * @param humanReadable - Format JSON with indentation (default: false)
 */
class JsonAdapter implements IAdapter<any> {
  constructor(adapter: IAdapter<string>, humanReadable?: boolean);
  
  /**
   * Read and parse JSON data with automatic date parsing
   * @returns Promise resolving to parsed JavaScript object
   */
  readAsync(): Promise<any>;
  
  /**
   * Stringify and write JSON data
   * @param data - JavaScript object to serialize
   * @returns Promise that resolves when write completes
   */
  writeAsync(data: any): Promise<void>;
}

Usage Examples:

import { JsonAdapter, FileAdapter } from "node-json-db";

// Basic JSON adapter
const fileAdapter = new FileAdapter("data.json", false);
const jsonAdapter = new JsonAdapter(fileAdapter);

// Human readable JSON with indentation
const readableAdapter = new JsonAdapter(fileAdapter, true);

// Custom usage
await jsonAdapter.writeAsync({ users: [], posts: [] });
const data = await jsonAdapter.readAsync();

Date Handling: The JsonAdapter automatically converts ISO date strings back to Date objects when reading:

// Writing
await db.push("/created", new Date());

// Reading - automatically converted back to Date object
const created = await db.getData("/created");
console.log(created instanceof Date); // true

FileAdapter Class

File system storage adapter that handles reading from and writing to files with directory creation and error handling.

/**
 * File system storage adapter
 * @param filename - Path to the file for storage
 * @param fsync - Use synchronous file operations for guaranteed persistence
 */
class FileAdapter implements IAdapter<string> {
  constructor(filename: string, fsync: boolean);
  
  readonly filename: string;
  
  /**
   * Read file content as string
   * @returns Promise resolving to file content or null if file doesn't exist
   */
  readAsync(): Promise<string | null>;
  
  /**
   * Write string content to file, creating directories as needed
   * @param data - String data to write to file
   * @returns Promise that resolves when write operation completes
   */
  writeAsync(data: string): Promise<void>;
}

Usage Examples:

import { FileAdapter } from "node-json-db";

// Basic file adapter
const adapter = new FileAdapter("database.json", false);

// With sync operations for data integrity
const syncAdapter = new FileAdapter("/critical/data.json", true);

// Directory creation is automatic
const nestedAdapter = new FileAdapter("data/backups/db.json", false);

// Read/write operations
await adapter.writeAsync('{"test": "data"}');
const content = await adapter.readAsync(); // '{"test": "data"}'

Features:

  • Automatic directory creation: Creates parent directories if they don't exist
  • Error handling: Properly handles file not found, permission errors, etc.
  • Atomic writes: Uses file handles for safe write operations
  • Sync option: Optional fsync for guaranteed disk persistence

Custom Adapter Implementation

You can implement custom adapters for different storage backends:

import { IAdapter } from "node-json-db";

// Example: Memory adapter
class MemoryAdapter implements IAdapter<any> {
  private data: any = null;
  
  async readAsync(): Promise<any> {
    return this.data;
  }
  
  async writeAsync(data: any): Promise<void> {
    this.data = data;
  }
}

// Example: Redis adapter
class RedisAdapter implements IAdapter<any> {
  constructor(private client: RedisClient, private key: string) {}
  
  async readAsync(): Promise<any> {
    const data = await this.client.get(this.key);
    return data ? JSON.parse(data) : null;
  }
  
  async writeAsync(data: any): Promise<void> {
    await this.client.set(this.key, JSON.stringify(data));
  }
}

// Usage with custom adapter
const config = new ConfigWithAdapter(new MemoryAdapter());
const db = new JsonDB(config);

Configuration Interface

JsonDBConfig Interface

Base configuration interface that all configuration classes must implement.

/**
 * Database configuration interface
 */
interface JsonDBConfig {
  /**
   * Storage adapter for reading/writing data
   */
  readonly adapter: IAdapter<any>;
  
  /**
   * Whether to automatically save after push operations
   */
  readonly saveOnPush: boolean;
  
  /**
   * Character used to separate DataPath segments
   */
  readonly separator: string;
}

Configuration Best Practices

Development vs Production

// Development - readable JSON, auto-save, async operations
const devConfig = new Config("dev-database.json", true, true, "/", false);

// Production - compact JSON, manual saves, sync operations for reliability
const prodConfig = new Config("prod-database.json", false, false, "/", true);

Memory vs Disk

// For caching or temporary data
const memoryConfig = new ConfigWithAdapter(new MemoryAdapter());

// For persistent data
const diskConfig = new Config("persistent.json", true, false, "/", true);

Custom Separators

// Windows-style paths
const windowsConfig = new Config("database.json", true, false, "\\");

// Dot notation
const dotConfig = new Config("database.json", true, false, ".");

// Usage with custom separator
await db.getData("\\users\\1\\name");  // Windows style
await db.getData(".users.1.name");    // Dot notation

docs

adapters.md

advanced-features.md

database-operations.md

index.md

tile.json