rename leftover from * to +
This commit is contained in:
parent
9778e04a8d
commit
6dd8b1af9e
File diff suppressed because one or more lines are too long
@ -1 +1,3 @@
|
||||
<!DOCTYPE html><html class="default no-js"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>"updux" | Updux</title><meta name="description" content="Documentation for Updux"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script async src="../assets/search.js" id="search-script"></script></head><body><header><div class="tsd-page-toolbar"><div class="container"><div class="table-wrap"><div class="table-cell" id="tsd-search" data-base=".."><div class="field"><label for="tsd-search-field" class="tsd-widget search no-caption">Search</label><input type="text" id="tsd-search-field"/></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">Updux</a></div><div class="table-cell" id="tsd-widgets"><div id="tsd-filter"><a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a><div class="tsd-filter-group"><div class="tsd-select" id="tsd-filter-visibility"><span class="tsd-select-label">All</span><ul class="tsd-select-list"><li data-value="public">Public</li><li data-value="protected">Public/Protected</li><li data-value="private" class="selected">All</li></ul></div> <input type="checkbox" id="tsd-filter-inherited" checked/><label class="tsd-widget" for="tsd-filter-inherited">Inherited</label></div></div><a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a></div></div></div></div><div class="tsd-page-title"><div class="container"><ul class="tsd-breadcrumb"><li><a href="../modules.html">Updux</a></li><li><a href="_updux_.html">"updux"</a></li></ul><h1>Namespace "updux"</h1></div></div></header><div class="container container-main"><div class="row"><div class="col-8 col-content"><section class="tsd-panel-group tsd-index-group"><h2>Index</h2><section class="tsd-panel tsd-index-panel"><div class="tsd-index-content"><section class="tsd-index-section "><h3>Classes</h3><ul class="tsd-index-list"><li class="tsd-kind-class tsd-parent-kind-namespace tsd-has-type-parameter"><a href="../classes/_updux_.Updux.html" class="tsd-kind-icon">Updux</a></li></ul></section><section class="tsd-index-section "><h3>Interfaces</h3><ul class="tsd-index-list"><li class="tsd-kind-interface tsd-parent-kind-namespace tsd-has-type-parameter"><a href="../interfaces/_updux_.UpduxConfig.html" class="tsd-kind-icon">Updux<wbr/>Config</a></li></ul></section></div></section></section></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class=""><a href="../modules.html">Exports</a></li><li class="current tsd-kind-namespace"><a href="_updux_.html">"updux"</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul><li class="tsd-kind-class tsd-parent-kind-namespace tsd-has-type-parameter"><a href="../classes/_updux_.Updux.html" class="tsd-kind-icon">Updux</a></li><li class="tsd-kind-interface tsd-parent-kind-namespace tsd-has-type-parameter"><a href="../interfaces/_updux_.UpduxConfig.html" class="tsd-kind-icon">Updux<wbr/>Config</a></li></ul></nav></div></div></div><footer class="with-border-bottom"><div class="container"><h2>Settings</h2><p>Theme <select id="theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></p></div></footer><div class="container tsd-generator"><p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></div><div class="overlay"></div><script src="../assets/main.js"></script></body></html>
|
||||
<!DOCTYPE html><html class="default no-js"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>"updux" | Updux</title><meta name="description" content="Documentation for Updux"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script async src="../assets/search.js" id="search-script"></script></head><body><header><div class="tsd-page-toolbar"><div class="container"><div class="table-wrap"><div class="table-cell" id="tsd-search" data-base=".."><div class="field"><label for="tsd-search-field" class="tsd-widget search no-caption">Search</label><input type="text" id="tsd-search-field"/></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">Updux</a></div><div class="table-cell" id="tsd-widgets"><div id="tsd-filter"><a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a><div class="tsd-filter-group"><div class="tsd-select" id="tsd-filter-visibility"><span class="tsd-select-label">All</span><ul class="tsd-select-list"><li data-value="public">Public</li><li data-value="protected">Public/Protected</li><li data-value="private" class="selected">All</li></ul></div> <input type="checkbox" id="tsd-filter-inherited" checked/><label class="tsd-widget" for="tsd-filter-inherited">Inherited</label></div></div><a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a></div></div></div></div><div class="tsd-page-title"><div class="container"><ul class="tsd-breadcrumb"><li><a href="../modules.html">Updux</a></li><li><a href="_updux_.html">"updux"</a></li></ul><h1>Namespace "updux"</h1></div></div></header><div class="container container-main"><div class="row"><div class="col-8 col-content"><section class="tsd-panel-group tsd-index-group"><h2>Index</h2><section class="tsd-panel tsd-index-panel"><div class="tsd-index-content"><section class="tsd-index-section "><h3>Classes</h3><ul class="tsd-index-list"><li class="tsd-kind-class tsd-parent-kind-namespace tsd-has-type-parameter"><a href="../classes/_updux_.Updux.html" class="tsd-kind-icon">Updux</a></li></ul></section><section class="tsd-index-section "><h3>Interfaces</h3><ul class="tsd-index-list"><li class="tsd-kind-interface tsd-parent-kind-namespace tsd-has-type-parameter"><a href="../interfaces/_updux_.UpduxConfig.html" class="tsd-kind-icon">Updux<wbr/>Config</a></li></ul></section><section class="tsd-index-section "><h3>Functions</h3><ul class="tsd-index-list"><li class="tsd-kind-function tsd-parent-kind-namespace"><a href="_updux_.html#action" class="tsd-kind-icon">action</a></li></ul></section></div></section></section><section class="tsd-panel-group tsd-member-group "><h2>Functions</h2><section class="tsd-panel tsd-member tsd-kind-function tsd-parent-kind-namespace"><a name="action" class="tsd-anchor"></a><h3>action</h3><ul class="tsd-signatures tsd-kind-function tsd-parent-kind-namespace"><li class="tsd-signature tsd-kind-icon">action<span class="tsd-signature-symbol">(</span>type<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">string</span>, payloadFunction<span class="tsd-signature-symbol">?: </span><span class="tsd-signature-type">Function</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../modules.html#ActionGenerator" class="tsd-signature-type" data-tsd-kind="Type alias">ActionGenerator</a></li></ul><ul class="tsd-descriptions"><li class="tsd-description"><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
|
||||
<p>Creates an action generator.</p>
|
||||
</div></div><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameters"><li><h5>type: <span class="tsd-signature-type">string</span></h5></li><li><h5><span class="tsd-flag ts-flagOptional">Optional</span> payloadFunction: <span class="tsd-signature-type">Function</span></h5></li></ul><h4 class="tsd-returns-title">Returns <a href="../modules.html#ActionGenerator" class="tsd-signature-type" data-tsd-kind="Type alias">ActionGenerator</a></h4></li></ul></section></section></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class=""><a href="../modules.html">Exports</a></li><li class="current tsd-kind-namespace"><a href="_updux_.html">"updux"</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul><li class="tsd-kind-class tsd-parent-kind-namespace tsd-has-type-parameter"><a href="../classes/_updux_.Updux.html" class="tsd-kind-icon">Updux</a></li><li class="tsd-kind-interface tsd-parent-kind-namespace tsd-has-type-parameter"><a href="../interfaces/_updux_.UpduxConfig.html" class="tsd-kind-icon">Updux<wbr/>Config</a></li><li class="tsd-kind-function tsd-parent-kind-namespace"><a href="_updux_.html#action" class="tsd-kind-icon">action</a></li></ul></nav></div></div></div><footer class="with-border-bottom"><div class="container"><h2>Settings</h2><p>Theme <select id="theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></p></div></footer><div class="container tsd-generator"><p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></div><div class="overlay"></div><script src="../assets/main.js"></script></body></html>
|
@ -1,12 +1,32 @@
|
||||
# Updux concepts
|
||||
|
||||
## actions
|
||||
## Actions and action generators
|
||||
|
||||
Updux internally uses the package `ts-action` to create action creator
|
||||
functions. Even if you don't use Typescript, I recommend that you use it,
|
||||
as it does what it does very well. But if you don't want to, no big deal.
|
||||
Updux will recognize a function as an action creator if it has a `type`
|
||||
property. So a homegrown creator could be as simple as:
|
||||
Updux assumes actions following the format
|
||||
|
||||
```js
|
||||
{
|
||||
type: 'theTypeName',
|
||||
payload: {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The important part is having action parameters in the `payload` property. The
|
||||
actions can also have other properties, like `meta`. They are mostly ignored
|
||||
by Updux.
|
||||
|
||||
|
||||
Updux provides an action generator, but you can roll your own if you do wish.
|
||||
All it needs to do to be recognized as an action generator by Updux is
|
||||
|
||||
1. To be a function returning an action (a plain object with at least a
|
||||
`type` property).
|
||||
2. The function also needs to have a `type` property itself.
|
||||
|
||||
|
||||
For example, the following function would work:
|
||||
|
||||
```js
|
||||
function action(type) {
|
||||
@ -14,7 +34,36 @@ function action(type) {
|
||||
}
|
||||
```
|
||||
|
||||
## effects
|
||||
### Mutations
|
||||
|
||||
The transformations typically
|
||||
done by a Redux's reducer are called 'mutations' in Updux. A mutation is a
|
||||
function with the following signature:
|
||||
|
||||
```
|
||||
( payload, action ) => state => {
|
||||
// ... stuff done here
|
||||
return new_state;
|
||||
}
|
||||
```
|
||||
|
||||
The inversion and chaining of parameters from the usual Redux reducer's
|
||||
signature is there to work with updeep's curried nature. The expansion of
|
||||
the usual `action` into `(payload, action)` is present because in most cases
|
||||
`payload` is what we're interested in. So why not make it easily available?
|
||||
|
||||
### Leftover mutation
|
||||
|
||||
A mutation associated to the special action `+` will match any action that haven't been
|
||||
explicitly dealt with with any other defined mutation.
|
||||
|
||||
```
|
||||
todosUpdux.addMutation( '+', (payload,action) => state => {
|
||||
console.log("hey, action has no mutation! ", action.type);
|
||||
});
|
||||
```
|
||||
|
||||
## Effects
|
||||
|
||||
Updux effects are redux middlewares. I kept that format, and the
|
||||
use of `next` mostly because I wanted to give myself a way to alter
|
||||
|
140
docs/tutorial.md
140
docs/tutorial.md
@ -44,142 +44,40 @@ todosDux.setAction( 'addTodo' );
|
||||
todosDux.setAction( 'todoDone' );
|
||||
```
|
||||
|
||||
Now, there is a lot of ways to add actions to a Updux object.
|
||||
|
||||
It can be defined when the object is created:
|
||||
|
||||
```
|
||||
const todosUpdux = new Updux({
|
||||
actions: {
|
||||
add_todo,
|
||||
todo_done,
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
It can be done via the method `addAction`:
|
||||
|
||||
```
|
||||
todosUpdux.addAction(add_todo);
|
||||
```
|
||||
|
||||
Or it can be directly used in the definition of a mutation or effect, and will
|
||||
be automatically added to the Updux.
|
||||
|
||||
```
|
||||
todosUpdux.addMutation( add_todo, todoMutation );
|
||||
```
|
||||
|
||||
For TypeScript projects I recommend declaring the actions as part of the
|
||||
configuration passed to the constructors, as it makes them accessible to the class
|
||||
at compile-time, and allows Updux to auto-add them to its aggregated `actions` type.
|
||||
|
||||
```
|
||||
const todosUpdux = new Updux({
|
||||
actions: {
|
||||
add_todo,
|
||||
}
|
||||
});
|
||||
|
||||
todosUpdux.addAction(todo_done);
|
||||
|
||||
// only `add_todo` is visible to the type
|
||||
type MyActions = typeof todosUpdux.actions;
|
||||
// { add_todo: Function }
|
||||
|
||||
// but both actions are accessible at runtime
|
||||
const myAction = ( todosUpdux.actions as any).todo_done(1);
|
||||
```
|
||||
|
||||
### Accessing actions
|
||||
|
||||
Once an action is defined, its creator is accessible via the `actions` accessor.
|
||||
|
||||
```js
|
||||
console.log( todosDux.actions.addTodo('write tutorial') ); // prints { type: 'addTodo', payload: 'write tutorial' }
|
||||
```
|
||||
console.log( todosUpdux.actions.add_todo('write tutorial') );
|
||||
// { type: 'add_todo', payload: 'write tutorial' }
|
||||
```
|
||||
|
||||
### What is an action?
|
||||
|
||||
In this tutorial we use `ts-action` for all the work, but under the hood Updux defines actions via
|
||||
their creators, which are expected to be:
|
||||
|
||||
1. Functions,
|
||||
2. returning a plain object of the format `{ type: string; payload?: unknown }`.
|
||||
3. with an additional property `type`, which is also the action type.
|
||||
|
||||
For example, this is a perfectly cromulent action:
|
||||
|
||||
```
|
||||
const add_todo = description => ({ type: 'add_todo', payload: description});
|
||||
add_todo.type = 'add_todo';
|
||||
```
|
||||
|
||||
## Mutations
|
||||
|
||||
Actions that don't do anything are not fun. The transformations typically
|
||||
done by a Redux's reducer are called 'mutations' in Updux. A mutation is a
|
||||
function with the following signature:
|
||||
|
||||
```
|
||||
( payload, action ) => state => {
|
||||
// ... stuff done here
|
||||
return new_state;
|
||||
}
|
||||
```
|
||||
|
||||
The inversion and chaining of parameters from the usual Redux reducer's
|
||||
signature is there to work with `updeep`'s curried nature. The expansion of
|
||||
the usual `action` into `(payload, action)` is present because in most cases
|
||||
`payload` is what we're interested in. So why not make it easily available?
|
||||
|
||||
### Adding a mutation
|
||||
|
||||
As for the actions, a mutation can be defined as part of the Updux
|
||||
Like actions, a mutation can be defined as part of the Updux
|
||||
init arguments:
|
||||
|
||||
```
|
||||
const add_todo_mutation = description => ({next_id: id, todos}) => {
|
||||
return {
|
||||
next_id: 1 + id,
|
||||
todos: [...todos, { description, id, done: false }]
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const todosUpdux = new Updux({
|
||||
actions: { add_todo },
|
||||
mutations: [
|
||||
[ add_todo, add_todo_mutation ]
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
or via the method `addMutation`:
|
||||
|
||||
```
|
||||
todos.addMutation( add_todo, description => ({next_id: id, todos}) => {
|
||||
return {
|
||||
next_id: 1 + id,
|
||||
todos: [...todos, { description, id, done: false }]
|
||||
```js
|
||||
const todosDux = new Updux({
|
||||
actions: {
|
||||
addTodo: null
|
||||
},
|
||||
mutations: {
|
||||
addTodo: description => ({next_id: id, todos}) => ({
|
||||
next_id: 1 + id,
|
||||
todos: [...todos, { description, id, done: false }]
|
||||
})
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
This time around, if the project is using TypeScript then the addition of
|
||||
mutations via `addMutation` is encouraged, as the method signature
|
||||
has visibility of the types of the action and state.
|
||||
or via the method `setMutation`:
|
||||
|
||||
### Leftover mutation
|
||||
|
||||
A mutation with the special action `*` will match any action that haven't been
|
||||
explicitly dealt with with any other defined mutation.
|
||||
|
||||
```
|
||||
todosUpdux.addMutation( '*', (payload,action) => state => {
|
||||
console.log("hey, action has no mutation! ", action.type);
|
||||
});
|
||||
```js
|
||||
todosDux.setMutation( 'addTodo', description => ({next_id: id, todos}) => ({
|
||||
next_id: 1 + id,
|
||||
todos: [...todos, { description, id, done: false }]
|
||||
}));
|
||||
```
|
||||
|
||||
## Effects
|
||||
|
@ -54,7 +54,7 @@ export class Updux {
|
||||
this.#mutations = config.mutations ?? {};
|
||||
|
||||
Object.keys(this.#mutations)
|
||||
.filter((action) => action !== '*')
|
||||
.filter((action) => action !== '+')
|
||||
.filter((action) => !this.actions.hasOwnProperty(action))
|
||||
.forEach((action) => {
|
||||
throw new Error(`action '${action}' is not defined`);
|
||||
|
@ -26,7 +26,7 @@ export function buildUpreducer(initial, mutations, subduxes = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
const a = mutations[action.type] || mutations['*'];
|
||||
const a = mutations[action.type] || mutations['+'];
|
||||
|
||||
if (!a) return newState;
|
||||
|
||||
|
@ -45,4 +45,6 @@ test('tutorial', async (t) => {
|
||||
todosDux.setAction( 'addTodo' );
|
||||
todosDux.setAction( 'todoDone' );
|
||||
|
||||
t.same( todosDux.actions.addTodo('write tutorial') , { type: 'addTodo', payload: 'write tutorial' });
|
||||
|
||||
})
|
||||
|
@ -1,2 +1,2 @@
|
||||
export { Updux } from './Updux.js';
|
||||
|
||||
export { action } from './actions.js';
|
||||
|
@ -27,7 +27,7 @@ test('override', async (t) => {
|
||||
const dux = new Updux({
|
||||
initial: { alpha: [] },
|
||||
mutations: {
|
||||
'*': (payload, action) => (state) => ({
|
||||
'+': (payload, action) => (state) => ({
|
||||
...state,
|
||||
alpha: [...state.alpha, action.type],
|
||||
}),
|
||||
|
8
types/index.d.ts
vendored
8
types/index.d.ts
vendored
@ -95,4 +95,12 @@ declare module 'updux' {
|
||||
*/
|
||||
setAction(actionType: string, payloadFunc?: Function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an action generator.
|
||||
*/
|
||||
export function action(
|
||||
actionType: string,
|
||||
payloadFunction?: Function
|
||||
): ActionGenerator;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user