'use strict';

function checkIsEmpty(arg) {
  return arg == null;
}
function throwIsEmpty(argPosition) {
  throw new Error("Argument " + argPosition + " is empty.");
}
function checkValidActionCreator(arg) {
  return typeof arg === 'function' && 'getType' in arg;
}
function checkInvalidActionCreator(arg) {
  return !checkValidActionCreator(arg);
}
function throwInvalidActionCreator(argPosition) {
  throw new Error("Argument " + argPosition + " is invalid, it should be an action-creator instance from \"typesafe-actions\"");
}
function checkInvalidActionCreatorInArray(arg, idx) {
  if (arg == null) {
    throw new Error("Argument contains array with empty element at index " + idx);
  } else if (arg.getType == null) {
    throw new Error("Argument contains array with invalid element at index " + idx + ", it should be an action-creator instance from \"typesafe-actions\"");
  }
}
function checkValidActionType(arg) {
  return typeof arg === 'string' || typeof arg === 'symbol';
}
function checkInvalidActionType(arg) {
  return !checkValidActionType(arg);
}
function throwInvalidActionType(argPosition) {
  throw new Error("Argument " + argPosition + " is invalid, it should be an action type of type: string | symbol");
}
function checkInvalidActionTypeInArray(arg, idx) {
  if (arg == null) {
    throw new Error("Argument contains array with empty element at index " + idx);
  } else if (typeof arg !== 'string' && typeof arg !== 'symbol') {
    throw new Error("Argument contains array with invalid element at index " + idx + ", it should be of type: string | symbol");
  }
}
function throwInvalidActionTypeOrActionCreator(argPosition) {
  throw new Error("Argument " + argPosition + " is invalid, it should be an action-creator instance from \"typesafe-actions\" or action type of type: string | symbol");
}

function action(type, payload, meta, error) {
  if (checkIsEmpty(type)) {
    throwIsEmpty(1);
  }

  if (checkInvalidActionType(type)) {
    throwInvalidActionCreator(1);
  }

  return {
    type: type,
    payload: payload,
    meta: meta,
    error: error
  };
}

function createCustomAction(type, createHandler) {
  if (checkIsEmpty(type)) {
    throwIsEmpty(1);
  }

  if (checkInvalidActionType(type)) {
    throwInvalidActionType(1);
  }

  var actionCreator = function actionCreator() {
    var customProps = createHandler != null ? createHandler.apply(void 0, arguments) : undefined;
    return Object.assign({
      type: type
    }, customProps);
  };

  var typeMeta = {
    getType: function getType() {
      return type;
    },
    toString: function toString() {
      return type;
    }
  };
  return Object.assign(actionCreator, typeMeta);
}

function createAction(type, payloadCreator, metaCreator) {
  if (checkIsEmpty(type)) {
    throwIsEmpty(1);
  }

  if (checkInvalidActionType(type)) {
    throwInvalidActionType(1);
  }

  return function () {
    return createCustomAction(type, function () {
      var payload = arguments.length <= 0 ? undefined : arguments[0];
      var meta = arguments.length <= 1 ? undefined : arguments[1];

      if (payloadCreator != null || metaCreator != null) {
        payload = payloadCreator != null ? payloadCreator.apply(void 0, arguments) : undefined;
        meta = metaCreator != null ? metaCreator.apply(void 0, arguments) : undefined;
      }

      return Object.assign({}, payload !== undefined && {
        payload: payload
      }, {}, meta !== undefined && {
        meta: meta
      });
    });
  };
}

function throwInvalidAsyncActionArgument(argPosition) {
  throw new Error("Argument " + argPosition + " is invalid, it should be an action type of \"string | symbol\" or a tuple of \"[string | symbol, Function, Function?]\"");
}
function createAsyncAction(requestArg, successArg, failureArg, cancelArg) {
  var constructor = function constructor() {
    var results = [requestArg, successArg, failureArg, cancelArg].map(function (arg, index) {
      if (Array.isArray(arg)) {
        return createAction(arg[0], arg[1], arg[2])();
      } else if (typeof arg === 'string' || typeof arg === 'symbol') {
        return createAction(arg)();
      } else if (index < 3) {
        throwInvalidAsyncActionArgument(index);
      }
    });
    var request = results[0],
        success = results[1],
        failure = results[2],
        cancel = results[3];
    return {
      request: request,
      success: success,
      failure: failure,
      cancel: cancel
    };
  };

  return constructor;
}

function getType(actionCreator) {
  if (checkIsEmpty(actionCreator)) {
    throwIsEmpty(1);
  }

  if (checkInvalidActionCreator(actionCreator)) {
    throwInvalidActionCreator(1);
  }

  return actionCreator.getType();
}

