├── .gitignore
├── LICENSE
├── README.md
├── examples
├── connect
│ ├── components
│ │ ├── greeting.js
│ │ ├── list.js
│ │ └── name.js
│ ├── index.js
│ └── reducer.js
└── simple
│ ├── component.js
│ ├── index.js
│ └── reducer.js
├── index.js
├── package.json
└── test
├── all.js
├── connect.js
└── simple.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | node_modules
28 |
29 | # Optional npm cache directory
30 | .npm
31 |
32 | # Optional REPL history
33 | .node_repl_history
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Jeremy Freeman
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # hxdx
2 |
3 | [![NPM version][npm-image]][npm-url]
4 | [![js-standard-style][standard-image]][standard-url]
5 |
6 | > simple connecter for state dispatching and rendering
7 |
8 | Connects a `redux`-style store to a `virtual-dom`-style view and sets up rendering with minimal boilerplate. Works well with functional components that take state and sometimes dispatch.
9 |
10 | Exposes an `hx` function for constructing components elements, and a `dx` function for dispatching to the store within your components. Thus the name! Currently uses [`hyperx`](http://github.com/substack/hyperx) for defining components and [`main-loop`](http://github.com/Raynos/main-loop) for rendering. Doesn't require `redux`, just something that acts as a state store.
11 |
12 | I wrote this because I love the `redux` design pattern, but found the `react-redux` bindings, and `react` in general, big and complex and hard to reason about. If you care about performance those are supposed to be much faster!
13 |
14 | See also
15 | - [`virtual-app`](https://github.com/sethvincent/virtual-app) related idea with different dependencies
16 | - [`redux-react`](https://github.com/reactjs/react-redux) official connector for using redux with react
17 |
18 | ## install
19 |
20 | ```
21 | npm install hxdx
22 | ```
23 |
24 | ## example
25 |
26 | Set up a simple `redux` store with one action
27 |
28 | ```javascript
29 | var reducer = function (state, action) {
30 | switch (action.type) {
31 | case 'INCREMENT':
32 | return state + 1
33 | default:
34 | return state
35 | }
36 | }
37 |
38 | var store = require('redux').createStore(reducer, 0)
39 | ```
40 |
41 | Then create your components (normally these would be in separate files)
42 |
43 | We'll make one that renders
44 |
45 | ```javascript
46 | var display = function (state) {
47 | return hx`
${state}
`
48 | }
49 | ```
50 |
51 | And one that dipatches
52 |
53 | ```javascript
54 | var button = function (state) {
55 | function onclick () {
56 | dx({type: 'INCREMENT'})
57 | }
58 | return hx``
59 | }
60 | ```
61 |
62 | Then just render your top-level component using the store
63 |
64 | ```javascript
65 | var app = function (state) {
66 | return hx`
${display(state)}${button()}
`
67 | }
68 |
69 | hxdx.render(app, store)
70 | ```
71 |
72 | and the DOM will be updated using diffing on every click.
73 |
74 | ## api
75 |
76 | #### `hxdx.render(component, store, [root])`
77 |
78 | Render a component and connect it to a store.
79 |
80 | - `component` function mapping state to a virtual dom element
81 | - `store` a state store with `subscribe`, `dispatch`, and `getState` methods
82 | - `root` a base DOM element to append to (if undefined will appemd to body)
83 |
84 | Store can be able object that follows the [`redux`](https://github.com/reactjs/redux) API.
85 |
86 | #### `hxdx.hx('<>')`
87 |
88 | Tagged template function for generating `virtual-dom` elements. Can be required inside any of your components.
89 |
90 | #### `hxdx.dx(action)`
91 |
92 | Dispatch action to the store. Can be required inside any of your components.
93 |
94 | [npm-image]: https://img.shields.io/badge/npm-v1.0.0-lightgray.svg?style=flat-square
95 | [npm-url]: https://npmjs.org/package/hxdx
96 | [standard-image]: https://img.shields.io/badge/code%20style-standard-lightgray.svg?style=flat-square
97 | [standard-url]: https://github.com/feross/standard
98 |
--------------------------------------------------------------------------------
/examples/connect/components/greeting.js:
--------------------------------------------------------------------------------
1 | const hxdx = require('../../../index')
2 | const hx = hxdx.hx
3 | const connect = hxdx.connect
4 |
5 | function greeting (state) {
6 | return hx`
7 | ${state.name}
8 | `
9 | }
10 |
11 | module.exports = connect({ name: 'name' }, greeting)
12 |
13 |
--------------------------------------------------------------------------------
/examples/connect/components/list.js:
--------------------------------------------------------------------------------
1 | const hxdx = require('../../../index')
2 | const hx = hxdx.hx
3 | const connect = hxdx.connect
4 |
5 | const greeting = require('./greeting.js')
6 |
7 | function list (state) {
8 | function greetings () {
9 | return state.greetings.map(function (word) {
10 | return hx`