wip: REMOVE ALL

This commit is contained in:
Yanick Champoux 2022-08-24 21:40:01 -04:00
parent 3aac2e092e
commit ef5751eb69
114 changed files with 0 additions and 25429 deletions

7
TODO
View File

@ -1,7 +0,0 @@
[ ] Warn if one tries to define the same action twice
[ ] Middleware of subduxes get sub-states and getRootState
[ ] add `addAction` method
[ ] can do .addMutation( 'foo', ... );, which either
use the action already existing or create a boring one (should I?)

View File

@ -1,26 +0,0 @@
# https://taskfile.dev
version: '3'
vars:
GREETING: Hello, World!
tasks:
tsc:
cmds:
- tsc
- echo 🙌 typescript compilation successful
test: jest
'prettier': prettier --check .
'prettier:fix': prettier --write .
check:
deps: [tsc, test, 'prettier']
'test:types': tsd
docs:
cmds:
- jsdoc -c jsdoc.json -t ./node_modules/better-docs src/index.js src/Updux.js

View File

@ -1,6 +0,0 @@
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
],
};

View File

View File

@ -1 +0,0 @@
TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.

View File

@ -1,92 +0,0 @@
:root {
--light-hl-0: #AF00DB;
--dark-hl-0: #C586C0;
--light-hl-1: #000000;
--dark-hl-1: #D4D4D4;
--light-hl-2: #001080;
--dark-hl-2: #9CDCFE;
--light-hl-3: #A31515;
--dark-hl-3: #CE9178;
--light-hl-4: #0000FF;
--dark-hl-4: #569CD6;
--light-hl-5: #0070C1;
--dark-hl-5: #4FC1FF;
--light-hl-6: #795E26;
--dark-hl-6: #DCDCAA;
--light-hl-7: #098658;
--dark-hl-7: #B5CEA8;
--light-hl-8: #008000;
--dark-hl-8: #6A9955;
--light-hl-9: #000000;
--dark-hl-9: #C8C8C8;
--light-code-background: #FFFFFF;
--dark-code-background: #1E1E1E;
}
@media (prefers-color-scheme: light) { :root {
--hl-0: var(--light-hl-0);
--hl-1: var(--light-hl-1);
--hl-2: var(--light-hl-2);
--hl-3: var(--light-hl-3);
--hl-4: var(--light-hl-4);
--hl-5: var(--light-hl-5);
--hl-6: var(--light-hl-6);
--hl-7: var(--light-hl-7);
--hl-8: var(--light-hl-8);
--hl-9: var(--light-hl-9);
--code-background: var(--light-code-background);
} }
@media (prefers-color-scheme: dark) { :root {
--hl-0: var(--dark-hl-0);
--hl-1: var(--dark-hl-1);
--hl-2: var(--dark-hl-2);
--hl-3: var(--dark-hl-3);
--hl-4: var(--dark-hl-4);
--hl-5: var(--dark-hl-5);
--hl-6: var(--dark-hl-6);
--hl-7: var(--dark-hl-7);
--hl-8: var(--dark-hl-8);
--hl-9: var(--dark-hl-9);
--code-background: var(--dark-code-background);
} }
body.light {
--hl-0: var(--light-hl-0);
--hl-1: var(--light-hl-1);
--hl-2: var(--light-hl-2);
--hl-3: var(--light-hl-3);
--hl-4: var(--light-hl-4);
--hl-5: var(--light-hl-5);
--hl-6: var(--light-hl-6);
--hl-7: var(--light-hl-7);
--hl-8: var(--light-hl-8);
--hl-9: var(--light-hl-9);
--code-background: var(--light-code-background);
}
body.dark {
--hl-0: var(--dark-hl-0);
--hl-1: var(--dark-hl-1);
--hl-2: var(--dark-hl-2);
--hl-3: var(--dark-hl-3);
--hl-4: var(--dark-hl-4);
--hl-5: var(--dark-hl-5);
--hl-6: var(--dark-hl-6);
--hl-7: var(--dark-hl-7);
--hl-8: var(--dark-hl-8);
--hl-9: var(--dark-hl-9);
--code-background: var(--dark-code-background);
}
.hl-0 { color: var(--hl-0); }
.hl-1 { color: var(--hl-1); }
.hl-2 { color: var(--hl-2); }
.hl-3 { color: var(--hl-3); }
.hl-4 { color: var(--hl-4); }
.hl-5 { color: var(--hl-5); }
.hl-6 { color: var(--hl-6); }
.hl-7 { color: var(--hl-7); }
.hl-8 { color: var(--hl-8); }
.hl-9 { color: var(--hl-9); }
pre, code { background: var(--code-background); }

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

File diff suppressed because one or more lines are too long

View File

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

File diff suppressed because one or more lines are too long

View File