function createReducer(initialState, initialHandlers) {
  if (initialHandlers === void 0) {
    initialHandlers = {};
  }

  var handlers = Object.assign({}, initialHandlers);

  var rootReducer = function rootReducer(state, action) {
    if (state === void 0) {
      state = initialState;
    }

    if (handlers.hasOwnProperty(action.type)) {
      var reducer = handlers[action.type];

      if (typeof reducer !== 'function') {
        throw Error("Reducer under \"" + action.type + "\" key is not a valid reducer");
      }

      return reducer(state, action);
    } else {
      return state;
    }
  };

  var reducerHandler = function reducerHandler(singleOrMultipleCreatorsAndTypes, reducer) {
    var creatorsAndTypes = Array.isArray(singleOrMultipleCreatorsAndTypes) ? singleOrMultipleCreatorsAndTypes : [singleOrMultipleCreatorsAndTypes];
    var newHandlers = {};
    creatorsAndTypes.map(function (acOrType, index) {
      return checkValidActionCreator(acOrType) ? getType(acOrType) : checkValidActionType(acOrType) ? acOrType : throwInvalidActionTypeOrActionCreator(index + 1);
    }).forEach(function (type) {
      return newHandlers[type] = reducer;
    });
    return createReducer(initialState, Object.assign({}, handlers, {}, newHandlers));
  };

  var chainApi = Object.assign(rootReducer, {
    handlers: Object.assign({}, handlers),
    handleAction: reducerHandler,
    handleType: reducerHandler
  });
  return chainApi;
}

function isOfType(actionTypeOrTypes, action) {
  if (checkIsEmpty(actionTypeOrTypes)) {
    throwIsEmpty(1);
  }

  var actionTypes = Array.isArray(actionTypeOrTypes) ? actionTypeOrTypes : [actionTypeOrTypes];
  actionTypes.forEach(checkInvalidActionTypeInArray);

  var assertFn = function assertFn(_action) {
    return actionTypes.includes(_action.type);
  };

  if (action === undefined) {
    return assertFn;
  }

  return assertFn(action);
}

function isActionOf(actionCreatorOrCreators, action) {
  if (checkIsEmpty(actionCreatorOrCreators)) {
    throwIsEmpty(1);
  }

  var actionCreators = Array.isArray(actionCreatorOrCreators) ? actionCreatorOrCreators : [actionCreatorOrCreators];
  actionCreators.forEach(checkInvalidActionCreatorInArray);

  var assertFn = function assertFn(_action) {
    return actionCreators.some(function (actionCreator) {
      return _action.type === actionCreator.getType();
    });
  };

  if (action === undefined) {
    return assertFn;
  }

  return assertFn(action);
}

function createAction$1(type, createHandler) {
  var actionCreator = createHandler == null ? function () {
    return action(type);
  } : createHandler(action.bind(null, type));
  return Object.assign(actionCreator, {
    getType: function getType() {
      return type;
    },
    toString: function toString() {
      return type;
    }
  });
}

function createCustomAction$1(type, createHandler) {
  if (checkIsEmpty(type)) {
    throwIsEmpty(1);
  }

  if (checkInvalidActionType(type)) {
    throwInvalidActionType(1);
  }

  var actionCreator = createHandler != null ? createHandler(type) : function () {
    return {
      type: type
    };
  };
  return Object.assign(actionCreator, {
    getType: function getType() {
      return type;
    },
    toString: function toString() {
      return type;
    }
  });
}

function createStandardAction(type) {
  if (checkIsEmpty(type)) {
    throwIsEmpty(1);
  }

  if (checkInvalidActionType(type)) {
    throwInvalidActionType(1);
  }

  function constructor() {
    return createCustomAction$1(type, function (_type) {
      return function (payload, meta) {
        return {
          type: _type,
          payload: payload,
          meta: meta
        };
      };
    });
  }

  function map(fn) {
    return createCustomAction$1(type, function (_type) {
      return function (payload, meta) {
        return Object.assign(fn(payload, meta), {
          type: _type
        });
      };
    });
  }

  return Object.assign(constructor, {
    map: map
  });
}

var index = {
  createAction: createAction$1,
  createCustomAction: createCustomAction$1,
  createStandardAction: createStandardAction
};

exports.action = action;
exports.createAction = createAction;
exports.createAsyncAction = createAsyncAction;
exports.createCustomAction = createCustomAction;
exports.createReducer = createReducer;
exports.deprecated = index;
exports.getType = getType;
exports.isActionOf = isActionOf;
exports.isOfType = isOfType;
//# sourceMappingURL=typesafe-actions.cjs.development.js.map
