documentation, actions
This commit is contained in:
parent
2e357b71e2
commit
9778e04a8d
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -89,4 +89,4 @@ well with <a href="https://immerjs.github.io/immer/docs/introduction">Immer</a>.
|
|||||||
can be used to wrap all mutations with it:</p>
|
can be used to wrap all mutations with it:</p>
|
||||||
<pre><code><span class="hl-0">import</span><span class="hl-1"> </span><span class="hl-2">Updux</span><span class="hl-1"> </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'updux'</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">produce</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'Immer'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">updux</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Updux</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">initial:</span><span class="hl-1"> { </span><span class="hl-2">counter:</span><span class="hl-1"> </span><span class="hl-7">0</span><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-6">groomMutations</span><span class="hl-2">:</span><span class="hl-1"> </span><span class="hl-2">mutation</span><span class="hl-1"> </span><span class="hl-4">=></span><span class="hl-1"> (...</span><span class="hl-2">args</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-6">produce</span><span class="hl-1">( </span><span class="hl-6">mutation</span><span class="hl-1">(...</span><span class="hl-2">args</span><span class="hl-1">) ),</span><br/><span class="hl-1"> </span><span class="hl-2">mutations:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">add</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">inc</span><span class="hl-1">=</span><span class="hl-7">1</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-2">draft</span><span class="hl-1"> </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-2">draft</span><span class="hl-1">.</span><span class="hl-2">counter</span><span class="hl-1"> += </span><span class="hl-2">inc</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span><br/>
|
<pre><code><span class="hl-0">import</span><span class="hl-1"> </span><span class="hl-2">Updux</span><span class="hl-1"> </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'updux'</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">produce</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'Immer'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">updux</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Updux</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">initial:</span><span class="hl-1"> { </span><span class="hl-2">counter:</span><span class="hl-1"> </span><span class="hl-7">0</span><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-6">groomMutations</span><span class="hl-2">:</span><span class="hl-1"> </span><span class="hl-2">mutation</span><span class="hl-1"> </span><span class="hl-4">=></span><span class="hl-1"> (...</span><span class="hl-2">args</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-6">produce</span><span class="hl-1">( </span><span class="hl-6">mutation</span><span class="hl-1">(...</span><span class="hl-2">args</span><span class="hl-1">) ),</span><br/><span class="hl-1"> </span><span class="hl-2">mutations:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">add</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">inc</span><span class="hl-1">=</span><span class="hl-7">1</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-2">draft</span><span class="hl-1"> </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-2">draft</span><span class="hl-1">.</span><span class="hl-2">counter</span><span class="hl-1"> += </span><span class="hl-2">inc</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span><br/>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</div></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class="current"><a href="modules.html">Exports</a></li><li class=" tsd-kind-namespace"><a href="modules/_updux_.html">"updux"</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul><li class="tsd-kind-type-alias tsd-has-type-parameter"><a href="modules.html#Dict" class="tsd-kind-icon">Dict</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>
|
</div></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class="current"><a href="modules.html">Exports</a></li><li class=" tsd-kind-namespace"><a href="modules/_updux_.html">"updux"</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul><li class="tsd-kind-type-alias"><a href="modules.html#ActionGenerator" class="tsd-kind-icon">Action<wbr/>Generator</a></li><li class="tsd-kind-type-alias tsd-has-type-parameter"><a href="modules.html#Dict" class="tsd-kind-icon">Dict</a></li><li class="tsd-kind-type-alias tsd-has-type-parameter"><a href="modules.html#Mutation" class="tsd-kind-icon">Mutation</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>
|
File diff suppressed because one or more lines are too long
@ -1,23 +1,21 @@
|
|||||||
|
## What's Updux?
|
||||||
# What's Updux?
|
|
||||||
|
|
||||||
So, I'm a fan of [Redux](https://redux.js.org).
|
So, I'm a fan of [Redux](https://redux.js.org).
|
||||||
|
|
||||||
As I was looking into tools to help cut on its boilerplate,
|
As I was looking into tools to help cut on its boilerplate,
|
||||||
I came across [rematch](https://rematch.github.io/rematch).
|
I came across [rematch](https://rematch.github.io/rematch).
|
||||||
It has some pretty darn good ideas.
|
It has some pretty darn good ideas.
|
||||||
Keeping mutations and asynchronous effects close to the
|
|
||||||
reducer definition? Nice. Automatically infering the
|
|
||||||
actions from the said mutations and effects? Genius!
|
|
||||||
|
|
||||||
But it also enforces a flat hierarchy of reducers -- where
|
But it also enforces a flat hierarchy of reducers -- where
|
||||||
is the fun in that? And I'm also having a strong love for
|
is the fun in that?
|
||||||
[Updeep](https://github.com/substantial/updeep), so I want reducer state updates to leverage the heck out of it.
|
|
||||||
|
I'm also having a strong love for
|
||||||
|
[Updeep](https://github.com/substantial/updeep), so I wanted a framework where
|
||||||
|
I could use it to define reducer state updates.
|
||||||
|
|
||||||
Hence: `Updux`. Heavily inspired by `rematch`, but twisted
|
Hence: `Updux`. Heavily inspired by `rematch`, but twisted
|
||||||
to work with `updeep` and to fit my peculiar needs. It offers features such as
|
to work with `updeep` and to fit my peculiar needs. It offers features such as
|
||||||
|
|
||||||
* Mimic the way VueX has mutations (reducer reactions to specific actions) and
|
* Mimic the way VueX has mutations (per-action reducer logic) and
|
||||||
effects (middleware reacting to actions that can be asynchronous and/or
|
effects (middleware reacting to actions that can be asynchronous and/or
|
||||||
have side-effects), so all things pertaining to a store are defined
|
have side-effects), so all things pertaining to a store are defined
|
||||||
in the space place.
|
in the space place.
|
||||||
@ -26,9 +24,7 @@ to work with `updeep` and to fit my peculiar needs. It offers features such as
|
|||||||
store.
|
store.
|
||||||
* Mutations have a signature that is friendly to Updux and Immer.
|
* Mutations have a signature that is friendly to Updux and Immer.
|
||||||
* Mutations auto-unwrapping the payload of actions for you.
|
* Mutations auto-unwrapping the payload of actions for you.
|
||||||
* TypeScript types.
|
* TypeScript support.
|
||||||
* Leverage [ts-action](https://www.npmjs.com/package/ts-action) for action
|
|
||||||
creation.
|
|
||||||
|
|
||||||
**Fair warning**: this package is still very new, likely to go through
|
**Fair warning**: this package is still very new, likely to go through
|
||||||
big changes before I find the perfect balance between ease of use and sanity.
|
big changes before I find the perfect balance between ease of use and sanity.
|
||||||
@ -36,70 +32,36 @@ Caveat Emptor.
|
|||||||
|
|
||||||
# Synopsis
|
# Synopsis
|
||||||
|
|
||||||
```
|
```js
|
||||||
import Updux from 'updux';
|
import { Updux } from 'updux';
|
||||||
import { action, payload } from 'ts-action';
|
import u from 'updeep';
|
||||||
|
import add from 'lodash/fp/add.js';
|
||||||
|
|
||||||
import otherDux from './otherUpdux';
|
import otherDux from './otherUpdux';
|
||||||
|
|
||||||
const inc = action( 'INC', payload<int>() );
|
const dux = new Updux({
|
||||||
|
|
||||||
const updux = new Updux({
|
|
||||||
initial: {
|
initial: {
|
||||||
counter: 0,
|
counter: 0,
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
inc
|
inc: null
|
||||||
},
|
},
|
||||||
subduxes: {
|
subduxes: {
|
||||||
otherDux,
|
otherDux,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
updux.addMutation( inc, increment => u({counter: s => s + increment }));
|
dux.setMutation('inc', (increment) => u({ counter: add(increment) }));
|
||||||
|
|
||||||
updux.addEffect( '*', api => next => action => {
|
dux.addEffect( '*', api => next => action => {
|
||||||
console.log( "hey, look, an action zoomed by!", action );
|
console.log( "hey, look, an action zoomed by!", action );
|
||||||
next(action);
|
next(action);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
const myDux = updux.asDux;
|
const store = dux.createStore();
|
||||||
|
|
||||||
const store = myDux.createStore();
|
store.dispatch.inc(1);
|
||||||
|
|
||||||
store.dispatch( myDux.actions.inc(3) );
|
console.log( store.getState().counter ); // prints 1
|
||||||
```
|
```
|
||||||
|
|
||||||
# Description
|
|
||||||
|
|
||||||
The formal documentation of the class Updux and its associated functions and
|
|
||||||
types can be found over [here](https://yanick.github.io/updux/docs/classes/updux.html).
|
|
||||||
|
|
||||||
## Exporting upduxes
|
|
||||||
|
|
||||||
If you are creating upduxes that will be used as subduxes
|
|
||||||
by other upduxes, or as
|
|
||||||
[ducks](https://github.com/erikras/ducks-modular-redux)-like containers, I
|
|
||||||
recommend that you export the "compiled" (as in, no more editable and with all its properties resolved) output of the Updux instance via its `asDux()` getter:
|
|
||||||
|
|
||||||
```
|
|
||||||
import Updux from 'updux';
|
|
||||||
|
|
||||||
const updux = new Updux({ ... });
|
|
||||||
|
|
||||||
export default updux.asDux;
|
|
||||||
```
|
|
||||||
|
|
||||||
Then you can use them as subduxes like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
import Updux from 'updux';
|
|
||||||
import foo from './foo'; // foo is a dux
|
|
||||||
import bar from './bar'; // bar is a dux as well
|
|
||||||
|
|
||||||
const updux = new Updux({
|
|
||||||
subduxes: {
|
|
||||||
foo, bar
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
- [README](/README.md)
|
- [Intro](/README.md)
|
||||||
- [Tutorial](/tutorial.md)
|
- [Tutorial](/tutorial.md)
|
||||||
- [Concepts](/concepts.md)
|
- [Concepts](/concepts.md)
|
||||||
- [Recipes](/recipes.md)
|
- [Recipes](/recipes.md)
|
||||||
|
@ -3,72 +3,45 @@
|
|||||||
This tutorial walks you through the features of `Updux` using the
|
This tutorial walks you through the features of `Updux` using the
|
||||||
time-honored example of the implementation of Todo list store.
|
time-honored example of the implementation of Todo list store.
|
||||||
|
|
||||||
This tutorial assumes that our project is written in TypeScript, and
|
We'll be using
|
||||||
that we are using [updeep](https://www.npmjs.com/package/updeep) to
|
[updeep](https://www.npmjs.com/package/updeep) to
|
||||||
help with immutability and deep merging and [ts-action][] to manage our
|
help with immutability and deep merging,
|
||||||
actions. This is the recommended setup, but
|
but that's totally optional. If `updeep` is not your bag,
|
||||||
neither of those two architecture
|
it can easily be substitued with, say, [immer][], [lodash][], or even
|
||||||
decisions are mandatory; Updux is equally usable in a pure-JavaScript setting,
|
plain JavaScript.
|
||||||
and `updeep` can easily be substitued with, say, [immer][], [lodash][], or even
|
|
||||||
just plain JavaScript. Eventually, I plan to write a version of this tutorial
|
|
||||||
with all those different configurations.
|
|
||||||
|
|
||||||
Also, the code used here is also available in the project repository, in the
|
|
||||||
`src/tutorial` directory.
|
|
||||||
|
|
||||||
## Definition of the state
|
## Definition of the state
|
||||||
|
|
||||||
First thing first: let's define the type of our store:
|
To begin with, let's define that has nothing but an initial state.
|
||||||
|
|
||||||
```
|
```js
|
||||||
type Todo = {
|
import { Updux } from 'updux';
|
||||||
id: number;
|
|
||||||
description: string;
|
|
||||||
done: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type TodoStore = {
|
const todosDux = new Updux({
|
||||||
next_id: number;
|
|
||||||
todos: Todo[];
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
With that, let's create our very first Updux:
|
|
||||||
|
|
||||||
```
|
|
||||||
import Updux from 'updux';
|
|
||||||
|
|
||||||
const todosUpdux = new Updux({
|
|
||||||
initial: {
|
initial: {
|
||||||
next_id: 1,
|
next_id: 1,
|
||||||
todos: [],
|
todos: [],
|
||||||
} as TodoStore
|
}
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that we explicitly cast the initial state as `as TodoStore`. This lets
|
Congrats! You have written your first Updux object. It
|
||||||
Updux know what is the store's state.
|
|
||||||
|
|
||||||
This being said, congrats! You have written your first Updux object. It
|
|
||||||
doesn't do a lot, but you can already create a store out of it, and its
|
doesn't do a lot, but you can already create a store out of it, and its
|
||||||
initial state will be automatically set:
|
initial state will be automatically set:
|
||||||
|
|
||||||
```
|
```js
|
||||||
const store = todosUpdux.createStore();
|
const store = todosDux.createStore();
|
||||||
|
|
||||||
console.log(store.getState());
|
console.log(store.getState()); // prints { next_id: 1, todos: [] }
|
||||||
// { next_id: 1, todos: [] }
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Add actions
|
## Add actions
|
||||||
|
|
||||||
This is all good, but a little static. Let's add actions!
|
This is all good, but a little static. Let's add actions!
|
||||||
|
|
||||||
```
|
```js
|
||||||
import { action, payload } from 'ts-action';
|
todosDux.setAction( 'addTodo' );
|
||||||
|
todosDux.setAction( 'todoDone' );
|
||||||
const add_todo = action('add_todo', payload<string>() );
|
|
||||||
const todo_done = action('todo_done', payload<number>() );
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, there is a lot of ways to add actions to a Updux object.
|
Now, there is a lot of ways to add actions to a Updux object.
|
||||||
|
@ -128,7 +128,7 @@ export class Updux {
|
|||||||
this.#subscriptions = [...this.#subscriptions, subscription];
|
this.#subscriptions = [...this.#subscriptions, subscription];
|
||||||
}
|
}
|
||||||
|
|
||||||
addAction(type, payloadFunc) {
|
setAction(type, payloadFunc) {
|
||||||
const theAction = action(type, payloadFunc);
|
const theAction = action(type, payloadFunc);
|
||||||
|
|
||||||
this.#actions = { ...this.#actions, [type]: theAction };
|
this.#actions = { ...this.#actions, [type]: theAction };
|
||||||
@ -144,7 +144,7 @@ export class Updux {
|
|||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
addMutation(name, mutation) {
|
setMutation(name, mutation) {
|
||||||
if (typeof name === 'function') name = name.type;
|
if (typeof name === 'function') name = name.type;
|
||||||
|
|
||||||
this.#mutations = {
|
this.#mutations = {
|
||||||
@ -152,7 +152,7 @@ export class Updux {
|
|||||||
[name]: mutation,
|
[name]: mutation,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return mutation;
|
||||||
}
|
}
|
||||||
|
|
||||||
addEffect(action, effect) {
|
addEffect(action, effect) {
|
||||||
@ -304,6 +304,3 @@ export class Updux {
|
|||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const x = new Updux();
|
|
||||||
x.selectors;
|
|
||||||
|
@ -45,13 +45,13 @@ test('basic actions', async (t) => {
|
|||||||
t.same(Object.keys(dux.actions).sort(), ['bar', 'foo']);
|
t.same(Object.keys(dux.actions).sort(), ['bar', 'foo']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('addAction', async (t) => {
|
test('setAction', async (t) => {
|
||||||
const dux = new Updux({
|
const dux = new Updux({
|
||||||
actions: {
|
actions: {
|
||||||
bar: action('bar'),
|
bar: action('bar'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
dux.addAction('foo');
|
dux.setAction('foo');
|
||||||
|
|
||||||
t.same(Object.keys(dux.actions).sort(), ['bar', 'foo']);
|
t.same(Object.keys(dux.actions).sort(), ['bar', 'foo']);
|
||||||
});
|
});
|
||||||
@ -81,7 +81,7 @@ test('basic selectors', async (t) => {
|
|||||||
(add) =>
|
(add) =>
|
||||||
add + foo
|
add + foo
|
||||||
);
|
);
|
||||||
dux.addAction('stuff');
|
dux.setAction('stuff');
|
||||||
|
|
||||||
t.equal(dux.selectors.getBar({ bar: 3 }), 3);
|
t.equal(dux.selectors.getBar({ bar: 3 }), 3);
|
||||||
t.equal(dux.selectors.getFoo({ foo: 3 }), 3);
|
t.equal(dux.selectors.getFoo({ foo: 3 }), 3);
|
||||||
@ -100,8 +100,8 @@ test('mutations', async (t) => {
|
|||||||
const alpha = new Updux({
|
const alpha = new Updux({
|
||||||
initial: { quux: 3 },
|
initial: { quux: 3 },
|
||||||
});
|
});
|
||||||
alpha.addAction('add');
|
alpha.setAction('add');
|
||||||
alpha.addMutation('add', (toAdd) => (state) => ({
|
alpha.setMutation('add', (toAdd) => (state) => ({
|
||||||
quux: state.quux + toAdd,
|
quux: state.quux + toAdd,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -112,12 +112,12 @@ test('mutations', async (t) => {
|
|||||||
},
|
},
|
||||||
subduxes: { alpha },
|
subduxes: { alpha },
|
||||||
});
|
});
|
||||||
dux.addAction('subtract');
|
dux.setAction('subtract');
|
||||||
dux.addMutation('add', (toAdd) => (state) => ({
|
dux.setMutation('add', (toAdd) => (state) => ({
|
||||||
...state,
|
...state,
|
||||||
foo: state.foo + toAdd,
|
foo: state.foo + toAdd,
|
||||||
}));
|
}));
|
||||||
dux.addMutation('subtract', (toSubtract) => (state) => ({
|
dux.setMutation('subtract', (toSubtract) => (state) => ({
|
||||||
...state,
|
...state,
|
||||||
bar: state.bar - toSubtract,
|
bar: state.bar - toSubtract,
|
||||||
}));
|
}));
|
||||||
|
48
src/documentation.test.js
Normal file
48
src/documentation.test.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { test } from 'tap';
|
||||||
|
import u from 'updeep';
|
||||||
|
import add from 'lodash/fp/add.js';
|
||||||
|
|
||||||
|
import { Updux } from './index.js';
|
||||||
|
|
||||||
|
test('README.md', async (t) => {
|
||||||
|
const otherDux = new Updux({});
|
||||||
|
|
||||||
|
const dux = new Updux({
|
||||||
|
initial: {
|
||||||
|
counter: 0,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
inc: null,
|
||||||
|
},
|
||||||
|
subduxes: {
|
||||||
|
otherDux,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
dux.setMutation('inc', (increment) => u({ counter: add(increment) }));
|
||||||
|
|
||||||
|
dux.addEffect('*', (api) => (next) => (action) => {
|
||||||
|
next(action);
|
||||||
|
});
|
||||||
|
|
||||||
|
const store = dux.createStore();
|
||||||
|
|
||||||
|
store.dispatch.inc(1);
|
||||||
|
|
||||||
|
t.equal(store.getState().counter, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('tutorial', async (t) => {
|
||||||
|
|
||||||
|
const todosDux = new Updux({
|
||||||
|
initial: {
|
||||||
|
next_id: 1,
|
||||||
|
todos: [],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
todosDux.setAction( 'addTodo' );
|
||||||
|
todosDux.setAction( 'todoDone' );
|
||||||
|
|
||||||
|
})
|
16
src/index.js
16
src/index.js
@ -1,16 +1,2 @@
|
|||||||
import Updux from './Updux.js';
|
export { Updux } from './Updux.js';
|
||||||
|
|
||||||
export {
|
|
||||||
/**
|
|
||||||
* The {@link Updux} class
|
|
||||||
*/
|
|
||||||
Updux
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `Updux` is a way to minimize and simplify the boilerplate associated with the
|
|
||||||
* creation of a `Redux` store. It takes a shorthand configuration
|
|
||||||
* object, and generates the appropriate reducer, actions, middleware, etc.
|
|
||||||
* In true `Redux`-like fashion, upduxes can be made of sub-upduxes (`subduxes` for short) for different slices of the root state.
|
|
||||||
* @module updux
|
|
||||||
*/
|
|
||||||
|
@ -81,7 +81,7 @@ test('order of processing', async (t) => {
|
|||||||
t.same(dux.reducer(undefined, foo()), { x: ['subdux', 'main'] });
|
t.same(dux.reducer(undefined, foo()), { x: ['subdux', 'main'] });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('addMutation', async (t) => {
|
test('setMutation', async (t) => {
|
||||||
const foo = action('foo');
|
const foo = action('foo');
|
||||||
|
|
||||||
const dux = new Updux({
|
const dux = new Updux({
|
||||||
@ -90,13 +90,13 @@ test('addMutation', async (t) => {
|
|||||||
|
|
||||||
t.equal(dux.reducer(undefined, foo()), '', 'noop');
|
t.equal(dux.reducer(undefined, foo()), '', 'noop');
|
||||||
|
|
||||||
dux.addMutation('foo', () => () => 'foo');
|
dux.setMutation('foo', () => () => 'foo');
|
||||||
|
|
||||||
t.equal(dux.reducer(undefined, foo()), 'foo', 'foo was added');
|
t.equal(dux.reducer(undefined, foo()), 'foo', 'foo was added');
|
||||||
|
|
||||||
await t.test('name as function', async (t) => {
|
await t.test('name as function', async (t) => {
|
||||||
const bar = action('bar');
|
const bar = action('bar');
|
||||||
dux.addMutation(bar, () => () => 'bar');
|
dux.setMutation(bar, () => () => 'bar');
|
||||||
|
|
||||||
t.equal(dux.reducer(undefined, bar()), 'bar', 'bar was added');
|
t.equal(dux.reducer(undefined, bar()), 'bar', 'bar was added');
|
||||||
});
|
});
|
||||||
|
35
types/index.d.ts
vendored
35
types/index.d.ts
vendored
@ -1,5 +1,15 @@
|
|||||||
type Dict<T> = Record<string, T>;
|
type Dict<T> = Record<string, T>;
|
||||||
|
|
||||||
|
type Mutation<TState = unknown> = (
|
||||||
|
payload: unknown,
|
||||||
|
action: Record<string, unknown>
|
||||||
|
) => (state: TState) => TState;
|
||||||
|
|
||||||
|
type ActionGenerator = { type: string } & ((...args: any[]) => {
|
||||||
|
type: string;
|
||||||
|
payload?: unknown;
|
||||||
|
});
|
||||||
|
|
||||||
declare module 'updux' {
|
declare module 'updux' {
|
||||||
/**
|
/**
|
||||||
* Configuration object typically passed to the constructor of the class Updux.
|
* Configuration object typically passed to the constructor of the class Updux.
|
||||||
@ -59,5 +69,30 @@ declare module 'updux' {
|
|||||||
|
|
||||||
get initial(): TState;
|
get initial(): TState;
|
||||||
get selectors(): unknown;
|
get selectors(): unknown;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the local mutation for the given action.
|
||||||
|
*
|
||||||
|
* The action can be specified via its type
|
||||||
|
* or its generator.
|
||||||
|
*
|
||||||
|
* Returns the same mutation function.
|
||||||
|
*/
|
||||||
|
setMutation<TMutation extends Mutation>(
|
||||||
|
actionType: string,
|
||||||
|
mutation: TMutation
|
||||||
|
): TMutation;
|
||||||
|
setMutation<TMutation extends Mutation>(
|
||||||
|
action: ActionGenerator,
|
||||||
|
mutation: TMutation
|
||||||
|
): TMutation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the action for the dux.
|
||||||
|
* If no payload function is provided, whatever is
|
||||||
|
* given as an argument to the action generator will
|
||||||
|
* be set as-is in the action's payload.
|
||||||
|
*/
|
||||||
|
setAction(actionType: string, payloadFunc?: Function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user