Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

Simple, small and embeddable NoSQL database for Node.js.

License

Notifications You must be signed in to change notification settings

chronoDave/leaf-db

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

leaf-db

leaf-db

leaf-db is a simple NoSQL embeddable database.

Features

  • Strong-typed documents and queries.
  • Easy to embed as it does not require an HTTP server to run.
  • Can be used in the browser if persistent storage isn't required.
  • Uses JSON documents.
  • Tiny and 0 dependencies.

Table of Contents

Getting Started

leaf-db is meant as a simple database that allows for basic querying over JSON data without needing to set up a database server / connection like with MongoDB or SQLite.

Node does support working with SQLite directly, if you prefer a more stable, feature-complete database.

leaf-db can be used in the browser if persistent read / write isn't required.

Installation

npm i leaf-db

Example

Create a database using file storage with strong-typed documents:

import LeafDB from 'leaf-db';

type Document = {
  title: string
  name: string
}

const db = new LeafDB<Document>();

await db.open({ name: 'db', dir: process.cwd() });

const drafts = [
  { title: 'Lady', name: 'Mipha' },
  { title: 'Young Rito Warrior', name: 'Tulin' }
]
await Promise.all(drafts.map(async draft => db.insert(draft)));

// [{ _id: <string>, title: 'Young Rito Warrior', name: 'Tulin' }]
const characters = db.query({ name: 'Tulin' });

const tulin = characters[0];
tulin.title = 'Rito Warrior';

await db.update(tulin); // Overwrite existing document

await db.close();

Concepts

Document

Leaf-db stores data as JSON documents and saves them inside a JSONL file.

Keys

Document keys must be of type string and cannot start with $.

Every document is required to have an _id field. Leaf-db automatically creates an _id if the field does not exist on insertion. _id is required to be unique when inserting documents.

Values

Leaf-db only supports JSON values, which is defined as:

type Json =
  string |
  number |
  boolean |
  null |
  Json[] |
  { [key: string]: Json };

Persistence

Leaf-db stores the database in memory by default. To make use of persistence, simply open the database.

import LeafDB from 'leaf-db';

/** Create a new database, `db.jsonl`, in process.cwd() */
const db = new LeafDB();
await db.open({ name: 'db', dir: process.cwd() });

Corruption

When opening a database from storage, leaf-db will return documents that are corrupt. These documents are deleted once opened and cannot be recovered afterwards.

import LeafDB from 'leaf-db';

const db = new LeafDB({ name: 'db', dir: process.cwd() });
const corrupt = await db.open(); // Corrupt[]
type Corrupt = {
  raw: string;
  error: Error;
};

Queries

Leaf-db supports both literal values and operators. Example:

/**
 * Literal query where value must equal the query value
 * { name: 'tulin' } // No match
 * { name: 'Mipha' } // No match
 */
const a = { name: 'Tulin' };

/**
 * Objects and arrays match on partial matches
 * { eras: [] } // Match
 * { eras: ['era of the wilds'] } // No match
 * { eras: [Sky Era'] } // No Match
 */
const b = { eras: ['Era of the Wilds'] }

Operators

Operators allow for more complex queries. Operators must always be used in combination with values.

Number
$gt

Is greater than

const query = { a: { $gt: 3 } };

const a = { a: 2 }; // false
const b = { a: 3 }; // false
const c = { a: 4 }; // true
$gte

Is greater than or equal to

const query = { a: { $gte: 3 } };

const a = { a: 2 }; // false
const b = { a: 3 }; // true
const c = { a: 4 }; // true
$lt

Is less than

const query = { a: { $lt: 3 } };

const a = { a: 2 }; // true
const b = { a: 3 }; // false
const c = { a: 4 }; // false
$lte

Is less than or equal to

const query = { a: { $lte: 3 } };

const a = { a: 2 }; // true
const b = { a: 3 }; // true
const c = { a: 4 }; // false
String
$regexp

Matches strings against RegExp

const query = { a: { $regexp: /\w+/g } }

const a = { a: '' }; // false
const b = { a: '0' }; // false
const c = { a: 'a' }; // true
Array
$length

Equal to length

const query = { a: { $length: 3 } }

const a = { a: [] }; // false
const b = { a: [1, 2, 3] }; // true
const c = { a: [1, 2, 3, 4] }; // false
$includes

Has value in array. Does not partial match on arrays or objects.

const query = { a: { $includes: 3 } };

const a = { a: [] }; // false
const b = { a: [1, 2, 3] }; // true

const query = { b: { $includes: [3] } };

const a = { b: [ [3] ] }; // true
const b = { b: [ [3, 4] ] }; // false
Logic
$not

Invert query

const query = { $not: { a: { $lt: 3 } } };

const a = { a: 2 }; // false
const b = { a: 4 }; // true
$and

Must match all queries

const query = { $and: [{ a: 2 }, { b: { $lt: 3 } }] };

const a = { a: 2, b: 2 }; // true
const b = { a: 2, b: 4 }; // false
$or

Matches any query

const query = { $and: [{ a: 2 }, { b: { $lt: 3 } }] };

const a = { a: 2, b: 2 }; // true
const b = { a: 2, b: 4 }; // true

API

id()

Generate a new, unique id with format [timestamp]-[random].

import LeafDB from 'leaf-db';

const id = LeafDB.id();

docs

Get all documents

const docs = db.docs // Doc<T>[]

open()

Open persistent storage.

import LeafDB from 'leaf-db';

const db = new LeafDB();
const corrupted = await db.open({ name: 'db', dir: process.cwd() }); // Corrupt[]

close()

Close persistent storage.

await db.close();

get()

Get document by id

db.get('a'); // { _id: 'a' }

insert()

Insert document(s) into the database. Will throw an error if duplicate _id's are found.

const drafts = [{ name: 'Tulin', }, { name: 'Mipha' }];
// [{ _id: <string>, name: 'Tulin' }, { _id: <string>, name: 'Mipha' }]
const docs = await Promise.all(drafts.map(async draft => draft.insert(draft)));

query()

Find document(s) based by query.

// Return docs where `name` is equal to `Mipha`
const docs = db.query({ name: 'Mipha' });
// Return docs where `name` is equal to `Mipha` or where `name` is equal to `Tulin`
const docs = db.query({ $or: [{ name: 'Mipha' }, { name: 'Tulin' }] });

update()

Update existing document. Throws if document does not exist

// Update document `a` with new name `Tulin`
const docs = db.update({ _id: 'a', name: 'Tulin' });

delete()

Delete document by _id

// Delete document `a`
await db.delete('a');

drop()

Delete all documents in the database.

await db.drop();

Acknowledgements

About

Simple, small and embeddable NoSQL database for Node.js.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •