{"id":20495317,"url":"https://github.com/kevinast/action-u","last_synced_at":"2026-04-19T00:33:14.216Z","repository":{"id":57172772,"uuid":"89506068","full_name":"KevinAst/action-u","owner":"KevinAst","description":"Redux Action Promotion (providing action creator generation, implicit action types, and overall action organization)","archived":false,"fork":false,"pushed_at":"2017-05-30T17:11:42.000Z","size":1126,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-16T07:03:00.682Z","etag":null,"topics":["action-creator-generation","action-organization","redux","redux-actions"],"latest_commit_sha":null,"homepage":"https://action-u.js.org/","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/KevinAst.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}},"created_at":"2017-04-26T16:58:37.000Z","updated_at":"2021-01-29T06:04:11.000Z","dependencies_parsed_at":"2022-08-24T14:41:07.697Z","dependency_job_id":null,"html_url":"https://github.com/KevinAst/action-u","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinAst%2Faction-u","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinAst%2Faction-u/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinAst%2Faction-u/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinAst%2Faction-u/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KevinAst","download_url":"https://codeload.github.com/KevinAst/action-u/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242077458,"owners_count":20068364,"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":["action-creator-generation","action-organization","redux","redux-actions"],"created_at":"2024-11-15T17:45:26.215Z","updated_at":"2026-04-19T00:33:14.172Z","avatar_url":"https://github.com/KevinAst.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# action-u\n\nThe action-u library provides a utility that auto generates your\n[redux] [action creators], and introduces organization to your\n[actions] through a JSON-based [ActionStruct].  This structure\ninstinctively groups related actions, implicitly defines your action\ntypes, and seamlessly promotes both [action creators] and action types\nthroughout your application.  This automates a tedious process, and\npromotes an overall organization to your actions.\n\n\u003c!--- Badges for CI Builds ---\u003e \n[![Build Status](https://travis-ci.org/KevinAst/action-u.svg?branch=master)](https://travis-ci.org/KevinAst/action-u)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/ab82e305bb24440281337ca3a1a732c0)](https://www.codacy.com/app/KevinAst/action-u?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=KevinAst/action-u\u0026amp;utm_campaign=Badge_Grade)\n[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/ab82e305bb24440281337ca3a1a732c0)](https://www.codacy.com/app/KevinAst/action-u?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=KevinAst/action-u\u0026amp;utm_campaign=Badge_Coverage)\n[![Known Vulnerabilities](https://snyk.io/test/github/kevinast/action-u/badge.svg)](https://snyk.io/test/github/kevinast/action-u)\n[![NPM Version Badge](https://img.shields.io/npm/v/action-u.svg)](https://www.npmjs.com/package/action-u)\n\n\n## Install\n\n```shell\nnpm install --save action-u\n```\n\n\n## Sample\n\nAs a simple example, let's say we want to facilitate an activity to\ndisplay a user message.  We will need:\n- an action to display the message in a dialog, \n- and a corresponding action to close the dialog.\n\n\n**Generation**:\n\nBy simply knowing the properties of each action, we can auto-generate\nour needed [ActionStruct] as follows:\n\n```js\nimport {generateActions} from 'action-u';\n\nconst actions = generateActions({\n  userMsg: {\n    display: {\n                actionMeta: {\n                  traits: ['msg']\n                }\n    },\n    close: {\n                actionMeta: {}\n    }\n  }\n});\n```\n\nBecause our two actions are inner-related, we packaged them in an\napp-specific structure that highlights these relationship through it's\nshape.  The `actions` [ActionStruct] *(returned above)* conceptually\nlooks like this:\n\n```js\nconst actions = { // auto-generated (from generateActions() - above)\n  userMsg {\n    display(msg): {},\n    close():      {},\n  }\n};\n```\n\n1. The **action creator** signatures are shown, but their\n   implementations are omitted.\n\n   - `actions.userMsg.display(msg)` is the **1st action creator**, and\n     accepts a single `msg` parameter\n\n   - `actions.userMsg.close()` is the **2nd action creator**, and\n      accepts no parameters\n\n1. The **action types** are implied from the JSON structure, and are\n   promoted through a string coercion of the action creator function\n   itself (the function's toString() has been overloaded).\n\n   In many contexts, this coercion happens implicitly *(such as\n   astx-redux-util reducerHash())*, while in other cases it must be\n   explicitly done *(for example, the case of a switch statement)*.\n\n   ```js\n   String(actions.userMsg.display) // yields: 'userMsg.display'\n   ''+actions.userMsg.close        // yields: 'userMsg.close'\n   ```\n\n**A Closer Look**\n\nThe following diagram summarizes the generation process\n\n![userMsg](docs/img/userMsg.png)\n\n1. The [generateActions] function accepts a single\n   [ActionGenesis] parameter that:\n\n   - defines one or more action creators\n\n   - implies the action types from the JSON structure\n\n   - defines the overall [ActionStruct] organization \n\n1. [ActionNodes] (ones that promote action creator functions) are defined\n   through the [actionMeta] property.\n\n   - The [actionMeta.traits] property is a string array\n     that defines *both* the parameter names (of the action creator)\n     and ultimately the property names of the action (returned from\n     the action creator).\n\n   - An empty [actionMeta] object (see `close`) merely defines an\n     action creator with NO parameters, and consequently no action\n     payload properties.\n\n   - There are more [actionMeta] properties that are discussed in the\n     full documentation.\n\n     **Formatting Preference**: So as to not confuse the [actionMeta]\n     property with app-level nodes, I prefer to indent them a bit deeper in\n     the structure *(you are free to disregard this advice)*.\n\n1. All other nodes (like `userMsg`) are merely intermediate nodes that\n   organize (i.e. add meaning) to the overall shape of the action\n   structure.\n\n\n**Usage**:\n\nHere is how the generated [ActionStruct] *(above)* is used:\n\n```js\n// action creators ...\nconst userMsg = actions.userMsg.display('Hello action-u');\n      // yields the following action (which can be dispatched):\n      //   {\n      //     type: 'userMsg.display',\n      //     msg:  'Hello action-u'\n      //   }\n\nconst closeIt = actions.userMsg.close();\n      // yields the following action (which can be dispatched):\n      //   {\n      //     type: 'userMsg.close'\n      //   }\n\n// action types (typically used in reducers) ...\nconsole.log(`First  type is '${actions.userMsg.display}'`); // First  type is 'userMsg.display'\nconsole.log(`Second type is '${actions.userMsg.close}'`);   // Second type is 'userMsg.close'\n```\n\n\n## Comprehensive Documentation\n\nThe sample above just scratches the service!\n\n**Comprehensive Documentation** can be found at https://action-u.js.org/,\nwhich includes both a **Dev Guide** *(building concepts with full and\nthorough **examples**)*, and a complete **API Reference**.\n\nThere is much more to cover in fully understanding this utility,\nincluding:\n\n- [ActionStruct Shapes] ... there is a lot of flexibility in how you\n  organize your [ActionStruct]\n\n- [Parameter Validation] ... learn how to inject app-specific\n  validation\n\n- [Defaulting Parameters] ... learn how to apply default semantics to\n  your action creator parameters\n\n- [Thunk Action Creators] ... learn how to integrate thunks into\n  action-u\n\n- [Action Promotion] ... options to maintain and promote the\n  actions within your application\n\n- [Action Documentation] ... considerations for documenting your\n  actions\n\n- [API Reference] ... and *(of course)* the complete functional **API\n  Reference**\n\n\nThe action-u library was pulled from a sandbox project\n([GeekU](https://github.com/KevinAst/GeekU)) that I use to study\nseveral technologies and frameworks.\n\nI hope you enjoy this effort, and comments are always welcome.\n\n\u0026lt;/Kevin\u0026gt;\n\n\n\n[action-u]:               https://action-u.js.org/\n[Getting Started]:        https://action-u.js.org/start.html\n[Basics]:                 https://action-u.js.org/basics.html\n[A Closer Look]:          https://action-u.js.org/formalTypes.html\n[ActionStruct Shapes]:    https://action-u.js.org/shapes.html\n[Parameter Validation]:   https://action-u.js.org/validation.html\n[Defaulting Parameters]:  https://action-u.js.org/default.html\n[Thunk Action Creators]:  https://action-u.js.org/thunks.html\n[Action Promotion]:       https://action-u.js.org/promotion.html\n[Action Documentation]:   https://action-u.js.org/actionDoc.html\n[Distribution]:           https://action-u.js.org/dist.html\n[Why action-u?]:          https://action-u.js.org/why.html\n[Revision History]:       https://action-u.js.org/history.html\n[MIT License]:            https://action-u.js.org/LICENSE.html\n[API Reference]:          https://action-u.js.org/api.html\n[generateActions]:        https://action-u.js.org/api.html#generateActions\n[ActionNodes]:            https://action-u.js.org/api.html#ActionNodes\n[ActionGenesis]:          https://action-u.js.org/api.html#ActionGenesis\n[actionMeta]:             https://action-u.js.org/api.html#ActionMeta\n[actionMeta.traits]:      https://action-u.js.org/api.html#ActionMeta\n[ActionStruct]:           https://action-u.js.org/api.html#ActionStruct\n[redux]:                  http://redux.js.org/\n[actions]:                http://redux.js.org/docs/basics/Actions.html\n[action creators]:        http://redux.js.org/docs/basics/Actions.html#action-creators\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinast%2Faction-u","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevinast%2Faction-u","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinast%2Faction-u/lists"}