Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/n1md7/indexeddb-promise
Indexeddb wrapper with promises
https://github.com/n1md7/indexeddb-promise
database indexed-db indexed-db-orm indexeddb-wrapper javascript typescript
Last synced: 26 days ago
JSON representation
Indexeddb wrapper with promises
- Host: GitHub
- URL: https://github.com/n1md7/indexeddb-promise
- Owner: n1md7
- License: mit
- Created: 2019-12-14T14:42:12.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2024-03-15T18:42:46.000Z (8 months ago)
- Last Synced: 2024-09-29T11:25:35.168Z (about 1 month ago)
- Topics: database, indexed-db, indexed-db-orm, indexeddb-wrapper, javascript, typescript
- Language: JavaScript
- Homepage: https://n1md7.github.io/indexeddb-promise/
- Size: 881 KB
- Stars: 10
- Watchers: 1
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: docs/README.md
- License: LICENSE
Awesome Lists containing this project
README
[![npm databaseVersion](https://badge.fury.io/js/@n1md7%2Findexeddb-promise.svg)](https://badge.fury.io/js/@n1md7%2Findexeddb-promise)
[![Node.js Package](https://github.com/n1md7/indexeddb-promise/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/n1md7/indexeddb-promise/actions/workflows/npm-publish.yml)
[![Node.js CI - tests](https://github.com/n1md7/indexeddb-promise/actions/workflows/node.js.yml/badge.svg)](https://github.com/n1md7/indexeddb-promise/actions/workflows/node.js.yml)
![GitHub](https://img.shields.io/github/license/n1md7/indexeddb-promise)
[![codecov](https://codecov.io/gh/n1md7/indexeddb-promise/branch/master/graph/badge.svg?token=Q5OJ22Q3LK)](https://codecov.io/gh/n1md7/indexeddb-promise)# Indexed DB wrapper with promises
Supports all browsers that support IndexedDB.
Has TypeScript support with TS-class decorators.
## Demo
- [Basic Example01](https://n1md7.github.io/indexeddb-promise/Example01.html)
- [Advanced Example02](https://n1md7.github.io/indexeddb-promise/Example02.html)## Installation
```shell
$ npm install @n1md7/indexeddb-promise
``````shell
$ yarn add @n1md7/indexeddb-promise
```## Decorators
Typescript decorators are supported.
Prerequisite:
```json
{
"experimentalDecorators": true
}
```### @Table
Class decorator for IndexedDB table. It defines the structure of the table.
Params: options - object with following properties:
- name? - string, name of the table, default is the class name
- timestamps? - boolean, if true, createdAt and updatedAt columns will be added, default is false
- initialData? - array of objects to be inserted into the table on database creation, default is empty```javascript
@Table({ name: 'Users', timestamps: true })
class User {}
```### @Indexed
Property decorator for IndexedDB index. It defines whether the property is indexed.
Params: options - object with following properties:
- unique? - boolean, if true, the index will be unique, default is false
- multiEntry? - boolean, if true, the index will be multi-entry, default is true```javascript
@Table()
class User {
@Indexed({ unique: true, multiEntry: false })
username: string;
}
```### @PrimaryKey
Property decorator for IndexedDB primary key. It defines whether the property is primary key.
Params: options - object with following properties:
- autoIncrement? - boolean, if true, the primary key will be auto-incremented, default is true
- unique? - boolean, if true, the primary key will be unique, default is true```javascript
@Table()
class User {
@PrimaryKey()
id: number;@Index()
name: string;
}
```## Methods
| Method | Description | Params |
| ------------------ | ------------------------------------------------- | ----------------------- |
| `selectAll` | Get the data from database | None |
| `select` | Fetch data from database with filters | Object |
| `insert` | Add data into database | Object |
| `openCursor` | Get database cursor to iterate on demand | None |
| `selectByIndex` | Select database data by indexed properties (one) | String, String |
| `selectByIndexAll` | Select database data by indexed properties (many) | String, String |
| `selectByPk` | Select database record by primary key | String \ Number |
| `updateByPk` | Update database record by primary key | Number \ Number, Object |
| `deleteByPk` | Delete database record by primary key | String \ Number |### - selectAll
#### Params
Gets all the data from database.
Return type: Promise
Accept params: None
#### Javascript example
```javascript
model.selectAll().then((data) => data);
const data = await model.selectAll();
```#### Typescript example
```typescript
model.selectAll().then((data) => {
// In TS {data} is inferred from the model
return data;
});
const data = await model.selectAll();
```### - select
#### Params
Gets filtered data from database.
Return type: Promise
Accept params: options: Object
Object properties:
```text
{
where?: Object | Function;
limit?: Number;
orderByDESC?: Boolean;
sortBy?: String | String[];
}
```#### JS/TS example
```javascript
const options = {
limit: 10,
where: (dataArray) => {
return dataArray;
},
orderByDESC: true,
sortBy: 'comments', // ['comments', 'date']
};
model.select(options).then((data) => data);
const data = await model.select(options);
```@where property can filter out data like
```javascript
const props = {
where: (data) => data.filter((item) => item.username === 'admin'),
};
```or it can be an object, which gets data with AND(&&) comparison
```javascript
const props = {
where: {
username: 'admin',
password: 'admin123',
},
};
```### - selectByIndex
#### Params
Gets the data from database with the specified indexed property.
Return type: Promise
Accept params: indexName: string, valueToMatch: string
#### JS/TS example
```javascript
model.selectByIndex('username', 'admin').then((data) => data);
const data = await model.selectByIndex('username', 'admin');
```### - selectByIndexAll
#### Params
Gets the data from database with the specified indexed property.
Return type: Promise>
Accept params: indexName: string, valueToMatch: string
#### JS/TS example
```javascript
model.selectByIndexAll('username', 'admin').then((data) => data);
const data = await model.selectByIndexAll('username', 'admin');
```### - selectByPk
#### Params
Gets the data from database with the specified primary key.
Return type: Promise
Accept params: primaryKey: string \ number
#### JS/TS example
```javascript
model.selectByPk(1).then((data) => data);
const data = await model.selectByPk('admin');
```### - updateByPk
#### Params
Updates the data in database with the specified primary key.
Return type: Promise
Accept params: primaryKey: string \ number, Object
#### JS/TS example
```javascript
model.updateByPk(123, { username: 'admin' });
const data = await model.updateByPk(123, { username: 'admin' });
```### - deleteByPk
#### Params
Deletes the data in database with the specified primary key.
Return type: Promise
Accept params: primaryKey: string \ number
#### JS/TS example
```javascript
model.deleteByPk(123);
const data = await model.deleteByPk(123);
```_note_ Primary key is type sensitive. If it is saved as integer then should pass as integer and vice versa
## Examples
### Html 01
Once you add _indexed-db.min.js_ in your document then you will be able to access
`IndexedDB` variable globally which contains `Model`. They can be extracted as following```html
IndexedDB app
const Database = IndexedDB.Database;
// Your script here
```
### Html 02
Basic usage of `Model`
```html
IndexedDB app
const db = new IndexedDB.Database({
databaseVersion: 1,
databaseName: 'MyNewDatabase',
tables: [
{
name: 'MyNewTable',
primaryKey: {
name: 'id',
autoIncrement: false,
unique: true,
},
initData: [],
indexes: {
username: { unique: false, autoIncrement: false },
password: { unique: false, autoIncrement: false },
},
},
],
});
await db.connect();
// Add a new record
const model = db.useModel('MyNewTable');
model
.insert({
id: Math.random() * 10,
username: 'admin',
password: 'nimda',
createdAt: new Date(),
updatedAt: new Date(),
})
.then(function() {
console.info('Yay, you have saved the data.');
})
.catch(function(error) {
console.error(error);
});// Get all results from the database
model.selectAll().then(function(results) {
console.log(...results);
});
```
### Javascript
```javascript
const IndexedDB = require('@n1md7/indexeddb-promise');
const { Database } = IndexedDB;
// or
import { Database } from '@n1md7/indexeddb-promise';
```### TypeScript 01
```javascript
import { Database } from '@n1md7/indexeddb-promise';interface Users {
id?: number;
username: string;
password: string;
}enum Priority {
LOW = 'LOW',
MEDIUM = 'MEDIUM',
HIGH = 'HIGH',
}interface ToDos {
id?: number;
userId: number;
title: string;
description: string;
done: boolean;
priority: Priority;
}const database = new Database({
version: 1,
name: 'Todo-list',
tables: [
{
name: 'users',
primaryKey: {
name: 'id',
autoIncrement: true,
unique: true,
},
indexes: {
username: {
unique: false,
},
},
timestamps: true,
},
{
name: 'todos',
primaryKey: {
name: 'id',
autoIncrement: true,
unique: true,
},
indexes: {
userId: {
unique: true,
},
},
timestamps: true,
},
],
});(async () => {
await database.connect();
const users = database.useModel('users');
const user = await users.insert({
username: 'admin',
password: 'admin',
});
const todos = database.useModel('todos');
await todos.insert({
userId: user.id,
title: 'Todo 1',
description: 'Description 1',
done: false,
priority: Priority.LOW,
});
})();
```### TypeScript decorators 02
```javascript
import { Table, PrimaryKey, Indexed, Database } from '@n1md7/indexeddb-promise';@Table({ name: '__Name__', timestamps: true })
class SomeTable {
@PrimaryKey({ autoIncrement: true, unique: true })
id: number;@Indexed({ unique: true, multiEntry: false })
username: string;@Indexed({ unique: false })
age: number;otherData: string;
}const anotherDb = new Database({
version: 1,
name: 'Other-DB',
tables: [SomeTable],
});
await anotherDb.connect();
const model = anotherDb.useModel(SomeTable);(async () => {
await model
.insert({
username: 'John',
age: 20,
otherData: 'Some data',
})
.catch((error) => console.error(error));model.selectAll().then((results) => {
if (results) {
results.forEach((result) => {
// result is inferred to be SomeTable
console.log(result.username);
});
}
});
})();
```### TypeScript decorators 02
```javascript
import { Database, Indexed, PrimaryKey, Table } from '@n1md7/indexeddb-promise';@Table({ timestamps: true })
class User {
@PrimaryKey({ autoIncrement: true, unique: true })
id: number;@Indexed({ unique: true, multiEntry: false })
username: string;@Indexed()
password: string;toString() {
return `#${this.id} ${this.username}`;
}
}@Table()
class Info {
@PrimaryKey({ autoIncrement: true, unique: true })
id: number;@Indexed()
userId: number;name: {
first: string,
last: string,
};age: number;
occupation: string;
toString() {
return `${this.name.first} ${this.name.last} ${this.age} years old - ${this.occupation}`;
}
}const store = new Database({
version: 1,
name: 'Store',
tables: [User, Info],
});await store.connect();
const userModel = store.useModel(User);
const infoModel = store.useModel(Info);(async () => {
const savedUser = await userModel.insert({
username: 'admin',
password: 'admin',
});await infoModel.insert({
userId: savedUser.id,
name: {
first: 'John',
last: 'Doe',
},
age: 27,
occupation: 'Web Developer',
});
})().catch(console.log);(async () => {
const user = await userModel.selectByIndex('username', 'admin');
if (!user) throw new Error('User not found');const info = await infoModel.select({ where: { userId: user.id } });
if (!info) throw new Error('Info not found');console.log(user.toString() + ' - ' + info.toString());
})().catch(console.log);
```