Need private packages and team management tools?Check out npm Teams »

idborm

1.0.1 • Public • Published

IDBORM · GitHub license npm version Build Status PRs Welcome

Homepage

A super simple and minimalist ORM built on top of IndexedDB powered by idb that makes IndexedDB usable in both service worker and application

Table of Contents

Installation

This is a Node.js module available through the npm registry.

Before installing, download and install Node.js.

Installation is done using the npm install command:

$ npm install idborm
# or yarn 
$ yarn add idborm

Configuration with service worker

In order to use this module inside the service worker use --serviceworker flag provided by idborm binary script :

$ ./node_modules/.bin/idborm --serviceworker <PATH_TO_YOUR_SERVICE_WORKER>

you'll see it create idborm.iife.js containing immediately invoked idborm function expression next to your service worker (provided after --serviceworker flag) and generate following code snippet on top of the service worker file:

/** "idborm": Following code snippet is required to access the "IDB"*/
importScripts("./idborm.iife.js");
const { IDB } = idborm;

now, you can access idborm utility functions using destructed IDB class

API

Assuming you're using a module-compatible system (like webpack, Rollup etc):

init ( database_name, database_version, object_store(s)_Initializer )

Initialize database and object stores

import IDB from "idborm";
 
const DB = IDB.init(database_name, database_version, object_store(s)_Initializer);
  • database_name: Name of the database

  • object_store(s)_Initializer: Represent database object store(s)( something like Table or Model in relational or non-relational databases ); you can initialize your database object store(s) using one of the following methods:

    1. initialize single object store:
    import { IDB } from "idborm";
     
    // Using an initializer_object
     
    const DB = IDB.init(database_name, database_version, {
      name: object_store_name,
      options: object_store_options,
    });
    1. initialize multiple object stores
    import { IDB } from "idborm";
     
    // Using List containing multiple initializer_objects
     
    const DB = IDB.init(database_name, database_version, [
      { name: object_store_one_name, options: object_store_one_options },
      { name: object_store_two_name },
      .
      .
      .
    ]);
    1. Create object store(s) using a callback function:
    import { IDB } from "idborm";
     
    // Using a callback function that and initializer_object contains or a list containing multiple initializer_objects
     
    const DB = IDB.init(database_name, database_version, () => {
      return { name: object_store_name, options: object_store_options };
      // or
      return [
        { name: object_store_one_name, options: object_store_one_options },
        { name: object_store_two_name, options: object_store_two_options },
      ];
    });
    • object_store_name: Name of object store

    • object_store_options optional : You can specify one of the following options:

      1. no_options: You should manually provide key for each record when putting it in the database

      2. keyPath: Uses specified keyPath as record's key therefore records should contains specified keyPath

      3. autoIncrement: Uses autoIncrement integers as record's key

// i.e.
import { IDB } from "idborm";
 
// Create a dataBase containing three object stores
const MyDB = IDB.init("MyDB", 1, [
  { name: "User", options: { keyPath: "email" } },
  { name: "Post", options: { autoIncrement: true } },
  { name: "Article" },
]);
  • database_version: Database objectStore(s) schema version, you have to bump database_version on changing object_store(s)_initializer to apply changes on database; (using same version or lower version will not change database object store(s)
/*
  i.e.
  In following example we're create "Post" object store to database so we increased database version (1 -> 2) to apply changes on database
*/
import { IDB } from "idborm";
 
// Before
const MyDB = IDB.init("MyDB", 1, { name: "User", options: { keyPath: "email" } });
 
// After
const MyDB = IDB.init("MyDB", 1, [
  { name: "User", options: { keyPath: "email" } }
  { name: "Post" }
  ]);

Caveats

  • Changing object store's name will completely delete it and create another one
  • Changing just object store's options not applying changes on database, you have to completely delete the data base using asynchronous DB.delete( ) and reinitialize it
  • Changing object without increasing database_version will not apply changes on database
  • Using a version less than current database version throw an exception

objectStores

Destructor objectStores

Once you define your object stores you can destructor them from your database.objectStores

// i.e.
import { IDB } from "idborm";
 
// Create a dataBase containing three object stores
const MyDB = IDB.init("MyDB", 1, [
  { name: "User", options: { keyPath: "email" } },
  { name: "Post", options: { autoIncrement: true } },
  { name: "Article" },
]);
 
// Make sure that destructor object stores using exact same name the you defined them
const { User, Post, Article } = MyDB.objectStores;

put ( value, optional_key )

Put record in the object store

Based on the options you specified to related object store you can put the record in the object store using ObjectStore.put(value, optional_key) it will Put record in the object store and Replaces items with the same keys

Notice when no option (keyPath or autoIncrement) specified key(out-of-the-line-key) is required

import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, [
  { name: "User", options: { keyPath: "email" } },
  { name: "Post", options: { autoIncrement: true } },
  { name: "Article" },
]);
 
const { User, Post, Article } = MyDB.objectStores;
 
(async () => {
  // email property is required because we're used email as object store keyPath
  await User.put({ email: "bob@bob.com", name: "bob" });
 
  // Uses autoIncrement integer as record's keys
  await Post.put("post");
 
  // Out-of-the-line-key is required because we not specified any option
  await Article.put(["article"], "article one");
})();

