{"id":15066746,"url":"https://github.com/n1md7/indexeddb-promise","last_synced_at":"2025-04-10T13:53:18.693Z","repository":{"id":257763246,"uuid":"228038405","full_name":"n1md7/indexeddb-promise","owner":"n1md7","description":"Indexeddb wrapper with promises","archived":false,"fork":false,"pushed_at":"2024-03-15T18:42:46.000Z","size":902,"stargazers_count":10,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-18T18:55:15.622Z","etag":null,"topics":["database","indexed-db","indexed-db-orm","indexeddb-wrapper","javascript","typescript"],"latest_commit_sha":null,"homepage":"https://n1md7.github.io/indexeddb-promise/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/n1md7.png","metadata":{"files":{"readme":"docs/README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-14T14:42:12.000Z","updated_at":"2024-09-15T09:30:51.000Z","dependencies_parsed_at":"2024-09-18T14:59:57.077Z","dependency_job_id":"c9318d70-53fe-4582-85aa-7096ee5fe0b8","html_url":"https://github.com/n1md7/indexeddb-promise","commit_stats":{"total_commits":71,"total_committers":6,"mean_commits":"11.833333333333334","dds":0.2816901408450704,"last_synced_commit":"33781bccf68d97fb842af8e2d41546149ec3d529"},"previous_names":["n1md7/indexeddb-promise"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n1md7%2Findexeddb-promise","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n1md7%2Findexeddb-promise/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n1md7%2Findexeddb-promise/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n1md7%2Findexeddb-promise/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/n1md7","download_url":"https://codeload.github.com/n1md7/indexeddb-promise/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248229048,"owners_count":21068815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","indexed-db","indexed-db-orm","indexeddb-wrapper","javascript","typescript"],"created_at":"2024-09-25T01:11:29.479Z","updated_at":"2025-04-10T13:53:18.675Z","avatar_url":"https://github.com/n1md7.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm databaseVersion](https://badge.fury.io/js/@n1md7%2Findexeddb-promise.svg)](https://badge.fury.io/js/@n1md7%2Findexeddb-promise)\n[![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)\n[![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)\n![GitHub](https://img.shields.io/github/license/n1md7/indexeddb-promise)\n[![codecov](https://codecov.io/gh/n1md7/indexeddb-promise/branch/master/graph/badge.svg?token=Q5OJ22Q3LK)](https://codecov.io/gh/n1md7/indexeddb-promise)\n\n# Indexed DB wrapper with promises\n\nSupports all browsers that support IndexedDB.\n\nHas TypeScript support with TS-class decorators.\n\n## Demo\n\n- [Basic Example01](https://n1md7.github.io/indexeddb-promise/Example01.html)\n- [Advanced Example02](https://n1md7.github.io/indexeddb-promise/Example02.html)\n\n## Installation\n\n```shell\n$ npm install @n1md7/indexeddb-promise\n```\n\n```shell\n$ yarn add @n1md7/indexeddb-promise\n```\n\n## Decorators\n\nTypescript decorators are supported.\n\nPrerequisite:\n\n```json\n{\n  \"experimentalDecorators\": true\n}\n```\n\n### @Table\n\nClass decorator for IndexedDB table. It defines the structure of the table.\n\nParams: options - object with following properties:\n\n- name? - string, name of the table, default is the class name\n- timestamps? - boolean, if true, createdAt and updatedAt columns will be added, default is false\n- initialData? - array of objects to be inserted into the table on database creation, default is empty\n\n```javascript\n@Table({ name: 'Users', timestamps: true })\nclass User {}\n```\n\n### @Indexed\n\nProperty decorator for IndexedDB index. It defines whether the property is indexed.\n\nParams: options - object with following properties:\n\n- unique? - boolean, if true, the index will be unique, default is false\n- multiEntry? - boolean, if true, the index will be multi-entry, default is true\n\n```javascript\n@Table()\nclass User {\n  @Indexed({ unique: true, multiEntry: false })\n  username: string;\n}\n```\n\n### @PrimaryKey\n\nProperty decorator for IndexedDB primary key. It defines whether the property is primary key.\n\nParams: options - object with following properties:\n\n- autoIncrement? - boolean, if true, the primary key will be auto-incremented, default is true\n- unique? - boolean, if true, the primary key will be unique, default is true\n\n```javascript\n@Table()\nclass User {\n  @PrimaryKey()\n  id: number;\n\n  @Index()\n  name: string;\n}\n```\n\n## Methods\n\n| Method             | Description                                       | Params                  |\n| ------------------ | ------------------------------------------------- | ----------------------- |\n| `selectAll`        | Get the data from database                        | None                    |\n| `select`           | Fetch data from database with filters             | Object                  |\n| `insert`           | Add data into database                            | Object                  |\n| `openCursor`       | Get database cursor to iterate on demand          | None                    |\n| `selectByIndex`    | Select database data by indexed properties (one)  | String, String          |\n| `selectByIndexAll` | Select database data by indexed properties (many) | String, String          |\n| `selectByPk`       | Select database record by primary key             | String \\ Number         |\n| `updateByPk`       | Update database record by primary key             | Number \\ Number, Object |\n| `deleteByPk`       | Delete database record by primary key             | String \\ Number         |\n\n### - selectAll\n\n#### Params\n\nGets all the data from database.\n\nReturn type: Promise\u003cObject[]\u003e\n\nAccept params: None\n\n#### Javascript example\n\n```javascript\nmodel.selectAll().then((data) =\u003e data);\nconst data = await model.selectAll();\n```\n\n#### Typescript example\n\n```typescript\nmodel.selectAll().then((data) =\u003e {\n  // In TS {data} is inferred from the model\n  return data;\n});\nconst data = await model.selectAll();\n```\n\n### - select\n\n#### Params\n\nGets filtered data from database.\n\nReturn type: Promise\u003cObject[]\u003e\n\nAccept params: options: Object\n\nObject properties:\n\n```text\n{\n  where?: Object | Function;\n  limit?: Number;\n  orderByDESC?: Boolean;\n  sortBy?: String | String[];\n}\n```\n\n#### JS/TS example\n\n```javascript\nconst options = {\n  limit: 10,\n  where: (dataArray) =\u003e {\n    return dataArray;\n  },\n  orderByDESC: true,\n  sortBy: 'comments', // ['comments', 'date']\n};\nmodel.select(options).then((data) =\u003e data);\nconst data = await model.select(options);\n```\n\n@where property can filter out data like\n\n```javascript\nconst props = {\n  where: (data) =\u003e data.filter((item) =\u003e item.username === 'admin'),\n};\n```\n\nor it can be an object, which gets data with AND(\u0026\u0026) comparison\n\n```javascript\nconst props = {\n  where: {\n    username: 'admin',\n    password: 'admin123',\n  },\n};\n```\n\n### - selectByIndex\n\n#### Params\n\nGets the data from database with the specified indexed property.\n\nReturn type: Promise\u003cObject|{}\u003e\n\nAccept params: indexName: string, valueToMatch: string\n\n#### JS/TS example\n\n```javascript\nmodel.selectByIndex('username', 'admin').then((data) =\u003e data);\nconst data = await model.selectByIndex('username', 'admin');\n```\n\n### - selectByIndexAll\n\n#### Params\n\nGets the data from database with the specified indexed property.\n\nReturn type: Promise\u003cArray\u003cObject|{}\u003e\u003e\n\nAccept params: indexName: string, valueToMatch: string\n\n#### JS/TS example\n\n```javascript\nmodel.selectByIndexAll('username', 'admin').then((data) =\u003e data);\nconst data = await model.selectByIndexAll('username', 'admin');\n```\n\n### - selectByPk\n\n#### Params\n\nGets the data from database with the specified primary key.\n\nReturn type: Promise\u003cObject|{}\u003e\n\nAccept params: primaryKey: string \\ number\n\n#### JS/TS example\n\n```javascript\nmodel.selectByPk(1).then((data) =\u003e data);\nconst data = await model.selectByPk('admin');\n```\n\n### - updateByPk\n\n#### Params\n\nUpdates the data in database with the specified primary key.\n\nReturn type: Promise\u003cObject|{}\u003e\n\nAccept params: primaryKey: string \\ number, Object\n\n#### JS/TS example\n\n```javascript\nmodel.updateByPk(123, { username: 'admin' });\nconst data = await model.updateByPk(123, { username: 'admin' });\n```\n\n### - deleteByPk\n\n#### Params\n\nDeletes the data in database with the specified primary key.\n\nReturn type: Promise\u003cString|Number\u003e\n\nAccept params: primaryKey: string \\ number\n\n#### JS/TS example\n\n```javascript\nmodel.deleteByPk(123);\nconst data = await model.deleteByPk(123);\n```\n\n_note_ Primary key is type sensitive. If it is saved as integer then should pass as integer and vice versa\n\n## Examples\n\n### Html 01\n\nOnce you add _indexed-db.min.js_ in your document then you will be able to access\n`IndexedDB` variable globally which contains `Model`. They can be extracted as following\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003eIndexedDB app\u003c/title\u003e\n    \u003cscript defer src=\"indexed-db.min.js\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cscript\u003e\n      const Database = IndexedDB.Database;\n      // Your script here\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Html 02\n\nBasic usage of `Model`\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003eIndexedDB app\u003c/title\u003e\n    \u003cscript src=\"indexed-db.min.js\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cscript\u003e\n      const db = new IndexedDB.Database({\n        databaseVersion: 1,\n        databaseName: 'MyNewDatabase',\n        tables: [\n          {\n            name: 'MyNewTable',\n            primaryKey: {\n              name: 'id',\n              autoIncrement: false,\n              unique: true,\n            },\n            initData: [],\n            indexes: {\n              username: { unique: false, autoIncrement: false },\n              password: { unique: false, autoIncrement: false },\n            },\n          },\n        ],\n      });\n      await db.connect();\n      // Add a new record\n      const model = db.useModel('MyNewTable');\n      model\n        .insert({\n          id: Math.random() * 10,\n          username: 'admin',\n          password: 'nimda',\n          createdAt: new Date(),\n          updatedAt: new Date(),\n        })\n        .then(function() {\n          console.info('Yay, you have saved the data.');\n        })\n        .catch(function(error) {\n          console.error(error);\n        });\n\n      // Get all results from the database\n      model.selectAll().then(function(results) {\n        console.log(...results);\n      });\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Javascript\n\n```javascript\nconst IndexedDB = require('@n1md7/indexeddb-promise');\nconst { Database } = IndexedDB;\n// or\nimport { Database } from '@n1md7/indexeddb-promise';\n```\n\n### TypeScript 01\n\n```javascript\nimport { Database } from '@n1md7/indexeddb-promise';\n\ninterface Users {\n  id?: number;\n  username: string;\n  password: string;\n}\n\nenum Priority {\n  LOW = 'LOW',\n  MEDIUM = 'MEDIUM',\n  HIGH = 'HIGH',\n}\n\ninterface ToDos {\n  id?: number;\n  userId: number;\n  title: string;\n  description: string;\n  done: boolean;\n  priority: Priority;\n}\n\nconst database = new Database({\n  version: 1,\n  name: 'Todo-list',\n  tables: [\n    {\n      name: 'users',\n      primaryKey: {\n        name: 'id',\n        autoIncrement: true,\n        unique: true,\n      },\n      indexes: {\n        username: {\n          unique: false,\n        },\n      },\n      timestamps: true,\n    },\n    {\n      name: 'todos',\n      primaryKey: {\n        name: 'id',\n        autoIncrement: true,\n        unique: true,\n      },\n      indexes: {\n        userId: {\n          unique: true,\n        },\n      },\n      timestamps: true,\n    },\n  ],\n});\n\n(async () =\u003e {\n  await database.connect();\n  const users = database.useModel\u003cUsers\u003e('users');\n  const user = await users.insert({\n    username: 'admin',\n    password: 'admin',\n  });\n  const todos = database.useModel\u003cToDos\u003e('todos');\n  await todos.insert({\n    userId: user.id,\n    title: 'Todo 1',\n    description: 'Description 1',\n    done: false,\n    priority: Priority.LOW,\n  });\n})();\n```\n\n### TypeScript decorators 02\n\n```javascript\nimport { Table, PrimaryKey, Indexed, Database } from '@n1md7/indexeddb-promise';\n\n@Table({ name: '__Name__', timestamps: true })\nclass SomeTable {\n  @PrimaryKey({ autoIncrement: true, unique: true })\n  id: number;\n\n  @Indexed({ unique: true, multiEntry: false })\n  username: string;\n\n  @Indexed({ unique: false })\n  age: number;\n\n  otherData: string;\n}\n\nconst anotherDb = new Database({\n  version: 1,\n  name: 'Other-DB',\n  tables: [SomeTable],\n});\nawait anotherDb.connect();\nconst model = anotherDb.useModel(SomeTable);\n\n(async () =\u003e {\n  await model\n    .insert({\n      username: 'John',\n      age: 20,\n      otherData: 'Some data',\n    })\n    .catch((error) =\u003e console.error(error));\n\n  model.selectAll().then((results) =\u003e {\n    if (results) {\n      results.forEach((result) =\u003e {\n        // result is inferred to be SomeTable\n        console.log(result.username);\n      });\n    }\n  });\n})();\n```\n\n### TypeScript decorators 02\n\n```javascript\nimport { Database, Indexed, PrimaryKey, Table } from '@n1md7/indexeddb-promise';\n\n@Table({ timestamps: true })\nclass User {\n  @PrimaryKey({ autoIncrement: true, unique: true })\n  id: number;\n\n  @Indexed({ unique: true, multiEntry: false })\n  username: string;\n\n  @Indexed()\n  password: string;\n\n  toString() {\n    return `#${this.id} ${this.username}`;\n  }\n}\n\n@Table()\nclass Info {\n  @PrimaryKey({ autoIncrement: true, unique: true })\n  id: number;\n\n  @Indexed()\n  userId: number;\n\n  name: {\n    first: string,\n    last: string,\n  };\n\n  age: number;\n\n  occupation: string;\n\n  toString() {\n    return `${this.name.first} ${this.name.last} ${this.age} years old - ${this.occupation}`;\n  }\n}\n\nconst store = new Database({\n  version: 1,\n  name: 'Store',\n  tables: [User, Info],\n});\n\nawait store.connect();\n\nconst userModel = store.useModel(User);\nconst infoModel = store.useModel(Info);\n\n(async () =\u003e {\n  const savedUser = await userModel.insert({\n    username: 'admin',\n    password: 'admin',\n  });\n\n  await infoModel.insert({\n    userId: savedUser.id,\n    name: {\n      first: 'John',\n      last: 'Doe',\n    },\n    age: 27,\n    occupation: 'Web Developer',\n  });\n})().catch(console.log);\n\n(async () =\u003e {\n  const user = await userModel.selectByIndex('username', 'admin');\n  if (!user) throw new Error('User not found');\n\n  const info = await infoModel.select({ where: { userId: user.id } });\n  if (!info) throw new Error('Info not found');\n\n  console.log(user.toString() + ' - ' + info.toString());\n})().catch(console.log);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fn1md7%2Findexeddb-promise","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fn1md7%2Findexeddb-promise","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fn1md7%2Findexeddb-promise/lists"}