Comparing version 0.2.20 to 0.3.0
@@ -1,2 +0,2 @@ | ||
function n(t,r){return t||r?t!==r&&(!!(!t&&r||t&&!r)||(typeof t!=typeof r||(Array.isArray(t)?function(n,t,r){if(!Array.isArray(t))return!0;if(n.length!==t.length)return!0;if(0===n.length&&0===t.length)return!1;return 0!==n.filter(function(n,e){return r(n,t[e])}).length}(t,r,n):"object"==typeof t?function(n,t,r){var e=Object.keys(n),u=Object.keys(t);if(e.length!==u.length)return!0;return 0!==e.filter(function(e,o){return e===u[o]&&r(n[e],t[e])}).length}(t,r,n):!(!t&&!r)||typeof t==typeof r))):typeof t==typeof r}var t=function(t,r){void 0===t&&(t={}),void 0===r&&(r={});var e=t,u=[],o=function(n){return n?n(e):e},f=function(n){return n?n(c):c},i=function(t){void 0!==t&&n(e,t)&&(e=t,u.forEach(function(n){return n(e,c)}))},c=function(n,t,r,e){return function(n,t){var r={};for(var e in n)r[e]=t(n[e]);return r}(n,function(n){return function(){for(var u=[],o=arguments.length;o--;)u[o]=arguments[o];return e(n(t(),r).apply(void 0,u))}})}(r,o,function(n){var t=[],r=arguments.length-1;for(;r-- >0;)t[r]=arguments[r+1];i(c[n].apply(c,t))},i);return{getState:o,getActions:f,actions:c,connect:function(t,r){var i=t?t(e):e;return function(e){var c=function(u,c){var a=o(t);n(i,a)&&(i=a,e(Object.assign({},a,f(r))))};return u.push(c),{dispose:function(){return function(n){u=u.filter(function(t){return t!==n})}(c)}}}}}};export{t as stateManager}; | ||
function t(n,r){return n||r?n!==r&&(!!(!n&&r||n&&!r)||(typeof n!=typeof r||(Array.isArray(n)?function(t,n,r){return!Array.isArray(n)||t.length!==n.length||(0!==t.length||0!==n.length)&&0!==t.filter(function(t,e){return r(t,n[e])}).length}(n,r,t):"object"==typeof n?function(t,n,r){var e=Object.keys(t),o=Object.keys(n);return e.length!==o.length||0!==e.filter(function(e,i){return e!==o[i]||r(t[e],n[e])}).length}(n,r,t):!(!n&&!r)||typeof n==typeof r))):typeof n==typeof r}var n=function(t,n,r,e,o){return function(t,n){var r={};for(var e in t)r[e]=n(t[e]);return r}(t,function(t){return function(){for(var i=[],u=0;u<arguments.length;u++)i[u]=arguments[u];var f=n(),c=t(f,r).apply(void 0,i);e(c),o({name:t.name,args:i,currentState:f,newState:c,lol:c})}})};function r(r,e,o){void 0===r&&(r={}),void 0===e&&(e={}),void 0===o&&(o=[]);var i=[],u=r,f=n(e,a,function(t){for(var n=[],r=1;r<arguments.length;r++)n[r-1]=arguments[r];"function"==typeof f[t]&&f[t].apply(f,n)},c,function(t){o.forEach(function(n){return n(t)})});function c(n){void 0!==n&&t(u,n)&&(u=n,i.forEach(function(t){return t(u,f)}))}function a(t){return t?t(u):u}function l(t){return t?t(f):f}this.__INITIAL_ACTIONS__=e,this.actions=f,this.getState=a,this.setState=c,this.getActions=l,this.connect=function(n,r,e){void 0===n&&(n=null),void 0===r&&(r=null),void 0===e&&(e=!1);var o=a(n);return function(u){var f=function(i,f){var c=a(n);(e||t(o,c))&&(o=c,u(c,l(r)))};return u(o,l(r)),i.push(f),{dispose:function(){!function(t){i=i.filter(function(n){return n!==t})}(f)}}}}}export{r as Store}; | ||
//# sourceMappingURL=mehdux.esm.js.map |
@@ -1,2 +0,2 @@ | ||
function n(t,r){return t||r?t!==r&&(!!(!t&&r||t&&!r)||(typeof t!=typeof r||(Array.isArray(t)?function(n,t,r){if(!Array.isArray(t))return!0;if(n.length!==t.length)return!0;if(0===n.length&&0===t.length)return!1;return 0!==n.filter(function(n,e){return r(n,t[e])}).length}(t,r,n):"object"==typeof t?function(n,t,r){var e=Object.keys(n),u=Object.keys(t);if(e.length!==u.length)return!0;return 0!==e.filter(function(e,o){return e===u[o]&&r(n[e],t[e])}).length}(t,r,n):!(!t&&!r)||typeof t==typeof r))):typeof t==typeof r}exports.stateManager=function(t,r){void 0===t&&(t={}),void 0===r&&(r={});var e=t,u=[],o=function(n){return n?n(e):e},f=function(n){return n?n(c):c},i=function(t){void 0!==t&&n(e,t)&&(e=t,u.forEach(function(n){return n(e,c)}))},c=function(n,t,r,e){return function(n,t){var r={};for(var e in n)r[e]=t(n[e]);return r}(n,function(n){return function(){for(var u=[],o=arguments.length;o--;)u[o]=arguments[o];return e(n(t(),r).apply(void 0,u))}})}(r,o,function(n){for(var t=[],r=arguments.length-1;r-- >0;)t[r]=arguments[r+1];i(c[n].apply(c,t))},i);return{getState:o,getActions:f,actions:c,connect:function(t,r){var i=t?t(e):e;return function(e){var c=function(u,c){var a=o(t);n(i,a)&&(i=a,e(Object.assign({},a,f(r))))};return u.push(c),{dispose:function(){return function(n){u=u.filter(function(t){return t!==n})}(c)}}}}}}; | ||
function t(n,r){return n||r?n!==r&&(!!(!n&&r||n&&!r)||(typeof n!=typeof r||(Array.isArray(n)?function(t,n,r){return!Array.isArray(n)||t.length!==n.length||(0!==t.length||0!==n.length)&&0!==t.filter(function(t,e){return r(t,n[e])}).length}(n,r,t):"object"==typeof n?function(t,n,r){var e=Object.keys(t),o=Object.keys(n);return e.length!==o.length||0!==e.filter(function(e,i){return e!==o[i]||r(t[e],n[e])}).length}(n,r,t):!(!n&&!r)||typeof n==typeof r))):typeof n==typeof r}var n=function(t,n,r,e,o){return function(t,n){var r={};for(var e in t)r[e]=n(t[e]);return r}(t,function(t){return function(){for(var i=[],u=0;u<arguments.length;u++)i[u]=arguments[u];var f=n(),c=t(f,r).apply(void 0,i);e(c),o({name:t.name,args:i,currentState:f,newState:c,lol:c})}})};exports.Store=function(r,e,o){void 0===r&&(r={}),void 0===e&&(e={}),void 0===o&&(o=[]);var i=[],u=r,f=n(e,a,function(t){for(var n=[],r=1;r<arguments.length;r++)n[r-1]=arguments[r];"function"==typeof f[t]&&f[t].apply(f,n)},c,function(t){o.forEach(function(n){return n(t)})});function c(n){void 0!==n&&t(u,n)&&(u=n,i.forEach(function(t){return t(u,f)}))}function a(t){return t?t(u):u}function l(t){return t?t(f):f}this.__INITIAL_ACTIONS__=e,this.actions=f,this.getState=a,this.setState=c,this.getActions=l,this.connect=function(n,r,e){void 0===n&&(n=null),void 0===r&&(r=null),void 0===e&&(e=!1);var o=a(n);return function(u){var f=function(i,f){var c=a(n);(e||t(o,c))&&(o=c,u(c,l(r)))};return u(o,l(r)),i.push(f),{dispose:function(){!function(t){i=i.filter(function(n){return n!==t})}(f)}}}}}; | ||
//# sourceMappingURL=mehdux.js.map |
@@ -1,2 +0,2 @@ | ||
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(n.mehdux={})}(this,function(n){function t(n,e){return n||e?n!==e&&(!!(!n&&e||n&&!e)||(typeof n!=typeof e||(Array.isArray(n)?function(n,t,e){if(!Array.isArray(t))return!0;if(n.length!==t.length)return!0;if(0===n.length&&0===t.length)return!1;return 0!==n.filter(function(n,r){return e(n,t[r])}).length}(n,e,t):"object"==typeof n?function(n,t,e){var r=Object.keys(n),o=Object.keys(t);if(r.length!==o.length)return!0;return 0!==r.filter(function(r,f){return r===o[f]&&e(n[r],t[r])}).length}(n,e,t):!(!n&&!e)||typeof n==typeof e))):typeof n==typeof e}n.stateManager=function(n,e){void 0===n&&(n={}),void 0===e&&(e={});var r=n,o=[],f=function(n){return n?n(r):r},u=function(n){return n?n(c):c},i=function(n){void 0!==n&&t(r,n)&&(r=n,o.forEach(function(n){return n(r,c)}))},c=function(n,t,e,r){return function(n,t){var e={};for(var r in n)e[r]=t(n[r]);return e}(n,function(n){return function(){for(var o=[],f=arguments.length;f--;)o[f]=arguments[f];return r(n(t(),e).apply(void 0,o))}})}(e,f,function(n){for(var t=[],e=arguments.length-1;e-- >0;)t[e]=arguments[e+1];i(c[n].apply(c,t))},i);return{getState:f,getActions:u,actions:c,connect:function(n,e){var i=n?n(r):r;return function(r){var c=function(o,c){var a=f(n);t(i,a)&&(i=a,r(Object.assign({},a,u(e))))};return o.push(c),{dispose:function(){return function(n){o=o.filter(function(t){return t!==n})}(c)}}}}}}}); | ||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(t.mehdux={})}(this,function(t){function n(t,e){return t||e?t!==e&&(!!(!t&&e||t&&!e)||(typeof t!=typeof e||(Array.isArray(t)?function(t,n,e){return!Array.isArray(n)||t.length!==n.length||(0!==t.length||0!==n.length)&&0!==t.filter(function(t,r){return e(t,n[r])}).length}(t,e,n):"object"==typeof t?function(t,n,e){var r=Object.keys(t),o=Object.keys(n);return r.length!==o.length||0!==r.filter(function(r,i){return r!==o[i]||e(t[r],n[r])}).length}(t,e,n):!(!t&&!e)||typeof t==typeof e))):typeof t==typeof e}var e=function(t,n,e,r,o){return function(t,n){var e={};for(var r in t)e[r]=n(t[r]);return e}(t,function(t){return function(){for(var i=[],f=0;f<arguments.length;f++)i[f]=arguments[f];var u=n(),c=t(u,e).apply(void 0,i);r(c),o({name:t.name,args:i,currentState:u,newState:c,lol:c})}})};t.Store=function(t,r,o){void 0===t&&(t={}),void 0===r&&(r={}),void 0===o&&(o=[]);var i=[],f=t,u=e(r,a,function(t){for(var n=[],e=1;e<arguments.length;e++)n[e-1]=arguments[e];"function"==typeof u[t]&&u[t].apply(u,n)},c,function(t){o.forEach(function(n){return n(t)})});function c(t){void 0!==t&&n(f,t)&&(f=t,i.forEach(function(t){return t(f,u)}))}function a(t){return t?t(f):f}function l(t){return t?t(u):u}this.__INITIAL_ACTIONS__=r,this.actions=u,this.getState=a,this.setState=c,this.getActions=l,this.connect=function(t,e,r){void 0===t&&(t=null),void 0===e&&(e=null),void 0===r&&(r=!1);var o=a(t);return function(f){var u=function(i,u){var c=a(t);(r||n(o,c))&&(o=c,f(c,l(e)))};return f(o,l(e)),i.push(u),{dispose:function(){!function(t){i=i.filter(function(n){return n!==t})}(u)}}}}}}); | ||
//# sourceMappingURL=mehdux.umd.js.map |
@@ -7,4 +7,4 @@ { | ||
"license": "MIT", | ||
"version": "0.2.20", | ||
"source": "src/main.js", | ||
"version": "0.3.0", | ||
"source": "src/main.ts", | ||
"main": "dist/mehdux.js", | ||
@@ -16,3 +16,4 @@ "module": "dist/mehdux.esm.js", | ||
"preact": "^8.2.7", | ||
"react": "^16.2.0" | ||
"react": "^16.2.0", | ||
"tslint": "^5.9.1" | ||
}, | ||
@@ -26,6 +27,9 @@ "peerDependencies": { | ||
"bundle:main": "microbundle", | ||
"bundle:preact": "microbundle src/preact.js -o ./preact.js -f cjs", | ||
"bundle:react": "microbundle src/react.js -o ./react.js -f cjs", | ||
"dev:main": "microbundle watch", | ||
"bundle:combine": "microbundle src/combine.ts -o ./combine.js -f cjs", | ||
"bundle:picodom": "microbundle src/bindings/picodom.ts -o ./picodom.js -f cjs", | ||
"bundle:preact": "microbundle src/bindings/preact.js -o ./preact.js -f cjs", | ||
"bundle:react": "microbundle src/bindings/react.js -o ./react.js -f cjs", | ||
"prepare": "npm run build", | ||
"build": "npm run bundle:main && npm run bundle:preact && npm run bundle:react", | ||
"build": "npm run bundle:main && npm run bundle:combine && npm run bundle:picodom && npm run bundle:preact && npm run bundle:react", | ||
"test": "echo 'should add some tests.. :)'" | ||
@@ -39,4 +43,6 @@ }, | ||
"preact.js", | ||
"preact.js.map" | ||
"preact.js.map", | ||
"combine.js", | ||
"combine.js.map" | ||
] | ||
} |
@@ -1,2 +0,2 @@ | ||
var t=require("preact");function n(t,e){return t||e?t!==e&&(!!(!t&&e||t&&!e)||(typeof t!=typeof e||(Array.isArray(t)?function(t,n,e){if(!Array.isArray(n))return!0;if(t.length!==n.length)return!0;if(0===t.length&&0===n.length)return!1;return 0!==t.filter(function(t,r){return e(t,n[r])}).length}(t,e,n):"object"==typeof t?function(t,n,e){var r=Object.keys(t),o=Object.keys(n);if(r.length!==o.length)return!0;return 0!==r.filter(function(r,i){return r===o[i]&&e(t[r],n[r])}).length}(t,e,n):!(!t&&!e)||typeof t==typeof e))):typeof t==typeof e}exports.stateManager=function(t,e){void 0===t&&(t={}),void 0===e&&(e={});var r=t,o=[],i=function(t){return t?t(r):r},c=function(t){return t?t(f):f},u=function(t){void 0!==t&&n(r,t)&&(r=t,o.forEach(function(t){return t(r,f)}))},f=function(t,n,e,r){return function(t,n){var e={};for(var r in t)e[r]=n(t[r]);return e}(t,function(t){return function(){for(var o=[],i=arguments.length;i--;)o[i]=arguments[i];return r(t(n(),e).apply(void 0,o))}})}(e,i,function(t){for(var n=[],e=arguments.length-1;e-- >0;)n[e]=arguments[e+1];u(f[t].apply(f,n))},u);return{getState:i,getActions:c,actions:f,connect:function(t,e){var u=t?t(r):r;return function(r){var f=function(o,f){var a=i(t);n(u,a)&&(u=a,r(Object.assign({},a,c(e))))};return o.push(f),{dispose:function(){return function(t){o=o.filter(function(n){return n!==t})}(f)}}}}}},exports.connect=function(n,e,r){return function(o){return function(i){function c(){i.call(this),this.connection=null,this.handleUpdate=this.handleUpdate.bind(this),this.state=Object.assign({},n.getState(e),n.getActions(r))}return i&&(c.__proto__=i),(c.prototype=Object.create(i&&i.prototype)).constructor=c,c.prototype.componentDidMount=function(){this.connection=n.connect(e,r)(this.handleUpdate)},c.prototype.handleUpdate=function(t){this.setState(Object.assign({},t))},c.prototype.componentWillUnmount=function(){this.connection&&this.connection.dispose()},c.prototype.render=function(){return t.h(o,this.state)},c}(t.Component)}}; | ||
var t=require("preact");function o(t){this.getChildContext=function(){return{store:t.store}}}o.prototype.render=function(t){return t.children[0]};exports.Provider=o,exports.connect=function(o){void 0===o&&(o={});var n=o.store,e=o.mapStateToProps,r=o.mapActionsToProps,i=!n||"object"!=typeof n;return function(o){return function(s){function c(t,o){s.call(this,t,o),this.connection=null,this.handleUpdate=this.handleUpdate.bind(this),this.store=i?o.store:n,this.state={actions:this.store.getActions(r),state:this.store.getState(e)}}return s&&(c.__proto__=s),(c.prototype=Object.create(s&&s.prototype)).constructor=c,c.prototype.componentDidMount=function(){this.connection=this.store.connect(e,r)(this.handleUpdate)},c.prototype.handleUpdate=function(t,o){this.setState(Object.assign({},{state:t,actions:o}))},c.prototype.componentWillUnmount=function(){this.connection&&this.connection.dispose()},c.prototype.render=function(){return t.h(o,this.state)},c}(t.Component)}}; | ||
//# sourceMappingURL=preact.js.map |
@@ -1,2 +0,2 @@ | ||
var t=require("react");function n(t,e){return t||e?t!==e&&(!!(!t&&e||t&&!e)||(typeof t!=typeof e||(Array.isArray(t)?function(t,n,e){if(!Array.isArray(n))return!0;if(t.length!==n.length)return!0;if(0===t.length&&0===n.length)return!1;return 0!==t.filter(function(t,r){return e(t,n[r])}).length}(t,e,n):"object"==typeof t?function(t,n,e){var r=Object.keys(t),o=Object.keys(n);if(r.length!==o.length)return!0;return 0!==r.filter(function(r,i){return r===o[i]&&e(t[r],n[r])}).length}(t,e,n):!(!t&&!e)||typeof t==typeof e))):typeof t==typeof e}exports.stateManager=function(t,e){void 0===t&&(t={}),void 0===e&&(e={});var r=t,o=[],i=function(t){return t?t(r):r},c=function(t){return t?t(f):f},u=function(t){void 0!==t&&n(r,t)&&(r=t,o.forEach(function(t){return t(r,f)}))},f=function(t,n,e,r){return function(t,n){var e={};for(var r in t)e[r]=n(t[r]);return e}(t,function(t){return function(){for(var o=[],i=arguments.length;i--;)o[i]=arguments[i];return r(t(n(),e).apply(void 0,o))}})}(e,i,function(t){for(var n=[],e=arguments.length-1;e-- >0;)n[e]=arguments[e+1];u(f[t].apply(f,n))},u);return{getState:i,getActions:c,actions:f,connect:function(t,e){var u=t?t(r):r;return function(r){var f=function(o,f){var a=i(t);n(u,a)&&(u=a,r(Object.assign({},a,c(e))))};return o.push(f),{dispose:function(){return function(t){o=o.filter(function(n){return n!==t})}(f)}}}}}},exports.connect=function(n,e,r){return function(o){return function(i){function c(){i.call(this),this.connection=null,this.handleUpdate=this.handleUpdate.bind(this),this.state=Object.assign({},n.getState(e),n.getActions(r))}return i&&(c.__proto__=i),(c.prototype=Object.create(i&&i.prototype)).constructor=c,c.prototype.componentDidMount=function(){this.connection=n.connect(e,r)(this.handleUpdate)},c.prototype.handleUpdate=function(t){this.setState(Object.assign({},t))},c.prototype.componentWillUnmount=function(){this.connection&&this.connection.dispose()},c.prototype.render=function(){return t.createElement(o,this.state)},c}(t.Component)}}; | ||
var t=require("react"),o={store:function(){}},e=function(o){function e(){o.apply(this,arguments)}return o&&(e.__proto__=o),(e.prototype=Object.create(o&&o.prototype)).constructor=e,e.prototype.getChildContext=function(){return{store:this.props.store}},e.prototype.render=function(){return t.Children.only(this.props.children)},e}(t.Component);e.childContextTypes=o;var n=function(o){void 0===o&&(o={});var e=o.store,n=o.mapStateToProps,r=o.mapActionsToProps,i=!e||"object"!=typeof e;return function(o){var s=function(s){function c(t,o){s.call(this,t,o),this.store=i?o.store:e,this.connection=null,this.handleUpdate=this.handleUpdate.bind(this),this.state={actions:this.store.getActions(r),state:this.store.getState(n)}}return s&&(c.__proto__=s),(c.prototype=Object.create(s&&s.prototype)).constructor=c,c.prototype.componentDidMount=function(){this.connection=this.store.connect(n,r)(this.handleUpdate)},c.prototype.handleUpdate=function(t,o){this.setState(Object.assign({},{state:t,actions:o}))},c.prototype.componentWillUnmount=function(){this.connection&&this.connection.dispose()},c.prototype.render=function(){return t.createElement(o,this.state)},c}(t.Component);return s.contextTypes={store:function(){}},s}};n.contextTypes=o,exports.Provider=e,exports.connect=n; | ||
//# sourceMappingURL=react.js.map |
257
README.md
@@ -10,5 +10,6 @@ <div align="center"> | ||
* Easy to grasp API | ||
* Tiny: 577 bytes gzipped | ||
* Small React and Preact integrations (~750 bytes gzipped) | ||
* Tiny, small, slim, light, slender, fit – bytes matter | ||
* Small React, Preact and Picodom integrations (~750 bytes gzipped) | ||
* WordArt logo | ||
* Emojis in README.md (Todo) | ||
@@ -31,7 +32,7 @@ ## Motivation | ||
const initialState = { | ||
someValue: 'My value' | ||
value: 0 | ||
} | ||
const actions = { | ||
// ...actions | ||
// ... | ||
} | ||
@@ -43,37 +44,36 @@ | ||
#### Creating and using actions | ||
The actions you create should be a function that takes the state and returns a function returning the new state. | ||
```Javascript | ||
const add = state => value => ({ | ||
...state, | ||
value: state.value + value | ||
}) | ||
// or without arrow functions | ||
const subtract = function(state) { | ||
return function(value) { | ||
return { | ||
...state, | ||
value: state.value - value | ||
} | ||
} | ||
const actions = { | ||
inc: state => value => ({ | ||
...state, | ||
value: state.value + value | ||
}), | ||
dec: state => value => ({ | ||
...state, | ||
value: state.value - value | ||
}) | ||
} | ||
``` | ||
const actions = { increment, decrement } | ||
``` | ||
`Mehdux` transforms the actions you pass the store. | ||
Using the actions simply looks like this: | ||
Using the actions simply looks like this: | ||
```Javascript | ||
store.actions.add(10) | ||
store.actions.subtract(20) | ||
store.actions.inc(1) | ||
``` | ||
### Subscribe to state changes | ||
To subscribe to state changes you use the `connect`-function on the `store` instance you have already created. | ||
On a state change the subscriber gets invoked with the state tree as the first argument and the actions as the second argument. | ||
```Javascript | ||
store.connect()(console.log) | ||
store.actions.setValue('A cooler value') | ||
// logs { someValue: 'A cooler Value' } | ||
store.actions.inc(10) | ||
// logs { value: 10 }, { inc: f(), dec: f() } | ||
``` | ||
@@ -84,74 +84,150 @@ | ||
```Javascript | ||
const mapStateToProps = ({ something, somethingElse }) => ({ | ||
something, | ||
somethingElse | ||
}) | ||
const mapState = state => ({ | ||
interesting: state.something | ||
store.connect(mapStateToProps)(console.log) | ||
``` | ||
Similiarly you can pass in a `mapActionsToProps`-function as the second argument to the `connect`-function. | ||
```Javascript | ||
const mapActionsToProps = actions => ({ | ||
inc: actions.inc, | ||
increaseByTen: () => actions.inc(10), | ||
}) | ||
store.connect(mapState)(console.log) | ||
store.connect(null, mapActionsToProps)(console.log) | ||
``` | ||
store.actions.setSomething('This is interesting') | ||
// logs { interesting: 'This is interesting' } | ||
Passing `null` as either the first or second argument passes the state or the actions object in its entirety. | ||
## Usage with other frameworks | ||
`Mehdux` has built-in integrations with `react`, `preact` and `picodom`. | ||
### React and Preact | ||
To connect a component to the store you need to wrap the component in the `connect`-function from `mehdux`. | ||
```Javascript | ||
import { connect } from 'mehdux/react' // or 'mehdux/preact' | ||
``` | ||
### Usage with other frameworks | ||
`Mehdux` has built-in integrations with `react` and `preact`. | ||
There are two ways to pass the store to the `connect`-function in `mehdux`: | ||
Simply import the `connect`-function, pass it the store you have already created and pass your component to the returning function. | ||
1. By wrapping your app in a higher order `provider`-function like, similiar to how `react-redux` does it. | ||
2. Passing the store as the first argument to the `connect`-function. | ||
#### 1. By using a Provider | ||
```Javascript | ||
import { connect } from 'mehdux/react' // or 'mehdux/preact | ||
import React from 'react' | ||
import ReactDOM from 'react-dom' | ||
import { Provider, connect } from 'mehdux/react' // or 'mehdux/preact' | ||
import { store } from './store' // or wherever you keep your store instance | ||
const SomeComponent = ({ myValue }) => <h1>{myValue}</h1> | ||
export default connect(store)(SomeComponent) | ||
// Some component has access the whole state and all the actions in the store | ||
const Button = ({ state, actions }) => { | ||
return <button onClick={actions.inc}>{state.value}</button> | ||
} | ||
const ConnectedButton = connect()(Button) | ||
ReactDOM.render( | ||
<Provider store={store}> | ||
<ConnectedButton /> | ||
</Provider>, | ||
document.getElementById('root') | ||
) | ||
``` | ||
#### Listening to just certain parts of the state tree | ||
Often you only care about a few parts of your state tree in a component. By only passing in those properties you will improve the performance of your application. | ||
#### 2. By passing in the store instance | ||
To achieve this you want to create a `mapActionsToProps`-function. This function gets passed the entire state and should return an object containing the properties you care about. Pass this as the second argument to the `connect`-function. | ||
```Javascript | ||
import { connect } from 'mehdux/react' // or 'mehdux/preact' | ||
import { store } from './store' // or wherever you keep your store instance | ||
Doing this is optional and you can pass in nothing or `null`, but it is strongly encouraged. | ||
const Button = ({ state, actions }) => { | ||
return <button onClick={actions.inc}>{state.value}</button> | ||
} | ||
const ConnectedButton = connect(store)(Button) | ||
``` | ||
**Note:** _When doing this, `mapStateToProps` and `mapActionsToProps` are passed as the second and third arguments, not the first and the second like usual_ | ||
### Picodom | ||
`Mehdux` exports a tiny, small, slender, light, fit `connect`-function for easy stateful components in Picodom. | ||
#### Regular usagage | ||
A typical Picodom and Mehdux app might look like this: | ||
```Javascript | ||
import { connect } from 'mehdux/react' // or 'mehdux/preact | ||
// @jsx h | ||
import { h, patch } from 'picodom' | ||
import { store } from './store' // or wherever you keep your store instance | ||
const SomeComponent = ({ myValue }) => <h1>{myValue}</h1> | ||
let node = null | ||
function mapStateToProps(state) { | ||
return { | ||
myValue: state.something.i.care.about | ||
} | ||
const render = viewFn => (state, actions) => { | ||
patch(node, (node = viewFn(state, actions)), root); | ||
}; | ||
const view = (state, actions) => { | ||
return <button onClick={actions.inc}>{state.value}</button> | ||
} | ||
export default connect(store, mapStateToProps)(SomeComponent) | ||
// Some component has access to myValue and all the actions in the store | ||
store.connect()(render(view)) | ||
``` | ||
#### Passing in certain actions | ||
Similarly you can use a `mapActionsToProps`-function to only pass the actions you care about to your component. | ||
Out of the box stateful components connected to a store is not straight-forward with `Picodom`. | ||
To make connected components in `Picodom` a breeze `Mehdux` comes with a small `connect`-function. | ||
This function gets passed all the actions in the store and should return an object containing the actions you care about. Pass this as the third argument to the `connect`-function. | ||
Here is how to do it: | ||
```Javascript | ||
import { connect } from 'mehdux/react' // or 'mehdux/preact' | ||
// @jsx h | ||
import { h, patch } from 'picodom' | ||
import { connect } from 'mehdux/picodom' | ||
import { store } from './store' // or wherever you keep your store instance | ||
const SomeComponent = ({ myValue }) => <h1>{myValue}</h1> | ||
let node = null | ||
function mapActionsToProps(actions) { | ||
return { | ||
setName: actions.setName, | ||
setUpperCaseName: (value) => actions.setName(value.toUpperCase()) | ||
} | ||
// Note the storeInstance that gets passed to 'render' from 'store.connect' | ||
const render = viewFn => (state, actions, storeInstance) => { | ||
patch(node, (node = viewFn(state, actions, storeInstance)), root); | ||
}; | ||
const Button = ({ actions, state }) => { | ||
return <button onClick={actions.inc}>{state.value}</button> | ||
} | ||
export default connect(store, null, mapActionsToProps)(SomeComponent) | ||
const ConnectedButton = connect()(Button) | ||
/* | ||
Some component has access to the whole state tree | ||
and the setName and setUpperCaseName functions | ||
*/ | ||
const view = (state, actions, storeInstance) => { | ||
return ( | ||
<div> | ||
<ConnectedButton store={storeInstance} /> | ||
</div> | ||
) | ||
} | ||
// Note the third argument to connect, which forces the store to emit even on equal states. | ||
// This is to enable the stateful components inside `view` to get rerun, | ||
// eventhough the parent state does not change. | ||
store.connect(null, null, true)(render(view)) | ||
``` | ||
#### Dispatching async thunk-like actions | ||
**Note:** _This implementation will likely be rewritten to be more similiar to the `React`/`Preact`-implementations_ | ||
## Advanced usage | ||
### Dispatching multiple or async actions | ||
`Mehdux` has support for dispatching actions within actions. | ||
@@ -162,15 +238,19 @@ All actions you create also gets passed a `dispatch`-function. | ||
```Javascript | ||
const actions = { | ||
setName: state => { | ||
return value => ({ | ||
...state, | ||
someValue: value | ||
}) | ||
addUser: state => user => ({ | ||
...state, | ||
user: [...state.users, user] | ||
}), | ||
addManyUsers: state => () => { | ||
dispatch('addUser', 'Kari') | ||
dispatch('addUser', 'Ola') | ||
}, | ||
addUserIn2s: (state, disaptch) => user => { | ||
setTimeout(() => dispatch('addUser', user), 2000) | ||
}, | ||
fetchAndSetName: async (state, dispatch) => { | ||
const res = await fetch('https://myapi.com/v0') | ||
const data = await res.json() | ||
dispatch('setName', data.name) | ||
const user = await res.json() | ||
dispatch('addUser', user) | ||
} | ||
@@ -180,4 +260,35 @@ } | ||
### Combining multiple store instances (WIP) | ||
Bigger apps often have complex state trees. In `redux` you would handle this by combining reducers. With `Mehdux` you can combine stores with the `combineStores`-function like so: | ||
```Javascript | ||
import { combineStores } from 'mehdux/combine' | ||
const store = combineStores({ users: userStore, posts: postStore }) | ||
``` | ||
### Middleware/Enhancers | ||
`Store` takes a third argument along side `initialState` and `actions`. This is an array of middleware-functions. Each middleware gets called on actions being called on the store. | ||
They recieve the action `name`, `arguments`, `currentState` and `nextState`. | ||
Logging and analytics are examples of middleware usages. | ||
```Javascript | ||
import { Store } from 'mehdux' | ||
import { Logger, Analytics } from './middlewares' // or wherever you keep your middlewares | ||
const store = new Store({}, {}, [Logger, Analytics]) | ||
export { store } | ||
``` | ||
## Todos | ||
* Sort out type-definitions when using `microbundle` | ||
## License | ||
[MIT](LICENSE). |
import { h, Component } from 'preact' | ||
export const connect = (store, mapStateToProps, mapDispatchToProps) => { | ||
return function(WrappedComponent) { | ||
export function Provider(props) { | ||
this.getChildContext = () => ({ store: props.store }) | ||
} | ||
Provider.prototype.render = props => props.children[0] | ||
export const connect = ({ store, mapStateToProps, mapActionsToProps } = {}) => { | ||
const useContext = !store || typeof store !== 'object' | ||
return function(WrappedComponent) { | ||
return class extends Component { | ||
constructor() { | ||
super() | ||
constructor(props, context) { | ||
super(props, context) | ||
this.connection = null | ||
this.handleUpdate = this.handleUpdate.bind(this) | ||
this.state = | ||
Object.assign( | ||
{}, | ||
store.getState(mapStateToProps), | ||
store.getActions(mapDispatchToProps) | ||
) | ||
this.store = useContext ? context.store : store | ||
this.state = { | ||
actions: this.store.getActions(mapActionsToProps), | ||
state: this.store.getState(mapStateToProps) | ||
} | ||
} | ||
componentDidMount() { | ||
this.connection = store.connect(mapStateToProps, mapDispatchToProps)( | ||
this.handleUpdate | ||
) | ||
this.connection = this.store.connect(mapStateToProps, mapActionsToProps)(this.handleUpdate) | ||
} | ||
handleUpdate(state) { | ||
this.setState(Object.assign({}, state)) | ||
handleUpdate(state, actions) { | ||
this.setState(Object.assign({}, { state, actions })) | ||
} | ||
componentWillUnmount() { | ||
@@ -29,0 +30,0 @@ this.connection && this.connection.dispose() |
@@ -1,28 +0,36 @@ | ||
import { createElement, Component } from 'react' | ||
import { createElement, Component, Children } from 'react' | ||
export const connect = (store, mapStateToProps, mapDispatchToProps) => { | ||
return function(WrappedComponent) { | ||
return class extends Component { | ||
constructor() { | ||
super() | ||
const contextType = { store: () => {} } | ||
class Provider extends Component { | ||
getChildContext() { | ||
return { store: this.props.store } | ||
} | ||
render() { | ||
return Children.only(this.props.children) | ||
} | ||
} | ||
Provider.childContextTypes = contextType | ||
const connect = ({ store, mapStateToProps, mapActionsToProps } = {}) => { | ||
const useContext = !store || typeof store !== 'object' | ||
return function(WrappedComponent) { | ||
class Wrapper extends Component { | ||
constructor(props, context) { | ||
super(props, context) | ||
this.store = useContext ? context.store : store | ||
this.connection = null | ||
this.handleUpdate = this.handleUpdate.bind(this) | ||
this.state = | ||
Object.assign( | ||
{}, | ||
store.getState(mapStateToProps), | ||
store.getActions(mapDispatchToProps) | ||
) | ||
this.state = { | ||
actions: this.store.getActions(mapActionsToProps), | ||
state: this.store.getState(mapStateToProps) | ||
} | ||
} | ||
componentDidMount() { | ||
this.connection = store.connect(mapStateToProps, mapDispatchToProps)( | ||
this.handleUpdate | ||
) | ||
this.connection = this.store.connect(mapStateToProps, mapActionsToProps)(this.handleUpdate) | ||
} | ||
handleUpdate(state) { | ||
this.setState(Object.assign({}, state)) | ||
handleUpdate(state, actions) { | ||
this.setState(Object.assign({}, { state, actions })) | ||
} | ||
componentWillUnmount() { | ||
@@ -35,3 +43,11 @@ this.connection && this.connection.dispose() | ||
} | ||
Wrapper.contextTypes = { | ||
store: () => {} | ||
} | ||
return Wrapper | ||
} | ||
} | ||
connect.contextTypes = contextType | ||
export { Provider, connect } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
70546
23
426
289
4
1