get ( key )

Retrieve a specific record from object store

Based on the options you specified to related object store you can get the record from object using ObjectStore.get(value, optional_key)

import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, [
  { name: "User", options: { keyPath: "email" } },
  { name: "Post", options: { autoIncrement: true } },
  { name: "Article" },
]);
 
const { User, Post, Article } = MyDB.objectStores;
 
(async () => {
  // Use specified keyPath property as key to retrieve the record
  const user = await User.get("bob@bob.com");
 
  // AutoIncrement integer as key to retrieve the record
  const post = await Post.get(1);
 
  // Use manually specified key to retrieve the record
  const article = await Article.get("article one");
})();

delete ( key )

Delete a specific record from database

import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, [
  { name: "User", options: { keyPath: "email" } },
  { name: "Post", options: { autoIncrement: true } },
  { name: "Article" },
]);
 
const { User, Post, Article } = MyDB.objectStores;
 
(async () => {
  // Use specified keyPath property as key to delete the record
  await User.delete("bob@bob.com");
 
  // AutoIncrement integer as key to delete the record
  await Post.delete(1);
 
  // Use manually specified key to delete the record
  await Article.delete("article one");
})();

keys ( )

Retrieve all records keys from database

import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, { name: "User" });
 
const { User } = MyDB.objectStores;
 
(async () => {
  await User.put("bob one", "user one");
  await User.put("bob 2", 2);
  await User.put("bob three", "user three");
 
  const keys = await User.keys();
 
  console.log(keys);
  /*
    output:
      [ "user one", 2, "user three" ]
  */
})();

values ( )

Retrieve all records values from database

import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, { name: "User", options: { autoIncrement: true } });
 
const { User } = MyDB.objectStores;
 
(async () => {
  await User.put("bob one");
  await User.put({ name: "bob two" });
  await User.put(3);
 
  const values = await User.values();
 
  console.log(values);
  /*
    output:
      [ "bob one", { name: "bob two" }, 3 ]
  */
})();

entries ( )

Retrieves an array of a given object's own enumerable string-keyed property [key, value] pairs

import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, { name: "User", options: { keyPath: "id" } });
 
const { User } = MyDB.objectStores;
 
(async () => {
  await User.put({ id: "user one", name: "bob one" });
  await User.put({ id: "user two", name: "bob two" });
 
  const entries = await User.entries();
 
  console.log(entries);
  /*
    output:
      [ 
        ["user one", { id: "user one", name: "bob one" }],
        ["user two", { id: "user two", name: "bob two" }]
      ]
  */
})();

clear( )

Delete all records stored in an object store

import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, { name: "User", options: { keyPath: "id" } });
 
const { User } = MyDB.objectStores;
 
(async () => {
  await User.put({ id: "user one", name: "bob one" });
  await User.put({ id: "user two", name: "bob two" });
 
  await User.clear();
 
  const values = await User.values();
 
  console.log(values);
  /*
    output:
      []
  */
})();

iterate ( ( value, index, entries) => Promise )

Iterate over all records inside the objectStore and perform an async action on each one

/*
  i.e.
  Delete all completed task:
 */
import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, { name: "Todo", options: { keyPath: "id" } });
 
const { Todo } = MyDB.objectStores;
 
(async () => {
  await Todo.put({ id: "task one", completed: true });
  await Todo.put({ id: "task two", completed: false });
 
  await Todo.iterate(([key, value], index, entries) => {
    if (value.completed) {
      return Todo.delete(key);
    }
  });
 
  const values = await Todo.values();
 
  console.log(values);
  /*
    output:
      [ { id: "task two", completed: false } ]
  */
})();

DB.objectStores.methods.iterate ( ( objectStore, index, ObjectStoresArray) => Promise )

Iterate over all the object stores inside a database and perform an async action on each one

/**
  i.e.
  Put some data in the all objectStore of a database:
*/
import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, [
  { name: "User", options: { autoIncrement: true } },
  { name: "Post", options: { autoIncrement: true } },
]);
 
(async () => {
  await MyDB.objectStores.methods.iterate((ObjectStore, index, objectStoresArray) => {
    return ObjectStore.put("some data");
  });
})();

DB.delete ( )

Delete an indexed database

import { IDB } from "idborm";
 
const MyDB = IDB.init("MyDB", 1, [
  { name: "User", options: { autoIncrement: true } },
  { name: "Post", options: { autoIncrement: true } },
]);
 
(async () => {
  await MyDB.delete();
})();

Examples

VanillaJS Demo

React-ServiceWorker

Netlify Status

Contribute!

I always welcome help. Please just stick to the lint rules and write tests with each feature/fix

Versioning

I use SemVer for versioning. For the versions available, see the tags on this repository

License

This project is licensed under the MIT License - see the LICENSE file for details

Install

npm i idborm

DownloadsWeekly Downloads

0

Version

1.0.1

License

MIT

Unpacked Size

58.8 kB

Total Files

13

Last publish

Collaborators

  • avatar