{"id":15026030,"url":"https://github.com/gruns/immortaldb","last_synced_at":"2025-05-14T12:08:36.771Z","repository":{"id":39562939,"uuid":"154541438","full_name":"gruns/ImmortalDB","owner":"gruns","description":":nut_and_bolt: A relentless key-value store for the browser.","archived":false,"fork":false,"pushed_at":"2023-01-06T01:36:32.000Z","size":2050,"stargazers_count":3057,"open_issues_count":39,"forks_count":62,"subscribers_count":30,"default_branch":"master","last_synced_at":"2025-04-11T04:57:47.390Z","etag":null,"topics":["cookies","database","indexeddb","javascript","key-value","key-value-database","key-value-store","library","localstorage","sessionstorage","storage"],"latest_commit_sha":null,"homepage":"","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/gruns.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.txt","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-24T17:29:42.000Z","updated_at":"2025-03-31T15:22:16.000Z","dependencies_parsed_at":"2023-02-05T01:45:59.249Z","dependency_job_id":null,"html_url":"https://github.com/gruns/ImmortalDB","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruns%2FImmortalDB","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruns%2FImmortalDB/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruns%2FImmortalDB/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruns%2FImmortalDB/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gruns","download_url":"https://codeload.github.com/gruns/ImmortalDB/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248345273,"owners_count":21088244,"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":["cookies","database","indexeddb","javascript","key-value","key-value-database","key-value-store","library","localstorage","sessionstorage","storage"],"created_at":"2024-09-24T20:03:34.500Z","updated_at":"2025-05-14T12:08:36.760Z","avatar_url":"https://github.com/gruns.png","language":"JavaScript","readme":"\u003ch1\u003e\n  \u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"logo.png\" width=\"260px\" height=\"435px\" alt=\"ImmortalDB\"\u003e\n  \u003c/div\u003e\n\n  ImmortalDB\n\u003c/h1\u003e\n\n\n### ImmortalDB is a resilient key-value store for the browser.\n\nImmortalDB is the best way to store persistent key-value data in the\nbrowser. Data saved to ImmortalDB is redundantly stored in\n[Cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies),\n[IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API), and\n[LocalStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage),\nand relentlessly self heals if any data therein is deleted or corrupted.\n\nFor example, clearing cookies is a common user action, even for non-technical\nusers. And browsers unceremoniously\n[delete](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria#LRU_policy)\nIndexedDB, LocalStorage, and/or SessionStorage without warning under storage\npressure.\n\nImmortalDB is resilient in the face of such events.\n\nIn this way, ImmortalDB is like\n[Evercookie](https://github.com/samyk/evercookie), but\n\n  1. Provides a simple, modern, [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)-based API.\n\n  2. Strikes an equitable balance between reliability and respect for the\n     user. Data is stored reliably but can also be voluntarily purged if the\n     user designedly clears cookies and application storage.\n\n  3. Doesn't use nefarious exploits nor deprecated third party plugins like\n     Flash, Silverlight, or Java. Only standard, ratified HTML5 APIs are used.\n\n  4. Doesn't vandalize performance or the user experience. For example,\n     Evercookie's CSS History Knocking can beget a deluge of background HTTP\n     requests, and loading Silverlight or Flash can raise unsought permission\n     modals or thrash the user's disk.\n\n\n### How ImmortalDB works.\n\nWhen you store a key-value pair in ImmortalDB, that key and value are\nsaved redundantly in the browser's cookies, IndexedDB, and LocalStorage\ndata stores.\n\nWhen a value is retrieved via its key, ImmortalDB\n\n  1. Looks up that key in every data store.\n  2. Counts each unique returned value.\n  3. Determines the most commonly returned unique value as the 'correct' value.\n  4. Returns this correct value.\n\nThen ImmortalDB self-heals: if any data store(s) returned a value different than\nthe determined correct value, or no value at all, the correct value is rewritten\nto that store. In this way, consensus, reliability, and redundancy is\nmaintained.\n\n\n### API\n\n#### Set\n\nImmortalDB's API is simple. To store a value, use `set(key, value)`:\n\n```javascript\nimport { ImmortalDB } from 'immortal-db'\n\nawait ImmortalDB.set('key', 'value')\n```\n\n`key` and `value` must be\n[DOMStrings](https://developer.mozilla.org/en-US/docs/Web/API/DOMString).\n`ImmortalDB.set(key, value)` also always returns `value`, so it can be chained or\nembedded, like\n\n```javascript\nconst countPlusOne = (await ImmortalDB.set('count', numberOfClowns)) + 1\n```\n\n#### Get\n\nTo retrieve a value, use `get(key, default=null)`:\n\n```javascript\nconst value = await ImmortalDB.get('key', default=null)\n```\n\n`get()` returns the value associated with `key`, if `key` exists. If `key`\ndoesn't exist, `default` is returned. `key` must be a\n[DOMString](https://developer.mozilla.org/en-US/docs/Web/API/DOMString).\n\n#### Remove\n\nFinally, to remove a key, use `remove(key)`:\n\n```javascript\nImmortalDB.set('hi', 'bonjour')\nconsole.log(await ImmortalDB.get('hi'))  // Prints 'bonjour'.\n\nawait ImmortalDB.remove('hi')\n\nconsole.log(await ImmortalDB.get('hi'))  // Prints 'null'.\n```\n\n`key` must be a\n[DOMString](https://developer.mozilla.org/en-US/docs/Web/API/DOMString).\n\n#### Data Stores\n\nThe data stores that ImmortalDB stores data in can also be configured.\nFor example, this is how to store data reliably in cookies and\nLocalStorage only:\n\n```javascript\nimport { ImmortalStorage, CookieStore, LocalStorageStore } from 'immortal-db'\n\nconst stores = [await CookieStore(), await LocalStorageStore()]\nconst db = new ImmortalStorage(stores)\n\nawait db.set(key, JSON.stringify({1:1}))\n```\n\nBy default, stores used by `ImmortalDB` are:\n\n  - `CookieStore` -\u003e Keys and values are stored in `document.cookie`.\n  - `IndexedDbStore` -\u003e Keys and values are stored in `window.indexedDB`.\n  - `LocalStorageStore` -\u003e Keys and values are stored in `window.localStorage`.\n\nOther, optional stores are:\n\n  - `SessionStorageStore` -\u003e Keys and values are stored in `window.sessionStorage`.\n\nNew storage implementations can easily be added, too; they need only\nimplement the async methods `get(key, default)`, `set(key, value)`, and\n`remove(key)`.\n\n\n### Installation\n\nInstalling ImmortalDB with npm is easy.\n\n```\n$ npm install immortal-db\n```\n\nOr include `dist/immortal-db[.min].js` and use `window.ImmortalDB` directly.\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cscript src=\"immortal-db.min.js\"\u003e\u003c/script\u003e\n    \u003cscript\u003e\n\n      ;(async () =\u003e {\n        const db = ImmortalDB.ImmortalDB\n        await db.set('hi', 'lolsup')\n      })()\n\n    \u003c/script\u003e\n  \u003c/head\u003e\n\n  ...\n\u003c/html\u003e\n```\n\n\n### Development\n\nTo test ImmortalDB, run\n\n```\nnpm run start\n```\n\nThis starts a [webpack](https://webpack.js.org/) dev server and opens\nImmortalDB's testing website,\n[http://localhost:9234/](http://localhost:9234/).\n\nOnce tested, to produce new production-ready files `immortal-db.js` and\n`immortal-db.min.js` in `dist/`, run\n\n```\nnpm run build\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgruns%2Fimmortaldb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgruns%2Fimmortaldb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgruns%2Fimmortaldb/lists"}