{"id":15373173,"url":"https://github.com/otiai10/localstorm","last_synced_at":"2025-10-17T16:05:08.268Z","repository":{"id":62716151,"uuid":"561105919","full_name":"otiai10/localstorm","owner":"otiai10","description":"ORM (Object-Relation Mapper) for LocalStorage of your browsers.","archived":false,"fork":false,"pushed_at":"2024-07-18T08:13:45.000Z","size":2331,"stargazers_count":6,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T21:03:42.434Z","etag":null,"topics":["browser","chrome","firefox","javascript","localstorage","localstorage-crud","localstorage-wrapper","npm","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/localstorm","language":"TypeScript","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/otiai10.png","metadata":{"files":{"readme":"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":"2022-11-03T00:43:10.000Z","updated_at":"2024-07-18T08:13:49.000Z","dependencies_parsed_at":"2024-11-08T11:02:56.905Z","dependency_job_id":"037e42e2-a441-47cc-b137-8cad7a9552d6","html_url":"https://github.com/otiai10/localstorm","commit_stats":{"total_commits":318,"total_committers":2,"mean_commits":159.0,"dds":0.1352201257861635,"last_synced_commit":"675a875decf93c0b0f111ec264b1c9cf3c169d5e"},"previous_names":["otiai10/active-storage"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otiai10%2Flocalstorm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otiai10%2Flocalstorm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otiai10%2Flocalstorm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otiai10%2Flocalstorm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/otiai10","download_url":"https://codeload.github.com/otiai10/localstorm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647251,"owners_count":21139081,"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":["browser","chrome","firefox","javascript","localstorage","localstorage-crud","localstorage-wrapper","npm","typescript"],"created_at":"2024-10-01T13:54:26.242Z","updated_at":"2025-10-17T16:05:03.225Z","avatar_url":"https://github.com/otiai10.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Project Transfer Notice: Please check [jstorm](https://github.com/otiai10/jstorm)\n\n[**localstorm**](https://github.com/otiai10/localstorm) has been officially transferred to the [**jstorm**](https://github.com/otiai10/jstorm). This transfer aims to ensure the continuous development and improvement of the project to support more usecases.\n\n## Important Links\n\n* [NPM Package: `jstorm`](https://www.npmjs.com/package/jstorm)\n* [GitHub Repository](https://github.com/otiai10/jstorm)\n\n## Compatibility\n\nTo use `jstorm` with `localStorage`, you can simply try:\n\n```javascript\nimport { Model } from \"jstorm/browser/local\";\n// Then, all the same with localstorm ;)\n```\n\n-----\n\u003cbr\u003e\u003cbr\u003e\n\nlocalstorm\n========\n\nObject/Relation Mapper for LocalStorage.\n\n[![npm](https://img.shields.io/npm/v/localstorm)](https://www.npmjs.com/package/localstorm)\n[![npm downloads](https://img.shields.io/npm/dy/localstorm)](https://www.npmjs.com/package/localstorm)\n[![Node.js CI](https://github.com/otiai10/localstorm/actions/workflows/node.js.yml/badge.svg)](https://github.com/otiai10/localstorm/actions/workflows/node.js.yml)\n[![codecov](https://codecov.io/github/otiai10/localstorm/branch/main/graph/badge.svg?token=aEjM39lnwW)](https://codecov.io/github/otiai10/localstorm)\n\n# Installation\n\n```sh\nnpm install localstorm\n```\n\n# Model\n\n`Model` is an ORM (Object-Relation Mapper) for `localStorage`, providing simple interfaces like `ActiveRecord`.\n\n\u003e NOTE: `Model` is NOT the best efficient accessor for `localStorage`, BUT provides the best small and easy way to manage `localStorage` and automatically map the object to your `Model` class.\n\n- Methods\n  - [new](#new)\n  - [save](#save)\n  - [find](#find)\n  - [update](#update)\n  - [delete](#delete)\n  - [create](#create)\n  - [all](#all)\n  - [list](#list)\n  - [filter](#filter)\n- Properties\n  - [schema](#schema)\n  - [nextID](#nextID)\n\n# How to use\n\n```js\nclass Player extends Model {}\nlet player = new Player({name: 'otiai10', age: 31});\nplayer.name // 'otiai10'\nplayer.age // 31\nplayer._id // undefined, because not saved yet\n\nplayer.save();\nplayer._id // 1, because it's saved to localStorage\n```\n\nMore complicated models with relations? See [`schema`](#schema)!\n\n# Methods\n\n## new\n\n- static\n- an alias for `constructor`\n\n```js\nlet player = Player.new({name: 'otiai20', age: 43});\nplayer.name // 'otiai10'\nplayer.age // 31\nplayer._id // undefined, because not saved yet\n```\n\n## save\n\n```js\nlet player = new Player({name: 'otiai20'});\nplayer.save();\nplayer._id // 2\n```\n\n## find\n\n- static\n\n```js\nlet player = Player.find(2);\nplayer.name // 'otiai10'\n```\n\n## update\n\n```js\nplayer.update({name: 'otiai22'});\nPlayer.find(player._id).name // 'otiai22'\n```\n\n## delete\n\n```js\nplayer.delete();\nPlayer.find(player._id) // undefined\n```\n\n## create\n\n- static\n- an alias for `new` and `save`\n\n```js\nlet player = Player.create({name: 'otiai99', age: 99});\nplayer._id // 3\n\n// Is equivalent to\nPlayer.new({name: 'otiai99'}).save();\n```\n\n## all\n\n- static\n- returns everything as a dictionary\n\n```js\nconst dict = Player.all(); // Object\ndict[1].name // 'otiai10'\ndict[1] instanceof Player // true\n```\n\n## list\n\n- static\n- returns everything as an array\n\n```js\nconst players = Player.list(); // [Player]\nplayers.length // 2\n\n// Is equivalent to\nPlayer.filter(() =\u003e true);\n```\n\n## filter\n\n- static\n- returns filtered array by filterFunc\n\n```js\nconst players = Player.filter(p =\u003e p.age \u003c 40);\nplayers.length // 1\n```\n\n## useStorage\n\n- static\n- replace storage with anything which satisfies Storage interface\n\n```js\nModel.useStorage(window.sessionStorage);\n\n// For example, you can embed any extra operation for getItem/setItem/removeItem\nconst storage = new MyStorageWithEffortAsyncPushing();\nModel.useStorage(storage);\n```\n\n# Properties\n\n## schema\n\n- static\n- optional, default `undefined`\n- can define validations for each props of this model\n- no validations, if `schema` is not set\n\n```js\nclass Player extends Model {\n  static schema = {\n    name: Model.Types.string.isRequired,\n    age:  Model.Types.number, // optional\n    location: Model.Types.shape({\n      address: Model.Types.string,\n      visible: Model.Types.bool.isRequired,\n    }),\n  }\n}\n```\n\nwith relations\n\n```js\nclass Team extends Model {\n  static schema = {\n    name: Model.Types.string.isRequired,\n    leader: Model.Types.reference(Player),\n    members: Model.Types.arrayOf(Model.Types.reference(Player)),\n  }\n}\n```\n\n## nextID\n\n- static\n- optional, default `timestampID`\n- replace it if you want to change algorythm of generating next id\n\n```js\nPlayer.nextID = () =\u003e Date.now();\nPlayer.create({name: 'otiai2017'})._id // 1488061388247\nPlayer.create({name: 'otiai1986'})._id // 1488061388928\n```\n\n# Types\n\n`Types` API provides followings:\n\n1. Validation data type of `Model` when it's saved.\n2. Resolving relationship of `Model`s.\n\n# Examples\n\n```js\nimport {Model, Types} from \"localstorm\";\n\nclass User extends Model {\n  protected static schema = {\n    name: Types.string.isRequired,\n    age: Types.number,\n    langs: Types.arrayOf(Types.string),\n  }\n}\n\nclass Team extends Model {\n  protected static schema = {\n    name: Types.string.isRequired,\n    active: Types.bool.isRequired,\n    address: Types.shape({\n      country: Types.string,\n      street: Types.string,\n      postcode: Types.number,\n    }),\n    leader: Types.reference(User, {eager: true}),\n    members: Types.arrayOf(Types.reference(User)),\n    roles: Types.dictOf(Types.reference(User)),\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fotiai10%2Flocalstorm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fotiai10%2Flocalstorm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fotiai10%2Flocalstorm/lists"}