ppx
Version:
ppx flux redux react
308 lines (248 loc) • 8.36 kB
JavaScript
;
exports.__esModule = true;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
require('promise-polyfill');
var _applymiddleware = require('./applymiddleware');
var _applymiddleware2 = _interopRequireDefault(_applymiddleware);
var _util = require('./util');
var _util2 = _interopRequireDefault(_util);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
//插件用于数据save与返回promise
var plugin = function plugin(next, action) {
var ret,
state,
_this6 = this;
return Promise.resolve().then(function () {
return next(action);
}).then(function (_resp) {
ret = _resp;
state = _this6.state;
if (!(ret === undefined)) {
//更新 state 值
_this6.state = _extends(state, ret);
// 修改值
// triggerSubscribe(action, ret);
return ret;
}
});
};
var Store = function () {
function Store() {
_classCallCheck(this, Store);
this._store = {};
this._fn = [];
this.middle = new _applymiddleware2.default();
this.use(plugin);
}
/**
* 获取model对象的namespace
* @param model
*/
Store.prototype.getRealModel = function getRealModel(Model) {
// 类对象
var model = Model;
if (typeof Model === 'function') {
model = new Model();
}
// 获取
var _model = model,
namespace = _model.namespace,
constructor = _model.constructor;
if (constructor && constructor.name) {
namespace = constructor.name;
}
return {
namespace: namespace,
model: model
};
};
/**
* model 支持
* @param Model
* @param force 强制新建model
* @returns {*}
*/
Store.prototype.model = function model(Model) {
var _this = this;
var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
// 支持多个model的情况
if (Model instanceof Array) {
return Model.map(function (oneModel) {
return _this.model(oneModel, force);
});
}
if (!Model) {
throw new Error(Model + ' is undefined');
}
// 类对象
var model = Model;
if (typeof Model === 'function') {
model = new Model();
}
// 获取 这个在压缩时有坑
var _model2 = model,
namespace = _model2.namespace;
//let { namespace, constructor } = model;
//if (constructor && constructor.name) {
// namespace = constructor.name;
//}
if (!namespace) {
throw new Error('It is not a model: ' + model);
}
if (!force && this._store[namespace]) {
// model已存在
return namespace;
}
// save namespace;
model.namespace = namespace;
// 不鼓励在model中使用dispatch 但是想来会有复杂需求使用到
model.dispatch = this._addDispatch(namespace);
// save
this._store[namespace] = model;
// model 触发事件调用 不鼓励使用
if (typeof model.bootstrap === 'function') {
_util2.default.defer(model.bootstrap.bind(model));
}
return namespace;
};
/**
* 获取namespace
* @returns {Iterator.<number>|Iterator.<K>|Iterator.<T>|*}
*/
Store.prototype.getNameSpace = function getNameSpace() {
return this._store.keys();
};
Store.prototype.unmodel = function unmodel(Model) {
var _this2 = this;
if (Model instanceof Array) {
Model.map(function (oneModel) {
_this2.unmodel(oneModel);
});
return this;
}
// 类对象
var model = Model;
if (typeof Model === 'function') {
model = new Model();
}
// 获取 这个在压缩时有坑
var _model3 = model,
namespace = _model3.namespace;
if (this._store[namespace]) {
delete this._store[namespace];
}
return this;
};
/**
* 用于 model内部支持dispatch 方法
* @param namespace
* @returns {function(*=, ...[*])}
* @private
*/
Store.prototype._addDispatch = function _addDispatch(namespace) {
var _this3 = this;
return function (action) {
for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
params[_key - 1] = arguments[_key];
}
if (typeof action === 'string') {
var type = namespace + '/' + action;
action = { type: type, params: params };
} else {
var _action = action,
_type = _action.type;
if (_type) {
action.type = namespace + '/' + _type;
}
}
return _this3.dispatch.apply(_this3, [action].concat(params));
};
};
/**
* 订阅
* @param fn
* @returns {function()}
*/
Store.prototype.subscribe = function subscribe(fn) {
var _this4 = this;
if (typeof fn !== 'function') {
throw new Error('first argument of subscription should be a function');
}
this._fn.push(fn);
/**
* 取消订阅
*/
return function () {
var index = _this4._fn.indexOf(fn);
_this4._fn.splice(index, 1);
};
};
/**
*
* @param action
* @param data
* @returns {*}
*/
Store.prototype.dispatch = function dispatch(action) {
var _this5 = this;
for (var _len2 = arguments.length, data = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
data[_key2 - 1] = arguments[_key2];
}
//兼容字符串
if (typeof action === 'string') {
action = { type: action, data: data };
}
var _action2 = action,
type = _action2.type;
var _type$split = type.split('/'),
namespace = _type$split[0],
reduce = _type$split[1];
if (!namespace || !reduce) {
throw Error('action ' + type + ' should like "namespace/reduce"');
}
//
var model = this._store[namespace];
if (!model) {
throw Error('can\'t find the model "' + namespace + '"');
}
//中间件应用
return this.middle.go(function (action) {
var type = action.type;
var _type$split2 = type.split('/'),
namespace = _type$split2[0],
reduce = _type$split2[1];
var fn = this[reduce];
if (!fn) {
throw Error('can\'t find function "' + reduce + '" in model "' + namespace + '"');
}
return this[reduce].call(this, model.state, action);
}, {
model: model,
action: action
}).then(function (ret) {
// 触发 subscribe
var retState = {};
var _action$type$split = action.type.split('/'),
namespace = _action$type$split[0],
reduce = _action$type$split[1];
retState[namespace] = ret;
_this5._fn.map(function (fn) {
fn(action, retState);
});
return ret;
});
};
/**
* 加载中间件
* @param middleware
*/
Store.prototype.use = function use() {
var _middle;
(_middle = this.middle).use.apply(_middle, arguments);
return this;
};
return Store;
}();
exports.default = new Store();
module.exports = exports['default'];