├── .gitignore
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── index.d.ts
├── index.js
├── package-lock.json
├── package.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | test.html
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Andy Johnson
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 | # hyperapp-redux-devtools
2 | hyperapp HOA (higher order app) to utilize redux-devtools-extension from hyperapp
3 |
4 | ```js
5 | import { h, app } from 'hyperapp';
6 | import devtools from 'hyperapp-redux-devtools';
7 |
8 | devtools(app)(
9 | { count: 0 },
10 | {
11 | increment: () => (state) => Object.assign({}, state, { count: state.count + 1 })
12 | },
13 | (state, actions) => {
14 | return (
15 |
16 | Click
17 | {state.count}
18 |
19 | );
20 | },
21 | document.body
22 | );
23 | ```
24 |
25 | ### Dev vs. Prod
26 |
27 | When deploying a Hyperapp with this HOA, it is advised you don't ship the devtools bundle with it:
28 |
29 | #### With Webpack Dynamic Import
30 |
31 | ```js
32 | import { h, app } from 'hyperapp';
33 |
34 | let main;
35 |
36 | if (process.env.NODE_ENV !== 'production') {
37 | import('hyperapp-redux-devtools')
38 | .then((devtools) => {
39 | main = devtools(app)(...);
40 | });
41 | } else {
42 | main = app(...);
43 | }
44 | ```
45 |
46 | #### With Conditional Require (Rollup/Gulp/etc..)
47 |
48 | ```js
49 | import { h, app } from 'hyperapp';
50 | const devtools = process.env.NODE_ENV !== 'production'
51 | ? require('hyperapp-redux-devtools')
52 | : null;
53 |
54 | let main;
55 |
56 | if (devtools) {
57 | main = devtools(app)(...);
58 | } else {
59 | main = app(...);
60 | }
61 | ```
62 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'hyperapp-redux-devtools';
2 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var { createStore } = require("redux");
2 | var { composeWithDevTools } = require("redux-devtools-extension");
3 |
4 | function reduxReducer(state = {}, action) {
5 | return Object.assign({}, state, action.payload);
6 | }
7 |
8 | function reducAction(name, data) {
9 | return {
10 | type: name,
11 | payload: data
12 | };
13 | }
14 |
15 | function copy(target, source) {
16 | var obj = {};
17 | for (var i in target) obj[i] = target[i];
18 | for (var i in source) obj[i] = source[i];
19 | return obj;
20 | }
21 |
22 | function set(path, value, source, target) {
23 | if (path.length) {
24 | target[path[0]] =
25 | 1 < path.length ? set(path.slice(1), value, source[path[0]], {}) : value;
26 | return copy(source, target);
27 | }
28 | return value;
29 | }
30 |
31 | function get(path, source) {
32 | for (var i = 0; i < path.length; i++) {
33 | source = source[path[i]];
34 | }
35 | return source;
36 | }
37 |
38 | module.exports = function devtools(app) {
39 | var composeEnhancers = composeWithDevTools({ action: reducAction });
40 | var store;
41 |
42 | return function(state, actions, view, container) {
43 | var appActions;
44 |
45 | function wire(path, actions) {
46 | for (var key in actions) {
47 | if (typeof actions[key] === "function") {
48 | (function(key, action) {
49 | actions[key] = function() {
50 | var reducer = action.apply(this, arguments);
51 | return function (slice) {
52 | var data = typeof reducer === "function"
53 | ? reducer(slice, get(path, appActions))
54 | : reducer;
55 | if (data && !data.then) {
56 | state = set(path, copy(slice, data), state, {});
57 | store.dispatch(reducAction(key, state));
58 | }
59 | return data;
60 | };
61 | };
62 | })(key, actions[key]);
63 | } else {
64 | wire(path.concat(key), (actions[key] = copy(actions[key])));
65 | }
66 | }
67 | }
68 | wire([], (actions = copy(actions)));
69 |
70 | actions.replaceState = function(actualState) {
71 | return function (state) {
72 | return actualState;
73 | }
74 | };
75 | store = createStore(reduxReducer, state, composeEnhancers());
76 | store.subscribe(function() {
77 | appActions.replaceState(store.getState());
78 | });
79 |
80 | appActions = app(state, actions, view, container);
81 | return appActions;
82 | };
83 | };
84 |
85 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hyperapp-redux-devtools",
3 | "version": "1.1.4",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "js-tokens": {
8 | "version": "3.0.2",
9 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
10 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
11 | },
12 | "lodash": {
13 | "version": "4.17.4",
14 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
15 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
16 | },
17 | "lodash-es": {
18 | "version": "4.17.4",
19 | "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz",
20 | "integrity": "sha1-3MHXVS4VCgZABzupyzHXDwMpUOc="
21 | },
22 | "loose-envify": {
23 | "version": "1.3.1",
24 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
25 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
26 | "requires": {
27 | "js-tokens": "3.0.2"
28 | }
29 | },
30 | "prettier": {
31 | "version": "1.9.2",
32 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.9.2.tgz",
33 | "integrity": "sha512-piXx9N2WT8hWb7PBbX1glAuJVIkEyUV9F5fMXFINpZ0x3otVOFKKeGmeuiclFJlP/UrgTckyV606VjH2rNK4bw==",
34 | "dev": true
35 | },
36 | "redux": {
37 | "version": "3.7.2",
38 | "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz",
39 | "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==",
40 | "requires": {
41 | "lodash": "4.17.4",
42 | "lodash-es": "4.17.4",
43 | "loose-envify": "1.3.1",
44 | "symbol-observable": "1.1.0"
45 | }
46 | },
47 | "redux-devtools-extension": {
48 | "version": "2.13.2",
49 | "resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.2.tgz",
50 | "integrity": "sha1-4Pmo6N/KfBe+kscSSVijuU6ykR0="
51 | },
52 | "symbol-observable": {
53 | "version": "1.1.0",
54 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.1.0.tgz",
55 | "integrity": "sha512-dQoid9tqQ+uotGhuTKEY11X4xhyYePVnqGSoSm3OGKh2E8LZ6RPULp1uXTctk33IeERlrRJYoVSBglsL05F5Uw=="
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hyperapp-redux-devtools",
3 | "version": "1.1.6",
4 | "description": "hyperapp HOA to utilize redux-devtools-extension for time travel debugging capabilities",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "format": "prettier --write \"./*.js\""
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/andyrj/hyperapp-redux-devtools.git"
13 | },
14 | "keywords": [
15 | "hyperapp",
16 | "redux",
17 | "devtools",
18 | "debug",
19 | "time-travel",
20 | "time",
21 | "travel",
22 | "debugging"
23 | ],
24 | "author": "Andy Johnson ",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/andyrj/hyperapp-redux-devtools/issues"
28 | },
29 | "homepage": "https://github.com/andyrj/hyperapp-redux-devtools#readme",
30 | "dependencies": {
31 | "redux": "^3.7.2",
32 | "redux-devtools-extension": "^2.13.2"
33 | },
34 | "devDependencies": {
35 | "prettier": "^1.9.2"
36 | },
37 | "peerDependencies": {
38 | "hyperapp": "^1.0.1"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | js-tokens@^3.0.0:
6 | version "3.0.1"
7 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
8 |
9 | lodash-es@^4.2.1:
10 | version "4.17.4"
11 | resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7"
12 |
13 | lodash@^4.2.1:
14 | version "4.17.4"
15 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
16 |
17 | loose-envify@^1.1.0:
18 | version "1.3.1"
19 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
20 | dependencies:
21 | js-tokens "^3.0.0"
22 |
23 | prettier@^1.5.2:
24 | version "1.5.2"
25 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.5.2.tgz#7ea0751da27b93bfb6cecfcec509994f52d83bb3"
26 |
27 | redux-devtools-extension@^2.13.2:
28 | version "2.13.2"
29 | resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.2.tgz#e0f9a8e8dfca7c17be92c7124958a3b94eb2911d"
30 |
31 | redux@^3.7.1:
32 | version "3.7.1"
33 | resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.1.tgz#bfc535c757d3849562ead0af18ac52122cd7268e"
34 | dependencies:
35 | lodash "^4.2.1"
36 | lodash-es "^4.2.1"
37 | loose-envify "^1.1.0"
38 | symbol-observable "^1.0.3"
39 |
40 | symbol-observable@^1.0.3:
41 | version "1.0.4"
42 | resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
43 |
--------------------------------------------------------------------------------