strudel-redux
Advanced tools
Comparing version 1.0.0 to 2.0.0
@@ -18,3 +18,2 @@ const path = require('path'); | ||
exclude: 'node_modules/**', | ||
presets: ['es2015-rollup'], | ||
}), | ||
@@ -21,0 +20,0 @@ resolve({ |
168
index.js
@@ -7,84 +7,134 @@ (function (global, factory) { | ||
var bindedMethods = ['init', 'beforeDestroy', '_react', 'onStateChange']; | ||
function _defineProperty(obj, key, value) { | ||
if (key in obj) { | ||
Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true | ||
}); | ||
} else { | ||
obj[key] = value; | ||
} | ||
var reactiveMixin = { | ||
init: function init() { | ||
var _this = this; | ||
return obj; | ||
} | ||
this._react(); | ||
function _objectSpread(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
var ownKeys = Object.keys(source); | ||
this.unsubscribe = window.__reduxStore.subscribe(function () { | ||
_this.onStateChange(); | ||
_this._react(); | ||
if (typeof Object.getOwnPropertySymbols === 'function') { | ||
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(source, sym).enumerable; | ||
})); | ||
} | ||
ownKeys.forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
}, | ||
beforeDestroy: function beforeDestroy() { | ||
this.unsubscribe(); | ||
}, | ||
onStateChange: function onStateChange() { | ||
return true; | ||
}, | ||
} | ||
return target; | ||
} | ||
// React Virtual-DOM | ||
_react: function _react() { | ||
if (!this.render) return; | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); | ||
} | ||
this.render(this); | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
function _iterableToArrayLimit(arr, i) { | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
try { | ||
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { | ||
_arr.push(_s.value); | ||
if (i && _arr.length === i) break; | ||
} | ||
} catch (err) { | ||
_d = true; | ||
_e = err; | ||
} finally { | ||
try { | ||
if (!_n && _i["return"] != null) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
}; | ||
var patch = function patch(target, funcName) { | ||
var base = target[funcName]; | ||
var mixinFunc = reactiveMixin[funcName]; | ||
return _arr; | ||
} | ||
var f = !base ? mixinFunc : function () { | ||
base.apply(this, arguments); | ||
mixinFunc.apply(this, arguments); | ||
}; | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance"); | ||
} | ||
target[funcName] = f; | ||
}; | ||
var subscribedStateChanged = function subscribedStateChanged(observedState, stateMemory) { | ||
return Object.entries(observedState).some(function (_ref) { | ||
var _ref2 = _slicedToArray(_ref, 2), | ||
key = _ref2[0], | ||
value = _ref2[1]; | ||
var mixin = function mixin(target) { | ||
bindedMethods.forEach(function (funcName) { | ||
patch(target, funcName); | ||
return stateMemory[key] !== value; | ||
}); | ||
}; | ||
/* eslint-disable no-param-reassign, func-names */ | ||
var getState = function getState() { | ||
return window.__reduxStore.getState(); | ||
}; | ||
var dispatch = function dispatch(e) { | ||
return window.__reduxStore.dispatch(e); | ||
}; | ||
var replaceReducer = function replaceReducer(e) { | ||
return window.__reduxStore.replaceReducer(e); | ||
}; | ||
var Subscribe = function Subscribe(store, _ref3) { | ||
var observed = _ref3.observed, | ||
_ref3$statics = _ref3.statics, | ||
statics = _ref3$statics === void 0 ? function () {} : _ref3$statics; | ||
return function (target) { | ||
var stateMemory = observed(store.getState()); | ||
Object.defineProperty(target.prototype, 'dispatch', { | ||
value: function value(action) { | ||
return store.dispatch(action); | ||
}, | ||
enumerable: true | ||
}); | ||
var orgInit = target.prototype.init; | ||
var orgTeardown = target.prototype.$teardown; | ||
var unsubscribe; | ||
var initStore = function initStore(store) { | ||
window.__reduxStore = store; | ||
return window.__reduxStore; | ||
}; | ||
target.prototype.init = function () { | ||
var _this = this; | ||
var subscribe = function subscribe(arg) { | ||
var componentClass = arg; | ||
var target = componentClass.prototype; | ||
orgInit.call(this); | ||
var unsubscribe = store.subscribe(function () { | ||
var storeState = store.getState(); | ||
var observedState = observed(storeState); | ||
var stateChanged = subscribedStateChanged(observedState, stateMemory); | ||
if (!target || !target.isStrudelClass) { | ||
throw new Error('Please pass a valid component to "Subscribe"'); | ||
} | ||
if (stateChanged) { | ||
var staticState = statics(storeState); | ||
mixin(target); | ||
return target; | ||
}; | ||
_this.onStateChange(_objectSpread({}, observedState, staticState)); | ||
exports.Subscribe = subscribe; | ||
exports.initStore = initStore; | ||
exports.getState = getState; | ||
exports.dispatch = dispatch; | ||
exports.replaceReducer = replaceReducer; | ||
stateMemory = observedState; | ||
} | ||
}); | ||
}; | ||
target.prototype.$teardown = function () { | ||
unsubscribe(); | ||
orgTeardown.call(this); | ||
}; | ||
return target; | ||
}; | ||
}; // eslint-enable no-param-reassign, func-names | ||
exports.subscribedStateChanged = subscribedStateChanged; | ||
exports.Subscribe = Subscribe; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
}))); |
{ | ||
"name": "strudel-redux", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"description": "Redux bindings for Strudel", | ||
"main": "index.js", | ||
"scripts": { | ||
"build": "node build-rollup.js" | ||
"build": "node build-rollup.js", | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"lint": "eslint src/*.js" | ||
}, | ||
@@ -14,3 +17,3 @@ "repository": { | ||
"keywords": [], | ||
"author": "Mateusz Kulinski, Mateusz Luczak <mateusz.luczak@outlook.com>", | ||
"author": "Mikolaj Kozakiewicz, Mateusz Kulinski, Mateusz Luczak <mateusz.luczak@outlook.com>", | ||
"license": "MIT", | ||
@@ -23,6 +26,11 @@ "bugs": { | ||
"devDependencies": { | ||
"babel-core": "^6.26.0", | ||
"babel-preset-es2015-rollup": "^3.0.0", | ||
"@babel/core": "^7.3.4", | ||
"@babel/preset-env": "^7.3.1", | ||
"eslint": "^5.14.1", | ||
"eslint-config-airbnb-base": "^13.1.0", | ||
"eslint-plugin-import": "^2.16.0", | ||
"jest": "^24.1.0", | ||
"redux": "^4.0.1", | ||
"rollup": "^0.52.1", | ||
"rollup-plugin-babel": "^3.0.2", | ||
"rollup-plugin-babel": "^4.3.2", | ||
"rollup-plugin-commonjs": "^8.2.6", | ||
@@ -29,0 +37,0 @@ "rollup-plugin-filesize": "^1.5.0", |
@@ -21,26 +21,22 @@ # Strudel-redux | ||
store.js | ||
``` | ||
import { initStore } from 'strudel-redux'; | ||
import { createStore } from 'redux'; | ||
import reducer from '../reducers/index'; | ||
const redux = createStore(reducer); | ||
initStore(redux); | ||
``` | ||
``` | ||
import { Component, Evt } from 'strudel'; | ||
import { Subscribe, getState, dispatch } from 'strudel-redux'; | ||
import { addTodo } from '../../actions/'; | ||
import { Subscribe, dispatch } from 'strudel-redux'; | ||
import { toggleStockStatus } from '../../actions/'; | ||
@Subscribe | ||
@Subscribe({ | ||
observed: state => ({ | ||
price: state.productDetails.price, | ||
}), | ||
statics: state => ({ | ||
stockStatus: state.productDetails.stockStatus, | ||
}) | ||
}) | ||
@Component('.example') | ||
class Example { | ||
init() { | ||
dispatch(addTodo('New task')); | ||
this.dispatch(toggleStockStatus()); | ||
} | ||
onStateChange() { | ||
onStateChange({ price, stockStatus }) { | ||
// put down your logic here | ||
@@ -51,44 +47,8 @@ } | ||
### Example 2 (Redux + React) | ||
You have a possibility to add `React` with `Virtual DOM` easily as well. | ||
`render()` is called immediately after update the state | ||
``` | ||
import React from 'react'; | ||
import reactDom from 'react-dom'; | ||
import { Component, Evt } from 'strudel'; | ||
import { Subscribe, getState } from 'strudel-redux'; | ||
import { addTodo } from '../../actions/'; | ||
import { Status } from './status'; | ||
@Subscribe | ||
@Component('.example-2') | ||
class Example2 { | ||
render() { | ||
reactDom.render( | ||
( | ||
<div> | ||
<input type="text"/> | ||
<div className="container"> | ||
<Status/> | ||
{getState().todos.map((item) => <p key={item.id}>{item.id}. {item.title}</p>)} | ||
</div> | ||
</div> | ||
), | ||
this.$element.first(), | ||
); | ||
} | ||
} | ||
``` | ||
### API | ||
* `@Subscribe` - required decorator to bind strudel-redux to the component | ||
* `initStore(store)` - initializing redux store | ||
* `onStateChange()` - this method is called after update the state | ||
* `getState()` - returns the current state tree of your application | ||
* `dispatch(action)` - dispatches action | ||
* `replaceReducer(nextReducer)` - replaces the reducer currently used by the store to calculate the state | ||
* `render()` - this method is called after update the state | ||
* `@Subscribe(store, callbackFunction)` - required decorator to bind strudel-redux to component | ||
* `onStateChange(properties)` - added method called on change of properties declared as observed | ||
* `callbackFunction: { observed: () => {}, statics: () => {}` - functions that will return mapped state properties | ||
* `observed` method is called on store change, and will trigger `onStateChange` if returned value differs from previous | ||
* `statics` method is called whenever `observed` function will detect change, and provides additional props that does not trigger onStateChange call |
@@ -1,67 +0,45 @@ | ||
const bindedMethods = ['init', 'beforeDestroy', 'onStateChange', '_react',]; | ||
export const subscribedStateChanged = (observedState, stateMemory) => Object | ||
.entries(observedState) | ||
.some(([key, value]) => stateMemory[key] !== value); | ||
const reactiveMixin = { | ||
init() { | ||
this._react(); | ||
/* eslint-disable no-param-reassign, func-names */ | ||
export const Subscribe = (store, { observed, statics = () => {} }) => function (target) { | ||
let stateMemory = observed(store.getState()); | ||
this.unsubscribe = window.__reduxStore.subscribe(() => { | ||
this.onStateChange(); | ||
this._react(); | ||
}); | ||
}, | ||
Object.defineProperty(target.prototype, 'dispatch', { | ||
value(action) { | ||
return store.dispatch(action); | ||
}, | ||
enumerable: true, | ||
}); | ||
beforeDestroy() { | ||
this.unsubscribe(); | ||
}, | ||
const orgInit = target.prototype.init; | ||
const orgTeardown = target.prototype.$teardown; | ||
let unsubscribe; | ||
onStateChange() { | ||
return true; | ||
}, | ||
target.prototype.init = function () { | ||
orgInit.call(this); | ||
_react() { | ||
if (!this.render) return; | ||
unsubscribe = store.subscribe(() => { | ||
const storeState = store.getState(); | ||
const observedState = observed(storeState); | ||
const stateChanged = subscribedStateChanged(observedState, stateMemory); | ||
this.render(this); | ||
} | ||
}; | ||
if (stateChanged) { | ||
const staticState = statics(storeState); | ||
this.onStateChange({ ...observedState, ...staticState }); | ||
const patch = (target, funcName) => { | ||
const base = target[funcName]; | ||
const mixinFunc = reactiveMixin[funcName]; | ||
stateMemory = observedState; | ||
} | ||
}); | ||
}; | ||
const f = !base ? mixinFunc : function () { | ||
base.apply(this, arguments); | ||
mixinFunc.apply(this, arguments); | ||
} | ||
target.prototype.$teardown = function () { | ||
unsubscribe(); | ||
orgTeardown.call(this); | ||
}; | ||
target[funcName] = f; | ||
} | ||
const mixin = (target) => { | ||
bindedMethods.forEach((funcName) => { | ||
patch(target, funcName); | ||
}); | ||
} | ||
const getState = () => window.__reduxStore.getState(); | ||
const dispatch = (e) => window.__reduxStore.dispatch(e); | ||
const replaceReducer = (e) => window.__reduxStore.replaceReducer(e); | ||
const initStore = (store) => { | ||
window.__reduxStore = store; | ||
return window.__reduxStore; | ||
}; | ||
const subscribe = (arg) => { | ||
const componentClass = arg; | ||
const target = componentClass.prototype; | ||
if (!target || !target.isStrudelClass) { | ||
throw new Error('Please pass a valid component to "Subscribe"'); | ||
} | ||
mixin(target); | ||
return target; | ||
}; | ||
export { subscribe as Subscribe, initStore, getState, dispatch, replaceReducer }; | ||
// eslint-enable no-param-reassign, func-names |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
162556
13
272
12
53
2