1 | # action-u
|
2 |
|
3 | The action-u library provides a utility that auto generates your
|
4 | [redux] [action creators], and introduces organization to your
|
5 | [actions] through a JSON-based [ActionStruct]. This structure
|
6 | instinctively groups related actions, implicitly defines your action
|
7 | types, and seamlessly promotes both [action creators] and action types
|
8 | throughout your application. This automates a tedious process, and
|
9 | promotes an overall organization to your actions.
|
10 |
|
11 |
|
12 | [![Build Status](https://travis-ci.org/KevinAst/action-u.svg?branch=master)](https://travis-ci.org/KevinAst/action-u)
|
13 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/ab82e305bb24440281337ca3a1a732c0)](https://www.codacy.com/app/KevinAst/action-u?utm_source=github.com&utm_medium=referral&utm_content=KevinAst/action-u&utm_campaign=Badge_Grade)
|
14 | [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/ab82e305bb24440281337ca3a1a732c0)](https://www.codacy.com/app/KevinAst/action-u?utm_source=github.com&utm_medium=referral&utm_content=KevinAst/action-u&utm_campaign=Badge_Coverage)
|
15 | [![Known Vulnerabilities](https://snyk.io/test/github/kevinast/action-u/badge.svg)](https://snyk.io/test/github/kevinast/action-u)
|
16 | [![NPM Version Badge](https://img.shields.io/npm/v/action-u.svg)](https://www.npmjs.com/package/action-u)
|
17 |
|
18 |
|
19 | ## Install
|
20 |
|
21 | ```shell
|
22 | npm install --save action-u
|
23 | ```
|
24 |
|
25 |
|
26 | ## Sample
|
27 |
|
28 | As a simple example, let's say we want to facilitate an activity to
|
29 | display a user message. We will need:
|
30 | - an action to display the message in a dialog,
|
31 | - and a corresponding action to close the dialog.
|
32 |
|
33 |
|
34 | **Generation**:
|
35 |
|
36 | By simply knowing the properties of each action, we can auto-generate
|
37 | our needed [ActionStruct] as follows:
|
38 |
|
39 | ```js
|
40 | import {generateActions} from 'action-u';
|
41 |
|
42 | const actions = generateActions({
|
43 | userMsg: {
|
44 | display: {
|
45 | actionMeta: {
|
46 | traits: ['msg']
|
47 | }
|
48 | },
|
49 | close: {
|
50 | actionMeta: {}
|
51 | }
|
52 | }
|
53 | });
|
54 | ```
|
55 |
|
56 | Because our two actions are inner-related, we packaged them in an
|
57 | app-specific structure that highlights these relationship through it's
|
58 | shape. The `actions` [ActionStruct] *(returned above)* conceptually
|
59 | looks like this:
|
60 |
|
61 | ```js
|
62 | const actions = { // auto-generated (from generateActions() - above)
|
63 | userMsg {
|
64 | display(msg): {},
|
65 | close(): {},
|
66 | }
|
67 | };
|
68 | ```
|
69 |
|
70 | 1. The **action creator** signatures are shown, but their
|
71 | implementations are omitted.
|
72 |
|
73 | - `actions.userMsg.display(msg)` is the **1st action creator**, and
|
74 | accepts a single `msg` parameter
|
75 |
|
76 | - `actions.userMsg.close()` is the **2nd action creator**, and
|
77 | accepts no parameters
|
78 |
|
79 | 1. The **action types** are implied from the JSON structure, and are
|
80 | promoted through a string coercion of the action creator function
|
81 | itself (the function's toString() has been overloaded).
|
82 |
|
83 | In many contexts, this coercion happens implicitly *(such as
|
84 | astx-redux-util reducerHash())*, while in other cases it must be
|
85 | explicitly done *(for example, the case of a switch statement)*.
|
86 |
|
87 | ```js
|
88 | String(actions.userMsg.display) // yields: 'userMsg.display'
|
89 | ''+actions.userMsg.close // yields: 'userMsg.close'
|
90 | ```
|
91 |
|
92 | **A Closer Look**
|
93 |
|
94 | The following diagram summarizes the generation process
|
95 |
|
96 | ![userMsg](docs/img/userMsg.png)
|
97 |
|
98 | 1. The [generateActions] function accepts a single
|
99 | [ActionGenesis] parameter that:
|
100 |
|
101 | - defines one or more action creators
|
102 |
|
103 | - implies the action types from the JSON structure
|
104 |
|
105 | - defines the overall [ActionStruct] organization
|
106 |
|
107 | 1. [ActionNodes] (ones that promote action creator functions) are defined
|
108 | through the [actionMeta] property.
|
109 |
|
110 | - The [actionMeta.traits] property is a string array
|
111 | that defines *both* the parameter names (of the action creator)
|
112 | and ultimately the property names of the action (returned from
|
113 | the action creator).
|
114 |
|
115 | - An empty [actionMeta] object (see `close`) merely defines an
|
116 | action creator with NO parameters, and consequently no action
|
117 | payload properties.
|
118 |
|
119 | - There are more [actionMeta] properties that are discussed in the
|
120 | full documentation.
|
121 |
|
122 | **Formatting Preference**: So as to not confuse the [actionMeta]
|
123 | property with app-level nodes, I prefer to indent them a bit deeper in
|
124 | the structure *(you are free to disregard this advice)*.
|
125 |
|
126 | 1. All other nodes (like `userMsg`) are merely intermediate nodes that
|
127 | organize (i.e. add meaning) to the overall shape of the action
|
128 | structure.
|
129 |
|
130 |
|
131 | **Usage**:
|
132 |
|
133 | Here is how the generated [ActionStruct] *(above)* is used:
|
134 |
|
135 | ```js
|
136 | // action creators ...
|
137 | const userMsg = actions.userMsg.display('Hello action-u');
|
138 | // yields the following action (which can be dispatched):
|
139 | // {
|
140 | // type: 'userMsg.display',
|
141 | // msg: 'Hello action-u'
|
142 | // }
|
143 |
|
144 | const closeIt = actions.userMsg.close();
|
145 | // yields the following action (which can be dispatched):
|
146 | // {
|
147 | // type: 'userMsg.close'
|
148 | // }
|
149 |
|
150 | // action types (typically used in reducers) ...
|
151 | console.log(`First type is '${actions.userMsg.display}'`); // First type is 'userMsg.display'
|
152 | console.log(`Second type is '${actions.userMsg.close}'`); // Second type is 'userMsg.close'
|
153 | ```
|
154 |
|
155 |
|
156 | ## Comprehensive Documentation
|
157 |
|
158 | The sample above just scratches the service!
|
159 |
|
160 | **Comprehensive Documentation** can be found at https://action-u.js.org/,
|
161 | which includes both a **Dev Guide** *(building concepts with full and
|
162 | thorough **examples**)*, and a complete **API Reference**.
|
163 |
|
164 | There is much more to cover in fully understanding this utility,
|
165 | including:
|
166 |
|
167 | - [ActionStruct Shapes] ... there is a lot of flexibility in how you
|
168 | organize your [ActionStruct]
|
169 |
|
170 | - [Parameter Validation] ... learn how to inject app-specific
|
171 | validation
|
172 |
|
173 | - [Defaulting Parameters] ... learn how to apply default semantics to
|
174 | your action creator parameters
|
175 |
|
176 | - [Thunk Action Creators] ... learn how to integrate thunks into
|
177 | action-u
|
178 |
|
179 | - [Action Promotion] ... options to maintain and promote the
|
180 | actions within your application
|
181 |
|
182 | - [Action Documentation] ... considerations for documenting your
|
183 | actions
|
184 |
|
185 | - [API Reference] ... and *(of course)* the complete functional **API
|
186 | Reference**
|
187 |
|
188 |
|
189 | The action-u library was pulled from a sandbox project
|
190 | ([GeekU](https://github.com/KevinAst/GeekU)) that I use to study
|
191 | several technologies and frameworks.
|
192 |
|
193 | I hope you enjoy this effort, and comments are always welcome.
|
194 |
|
195 | </Kevin>
|
196 |
|
197 |
|
198 |
|
199 | [action-u]: https://action-u.js.org/
|
200 | [Getting Started]: https://action-u.js.org/start.html
|
201 | [Basics]: https://action-u.js.org/basics.html
|
202 | [A Closer Look]: https://action-u.js.org/formalTypes.html
|
203 | [ActionStruct Shapes]: https://action-u.js.org/shapes.html
|
204 | [Parameter Validation]: https://action-u.js.org/validation.html
|
205 | [Defaulting Parameters]: https://action-u.js.org/default.html
|
206 | [Thunk Action Creators]: https://action-u.js.org/thunks.html
|
207 | [Action Promotion]: https://action-u.js.org/promotion.html
|
208 | [Action Documentation]: https://action-u.js.org/actionDoc.html
|
209 | [Distribution]: https://action-u.js.org/dist.html
|
210 | [Why action-u?]: https://action-u.js.org/why.html
|
211 | [Revision History]: https://action-u.js.org/history.html
|
212 | [MIT License]: https://action-u.js.org/LICENSE.html
|
213 | [API Reference]: https://action-u.js.org/api.html
|
214 | [generateActions]: https://action-u.js.org/api.html#generateActions
|
215 | [ActionNodes]: https://action-u.js.org/api.html#ActionNodes
|
216 | [ActionGenesis]: https://action-u.js.org/api.html#ActionGenesis
|
217 | [actionMeta]: https://action-u.js.org/api.html#ActionMeta
|
218 | [actionMeta.traits]: https://action-u.js.org/api.html#ActionMeta
|
219 | [ActionStruct]: https://action-u.js.org/api.html#ActionStruct
|
220 | [redux]: http://redux.js.org/
|
221 | [actions]: http://redux.js.org/docs/basics/Actions.html
|
222 | [action creators]: http://redux.js.org/docs/basics/Actions.html#action-creators
|