react-redux-mvc
Advanced tools
Comparing version
{ | ||
"name": "react-redux-mvc", | ||
"version": "0.0.1", | ||
"version": "0.1.1", | ||
"description": "Implementation of MVC pattern based on React-Redux bunch", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "npm run test" | ||
"test": "npm run test", | ||
"build": "babel src --out-dir lib", | ||
"dev": "better-npm-run dev" | ||
}, | ||
"betterScripts": { | ||
"dev": { | ||
"command": "webpack --watch", | ||
"env": { | ||
"NODE_ENV": "dev" | ||
} | ||
} | ||
}, | ||
"repository": { | ||
@@ -24,5 +34,28 @@ "type": "git", | ||
"homepage": "https://github.com/welljs/react-redux-mvc#readme", | ||
"devDependencies": { | ||
"babel-cli": "^6.6.4", | ||
"babel-core": "6.6.4", | ||
"babel-loader": "^6.2.4", | ||
"babel-plugin-add-module-exports": "0.1.2", | ||
"babel-plugin-transform-class-properties": "6.6.0", | ||
"babel-plugin-transform-decorators-legacy": "1.3.4", | ||
"babel-plugin-transform-runtime": "6.6.0", | ||
"babel-preset-es2015": "6.9.0", | ||
"babel-preset-react": "^6.5.0", | ||
"babel-preset-es2015-loose": "^7.0.0", | ||
"babel-preset-stage-0": "6.5.0", | ||
"babel-preset-stage-1": "6.5.0", | ||
"babel-preset-stage-2": "6.5.0", | ||
"babel-preset-stage-3": "6.5.0", | ||
"babel-register": "6.7.2", | ||
"better-npm-run": "0.0.10", | ||
"webpack": "2.1.0-beta.6" | ||
}, | ||
"dependencies": { | ||
"easy-redux": "^0.2.1" | ||
"easy-redux": "^0.3.3", | ||
"hoist-non-react-statics": "^1.2.0", | ||
"react": "0.14.7", | ||
"react-redux": "4.4.0", | ||
"redux": "3.0.4" | ||
} | ||
} |
@@ -1,1 +0,101 @@ | ||
export default class Controller {} | ||
import {PropTypes} from 'react'; | ||
import _get from 'lodash/get'; | ||
//Базовый контроллер | ||
export default class Controller { | ||
storeKey = null; | ||
static propsTypes = {}; | ||
//список полей, которые надо получить из стора. | ||
// чтобы получить вложенные, надо указать их через точку: routing.location | ||
static connectedState = []; | ||
//действия которые надо обернуть dispatch-ем | ||
static actions = {}; | ||
constructor (Model, ...props) { | ||
this.Model = Model; | ||
this.checkSettings(); | ||
this.storeKey = this.constructor.storeKey; | ||
this.actions = this.constructor.actions; | ||
this.propTypes = this.constructor.propTypes; | ||
} | ||
/** | ||
* проверяет, чтобы все необходимое было установлено | ||
*/ | ||
checkSettings () { | ||
if (!this.constructor.storeKey) { | ||
throw new Error(`Store key in ${this.name} must be defined`); | ||
} | ||
if (!this.Model) { | ||
throw new Error(`Model proto in ${this.name} must be passed to BasicController defined`); | ||
} | ||
} | ||
/** | ||
* используется для коннекта к стору | ||
* @example ['currentContract', 'routing.location:location'] | ||
* @param {[String]} state - свойства стора которые надо приконенктить | ||
* @returns {*} | ||
*/ | ||
mappedProps(state) { | ||
return this.constructor.connectedState.reduce((result, prop) => { | ||
let key = prop; | ||
if (prop.includes(':')) { | ||
const parts = prop.split(':'); | ||
prop = parts[0]; | ||
key = parts[1]; | ||
} | ||
return (result[key] = _get(state, prop), result); | ||
}, {}); | ||
} | ||
/** | ||
* диспатчит действие | ||
* @param args | ||
*/ | ||
action (...args) { | ||
const [name, ...restArguments] = args; | ||
const action = this.actions[name]; | ||
if (typeof action !== 'function') { | ||
throw Error('Action must be a function'); | ||
} | ||
return this.dispatch(action.apply(undefined, restArguments)); | ||
} | ||
/** | ||
* запсускается при инициализации, для первоначальных загрузок. | ||
* ! Пока не выполнится, не происходит первый рендер | ||
*/ | ||
onInit = () => Promise.resolve(); | ||
/** | ||
* Возвращает connected state. Может быть вложенным. | ||
* @example getState('routing'); getState('routing.location') | ||
* @param {String} prop | ||
* @returns {undefined} | ||
*/ | ||
getState (prop) { | ||
return typeof prop === 'string' ? _get(this.getGlobalState(), prop) : undefined; | ||
}; | ||
/** | ||
* возвращает ожидющие ключи | ||
* @param key | ||
*/ | ||
getWaiting (key) { | ||
return new this.Model(this.getState()).getWaiting(); | ||
} | ||
/** | ||
* возвращает ошибки | ||
* @returns {*} | ||
*/ | ||
getFailed () { | ||
return this.model.update(this.getState()).getFailed(); | ||
} | ||
} | ||
Controller.prototype.name = 'BasicController'; | ||
//withController должен передать сюда реальный диспатчер | ||
Controller.prototype.dispatch = function () {}; | ||
Controller.prototype.getGlobalState = function () {}; |
@@ -0,2 +1,9 @@ | ||
import {applyReducer} from 'easy-redux'; | ||
export {default as Controller} from './controller'; | ||
export {default as Model} from './model'; | ||
import Model from './model'; | ||
import ReactReduxMvc from './ReactReduxMvc'; | ||
import { withController } from './withController'; | ||
export {Model, withController, ReactReduxMvc}; | ||
//--------------- create action |
105
src/model.js
@@ -1,3 +0,104 @@ | ||
export default class Model { | ||
import _get from 'lodash/get'; | ||
import _set from 'lodash/set'; | ||
import _isPlainObject from 'lodash/isPlainObject'; | ||
import cloneDeep from 'lodash/cloneDeep'; | ||
import {merge} from './helpers'; | ||
}; | ||
function prepare (obj) { | ||
return obj; | ||
} | ||
class Model { | ||
state = { | ||
data: {}, | ||
waiting: {}, | ||
failed: {} | ||
}; | ||
setWaiting (prop) { | ||
this.set('waiting.' + prop, true); | ||
return this; | ||
} | ||
resetWaiting (prop) { | ||
this.set('waiting.' + prop, false); | ||
return this; | ||
} | ||
setFailed (prop) { | ||
this.set('failed.' + prop, true); | ||
return this; | ||
} | ||
resetFailed (prop) { | ||
this.set('failed.' + prop, false); | ||
return this; | ||
} | ||
isWaiting (key) { | ||
return this.state.waiting[key]; | ||
} | ||
isFailed (key) { | ||
return this.state.failed[key]; | ||
} | ||
getWaiting () { | ||
return this.state.waiting; | ||
} | ||
getFailed () { | ||
return this.state.failed; | ||
} | ||
/** | ||
* устанавливает значение prop в value | ||
* @param {String|Object} prop | ||
* @param value | ||
*/ | ||
set (prop, value) { | ||
if (!prop) { | ||
throw Error('Property must be set'); | ||
} | ||
//устанавливает значения для целого объекта | ||
if (_isPlainObject(prop)) { | ||
Object.entries(prop).forEach(([key, value]) => { | ||
if (value) { | ||
this.state[key] = value; | ||
} | ||
}); | ||
} | ||
else if (typeof prop === 'string' && value !== undefined) { | ||
//позволяет устанавливать значения для вложенных ключей. Нармер set('user.name','Ivan') | ||
_set(this.state, prop, value); | ||
} | ||
return this; | ||
} | ||
constructor (props) { | ||
if (props) { | ||
this.state = prepare(props); | ||
} | ||
} | ||
update(data) { | ||
this.state = prepare(data); | ||
return this; | ||
} | ||
getState (prop) { | ||
return prop ? _get(this.state, prop) : this.state; | ||
} | ||
updateState (updates) { | ||
this.state = cloneDeep(merge(this.state, updates)); | ||
return this; | ||
} | ||
static newState (oldState, updates) { | ||
return cloneDeep(merge(oldState, updates)); | ||
} | ||
} | ||
export default Model; |
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Trivial Package
Supply chain riskPackages less than 10 lines of code are easily copied into your own project and may not warrant the additional supply chain risk of an external dependency.
Found 1 instance in 1 package
48026
2231.36%18
125%511
10120%5
400%17
Infinity%3
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
Updated