{"id":16322136,"url":"https://github.com/1999/sklad","last_synced_at":"2025-03-16T14:31:02.729Z","repository":{"id":8160346,"uuid":"9581712","full_name":"1999/sklad","owner":"1999","description":"Promise-based API for IndexedDB","archived":false,"fork":false,"pushed_at":"2023-03-02T06:43:32.000Z","size":1734,"stargazers_count":47,"open_issues_count":24,"forks_count":12,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-14T05:32:16.185Z","etag":null,"topics":["html5","indexeddb","javascript"],"latest_commit_sha":null,"homepage":"http://1999.github.io/sklad","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/1999.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2013-04-21T15:56:04.000Z","updated_at":"2023-12-29T17:16:39.000Z","dependencies_parsed_at":"2024-09-25T06:18:50.815Z","dependency_job_id":"677cf644-f399-4bda-aef1-1d49b4d0f576","html_url":"https://github.com/1999/sklad","commit_stats":{"total_commits":201,"total_committers":7,"mean_commits":"28.714285714285715","dds":0.5422885572139303,"last_synced_commit":"6aa3479b4e9704e7ca0ed2f0fcf050440ca823b1"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1999%2Fsklad","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1999%2Fsklad/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1999%2Fsklad/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1999%2Fsklad/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/1999","download_url":"https://codeload.github.com/1999/sklad/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243818195,"owners_count":20352629,"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":["html5","indexeddb","javascript"],"created_at":"2024-10-10T22:50:04.737Z","updated_at":"2025-03-16T14:31:02.280Z","avatar_url":"https://github.com/1999.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sklad: Promise-based API for IndexedDB\n\n[![Build Status](https://img.shields.io/travis/1999/sklad/master.svg)](https://travis-ci.org/1999/sklad)\n[![DevDependency Status](http://img.shields.io/david/dev/1999/sklad/master.svg)](https://david-dm.org/1999/sklad#info=devDependencies)\n[![Greenkeeper badge](https://badges.greenkeeper.io/1999/sklad.svg)](https://greenkeeper.io/)\n\nSklad library makes work with IndexedDB less weird by providing a tiny Promise-based API on top of IndexedDB. If your browser doesn't support promises you can include [polyfill](https://www.npmjs.com/package/promise-polyfill) for this.\n\nStarting from 4.0.0 Sklad library is working in all major browsers: Chrome, Firefox, IE11, Microsoft Edge, Safari9 and Android browser. Still there are some browser issues for IE11, Microsoft Edge and Safari9 which can't be patched inside library. Read [changelog](https://github.com/1999/sklad/blob/master/CHANGELOG.md#400) for more info.\n\nIf you're using Sklad with a bundler like Webpack or Rollup, you can either `import sklad from 'sklad/es2015'` or even import as is if your bundler supports [jsnext:main](https://github.com/rollup/rollup/wiki/jsnext:main). Otherwise UMD code will be used.\n\n## Open database ([details](https://github.com/1999/sklad/blob/master/docs/README_sklad_open.md))\n```javascript\nconst conn = await sklad.open(dbName, {\n    version: 2,\n    migration: {\n        '1': (database) =\u003e {\n            // This migration part starts when your code runs first time in the browser.\n            // This is a migration from \"didn't exist\" to \"1\" database version\n            const objStore = database.createObjectStore('users', {autoIncrement: true});\n            objStore.createIndex('fb_search', 'facebook_id', {unique: true});\n        },\n        '2': (database) =\u003e {\n            // This migration part starts when your database migrates from \"1\" to \"2\" version\n            const objStore = database.createObjectStore('users_likes', {keyPath: 'date'});\n        }\n    }\n});\n```\n\n## Insert one or multiple records ([details](https://github.com/1999/sklad/blob/master/docs/README_skladConnection_insert.md))\n```javascript\nconst conn = await sklad.open(dbName, options);\n\n// insert one document into store\nconst insertedKey = await conn.insert(objStoreName, 'hello world');\n\n// insert data into multiple stores inside one transaction\nconst insertedKeys = await conn.insert({\n    users: [\n        {email: 'example1@gmail.com', firstname: 'John'},\n        {email: 'example2@gmail.com', firstname: 'Jack'},\n        {email: 'example3@gmail.com', firstname: 'Peter'},\n    ],\n    foo_obj_store: ['truly', 'madly', 'deeply']\n});\n\nassert.equal(insertedKeys, {\n    users: [id1, id2, id3],\n    foo_obj_store: [id4, id5, id6]\n});\n```\n\n## Upsert one or multiple records ([details](https://github.com/1999/sklad/blob/master/docs/README_skladConnection_upsert.md))\n```javascript\nconst conn = await sklad.open(dbName, options);\n\n// upsert one document inside store\nconst upsertedKey = await conn.upsert(objStoreName, {id: 'BMTH', bandMembersCount: 5})\n\n// upsert data in multiple stores inside one transaction\nconst upsertedKeys = await conn.upsert({\n    users: [\n        {email: 'example1@gmail.com', firstname: 'John'},\n        {email: 'example2@gmail.com', firstname: 'Jack'},\n        {email: 'example3@gmail.com', firstname: 'Peter'},\n    ],\n    foo_obj_store: ['truly', 'madly', 'deeply']\n});\n\nassert.equal(insertedKeys, {\n    users: [id1, id2, id3],\n    foo_obj_store: [id4, id5, id6]\n});\n```\n\n## Delete one or mutiple records ([details](https://github.com/1999/sklad/blob/master/docs/README_skladConnection_delete.md))\n```javascript\nconst conn = await sklad.open(dbName, options);\n\n// delete document from the object store\nawait conn.delete(objStoreName, 'key');\n\n// delete multiple documents from different object stores inside one transaction\nawait conn.delete({\n    objStoreName1: ['key_1', 'key_2', 'key_3'],\n    objStoreName2: ['key1']\n});\n```\n\n## Clear one or multiple object stores ([details](https://github.com/1999/sklad/blob/master/docs/README_skladConnection_clear.md))\n```javascript\nconst conn = await sklad.open(dbName, options);\n\n// clear everything in one object store\nawait conn.clear(objStoreName);\n\n// clear everything in multiple object stores\nawait conn.clear([objStoreName1, objStoreName2]);\n```\n\n## Get records from the object store(s) ([details](https://github.com/1999/sklad/blob/master/docs/README_skladConnection_get.md))\nBeware: if you use `index` or `direction` options in your request then fast `IDBObjectStore.prototype.getAll()` API is not used. This is still okay in most cases. More info [here](https://github.com/1999/sklad/releases/tag/4.1.0).\n\n```javascript\nconst conn = await sklad.open(dbName, options);\n\n// get documents from one object store\nconst resOneStore = await conn.get(objStoreName, {\n    index: 'missing_index', // index name, optional\n    direction: sklad.ASC_UNIQUE, // one of: ASC, ASC_UNIQUE, DESC, DESC_UNIQUE, optional\n    limit: 4, // optional\n    offset: 1, // optional\n    range: IDBKeyRange.only('some_key') // range, instance of IDBKeyRange, optional\n});\n\nassert.equal(resOneStore, {\n    [objStoreName]: [\n        {key: ..., value: ...},\n        {key: ..., value: ...},\n        ...\n    ]\n});\n\n// get documents from multiple stores in one transaction\nconst resMultipleStores = await conn.get({\n    objStoreName1: {},\n    objStoreName1: {limit: 1, offset: 1}\n});\n\nassert.equal(resMultipleStores, {\n    objStoreName1: [{key: ..., value: ...}, ...],\n    objStoreName2: [{key: ..., value: ...}, ...]\n});\n```\n\n## Count objects in the object store(s) ([details](https://github.com/1999/sklad/blob/master/docs/README_skladConnection_count.md))\n```javascript\nconst conn = await sklad.open(dbName, options);\n\n// count documents inside one object store\nconst total = await conn.count(objStoreName, {\n    range: IDBKeyRange.bound(x, y, true, true), // range, instance of IDBKeyRange, optional\n    index: 'index_name' // index name, optional\n});\n\n// count documents inside multiple object stores\nconst res = await conn.count({\n    objStoreName1: null,\n    objStoreName2: {index: 'index_name'}\n});\n\nassert.equal(res, {\n    objStoreName1: NUMBER_OF_DOCUMENTS_INSIDE_objStoreName1,\n    objStoreName2: NUMBER_OF_DOCUMENTS_INSIDE_objStoreName2\n});\n```\n\n## Close existing database connection ([details](https://github.com/1999/sklad/blob/master/docs/README_skladConnection_close.md))\n```javascript\nconst conn = await sklad.open(dbName, options);\nconn.close(); // it's sync\n```\n\n## Delete database\n```javascript\nawait sklad.deleteDatabase(dbName)\n```\n\n# Structuring the database\nYou can specify `keyPath` and `autoIncrement` fields in `IDBDatabase.prototype.createObjectStore()` inside migration code. **Key path** (`keyPath`) is just a name of the field inside the objects which you store in the object store. For instance, it can be `foo` for object `{foo: 'bar'}`. **Key generator** (`autoIncrement`) is just a name for auto incrementing counter which is used as a primary key. Both of them (key path and key generator) can be used as primary keys for the records stored in the object stores.\n\nMore info on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#Structuring_the_database).\n\n## key path used, no key generator (objects with mandatory field)\n```javascript\nconst objStore = database.createObjectStore('obj_store_title', {keyPath: 'field_name'});\n```\nIn this case you **must** store **only objects** in the object store. You **can** specify `field_name` in the stored objects and its value will be used as a primary key for them. If you don't specify it, Sklad library will generate this field's value for you.\n\n**SAMPLE USE CASE:** a database of users with unique logins and each user can be represented as an object with fields \"firstname\", \"lastname\", \"login\", \"phone\" etc.\n\n## no key path, key generator used (any data, autoincremented primary key)\n```javascript\nconst objStore = database.createObjectStore('obj_store_title', {autoIncrement: true});\n```\nIn this case you **can** store any type of data in the object store. Primary key for the new created record will be generated by the auto incrementing key generator, but you also **can** specify your own primary key like this:\n```javascript\nconst data = sklad.keyValue('your_unique_key', value);\ndatabase.insert('obj_store_title', data).then(...);\n```\n\n**SAMPLE USE CASE:** a simple set of data or even hierarchical objects which don't need a special field to be unique.\n\n## key path used, key generator used (objects with optional primary key field)\n```javascript\nconst objStore = database.createObjectStore('obj_store_title', {\n    keyPath: 'field_name',\n    autoIncrement: true\n});\n```\nIn this case you **must** store only objects in the object store. You **can** specify `field_name` in the stored objects and its value will be used as a primary key for them. If you don't specify it, its value will be an auto incremented value produced by the key generator.\n\n**SAMPLE USE CASE:** set of hierarchical objects, which don't have a unique field.\n\n## no keypath, no key generator (any data, primary key anarchy)\n```javascript\nconst objStore = database.createObjectStore('obj_store_title');\n```\nIn this case you **can** store **any type of data** in the object store. You **can** also specify a key to be used as a primary key for the record like this:\n```javascript\nvar data = sklad.keyValue('your_unique_key', value);\ndatabase.insert('obj_store_title', data).then(...);\n```\n\nOtherwise Sklad library will generate this value for you.\n\n**SAMPLE USE CASE:** non-structured data with a need for your own primary keys.\n\n# Examples\n[Detailed docs](https://github.com/1999/sklad/tree/master/docs) contain nice pieces of code using Sklad library.\n\n# Tests\nTests are written with Jasmine testing framework and run with Karma runner. You need to have SauceLabs account to run tests in multiple browsers.\n\n# Development/release process\n * Watcher is started with `yarn watch`\n * Release files are built with `yarn release`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F1999%2Fsklad","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F1999%2Fsklad","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F1999%2Fsklad/lists"}