{"id":18475904,"url":"https://github.com/mariuslundgard/opstore","last_synced_at":"2025-07-05T19:03:50.857Z","repository":{"id":57315793,"uuid":"87696303","full_name":"mariuslundgard/opstore","owner":"mariuslundgard","description":"An immutable operator-based state container for JavaScript.","archived":false,"fork":false,"pushed_at":"2019-05-31T23:21:32.000Z","size":194,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-09-24T05:18:15.809Z","etag":null,"topics":["immutable-datastructures","javascript","state-management","store"],"latest_commit_sha":null,"homepage":"","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/mariuslundgard.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}},"created_at":"2017-04-09T09:10:37.000Z","updated_at":"2019-05-31T23:21:34.000Z","dependencies_parsed_at":"2022-09-18T20:52:21.927Z","dependency_job_id":null,"html_url":"https://github.com/mariuslundgard/opstore","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariuslundgard%2Fopstore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariuslundgard%2Fopstore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariuslundgard%2Fopstore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariuslundgard%2Fopstore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mariuslundgard","download_url":"https://codeload.github.com/mariuslundgard/opstore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223320021,"owners_count":17126008,"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":["immutable-datastructures","javascript","state-management","store"],"created_at":"2024-11-06T10:35:39.805Z","updated_at":"2024-11-06T10:35:40.009Z","avatar_url":"https://github.com/mariuslundgard.png","language":"TypeScript","readme":"# opstore\n\nAn immutable operator-based state container for JavaScript.\n\n```sh\nnpm install opstore\n```\n\n[![build status](https://img.shields.io/travis/mariuslundgard/opstore/master.svg?style=flat-square)](https://travis-ci.org/mariuslundgard/opstore)\n[![coverage status](https://img.shields.io/coveralls/mariuslundgard/opstore/master.svg?style=flat-square)](https://coveralls.io/github/mariuslundgard/opstore?branch=master)\n[![npm version](https://img.shields.io/npm/v/opstore.svg?style=flat-square)](https://www.npmjs.com/package/opstore)\n\n## Features\n\n* **Single source of truth.** Data is stored in a single, immutable atom.\n* **Composable.** Keep sizes small and roll your own store by only bundling the operators you need.\n* **Extensible.** Add your own operators and middleware.\n* **Observable.** Subscribe to partial and/or every state change.\n* **Message-driven.** Every operation is dispatched internally as a message, which enables such things as logging and\n  event sourcing by way of middleware.\n* **Typed.** Written in TypeScript.\n\n## Motivation\n\n`opstore` was built to make it easier to build “vanilla” web apps. Being able to listen to state changes in certain part\nof the state tree, makes it possible to create tiny render cycles that are simple to reason about and perform well.\n\nThis project is based on ideas from [Redux](http://redux.js.org/), [Redis](https://redis.io/),\n[Firebase](https://firebase.google.com/) and [Yr](https://www.yr.no/en)’s source code.\n\n## Usage\n\n### Out of the box\n\n```js\nimport {createStore} from 'opstore'\n\nconst store = createStore({count: 0})\nconst countRef = store.ref('count')\n\ncountRef.subscribe(count =\u003e console.log(count))\n\nconsole.log(countRef.get()) // 0\n\ncountRef.incr() // 1\ncountRef.incr() // 2\ncountRef.decr() // 1\ncountRef.decr() // 0\n```\n\n### Composing a store\n\n```js\nimport {createFactory, lpush, lremi} from 'opstore'\n\nconst createStore = createFactory({lpush, lremi})\n\nconst store = createStore({\n  todos: []\n})\n\nconst todosRef = store.ref('todos')\n\ntodosRef.subscribe(todos =\u003e console.log(JSON.stringify(todos)))\n\nconsole.log(JSON.stringify(store.get())) // []\ntodosRef.lpush({title: 'A'}) // [{\"title\":\"A\"}]\ntodosRef.lpush({title: 'B'}) // [{\"title\":\"A\"},{\"title\":\"B\"}]\ntodosRef.lremi(0) // [{\"title\":\"B\"}]\n```\n\n## Documentation\n\nSee [API Documentation](API.md).\n\n## License\n\nMIT © [Marius Lundgård](https://mariuslundgard.com)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmariuslundgard%2Fopstore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmariuslundgard%2Fopstore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmariuslundgard%2Fopstore/lists"}