@ -1,92 +0,0 @@
<!DOCTYPE html><html class="default no-js"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>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"><h1>Updux</h1></div></div></header><div class="container container-main"><div class="row"><div class="col-8 col-content"><div class="tsd-panel tsd-typography">
<a href="#what39s-updux" id="what39s-updux" style="color: inherit; text-decoration: none;">
<h1>What&#39;s Updux?</h1>
</a>
<p>So, I&#39;m a fan of <a href="https://redux.js.org">Redux</a>. Two days ago I discovered
<a href="https://rematch.github.io/rematch">rematch</a> alonside a few other frameworks built atop Redux.</p>
<p>It has a couple of pretty good ideas that removes some of the
boilerplate. Keeping mutations and asynchronous effects close to the
reducer definition? Nice. Automatically infering the
actions from the said mutations and effects? Genius!</p>
<p>But it also enforces a flat hierarchy of reducers -- where
is the fun in that? And I&#39;m also having a strong love for
<a href="https://github.com/substantial/updeep">Updeep</a>, so I want reducer state updates to leverage the heck out of it.</p>
<p>All that to say, say hello to <code>Updux</code>. Heavily inspired by <code>rematch</code>, but twisted
to work with <code>updeep</code> and to fit my peculiar needs. It offers features such as</p>
<ul>
<li>Mimic the way VueX has mutations (reducer reactions to specific actions) and
effects (middleware reacting to actions that can be asynchronous and/or
have side-effects), so everything pertaining to a store are all defined
in the space place.</li>
<li>Automatically gather all actions used by the updux&#39;s effects and mutations,
and makes then accessible as attributes to the <code>dispatch</code> object of the
store.</li>
<li>Mutations have a signature that is friendly to Updux and Immer.</li>
<li>Also, the mutation signature auto-unwrap the payload of the actions for you.</li>
<li>TypeScript types.</li>
</ul>
<p>Fair warning: this package is still very new, probably very buggy,
definitively very badly documented, and very subject to changes. Caveat
Maxima Emptor.</p>
<a href="#synopsis" id="synopsis" style="color: inherit; text-decoration: none;">
<h1>Synopsis</h1>
</a>
<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">&#39;updux&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">import</span><span class="hl-1"> </span><span class="hl-2">otherUpdux</span><span class="hl-1"> </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;./otherUpdux&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">initial</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">reducer</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">actions</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">middleware</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">createStore</span><span class="hl-1">,</span><br/><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><br/><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><br/><span class="hl-1"> </span><span class="hl-2">subduxes:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">otherUpdux</span><span class="hl-1">,</span><br/><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">inc</span><span class="hl-2">:</span><span class="hl-1"> ( </span><span class="hl-2">increment</span><span class="hl-1"> = </span><span class="hl-7">1</span><span class="hl-1"> ) </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-6">u</span><span class="hl-1">({</span><span class="hl-6">counter</span><span class="hl-2">:</span><span class="hl-1"> </span><span class="hl-2">s</span><span class="hl-1"> </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-2">s</span><span class="hl-1"> + </span><span class="hl-2">increment</span><span class="hl-1"> })</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-2">effects:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">&#39;*&#39;</span><span class="hl-2"> =&gt; api =&gt; next =&gt; action =&gt; {</span><br/><span class="hl-2"> console.log( </span><span class="hl-3">&quot;hey, look, an action zoomed by!&quot;</span><span class="hl-1">, action );</span><br/><span class="hl-1"> </span><span class="hl-6">next</span><span class="hl-1">(</span><span class="hl-2">action</span><span class="hl-1">);</span><br/><span class="hl-1"> };</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-2">actions</span><span class="hl-1">: {</span><br/><span class="hl-1"> </span><span class="hl-6">customAction</span><span class="hl-2">:</span><span class="hl-1"> ( </span><span class="hl-2">someArg</span><span class="hl-1"> ) </span><span class="hl-4">=&gt;</span><span class="hl-1"> ({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&quot;custom&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">payload:</span><span class="hl-1"> { </span><span class="hl-2">someProp:</span><span class="hl-1"> </span><span class="hl-2">someArg</span><span class="hl-1"> }</span><br/><span class="hl-1"> }),</span><br/><span class="hl-1"> },</span><br/><br/><span class="hl-1">});</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">store</span><span class="hl-1"> = </span><span class="hl-6">createStore</span><span class="hl-1">();</span><br/><br/><span class="hl-2">store</span><span class="hl-1">.</span><span class="hl-2">dispatch</span><span class="hl-1">.</span><span class="hl-6">inc</span><span class="hl-1">(</span><span class="hl-7">3</span><span class="hl-1">);</span>
</code></pre>
<a href="#description" id="description" style="color: inherit; text-decoration: none;">
<h1>Description</h1>
</a>
<p>Full documentation can be <a href="https://yanick.github.io/updux/">found here</a>.
Right now the best way to understand the whole thing is to go
through the <a href="https://yanick.github.io/updux/#/tutorial">tutorial</a></p>
<a href="#exporting-upduxes" id="exporting-upduxes" style="color: inherit; text-decoration: none;">
<h2>Exporting upduxes</h2>
</a>
<p>If you are creating upduxes that will be used as subduxes
by other upduxes, or as
<a href="https://github.com/erikras/ducks-modular-redux">ducks</a>-like containers, I
recommend that you export the Updux instance as the default export:</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">&#39;updux&#39;</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/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-0">default</span><span class="hl-1"> </span><span class="hl-2">updux</span><span class="hl-1">;</span>
</code></pre>
<p>Then you can use them as subduxes like this:</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">&#39;updux&#39;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> </span><span class="hl-2">foo</span><span class="hl-1"> </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;./foo&#39;</span><span class="hl-1">; </span><span class="hl-8">// foo is an Updux</span><br/><span class="hl-0">import</span><span class="hl-1"> </span><span class="hl-2">bar</span><span class="hl-1"> </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;./bar&#39;</span><span class="hl-1">; </span><span class="hl-8">// bar is an Updux as well</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">subduxes:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">foo</span><span class="hl-1">, </span><span class="hl-2">bar</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span>
</code></pre>
<p>Or if you want to use 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">&#39;./myUpdux&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">reducer</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">actions</span><span class="hl-1">: { </span><span class="hl-5">doTheThing</span><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-5">createStore</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">middleware</span><span class="hl-1">,</span><br/><span class="hl-1">} = </span><span class="hl-2">updux</span><span class="hl-1">;</span>
</code></pre>
<a href="#mapping-a-mutation-to-all-values-of-a-state" id="mapping-a-mutation-to-all-values-of-a-state" style="color: inherit; text-decoration: none;">
<h2>Mapping a mutation to all values of a state</h2>
</a>
<p>Say you have a <code>todos</code> state that is an array of <code>todo</code> sub-states. It&#39;s easy
enough to have the main reducer maps away all items to the sub-reducer:</p>
<pre><code><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">todo</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">mutations:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">review</span><span class="hl-2">:</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-6">u</span><span class="hl-1">({ </span><span class="hl-2">reviewed:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">}),</span><br/><span class="hl-1"> </span><span class="hl-6">done</span><span class="hl-2">:</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-6">u</span><span class="hl-1">({</span><span class="hl-2">done:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">}),</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">todos</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><span class="hl-2">initial:</span><span class="hl-1"> [] });</span><br/><br/><span class="hl-2">todos</span><span class="hl-1">.</span><span class="hl-6">addMutation</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">todo</span><span class="hl-1">.</span><span class="hl-2">actions</span><span class="hl-1">.</span><span class="hl-2">review</span><span class="hl-1">,</span><br/><span class="hl-1"> (</span><span class="hl-2">_</span><span class="hl-1">,</span><span class="hl-2">action</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1"> </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-6">map</span><span class="hl-1">( </span><span class="hl-2">todo</span><span class="hl-1">.</span><span class="hl-6">upreducer</span><span class="hl-1">(</span><span class="hl-2">action</span><span class="hl-1">) )</span><br/><span class="hl-1">);</span><br/><span class="hl-2">todos</span><span class="hl-1">.</span><span class="hl-6">addMutation</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">todo</span><span class="hl-1">.</span><span class="hl-2">actions</span><span class="hl-1">.</span><span class="hl-2">done</span><span class="hl-1">,</span><br/><span class="hl-1"> (</span><span class="hl-2">id</span><span class="hl-1">,</span><span class="hl-2">action</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-2">u</span><span class="hl-1">.</span><span class="hl-6">map</span><span class="hl-1">(</span><span class="hl-2">u</span><span class="hl-1">.</span><span class="hl-6">if</span><span class="hl-1">(</span><span class="hl-2">u</span><span class="hl-1">.</span><span class="hl-6">is</span><span class="hl-1">(</span><span class="hl-3">&#39;id&#39;</span><span class="hl-1">,</span><span class="hl-2">id</span><span class="hl-1">), </span><span class="hl-2">todo</span><span class="hl-1">.</span><span class="hl-6">upreducer</span><span class="hl-1">(</span><span class="hl-2">action</span><span class="hl-1">))),</span><br/><span class="hl-1">);</span><br/>
</code></pre>
<p>But <code>updeep</code> can iterate through all the items of an array (or the values of
an object) via the special key <code>*</code>. So the todos updux above could also be
written:</p>
<pre><code><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">todo</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">mutations:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">review</span><span class="hl-2">:</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-6">u</span><span class="hl-1">({ </span><span class="hl-2">reviewed:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">}),</span><br/><span class="hl-1"> </span><span class="hl-6">done</span><span class="hl-2">:</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-6">u</span><span class="hl-1">({</span><span class="hl-2">done:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">}),</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">todos</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">subduxes:</span><span class="hl-1"> { </span><span class="hl-3">&#39;*&#39;</span><span class="hl-2">:</span><span class="hl-1"> </span><span class="hl-2">todo</span><span class="hl-1"> },</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-2">todos</span><span class="hl-1">.</span><span class="hl-6">addMutation</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">todo</span><span class="hl-1">.</span><span class="hl-2">actions</span><span class="hl-1">.</span><span class="hl-2">done</span><span class="hl-1">,</span><br/><span class="hl-1"> (</span><span class="hl-2">id</span><span class="hl-1">,</span><span class="hl-2">action</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-2">u</span><span class="hl-1">.</span><span class="hl-6">map</span><span class="hl-1">(</span><span class="hl-2">u</span><span class="hl-1">.</span><span class="hl-6">if</span><span class="hl-1">(</span><span class="hl-2">u</span><span class="hl-1">.</span><span class="hl-6">is</span><span class="hl-1">(</span><span class="hl-3">&#39;id&#39;</span><span class="hl-1">,</span><span class="hl-2">id</span><span class="hl-1">), </span><span class="hl-2">todo</span><span class="hl-1">.</span><span class="hl-6">upreducer</span><span class="hl-1">(</span><span class="hl-2">action</span><span class="hl-1">))),</span><br/><span class="hl-1"> </span><span class="hl-4">true</span><br/><span class="hl-1">);</span>
</code></pre>
<p>The advantages being that the actions/mutations/effects of the subdux will be
imported by the root updux as usual, and all actions that aren&#39;t being
overridden by a sink mutation will trickle down automatically.</p>
<a href="#usage-with-immer" id="usage-with-immer" style="color: inherit; text-decoration: none;">
<h2>Usage with Immer</h2>
</a>
<p>While Updux was created with Updeep in mind, it also plays very
well with <a href="https://immerjs.github.io/immer/docs/introduction">Immer</a>.</p>
<p>For example, taking this basic updux:</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">&#39;updux&#39;</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-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">=&gt;</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1"> </span><span class="hl-4">=&gt;</span><span class="hl-1"> { </span><span class="hl-9">counter</span><span class="hl-1">: </span><span class="hl-2">counter</span><span class="hl-1"> + </span><span class="hl-2">inc</span><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span><br/>
</code></pre>
<p>Converting it to Immer would look like:</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">&#39;updux&#39;</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">&#39;Immer&#39;</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-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">=&gt;</span><span class="hl-1"> </span><span class="hl-6">produce</span><span class="hl-1">( </span><span class="hl-2">draft</span><span class="hl-1"> </span><span class="hl-4">=&gt;</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><span class="hl-1"> ) }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span><br/>
</code></pre>
<p>But since typing <code>produce</code> over and over is no fun, <code>groomMutations</code>
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">&#39;updux&#39;</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">&#39;Immer&#39;</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">=&gt;</span><span class="hl-1"> (...</span><span class="hl-2">args</span><span class="hl-1">) </span><span class="hl-4">=&gt;</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">=&gt;</span><span class="hl-1"> </span><span class="hl-2">draft</span><span class="hl-1"> </span><span class="hl-4">=&gt;</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>
</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">&quot;updux&quot;</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>

View File

@ -1,25 +0,0 @@
<!DOCTYPE html><html class="default no-js"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>UpduxConfig | 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="../modules/_updux_.html">&quot;updux&quot;</a></li><li><a href="_updux_.UpduxConfig.html">UpduxConfig</a></li></ul><h1>Interface UpduxConfig&lt;TState&gt;</h1></div></div></header><div class="container container-main"><div class="row"><div class="col-8 col-content"><section class="tsd-panel tsd-comment"><div class="tsd-comment tsd-typography"><div class="lead">
<p>Configuration object typically passed to the constructor of the class Updux.</p>
</div></div></section><section class="tsd-panel tsd-type-parameters"><h3>Type parameters</h3><ul class="tsd-type-parameters"><li><h4>TState = <span class="tsd-signature-type">unknown</span></h4></li></ul></section><section class="tsd-panel tsd-hierarchy"><h3>Hierarchy</h3><ul class="tsd-hierarchy"><li><span class="target">UpduxConfig</span></li></ul></section><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>Properties</h3><ul class="tsd-index-list"><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#actions" class="tsd-kind-icon">actions</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#effects" class="tsd-kind-icon">effects</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#initial" class="tsd-kind-icon">initial</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#mappedReaction" class="tsd-kind-icon">mapped<wbr/>Reaction</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#mappedSelectors" class="tsd-kind-icon">mapped<wbr/>Selectors</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#mutations" class="tsd-kind-icon">mutations</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#reactions" class="tsd-kind-icon">reactions</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#selectors" class="tsd-kind-icon">selectors</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#subduxes" class="tsd-kind-icon">subduxes</a></li></ul></section></div></section></section><section class="tsd-panel-group tsd-member-group "><h2>Properties</h2><section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface"><a name="actions" class="tsd-anchor"></a><h3><span class="tsd-flag ts-flagOptional">Optional</span> actions</h3><div class="tsd-signature tsd-kind-icon">actions<span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">&gt;</span></div><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
<p>Local actions.</p>
</div></div></section><section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface"><a name="effects" class="tsd-anchor"></a><h3><span class="tsd-flag ts-flagOptional">Optional</span> effects</h3><div class="tsd-signature tsd-kind-icon">effects<span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Function</span><span class="tsd-signature-symbol">&gt;</span></div><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
<p>Local effects.</p>
</div></div></section><section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface"><a name="initial" class="tsd-anchor"></a><h3><span class="tsd-flag ts-flagOptional">Optional</span> initial</h3><div class="tsd-signature tsd-kind-icon">initial<span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type" data-tsd-kind="Type parameter">TState</span></div><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
<p>Local initial state.</p>
</div><dl class="tsd-comment-tags"><dt>default</dt><dd><p>{}</p>
</dd></dl></div></section><section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface"><a name="mappedReaction" class="tsd-anchor"></a><h3><span class="tsd-flag ts-flagOptional">Optional</span> mapped<wbr/>Reaction</h3><div class="tsd-signature tsd-kind-icon">mapped<wbr/>Reaction<span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">boolean</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Function</span></div><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
<p>If true, enables mapped reactions. Additionally, it can be
a reaction function, which will treated as a regular
reaction for the mapped dux.</p>
</div></div></section><section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface"><a name="mappedSelectors" class="tsd-anchor"></a><h3><span class="tsd-flag ts-flagOptional">Optional</span> mapped<wbr/>Selectors</h3><div class="tsd-signature tsd-kind-icon">mapped<wbr/>Selectors<span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Function</span><span class="tsd-signature-symbol">&gt;</span></div><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
<p> Selectors to apply to the mapped subduxes. Only
applicable if the dux is a mapping dux.</p>
</div></div></section><section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface"><a name="mutations" class="tsd-anchor"></a><h3><span class="tsd-flag ts-flagOptional">Optional</span> mutations</h3><div class="tsd-signature tsd-kind-icon">mutations<span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Function</span><span class="tsd-signature-symbol">&gt;</span></div><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
<p>Local mutations</p>
</div></div></section><section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface"><a name="reactions" class="tsd-anchor"></a><h3><span class="tsd-flag ts-flagOptional">Optional</span> reactions</h3><div class="tsd-signature tsd-kind-icon">reactions<span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Function</span><span class="tsd-signature-symbol">&gt;</span></div><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
<p>Local reactions.</p>
</div></div></section><section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface"><a name="selectors" class="tsd-anchor"></a><h3><span class="tsd-flag ts-flagOptional">Optional</span> selectors</h3><div class="tsd-signature tsd-kind-icon">selectors<span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">Function</span><span class="tsd-signature-symbol">&gt;</span></div><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
<p>Local selectors.</p>
</div></div></section><section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface"><a name="subduxes" class="tsd-anchor"></a><h3><span class="tsd-flag ts-flagOptional">Optional</span> subduxes</h3><div class="tsd-signature tsd-kind-icon">subduxes<span class="tsd-signature-symbol">?:</span> <a href="../modules.html#Dict" class="tsd-signature-type" data-tsd-kind="Type alias">Dict</a><span class="tsd-signature-symbol">&lt;</span><a href="../classes/_updux_.Updux.html" class="tsd-signature-type" data-tsd-kind="Class">Updux</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol"> | </span><a href="_updux_.UpduxConfig.html" class="tsd-signature-type" data-tsd-kind="Interface">UpduxConfig</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">&gt;</span></div><aside class="tsd-sources"></aside><div class="tsd-comment tsd-typography"><div class="lead">
<p>Subduxes to be merged to this dux.</p>
</div></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="../modules/_updux_.html">&quot;updux&quot;</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul><li class="current tsd-kind-interface tsd-parent-kind-namespace tsd-has-type-parameter"><a href="_updux_.UpduxConfig.html" class="tsd-kind-icon">Updux<wbr/>Config</a><ul><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#actions" class="tsd-kind-icon">actions</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#effects" class="tsd-kind-icon">effects</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#initial" class="tsd-kind-icon">initial</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#mappedReaction" class="tsd-kind-icon">mapped<wbr/>Reaction</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#mappedSelectors" class="tsd-kind-icon">mapped<wbr/>Selectors</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#mutations" class="tsd-kind-icon">mutations</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#reactions" class="tsd-kind-icon">reactions</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#selectors" class="tsd-kind-icon">selectors</a></li><li class="tsd-kind-property tsd-parent-kind-interface"><a href="_updux_.UpduxConfig.html#subduxes" class="tsd-kind-icon">subduxes</a></li></ul></li></ul></nav></div></div></div><footer class="with-border-bottom"><div class="container"><h2>Legend</h2><div class="tsd-legend-group"><ul class="tsd-legend"><li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li></ul></div><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

View File

@ -1,3 +0,0 @@
<!DOCTYPE html><html class="default no-js"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>&quot;updux&quot; | 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">&quot;updux&quot;</a></li></ul><h1>Namespace &quot;updux&quot;</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">&quot;updux&quot;</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>

View File

@ -1,67 +0,0 @@
## What's Updux?
So, I'm a fan of [Redux](https://redux.js.org).
As I was looking into tools to help cut on its boilerplate,
I came across [rematch](https://rematch.github.io/rematch).
It has some pretty darn good ideas.
But it also enforces a flat hierarchy of reducers -- where
is the fun in that?
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
to work with `updeep` and to fit my peculiar needs. It offers features such as
* Mimic the way VueX has mutations (per-action reducer logic) and
effects (middleware reacting to actions that can be asynchronous and/or
have side-effects), so all things pertaining to a store are defined
in the space place.
* Automatically gather all actions used by the updux's effects and mutations,
and makes then accessible as attributes to the `dispatch` object of the
store.
* Mutations have a signature that is friendly to Updux and Immer.
* Mutations auto-unwrapping the payload of actions for you.
* TypeScript support.
**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.
Caveat Emptor.
# Synopsis
```js
import { Updux } from 'updux';
import u from 'updeep';
import add from 'lodash/fp/add.js';
import otherDux from './otherUpdux';
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 => {
console.log( "hey, look, an action zoomed by!", action );
next(action);
} );
const store = dux.createStore();
store.dispatch.inc(1);
console.log( store.getState().counter ); // prints 1
```

View File

@ -1,406 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> Updux</title>
<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="./build/entry.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Roboto:100,400,700|Inconsolata,700" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://jmblog.github.io/color-themes-for-google-code-prettify/themes/tomorrow-night.min.css">
<link type="text/css" rel="stylesheet" href="styles/app.min.css">
<link type="text/css" rel="stylesheet" href="styles/iframe.css">
<link type="text/css" rel="stylesheet" href="">
<script async defer src="https://buttons.github.io/buttons.js"></script>
</head>
<body class="layout small-header">
<div id="stickyNavbarOverlay"></div>
<div class="top-nav">
<div class="inner">
<a id="hamburger" role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
<div class="logo">
</div>
<div class="menu">
<div class="navigation">
<a
href="index.html"
class="link"
>
API Documentation
</a>
</div>
</div>
</div>
</div>
<div id="main">
<div
class="sidebar "
id="sidebarNav"
>
<nav>
<h2><a href="index.html">Documentation</a></h2><div class="category"><h3>Modules</h3><ul><li><a href="module-updux.html">updux</a></li></ul><h3>Classes</h3><ul><li><a href="Updux.html">Updux</a></li></ul></div>
</nav>
</div>
<div class="core" id="main-content-wrapper">
<div class="content">
<header class="page-title">
<p>Class</p>
<h1>Updux</h1>
</header>
<section>
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>Updux<span class="signature">()</span><span class="type-signature"></span></h2>
<div class="class-description"><p><code>Updux</code> is a way to minimize and simplify the boilerplate associated with the
creation of a <code>Redux</code> store. It takes a shorthand configuration
object, and generates the appropriate reducer, actions, middleware, etc.
In true <code>Redux</code>-like fashion, upduxes can be made of sub-upduxes (<code>subduxes</code> for short) for different slices of the root state.</p></div>
</header>
<article>
<div class="container-overview">
<div class='vertical-section'>
<div class="members">
<div class="member">
<div class=name>
<span class="tag">Constructor</span>
</div>
<h4 class="name" id="Updux">
<a class="href-link" href="#Updux">#</a>
<span class="code-name">
new Updux<span class="signature">()</span><span class="type-signature"></span>
</span>
</h4>
<dl class="details">
<p class="tag-source">
<a href="Updux.js.html" class="button">View Source</a>
<span>
<a href="Updux.js.html">Updux.js</a>, <a href="Updux.js.html#line23">line 23</a>
</span>
</p>
</dl>
</div>
</div>
</div>
</div>
<h3 class="subsection-title">Classes</h3>
<dl>
<dt><a href="Updux.html">Updux</a></dt>
<dd></dd>
</dl>
<div class='vertical-section'>
<h1>Members</h1>
<div class="members">
<div class="member">
<h4 class="name" id="actions">
<a class="href-link" href="#actions">#</a>
<span class="code-name">
actions
</span>
</h4>
<dl class="details">
<p class="tag-source">
<a href="Updux.js.html" class="button">View Source</a>
<span>
<a href="Updux.js.html">Updux.js</a>, <a href="Updux.js.html#line110">line 110</a>
</span>
</p>
</dl>
</div>
<div class="member">
<span class="method-parameter is-pulled-right">
<label>Type:</label>
<span class="param-type">unknown</span>
</span>
<h4 class="name" id="initial">
<a class="href-link" href="#initial">#</a>
<span class="code-name">
initial
</span>
</h4>
<dl class="details">
<p class="tag-source">
<a href="Updux.js.html" class="button">View Source</a>
<span>
<a href="Updux.js.html">Updux.js</a>, <a href="Updux.js.html#line103">line 103</a>
</span>
</p>
</dl>
</div>
</div>
</div>
</article>
</section>
</div>
<footer class="footer">
<div class="content has-text-centered">
<p>Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.7</a></p>
<p class="sidebar-created-by">
<a href="https://github.com/SoftwareBrothers/better-docs" target="_blank">BetterDocs theme</a> provided with <i class="fas fa-heart"></i> by
<a href="http://softwarebrothers.co" target="_blank">SoftwareBrothers - JavaScript Development Agency</a>
</p>
</div>
</footer>
</div>
<div id="side-nav" class="side-nav">
</div>
</div>
<script src="scripts/app.min.js"></script>
<script>PR.prettyPrint();</script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -1,432 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> Updux.js</title>
<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="./build/entry.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Roboto:100,400,700|Inconsolata,700" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://jmblog.github.io/color-themes-for-google-code-prettify/themes/tomorrow-night.min.css">
<link type="text/css" rel="stylesheet" href="styles/app.min.css">
<link type="text/css" rel="stylesheet" href="styles/iframe.css">
<link type="text/css" rel="stylesheet" href="">
<script async defer src="https://buttons.github.io/buttons.js"></script>
</head>
<body class="layout small-header">
<div id="stickyNavbarOverlay"></div>
<div class="top-nav">
<div class="inner">
<a id="hamburger" role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
<div class="logo">
</div>
<div class="menu">
<div class="navigation">
<a
href="index.html"
class="link"
>
API Documentation
</a>
</div>
</div>
</div>
</div>
<div id="main">
<div
class="sidebar "
id="sidebarNav"
>
<nav>
<h2><a href="index.html">Documentation</a></h2><div class="category"><h3>Modules</h3><ul><li><a href="module-updux.html">updux</a></li></ul><h3>Classes</h3><ul><li><a href="Updux.html">Updux</a></li></ul></div>
</nav>
</div>
<div class="core" id="main-content-wrapper">
<div class="content">
<header class="page-title">
<p>Source</p>
<h1>Updux.js</h1>
</header>
<section>
<article>
<pre class="prettyprint source linenums"><code>/* TODO change * for leftovers to +, change subscriptions to reactions */
import moize from 'moize';
import u from '@yanick/updeep';
import { createStore as reduxCreateStore, applyMiddleware } from 'redux';
import { get, map, mapValues, merge, difference } from 'lodash-es';
import { buildInitial } from './buildInitial/index.js';
import { buildActions } from './buildActions/index.js';
import { buildSelectors } from './buildSelectors/index.js';
import { action } from './actions.js';
import { buildUpreducer } from './buildUpreducer.js';
import {
buildMiddleware,
augmentMiddlewareApi,
} from './buildMiddleware/index.js';
/**
* `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.
*/
export class Updux {
/** @type { unknown } */
#initial = {};
#subduxes = {};
/** @type Record&lt;string,Function> */
#actions = {};
#selectors = {};
#mutations = {};
#effects = [];
#subscriptions = [];
#splatSelector = undefined;
#splatReaction = undefined;
constructor(config) {
this.#initial = config.initial ?? {};
this.#subduxes = config.subduxes ?? {};
if (config.subduxes) {
this.#subduxes = mapValues(config.subduxes, (sub) =>
sub instanceof Updux ? sub : new Updux(sub)
);
}
if (config.actions) {
for (const [type, actionArg] of Object.entries(config.actions)) {
if (typeof actionArg === 'function' &amp;&amp; actionArg.type) {
this.#actions[type] = actionArg;
} else {
this.#actions[type] = action(type, actionArg);
}
}
}
this.#selectors = config.selectors ?? {};
this.#mutations = config.mutations ?? {};
this.#splatSelector = config.splatSelector;
Object.keys(this.#mutations)
.filter((action) => action !== '*')
.filter((action) => !this.actions.hasOwnProperty(action))
.forEach((action) => {
throw new Error(`action '${action}' is not defined`);
});
if (config.effects) {
this.#effects = Object.entries(config.effects);
}
this.#subscriptions = config.subscriptions ?? [];
this.#splatReaction = config.splatReaction;
}
#memoInitial = moize(buildInitial);
#memoActions = moize(buildActions);
#memoSelectors = moize(buildSelectors);
#memoUpreducer = moize(buildUpreducer);
#memoMiddleware = moize(buildMiddleware);
get subscriptions() {
return this.#subscriptions;
}
setSplatSelector(name, f) {
this.#splatSelector = [name, f];
}
get middleware() {
return this.#memoMiddleware(
this.#effects,
this.actions,
this.selectors,
this.#subduxes
);
}
/** @member { unknown } */
get initial() {
return this.#memoInitial(this.#initial, this.#subduxes);
}
/**
* @return {Record&lt;string,Function>}
*/
get actions() {
return this.#memoActions(this.#actions, this.#subduxes);
}
get selectors() {
return this.#memoSelectors(
this.#selectors,
this.#splatSelector,
this.#subduxes
);
}
get upreducer() {
return this.#memoUpreducer(
this.initial,
this.#mutations,
this.#subduxes
);
}
get reducer() {
return (state, action) => this.upreducer(action)(state);
}
addSubscription(subscription) {
this.#subscriptions = [...this.#subscriptions, subscription];
}
addAction(type, payloadFunc) {
const theAction = action(type, payloadFunc);
this.#actions = { ...this.#actions, [type]: theAction };
return theAction;
}
addSelector(name, func) {
this.#selectors = {
...this.#selectors,
[name]: func,
};
return func;
}
addMutation(name, mutation) {
if (typeof name === 'function') name = name.type;
this.#mutations = {
...this.#mutations,
[name]: mutation,
};
return this;
}
addEffect(action, effect) {
this.#effects = [...this.#effects, [action, effect]];
}
splatSubscriber(store, inner, splatReaction) {
const cache = {};
return () => (state, previous, unsub) => {
const cacheKeys = Object.keys(cache);
const newKeys = difference(Object.keys(state), cacheKeys);
for (const slice of newKeys) {
let localStore = {
...store,
getState: () => store.getState()[slice],
};
cache[slice] = [];
if (typeof splatReaction === 'function') {
localStore = {
...localStore,
...splatReaction(localStore, slice),
};
}
const { unsub, subscriber, subscriberRaw } =
inner.subscribeAll(localStore);
cache[slice].push({ unsub, subscriber, subscriberRaw });
subscriber();
}
const deletedKeys = difference(cacheKeys, Object.keys(state));
for (const deleted of deletedKeys) {
for (const inner of cache[deleted]) {
inner.subscriber();
inner.unsub();
}
delete cache[deleted];
}
};
}
subscribeTo(store, subscription, setupArgs = []) {
const localStore = augmentMiddlewareApi(
{
...store,
subscribe: (subscriber) =>
this.subscribeTo(store, () => subscriber),
},
this.actions,
this.selectors
);
const subscriber = subscription(localStore, ...setupArgs);
let previous;
const memoSub = () => {
const state = store.getState();
if (state === previous) return;
let p = previous;
previous = state;
subscriber(state, p, unsub);
};
let ret = store.subscribe(memoSub);
const unsub = typeof ret === 'function' ? ret : ret.unsub;
return {
unsub,
subscriber: memoSub,
subscriberRaw: subscriber,
};
}
subscribeAll(store) {
let results = this.#subscriptions.map((sub) =>
this.subscribeTo(store, sub)
);
for (const subdux in this.#subduxes) {
if (subdux !== '*') {
const localStore = {
...store,
getState: () => get(store.getState(), subdux),
};
results.push(this.#subduxes[subdux].subscribeAll(localStore));
}
}
if (this.#splatReaction) {
results.push(
this.subscribeTo(
store,
this.splatSubscriber(
store,
this.#subduxes['*'],
this.#splatReaction
)
)
);
}
return {
unsub: () => results.forEach(({ unsub }) => unsub()),
subscriber: () => results.forEach(({ subscriber }) => subscriber()),
subscriberRaw: (...args) =>
results.forEach(({ subscriberRaw }) => subscriberRaw(...args)),
};
}
createStore(initial) {
const store = reduxCreateStore(
this.reducer,
initial ?? this.initial,
applyMiddleware(this.middleware)
);
store.actions = this.actions;
store.selectors = this.selectors;
merge(
store.getState,
mapValues(this.selectors, (selector) => {
return (...args) => {
let result = selector(store.getState());
if (typeof result === 'function') return result(...args);
return result;
};
})
);
for (const action in this.actions) {
store.dispatch[action] = (...args) => {
return store.dispatch(this.actions[action](...args));
};
}
this.subscribeAll(store);
return store;
}
}
const x = new Updux();
x.selectors;
</code></pre>
</article>
</section>
</div>
<footer class="footer">
<div class="content has-text-centered">
<p>Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.7</a></p>
<p class="sidebar-created-by">
<a href="https://github.com/SoftwareBrothers/better-docs" target="_blank">BetterDocs theme</a> provided with <i class="fas fa-heart"></i> by
<a href="http://softwarebrothers.co" target="_blank">SoftwareBrothers - JavaScript Development Agency</a>
</p>
</div>
</footer>
</div>
<div id="side-nav" class="side-nav">
</div>
</div>
<script src="scripts/app.min.js"></script>
<script>PR.prettyPrint();</script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -1,7 +0,0 @@
- [Intro](/README.md)
- [Tutorial](/tutorial.md)
- [Concepts](/concepts.md)
- [Recipes](/recipes.md)
- API
- [Top-level exports](/exports.md)
- [main index](/API/globals.md)

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

File diff suppressed because one or more lines are too long

View File

@ -1,33 +0,0 @@
declare namespace typedoc {
namespace search {
namespace data {
const kinds: {
"32": string;
"64": string;
"128": string;
"256": string;
"512": string;
"1024": string;
"2048": string;
"65536": string;
"262144": string;
"4194304": string;
};
const rows: ({
id: number;
kind: number;
name: string;
url: string;
classes: string;
parent?: undefined;
} | {
id: number;
kind: number;
name: string;
url: string;
classes: string;
parent: string;
})[];
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,812 +0,0 @@
<!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="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../assets/css/main.css">
</head>
<body>
<header>
<div class="tsd-page-toolbar">
<div class="container">
<div class="table-wrap">
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.js" data-base="..">
<div class="field">
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
<input id="tsd-search-field" type="text" />
</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>
<input type="checkbox" id="tsd-filter-externals" checked />
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
<input type="checkbox" id="tsd-filter-only-exported" />
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</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="../globals.html">Globals</a>
</li>
<li>
<a href="updux.html">Updux</a>
</li>
</ul>
<h1>Class Updux&lt;S&gt;</h1>
</div>
</div>
</header>
<div class="container container-main">
<div class="row">
<div class="col-8 col-content">
<section class="tsd-panel tsd-comment">
<div class="tsd-comment tsd-typography">
<div class="lead">
<p><code>Updux</code> is a way to minimize and simplify the boilerplate associated with the
creation of a <code>Redux</code> store. It takes a shorthand configuration
object, and generates the appropriate reducer, actions, middleware, etc.
In true <code>Redux</code>-like fashion, upduxes can be made of sub-upduxes (<code>subduxes</code> for short) for different slices of the root state.</p>
</div>
</div>
</section>
<section class="tsd-panel tsd-type-parameters">
<h3>Type parameters</h3>
<ul class="tsd-type-parameters">
<li>
<h4>S</h4>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Store&#39;s state type. Defaults to <code>any</code>.</p>
</div>
</div>
</li>
</ul>
</section>
<section class="tsd-panel tsd-hierarchy">
<h3>Hierarchy</h3>
<ul class="tsd-hierarchy">
<li>
<span class="target">Updux</span>
</li>
</ul>
</section>
<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>Constructors</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-constructor tsd-parent-kind-class"><a href="updux.html#constructor" class="tsd-kind-icon">constructor</a></li>
</ul>
</section>
<section class="tsd-index-section ">
<h3>Properties</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-property tsd-parent-kind-class"><a href="updux.html#groommutations" class="tsd-kind-icon">groom<wbr>Mutations</a></li>
<li class="tsd-kind-property tsd-parent-kind-class"><a href="updux.html#initial" class="tsd-kind-icon">initial</a></li>
<li class="tsd-kind-property tsd-parent-kind-class"><a href="updux.html#subduxes" class="tsd-kind-icon">subduxes</a></li>
</ul>
</section>
<section class="tsd-index-section ">
<h3>Accessors</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#actions" class="tsd-kind-icon">actions</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#asdux" class="tsd-kind-icon">as<wbr>Dux</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#createstore" class="tsd-kind-icon">create<wbr>Store</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#middleware" class="tsd-kind-icon">middleware</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#mutations" class="tsd-kind-icon">mutations</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#reducer" class="tsd-kind-icon">reducer</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#subduxupreducer" class="tsd-kind-icon">subdux<wbr>Upreducer</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#upreducer" class="tsd-kind-icon">upreducer</a></li>
</ul>
</section>
<section class="tsd-index-section ">
<h3>Methods</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter"><a href="updux.html#addmutation" class="tsd-kind-icon">add<wbr>Mutation</a></li>
</ul>
</section>
</div>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Constructors</h2>
<section class="tsd-panel tsd-member tsd-kind-constructor tsd-parent-kind-class">
<a name="constructor" class="tsd-anchor"></a>
<h3>constructor</h3>
<ul class="tsd-signatures tsd-kind-constructor tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon">new <wbr>Updux<span class="tsd-signature-symbol">(</span>config<span class="tsd-signature-symbol">?: </span><a href="../globals.html#upduxconfig" class="tsd-signature-type">UpduxConfig</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="updux.html" class="tsd-signature-type">Updux</a></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L109">updux.ts:109</a></li>
</ul>
</aside>
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5><span class="tsd-flag ts-flagDefault value">Default value</span> config: <a href="../globals.html#upduxconfig" class="tsd-signature-type">UpduxConfig</a><span class="tsd-signature-symbol"> =&nbsp;{}</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <a href="updux.html" class="tsd-signature-type">Updux</a></h4>
</li>
</ul>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Properties</h2>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="groommutations" class="tsd-anchor"></a>
<h3>groom<wbr>Mutations</h3>
<div class="tsd-signature tsd-kind-icon">groom<wbr>Mutations<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">function</span></div>
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L99">updux.ts:99</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Function that can be provided to alter all local mutations of the updux
(the mutations of subduxes are left untouched).</p>
</div>
<p>Can be used, for example, for Immer integration:</p>
<pre><code><span class="hljs-keyword">import</span> Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">import</span> { produce } <span class="hljs-keyword">from</span> <span class="hljs-string">'Immer'</span>;
<span class="hljs-keyword">const</span> updux = <span class="hljs-keyword">new</span> Updux({
<span class="hljs-attr">initial</span>: { <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span> },
<span class="hljs-attr">groomMutations</span>: <span class="hljs-function"><span class="hljs-params">mutation</span> =&gt;</span> <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> produce( mutation(...args) ),
<span class="hljs-attr">mutations</span>: {
<span class="hljs-attr">add</span>: <span class="hljs-function">(<span class="hljs-params">inc=<span class="hljs-number">1</span></span>) =&gt;</span> <span class="hljs-function"><span class="hljs-params">draft</span> =&gt;</span> draft.counter += inc
}
});
</code></pre><p>Or perhaps for debugging:</p>
<pre><code><span class="hljs-keyword">import</span> Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">const</span> updux = <span class="hljs-keyword">new</span> Updux({
<span class="hljs-attr">initial</span>: { <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span> },
<span class="hljs-attr">groomMutations</span>: <span class="hljs-function"><span class="hljs-params">mutation</span> =&gt;</span> <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> <span class="hljs-function"><span class="hljs-params">state</span> =&gt;</span> {
<span class="hljs-built_in">console</span>.log( <span class="hljs-string">"got action "</span>, args[<span class="hljs-number">1</span>] );
<span class="hljs-keyword">return</span> mutation(...args)(state);
}
});
</code></pre>
</div>
<div class="tsd-type-declaration">
<h4>Type declaration</h4>
<ul class="tsd-parameters">
<li class="tsd-parameter-siganture">
<ul class="tsd-signatures tsd-kind-type-literal tsd-parent-kind-property">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span>mutation<span class="tsd-signature-symbol">: </span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>mutation: <a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</li>
</ul>
</div>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="initial" class="tsd-anchor"></a>
<h3>initial</h3>
<div class="tsd-signature tsd-kind-icon">initial<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">S</span></div>
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L62">updux.ts:62</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Default initial state of the reducer. If applicable, merges the
initial states of <code>config</code> and <code>subduxes</code>, with <code>config</code> having
precedence.</p>
</div>
<p>If nothing was provided, defaults to an empty object.</p>
</div>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="subduxes" class="tsd-anchor"></a>
<h3>subduxes</h3>
<div class="tsd-signature tsd-kind-icon">subduxes<span class="tsd-signature-symbol">:</span> <a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="updux.html" class="tsd-signature-type">Updux</a><span class="tsd-signature-symbol">&gt;</span></div>
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L53">updux.ts:53</a></li>
</ul>
</aside>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Accessors</h2>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="actions" class="tsd-anchor"></a>
<h3>actions</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> actions<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="../globals.html#actioncreator" class="tsd-signature-type">ActionCreator</a><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L162">updux.ts:162</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Action creators for all actions defined or used in the actions, mutations, effects and subduxes
of the updux config.</p>
</div>
<p>Non-custom action creators defined in <code>actions</code> have the signature <code>(payload={},meta={}) =&gt; ({type,
payload,meta})</code> (with the extra sugar that if <code>meta</code> or <code>payload</code> are not
specified, the key is not present in the produced action).</p>
<p>If the same action appears in multiple locations, the precedence order
determining which one will prevail is</p>
<pre><code>actions generated <span class="hljs-keyword">from</span> mutations/effects &lt; non-<span class="hljs-keyword">custom</span> subduxes actions &lt;
<span class="hljs-keyword">custom</span> subduxes actions &lt; <span class="hljs-keyword">custom</span> actions</code></pre>
</div>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="../globals.html#actioncreator" class="tsd-signature-type">ActionCreator</a><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="asdux" class="tsd-anchor"></a>
<h3>as<wbr>Dux</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> asDux<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#dux" class="tsd-signature-type">Dux</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L258">updux.ts:258</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Returns a
<a href="https://github.com/erikras/ducks-modular-redux">ducks</a>-like
plain object holding the reducer from the Updux object and all
its trimmings.</p>
</div>
</div>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#dux" class="tsd-signature-type">Dux</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="createstore" class="tsd-anchor"></a>
<h3>create<wbr>Store</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> createStore<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">function</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L241">updux.ts:241</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Same as doing</p>
</div>
<pre><code>import { createStore, applyMiddleware } <span class="hljs-keyword">from</span> <span class="hljs-string">'redux'</span>;
const { initial, reducer, middleware, actions } = updox(<span class="hljs-built_in">..</span>.);
const store = createStore( initial, reducer, applyMiddleware(middleware) );
<span class="hljs-keyword">for</span> ( let<span class="hljs-built_in"> type </span><span class="hljs-keyword">in</span> actions ) {
store.dispatch[type] = (<span class="hljs-built_in">..</span>.args) =&gt; {
store.dispatch(actions[type](<span class="hljs-built_in">..</span>.args))
};
}</code></pre><p>So that later on you can do</p>
<pre><code>store.dispatch.addTodo<span class="hljs-comment">(...)</span>;
<span class="hljs-comment">// still work</span>
store.dispatch<span class="hljs-comment">( actions.addTodo(...)</span> );</code></pre>
</div>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">function</span></h4>
<ul class="tsd-parameters">
<li class="tsd-parameter-siganture">
<ul class="tsd-signatures tsd-kind-type-literal">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#storewithdispatchactions" class="tsd-signature-type">StoreWithDispatchActions</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<h4 class="tsd-returns-title">Returns <a href="../globals.html#storewithdispatchactions" class="tsd-signature-type">StoreWithDispatchActions</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="middleware" class="tsd-anchor"></a>
<h3>middleware</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> middleware<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#upduxmiddleware" class="tsd-signature-type">UpduxMiddleware</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L140">updux.ts:140</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>A middleware aggregating all the effects defined in the
updux and its subduxes. Effects of the updux itself are
done before the subduxes effects.
Note that <code>getState</code> will always return the state of the
local updux. The function <code>getRootState</code> is provided
alongside <code>getState</code> to get the root state.</p>
</div>
</div>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#upduxmiddleware" class="tsd-signature-type">UpduxMiddleware</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="mutations" class="tsd-anchor"></a>
<h3>mutations</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> mutations<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L191">updux.ts:191</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Merge of the updux and subduxes mutations. If an action triggers
mutations in both the main updux and its subduxes, the subduxes
mutations will be performed first.</p>
</div>
</div>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="reducer" class="tsd-anchor"></a>
<h3>reducer</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> reducer<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">function</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L182">updux.ts:182</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>A Redux reducer generated using the computed initial state and
mutations.</p>
</div>
</div>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">function</span></h4>
<ul class="tsd-parameters">
<li class="tsd-parameter-siganture">
<ul class="tsd-signatures tsd-kind-type-literal">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span>state<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">undefined</span>, action<span class="tsd-signature-symbol">: </span><a href="../globals.html#action" class="tsd-signature-type">Action</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">S</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>state: <span class="tsd-signature-type">S</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">undefined</span></h5>
</li>
<li>
<h5>action: <a href="../globals.html#action" class="tsd-signature-type">Action</a></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">S</span></h4>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="subduxupreducer" class="tsd-anchor"></a>
<h3>subdux<wbr>Upreducer</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> subduxUpreducer<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">function</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L212">updux.ts:212</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Returns the upreducer made of the merge of all sudbuxes reducers, without
the local mutations. Useful, for example, for sink mutations.</p>
</div>
<dl class="tsd-comment-tags">
<dt>example</dt>
<dd><pre><code><span class="hljs-keyword">import</span> todo <span class="hljs-keyword">from</span> <span class="hljs-string">'./todo'</span>; <span class="hljs-comment">// updux for a single todo</span>
<span class="hljs-keyword">import</span> Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">import</span> u <span class="hljs-keyword">from</span> <span class="hljs-string">'updeep'</span>;
<span class="hljs-keyword">const</span> todos = <span class="hljs-keyword">new</span> Updux({ initial: [], subduxes: { <span class="hljs-string">'*'</span>: todo } });
todos.addMutation(
todo.actions.done,
<span class="hljs-function">(<span class="hljs-params">{todo_id},action</span>) =&gt;</span> u.map( u.if( u.is(<span class="hljs-string">'id'</span>,todo_id) ), todos.subduxUpreducer(action) )
<span class="hljs-literal">true</span>
);</code></pre></dd>
</dl>
</div>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">function</span></h4>
<ul class="tsd-parameters">
<li class="tsd-parameter-siganture">
<ul class="tsd-signatures tsd-kind-type-literal">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span>action<span class="tsd-signature-symbol">: </span><a href="../globals.html#action" class="tsd-signature-type">Action</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">function</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>action: <a href="../globals.html#action" class="tsd-signature-type">Action</a></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">function</span></h4>
<ul class="tsd-parameters">
<li class="tsd-parameter-siganture">
<ul class="tsd-signatures tsd-kind-type-literal">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span>state<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">S</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>state: <span class="tsd-signature-type">S</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">S</span></h4>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="upreducer" class="tsd-anchor"></a>
<h3>upreducer</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> upreducer<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#upreducer" class="tsd-signature-type">Upreducer</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L174">updux.ts:174</a></li>
</ul>
</aside>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#upreducer" class="tsd-signature-type">Upreducer</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Methods</h2>
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter">
<a name="addmutation" class="tsd-anchor"></a>
<h3>add<wbr>Mutation</h3>
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter">
<li class="tsd-signature tsd-kind-icon">add<wbr>Mutation&lt;A&gt;<span class="tsd-signature-symbol">(</span>creator<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">A</span>, mutation<span class="tsd-signature-symbol">: </span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">A extends (...args: any[]) &#x3D;&gt; infer R ? R : never</span><span class="tsd-signature-symbol">&gt;</span>, isSink<span class="tsd-signature-symbol">?: </span><span class="tsd-signature-type">undefined</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">false</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">true</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">void</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/updux.ts#L283">updux.ts:283</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Adds a mutation and its associated action to the updux.
If a local mutation was already associated to the action,
it will be replaced by the new one.</p>
</div>
<dl class="tsd-comment-tags">
<dt>example</dt>
<dd><pre><code>updux.addMutation( add, inc =&gt; <span class="hljs-keyword">state</span> =&gt; <span class="hljs-keyword">state</span> + inc );</code></pre></dd>
</dl>
</div>
<h4 class="tsd-type-parameters-title">Type parameters</h4>
<ul class="tsd-type-parameters">
<li>
<h4>A<span class="tsd-signature-symbol">: </span><a href="../globals.html#actioncreator" class="tsd-signature-type">ActionCreator</a></h4>
</li>
</ul>
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>creator: <span class="tsd-signature-type">A</span></h5>
</li>
<li>
<h5>mutation: <a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">A extends (...args: any[]) &#x3D;&gt; infer R ? R : never</span><span class="tsd-signature-symbol">&gt;</span></h5>
</li>
<li>
<h5><span class="tsd-flag ts-flagOptional">Optional</span> isSink: <span class="tsd-signature-type">undefined</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">false</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">true</span></h5>
<div class="tsd-comment tsd-typography">
<p>If <code>true</code>, disables the subduxes mutations for this action. To
conditionally run the subduxes mutations, check out <a href="updux.html#subduxupreducer">subduxUpreducer</a>.</p>
</div>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></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="globals ">
<a href="../globals.html"><em>Globals</em></a>
</li>
</ul>
</nav>
<nav class="tsd-navigation secondary menu-sticky">
<ul class="before-current">
</ul>
<ul class="current">
<li class="current tsd-kind-class tsd-has-type-parameter">
<a href="updux.html" class="tsd-kind-icon">Updux</a>
<ul>
<li class=" tsd-kind-constructor tsd-parent-kind-class">
<a href="updux.html#constructor" class="tsd-kind-icon">constructor</a>
</li>
<li class=" tsd-kind-property tsd-parent-kind-class">
<a href="updux.html#groommutations" class="tsd-kind-icon">groom<wbr>Mutations</a>
</li>
<li class=" tsd-kind-property tsd-parent-kind-class">
<a href="updux.html#initial" class="tsd-kind-icon">initial</a>
</li>
<li class=" tsd-kind-property tsd-parent-kind-class">
<a href="updux.html#subduxes" class="tsd-kind-icon">subduxes</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#actions" class="tsd-kind-icon">actions</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#asdux" class="tsd-kind-icon">as<wbr>Dux</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#createstore" class="tsd-kind-icon">create<wbr>Store</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#middleware" class="tsd-kind-icon">middleware</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#mutations" class="tsd-kind-icon">mutations</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#reducer" class="tsd-kind-icon">reducer</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#subduxupreducer" class="tsd-kind-icon">subdux<wbr>Upreducer</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#upreducer" class="tsd-kind-icon">upreducer</a>
</li>
<li class=" tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter">
<a href="updux.html#addmutation" class="tsd-kind-icon">add<wbr>Mutation</a>
</li>
</ul>
</li>
</ul>
<ul class="after-current">
<li class=" tsd-kind-interface tsd-has-type-parameter">
<a href="../interfaces/upduxmiddlewareapi.html" class="tsd-kind-icon">Updux<wbr>MiddlewareAPI</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#action" class="tsd-kind-icon">Action</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#actioncreator" class="tsd-kind-icon">Action<wbr>Creator</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#actionpair" class="tsd-kind-icon">Action<wbr>Pair</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../globals.html#actionpayloadgenerator" class="tsd-kind-icon">Action<wbr>Payload<wbr>Generator</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#dictionary" class="tsd-kind-icon">Dictionary</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#dux" class="tsd-kind-icon">Dux</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter tsd-is-not-exported">
<a href="../globals.html#maybepayload" class="tsd-kind-icon">Maybe<wbr>Payload</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#mutation" class="tsd-kind-icon">Mutation</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#next" class="tsd-kind-icon">Next</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter tsd-is-not-exported">
<a href="../globals.html#storewithdispatchactions" class="tsd-kind-icon">Store<wbr>With<wbr>Dispatch<wbr>Actions</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#submutations" class="tsd-kind-icon">Sub<wbr>Mutations</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#upduxconfig" class="tsd-kind-icon">Updux<wbr>Config</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../globals.html#upduxdispatch" class="tsd-kind-icon">Updux<wbr>Dispatch</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#upduxmiddleware" class="tsd-kind-icon">Updux<wbr>Middleware</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#upreducer" class="tsd-kind-icon">Upreducer</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#middlewarefor" class="tsd-kind-icon">Middleware<wbr>For</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#actioncreator" class="tsd-kind-icon">action<wbr>Creator</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#actionfor" class="tsd-kind-icon">action<wbr>For</a>
</li>
<li class=" tsd-kind-function">
<a href="../globals.html#buildactions" class="tsd-kind-icon">build<wbr>Actions</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildcreatestore" class="tsd-kind-icon">build<wbr>Create<wbr>Store</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildinitial" class="tsd-kind-icon">build<wbr>Initial</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildmiddleware" class="tsd-kind-icon">build<wbr>Middleware</a>
</li>
<li class=" tsd-kind-function">
<a href="../globals.html#buildmutations" class="tsd-kind-icon">build<wbr>Mutations</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildupreducer" class="tsd-kind-icon">build<wbr>Upreducer</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#composemutations" class="tsd-kind-icon">compose<wbr>Mutations</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#slicemw" class="tsd-kind-icon">slice<wbr>Mw</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<footer class="with-border-bottom">
<div class="container">
<h2>Legend</h2>
<div class="tsd-legend-group">
<ul class="tsd-legend">
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
<li class="tsd-kind-type-alias tsd-has-type-parameter"><span class="tsd-kind-icon">Type alias with type parameter</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
</ul>
</div>
</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/js/main.js"></script>
<script>if (location.protocol == 'file:') document.write('<script src="../assets/js/search.js"><' + '/script>');</script>
</body>
</html>

View File

@ -1,111 +0,0 @@
# Updux concepts
## Actions and action generators
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) {
return Object.assign( payload => ({type, payload}), { type } )
}
```
### 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
actions before they hit the reducer, something that `redux-saga` and
`rematch` don't allow.
An effect has the signature
```js
const effect = ({ getState, dispatch }) => next => action => { ... }
```
## Selectors
Selectors are used to get data derived from the store's state.
The signature of a selector function is either `(state) => result`
or `(state) => (...args) => result`. The selector instances attached
to a store's `getState` already do the first call on `state`, so you don't have to.
```js
const dux = new Updux({
initial: {
foo: 1,
},
selectors: {
getFoo: ({foo}) => foo,
getFooPlus: ({foo}) => increment => foo + increment,
}
});
console.log(dux.selectors.getFoo({foo: 2})); // prints 2
console.log(dux.selectors.getFooPlus({foo: 2})(3)); // prints 5
const store = dux.createStore();
console.log(store.selectors.getFoo({foo: 2})); // prints 2
console.log(store.selectors.getFooPlus({foo: 2})(3)); // prints 5
console.log(store.getState.getFoo()); // prints 2
console.log(store.getState.getFooPlus(3)); // prints 5
```

View File

@ -1,12 +0,0 @@
# Top-level exports
## Default export
* [Updux](/API/classes/updux)
## Exports
* [Updux](/API/classes/updux)
* [dux](/API/globals?id=const-dux)
* [coduxes](/API/globals?id=const-coduxes)
* [subEffects](/API/globals?id=const-subeffects)

Binary file not shown.

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 116 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 118 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 120 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 114 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 120 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 117 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>updux - Updeep-friendly Redux helper framework</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Updeep-friendly Redux helper framework">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
</head>
<body>
<div id="app"></div>
<script>
window.$docsify = {
name: 'updux',
repo: 'https://github.com/yanick/updux',
loadSidebar: true,
subMaxLevel: 4,
relativePath: true,
}
</script>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
</body>
</html>

View File

@ -1,132 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> index.js</title>
<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="./build/entry.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Roboto:100,400,700|Inconsolata,700" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://jmblog.github.io/color-themes-for-google-code-prettify/themes/tomorrow-night.min.css">
<link type="text/css" rel="stylesheet" href="styles/app.min.css">
<link type="text/css" rel="stylesheet" href="styles/iframe.css">
<link type="text/css" rel="stylesheet" href="">
<script async defer src="https://buttons.github.io/buttons.js"></script>
</head>
<body class="layout small-header">
<div id="stickyNavbarOverlay"></div>
<div class="top-nav">
<div class="inner">
<a id="hamburger" role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
<div class="logo">
</div>
<div class="menu">
<div class="navigation">
<a
href="index.html"
class="link"
>
API Documentation
</a>
</div>
</div>
</div>
</div>
<div id="main">
<div
class="sidebar "
id="sidebarNav"
>
<nav>
<h2><a href="index.html">Documentation</a></h2><div class="category"><h3>Modules</h3><ul><li><a href="module-updux.html">updux</a></li></ul><h3>Classes</h3><ul><li><a href="Updux.html">Updux</a></li></ul></div>
</nav>
</div>
<div class="core" id="main-content-wrapper">
<div class="content">
<header class="page-title">
<p>Source</p>
<h1>index.js</h1>
</header>
<section>
<article>
<pre class="prettyprint source linenums"><code>import 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
*/
</code></pre>
</article>
</section>
</div>
<footer class="footer">
<div class="content has-text-centered">
<p>Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.7</a></p>
<p class="sidebar-created-by">
<a href="https://github.com/SoftwareBrothers/better-docs" target="_blank">BetterDocs theme</a> provided with <i class="fas fa-heart"></i> by
<a href="http://softwarebrothers.co" target="_blank">SoftwareBrothers - JavaScript Development Agency</a>
</p>
</div>
</footer>
</div>
<div id="side-nav" class="side-nav">
</div>
</div>
<script src="scripts/app.min.js"></script>
<script>PR.prettyPrint();</script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -1,337 +0,0 @@
<!doctype html>
<html class="default no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>UpduxMiddlewareAPI | updux</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../assets/css/main.css">
</head>
<body>
<header>
<div class="tsd-page-toolbar">
<div class="container">
<div class="table-wrap">
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.js" data-base="..">
<div class="field">
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
<input id="tsd-search-field" type="text" />
</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>
<input type="checkbox" id="tsd-filter-externals" checked />
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
<input type="checkbox" id="tsd-filter-only-exported" />
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</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="../globals.html">Globals</a>
</li>
<li>
<a href="upduxmiddlewareapi.html">UpduxMiddlewareAPI</a>
</li>
</ul>
<h1>Interface UpduxMiddlewareAPI&lt;S&gt;</h1>
</div>
</div>
</header>
<div class="container container-main">
<div class="row">
<div class="col-8 col-content">
<section class="tsd-panel tsd-type-parameters">
<h3>Type parameters</h3>
<ul class="tsd-type-parameters">
<li>
<h4>S</h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-hierarchy">
<h3>Hierarchy</h3>
<ul class="tsd-hierarchy">
<li>
<span class="target">UpduxMiddlewareAPI</span>
</li>
</ul>
</section>
<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>Properties</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-property tsd-parent-kind-interface"><a href="upduxmiddlewareapi.html#dispatch" class="tsd-kind-icon">dispatch</a></li>
</ul>
</section>
<section class="tsd-index-section ">
<h3>Methods</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-method tsd-parent-kind-interface"><a href="upduxmiddlewareapi.html#getrootstate" class="tsd-kind-icon">get<wbr>Root<wbr>State</a></li>
<li class="tsd-kind-method tsd-parent-kind-interface"><a href="upduxmiddlewareapi.html#getstate" class="tsd-kind-icon">get<wbr>State</a></li>
</ul>
</section>
</div>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Properties</h2>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-interface">
<a name="dispatch" class="tsd-anchor"></a>
<h3>dispatch</h3>
<div class="tsd-signature tsd-kind-icon">dispatch<span class="tsd-signature-symbol">:</span> <a href="../globals.html#upduxdispatch" class="tsd-signature-type">UpduxDispatch</a></div>
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/types.ts#L187">types.ts:187</a></li>
</ul>
</aside>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Methods</h2>
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-interface">
<a name="getrootstate" class="tsd-anchor"></a>
<h3>get<wbr>Root<wbr>State</h3>
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-interface">
<li class="tsd-signature tsd-kind-icon">get<wbr>Root<wbr>State<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">S</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/types.ts#L189">types.ts:189</a></li>
</ul>
</aside>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">S</span></h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-interface">
<a name="getstate" class="tsd-anchor"></a>
<h3>get<wbr>State</h3>
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-interface">
<li class="tsd-signature tsd-kind-icon">get<wbr>State<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">any</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/yanick/updux/blob/8d4542f/src/types.ts#L188">types.ts:188</a></li>
</ul>
</aside>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">any</span></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="globals ">
<a href="../globals.html"><em>Globals</em></a>
</li>
</ul>
</nav>
<nav class="tsd-navigation secondary menu-sticky">
<ul class="before-current">
<li class=" tsd-kind-class tsd-has-type-parameter">
<a href="../classes/updux.html" class="tsd-kind-icon">Updux</a>
</li>
</ul>
<ul class="current">
<li class="current tsd-kind-interface tsd-has-type-parameter">
<a href="upduxmiddlewareapi.html" class="tsd-kind-icon">Updux<wbr>MiddlewareAPI</a>
<ul>
<li class=" tsd-kind-property tsd-parent-kind-interface">
<a href="upduxmiddlewareapi.html#dispatch" class="tsd-kind-icon">dispatch</a>
</li>
<li class=" tsd-kind-method tsd-parent-kind-interface">
<a href="upduxmiddlewareapi.html#getrootstate" class="tsd-kind-icon">get<wbr>Root<wbr>State</a>
</li>
<li class=" tsd-kind-method tsd-parent-kind-interface">
<a href="upduxmiddlewareapi.html#getstate" class="tsd-kind-icon">get<wbr>State</a>
</li>
</ul>
</li>
</ul>
<ul class="after-current">
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#action" class="tsd-kind-icon">Action</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#actioncreator" class="tsd-kind-icon">Action<wbr>Creator</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#actionpair" class="tsd-kind-icon">Action<wbr>Pair</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../globals.html#actionpayloadgenerator" class="tsd-kind-icon">Action<wbr>Payload<wbr>Generator</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#dictionary" class="tsd-kind-icon">Dictionary</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#dux" class="tsd-kind-icon">Dux</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter tsd-is-not-exported">
<a href="../globals.html#maybepayload" class="tsd-kind-icon">Maybe<wbr>Payload</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#mutation" class="tsd-kind-icon">Mutation</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#next" class="tsd-kind-icon">Next</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter tsd-is-not-exported">
<a href="../globals.html#storewithdispatchactions" class="tsd-kind-icon">Store<wbr>With<wbr>Dispatch<wbr>Actions</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#submutations" class="tsd-kind-icon">Sub<wbr>Mutations</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#upduxconfig" class="tsd-kind-icon">Updux<wbr>Config</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../globals.html#upduxdispatch" class="tsd-kind-icon">Updux<wbr>Dispatch</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#upduxmiddleware" class="tsd-kind-icon">Updux<wbr>Middleware</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#upreducer" class="tsd-kind-icon">Upreducer</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#middlewarefor" class="tsd-kind-icon">Middleware<wbr>For</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#actioncreator" class="tsd-kind-icon">action<wbr>Creator</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#actionfor" class="tsd-kind-icon">action<wbr>For</a>
</li>
<li class=" tsd-kind-function">
<a href="../globals.html#buildactions" class="tsd-kind-icon">build<wbr>Actions</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildcreatestore" class="tsd-kind-icon">build<wbr>Create<wbr>Store</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildinitial" class="tsd-kind-icon">build<wbr>Initial</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildmiddleware" class="tsd-kind-icon">build<wbr>Middleware</a>
</li>
<li class=" tsd-kind-function">
<a href="../globals.html#buildmutations" class="tsd-kind-icon">build<wbr>Mutations</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildupreducer" class="tsd-kind-icon">build<wbr>Upreducer</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#composemutations" class="tsd-kind-icon">compose<wbr>Mutations</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#slicemw" class="tsd-kind-icon">slice<wbr>Mw</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<footer class="with-border-bottom">
<div class="container">
<h2>Legend</h2>
<div class="tsd-legend-group">
<ul class="tsd-legend">
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
<li class="tsd-kind-type-alias tsd-has-type-parameter"><span class="tsd-kind-icon">Type alias with type parameter</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
</ul>
</div>
</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/js/main.js"></script>
<script>if (location.protocol == 'file:') document.write('<script src="../assets/js/search.js"><' + '/script>');</script>
</body>
</html>

View File

@ -1,313 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> updux</title>
<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="./build/entry.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Roboto:100,400,700|Inconsolata,700" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://jmblog.github.io/color-themes-for-google-code-prettify/themes/tomorrow-night.min.css">
<link type="text/css" rel="stylesheet" href="styles/app.min.css">
<link type="text/css" rel="stylesheet" href="styles/iframe.css">
<link type="text/css" rel="stylesheet" href="">
<script async defer src="https://buttons.github.io/buttons.js"></script>
</head>
<body class="layout small-header">
<div id="stickyNavbarOverlay"></div>
<div class="top-nav">
<div class="inner">
<a id="hamburger" role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
<div class="logo">
</div>
<div class="menu">
<div class="navigation">
<a
href="index.html"
class="link"
>
API Documentation
</a>
</div>
</div>
</div>
</div>
<div id="main">
<div
class="sidebar "
id="sidebarNav"
>
<nav>
<h2><a href="index.html">Documentation</a></h2><div class="category"><h3>Modules</h3><ul><li><a href="module-updux.html">updux</a></li></ul><h3>Classes</h3><ul><li><a href="Updux.html">Updux</a></li></ul></div>
</nav>
</div>
<div class="core" id="main-content-wrapper">
<div class="content">
<header class="page-title">
<p>Module</p>
<h1>updux</h1>
</header>
<section>
<header>
</header>
<article>
<div class="container-overview">
<div class="description"><p><code>Updux</code> is a way to minimize and simplify the boilerplate associated with the
creation of a <code>Redux</code> store. It takes a shorthand configuration
object, and generates the appropriate reducer, actions, middleware, etc.
In true <code>Redux</code>-like fashion, upduxes can be made of sub-upduxes (<code>subduxes</code> for short) for different slices of the root state.</p></div>
<dl class="details">
<p class="tag-source">
<a href="index.js.html" class="button">View Source</a>
<span>
<a href="index.js.html">index.js</a>, <a href="index.js.html#line10">line 10</a>
</span>
</p>
</dl>
</div>
<div class='vertical-section'>
<h1>Members</h1>
<div class="members">
<div class="member">
<h4 class="name" id=".Updux">
<a class="href-link" href="#.Updux">#</a>
<span class='tag'>static</span>
<span class="code-name">
Updux
</span>
</h4>
<div class="description">
<p>The <a href="Updux.html">Updux</a> class</p>
</div>
<dl class="details">
<p class="tag-source">
<a href="index.js.html" class="button">View Source</a>
<span>
<a href="index.js.html">index.js</a>, <a href="index.js.html#line7">line 7</a>
</span>
</p>
</dl>
</div>
</div>
</div>
</article>
</section>
</div>
<footer class="footer">
<div class="content has-text-centered">
<p>Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.7</a></p>
<p class="sidebar-created-by">
<a href="https://github.com/SoftwareBrothers/better-docs" target="_blank">BetterDocs theme</a> provided with <i class="fas fa-heart"></i> by
<a href="http://softwarebrothers.co" target="_blank">SoftwareBrothers - JavaScript Development Agency</a>
</p>
</div>
</footer>
</div>
<div id="side-nav" class="side-nav">
</div>
</div>
<script src="scripts/app.min.js"></script>
<script>PR.prettyPrint();</script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -1,107 +0,0 @@
# Recipes
## Mapping a mutation to all values of a state
Say you have a `todos` state that is an array of `todo` sub-states. It's easy
enough to have the main reducer map away all items to the sub-reducer:
```
const todo = new Updux({
actions: {
review: action('REVIEW'),
done: action('DONE',payload<int>()),
},
mutations: {
review: () => u({reviewed: true}),
done: () => u({done: true}),
},
});
const todos = new Updux({ initial: [] });
todos.addMutation(
todo.actions.review,
(_,action) => state => state.map( todo.upreducer(action) )
);
todos.addMutation(
todo.actions.done,
(id,action) => u.map(u.if(u.is('id',id), todo.upreducer(action))),
);
```
But `updeep` can iterate through all the items of an array (or the values of
an object) via the special key `*`. So the todos updux above can be
rewritten as:
```
const todos = new Updux({
subduxes: { '*': todo },
});
todos.addMutation(
todo.actions.done,
(id,action) => u.map(u.if(u.is('id',id), todo.upreducer(action))),
true
);
```
The advantages being that the actions/mutations/effects of the subdux will be
imported by the root updux as usual, and all actions not
overridden by a sink mutation will trickle down automatically.
## Usage with Immer
While Updux was created with Updeep in mind, it also plays very
well with [Immer](https://immerjs.github.io/immer/docs/introduction).
For example, taking this basic updux:
```
import Updux from 'updux';
const updux = new Updux({
initial: { counter: 0 },
mutations: {
add: (inc=1) => state => ({ counter: state.counter + inc })
}
});
```
Converting it to Immer would look like:
```
import Updux from 'updux';
import { produce } from 'immer';
const updux = new Updux({
initial: { counter: 0 },
mutations: {
add: (inc=1) => produce( draft => draft.counter += inc ) }
}
});
```
But since typing `produce` over and over is no fun, `groomMutations`
can be used to wrap all mutations with it:
```
import Updux from 'updux';
import { produce } from 'immer';
const updux = new Updux({
initial: { counter: 0 },
groomMutations: mutation => (...args) => produce( mutation(...args) ),
mutations: {
add: (inc=1) => draft => draft.counter += inc
}
});
```

View File

@ -1 +0,0 @@
"use strict";$().ready(function(){});var sidebarIsVisible=!1,toggleSidebar=function(e){var a=!(0<arguments.length&&void 0!==e)||e;$("#sidebarNav").toggleClass("sticky",a),$("#stickyNavbarOverlay").toggleClass("active",a),$("#hamburger").toggleClass("is-active"),sidebarIsVisible=a};$().ready(function(){$("#hamburger").click(function(){toggleSidebar(!sidebarIsVisible)}),$("#stickyNavbarOverlay").click(function(){sidebarIsVisible&&toggleSidebar(!1)})});var OFFSET=150;$().ready(function(){var o=$("#side-nav"),c=[];if($(".vertical-section").length||o.hide(),$(".vertical-section").each(function(e,a){var i=$(a),t=i.find("> h1").text();if(t){o.append($("<h3/>").text(t));var s=$("<ul></ul>");i.find(".members h4.name").each(function(e,a){var i=$(a),t=i.find(".code-name").clone().children().remove().end().text(),n=i.find("a").attr("href"),r=$('<a href="'.concat(n,'" />')).text(t);s.append($("<li></li>").append(r)),c.push({link:r,offset:i.offset().top})}),o.append(s)}else i.find(".members h4.name").each(function(e,a){var i=$(a),t=i.find(".code-name").clone().children().remove().end().text(),n=i.find("a").attr("href"),r=$('<a href="'.concat(n,'" />')).text(t);o.append(r),c.push({link:r,offset:i.offset().top})})}),!$.trim(o.text()))return o.hide();function e(){for(var e=n.scrollTop(),a=!1,i=c.length-1;0<=i;i--){var t=c[i];t.link.removeClass("is-active"),e+OFFSET>=t.offset?a?t.link.addClass("is-past"):(t.link.addClass("is-active"),a=!0):t.link.removeClass("is-past")}}var n=$("#main-content-wrapper");n.on("scroll",e),e(),c.forEach(function(e){e.link.click(function(){n.animate({scrollTop:e.offset-OFFSET+1},500)})})}),$().ready(function(){$("#sidebarNav a").each(function(e,a){var i=$(a).attr("href");window.location.pathname.match("/"+i)&&($(a).addClass("active"),$("#sidebarNav").scrollTop($(a).offset().top-150))})});

View File

View File

@ -1,26 +0,0 @@
/*global document */
(function() {
var source = document.getElementsByClassName('prettyprint source linenums');
var i = 0;
var lineNumber = 0;
var lineId;
var lines;
var totalLines;
var anchorHash;
if (source && source[0]) {
anchorHash = document.location.hash.substring(1);
lines = source[0].getElementsByTagName('li');
totalLines = lines.length;
for (; i < totalLines; i++) {
lineNumber++;
lineId = 'line' + lineNumber;
lines[i].id = lineId;
if (lineId === anchorHash) {
lines[i].className += ' selected';
}
}
}
})();

View File

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

View File

@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);

View File

@ -1 +0,0 @@
declare var q: any;

View File

@ -1,28 +0,0 @@
var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();

View File

View File

@ -1,39 +0,0 @@
(function() {
const input = document.querySelector('#search')
const targets = [ ...document.querySelectorAll('#sidebarNav li')]
input.addEventListener('keyup', () => {
// loop over each targets and hide the not corresponding ones
targets.forEach(target => {
if (!target.innerText.toLowerCase().includes(input.value.toLowerCase())) {
target.style.display = 'none'
/**
* Detects an empty list
* Remove the list and the list's title if the list is not displayed
*/
const list = [...target.parentNode.childNodes].filter( elem => elem.style.display !== 'none')
if (!list.length) {
target.parentNode.style.display = 'none'
target.parentNode.previousSibling.style.display = 'none'
}
/**
* Detects empty category
* Remove the entire category if no item is displayed
*/
const category = [...target.parentNode.parentNode.childNodes]
.filter( elem => elem.tagName !== 'H2' && elem.style.display !== 'none')
if (!category.length) {
target.parentNode.parentNode.style.display = 'none'
}
} else {
target.parentNode.style.display = 'block'
target.parentNode.previousSibling.style.display = 'block'
target.parentNode.parentNode.style.display = 'block'
target.style.display = 'block'
}
})
})
})()

File diff suppressed because one or more lines are too long

View File

@ -1,13 +0,0 @@
.bd__button {
padding: 10px 0;
text-align: right;
}
.bd__button > a{
font-weight: 100;
text-decoration: none;
color: #BDC3CB;
font-family: sans-serif;
}
.bd__button > a:hover {
color: #798897;
}

View File

@ -1,358 +0,0 @@
@font-face {
font-family: 'Open Sans';
font-weight: normal;
font-style: normal;
src: url('../fonts/OpenSans-Regular-webfont.eot');
src:
local('Open Sans'),
local('OpenSans'),
url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/OpenSans-Regular-webfont.woff') format('woff'),
url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg');
}
@font-face {
font-family: 'Open Sans Light';
font-weight: normal;
font-style: normal;
src: url('../fonts/OpenSans-Light-webfont.eot');
src:
local('Open Sans Light'),
local('OpenSans Light'),
url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/OpenSans-Light-webfont.woff') format('woff'),
url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg');
}
html
{
overflow: auto;
background-color: #fff;
font-size: 14px;
}
body
{
font-family: 'Open Sans', sans-serif;
line-height: 1.5;
color: #4d4e53;
background-color: white;
}
a, a:visited, a:active {
color: #0095dd;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
header
{
display: block;
padding: 0px 4px;
}
tt, code, kbd, samp {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
}
.class-description {
font-size: 130%;
line-height: 140%;
margin-bottom: 1em;
margin-top: 1em;
}
.class-description:empty {
margin: 0;
}
#main {
float: left;
width: 70%;
}
article dl {
margin-bottom: 40px;
}
article img {
max-width: 100%;
}
section
{
display: block;
background-color: #fff;
padding: 12px 24px;
border-bottom: 1px solid #ccc;
margin-right: 30px;
}
.variation {
display: none;
}
.signature-attributes {
font-size: 60%;
color: #aaa;
font-style: italic;
font-weight: lighter;
}
nav
{
display: block;
float: right;
margin-top: 28px;
width: 30%;
box-sizing: border-box;
border-left: 1px solid #ccc;
padding-left: 16px;
}
nav ul {
font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
font-size: 100%;
line-height: 17px;
padding: 0;
margin: 0;
list-style-type: none;
}
nav ul a, nav ul a:visited, nav ul a:active {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
line-height: 18px;
color: #4D4E53;
}
nav h3 {
margin-top: 12px;
}
nav li {
margin-top: 6px;
}
footer {
display: block;
padding: 6px;
margin-top: 12px;
font-style: italic;
font-size: 90%;
}
h1, h2, h3, h4 {
font-weight: 200;
margin: 0;
}
h1
{
font-family: 'Open Sans Light', sans-serif;
font-size: 48px;
letter-spacing: -2px;
margin: 12px 24px 20px;
}
h2, h3.subsection-title
{
font-size: 30px;
font-weight: 700;
letter-spacing: -1px;
margin-bottom: 12px;
}
h3
{
font-size: 24px;
letter-spacing: -0.5px;
margin-bottom: 12px;
}
h4
{
font-size: 18px;
letter-spacing: -0.33px;
margin-bottom: 12px;
color: #4d4e53;
}
h5, .container-overview .subsection-title
{
font-size: 120%;
font-weight: bold;
letter-spacing: -0.01em;
margin: 8px 0 3px 0;
}
h6
{
font-size: 100%;
letter-spacing: -0.01em;
margin: 6px 0 3px 0;
font-style: italic;
}
table
{
border-spacing: 0;
border: 0;
border-collapse: collapse;
}
td, th
{
border: 1px solid #ddd;
margin: 0px;
text-align: left;
vertical-align: top;
padding: 4px 6px;
display: table-cell;
}
thead tr
{
background-color: #ddd;
font-weight: bold;
}
th { border-right: 1px solid #aaa; }
tr > th:last-child { border-right: 1px solid #ddd; }
.ancestors, .attribs { color: #999; }
.ancestors a, .attribs a
{
color: #999 !important;
text-decoration: none;
}
.clear
{
clear: both;
}
.important
{
font-weight: bold;
color: #950B02;
}
.yes-def {
text-indent: -1000px;
}
.type-signature {
color: #aaa;
}
.name, .signature {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
}
.details { margin-top: 14px; border-left: 2px solid #DDD; }
.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; }
.details dd { margin-left: 70px; }
.details ul { margin: 0; }
.details ul { list-style-type: none; }
.details li { margin-left: 30px; padding-top: 6px; }
.details pre.prettyprint { margin: 0 }
.details .object-value { padding-top: 0; }
.description {
margin-bottom: 1em;
margin-top: 1em;
}
.code-caption
{
font-style: italic;
font-size: 107%;
margin: 0;
}
.source
{
border: 1px solid #ddd;
width: 80%;
overflow: auto;
}
.prettyprint.source {
width: inherit;
}
.source code
{
font-size: 100%;
line-height: 18px;
display: block;
padding: 4px 12px;
margin: 0;
background-color: #fff;
color: #4D4E53;
}
.prettyprint code span.line
{
display: inline-block;
}
.prettyprint.linenums
{
padding-left: 70px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.prettyprint.linenums ol
{
padding-left: 0;
}
.prettyprint.linenums li
{
border-left: 3px #ddd solid;
}
.prettyprint.linenums li.selected,
.prettyprint.linenums li.selected *
{
background-color: lightyellow;
}
.prettyprint.linenums li *
{
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
.params .name, .props .name, .name code {
color: #4D4E53;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
font-size: 100%;
}
.params td.description > p:first-child,
.props td.description > p:first-child
{
margin-top: 0;
padding-top: 0;
}
.params td.description > p:last-child,
.props td.description > p:last-child
{
margin-bottom: 0;
padding-bottom: 0;
}
.disabled {
color: #454545;
}

View File

@ -1,111 +0,0 @@
/* JSDoc prettify.js theme */
/* plain text */
.pln {
color: #000000;
font-weight: normal;
font-style: normal;
}
/* string content */
.str {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a keyword */
.kwd {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* a comment */
.com {
font-weight: normal;
font-style: italic;
}
/* a type name */
.typ {
color: #000000;
font-weight: normal;
font-style: normal;
}
/* a literal value */
.lit {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* punctuation */
.pun {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* lisp open bracket */
.opn {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* lisp close bracket */
.clo {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* a markup tag name */
.tag {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a markup attribute name */
.atn {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a markup attribute value */
.atv {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a declaration */
.dec {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* a variable name */
.var {
color: #000000;
font-weight: normal;
font-style: normal;
}
/* a function name */
.fun {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0;
}

View File

@ -1,132 +0,0 @@
/* Tomorrow Theme */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
/* Pretty printing styles. Used with prettify.js. */
/* SPAN elements with the classes below are added by prettyprint. */
/* plain text */
.pln {
color: #4d4d4c; }
@media screen {
/* string content */
.str {
color: #718c00; }
/* a keyword */
.kwd {
color: #8959a8; }
/* a comment */
.com {
color: #8e908c; }
/* a type name */
.typ {
color: #4271ae; }
/* a literal value */
.lit {
color: #f5871f; }
/* punctuation */
.pun {
color: #4d4d4c; }
/* lisp open bracket */
.opn {
color: #4d4d4c; }
/* lisp close bracket */
.clo {
color: #4d4d4c; }
/* a markup tag name */
.tag {
color: #c82829; }
/* a markup attribute name */
.atn {
color: #f5871f; }
/* a markup attribute value */
.atv {
color: #3e999f; }
/* a declaration */
.dec {
color: #f5871f; }
/* a variable name */
.var {
color: #c82829; }
/* a function name */
.fun {
color: #4271ae; } }
/* Use higher contrast and text-weight for printable form. */
@media print, projection {
.str {
color: #060; }
.kwd {
color: #006;
font-weight: bold; }
.com {
color: #600;
font-style: italic; }
.typ {
color: #404;
font-weight: bold; }
.lit {
color: #044; }
.pun, .opn, .clo {
color: #440; }
.tag {
color: #006;
font-weight: bold; }
.atn {
color: #404; }
.atv {
color: #060; } }
/* Style */
/*
pre.prettyprint {
background: white;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
font-size: 12px;
line-height: 1.5;
border: 1px solid #ccc;
padding: 10px; }
*/
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0; }
/* IE indents via margin-left */
li.L0,
li.L1,
li.L2,
li.L3,
li.L4,
li.L5,
li.L6,
li.L7,
li.L8,
li.L9 {
/* */ }
/* Alternate shading for lines */
li.L1,
li.L3,
li.L5,
li.L7,
li.L9 {
/* */ }

View File

@ -1,44 +0,0 @@
/* reset css */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

View File

@ -1,421 +0,0 @@
# Tutorial
This tutorial walks you through the features of `Updux` using the
time-honored example of the implementation of Todo list store.
We'll be using
[updeep](https://www.npmjs.com/package/updeep) to
help with immutability and deep merging,
but that's totally optional. If `updeep` is not your bag,
it can easily be substitued with, say, [immer][], [lodash][], or even
plain JavaScript.
## Definition of the state
To begin with, let's define that has nothing but an initial state.
```js
import { Updux } from 'updux';
const todosDux = new Updux({
initial: {
next_id: 1,
todos: [],
}
});
```
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
initial state will be automatically set:
```js
const store = todosDux.createStore();
console.log(store.getState()); // prints { next_id: 1, todos: [] }
```
## Add actions
This is all good, but a little static. Let's add actions!
```js
todosDux.setAction( 'addTodo' );
todosDux.setAction( 'todoDone' );
```
### 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' }
```
### Adding a mutation
Like actions, a mutation can be defined as part of the Updux
init arguments:
```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 }]
})
}
});
```
or via the method `setMutation`:
```js
todosDux.setMutation( 'addTodo', description => ({next_id: id, todos}) => ({
next_id: 1 + id,
todos: [...todos, { description, id, done: false }]
}));
```
## Effects
In addition to mutations, Updux also provides action-specific middleware, here
called effects.
Effects use the usual Redux middleware signature, plus a few goodies.
The `getState` and `dispatch` functions are augmented with the dux selectors,
and actions, respectively. The selectors and actions are also available by
themselves in the api object too.
```js
import u from 'updeep';
// we want to decouple the increment of next_id and the creation of
// a new todo. So let's use a new version of the action 'addTodo'.
const addTodoWithId = action('addTodoWithId');
const incNextId = action('incNextId');
const addTodo = action('addTodo');
const addTodoEffect = ({ getState, dispatch }) => next => action => {
const id = getState.nextId();
dispatch.incNextId();
next(action);
dispatch.addTodoWithId({ description: action.payload, id }) );
}
```
And just like mutations, they can be defined as part of the init
configuration, or after via the method `addEffect`:
```
const todosDux = new Updux({
initial: { nextId: 1, todos: [] },
actions: { addTodo, incNextId, addTodoWithId },
selectors: {
nextId: ({nextId}) => nextId,
},
mutations: {
addTodoWithId: (todo) => u({ todos => (todos) => [...todos, todo] }),
incNextId: () => u({ nextId: id => id+1 }),
},
effects: {
'addTodo': addTodoEffect
}
});
const store = todosDux.createStore();
store.dispatch.addTodo('Do the thing');
```
or
```
todosDux.addEffect( 'addTodo', addTodoEffect );
```
### Catch-all effect
It is possible to have an effect match all actions via the special `*` token.
```
todosUpdux.addEffect('*', () => next => action => {
console.log( 'seeing action fly by:', action );
next(action);
});
```
## Adding selectors
Selectors can be defined to get data derived from the state.
From now you should know the drill: selectors can be defined at construction
time or via `setSelector`.
```
import fp from 'lodash/fp';
const getTodoById = ({todos}) => id => fp.find({id},todos);
const todosUpdux = new Updux({
selectors: {
getTodoById
}
})
```
or
```
todosDux.setSelector('getTodoById', ({todos}) => id => fp.find({id},todos));
```
### Accessing selectors
The `getState` method of a dux store is augmented
with its selectors, with the first call for the state already
called in for you.
```js
const store = todosDux.createStore();
console.log(
todosUpdux.getState.getTodoById(1)
);
```
## Subduxes
Now that we have all the building blocks, we can embark on the last and
funkiest part of Updux: its recursive nature.
### Recap: the Todos dux, undivided
Upduxes can be divided into sub-upduxes that deal with the various parts of
the global state. This is better understood by working out an example, so
let's recap on the Todos dux we have so far:
```js
import Updux from 'updux';
import u from 'updeep';
import fp from 'lodash/fp';
const todosDux = new Updux({
initial: {
nextId: 1,
todos: [],
},
actions: {
addTodo: null,
addTodoWithId: (description, id) => ({description, id, done: false}),
todoDone: null,
incNextId: null,
},
selectors: {
getTodoById: ({todos}) => id => fp.find({id},todos)
},
mutations: {
addTodoWithId: todo =>
u.updateIn( 'todos', todos => [ ...todos, todo] ),
incrementNextId: () => u({ nextId: fp.add(1) }),
todoDone: (id) => u.updateIn('todos',
u.map( u.if( fp.matches({id}), todo => u({done: true}, todo) ) )
),
},
effects: {
addTodo: ({ getState, dispatch }) => next => action => {
const { nextId: id } = getState();
dispatch.incNextId();
next(action);
dispatch.addTodoWithId(action.payload, id);
}
}
});
```
This store has two main components: the `nextId`, and the `todos` collection.
The `todos` collection is itself composed of the individual `todo`s. Let's
create upduxes for each of those.
### NextId dux
```
// dux/nextId.js
import { Updux } from 'updux';
import u from 'updeep';
import fp from 'lodash/fp';
export default new Updux({
initial: 1,
actions: {
incNextId: null,
},
selectors: {
getNextId: state => state
},
mutations: {
incrementNextId: () => fp.add(1)
}
});
```
### Todo updux
```
// dux/todos/todo/index.ts
import { Updux } from 'updux';
import u from 'updeep';
import fp from 'lodash/fp';
export default new Updux({
initial: {
id: 0,
description: "",
done: false,
},
actions: {
todoDone: null,
},
mutations: {
todoDone: id => u.if( fp.matches({id}), { done: true }) )
}
});
```
### Todos updux
```
// dux/todos/index.js
import { Updux } from 'updux';
import u from 'updeep';
import fp from 'lodash/fp';
import todo from './todo/index.js';
export default new Updux({
initial: [],
subduxes: {
'*': todo
},
actions: {
addTodoWithId,
},
mappedSelectors: {
getTodoById: state => id => fp.find({id},state)
},
mutations: {
addTodoWithId: todo =>
todos => [ ...todos, todo ]
}
});
```
Note the special '\*' subdux key used here. This
allows the updux to map every item present in its
state to a `todo` updux. See [this recipe](/recipes?id=mapping-a-mutation-to-all-values-of-a-state) for details.
### Main store
```
// dux/index.js
import Updux from 'updux';
import todos from './todos';
import nextId from './next_id';
export new Updux({
subduxes: {
nextId,
todos,
},
actions: {
addTodo: null
},
effects: {
addTodo: ({ getState, dispatch }) => next => action => {
const id = getState.getNextId();
dispatch.incNextId()
next(action);
dispatch.addTodoWithId( action.payload, id );
}
}
});
```
Tadah! We had to define the `addTodo` effect at the top level as it needs to
access the `getNextId` selector from `nextId` and the `addTodoWithId`
action from the `todos`.
Note that the `getNextId` selector still gets the
right value; when aggregating subduxes selectors Updux auto-wraps them to
access the right slice of the top object. ```
## Reactions
Reactions -- aka Redux's subscriptions -- can be added to a updux store via the initial config
or the method `addSubscription`. The signature of a reaction is:
```
(storeApi) => (state, previousState, unsubscribe) => {
...
}
```
Subscriptions registered for an updux and its subduxes are automatically
subscribed to the store when calling `createStore`.
The `state` passed to the subscriptions of the subduxes is the local state.
Also, all subscriptions are wrapped such that they are called only if the
local `state` changed since their last invocation.
Example:
```
const todos = new Updux({
initial: [],
actions: {
setNbrTodos: null,
}
reactions: [
({dispatch}) => todos => dispatch.setNbrTodos(todos.length);
],
});
const myDux = new Updux({
initial: {
nbr_todos: 0
},
subduxes: {
todos,
},
mutations: {
setNbrTodos: nbrTodos => u({ nbrTodos })
}
})
```
[immer]: https://www.npmjs.com/package/immer
[lodash]: https://www.npmjs.com/package/lodash
[ts-action]: https://www.npmjs.com/package/ts-action

View File

@ -1,228 +0,0 @@
[updux - v1.2.0](README.md) [Globals](globals.md)
# updux - v1.2.0
# What's Updux?
So, I'm a fan of [Redux](https://redux.js.org). Two days ago I discovered
[rematch](https://rematch.github.io/rematch) alonside a few other frameworks built atop Redux.
It has a couple of pretty good ideas that removes some of the
boilerplate. 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
is the fun in that? And I'm also having a strong love for
[Updeep](https://github.com/substantial/updeep), so I want reducer state updates to leverage the heck out of it.
All that to say, say hello to `Updux`. Heavily inspired by `rematch`, but twisted
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
effects (middleware reacting to actions that can be asynchronous and/or
have side-effects), so everything pertaining to a store are all defined
in the space place.
* Automatically gather all actions used by the updux's effects and mutations,
and makes then accessible as attributes to the `dispatch` object of the
store.
* Mutations have a signature that is friendly to Updux and Immer.
* Also, the mutation signature auto-unwrap the payload of the actions for you.
* TypeScript types.
Fair warning: this package is still very new, probably very buggy,
definitively very badly documented, and very subject to changes. Caveat
Maxima Emptor.
# Synopsis
```
import updux from 'updux';
import otherUpdux from './otherUpdux';
const {
initial,
reducer,
actions,
middleware,
createStore,
} = new Updux({
initial: {
counter: 0,
},
subduxes: {
otherUpdux,
},
mutations: {
inc: ( increment = 1 ) => u({counter: s => s + increment })
},
effects: {
'*' => api => next => action => {
console.log( "hey, look, an action zoomed by!", action );
next(action);
};
},
actions: {
customAction: ( someArg ) => ({
type: "custom",
payload: { someProp: someArg }
}),
},
});
const store = createStore();
store.dispatch.inc(3);
```
# Description
Full documentation can be [found here](https://yanick.github.io/updux/docs/).
## 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 Updux instance as the default export:
```
import Updux from 'updux';
const updux = new Updux({ ... });
export default updux;
```
Then you can use them as subduxes like this:
```
import Updux from 'updux';
import foo from './foo'; // foo is an Updux
import bar from './bar'; // bar is an Updux as well
const updux = new Updux({
subduxes: {
foo, bar
}
});
```
Or if you want to use it:
```
import updux from './myUpdux';
const {
reducer,
actions: { doTheThing },
createStore,
middleware,
} = updux;
```
## Mapping a mutation to all values of a state
Say you have a `todos` state that is an array of `todo` sub-states. It's easy
enough to have the main reducer maps away all items to the sub-reducer:
```
const todo = new Updux({
mutations: {
review: () => u({ reviewed: true}),
done: () => u({done: true}),
},
});
const todos = new Updux({ initial: [] });
todos.addMutation(
todo.actions.review,
(_,action) => state => state.map( todo.upreducer(action) )
);
todos.addMutation(
todo.actions.done,
(id,action) => u.map(u.if(u.is('id',id), todo.upreducer(action))),
);
```
But `updeep` can iterate through all the items of an array (or the values of
an object) via the special key `*`. So the todos updux above could also be
written:
```
const todo = new Updux({
mutations: {
review: () => u({ reviewed: true}),
done: () => u({done: true}),
},
});
const todos = new Updux({
subduxes: { '*': todo },
});
todos.addMutation(
todo.actions.done,
(id,action) => u.map(u.if(u.is('id',id), todo.upreducer(action))),
true
);
```
The advantages being that the actions/mutations/effects of the subdux will be
imported by the root updux as usual, and all actions that aren't being
overridden by a sink mutation will trickle down automatically.
## Usage with Immer
While Updux was created with Updeep in mind, it also plays very
well with [Immer](https://immerjs.github.io/immer/docs/introduction).
For example, taking this basic updux:
```
import Updux from 'updux';
const updux = new Updux({
initial: { counter: 0 },
mutations: {
add: (inc=1) => state => { counter: counter + inc }
}
});
```
Converting it to Immer would look like:
```
import Updux from 'updux';
import { produce } from 'Immer';
const updux = new Updux({
initial: { counter: 0 },
mutations: {
add: (inc=1) => produce( draft => draft.counter += inc ) }
}
});
```
But since typing `produce` over and over is no fun, `groomMutations`
can be used to wrap all mutations with it:
```
import Updux from 'updux';
import { produce } from 'Immer';
const updux = new Updux({
initial: { counter: 0 },
groomMutations: mutation => (...args) => produce( mutation(...args) ),
mutations: {
add: (inc=1) => draft => draft.counter += inc
}
});
```

View File

@ -1,491 +0,0 @@
[updux - v1.2.0](../README.md) [Globals](../globals.md) [Updux](updux.md)
# Class: Updux <**S, A, X, C**>
## Type parameters
▪ **S**
▪ **A**
▪ **X**
**C**: *[UpduxConfig](../globals.md#upduxconfig)*
## Hierarchy
* **Updux**
## Index
### Constructors
* [constructor](updux.md#constructor)
### Properties
* [coduxes](updux.md#coduxes)
* [groomMutations](updux.md#groommutations)
* [subduxes](updux.md#subduxes)
### Accessors
* [_middlewareEntries](updux.md#_middlewareentries)
* [actions](updux.md#actions)
* [asDux](updux.md#asdux)
* [createStore](updux.md#createstore)
* [initial](updux.md#initial)
* [middleware](updux.md#middleware)
* [mutations](updux.md#mutations)
* [reducer](updux.md#reducer)
* [selectors](updux.md#selectors)
* [subduxUpreducer](updux.md#subduxupreducer)
* [upreducer](updux.md#upreducer)
### Methods
* [addAction](updux.md#addaction)
* [addEffect](updux.md#addeffect)
* [addMutation](updux.md#addmutation)
* [addSelector](updux.md#addselector)
## Constructors
### constructor
\+ **new Updux**(`config`: C): *[Updux](updux.md)*
**Parameters:**
Name | Type | Default | Description |
------ | ------ | ------ | ------ |
`config` | C | {} as C | an [UpduxConfig](../globals.md#upduxconfig) plain object |
**Returns:** *[Updux](updux.md)*
## Properties
### coduxes
**coduxes**: *[Dux](../globals.md#dux)[]*
___
### groomMutations
**groomMutations**: *function*
#### Type declaration:
▸ (`mutation`: [Mutation](../globals.md#mutation)S): *[Mutation](../globals.md#mutation)S*
**Parameters:**
Name | Type |
------ | ------ |
`mutation` | [Mutation](../globals.md#mutation)S |
___
### subduxes
**subduxes**: *[Dictionary](../globals.md#dictionary)[Dux](../globals.md#dux)*
## Accessors
### _middlewareEntries
**get _middlewareEntries**(): *any[]*
**Returns:** *any[]*
___
### actions
**get actions**(): *[DuxActions](../globals.md#duxactions)A, C*
Action creators for all actions defined or used in the actions, mutations, effects and subduxes
of the updux config.
Non-custom action creators defined in `actions` have the signature `(payload={},meta={}) => ({type,
payload,meta})` (with the extra sugar that if `meta` or `payload` are not
specified, that key won't be present in the produced action).
The same action creator can be included
in multiple subduxes. However, if two different creators
are included for the same action, an error will be thrown.
**`example`**
```
const actions = updux.actions;
```
**Returns:** *[DuxActions](../globals.md#duxactions)A, C*
___
### asDux
**get asDux**(): *object*
Returns a <a href="https://github.com/erikras/ducks-modular-redux">ducks</a>-like
plain object holding the reducer from the Updux object and all
its trimmings.
**`example`**
```
const {
createStore,
upreducer,
subduxes,
coduxes,
middleware,
actions,
reducer,
mutations,
initial,
selectors,
} = myUpdux.asDux;
```
**Returns:** *object*
* **actions**: = this.actions
* **coduxes**: *object[]* = this.coduxes
* **createStore**(): *function*
* (`initial?`: S, `injectEnhancer?`: Function): *StoreS & object*
* **initial**: = this.initial
* **middleware**(): *function*
* (`api`: UpduxMiddlewareAPIS, X): *function*
* (`next`: Function): *function*
* (`action`: A): *any*
* **mutations**(): *object*
* **reducer**(): *function*
* (`state`: S | undefined, `action`: [Action](../globals.md#action)): *S*
* **selectors**: = this.selectors
* **subduxes**(): *object*
* **upreducer**(): *function*
* (`action`: [Action](../globals.md#action)): *function*
* (`state`: S): *S*
___
### createStore
**get createStore**(): *function*
Returns a `createStore` function that takes two argument:
`initial` and `injectEnhancer`. `initial` is a custom
initial state for the store, and `injectEnhancer` is a function
taking in the middleware built by the updux object and allowing
you to wrap it in any enhancer you want.
**`example`**
```
const createStore = updux.createStore;
const store = createStore(initial);
```
**Returns:** *function*
▸ (`initial?`: S, `injectEnhancer?`: Function): *StoreS & object*
**Parameters:**
Name | Type |
------ | ------ |
`initial?` | S |
`injectEnhancer?` | Function |
___
### initial
**get initial**(): *AggDuxStateS, C*
**Returns:** *AggDuxStateS, C*
___
### middleware
**get middleware**(): *[UpduxMiddleware](../globals.md#upduxmiddleware)AggDuxStateS, C, [DuxSelectors](../globals.md#duxselectors)AggDuxStateS, C, X, C*
Array of middlewares aggregating all the effects defined in the
updux and its subduxes. Effects of the updux itself are
done before the subduxes effects.
Note that `getState` will always return the state of the
local updux.
**`example`**
```
const middleware = updux.middleware;
```
**Returns:** *[UpduxMiddleware](../globals.md#upduxmiddleware)AggDuxStateS, C, [DuxSelectors](../globals.md#duxselectors)AggDuxStateS, C, X, C*
___
### mutations
**get mutations**(): *[Dictionary](../globals.md#dictionary)[Mutation](../globals.md#mutation)S*
Merge of the updux and subduxes mutations. If an action triggers
mutations in both the main updux and its subduxes, the subduxes
mutations will be performed first.
**Returns:** *[Dictionary](../globals.md#dictionary)[Mutation](../globals.md#mutation)S*
___
### reducer
**get reducer**(): *function*
A Redux reducer generated using the computed initial state and
mutations.
**Returns:** *function*
▸ (`state`: S | undefined, `action`: [Action](../globals.md#action)): *S*
**Parameters:**
Name | Type |
------ | ------ |
`state` | S &#124; undefined |
`action` | [Action](../globals.md#action) |
___
### selectors
**get selectors**(): *[DuxSelectors](../globals.md#duxselectors)AggDuxStateS, C, X, C*
A dictionary of the updux's selectors. Subduxes'
selectors are included as well (with the mapping to the
sub-state already taken care of you).
**Returns:** *[DuxSelectors](../globals.md#duxselectors)AggDuxStateS, C, X, C*
___
### subduxUpreducer
**get subduxUpreducer**(): *function*
Returns the upreducer made of the merge of all sudbuxes reducers, without
the local mutations. Useful, for example, for sink mutations.
**`example`**
```
import todo from './todo'; // updux for a single todo
import Updux from 'updux';
import u from 'updeep';
const todos = new Updux({ initial: [], subduxes: { '*': todo } });
todos.addMutation(
todo.actions.done,
({todo_id},action) => u.map( u.if( u.is('id',todo_id) ), todos.subduxUpreducer(action) )
true
);
```
**Returns:** *function*
▸ (`action`: [Action](../globals.md#action)): *function*
**Parameters:**
Name | Type |
------ | ------ |
`action` | [Action](../globals.md#action) |
▸ (`state`: S): *S*
**Parameters:**
Name | Type |
------ | ------ |
`state` | S |
___
### upreducer
**get upreducer**(): *[Upreducer](../globals.md#upreducer)S*
**Returns:** *[Upreducer](../globals.md#upreducer)S*
## Methods
### addAction
**addAction**(`theaction`: string, `transform?`: any): *ActionCreatorstring, any*
Adds an action to the updux. It can take an already defined action
creator, or any arguments that can be passed to `actionCreator`.
**`example`**
```
const action = updux.addAction( name, ...creatorArgs );
const action = updux.addAction( otherActionCreator );
```
**`example`**
```
import {actionCreator, Updux} from 'updux';
const updux = new Updux();
const foo = updux.addAction('foo');
const bar = updux.addAction( 'bar', (x) => ({stuff: x+1}) );
const baz = actionCreator( 'baz' );
foo({ a: 1}); // => { type: 'foo', payload: { a: 1 } }
bar(2); // => { type: 'bar', payload: { stuff: 3 } }
baz(); // => { type: 'baz', payload: undefined }
```
**Parameters:**
Name | Type |
------ | ------ |
`theaction` | string |
`transform?` | any |
**Returns:** *ActionCreatorstring, any*
**addAction**(`theaction`: string | ActionCreatorany, `transform?`: undefined): *ActionCreatorstring, any*
**Parameters:**
Name | Type |
------ | ------ |
`theaction` | string &#124; ActionCreatorany |
`transform?` | undefined |
**Returns:** *ActionCreatorstring, any*
___
### addEffect
**addEffect**<**AC**>(`creator`: AC, `middleware`: [UpduxMiddleware](../globals.md#upduxmiddleware)AggDuxStateS, C, [DuxSelectors](../globals.md#duxselectors)AggDuxStateS, C, X, C, ReturnTypeAC, `isGenerator?`: undefined | false | true): *any*
**Type parameters:**
**AC**: *ActionCreator*
**Parameters:**
Name | Type |
------ | ------ |
`creator` | AC |
`middleware` | [UpduxMiddleware](../globals.md#upduxmiddleware)AggDuxStateS, C, [DuxSelectors](../globals.md#duxselectors)AggDuxStateS, C, X, C, ReturnTypeAC |
`isGenerator?` | undefined &#124; false &#124; true |
**Returns:** *any*
**addEffect**(`creator`: string, `middleware`: [UpduxMiddleware](../globals.md#upduxmiddleware)AggDuxStateS, C, [DuxSelectors](../globals.md#duxselectors)AggDuxStateS, C, X, C, `isGenerator?`: undefined | false | true): *any*
**Parameters:**
Name | Type |
------ | ------ |
`creator` | string |
`middleware` | [UpduxMiddleware](../globals.md#upduxmiddleware)AggDuxStateS, C, [DuxSelectors](../globals.md#duxselectors)AggDuxStateS, C, X, C |
`isGenerator?` | undefined &#124; false &#124; true |
**Returns:** *any*
___
### addMutation
**addMutation**<**A**>(`creator`: A, `mutation`: [Mutation](../globals.md#mutation)S, ActionTypeA, `isSink?`: undefined | false | true): *any*
Adds a mutation and its associated action to the updux.
**`remarks`**
If a local mutation was already associated to the action,
it will be replaced by the new one.
**`example`**
```js
updux.addMutation(
action('ADD', payload<int>() ),
inc => state => state + in
);
```
**Type parameters:**
**A**: *ActionCreator*
**Parameters:**
Name | Type | Description |
------ | ------ | ------ |
`creator` | A | - |
`mutation` | [Mutation](../globals.md#mutation)S, ActionTypeA | - |
`isSink?` | undefined &#124; false &#124; true | If `true`, disables the subduxes mutations for this action. To conditionally run the subduxes mutations, check out [subduxUpreducer](updux.md#subduxupreducer). Defaults to `false`. |
**Returns:** *any*
**addMutation**<**A**>(`creator`: string, `mutation`: [Mutation](../globals.md#mutation)S, any, `isSink?`: undefined | false | true): *any*
**Type parameters:**
**A**: *ActionCreator*
**Parameters:**
Name | Type |
------ | ------ |
`creator` | string |
`mutation` | [Mutation](../globals.md#mutation)S, any |
`isSink?` | undefined &#124; false &#124; true |
**Returns:** *any*
___
### addSelector
**addSelector**(`name`: string, `selector`: [Selector](../globals.md#selector)): *void*
**Parameters:**
Name | Type |
------ | ------ |
`name` | string |
`selector` | [Selector](../globals.md#selector) |
**Returns:** *void*

View File

@ -1,980 +0,0 @@
[updux - v1.2.0](README.md) [Globals](globals.md)
# updux - v1.2.0
## Index
### Classes
* [Updux](classes/updux.md)
### Type aliases
* [Action](globals.md#action)
* [ActionPair](globals.md#actionpair)
* [ActionPayloadGenerator](globals.md#actionpayloadgenerator)
* [ActionsOf](globals.md#actionsof)
* [CoduxesOf](globals.md#coduxesof)
* [Dictionary](globals.md#dictionary)
* [Dux](globals.md#dux)
* [DuxActions](globals.md#duxactions)
* [DuxActionsCoduxes](globals.md#duxactionscoduxes)
* [DuxActionsSubduxes](globals.md#duxactionssubduxes)
* [DuxSelectors](globals.md#duxselectors)
* [DuxState](globals.md#duxstate)
* [DuxStateCoduxes](globals.md#duxstatecoduxes)
* [DuxStateGlobSub](globals.md#duxstateglobsub)
* [DuxStateSubduxes](globals.md#duxstatesubduxes)
* [Effect](globals.md#effect)
* [GenericActions](globals.md#genericactions)
* [ItemsOf](globals.md#itemsof)
* [LocalDuxState](globals.md#localduxstate)
* [MaybePayload](globals.md#maybepayload)
* [MaybeReturnType](globals.md#maybereturntype)
* [Merge](globals.md#merge)
* [Mutation](globals.md#mutation)
* [MutationEntry](globals.md#mutationentry)
* [MwGen](globals.md#mwgen)
* [Next](globals.md#next)
* [RebaseSelector](globals.md#rebaseselector)
* [Selector](globals.md#selector)
* [SelectorsOf](globals.md#selectorsof)
* [StateOf](globals.md#stateof)
* [StoreWithDispatchActions](globals.md#storewithdispatchactions)
* [SubMutations](globals.md#submutations)
* [Submws](globals.md#submws)
* [UnionToIntersection](globals.md#uniontointersection)
* [UpduxActions](globals.md#upduxactions)
* [UpduxConfig](globals.md#upduxconfig)
* [UpduxLocalActions](globals.md#upduxlocalactions)
* [UpduxMiddleware](globals.md#upduxmiddleware)
* [Upreducer](globals.md#upreducer)
### Variables
* [subEffects](globals.md#const-subeffects)
* [updux](globals.md#const-updux)
### Functions
* [MiddlewareFor](globals.md#const-middlewarefor)
* [buildActions](globals.md#buildactions)
* [buildCreateStore](globals.md#buildcreatestore)
* [buildInitial](globals.md#buildinitial)
* [buildMiddleware](globals.md#buildmiddleware)
* [buildMutations](globals.md#buildmutations)
* [buildSelectors](globals.md#buildselectors)
* [buildUpreducer](globals.md#buildupreducer)
* [coduxes](globals.md#const-coduxes)
* [composeMutations](globals.md#const-composemutations)
* [composeMw](globals.md#const-composemw)
* [dux](globals.md#const-dux)
* [effectToMw](globals.md#const-effecttomw)
* [sliceMw](globals.md#slicemw)
* [subMiddleware](globals.md#const-submiddleware)
* [subSelectors](globals.md#subselectors)
## Type aliases
### Action
Ƭ **Action**: *object & [MaybePayload](globals.md#maybepayload)P*
___
### ActionPair
Ƭ **ActionPair**: *[string, ActionCreator]*
___
### ActionPayloadGenerator
Ƭ **ActionPayloadGenerator**: *function*
#### Type declaration:
▸ (...`args`: any[]): *any*
**Parameters:**
Name | Type |
------ | ------ |
`...args` | any[] |
___
### ActionsOf
Ƭ **ActionsOf**: *U extends Updux ? U["actions"] : object*
___
### CoduxesOf
Ƭ **CoduxesOf**: *U extends Updux<any, any, any, infer S> ? S : []*
___
### Dictionary
Ƭ **Dictionary**: *object*
#### Type declaration:
* \[ **key**: *string*\]: T
___
### Dux
Ƭ **Dux**: *object*
#### Type declaration:
* **actions**: *A*
* **coduxes**: *[Dux](globals.md#dux)[]*
* **initial**: *AggDuxStateS, C*
* **subduxes**: *[Dictionary](globals.md#dictionary)[Dux](globals.md#dux)*
___
### DuxActions
Ƭ **DuxActions**:
___
### DuxActionsCoduxes
Ƭ **DuxActionsCoduxes**: *C extends Array<infer I> ? UnionToIntersection<ActionsOf<I>> : object*
___
### DuxActionsSubduxes
Ƭ **DuxActionsSubduxes**: *C extends object ? ActionsOf<C[keyof C]> : unknown*
___
### DuxSelectors
Ƭ **DuxSelectors**: *unknown extends X ? object : X*
___
### DuxState
Ƭ **DuxState**: *D extends object ? S : unknown*
___
### DuxStateCoduxes
Ƭ **DuxStateCoduxes**: *C extends Array<infer U> ? UnionToIntersection<StateOf<U>> : unknown*
___
### DuxStateGlobSub
Ƭ **DuxStateGlobSub**: *S extends object ? StateOf<I> : unknown*
___
### DuxStateSubduxes
Ƭ **DuxStateSubduxes**: *C extends object ? object : C extends object ? object : unknown*
___
### Effect
Ƭ **Effect**: *[string, [UpduxMiddleware](globals.md#upduxmiddleware) | [MwGen](globals.md#mwgen), undefined | false | true]*
___
### GenericActions
Ƭ **GenericActions**: *[Dictionary](globals.md#dictionary)ActionCreatorstring, function*
___
### ItemsOf
Ƭ **ItemsOf**: *C extends object ? C[keyof C] : unknown*
___
### LocalDuxState
Ƭ **LocalDuxState**: *S extends never[] ? unknown[] : S*
___
### MaybePayload
Ƭ **MaybePayload**: *P extends object | string | boolean | number ? object : object*
___
### MaybeReturnType
Ƭ **MaybeReturnType**: *X extends function ? ReturnType<X> : unknown*
___
### Merge
Ƭ **Merge**: *[UnionToIntersection](globals.md#uniontointersection)T[keyof T]*
___
### Mutation
Ƭ **Mutation**: *function*
#### Type declaration:
▸ (`payload`: A["payload"], `action`: A): *function*
**Parameters:**
Name | Type |
------ | ------ |
`payload` | A["payload"] |
`action` | A |
▸ (`state`: S): *S*
**Parameters:**
Name | Type |
------ | ------ |
`state` | S |
___
### MutationEntry
Ƭ **MutationEntry**: *[ActionCreator | string, [Mutation](globals.md#mutation)any, [Action](globals.md#action)string, any, undefined | false | true]*
___
### MwGen
Ƭ **MwGen**: *function*
#### Type declaration:
▸ (): *[UpduxMiddleware](globals.md#upduxmiddleware)*
___
### Next
Ƭ **Next**: *function*
#### Type declaration:
▸ (`action`: [Action](globals.md#action)): *any*
**Parameters:**
Name | Type |
------ | ------ |
`action` | [Action](globals.md#action) |
___
### RebaseSelector
Ƭ **RebaseSelector**: *object*
#### Type declaration:
___
### Selector
Ƭ **Selector**: *function*
#### Type declaration:
▸ (`state`: S): *unknown*
**Parameters:**
Name | Type |
------ | ------ |
`state` | S |
___
### SelectorsOf
Ƭ **SelectorsOf**: *C extends object ? S : unknown*
___
### StateOf
Ƭ **StateOf**: *D extends object ? I : unknown*
___
### StoreWithDispatchActions
Ƭ **StoreWithDispatchActions**: *StoreS & object*
___
### SubMutations
Ƭ **SubMutations**: *object*
#### Type declaration:
* \[ **slice**: *string*\]: [Dictionary](globals.md#dictionary)[Mutation](globals.md#mutation)
___
### Submws
Ƭ **Submws**: *[Dictionary](globals.md#dictionary)[UpduxMiddleware](globals.md#upduxmiddleware)*
___
### UnionToIntersection
Ƭ **UnionToIntersection**: *U extends any ? function : never extends function ? I : never*
___
### UpduxActions
Ƭ **UpduxActions**: *U extends Updux ? UnionToIntersection<UpduxLocalActions<U> | ActionsOf<CoduxesOf<U>[keyof CoduxesOf<U>]>> : object*
___
### UpduxConfig
Ƭ **UpduxConfig**: *Partialobject*
Configuration object given to Updux's constructor.
#### arguments
##### initial
Default initial state of the reducer. If applicable, is merged with
the subduxes initial states, with the parent having precedence.
If not provided, defaults to an empty object.
##### actions
[Actions](/concepts/Actions) used by the updux.
```js
import { dux } from 'updux';
import { action, payload } from 'ts-action';
const bar = action('BAR', payload<int>());
const foo = action('FOO');
const myDux = dux({
actions: {
bar
},
mutations: [
[ foo, () => state => state ]
]
});
myDux.actions.foo({ x: 1, y: 2 }); // => { type: foo, x:1, y:2 }
myDux.actions.bar(2); // => { type: bar, payload: 2 }
```
New actions used directly in mutations and effects will be added to the
dux actions -- that is, they will be accessible via `dux.actions` -- but will
not appear as part of its Typescript type.
##### selectors
Dictionary of selectors for the current updux. The updux also
inherit its subduxes' selectors.
The selectors are available via the class' getter.
##### mutations
mutations: [
[ action, mutation, isSink ],
...
]
or
mutations: {
action: mutation,
...
}
List of mutations for assign to the dux. If you want Typescript goodness, you
probably want to use `addMutation()` instead.
In its generic array-of-array form,
each mutation tuple contains: the action, the mutation,
and boolean indicating if this is a sink mutation.
The action can be an action creator function or a string. If it's a string, it's considered to be the
action type and a generic `action( actionName, payload() )` creator will be
generated for it. If an action is not already defined in the `actions`
parameter, it'll be automatically added.
The pseudo-action type `*` can be used to match any action not explicitly matched by other mutations.
```js
const todosUpdux = updux({
mutations: {
add: todo => state => [ ...state, todo ],
done: done_id => u.map( u.if( ({id} => id === done_id), {done: true} ) ),
'*' (payload,action) => state => {
console.warn( "unexpected action ", action.type );
return state;
},
}
});
```
The signature of the mutations is `(payload,action) => state => newState`.
It is designed to play well with `Updeep` (and [Immer](https://immerjs.github.io/immer/docs/introduction)). This way, instead of doing
```js
mutation: {
renameTodo: newName => state => { ...state, name: newName }
}
```
we can do
```js
mutation: {
renameTodo: newName => u({ name: newName })
}
```
The final argument is the optional boolean `isSink`. If it is true, it'll
prevent subduxes' mutations on the same action. It defaults to `false`.
The object version of the argument can be used as a shortcut when all actions
are strings. In that case, `isSink` is `false` for all mutations.
##### groomMutations
Function that can be provided to alter all local mutations of the updux
(the mutations of subduxes are left untouched).
Can be used, for example, for Immer integration:
```js
import Updux from 'updux';
import { produce } from 'Immer';
const updux = new Updux({
initial: { counter: 0 },
groomMutations: mutation => (...args) => produce( mutation(...args) ),
mutations: {
add: (inc=1) => draft => draft.counter += inc
}
});
```
Or perhaps for debugging:
```js
import Updux from 'updux';
const updux = new Updux({
initial: { counter: 0 },
groomMutations: mutation => (...args) => state => {
console.log( "got action ", args[1] );
return mutation(...args)(state);
}
});
```
##### subduxes
Object mapping slices of the state to sub-upduxes. In addition to creating
sub-reducers for those slices, it'll make the parend updux inherit all the
actions and middleware from its subduxes.
For example, if in plain Redux you would do
```js
import { combineReducers } from 'redux';
import todosReducer from './todos';
import statisticsReducer from './statistics';
const rootReducer = combineReducers({
todos: todosReducer,
stats: statisticsReducer,
});
```
then with Updux you'd do
```js
import { updux } from 'updux';
import todos from './todos';
import statistics from './statistics';
const rootUpdux = updux({
subduxes: {
todos,
statistics
}
});
```
##### effects
Array of arrays or plain object defining asynchronous actions and side-effects triggered by actions.
The effects themselves are Redux middleware, with the `dispatch`
property of the first argument augmented with all the available actions.
```
updux({
effects: {
fetch: ({dispatch}) => next => async (action) => {
next(action);
let result = await fetch(action.payload.url).then( result => result.json() );
dispatch.fetchSuccess(result);
}
}
});
```
**`example`**
```
import Updux from 'updux';
import { actions, payload } from 'ts-action';
import u from 'updeep';
const todoUpdux = new Updux({
initial: {
done: false,
note: "",
},
actions: {
finish: action('FINISH', payload()),
edit: action('EDIT', payload()),
},
mutations: [
[ edit, note => u({note}) ]
],
selectors: {
getNote: state => state.note
},
groomMutations: mutation => transform(mutation),
subduxes: {
foo
},
effects: {
finish: () => next => action => {
console.log( "Woo! one more bites the dust" );
}
}
})
```
___
### UpduxLocalActions
Ƭ **UpduxLocalActions**: *S extends Updux<any, null> ? object : S extends Updux<any, infer A> ? A : object*
___
### UpduxMiddleware
Ƭ **UpduxMiddleware**: *function*
#### Type declaration:
▸ (`api`: UpduxMiddlewareAPIS, X): *function*
**Parameters:**
Name | Type |
------ | ------ |
`api` | UpduxMiddlewareAPIS, X |
▸ (`next`: Function): *function*
**Parameters:**
Name | Type |
------ | ------ |
`next` | Function |
▸ (`action`: A): *any*
**Parameters:**
Name | Type |
------ | ------ |
`action` | A |
___
### Upreducer
Ƭ **Upreducer**: *function*
#### Type declaration:
▸ (`action`: [Action](globals.md#action)): *function*
**Parameters:**
Name | Type |
------ | ------ |
`action` | [Action](globals.md#action) |
▸ (`state`: S): *S*
**Parameters:**
Name | Type |
------ | ------ |
`state` | S |
## Variables
### `Const` subEffects
**subEffects**: *[Effect](globals.md#effect)* = [ '*', subMiddleware ] as any
___
### `Const` updux
**updux**: *[Updux](classes/updux.md)unknown, null, unknown, object* = new Updux({
subduxes: {
foo: dux({ initial: "banana" })
}
})
## Functions
### `Const` MiddlewareFor
**MiddlewareFor**(`type`: any, `mw`: Middleware): *Middleware*
**Parameters:**
Name | Type |
------ | ------ |
`type` | any |
`mw` | Middleware |
**Returns:** *Middleware*
___
### buildActions
**buildActions**(`actions`: [ActionPair](globals.md#actionpair)[]): *[Dictionary](globals.md#dictionary)ActionCreatorstring, function*
**Parameters:**
Name | Type | Default |
------ | ------ | ------ |
`actions` | [ActionPair](globals.md#actionpair)[] | [] |
**Returns:** *[Dictionary](globals.md#dictionary)ActionCreatorstring, function*
___
### buildCreateStore
**buildCreateStore**<**S**, **A**>(`reducer`: ReducerS, `middleware`: Middleware, `actions`: A): *function*
**Type parameters:**
▪ **S**
▪ **A**
**Parameters:**
Name | Type | Default |
------ | ------ | ------ |
`reducer` | ReducerS | - |
`middleware` | Middleware | - |
`actions` | A | {} as A |
**Returns:** *function*
▸ (`initial?`: S, `injectEnhancer?`: Function): *StoreS & object*
**Parameters:**
Name | Type |
------ | ------ |
`initial?` | S |
`injectEnhancer?` | Function |
___
### buildInitial
**buildInitial**(`initial`: any, `coduxes`: any, `subduxes`: any): *any*
**Parameters:**
Name | Type | Default |
------ | ------ | ------ |
`initial` | any | - |
`coduxes` | any | [] |
`subduxes` | any | {} |
**Returns:** *any*
___
### buildMiddleware
**buildMiddleware**<**S**>(`local`: [UpduxMiddleware](globals.md#upduxmiddleware)[], `co`: [UpduxMiddleware](globals.md#upduxmiddleware)[], `sub`: [Submws](globals.md#submws)): *[UpduxMiddleware](globals.md#upduxmiddleware)S*
**Type parameters:**
▪ **S**
**Parameters:**
Name | Type | Default |
------ | ------ | ------ |
`local` | [UpduxMiddleware](globals.md#upduxmiddleware)[] | [] |
`co` | [UpduxMiddleware](globals.md#upduxmiddleware)[] | [] |
`sub` | [Submws](globals.md#submws) | {} |
**Returns:** *[UpduxMiddleware](globals.md#upduxmiddleware)S*
___
### buildMutations
**buildMutations**(`mutations`: [Dictionary](globals.md#dictionary)[Mutation](globals.md#mutation) | [[Mutation](globals.md#mutation), boolean | undefined], `subduxes`: object, `coduxes`: [Upreducer](globals.md#upreducer)[]): *object*
**Parameters:**
Name | Type | Default |
------ | ------ | ------ |
`mutations` | [Dictionary](globals.md#dictionary)[Mutation](globals.md#mutation) &#124; [[Mutation](globals.md#mutation), boolean &#124; undefined] | {} |
`subduxes` | object | {} |
`coduxes` | [Upreducer](globals.md#upreducer)[] | [] |
**Returns:** *object*
___
### buildSelectors
**buildSelectors**(`localSelectors`: [Dictionary](globals.md#dictionary)[Selector](globals.md#selector), `coduxes`: [Dictionary](globals.md#dictionary)[Selector](globals.md#selector)[], `subduxes`: [Dictionary](globals.md#dictionary)[Selector](globals.md#selector)): *object*
**Parameters:**
Name | Type | Default |
------ | ------ | ------ |
`localSelectors` | [Dictionary](globals.md#dictionary)[Selector](globals.md#selector) | {} |
`coduxes` | [Dictionary](globals.md#dictionary)[Selector](globals.md#selector)[] | [] |
`subduxes` | [Dictionary](globals.md#dictionary)[Selector](globals.md#selector) | {} |
**Returns:** *object*
___
### buildUpreducer
**buildUpreducer**<**S**>(`initial`: S, `mutations`: [Dictionary](globals.md#dictionary)[Mutation](globals.md#mutation)S): *[Upreducer](globals.md#upreducer)S*
**Type parameters:**
▪ **S**
**Parameters:**
Name | Type |
------ | ------ |
`initial` | S |
`mutations` | [Dictionary](globals.md#dictionary)[Mutation](globals.md#mutation)S |
**Returns:** *[Upreducer](globals.md#upreducer)S*
___
### `Const` coduxes
**coduxes**<**C**, **U**>(...`coduxes`: U): *object*
**Type parameters:**
**C**: *[Dux](globals.md#dux)*
**U**: *[C]*
**Parameters:**
Name | Type |
------ | ------ |
`...coduxes` | U |
**Returns:** *object*
* **coduxes**: *U*
___
### `Const` composeMutations
**composeMutations**(`mutations`: [Mutation](globals.md#mutation)[]): *function | (Anonymous function)*
**Parameters:**
Name | Type |
------ | ------ |
`mutations` | [Mutation](globals.md#mutation)[] |
**Returns:** *function | (Anonymous function)*
___
### `Const` composeMw
**composeMw**(`mws`: [UpduxMiddleware](globals.md#upduxmiddleware)[]): *(Anonymous function)*
**Parameters:**
Name | Type |
------ | ------ |
`mws` | [UpduxMiddleware](globals.md#upduxmiddleware)[] |
**Returns:** *(Anonymous function)*
___
### `Const` dux
**dux**<**S**, **A**, **X**, **C**>(`config`: C): *object*
**Type parameters:**
▪ **S**
▪ **A**
▪ **X**
**C**: *[UpduxConfig](globals.md#upduxconfig)*
**Parameters:**
Name | Type |
------ | ------ |
`config` | C |
**Returns:** *object*
* **actions**: = this.actions
* **coduxes**: *object[]* = this.coduxes
* **createStore**(): *function*
* (`initial?`: S, `injectEnhancer?`: Function): *StoreS & object*
* **initial**: = this.initial
* **middleware**(): *function*
* (`api`: UpduxMiddlewareAPIS, X): *function*
* (`next`: Function): *function*
* (`action`: A): *any*
* **mutations**(): *object*
* **reducer**(): *function*
* (`state`: S | undefined, `action`: [Action](globals.md#action)): *S*
* **selectors**: = this.selectors
* **subduxes**(): *object*
* **upreducer**(): *function*
* (`action`: [Action](globals.md#action)): *function*
* (`state`: S): *S*
___
### `Const` effectToMw
**effectToMw**(`effect`: [Effect](globals.md#effect), `actions`: [Dictionary](globals.md#dictionary)ActionCreator, `selectors`: [Dictionary](globals.md#dictionary)[Selector](globals.md#selector)): *subMiddleware | augmented*
**Parameters:**
Name | Type |
------ | ------ |
`effect` | [Effect](globals.md#effect) |
`actions` | [Dictionary](globals.md#dictionary)ActionCreator |
`selectors` | [Dictionary](globals.md#dictionary)[Selector](globals.md#selector) |
**Returns:** *subMiddleware | augmented*
___
### sliceMw
**sliceMw**(`slice`: string, `mw`: [UpduxMiddleware](globals.md#upduxmiddleware)): *[UpduxMiddleware](globals.md#upduxmiddleware)*
**Parameters:**
Name | Type |
------ | ------ |
`slice` | string |
`mw` | [UpduxMiddleware](globals.md#upduxmiddleware) |
**Returns:** *[UpduxMiddleware](globals.md#upduxmiddleware)*
___
### `Const` subMiddleware
**subMiddleware**(): *(Anonymous function)*
**Returns:** *(Anonymous function)*
___
### subSelectors
**subSelectors**(`__namedParameters`: [string, Function]): *[string, [Selector](globals.md#selector)][]*
**Parameters:**
Name | Type |
------ | ------ |
`__namedParameters` | [string, Function] |
**Returns:** *[string, [Selector](globals.md#selector)][]*

View File

@ -1,3 +0,0 @@
export default {
roots: ['./src'],
};

View File

@ -1,21 +0,0 @@
{
"plugins": ["plugins/markdown"],
"recurseDepth": 10,
"source": {
"includePattern": ".+\\.js(doc|x)?$",
"excludePattern": "(^|\\/|\\\\)_"
},
"sourceType": "module",
"tags": {
"allowUnknownTags": true,
"dictionaries": ["jsdoc", "closure"]
},
"templates": {
"cleverLinks": false,
"monospaceLinks": false
},
"opts": {
"destination": "./docs",
"tutorials": "./tutorials"
}
}

View File

@ -1,13 +0,0 @@
{
"groups": [
{
"title": "Documentation",
"pages": [
{
"title": "Blah",
"source": "./tutorials/tutorial.md"
}
]
}
]
}

18
src/Updux.d.ts vendored
View File

@ -1,18 +0,0 @@
type UpduxConfig<TState> = Partial<{
initial: TState;
subduxes: Record<string, any>;
actions: Record<string, any>;
selectors: Record<string, Function>;
mutations: Record<string, Function>;
mappedSelectors: Record<string, Function>;
effects: Record<string, Function>;
reactions: Record<string, Function>;
mappedReaction: Function;
}>;
export class Updux<TState = unknown> {
constructor(config: UpduxConfig<TState>);
get initial(): TState;
get selectors(): unknown;
}

View File

@ -1,168 +0,0 @@
import { Updux } from './Updux.js';
import { action } from './actions.js';
test('basic state', () => {
const alpha = new Updux({
initial: { sub: 1 },
});
const beta = new Updux({
initial: { foo: 1 },
});
const dux = new Updux({
initial: { a: 1, b: 'two' },
subduxes: { alpha, beta },
});
expect(dux.initial).toMatchObject({
a: 1,
b: 'two',
alpha: { sub: 1 },
beta: { foo: 1 },
});
});
test('basic actions', () => {
const alpha = new Updux({
actions: {
foo: action('foo'),
},
});
const beta = new Updux({});
const dux = new Updux({
subduxes: { alpha, beta },
actions: {
bar: action('bar'),
},
});
expect(Object.keys(dux.actions).sort()).toMatchObject(['bar', 'foo']);
});
test('setAction', () => {
const dux = new Updux({
actions: {
bar: action('bar'),
},
});
dux.setAction('foo');
expect(Object.keys(dux.actions).sort()).toMatchObject(['bar', 'foo']);
});
test('basic selectors', () => {
const alpha = new Updux({
initial: { quux: 3 },
selectors: {
getQuux: ({ quux }) => quux,
},
});
const dux = new Updux({
initial: {
foo: 1,
bar: 4,
},
subduxes: { alpha },
selectors: {
getBar: ({ bar }) => bar,
},
});
dux.setSelector('getFoo', ({ foo }) => foo);
dux.setSelector(
'getAdd',
({ foo }) =>
(add) =>
add + foo
);
dux.setAction('stuff');
expect(dux.selectors.getBar({ bar: 3 })).toEqual(3);
expect(dux.selectors.getFoo({ foo: 3 })).toEqual(3);
expect(alpha.selectors.getQuux({ quux: 1 })).toEqual(1);
expect(dux.selectors.getQuux({ alpha: { quux: 1 } })).toEqual(1);
const store = dux.createStore();
expect(store.getState.getFoo()).toEqual(1);
expect(store.getState.getQuux()).toEqual(3);
expect(store.getState.getAdd(7)).toEqual(8);
});
test('mutations', () => {
const alpha = new Updux({
initial: { quux: 3 },
actions: { add: (x:number)=>x },
});
alpha.setMutation('add', (toAdd) => (state) => ({
quux: state.quux + toAdd,
}));
const dux = new Updux({
initial: {
foo: 1,
bar: 4,
},
subduxes: { alpha },
actions: {
subtract: ()=>{},
}
});
dux.setMutation('add', (toAdd) => (state) => ({
...state,
foo: state.foo + toAdd,
}));
dux.setMutation('subtract', (toSubtract) => (state) => ({
...state,
bar: state.bar - toSubtract,
}));
const store = dux.createStore();
expect(store.getState()).toMatchObject({
foo: 1,
bar: 4,
alpha: { quux: 3 },
});
store.dispatch.add(10);
expect(store.getState()).toMatchObject({
foo: 11,
bar: 4,
alpha: { quux: 13 },
});
store.dispatch.subtract(20);
expect(store.getState()).toMatchObject({
foo: 11,
bar: -16,
alpha: { quux: 13 },
});
});
test('middleware', () => {
const fooEffect = jest.fn(() => true);
const dux = new Updux({
effects: {
foo: () => (next) => (action) => {
fooEffect();
next(action);
},
},
});
const store = dux.createStore();
expect(fooEffect).not.toBeCalled();
store.dispatch({ type: 'foo' });
expect(fooEffect).toBeCalled();
});

View File

@ -1,457 +0,0 @@
/* TODO change * for leftovers to +, change subscriptions to reactions */
import moize from 'moize';
import u from 'updeep';
import { createStore as reduxCreateStore, applyMiddleware } from 'redux';
import { get, map, mapValues, merge, difference } from 'lodash-es';
import { buildInitial } from './buildInitial/index.js';
import { buildActions } from './buildActions/index.js';
import { buildSelectors } from './buildSelectors/index.js';
import { action } from './actions.js';
import { buildUpreducer } from './buildUpreducer.js';
import {
buildMiddleware,
augmentMiddlewareApi,
effectToMiddleware,
} from './buildMiddleware/index.js';
import {
AggregateDuxActions,
AggregateDuxState,
Dict,
ItemsOf,
Reducer,
Upreducer,
} from './types.js';
type Mutation<TState,TAction extends { payload?: any }> = (payload:TAction['payload'], action:TAction) => (state: TState) => TState;
/**
* Configuration object typically passed to the constructor of the class Updux.
*/
export interface UpduxConfig<
TState = any,
TActions = {},
TSelectors = {},
TSubduxes = {}
> {
/**
* Local initial state.
* @default {}
*/
initial?: TState;
/**
* Subduxes to be merged to this dux.
*/
subduxes?: TSubduxes;
/**
* Local actions.
*/
actions?: TActions;
/**
* Local selectors.
*/
selectors?: Record<string, Function>;
/**
* Local mutations
*/
mutations?: Record<string, Function>;
/**
* Selectors to apply to the mapped subduxes. Only
* applicable if the dux is a mapping dux.
*/
mappedSelectors?: Record<string, Function>;
/**
* Local effects.
*/
effects?: Record<string, Function>;
/**
* Local reactions.
*/
reactions?: Function[];
/**
* If true, enables mapped reactions. Additionally, it can be
* a reaction function, which will treated as a regular
* reaction for the mapped dux.
*/
mappedReaction?: Function | boolean;
/**
* Wrapping function for the upreducer to provides full customization.
* @example
* // if an action has the 'dontDoIt' meta flag, don't do anything
* const dux = new Updux({
* ...,
* upreducerWrapper: (upreducer) => action => {
* if( action?.meta?.dontDoIt ) return state => state;
* return upreducer(action);
* }
* })
*/
upreducerWrapper?: (
upreducer: Upreducer<
AggregateDuxState<TState, TSubduxes>,
ItemsOf<AggregateDuxActions<TActions, TSubduxes>>
>
) => Upreducer<
AggregateDuxState<TState, TSubduxes>,
ItemsOf<AggregateDuxActions<TActions, TSubduxes>>
>;
middlewareWrapper?: Function;
}
export class Updux<
TState extends any = {},
TActions extends object = {},
TSelectors = {},
TSubduxes extends object = {}
> {
/** @type { unknown } */
#initial = {};
#subduxes = {};
/** @type Record<string,Function> */
#actions = {};
#selectors = {};
#mutations = {};
#effects = [];
#reactions = [];
#mappedSelectors = undefined;
#mappedReaction = undefined;
#upreducerWrapper = undefined;
#middlewareWrapper = undefined;
constructor(
config: UpduxConfig<TState, TActions, TSelectors, TSubduxes>
) {
this.#initial = config.initial ?? {};
this.#subduxes = config.subduxes ?? {};
if (config.subduxes) {
this.#subduxes = mapValues(config.subduxes, (sub) =>
sub instanceof Updux ? sub : new Updux(sub)
);
}
if (config.actions) {
for (const [type, actionArg] of Object.entries(config.actions)) {
if (typeof actionArg === 'function' && actionArg.type) {
this.#actions[type] = actionArg;
} else {
const args = Array.isArray(actionArg)
? actionArg
: [actionArg];
this.#actions[type] = action(type, ...args);
}
}
}
this.#selectors = config.selectors ?? {};
this.#mappedSelectors = config.mappedSelectors;
this.#mutations = config.mutations ?? {};
Object.keys(this.#mutations)
.filter((action) => action !== '+')
.filter((action) => !this.actions.hasOwnProperty(action))
.forEach((action) => {
throw new Error(`action '${action}' is not defined`);
});
if (config.effects) {
this.#effects = Object.entries(config.effects);
}
this.#reactions = config.reactions ?? [];
this.#mappedReaction = config.mappedReaction;
this.#upreducerWrapper = config.upreducerWrapper;
this.#middlewareWrapper = config.middlewareWrapper;
}
#memoInitial = moize(buildInitial);
#memoActions = moize(buildActions);
#memoSelectors = moize(buildSelectors);
#memoUpreducer = moize(buildUpreducer);
#memoMiddleware = moize(buildMiddleware);
setMappedSelector(name, f) {
this.#mappedSelectors = {
...this.#mappedSelectors,
[name]: f,
};
}
get middleware() {
return this.#memoMiddleware(
this.#effects,
this.actions,
this.selectors,
this.#subduxes,
this.#middlewareWrapper,
this
);
}
setMiddlewareWrapper(wrapper: Function) {
this.#middlewareWrapper = wrapper;
}
/** @member { unknown } */
get initial(): AggregateDuxState<TState, TSubduxes> {
return this.#memoInitial(this.#initial, this.#subduxes);
}
get actions(): AggregateDuxActions<TActions, TSubduxes> {
return this.#memoActions(this.#actions, this.#subduxes) as any;
}
get selectors() {
return this.#memoSelectors(
this.#selectors,
this.#mappedSelectors,
this.#subduxes
);
}
get subduxes() { return this.#subduxes }
get upreducer(): Upreducer<
AggregateDuxState<TState, TSubduxes>,
ItemsOf<AggregateDuxActions<TActions, TSubduxes>>
> {
return this.#memoUpreducer(
this.initial,
this.#mutations,
this.#subduxes,
this.#upreducerWrapper
);
}
get reducer(): Reducer<
AggregateDuxState<TState, TSubduxes>,
ItemsOf<AggregateDuxActions<TActions, TSubduxes>>
> {
return (state, action) => this.upreducer(action)(state);
}
addSubscription(subscription) {
this.#reactions = [...this.#reactions, subscription];
}
addReaction(reaction) {
this.#reactions = [...this.#reactions, reaction];
}
setAction(type, payloadFunc?: (...args: any) => any) {
const theAction = action(type, payloadFunc);
this.#actions = { ...this.#actions, [type]: theAction };
return theAction;
}
setSelector(name, func) {
// TODO selector already exists? Complain!
this.#selectors = {
...this.#selectors,
[name]: func,
};
return func;
}
setMutation<TAction extends keyof AggregateDuxActions<TActions,TSubduxes>>(name: TAction, mutation: Mutation<AggregateDuxState<TState, TSubduxes>,
ReturnType<AggregateDuxActions<TActions,TSubduxes>[TAction]>>) {
if (typeof name === 'function') name = name.type;
this.#mutations = {
...this.#mutations,
[name]: mutation,
};
return mutation;
}
addEffect<TType, E>(action: TType, effect: E): E {
this.#effects = [...this.#effects, [action, effect]];
return effect;
}
augmentMiddlewareApi(api) {
return augmentMiddlewareApi(api, this.actions, this.selectors);
}
splatSubscriber(store, inner, splatReaction) {
const cache = {};
return () => (state, previous, unsub) => {
const cacheKeys = Object.keys(cache);
const newKeys = difference(Object.keys(state), cacheKeys);
for (const slice of newKeys) {
let localStore = {
...store,
getState: () => store.getState()[slice],
};
cache[slice] = [];
if (typeof splatReaction === 'function') {
localStore = {
...localStore,
...splatReaction(localStore, slice),
};
}
const { unsub, subscriber, subscriberRaw } =
inner.subscribeAll(localStore);
cache[slice].push({ unsub, subscriber, subscriberRaw });
subscriber();
}
const deletedKeys = difference(cacheKeys, Object.keys(state));
for (const deleted of deletedKeys) {
for (const inner of cache[deleted]) {
inner.subscriber();
inner.unsub();
}
delete cache[deleted];
}
};
}
subscribeTo(store, subscription, setupArgs = []) {
const localStore = augmentMiddlewareApi(
{
...store,
subscribe: (subscriber) =>
this.subscribeTo(store, () => subscriber),
},
this.actions,
this.selectors
);
const subscriber = subscription(localStore, ...setupArgs);
let previous;
const memoSub = () => {
const state = store.getState();
if (state === previous) return;
let p = previous;
previous = state;
subscriber(state, p, unsub);
};
let ret = store.subscribe(memoSub);
const unsub = typeof ret === 'function' ? ret : ret.unsub;
return {
unsub,
subscriber: memoSub,
subscriberRaw: subscriber,
};
}
subscribeAll(store) {
let results = this.#reactions.map((sub) =>
this.subscribeTo(store, sub)
);
for (const subdux in this.#subduxes) {
if (subdux !== '*') {
const localStore = {
...store,
getState: () => get(store.getState(), subdux),
};
results.push(this.#subduxes[subdux].subscribeAll(localStore));
}
}
if (this.#mappedReaction) {
results.push(
this.subscribeTo(
store,
this.splatSubscriber(
store,
this.#subduxes['*'],
this.#mappedReaction
)
)
);
}
return {
unsub: () => results.forEach(({ unsub }) => unsub()),
subscriber: () =>
results.forEach(({ subscriber }) => subscriber()),
subscriberRaw: (...args) =>
results.forEach(({ subscriberRaw }) =>
subscriberRaw(...args)
),
};
}
createStore(initial?: unknown, enhancerGenerator?: Function) {
const enhancer = (enhancerGenerator ?? applyMiddleware)(
this.middleware
);
const store: {
getState: Function & Record<string, Function>;
dispatch: Function & Record<string, Function>;
selectors: Record<string, Function>;
actions: AggregateDuxActions<TActions, TSubduxes>;
} = reduxCreateStore(
this.reducer as any,
initial ?? this.initial,
enhancer
) as any;
store.actions = this.actions;
store.selectors = this.selectors;
merge(
store.getState,
mapValues(this.selectors, (selector) => {
return (...args) => {
let result = selector(store.getState());
if (typeof result === 'function') return result(...args);
return result;
};
})
);
for (const action in this.actions) {
store.dispatch[action] = (...args) => {
return store.dispatch(this.actions[action](...(args as any)));
};
}
this.subscribeAll(store);
return store;
}
effectToMiddleware(effect) {
return effectToMiddleware(effect, this.actions, this.selectors);
}
}

View File

@ -1,34 +0,0 @@
import { action } from './actions.js';
import u from 'updeep';
test('action generators', () => {
const foo = action('foo');
expect(foo.type).toEqual('foo');
expect(foo()).toMatchObject({ type: 'foo' });
const bar = action('bar');
expect(bar.type).toEqual('bar');
expect(bar()).toMatchObject({ type: 'bar' });
const action3 = action('a3', (x:number) => x);
expect(action3(12)).toMatchObject({
type: 'a3',
payload: 12,
});
const action4 = action('a4', undefined, u.updateIn('meta.x','yay'));
expect(action4(13)).toMatchObject({
type: 'a4',
payload: 13,
meta: {x:'yay'},
});
expect(action4.type).toEqual('a4');
});

View File

@ -1,60 +0,0 @@
export type Action<T extends string = string, TPayload = any> = {
type: T;
meta?: Record<string, unknown>;
} & {
payload?: TPayload;
};
export type ActionGenerator<
TType extends string = string,
TPayloadGen = (...args: any[]) => any
> = {
type: TType;
} & (TPayloadGen extends (...args: any) => any
? ReturnType<TPayloadGen> extends void
? (...args: Parameters<TPayloadGen>) => {
type: TType;
}
: (...args: Parameters<TPayloadGen>) => {
type: TType;
payload: ReturnType<TPayloadGen>;
}
: (...args: any[]) => { type: TType; payload?: unknown });
// interface Action {
// <T extends string = string>(actionType: T): ActionGenerator<T>;
// <T extends string = string, F extends Function = Function>(
// actionType: T,
// payloadGen: F
// ): ActionGenerator<T, F>;
// }
export function action<
TType extends string,
TPayload extends (...args: any) => any
>(
type: TType,
payloadFunction?: TPayload,
transformer?: Function
): ActionGenerator<TType, TPayload> {
let generator : any= function (...payloadArg) {
const result: Action = { type };
if (payloadFunction) {
result.payload = payloadFunction(...payloadArg);
} else {
if (payloadArg[0] !== undefined) result.payload = payloadArg[0];
}
return result;
};
if(transformer) {
const orig = generator;
generator = (...args: any) => transformer(orig(...args), args);
}
generator.type = type;
return generator;
}

View File

@ -1,20 +0,0 @@
export function buildActions(actions = {}, subduxes = {}) {
// priority => generics => generic subs => craft subs => creators
const merged = { ...actions };
Object.values(subduxes).forEach(({ actions }) => {
if (!actions) return;
Object.entries(actions).forEach(([type, func]) => {
if (merged[type]) {
if (merged[type] === func) return;
throw new Error(
`trying to merge two different actions ${type}`
);
}
merged[type] = func;
});
});
return merged;
}

View File

@ -1,18 +0,0 @@
import { mapValues } from 'lodash-es';
import isPlainObject from 'lodash/isPlainObject.js';
import u from 'updeep';
export function buildInitial(initial, subduxes = {}) {
if (!isPlainObject(initial) && Object.keys(subduxes).length > 0)
throw new Error(
"can't have subduxes on a dux which state is not an object"
);
if (Object.keys(subduxes).length === 1 && subduxes['*']) return initial;
const subInitial = mapValues(subduxes, ({ initial }, key) =>
key === '*' ? [] : initial
);
return u(initial, subInitial);
}

View File

@ -1,8 +0,0 @@
import { buildInitial } from './index.js';
test('basic', () => {
expect(buildInitial({ a: 1 }, { b: { initial: { c: 2 } } })).toMatchObject({
a: 1,
b: { c: 2 },
});
});

View File

@ -1,85 +0,0 @@
import u from 'updeep';
import { mapValues, map, get } from 'lodash-es';
const middlewareFor = (type, middleware) => (api) => (next) => (action) => {
if (type !== '*' && action.type !== type) return next(action);
return middleware(api)(next)(action);
};
const sliceMw = (slice, mw) => (api) => {
const getSliceState = () => get(api.getState(), slice);
return mw({ ...api, getState: getSliceState });
};
export function augmentMiddlewareApi(api, actions, selectors) {
const getState = () => api.getState();
const dispatch = (action) => api.dispatch(action);
Object.assign(
getState,
mapValues(selectors, (selector) => {
return (...args) => {
let result = selector(api.getState());
if (typeof result === 'function') return result(...args);
return result;
};
})
);
Object.assign(
dispatch,
mapValues(actions, (action) => {
return (...args) => api.dispatch(action(...args));
})
);
return {
...api,
getState,
dispatch,
actions,
selectors,
};
}
export const effectToMiddleware = (effect, actions, selectors) => {
let mw = effect;
let action = '*';
if (Array.isArray(effect)) {
action = effect[0];
mw = effect[1];
mw = middlewareFor(action, mw);
}
return (api) => mw(augmentMiddlewareApi(api, actions, selectors));
};
const composeMw = (mws) => (api) => (original_next) =>
mws.reduceRight((next, mw) => mw(api)(next), original_next);
export function buildMiddleware(
effects = [],
actions = {},
selectors = {},
sub = {},
wrapper = undefined,
dux = undefined,
) {
let inner = map(sub, ({ middleware }, slice) =>
slice !== '*' && middleware ? sliceMw(slice, middleware) : undefined
).filter((x) => x);
const local = effects.map((effect) =>
effectToMiddleware(effect, actions, selectors)
);
let mws = [...local, ...inner];
if( wrapper ) mws = wrapper(mws,dux);
return composeMw(mws);
}

View File

@ -1,114 +0,0 @@
import { buildMiddleware } from '.';
import { action } from '../actions';
test('single effect', async () => {
const effect = (api) => (next) => (action) => {
expect(action).toMatchObject({ type: 'foo' });
expect(api).toHaveProperty('actions');
expect(api).toHaveProperty('selectors');
next();
};
const middleware = buildMiddleware([effect]);
await new Promise((resolve) => {
middleware({})(resolve)({ type: 'foo' });
});
});
test('augmented api', async () => {
const effect = (api) => (next) => (action) => {
// selectors
expect(api.getState.getB()).toEqual(1);
expect(api.selectors.getB({ a: { b: 2 } })).toEqual(2);
expect(api.getState()).toMatchObject({ a: { b: 1 } });
// dispatch
expect(api.actions.actionOne()).toMatchObject({ type: 'actionOne' });
api.dispatch.actionOne('the payload');
next();
};
const middleware = buildMiddleware(
[effect],
{
actionOne: action('actionOne'),
},
{
getB: (state) => state.a.b,
}
);
const getState = jest.fn(() => ({ a: { b: 1 } }));
const dispatch = jest.fn(() => null);
await new Promise((resolve) => {
middleware({
getState,
dispatch,
})(resolve)({ type: 'foo' });
});
expect(dispatch).toBeCalledTimes(1);
expect(dispatch).toBeCalledWith({
type: 'actionOne',
payload: 'the payload',
});
});
test('subduxes', async () => {
const effect1 = (api) => (next) => (action) => {
next({
type: action.type,
payload: [...action.payload, 1],
});
};
const effect2 = (api) => (next) => (action) => {
next({
type: action.type,
payload: [...action.payload, 2],
});
};
const effect3 = (api) => (next) => (action) => {
next({
type: action.type,
payload: [...action.payload, 3],
});
};
const mw = buildMiddleware(
[effect1],
{},
{},
{
a: { middleware: effect2 },
b: { middleware: effect3 },
}
);
mw({})(({ payload }) => {
expect(payload).toMatchObject([1, 2, 3]);
})({ type: 'foo', payload: [] });
// api for subduxes
const effect = (api) => (next) => (action) => {
expect(api.getState()).toEqual(3);
next();
};
const mwInner = buildMiddleware([effect]);
const mwOuter = buildMiddleware(
[],
{},
{},
{ alpha: { middleware: mwInner } }
);
await new Promise((resolve) => {
mwOuter({
getState: () => ({ alpha: 3 }),
})(resolve)({ type: 'foo' });
});
});

View File

@ -1,38 +0,0 @@
import { map, mapValues, merge } from 'lodash-es';
export function buildSelectors(
localSelectors,
splatSelector = {},
subduxes = {}
) {
const subSelectors = map(subduxes, ({ selectors }, slice) => {
if (!selectors) return {};
if (slice === '*') return {};
return mapValues(
selectors,
(func: Function) => (state) => func(state[slice])
);
});
let splat = {};
for (const name in splatSelector) {
splat[name] =
(state) =>
(...args) => {
const value = splatSelector[name](state)(...args);
const res = () => value;
return merge(
res,
mapValues(
subduxes['*'].selectors,
(selector) => () => selector(value)
)
);
};
}
return merge({}, ...subSelectors, localSelectors, splat);
}

View File

@ -1,45 +0,0 @@
import u from 'updeep';
import { mapValues } from 'lodash-es';
export function buildUpreducer(
initial,
mutations,
subduxes = {},
wrapper = undefined
) {
const subReducers =
Object.keys(subduxes).length > 0
? mapValues(subduxes, ({ upreducer }) => upreducer)
: null;
const upreducer = (action) => (state) => {
if (!action?.type)
throw new Error('upreducer called with a bad action');
let newState = state ?? initial;
if (subReducers) {
if (subduxes['*']) {
newState = u.updateIn(
'*',
subduxes['*'].upreducer(action),
newState
);
} else {
const update = mapValues(subReducers, (upReducer) =>
upReducer(action)
);
newState = u(update, newState);
}
}
const a = mutations[action.type] || mutations['+'];
if (!a) return newState;
return a(action.payload, action)(newState);
};
return wrapper ? wrapper(upreducer) : upreducer;
}

View File

@ -1,49 +0,0 @@
import u from 'updeep';
import add from 'lodash/fp/add.js';
import { Updux } from './index.js';
test('README.md', () => {
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);
expect(store.getState().counter).toEqual(1);
});
test('tutorial', () => {
const todosDux = new Updux<any, any>({
initial: {
next_id: 1,
todos: [],
},
});
todosDux.setAction('addTodo');
todosDux.setAction('todoDone');
expect(todosDux.actions.addTodo('write tutorial')).toMatchObject({
type: 'addTodo',
payload: 'write tutorial',
});
});

View File

@ -1,3 +0,0 @@
export { Updux, UpduxConfig } from './Updux.js';
export { action } from './actions.js';
export { AggregateDuxActions, AggregateDuxState } from './types.js';

View File

@ -1,110 +0,0 @@
import { Updux } from './Updux';
import { action } from './actions';
test('basic', () => {
const doIt = action('doIt');
const thisToo = action('thisToo');
const dux = new Updux({
initial: '',
actions: { doIt, thisToo },
mutations: {
doIt: () => () => 'bingo',
thisToo: () => () => 'straight type',
},
});
expect(dux.reducer(undefined, dux.actions.doIt())).toEqual('bingo');
expect(dux.reducer(undefined, dux.actions.thisToo())).toEqual(
'straight type'
);
});
test('override', () => {
const foo = action('foo');
const dux = new Updux({
initial: { alpha: [] },
mutations: {
'+': (payload, action) => (state) => ({
...state,
alpha: [...state.alpha, action.type],
}),
},
subduxes: {
subbie: new Updux({
initial: 0,
actions: {
foo,
},
mutations: {
foo: () => (state) => state + 1,
},
}),
},
});
let state = [foo(), { type: 'bar' }].reduce(
(state, action) => dux.upreducer(action)(state),
undefined
);
expect(state).toMatchObject({
alpha: ['foo', 'bar'],
subbie: 1,
});
});
test('order of processing', () => {
const foo = action('foo');
const dux = new Updux({
initial: {
x: [],
},
mutations: {
foo:
() =>
({ x }) => ({ x: [...x, 'main'] }),
},
subduxes: {
x: new Updux({
actions: { foo },
mutations: {
foo: () => (state) => [...state, 'subdux'],
},
}),
},
});
expect(dux.reducer(undefined, foo())).toMatchObject({
x: ['subdux', 'main'],
});
});
test('setMutation', () => {
const foo = action('foo');
const dux = new Updux({
initial: '',
});
// noop
expect(dux.reducer(undefined, foo())).toEqual('');
dux.setMutation('foo', () => () => 'foo');
expect(dux.reducer(undefined, foo())).toEqual('foo');
});
test('setMutation, name as function', () => {
const bar = action('bar');
const dux = new Updux({
initial: '',
});
dux.setMutation(bar, () => () => 'bar');
expect(dux.reducer(undefined, bar())).toEqual('bar');
});

View File

@ -1,32 +0,0 @@
import u from 'updeep';
import { Updux } from './Updux';
test('basic reducer', () => {
const dux = new Updux({});
expect(typeof dux.reducer).toBe('function');
expect(dux.reducer({ a: 1 }, { type: 'foo' })).toMatchObject({ a: 1 }); // noop
});
test('basic upreducer', () => {
const dux = new Updux({});
expect(typeof dux.upreducer).toBe('function');
expect(dux.upreducer({ type: 'foo' })({ a: 1 })).toMatchObject({ a: 1 }); // noop
});
test('reducer with action', () => {
const dux = new Updux({
actions: {
inc: null,
},
mutations: {
inc: () => u({ a: (x) => x + 1 }),
},
});
expect(dux.reducer({ a: 1 }, { type: 'inc' })).toMatchObject({ a: 2 });
});

View File

@ -1,135 +0,0 @@
import { Updux } from '.';
import { action } from './actions';
test('basic selectors', () => {
const updux = new Updux({
subduxes: {
bogeys: new Updux({
selectors: {
bogey: (bogeys) => (id) => bogeys[id],
},
}),
},
selectors: {
bogeys: ({ bogeys }) => bogeys,
},
});
const state = {
bogeys: {
foo: 1,
bar: 2,
},
};
expect(updux.selectors.bogeys(state)).toMatchObject({ foo: 1, bar: 2 });
expect(updux.selectors.bogey(state)('foo')).toEqual(1);
});
test('available in the middleware', () => {
const doIt = action('doIt');
const updux = new Updux({
actions: { doIt },
subduxes: {
bogeys: new Updux({
initial: { enkidu: 'foo' },
selectors: {
bogey: (bogeys) => (id) => bogeys[id],
},
}),
},
effects: {
doIt:
({ selectors: { bogey }, getState }) =>
(next) =>
(action) => {
next({
...action,
payload: bogey(getState())('enkidu'),
});
},
},
mutations: {
doIt: (payload) => (state) => ({ ...state, payload }),
},
});
const store = updux.createStore();
store.dispatch(updux.actions.doIt());
expect(store.getState()).toMatchObject({ payload: 'foo' });
});
test('selector typescript', () => {
const bar = new Updux({
initial: { baz: 1 },
selectors: {
getBaz: (state) => state.baz,
getStringBaz: (state) => `${state.baz}`,
getMultBaz: (state) => (mult) => state.baz * mult,
},
});
expect(bar.selectors.getBaz(bar.initial)).toEqual(1);
expect(bar.selectors.getMultBaz({ baz: 3 })(2)).toEqual(6);
// subduxes
const foo = new Updux({
subduxes: { bar },
selectors: {
getRoot: () => 'root',
},
});
expect(foo.selectors.getBaz(foo.initial)).toEqual(1);
expect(foo.selectors.getMultBaz({ bar: { baz: 3 } })(2)).toEqual(6);
expect(foo.selectors.getRoot).toBeTruthy();
/// no root selector
const foo3 = new Updux({
subduxes: {
quux: new Updux({}),
bar: new Updux({
selectors: {
getBaz: () => 'baz',
},
}),
},
});
expect(foo3.selectors.getBaz).toBeTruthy();
});
test('selector in mw', () => {
const myDux = new Updux({
initial: { stuff: 12 },
subduxes: {
bar: new Updux({
initial: 'potato',
selectors: { getBar: () => 'meh' },
}),
},
selectors: {
getStuff: (state) => state.stuff,
},
});
let ranEffect = false;
myDux.addEffect('*', ({ selectors, getState }) => () => () => {
['getStuff', 'getBar'].forEach((selector) =>
expect(typeof selectors[selector]).toEqual('function')
);
expect(getState.getStuff()).toEqual(12);
expect(getState.getBar()).toEqual('meh');
ranEffect = true;
});
myDux.createStore().dispatch({ type: 'foo' });
expect(ranEffect).toBeTruthy();
});

Some files were not shown because too many files have changed in this diff Show More