UNPKG

@snipsonian/observable-state

Version:

Observable-state snippets (redux-like)

167 lines (166 loc) 8.65 kB
"use strict"; 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;