npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

membrace-db

v1.0.5

Published

Give MembraceDb a root object and it will save it as json (it's deep graph) and load it from disk next start.

Downloads

10

Readme

MembraceDb

An easy-to-use memory-first database for Node.js

Just give MembraceDb a root object and it will save it as json (it's deep graph) and load it from disk next start.

That's the concept. So the main organization structure is just your objects in memory (at your fingertips) yeah. You don't have to think how to fit these into tables, meaning: No SQL, no ORM, no relations to configure, ...

Let's first have an honest look at the pro / cons of that concept so you can decide, if that fits into your range:

  • Pro: Simple as hell.
  • Pro: Reads are fast as hell, cause just taken from memory.
  • Con: After each durable commit, the whole object graph needs to be written do disk. But i'm working on that towards change tracking with incremental writes. Currently you may be fine with periodic flushes to disk, like every 10 minutes, depending on the application.
  • Con: Everything must fit into RAM. But that shouldn't be a problem in today's times where you can rent dedicated servers in the terrabyte range for reasonable prices. If you don't fit your highly webbed core business data into that, then i don't know what...
  • Con: Your app is limted to one node (1 cpu core). Currently, this can still serve you roughly 100.000 requests per second via http to the client, if you tune your application well. I think, most applications can live with that very well.

So, the the concept looks promising and let's see how far we can drill up this concept to use that on a professional level yeah !

Features

  • Can persist class instances and restore them as such. MembraceDb will tell you to register them.
  • Can keep backups. With smart consolidation.
  • Atomic writes (file swaps) and corruption checks.
  • Supports data types beyond json: undefined, Infinity, NaN, -0, Date, Map, Set, BigInt, regular expressions, circular references. See the format option.
  • Planned: Change tracking and incremental saving. This will lift it to a professional scale.
  • Planned: Automatic schema migration. Will automacally inspect the typescript types via typescript-rtti, compare the difference and give you a template, how to write the proper migration method for that in your class.

Install

npm install --save membrace-db

Usage

import {MembraceDb, persistence} from "membrace-db";

const exampleDatabaseContent = {
    users: [{id: 1, name: "Alice"}, {id: 2, name: "Bob"}],
    currentComment: "Hello",
}

// Create the database instance. All content will be saved to ./db/db.json:
const db = new MembraceDb("./db", {
    root: exampleDatabaseContent, // This will be the first initial content, if no database file was created yet.
    // ... other options (use intellisense)
});

console.log(`Current db content is: ${db.root}`) // On the second run, you will also see Andrej here

db.root.users.push({id: 3, name: "Andrej"}) // Modify the data somehow.

db.writeToDisk() // Writes everything to disk immediately, blocking.

Usage with class instances (OOP)

You like to program the OOP way ? You can store class instances and they will be restored on the next run. Even your root object can be a class instance (class ApplicationData here):

import {MembraceDb, persistence} from "membrace-db";

class User {
    id: number = generateID();
    
    @persistence({/* options */}) // Within classes, you also have some options here, like non-persistent/transient fields. Use IntelliSense.
    name: string

    constructor(name?: string) { // Note: the parameter `name` is optional. You must give MembraceDb the chance to call the constructor with **no arguments** when it restores from disk.
        this.name = name!;
    }
}

class ApplicationData {
    users: User[] = []
    currentComment = "Hello"
}

const db = new MembraceDb<ApplicationData>("./db", {
    root: new ApplicationData(), // Initial content
    classes: [ApplicationData, User] // All your classes must be registed here, so MembraceDb knows, how to restore them from disk.
});

db.root.users.push(new User("Andrej")); // somehow modify data (as usual)

db.writeToDisk()

Performance: Write to disk only occasionally:

As an alternative to db.writeToDisk(), like in a webserver where you have lots of small write events, you could instead do:

db.markChanged() // Informs the db, that the content (deep inside root) has changed. It will soon write it to disk.

See the maxWriteWaitInSeconds option.

Example project

On github or Open in StackBlitz. Not working with StackBlitz on Firefox currently. Ignore the ever-spinning "Installing dependencies".