canner
Version:
Build CMS in few lines of code for different data sources
363 lines (286 loc) • 13.3 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = withCache;
exports.isRoutesEndAtMe = isRoutesEndAtMe;
exports.genSubscriberId = genSubscriberId;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var React = _interopRequireWildcard(require("react"));
var _action = require("../action");
var _route = require("./route");
var _lodash = require("lodash");
var _mapValues = _interopRequireDefault(require("lodash/mapValues"));
var _onDeployManager = require("../onDeployManager");
function withCache(Com, options) {
var _ref = options || {},
_ref$mutate = _ref.mutate,
mutate = _ref$mutate === void 0 ? _action.mutate : _ref$mutate,
_ref$ActionManager = _ref.ActionManager,
ActionManager = _ref$ActionManager === void 0 ? _action.ActionManager : _ref$ActionManager;
return (
/*#__PURE__*/
function (_React$Component) {
(0, _inherits2.default)(ComWithCache, _React$Component);
function ComWithCache(props) {
var _this;
(0, _classCallCheck2.default)(this, ComWithCache);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ComWithCache).call(this, props));
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "actionManager", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "onDeployManager", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "subscribers", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "subscribers", {});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "subscription", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "addSubscriber", function (key, id, callback) {
var subscriber = {
id: id,
callback: callback
};
if (_this.subscribers[key]) {
_this.subscribers[key].push(subscriber);
} else {
_this.subscribers[key] = [subscriber];
}
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "unsubscribe", function (key, subscriberId) {
_this.subscribers[key] = _this.subscribers[key].filter(function (subscriber) {
return subscriber.id !== subscriberId;
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "publish", function (key, id) {
// $FlowFixMe
if (!_this.actionManager) {
return;
}
var data = _this.state[key];
if (!data) {
return;
}
var actions = _this.actionManager.getActions(key, id);
var mutatedData = actions.reduce(function (result, action) {
return mutate(result, action);
}, data);
(_this.subscribers[key] || []).forEach(function (subscribe) {
subscribe.callback(mutatedData);
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "fetch", function (key) {
// the data will be mutated by cached actions
var fetch = _this.props.fetch;
if (!_this.actionManager) {
return fetch(key);
}
var actions = _this.actionManager.getActions(key);
return fetch(key).then(function (data) {
_this.setState((0, _defineProperty2.default)({}, key, data));
_this._subscribe(key);
return actions.reduce(function (result, action) {
return mutate(result, action);
}, data);
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "_subscribe", function (key) {
var subscribe = _this.props.subscribe;
_this.subscription = subscribe(key, function (data) {
_this.setState((0, _defineProperty2.default)({}, key, data), function () {
return _this.publish(key);
});
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "_unsubscribe", function () {
if (_this.subscription) {
_this.subscription.unsubscribe();
}
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "request", function (action) {
// use action manager cache the actions
// update state.actions
var request = _this.props.request;
if (!_this.actionManager) {
// $FlowFixMe
return request(action);
}
var key, id;
if ((0, _lodash.isArray)(action)) {
// $FlowFixMe
action.forEach(function (ac) {
// $FlowFixMe
_this.actionManager.addAction(ac);
});
key = action[0].payload.key;
id = action[0].payload.id;
} else {
// $FlowFixMe
_this.actionManager.addAction(action); // $FlowFixMe
key = action.payload.key; // $FlowFixMe
id = action.payload.id;
}
_this.updateDataChanged();
_this.publish(key, id);
return Promise.resolve();
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "onDeploy", function (key, callback) {
var onDeploy = _this.props.onDeploy;
if (!_this.onDeployManager) {
return onDeploy(key, callback);
}
return _this.onDeployManager.registerCallback(key, callback);
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "removeOnDeploy", function (key, callbackId) {
var removeOnDeploy = _this.props.removeOnDeploy;
if (!_this.onDeployManager) {
return removeOnDeploy(key, callbackId);
}
return _this.onDeployManager.unregisterCallback(key, callbackId);
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "_executeOnDeployCallback", function (key, value) {
return _this.onDeployManager.execute({
key: key,
value: value
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "deploy", function (key, id) {
// request cached actions
var _this$props = _this.props,
request = _this$props.request,
deploy = _this$props.deploy,
pattern = _this$props.pattern;
if (!_this.actionManager) {
return deploy(key, id);
}
var originData = _this.state[key];
var actions = _this.actionManager.getActions(key, id);
var mutatedData = actions.reduce(function (result, action) {
return mutate(result, action);
}, originData);
var _this$_executeOnDeplo = _this._executeOnDeployCallback(key, mutatedData[key]),
error = _this$_executeOnDeplo.error;
if (error) {
return Promise.reject();
} // actions = actions.map(action => {
// const {key, value} = action.payload;
// hasError = hasError || error;
// action.payload.value = data;
// return action;
// });
// $FlowFixMe
_this.actionManager.removeActions(key, id);
_this.updateDataChanged(); // $FlowFixMe
request(actions); // if this cache is on the first layer,
// it should call the deploy after request
if (pattern.split('.').length === 1) {
return deploy(key, id);
}
return Promise.resolve();
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "reset", function (key, id) {
// remove sepicfic cached actions in actionManager
var reset = _this.props.reset;
if (!_this.actionManager) {
return reset(key, id);
}
_this.actionManager.removeActions(key, id);
_this.updateDataChanged();
_this.publish(key, id);
return Promise.resolve();
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "subscribe", function (key, callback) {
var subscribe = _this.props.subscribe;
if (!_this.actionManager) {
return subscribe(key, callback);
}
var id = genSubscriberId();
_this.addSubscriber(key, id, callback);
return {
unsubscribe: function unsubscribe() {
_this.unsubscribe(key, id);
}
};
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "updateDataChanged", function () {
if (!_this.actionManager) {
return;
}
var actions = _this.actionManager.getActions();
var dataChanged = (0, _lodash.groupBy)(actions, function (action) {
return action.payload.key;
});
dataChanged = (0, _mapValues.default)(dataChanged, function (value) {
if (value[0].type === 'UPDATE_OBJECT') {
return true;
}
return value.map(function (v) {
return v.payload.id;
});
});
_this.setState({
dataChanged: dataChanged
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "updateQuery", function (paths, args) {
var updateQuery = _this.props.updateQuery;
return updateQuery(paths, args).then(function (reWatch) {
if (reWatch) {
_this._unsubscribe();
_this.fetch(paths[0]);
}
return reWatch;
});
});
var _this$props2 = _this.props,
routes = _this$props2.routes,
cacheActions = _this$props2.cacheActions,
_pattern = _this$props2.pattern,
path = _this$props2.path;
if (routes.length > 1 && isRoutesEndAtMe({
routes: routes,
pattern: _pattern,
path: path
}) || cacheActions) {
_this.actionManager = new ActionManager();
_this.onDeployManager = new _onDeployManager.OnDeployManager();
}
_this.state = {
dataChanged: {}
};
return _this;
}
(0, _createClass2.default)(ComWithCache, [{
key: "render",
value: function render() {
return React.createElement(Com, (0, _extends2.default)({}, this.props, {
fetch: this.fetch,
request: this.request,
deploy: this.deploy,
reset: this.reset,
subscribe: this.subscribe,
updateQuery: this.updateQuery,
onDeploy: this.onDeploy,
removeOnDeploy: this.removeOnDeploy,
dataChanged: this.state.dataChanged
}));
}
}]);
return ComWithCache;
}(React.Component)
);
}
function isRoutesEndAtMe(_ref2) {
var routes = _ref2.routes,
path = _ref2.path,
pattern = _ref2.pattern;
var paths = (0, _route.genPaths)(path, pattern);
return paths.length === routes.length && (0, _route.isCompleteContain)(paths, routes);
}
function genSubscriberId() {
return Math.random().toString(36).substr(2, 7);
}