{"id":20046375,"url":"https://github.com/aneldev/dynadux","last_synced_at":"2025-05-05T09:31:37.528Z","repository":{"id":38618699,"uuid":"243208857","full_name":"aneldev/dynadux","owner":"aneldev","description":"Advanced and simpler Stores based on dispatch and Reducers. Alternative to Redux.","archived":false,"fork":false,"pushed_at":"2024-10-29T16:12:04.000Z","size":2513,"stargazers_count":15,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-06T07:47:52.363Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.dynadux.org","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/aneldev.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":"2020-02-26T08:25:32.000Z","updated_at":"2024-09-02T17:05:08.000Z","dependencies_parsed_at":"2024-04-02T10:46:18.781Z","dependency_job_id":null,"html_url":"https://github.com/aneldev/dynadux","commit_stats":{"total_commits":215,"total_committers":3,"mean_commits":71.66666666666667,"dds":"0.31162790697674414","last_synced_commit":"fbefd3fc46e3cd2952f1f4818b21f82331d2a872"},"previous_names":[],"tags_count":85,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aneldev%2Fdynadux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aneldev%2Fdynadux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aneldev%2Fdynadux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aneldev%2Fdynadux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aneldev","download_url":"https://codeload.github.com/aneldev/dynadux/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224437604,"owners_count":17311036,"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":[],"created_at":"2024-11-13T11:23:22.769Z","updated_at":"2024-11-13T11:23:23.775Z","avatar_url":"https://github.com/aneldev.png","language":"TypeScript","readme":"![Dynadux Logo](doc/assets/dynadux-logo.png)\n\n##### Table of Contents  \n* [What is Dynadux](#whatIs)  \n* [How does it work?](#howItWorks)  \n* [Motivation](#motivation)  \n* [Create a Store](#createAStore)  \n* [Create a Business Store](#createABusinessStore)  \n* [Architecture](#architecture)  \n* [API](doc/API.md)\n    * [Create store](doc/API-CreateStore.md)\n    * [Reducers](doc/API-Reducers.md)\n    * [Dispatch](doc/API-Dispatch.md)\n    * [Middlewares](doc/API-Middlewares.md)\n    * [Sections](doc/API-Sections.md)\n    * [Debugging](doc/API-Debugging.md)\n* [Use it in React](./doc/React.md)\n* [Examples](./doc/Examples.md)\n* [Advanced](./doc/Advanced.md)\n    * [Dispatch Promises](doc/Advanced-DispatchPromises.md)\n    * [Block Changes (and renders)](doc/Advanced-BlockChanges.md)\n    * [Debounce Changes](doc/Advanced-DebounceChanges.md) _and React renders_\n    * [Create 3rd party Library](doc/Advanced-Create3rdPartyLibrary.md)\n    * [Understanding Dispatches in Reducer](doc/Advanced-UnderstandingDispatchesInReducer.md)\n* [Typescript](./doc/Typescript.md)\n* [Terminology](./doc/Terminology.md)\n* [Change Log](doc/Change-Log.md)\n* [FAQ](./doc/FAQ.md)\n\n\u003ca name=\"whatIs\"/\u003e\n\n# What is Dynadux\n\nAdvanced and straightforward Stores based on dispatched Actions and Reducers.\n\nDynadux is an alternative to Redux, and it reduces Redux's boilerplate.\n\nIt can work for NodeJs libraries, React/Vue Apps, or React Components without complementary libraries.\n\nDynadux works with any UI layer.\n\nSuper light, zero dependencies, 2.2kb zipped bundle effort.\n\n[See the live examples](./doc/Examples.md).\n\n\u003ca name=\"howItWorks\"/\u003e\n\n# How does it work?\n\nIn general \n- You dispatch actions\n- Dynadux is calling the reducers and middlewares\n- Dynadux is calling the `onChange` callback with the new state\n\n\u003ca name=\"motivation\"/\u003e\n\n# Motivation\n\n## Benefits to working with Dynadux instead of classic setState\n\n- Reusable State Management.\n- The use of pure reducer functions.\n- Centralizing the state makes.\n- Debuggable.\n- History of the changes.\n\n[Benefits instead of Redux](doc/InsteadOfRedux.md).\n\n# Install\n```\nnpm install dynadux\n```\nor\n```\nyarn add dynadux\n```\nTypes are already there. _Dynadux is written in TypeScript._\n\n# Import\n```\nimport {createStore} from \"dynadux\";\n```\nEverything of Dynadux is imported with `{} from \"dynadux`, _no default exports_.\n\n\u003ca name=\"createAStore\"/\u003e\n\n# Create a Store\nThis is the store to add and remove todo items.\n\n```\nconst actions = {\n  ADD_TODO: 'ADD_TODO',\n  REMOVE_TODO: 'REMOVE_TODO',\n};\n\nconst store = createStore({\n    initialState: {\n        todos: [],\n    },\n    reducers: {\n          [actions.ADD_TODO]: ({state: {todos}, payload}) =\u003e {\n            return {\n              todos: todos.concat(payload),\n            };\n          },\n          [actions.REMOVE_TODO]: ({state: {todos}, payload: todoId}) =\u003e {\n            return {\n              todos: todos.filter(todo =\u003e todo.id !== todoId),\n            };\n          },\n    },\n    onChange: (state) =\u003e console.log('State changed:', state),\n});\n```\nNow lets add a todo\n```\nstore.dispatch(actions.ADD_TODO, {id: '234', label: 'Drink beers'}});\n```\nLet's remove this todo\n```\nstore.dispatch(actions.REMOVE_TODO, '234');\n```\nOn every change the `onChange` will be called with the above code will be consoled.\n\n\u003ca name=\"createABusinessStore\"/\u003e\n\n# Create a Business Store (Dynadux's approach)\n\nCreate business logic stores and methods.\n\n\u003e Note: this is a suggestion, not mandatory.\n\nIt is nice to have a store and dispatch actions, but we can do something more.\n\n## What is Business Store\n\nThe Business Store is a function that\n- creates a Dynadux store that is used internally in this function only\n- we pass to the Dynadux the initial state and the actions/reducers dictionary object \n- the function returns an object with methods and getters, and this is the API of our Business store\n\nThe containers and any other components will use these getters and functions. \n\n## The principals\n\n- wrap the create Dynadux store\n- return a getter for the state\n- return business logic methods that dispatch actions\n- do not expose the dispatch _but expose methods that dispatch actions_\n- do not expose the store _to ensure that the store handled properly_\n\n```\nconst createTodoAppStore = (onChange) =\u003e {\n    const store = createStore({\n        initialState: {\n            todos: [],\n        },\n        reducers: {\n              [actions.ADD_TODO]: ({state: {todos}, payload}) =\u003e {\n                return {\n                  todos: todos.concat(payload),\n                };\n              },\n              [actions.REMOVE_TODO]: ({state: {todos}, payload: todoId}) =\u003e {\n                return {\n                  todos: todos.filter(todo =\u003e todo.id !== todoId),\n                };\n              },\n        },\n        onChange,\n    });\n\n    return {\n        get state() { return store.state; },\n        addTodo: (todo) =\u003e store.dispatch(actions.ADD_TODO, todo),\n        removeTodo: (todoId) =\u003e store.dispatch(actions.REMOVE_TODO, todoId),\n    };\n};\n\n```\nThis is a function that creates the store and provides business logic methods. The `addTodo` \u0026 the `removeTodo`.\n\n## Usage of the Bussiness Store\n\nNow our `store` it won't be directly a `dynadux` store but a more sophisticated business one.\n\n```\nconst store = createTodoAppStore(state =\u003e console.log('State change:', state));\n\n```\n\nAnd we can add a todo in a more business logic way.\n\n```\nstore.addTodo({id: '121', label: 'Drink beers'});\n```\n\nAnd remove it in a more straightforward way.\n\n```\nstore.removeTodo('121');\n```\n\nFor React components the store should be instantiated in constructor.\n```\nconst store = createTodoAppStore(() =\u003e this.setState({}));\n\n```\n\nThen pass the `store` to children and use the `store.state` for the state.\n\nIt is not needed to pass the entire store to the children, only pass what is needed.\n\n## Benefits of Business stores\n\nIn the Business store approach, the Containers are not dispatching actions, but they use the methods of the store.\n\nThe action would be dispatched from any container. But some actions are for the internal use of the reducers. \nAlso, each action requires a specific type of payload. But from the action's user perspective it is unclear which payload type should be used.\n\nAll these problems are solved providing to the containers javascript methods that do all this job. These are the Business methods provided by the app store that is wrapping the Dynadux store.\n\nIn the end, only business methods, reducers, and middlewares are dispatching actions. That makes the code much cleaner, and the actions can be used safely. \n\n## Redux/Dynadux Containers Connection Comparison\n\n![Redux/Dynadux Containers Connection Comparison](doc/assets/dynadux-redux-container-connection-compare.png)\n\n[Diagram](https://drive.google.com/file/d/1SWPbCHS5I8YCdTeCbNMUm8Nfy3eEgu59/view?usp=sharing)\n\n# That's all\n\nThe logic of Dynadux depicted in the text above. \n\nThere is nothing more. Portable and straightforward, use your imagination and create Business Stores.\n\n\u003ca name=\"architecture\"/\u003e\n\n# Dynadux's Architecture\n\n**Dynadux is an elementary library.** Technically the Dynadux is only an \n\n`Object.assign({}, state, middleware.before(), reducer(), middleware.after())`\n\nAnd nothing else! Since it is small and straightforward, we can use it in the architecture of Business Stores. \n\n\u003ca name=\"api\"/\u003e\n\n# API\n\n## Just for App State Management\n\nThat's enough to setup an Application State Management.\n\n- [Create store](doc/API-CreateStore.md)\n- [Reducers](doc/API-Reducers.md)\n- [Sections](doc/API-Sections.md)\n\n## Complete guide\n\nComplete guide including middlewares and debugging.\n\n- [Create store](doc/API-CreateStore.md)\n- [Reducers](doc/API-Reducers.md)\n- [Middlewares](doc/API-Middlewares.md)\n- [Sections](doc/API-Sections.md)\n- [Debugging](doc/API-Debugging.md)\n\n# What's next? The future of Dynadux.\n\nFeel free. Dynadux is simple and straightforward state management. **There are no plans to introduce new API or features because simplicity matters.**\n\nDynadux has no dependencies, so no need to maintain them. Dynadux is running on large production projects, and most of the fixes are already applied.\n\nImprovements and updates will be for\n\n- `react-dynadux` package where is Dynadux Provider for React components\n- Current and new 3rd party Sections\n- but ont for the Dynadux itself.\n\n\u003ca name=\"readMore\"/\u003e\n\n# Read more \n\n- [FAQ](./doc/FAQ.md) Frequently asked questions\n- [Use it in React](./doc/React.md) How to use it in react\n- [Examples](./doc/Examples.md) Live examples. Examples compared to redux's implementations\n- [Advanced](./doc/Advanced.md) Dispached promises, boost up your app and more\n- [Typescript](./doc/Typescript.md) Tips for Typescript implementations\n- [Terminology](./doc/Terminology.md) Terminology of dynadux, (is small!)\n- [History, Undo/Redo](https://github.com/aneldev/dynadux-history-middleware) Middleware for History, Undo/Redo and Restore Points\n- [React Dynadux](https://github.com/aneldev/react-dynadux) Provider for Dynadux App Stores\n- [Change Log](./doc/Change-Log.md) Changes of Dynadux per semver version\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faneldev%2Fdynadux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faneldev%2Fdynadux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faneldev%2Fdynadux/lists"}