UNPKG

@gjv/redux-slice-factory

Version:

Generic factory functions for common slice data structures

426 lines (370 loc) 14.9 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var toolkit = require('@reduxjs/toolkit'); var merge = _interopDefault(require('lodash.merge')); /** * @public */ var StatusEnum; (function (StatusEnum) { StatusEnum["Settled"] = "Settled"; StatusEnum["Requesting"] = "Requesting"; StatusEnum["Failed"] = "Failed"; })(StatusEnum || (StatusEnum = {})); var StatusEnum$1 = StatusEnum; function _extends() { _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; }; return _extends.apply(this, arguments); } var create = function create(args) { var _args$status, _args$error, _args$lastModified, _args$lastHydrated; if (args === void 0) { args = {}; } return { status: (_args$status = args.status) != null ? _args$status : StatusEnum$1.Settled, error: (_args$error = args.error) != null ? _args$error : null, lastModified: (_args$lastModified = args.lastModified) != null ? _args$lastModified : null, lastHydrated: (_args$lastHydrated = args.lastHydrated) != null ? _args$lastHydrated : null }; }; /** * @public */ var MetaState = { create: create }; var create$1 = function create(args) { var _args$ids, _args$entities; if (args === void 0) { args = {}; } var metaState = MetaState.create(args); return _extends({}, metaState, { ids: (_args$ids = args.ids) != null ? _args$ids : [], entities: (_args$entities = args.entities) != null ? _args$entities : {} }); }; /** * @public */ var EntityState = { create: create$1 }; /** * @internal */ var getISOString = function getISOString(dateTime) { if (dateTime === void 0) { dateTime = new Date(); } return dateTime.toISOString(); }; /** * @public */ function createEntitySlice(options) { var defaultCanRequestSelector = function defaultCanRequestSelector(sliceState) { return sliceState.status !== StatusEnum$1.Requesting && sliceState.error === null && sliceState.lastModified === null; }; var defaultShouldRequestSelector = function defaultShouldRequestSelector(sliceState, canRequest) { return canRequest && sliceState.lastHydrated === null; }; var name = options.name, selectId = options.selectId, sortComparer = options.sortComparer, selectSliceState = options.selectSliceState, _options$selectShould = options.selectShouldRequest, selectShouldRequest = _options$selectShould === void 0 ? defaultShouldRequestSelector : _options$selectShould, _options$selectCanReq = options.selectCanRequest, selectCanRequest = _options$selectCanReq === void 0 ? defaultCanRequestSelector : _options$selectCanReq, _options$initialState = options.initialState, initialState = _options$initialState === void 0 ? {} : _options$initialState, _options$createTimest = options.createTimestamp, createTimestamp = _options$createTimest === void 0 ? getISOString : _options$createTimest; // intentional, necessary with immer /* eslint-disable no-param-reassign */ var setEntityState = function setEntityState(state, entityState) { state.ids = entityState.ids; state.entities = entityState.entities; }; var _setError = function setError(state, error) { state.error = error === null ? null : error; }; var _setStatus = function setStatus(state, status) { state.status = status; }; var setLastModified = function setLastModified(state, lastModified) { state.lastModified = lastModified; }; var setLastHydrated = function setLastHydrated(state, lastHydrated) { state.lastHydrated = lastHydrated; }; /* eslint-enable no-param-reassign */ var modifyState = function modifyState(state, entityState) { setEntityState(state, entityState); // TODO: should not have a side effect: https://redux.js.org/style-guide/style-guide#reducers-must-not-have-side-effects setLastModified(state, createTimestamp()); }; var hydrateState = function hydrateState(state, entityState) { setEntityState(state, entityState); setLastModified(state, null); // TODO: should not have a side effect: https://redux.js.org/style-guide/style-guide#reducers-must-not-have-side-effects setLastHydrated(state, createTimestamp()); }; var entityAdapter = toolkit.createEntityAdapter({ selectId: selectId, sortComparer: sortComparer }); var initialEntityState = entityAdapter.getInitialState(initialState); var initialSliceState = EntityState.create(initialEntityState); /* eslint-disable no-param-reassign */ var slice = toolkit.createSlice({ name: name, initialState: initialSliceState, reducers: { addOne: function addOne(state, action) { var newEntityState = entityAdapter.addOne(state, action.payload); modifyState(state, newEntityState); }, addMany: function addMany(state, action) { var newEntityState = entityAdapter.addMany(state, action.payload); modifyState(state, newEntityState); }, hydrateOne: function hydrateOne(state, action) { var newEntityState = entityAdapter.upsertOne(state, action.payload); hydrateState(state, newEntityState); }, hydrateMany: function hydrateMany(state, action) { var newEntityState = entityAdapter.upsertMany(state, action.payload); hydrateState(state, newEntityState); }, hydrateAll: function hydrateAll(state, action) { var newEntityState = entityAdapter.setAll(state, action.payload); hydrateState(state, newEntityState); }, updateOne: function updateOne(state, action) { var newEntityState = entityAdapter.updateOne(state, action.payload); modifyState(state, newEntityState); }, updateMany: function updateMany(state, action) { var newEntityState = entityAdapter.updateMany(state, action.payload); modifyState(state, newEntityState); }, upsertOne: function upsertOne(state, action) { var newEntityState = entityAdapter.upsertOne(state, action.payload); modifyState(state, newEntityState); }, upsertMany: function upsertMany(state, action) { var newEntityState = entityAdapter.upsertMany(state, action.payload); modifyState(state, newEntityState); }, removeOne: function removeOne(state, action) { var newEntityState = entityAdapter.removeOne(state, action.payload); modifyState(state, newEntityState); }, removeMany: function removeMany(state, action) { var newEntityState = entityAdapter.removeMany(state, action.payload); modifyState(state, newEntityState); }, removeAll: function removeAll(state) { var newEntityState = entityAdapter.removeAll(state); modifyState(state, newEntityState); }, reset: function reset() { return initialSliceState; }, setAll: function setAll(state, action) { var newEntityState = entityAdapter.setAll(state, action.payload); modifyState(state, newEntityState); }, setError: function setError(state, action) { _setError(state, action.payload); }, setStatus: function setStatus(state, action) { _setStatus(state, action.payload); }, setMetaState: function setMetaState(state, action) { var _createNextState, _createNextState2; state.status = (_createNextState = toolkit.createNextState(state.status, function () { return action.payload.status; })) != null ? _createNextState : state.status; state.error = (_createNextState2 = toolkit.createNextState(state.error, function () { return action.payload.error; })) != null ? _createNextState2 : state.error; } } }); var entitySelectors = entityAdapter.getSelectors(function (state) { return selectSliceState(state); }); var selectors = { selectIds: entitySelectors.selectIds, selectEntities: entitySelectors.selectEntities, selectAll: entitySelectors.selectAll, selectTotal: entitySelectors.selectTotal, selectById: entitySelectors.selectById, /* TODO remove type assertion */ selectSliceState: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState; }), selectStatus: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState.status; }), selectError: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState.error; }), selectLastModified: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState.lastModified; }), selectLastHydrated: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState.lastHydrated; }), selectCanRequest: toolkit.createSelector([selectSliceState], function (sliceState) { return selectCanRequest(sliceState); }), selectShouldRequest: toolkit.createSelector([selectSliceState], function (sliceState) { return selectShouldRequest(sliceState, selectCanRequest(sliceState)); }) }; return { name: slice.name, reducer: slice.reducer, actions: slice.actions, selectors: selectors }; } var create$2 = function create(args) { if (args === void 0) { args = {}; } var metaState = MetaState.create(args); return _extends({}, metaState, { model: args.model }); }; /** * @public */ var ModelState = { create: create$2 }; /** * @public */ function createModelSlice(options) { var defaultCanRequestSelector = function defaultCanRequestSelector(sliceState) { return sliceState.status !== 'Requesting' && sliceState.error === null && sliceState.lastModified === null; }; var defaultShouldRequestSelector = function defaultShouldRequestSelector(sliceState, canRequest) { return canRequest && sliceState.lastHydrated === null; }; var name = options.name, _options$handleUpdate = options.handleUpdate, handleUpdate = _options$handleUpdate === void 0 ? function (current, update) { return merge(current, update); } : _options$handleUpdate, selectSliceState = options.selectSliceState, _options$selectCanReq = options.selectCanRequest, selectCanRequest = _options$selectCanReq === void 0 ? defaultCanRequestSelector : _options$selectCanReq, _options$selectShould = options.selectShouldRequest, selectShouldRequest = _options$selectShould === void 0 ? defaultShouldRequestSelector : _options$selectShould, _options$initialState = options.initialState, initialState = _options$initialState === void 0 ? {} : _options$initialState, _options$createTimest = options.createTimestamp, createTimestamp = _options$createTimest === void 0 ? getISOString : _options$createTimest; var initialSliceState = ModelState.create(initialState); var slice = toolkit.createSlice({ name: name, initialState: initialSliceState, // intentional, necessary with immer /* eslint-disable no-param-reassign */ reducers: { hydrate: function hydrate(state, action) { state.model = toolkit.createNextState(state.model, function () { return action.payload; }); state.lastModified = null; // TODO: should not have a side effect: https://redux.js.org/style-guide/style-guide#reducers-must-not-have-side-effects state.lastHydrated = createTimestamp(); }, update: function update(state, action) { state.model = toolkit.createNextState(state.model, function () { return handleUpdate(state.model, action.payload); }); // TODO: should not have a side effect: https://redux.js.org/style-guide/style-guide#reducers-must-not-have-side-effects state.lastModified = createTimestamp(); }, reset: function reset() { return initialSliceState; }, set: function set(state, action) { state.model = toolkit.createNextState(state.model, function () { return action.payload; }); // TODO: should not have a side effect: https://redux.js.org/style-guide/style-guide#reducers-must-not-have-side-effects state.lastModified = createTimestamp(); }, setError: function setError(state, action) { state.error = toolkit.createNextState(state.error, function () { return action.payload; }); }, setStatus: function setStatus(state, action) { state.status = toolkit.createNextState(state.status, function () { return action.payload; }); }, setMetaState: function setMetaState(state, action) { var _createNextState, _createNextState2; state.status = (_createNextState = toolkit.createNextState(state.status, function () { return action.payload.status; })) != null ? _createNextState : state.status; state.error = (_createNextState2 = toolkit.createNextState(state.error, function () { return action.payload.error; })) != null ? _createNextState2 : state.error; } } }); var selectors = { selectSliceState: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState; }), selectModel: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState.model; }), selectStatus: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState.status; }), selectError: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState.error; }), selectLastModified: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState.lastModified; }), selectLastHydrated: toolkit.createSelector([selectSliceState], function (sliceState) { return sliceState.lastHydrated; }), selectCanRequest: toolkit.createSelector([selectSliceState], function (sliceState) { return selectCanRequest(sliceState); }), selectShouldRequest: toolkit.createSelector([selectSliceState], function (sliceState) { return selectShouldRequest(sliceState, selectCanRequest(sliceState)); }) }; return { name: slice.name, reducer: slice.reducer, actions: slice.actions, selectors: selectors }; } exports.StatusEnum = StatusEnum$1; exports.createEntitySlice = createEntitySlice; exports.createModelSlice = createModelSlice; //# sourceMappingURL=redux-slice-factory.cjs.development.js.map