A super simple and minimalist ORM built on top of IndexedDB powered by idb that makes IndexedDB usable in both service worker and application
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
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
Assuming you're using a module-compatible system (like webpack, Rollup etc):
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:
import { IDB } from "idborm";
// Using an initializer_object
const DB = IDB.init(database_name, database_version, {
name: object_store_name,
options: object_store_options,
});
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 },
.
.
.
]);
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:
no_options: You should manually provide key for each record when putting it in the database
keyPath
: Uses specified keyPath as record's key therefore records should contains specified keyPath
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" }
]);
name
will completely delete it and create another oneoptions
not applying changes on database, you have to completely delete the data base using asynchronous DB.delete( ) and reinitialize itdatabase_version
will not apply changes on databaseOnce 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;
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");
})();
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");
})();
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");
})();
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" ]
*/
})();
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 ]
*/
})();
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" }]
]
*/
})();
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:
[]
*/
})();
/*
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 } ]
*/
})();
/**
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");
});
})();
import { IDB } from "idborm";
const MyDB = IDB.init("MyDB", 1, [
{ name: "User", options: { autoIncrement: true } },
{ name: "Post", options: { autoIncrement: true } },
]);
(async () => {
await MyDB.delete();
})();
I always welcome help. Please just stick to the lint rules and write tests with each feature/fix
I use SemVer for versioning. For the versions available, see the tags on this repository
This project is licensed under the MIT License - see the LICENSE file for details
Generated using TypeDoc