redux-resource
Version:
Resource management for Redux.
156 lines (124 loc) • 6.68 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; };
var _upsertResources = require('../utils/upsert-resources');
var _upsertResources2 = _interopRequireDefault(_upsertResources);
var _upsertMeta = require('../utils/upsert-meta');
var _upsertMeta2 = _interopRequireDefault(_upsertMeta);
var _initialResourceMetaState = require('../utils/initial-resource-meta-state');
var _initialResourceMetaState2 = _interopRequireDefault(_initialResourceMetaState);
var _requestStatuses = require('../utils/request-statuses');
var _requestStatuses2 = _interopRequireDefault(_requestStatuses);
var _warning = require('../utils/warning');
var _warning2 = _interopRequireDefault(_warning);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = (resourceType, { initialResourceMeta }) => (state, action) => {
if (action.type !== 'UPDATE_RESOURCES' && action.type !== 'DELETE_RESOURCES') {
return state;
}
const naiveNewResources = action.resources && action.resources[resourceType];
const naiveNewMeta = action.meta && action.meta[resourceType];
const additionalLists = action.lists && action.lists[resourceType];
if (action.type === 'UPDATE_RESOURCES') {
if (process.env.NODE_ENV !== 'production') {
if (typeof action.mergeListIds !== 'undefined') {
(0, _warning2.default)(`You passed the "mergeListId" properties to an UPDATE_RESOURCES action. ` + `This property only works for the request action types (such as ` + `READ_RESOURCES_PENDING). When using UPDATE_RESOURCES, you must modify the ` + `list yourself, and then pass the new list to the action creator. ` + `For more information, refer to the documentation on this action at: ` + `https://redux-resource.js.org/docs/resources/modifying-resources.html`, 'MERGE_LIST_ID_UPDATE_RESOURCES');
}
if (!action.resources && !action.meta && !action.lists) {
(0, _warning2.default)(`You dispatched an UPDATE_RESOURCES action without any resources, meta, ` + `or lists, so the store will not be updated. ` + `For more information, refer to the documentation on this action at: ` + `https://redux-resource.js.org/docs/resources/modifying-resources.html`, 'UPDATE_RESOURCES_NO_OP');
}
}
let mergeResources;
if (typeof action.mergeResources === 'boolean') {
mergeResources = action.mergeResources;
} else if (typeof action.mergeResources === 'object') {
mergeResources = action.mergeResources[resourceType];
} else {
mergeResources = true;
}
let mergeMeta;
if (typeof action.mergeMeta === 'boolean') {
mergeMeta = action.mergeMeta;
} else if (typeof action.mergeMeta === 'object') {
mergeMeta = action.mergeMeta[resourceType];
} else {
mergeMeta = true;
}
const newResources = (0, _upsertResources2.default)(state.resources, naiveNewResources, mergeResources);
let newMeta;
if (!Array.isArray(naiveNewMeta)) {
newMeta = (0, _upsertMeta2.default)(state.meta, naiveNewMeta, mergeMeta);
} else {
newMeta = state.meta;
}
let newLists = state.lists;
if (additionalLists) {
newLists = _extends({}, state.lists, additionalLists);
}
return _extends({}, state, action.resourceSliceAttributes, {
resources: newResources,
meta: newMeta,
lists: newLists
});
} else {
if (process.env.NODE_ENV !== 'production') {
if (!action.resources && !action.meta) {
(0, _warning2.default)(`You dispatched a DELETE_RESOURCES action without any resources ` + `or meta, so the store will not be updated. ` + `For more information, refer to the documentation on this action at: ` + `https://redux-resource.js.org/docs/resources/modifying-resources.html`, 'DELETE_RESOURCES_NO_OP');
}
}
let idList;
if (naiveNewResources && naiveNewResources.map) {
idList = naiveNewResources.map(r => {
if (typeof r === 'object') {
if (process.env.NODE_ENV !== 'production') {
if (!r.id && r.id !== 0 || typeof r.id !== 'string' && typeof r.id !== 'number') {
(0, _warning2.default)(`A resource without an ID was passed to an action with type ` + `${action.type}. Every resource must have an ID that is either ` + `a number of a string. You should check your action creators to ` + `make sure that an ID is always included in your resources. ` + `For more information, refer to the documentation on resource objects at: ` + `https://redux-resource.js.org/docs/resources/resource-objects.html`, 'NO_RESOURCE_ID');
}
}
return r.id;
} else {
if (process.env.NODE_ENV !== 'production') {
if (typeof r !== 'string' && typeof r !== 'number') {
(0, _warning2.default)(`A resource without an ID was passed to an action with type ` + `${action.type}. Every resource must have an ID that is either ` + `a number of a string. You should check your action creators to ` + `make sure that an ID is always included in your resources. ` + `For more information, refer to the documentation on resource objects at: ` + `https://redux-resource.js.org/docs/resources/resource-objects.html`, 'NO_RESOURCE_ID');
}
}
return r;
}
});
} else {
idList = Object.keys(naiveNewResources || {});
}
const hasIds = idList && idList.length;
if (!hasIds) {
return state;
}
let newMeta;
let newLists = {};
const meta = state.meta;
const lists = state.lists;
for (let resourceList in lists) {
const existingList = lists[resourceList];
newLists[resourceList] = existingList.filter(r => !idList.includes(r));
}
const nullMeta = idList.reduce((memo, id) => {
const newMeta = (naiveNewMeta || {})[id];
memo[id] = _extends({}, _initialResourceMetaState2.default, initialResourceMeta, newMeta, {
deleteStatus: _requestStatuses2.default.SUCCEEDED
});
return memo;
}, {});
newMeta = _extends({}, meta, nullMeta);
// Shallow clone the existing resource object, nulling any deleted resources
let newResources = Object.assign({}, state.resources);
if (hasIds) {
idList.forEach(id => {
delete newResources[id];
});
}
return _extends({}, state, {
meta: newMeta,
lists: newLists,
resources: newResources
});
}
};
;