{"id":13452530,"url":"https://github.com/neurosnap/robodux","last_synced_at":"2025-07-30T21:34:43.733Z","repository":{"id":38272142,"uuid":"147455904","full_name":"neurosnap/robodux","owner":"neurosnap","description":"caching in redux made simple","archived":false,"fork":false,"pushed_at":"2023-10-07T08:46:56.000Z","size":1169,"stargazers_count":101,"open_issues_count":8,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-07-15T05:28:00.750Z","etag":null,"topics":["caching","javascript","react","reactjs","redux"],"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/neurosnap.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-09-05T03:43:32.000Z","updated_at":"2024-12-09T23:50:42.000Z","dependencies_parsed_at":"2024-01-16T03:46:28.487Z","dependency_job_id":"89d46696-49c0-47ad-a892-ba5b08239a3a","html_url":"https://github.com/neurosnap/robodux","commit_stats":{"total_commits":198,"total_committers":6,"mean_commits":33.0,"dds":"0.36868686868686873","last_synced_commit":"c41283f03ad7eea11544902f9000575438dcd2ab"},"previous_names":[],"tags_count":45,"template":false,"template_full_name":null,"purl":"pkg:github/neurosnap/robodux","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neurosnap%2Frobodux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neurosnap%2Frobodux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neurosnap%2Frobodux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neurosnap%2Frobodux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neurosnap","download_url":"https://codeload.github.com/neurosnap/robodux/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neurosnap%2Frobodux/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267945313,"owners_count":24170216,"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","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["caching","javascript","react","reactjs","redux"],"created_at":"2024-07-31T07:01:26.687Z","updated_at":"2025-07-30T21:34:43.702Z","avatar_url":"https://github.com/neurosnap.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# robodux\n\n[![ci](https://github.com/neurosnap/robodux/actions/workflows/ci.yml/badge.svg)](https://github.com/neurosnap/robodux/actions/workflows/ci.yml)\n\n- [Documentation](./docs/index.md)\n- [Example repo](https://github.com/neurosnap/listifi)\n- [Style guide](https://erock.io/2020/01/01/redux-saga-style-guide.html)\n\nOne of the biggest complaints developers have with redux is the amount of\nboilerplate and new concepts they have to learn to use it. By using the\n`robodux` pattern the amount of redux boilerplate is dramatically reduced. In\nmost cases, wiring up action types, action creators, and reducers can be done in\none line of code.\n\n## Features\n\n- Create actions, reducer, and selectors for common data structures\n- Automates the boring parts of redux\n- Dramatically reduces redux boilerplate\n- Works well with [saga-query](https://github.com/neurosnap/saga-query)\n\n## What's included\n\n- [createTable](./docs/basic-concepts.md#createtable): Thinking of reducers as\n  database tables, this function builds actions, reducer, and selectors that\n  builds simple and repeatable operations for that table.\n- [createAssign](./docs/basic-concepts.md#createassign): A catch-all data\n  structure that makes it easy to set or reset the reducer.\n- [createList](./docs/basic-concepts.md#createlist): Store an array of items in\n  a slice\n- [createLoaderTable](./docs/basic-concepts.md#createloadertable): Store as many\n  independent loaders in this reducer which are all accessible by an `id`.\n- [createSlice](./docs/api.md#createslice): Core function that the above slice\n  helpers leverage. Build action types, action creators, and reducer pairs with\n  one simple function.\n- [and more!](./docs/api.md)\n\n## Core principles\n\nThe overriding principle is that effects (like sagas) should be the central\nprocessing unit for all business logic in a react/redux application. We should\nremove as much business logic as possible from reducers and instead centralize\nthem inside of our side-effect handlers.\n\nThe other primary principle is to think of redux as a database and reducers as\ntables. This simplifies the action/reducer logic and makes it possible to build\nreuseable components which dramatically reducers boilerplate.\n\nPlease see [style-guide](https://erock.io/redux-saga-style-guide) for more\ndetails.\n\n## Getting started\n\n```bash\nyarn add robodux\n```\n\n### Usage\n\nThe primary philosophical change between this library and other libraries is to\nthink of your redux store as a database.\n\nReducers are database tables and operating on those tables should have a\nconsistent API for managing them.\n\n`robodux` has a few slice helpers that cover ~90% of the logic and data\nstructures needed to build and scale your state.\n\nThese are one-line functions that create action types, action creators, and\nreducers using a simple set of lower-level functions. There's no magic here,\nit's more of how we think about our state that has made it dramatically simple\nto automate repetitive tasks in redux.\n\nOne of the more useful APIs from this library is `createTable`. This slice\nhelper creates a reducer and a set of actions that make it easy to treat a slice\nas a database table.\n\n```ts\nimport { combineReducers, createStore } from 'redux';\nimport { createTable, createReducerMap, MapEntity } from 'robodux';\n\n// setup reducer state\ninterface Comment {\n  message: string;\n  timestamp: number;\n}\n\ninterface State {\n  comments: MapEntity\u003cComment\u003e;\n}\n\n// create reducer and actions\nconst comments = createTable\u003cComment\u003e({ name: 'comments' });\n\n// converts multiple slices into an object of reducers to be used with combineReducers\n// { comments: (state, action) =\u003e state }\nconst reducers = createReducerMap(comments);\nconst rootReducer = combineReducers(reducers);\nconst store = createStore(rootReducer);\n\n// dispatch action to add a record to our table\nstore.dispatch(\n  actions.add({\n    1: { message: 'you awake?', timestamp: 1577117359 },\n  }),\n);\n// { comments: { 1: { message: 'you awake?', timestamp: 1577117359 } } }\n\nstore.dispatch(\n  actions.patch({\n    1: { message: 'Are you awake?' },\n  }),\n);\n// { comments: { 1: { message: 'Are you awake?', timestamp: 1577117359 } } }\n\nconst selectors = comments.getSelectors((state) =\u003e state[comments.name]);\n\nconst state = store.getState();\nconst commentMap = selectors.selectTable(state);\nconst commentList = selectors.selectTableAsList(state);\nconst commentOne = selectors.selectById(state, { id: '1' });\nconst foundComments = selectors.selectByIds(state, { ids: ['1', '3'] });\n```\n\n## References\n\n- [saga-query](https://github.com/neurosnap/saga-query)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneurosnap%2Frobodux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneurosnap%2Frobodux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneurosnap%2Frobodux/lists"}