Skip to content

Commit

Permalink
Merge pull request #8 from KevinAst/feature-gitbookDoc
Browse files Browse the repository at this point in the history
publish: v1.0.0 Revised Documentation
  • Loading branch information
KevinAst authored Apr 11, 2017
2 parents dc0f00a + 75a6ed9 commit e1275fd
Show file tree
Hide file tree
Showing 35 changed files with 661 additions and 292 deletions.
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
/lib/
/es/

# documentation (generated via "npm run docs")
/docs/
# documentation (machine generated from GitBook)
/_book/

# api documentation (machine generated from jsdoc2md)
# ... hmmm: cannot ignore it (even though it is machine generated), because gitbook ignores it too :-(
# /docs/api.md

# code coverage reports
/.nyc_output/
Expand Down
16 changes: 14 additions & 2 deletions SCRIPTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,20 @@ pkgReview ... show outdated installed packages
DOCUMENTATION
=============
docs ......... build docs from JavaDoc comments (src/*.js), and Dev Guide (src/docs)
docs:clean ... clean the machine-generated docs/ directory
docs ... build docs - integrating Dev Guide (GitBook: docs/*) with API (JSDoc comments: src/*.js)
docs:api ....... generate docs/api.md from embedded JSDoc comments in src/*.js (run as needed)
docs:prepare ... install gitbook/plugins/dependencies (run once and whenever a plugin is added)
docs:build ..... alias to docs script (minus docs:prepare)
docs:serve ..... build/serve docs (http://localhost:4000/), continuously watching for changes
docs:jsdoc2md:help ... show jsdoc2md command-line help (convenience)
docs:gitbook:help .... show GitBook command-line help (convenience)
docs:clean ... clean the machine-generated docs (_book/)
MISC
Expand Down
60 changes: 60 additions & 0 deletions book.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"gitbook": "3.2.2",
"root": "./docs",
"title": "astx-redux-util",
"description": "Redux Reducer Composition Utilities",
"author": "Kevin J. Bridges <kevinast@gmail.com> (https://github.com/KevinAst)",
"structure": {
"readme": "intro.md",
"summary": "toc.md"
},
"plugins": ["-sharing", "-livereload", "toolbar"],
"pluginsConfig": {
"toolbar": {
"buttons": [
{
"label": "GitHub",
"icon": "fa fa-github",
"url": "https://github.com/KevinAst/astx-redux-util"
},
{
"label": "NPM",
"icon": "fa fa-bullseye",
"url": "https://www.npmjs.com/package/astx-redux-util"
}
]
}
},
"variables": {

"guide": {
"devGuide": "[**Dev Guide**](/index.html)",

"conceptConditional": "[`Conditional Reduction`](/concepts/conditionalReducer.md)",
"conceptJoin": "[`Joining Reducers`](/concepts/joinReducers.md)",
"concepts": "[`Concepts`](/concepts/README.md)",
"conceptHash": "[`Basics`](/concepts/reducerHash.md)",

"dist": "[`Distribution`](/dist.md)",

"ext": "[`Extending astx-redux-util`](/extending/ext.md)",
"logExt": "[`Logging Extension`](/extending/logExt.md)",

"fullExample": "[`A Most Excellent Example`](/fullExample.md)",
"history": "[`Revision History`](/history.md)",
"LICENSE": "[`MIT License`](/LICENSE.md)",
"originalReducerState": "[`originalReducerState`](/originalReducerState.md)",
"start": "[`Getting Started`](/start.md)",
"why": "[`Why astx-redux-util?`](/why.md)"
},

"api": {
"ref": "[`API Reference`](/api.md)",
"conditionalReducer": "[`conditionalReducer()`](/api.md#conditionalReducer)",
"conditionalReducerCB": "[`conditionalReducerCB()`](/api.md#conditionalReducerCB)",
"joinReducers": "[`joinReducers()`](/api.md#joinReducers)",
"reducerHash": "[`reducerHash()`](/api.md#reducerHash)",
"InitialState": "[`InitialState`](/api.md#InitialState)"
}
}
}
2 changes: 2 additions & 0 deletions src/docs/guide/LICENSE.md → docs/LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# MIT License

MIT License

Copyright (c) 2017 Kevin Bridges
Expand Down
125 changes: 125 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@

<br/><br/><br/>

<a id="conditionalReducer"></a>

<h5 style="margin: 10px 0px; border-width: 5px 0px; padding: 5px; border-style: solid;">
conditionalReducer(conditionalFn, thenReducerFn, [elseReducerFn], [initialState]) ⇒ [`reducerFn`](#reducerFn)</h5>
Create a higher-order reducer that conditionally executes one ofthe supplied reducerFns, based on the conditionalFn() returndirective.The {{book.guide.devGuide}} discusses conditionalReducer() in more detail(see {{book.guide.conceptConditional}}), and additional examples canbe found in {{book.guide.conceptJoin}} and {{book.guide.fullExample}}.


| Param | Type | Default | Description |
| --- | --- | --- | --- |
| conditionalFn | [`conditionalReducerCB`](#conditionalReducerCB) | | a callback function whose return value determines which reducerFn is executed ... truthy: thenReducerFn(), falsy: elseReducerFn(). |
| thenReducerFn | [`reducerFn`](#reducerFn) | | the "wrapped" reducer invoked when conditionalFn returns truthy. |
| [elseReducerFn] | [`reducerFn`](#reducerFn) | <code>identity</code> | the optional "wrapped" reducer invoked when conditionalFn returns falsy. DEFAULT: [identity function](https://lodash.com/docs#identity) |
| [initialState] | [`InitialState`](#InitialState) | | the optional fall-back state value used during the state initialization boot-strap process. |

**Returns**: [`reducerFn`](#reducerFn) - a newly created reducer function (described above).

<br/><br/><br/>

<a id="joinReducers"></a>

<h5 style="margin: 10px 0px; border-width: 5px 0px; padding: 5px; border-style: solid;">
joinReducers(...reducerFns, [initialState]) ⇒ [`reducerFn`](#reducerFn)</h5>
Create a higher-order reducer by combining two or more reducers,logically executing each in sequence (in essence combining theirfunctionality into one). This is useful when combining variousreducer types into one logical construct.**Please Note:** Because each reducer is able to build on what hasbeen accomplished by a prior reducer, joinReducers cumulativelypasses the state parameter that was returned from any prior reducer(in the chain of reducers to execute). In essence this is anaccumulative process. While this does NOT relax the immutableconstraint of the reducer's state parameter, it is possible for adown-stream reducer to receive a state parameter that is adifferent instance from the start of the reduction process (becausean up-stream reducer needed to alter it in some way).The {{book.guide.devGuide}} discusses joinReducers() in more detail(see {{book.guide.conceptJoin}}), and additional examples canbe found in {{book.guide.fullExample}}.


| Param | Type | Description |
| --- | --- | --- |
| ...reducerFns | [`reducerFn`](#reducerFn) | two or more reducer functions to join together. |
| [initialState] | [`InitialState`](#InitialState) | the optional fall-back state value used during the state initialization boot-strap process. |

**Returns**: [`reducerFn`](#reducerFn) - a newly created reducer function (described above).

<br/><br/><br/>

<a id="reducerHash"></a>

<h5 style="margin: 10px 0px; border-width: 5px 0px; padding: 5px; border-style: solid;">
reducerHash(actionHandlers, [initialState]) ⇒ [`reducerFn`](#reducerFn)</h5>
Create a higher-order reducer by combining a set of sub-reducerfunctions that are indexed by the standard action.type. When noaction.type is acted on, the original state is merelypassed-through (using the [identityfunction](https://lodash.com/docs#identity)).This is one of the more prevalent composition reducers, andprovides an alternative to the switch statement (commonly used toprovide this control mechanism).The {{book.guide.devGuide}} discusses reducerHash() in more detail (see{{book.guide.conceptHash}}), and additional examples can be found in{{book.guide.conceptJoin}} and {{book.guide.fullExample}}.**SideBar**: Because reducerHash is so central to the rudimentaryaspect of reduction, it is a common practice to extend it,promoting a [`centralized reducer-based logging capability`](/extending/logExt.md), with an ability to correlate logging levels to state changes*(providing a means to filter logs at a high level with minimaloutput)*.


| Param | Type | Description |
| --- | --- | --- |
| actionHandlers | [`ActionReducerHash`](#ActionReducerHash) | a hash of reducer functions, indexed by the standard redux action.type. |
| [initialState] | [`InitialState`](#InitialState) | the optional fall-back state value used during the state initialization boot-strap process. |

**Returns**: [`reducerFn`](#reducerFn) - a newly created reducer function (described above).

<br/><br/><br/>

<a id="conditionalReducerCB"></a>

<h5 style="margin: 10px 0px; border-width: 5px 0px; padding: 5px; border-style: solid;">
conditionalReducerCB ⇒ truthy</h5>
A callback function (used in {{book.api.conditionalReducer}}) whosereturn value determines which reducerFn is executed.


| Param | Type | Description |
| --- | --- | --- |
| state | \* | The current immutable state that is the reduction target. |
| action | [`Action`](#Action) | The standard redux Action object that drives the reduction process. |
| originalReducerState | \* | The immutable state at the time of the start of the reduction process. This is useful in determining whether state has changed within a series of reductions {{book.api.joinReducers}} ... because each individual reducer only has visibility of the state within it's own reduction process. Further information can be found in the {{book.guide.originalReducerState}} discussion of the {{book.guide.devGuide}}. |

**Returns**: truthy - A truthy value indicating which reducerFn isexecuted ... truthy: thenReducerFn(), falsy: elseReducerFn().

<br/><br/><br/>

<a id="ActionReducerHash"></a>

<h5 style="margin: 10px 0px; border-width: 5px 0px; padding: 5px; border-style: solid;">
ActionReducerHash : Object</h5>
A hash of reducer functions, indexed by the standard reduxaction.type.

**Properties**

| Name | Type | Description |
| --- | --- | --- |
| actionType1 | [`reducerFn`](#reducerFn) | The reducer function servicing: 'actionType1'. |
| actionType2 | [`reducerFn`](#reducerFn) | The reducer function servicing: 'actionType2'. |
| ...more | [`reducerFn`](#reducerFn) | ...etc. |


<br/><br/><br/>

<a id="reducerFn"></a>

<h5 style="margin: 10px 0px; border-width: 5px 0px; padding: 5px; border-style: solid;">
reducerFn ⇒ \*</h5>
A standard [redux reducer function](http://redux.js.org/docs/basics/Reducers.html)that is responsible for state changes.


| Param | Type | Description |
| --- | --- | --- |
| state | \* | The current immutable state that is the reduction target. |
| action | [`Action`](#Action) | The standard redux action which drives the reduction process. |

**Returns**: \* - The resulting state after reduction.

<br/><br/><br/>

<a id="Action"></a>

<h5 style="margin: 10px 0px; border-width: 5px 0px; padding: 5px; border-style: solid;">
Action : Object</h5>
A standard [redux Action object](http://redux.js.org/docs/basics/Actions.html)that drives the reduction process.

**Properties**

| Name | Type | Description |
| --- | --- | --- |
| type | string | The action type. |
| whatever | \* | Additional app-specific payload (as needed). |


<br/><br/><br/>

<a id="InitialState"></a>

<h5 style="margin: 10px 0px; border-width: 5px 0px; padding: 5px; border-style: solid;">
InitialState : \*</h5>
All astx-redux-util reducer creators, expose an `initialState`parameter which optionally provides a fall-back state value to useduring the state initialization boot-strap process.In general, redux expects your state to have concrete values(i.e. something other than `undefined`). This means that thereduction entry point to each state element should define adefault. Keeping this in mind, the `initialState` parameter isoptional, because some reducers are "by design" (when combined in acomposition) intended to be mid-stream processors (i.e. NOT thereduction entry point).

Expand Down
14 changes: 14 additions & 0 deletions docs/concepts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Concepts

- {{book.guide.conceptHash}} ... using {{book.api.reducerHash}}, eliminate
the switch statement commonly found in reducers *("look ma, no
switch")*

- {{book.guide.conceptConditional}} ... using
{{book.api.conditionalReducer}}, invoke a reducer only when
certain constraints are met *("to reduce or NOT to reduce; that is
the question")*

- {{book.guide.conceptJoin}} ... using {{book.api.joinReducers}}, team up
multiple reducers to promote higher order functionality *("working
together is success" - Henry Ford)*
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Conditional Reduction

There are times where you may wish to conditionally apply a reduction.

There can be many reasons for this. Take a simple example where you
wish to bypass a reduction process upon determination that an action
will not impact an entire branch of your state tree. In this example
the conditional aspect is purely an optimization.

This can be accomplished through the {@link conditionalReducer} utility.
This can be accomplished through the {{book.api.conditionalReducer}} utility.

```js
import * as Redux from 'redux';
Expand All @@ -30,17 +32,17 @@ example, our action types are organized with a federated namespace, so
it is easy to isolate which actions will impact various parts of our
state.

**Please Note** that a `{}` {@link InitialState} value is applied in
**Please Note** that a `{}` {{book.api.InitialState}} value is applied in
this reduction, which provides the fall-back state value during the
state initialization boot-strap process.

**Also Note:** that normally it is not necessary to supply the
`elseReducerFn` {@link conditionalReducer} parameter (the third),
`elseReducerFn` {{book.api.conditionalReducer}} parameter (the third),
because it defaults to the [identity
function](https://lodash.com/docs#identity) function, which retains
the state for a falsy directive. In this case however, we had to
manually pass the identity function, in order to supply the subsequent
{@link InitialState} parameter.
{{book.api.InitialState}} parameter.

**More to Come:** This example is merely intended to introduce you to
the concept of conditional reduction. It is somewhat "contrived",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Joining Reducers

Occasionally it is necessary for a state to have multiple reductions
applied to it. Typically this occurs when the reducers involved
represent fundamentally different operational types.
Expand Down Expand Up @@ -86,8 +88,8 @@ export default function widget(widget=null, action) {

A more elegant solution can be accomplished by employing reducer
composition, eliminating the procedural code completely. We have
already discussed {@link reducerHash} and {@link conditionalReducer}.
A third utility, the {@link joinReducers} function, combines two or
already discussed {{book.api.reducerHash}} and {{book.api.conditionalReducer}}.
A third utility, the {{book.api.joinReducers}} function, combines two or
more reducers logically executing each in sequence.

*The following snippet, is equivalent to the one above:*
Expand Down
15 changes: 10 additions & 5 deletions src/docs/guide/conceptHash.md → docs/concepts/reducerHash.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Basics

Reducers frequently reason about the action.type, very often using a
switch statement to drive conditional logic:

Expand All @@ -18,7 +20,7 @@ export default function widget(widget=null, action) {
}
```

The {@link reducerHash} function *(the most common composition
The {{book.api.reducerHash}} function *(the most common composition
reducer)* provides a more elegant solution, eliminating the switch
statement altogether. It creates a higher-order reducer, by combining
a set of sub-reducer functions that are indexed by the standard
Expand All @@ -31,18 +33,21 @@ import { reducerHash } from 'astx-redux-util';
export default reducerHash({
"widget.edit": (widget, action) => action.widget,
"widget.edit.close": (widget, action) => null,
}, null);
}, null); // initialState
```

Not only is the conditional logic better encapsulated, but the default
pass-through logic is automatically applied (using the [identity
function](https://lodash.com/docs#identity)), passing through the
original state when no action.type is acted on.

**Please Note** that a `null` {@link InitialState} value is applied in
**Please Note** A `null` {{book.api.InitialState}} value is applied in
this reduction, which provides the fall-back state value during the
state initialization boot-strap process.

**Also Note** that because {@link reducerHash} is so central to the
**SideBar** Because {{book.api.reducerHash}} is so central to the
rudimentary aspects of reduction, it is common to provide a
value-added {@tutorial logExt}.
value-added {{book.guide.logExt}}, with the ability to correlate
logging levels to state changes *(providing a means to filter logs at
a high level with minimal output)*.

2 changes: 2 additions & 0 deletions src/docs/guide/dist.md → docs/dist.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Distribution

This utility is primarily distributed as an [npm
package](https://www.npmjs.com/package/astx-redux-util) (*simply `npm
install` and use it in your [Node.js](https://nodejs.org/en/)
Expand Down
14 changes: 9 additions & 5 deletions src/docs/guide/ext.md → docs/extending/ext.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Extending astx-redux-util

There are many reasons to extend the capabilities of any utility. It
may be a specific proprietary requirement or a common cross-cutting
concerns such as timing, logging, etc. In either case, extending a
Expand All @@ -14,8 +16,9 @@ includes wrapping both the hof (the creator) and the returned function

## The Extension

The basic template for this process is shown here. We enhance {@link
reducerHash}, by applying a hypothetical **foo** operation ...
The basic template for this process is shown here. We enhance
{{book.api.reducerHash}}, by applying a hypothetical **foo** operation
...

```js
import AstxReduxUtil from 'astx-redux-util';
Expand Down Expand Up @@ -74,9 +77,10 @@ high-level points of interest:

## Usage

From a **usage perspective**, we simply replace `reducerHash()` invocations
with `reducerHash.withFoo()` and pass the appropriate foo parameter in
addition to the reducerHash arguments.
From a **usage perspective**, we simply replace
{{book.api.reducerHash}} invocations with `reducerHash.withFoo()` and
pass the appropriate foo parameter in addition to the reducerHash
arguments.

```js
import { reducerHash } from 'astx-redux-util';
Expand Down
File renamed without changes
File renamed without changes
Loading

0 comments on commit e1275fd

Please sign in to comment.