@snipsonian/observable-state
Version:
Observable-state snippets (redux-like)
167 lines (166 loc) • 8.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.initAsyncEntityActionCreators = void 0;
const isSet_1 = require("@snipsonian/core/cjs/is/isSet");
const actionCreators_1 = require("../actionCreators");
const types_1 = require("./types");
const asyncEntityUpdaters_1 = require("./asyncEntityUpdaters");
function initAsyncEntityActionCreators({ entitiesStateField = 'entities', getEntitiesInitialState, }) {
const asyncEntityActionCreators = {
getAsyncEntity: (state, asyncEntityKey) => state[entitiesStateField][asyncEntityKey],
updateAsyncEntityInState: ({ asyncEntityKey, entityUpdater, options, setState, }) => {
setState({
newState: (currentState) => {
const entity = asyncEntityActionCreators.getAsyncEntity(currentState, asyncEntityKey);
return Object.assign(Object.assign({}, currentState), { [entitiesStateField]: Object.assign(Object.assign({}, currentState[entitiesStateField]), { [asyncEntityKey]: entityUpdater(entity) }) });
},
notificationsToTrigger: options.notificationsToTrigger,
nrOfParentNotificationLevelsToTrigger: options.nrOfParentNotificationLevelsToTrigger,
});
},
fetchAsyncEntityAction: ({ asyncEntityKey, api, apiInputSelector, mapApiResponse, notificationsToTrigger, nrOfParentNotificationLevelsToTrigger, resetDataOnTrigger = true, onTrigger, onPreSuccess, onSuccess, onError, }) => createAsyncEntityActionBase({
asyncEntityKey,
api,
apiInputSelector,
mapApiResponse,
notificationsToTrigger,
nrOfParentNotificationLevelsToTrigger,
operation: types_1.AsyncOperation.fetch,
resetDataOnTrigger,
updateDataOnSuccess: true,
onTrigger,
onPreSuccess,
onSuccess,
onError,
}),
createAsyncEntityAction: ({ asyncEntityKey, api, apiInputSelector, mapApiResponse, notificationsToTrigger, nrOfParentNotificationLevelsToTrigger, updateDataOnSuccess = false, markAsFetchedOnSuccess, onTrigger, onPreSuccess, onSuccess, onError, }) => createAsyncEntityActionBase({
asyncEntityKey,
api,
apiInputSelector,
mapApiResponse,
notificationsToTrigger,
nrOfParentNotificationLevelsToTrigger,
operation: types_1.AsyncOperation.create,
resetDataOnTrigger: false,
updateDataOnSuccess,
markAsFetchedOnSuccess: (0, isSet_1.default)(markAsFetchedOnSuccess) ? markAsFetchedOnSuccess : updateDataOnSuccess,
onTrigger,
onPreSuccess,
onSuccess,
onError,
}),
updateAsyncEntityAction: ({ asyncEntityKey, api, apiInputSelector, mapApiResponse, notificationsToTrigger, nrOfParentNotificationLevelsToTrigger, updateDataOnSuccess = false, onTrigger, onPreSuccess, onSuccess, onError, }) => createAsyncEntityActionBase({
asyncEntityKey,
api,
apiInputSelector,
mapApiResponse,
notificationsToTrigger,
nrOfParentNotificationLevelsToTrigger,
operation: types_1.AsyncOperation.update,
resetDataOnTrigger: false,
updateDataOnSuccess,
onTrigger,
onPreSuccess,
onSuccess,
onError,
}),
removeAsyncEntityAction: ({ asyncEntityKey, api, apiInputSelector, notificationsToTrigger, nrOfParentNotificationLevelsToTrigger, markAsNotFetchedOnSuccess = true, onTrigger, onPreSuccess, onSuccess, onError, }) => createAsyncEntityActionBase({
asyncEntityKey,
api,
apiInputSelector,
notificationsToTrigger,
nrOfParentNotificationLevelsToTrigger,
operation: types_1.AsyncOperation.remove,
resetDataOnTrigger: false,
updateDataOnSuccess: false,
markAsNotFetchedOnSuccess,
onTrigger,
onPreSuccess,
onSuccess,
onError,
}),
};
return asyncEntityActionCreators;
function createAsyncEntityActionBase({ asyncEntityKey, api, apiInputSelector, mapApiResponse, notificationsToTrigger, nrOfParentNotificationLevelsToTrigger, operation, resetDataOnTrigger, updateDataOnSuccess, markAsFetchedOnSuccess = false, markAsNotFetchedOnSuccess = false, onTrigger, onPreSuccess, onSuccess, onError, }) {
return (0, actionCreators_1.createObservableStateAction)({
type: `${asyncEntityKey}_${operation.toUpperCase()}`,
payload: {
operation,
},
async process({ getState, setState, dispatch }) {
const asyncEntityUpdaters = asyncEntityUpdaters_1.ASYNC_OPERATION_2_ASYNC_ENTITY_UPDATERS[operation];
const asyncEntityUpdatersFetch = asyncEntityUpdaters_1.ASYNC_OPERATION_2_ASYNC_ENTITY_UPDATERS[types_1.AsyncOperation.fetch];
try {
asyncEntityActionCreators.updateAsyncEntityInState({
entityUpdater: (entity) => {
return resetDataOnTrigger
? asyncEntityUpdaters.trigger(entity, getEntitiesInitialState()[asyncEntityKey].data)
: asyncEntityUpdaters.triggerWithoutDataReset(entity);
},
asyncEntityKey,
setState,
options: {
notificationsToTrigger,
nrOfParentNotificationLevelsToTrigger,
},
});
if (onTrigger) {
onTrigger({ state: getState(), dispatch });
}
const apiInput = (0, isSet_1.default)(apiInputSelector)
? apiInputSelector({ state: getState() })
: {};
const apiResponse = await api(apiInput);
const apiResult = (0, isSet_1.default)(mapApiResponse)
? mapApiResponse({ response: apiResponse, state: getState() })
: apiResponse;
if (onPreSuccess) {
onPreSuccess({ apiResponse, apiResult, apiInput, state: getState(), dispatch });
}
asyncEntityActionCreators.updateAsyncEntityInState({
entityUpdater: (entity) => {
const updatedEntity = updateDataOnSuccess
? asyncEntityUpdaters.succeeded(entity, apiResult)
: asyncEntityUpdaters.succeededWithoutDataSet(entity);
if (markAsFetchedOnSuccess) {
return asyncEntityUpdatersFetch.succeededWithoutDataSet(updatedEntity);
}
if (markAsNotFetchedOnSuccess) {
return asyncEntityUpdatersFetch.resetWithoutDataReset(updatedEntity);
}
return updatedEntity;
},
asyncEntityKey,
setState,
options: {
notificationsToTrigger,
nrOfParentNotificationLevelsToTrigger,
},
});
if (onSuccess) {
onSuccess({ apiResponse, apiResult, apiInput, state: getState(), dispatch });
}
}
catch (error) {
asyncEntityActionCreators.updateAsyncEntityInState({
entityUpdater: (entity) => asyncEntityUpdaters.failed(entity, error),
asyncEntityKey,
setState,
options: {
notificationsToTrigger,
nrOfParentNotificationLevelsToTrigger,
},
});
if (onError) {
onError({
error: error,
state: getState(),
dispatch,
});
}
}
},
});
}
}
exports.initAsyncEntityActionCreators = initAsyncEntityActionCreators;