npm

@tducasse/js-db
TypeScript icon, indicating that this package has built-in type declarations

0.2.2 • Public • Published

js-db

weekend-project Build Status Coverage Status

A very tiny js in-memory database, using native JavaScript objects. Inspired by mongodb's syntax, even though it implements a subset of it.

Install

Using Node:

npm i @tducasse/js-db

Or in the browser:

<html>
  <head>
    <script src="https://unpkg.com/@tducasse/js-db/dist/umd/js-db.js"></script>
    <script>
      // the script is exported as 'jsdb'
      jsdb.register("users")
      jsdb.db.users.insert({name: "name"});
      const user = jsdb.db.users.findOne();
      console.log(user.name)
      // "name"
    </script>
  </head>
</html>

Docs

We basically export one object, called db, to which we attach collections using the register() function.

import { db, register } from "@tducasse/js-db";

// register the "users" collection
register("users");

// now you can call `db.users`
db.users.insert({ name: "John" });

const user = db.users.findOne({ name: "John" });
console.log(user);
// { name: "John" }

register()

Registers a collection on the db object.

register("users");

// now you can access `users` on `db`
db.users.find();
// []

seed()

Import initial data into the database. Also calls register() under the hood.

const items = {
  users: [{ name: "John" }, { name: "Joe" }],
  cities: [{ name: "Paris" }],
};

seed(items);

const users = db.users.find();
// [{ name: "John" }, { name: "Joe" }]
const cities = db.cities.find();
// [{ name: "Paris" }]

reset()

Just a nice helper to reset the database. I mostly use it in tests though!

register("users");

// now you can access `users` on `db`
db.users.find();
// []

reset();
// db.users is now undefined

collection.find()

Finds all the elements that match the query. Calling it without a query argument will just return everything.

register("users");
db.users.insert([{ name: "John" }, { name: "Joe" }]);

const users = db.users.find({ name: "John" });
// [{ name: "John" }]

collection.count()

Like find(), except it just returns the number of elements that match the query. Again, calling it without any arguments will count everything.

register("users");
db.users.insert([{ name: "John" }, { name: "Joe" }]);

const count = db.users.find({ name: "John" });
// 1

collection.findOne()

Finds the first (not sure about the order) element that matches the query. Calling it without a query argument will just return the first item (again, not really sure which).

register("users");
db.users.insert([{ name: "John" }, { name: "Joe" }]);

const users = db.users.findOne({ name: "John" });
// { name: "John" }

collection.insert()

You've seen me use it already, but it does what it looks like: inserts the item(s) in the collection. Can be either an array or a single item.

register("users");
// works with an array
db.users.insert([{ name: "John" }, { name: "Joe" }]);
// or with a single element
db.users.insert({ name: "Mark" });

collection.remove()

Removes all the elements that match the query.

register("users");
db.users.insert([{ name: "John" }, { name: "Joe" }]);

db.users.remove({ name: "John" });
const users = db.users.find();
// [{ name: "Joe" }]

collection.update()

Updates every element that matches the query. Use $set for single value fields, and $push for array fields. $push and $set don't need the key to exist, they will create it if it doesn't.

register("users");
db.users.insert([{ name: "John" }, { name: "Joe", cities: [] }]);

// use $set for single value fields
db.users.update({ name: "John" }, { $set: { name: "Mark" } });
const users = db.users.find();
// [{ name: "Mark"}, { name: "Joe" }]

// and $push for array fields
db.users.update({ name: "Joe" }, { $push: { cities: "Melbourne" } });
const users = db.users.find();
// [{ name: "Mark"}, { name: "Joe", cities: ["Melbourne"] }]

Note on the query/update object

You can access nested keys using the dot-notation syntax.

register("users");
db.users.insert({ name: "John" });

db.users.update({ name: "John" }, { $set: { "address.city": "Melbourne" } });
const users = db.users.find();
// [{ name: "John", address: { city: "Melbourne" }}]

const user = db.users.findOne({ "address.city": "Melbourne" });
// [{ name: "John", address: { city: "Melbourne" }}]

Creating a shell

You can access the database in your code, importing the db object, but you can also create a separate npm script to run it through a Node repl.

// start a socket on 1337
net
  .createServer((socket) => {
    const r = repl.start({
      prompt: "js-db>",
      input: socket,
      output: socket,
      terminal: true,
      preview: false,
    });
    // share the `db` object with the socket
    r.context.db = db;
  })
  .listen(1337);
// in cli.js
import net from "net";

const sock = net.connect(1337);

process.stdin.pipe(sock);
sock.pipe(process.stdout);

process.stdin.on("data", (b) => {
  if (b.length === 1 && b[0] === 4) {
    process.stdin.emit("end");
  }
});
// in package.json
{
  "scripts:
    // I use esm, but you get the idea
    "cli": "node -r esm cli.js"
}

Now, when you run npm run cli, you get a node interactive shell (with autocompletion, etc), in which you can access db.

Readme

Keywords

none

Package Sidebar

Install

npm i @tducasse/js-db

Weekly Downloads

4

Version

0.2.2

License

MIT

Unpacked Size

20 kB

Total Files

7

Last publish

Collaborators

  • tducasse