import { busy, scheduleRetry } from './actions';
import { JS_ERROR } from './constants';
import type { Config, OfflineAction, ResultAction } from './types';

const complete = (
  action: ResultAction,
  success: boolean,
  payload: {}
): ResultAction => ({
  ...action,
  payload,
  meta: { ...action.meta, success, completed: true }
});

const send = (action: OfflineAction, dispatch, config: Config, retries = 0) => {
  const metadata = action.meta.offline;
  dispatch(busy(true));
  return config
    .effect(metadata.effect, action)
    .then(result => {
      const commitAction = metadata.commit || config.defaultCommit;
      try {
        dispatch(complete(commitAction, true, result));
      } catch (e) {
        dispatch(complete({ type: JS_ERROR, payload: e }, false));
      }
    })
    .catch(error => {
      const rollbackAction = metadata.rollback || config.defaultRollback;

      // discard
      if (config.discard(error, action, retries)) {
        dispatch(complete(rollbackAction, false, error));
        return;
      }
      const delay = config.retry(action, retries);
      if (delay != null) {
        dispatch(scheduleRetry(delay));
        return;
      }
      dispatch(complete(rollbackAction, false, error));
    });
};

export default send;

@@ -594,24 +594,37 @@
 a.commit %7C%7C 
+%7B%0A        ...
 config.defau
@@ -631,16 +631,95 @@
 ltCommit
+,%0A        meta: %7B ...config.defaultCommit.meta, offlineAction: action %7D%0A      %7D
 ;%0A      
@@ -954,16 +954,29 @@
 back %7C%7C 
+%7B%0A        ...
 config.d
@@ -989,16 +989,97 @@
 Rollback
+,%0A        meta: %7B ...config.defaultRollback.meta, offlineAction: action %7D%0A      %7D
 ;%0A%0A     

Add offline action to default commit and rollback actions