"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = useQuery;
exports.parseUrl = parseUrl;
exports.useDebounce = useDebounce;
exports.useDebounceFn = useDebounceFn;
exports.useDebouncedEffect = useDebouncedEffect;

var _react = require("react");

var _debounce = _interopRequireDefault(require("lodash/debounce"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function parseUrl(fragmentStr) {
  var queryObject = {};
  if (!fragmentStr) return queryObject;
  var markIndex = fragmentStr.indexOf('?'); // contain query string in fragments

  if (markIndex > -1) {
    // build query object
    var queryString = fragmentStr.slice(markIndex + 1);
    var queryArray = queryString.split('&');

    for (var i = 0; i < queryArray.length; i += 1) {
      var queryPair = queryArray[i].split('=');
      queryObject[queryPair[0]] = decodeURIComponent(queryPair[1]);
    }
  }

  return queryObject;
}

function useQuery(name) {
  var initValue = name ? parseUrl(decodeURIComponent(window.location.hash))[name] : parseUrl(decodeURIComponent(window.location.hash));

  var _useState = (0, _react.useState)(initValue),
      _useState2 = _slicedToArray(_useState, 2),
      state = _useState2[0],
      setState = _useState2[1];

  var stateRef = (0, _react.useRef)();
  stateRef.current = {
    state: state,
    setState: setState
  };
  var hashChangeHandler = (0, _react.useCallback)(function () {
    var _stateRef$current = stateRef.current,
        state = _stateRef$current.state,
        setState = _stateRef$current.setState;
    var value = name ? parseUrl(decodeURIComponent(window.location.hash))[name] : parseUrl(decodeURIComponent(window.location.hash));

    if (value !== state) {
      setState(value);
    }
  }, []);
  (0, _react.useEffect)(function () {
    window.addEventListener('hashchange', hashChangeHandler);
    return function () {
      window.removeEventListener('hashchange', hashChangeHandler);
    };
  }, []);
  return state;
}

function useLatest(value) {
  var ref = (0, _react.useRef)(value);
  ref.current = value;
  return ref;
}

var useUnmount = function useUnmount(fn) {
  var fnRef = useLatest(fn);
  (0, _react.useEffect)(function () {
    return function () {
      fnRef.current();
    };
  }, []);
};

function useDebounceFn(fn, options) {
  var _options$wait;

  var fnRef = useLatest(fn);
  var wait = (_options$wait = options === null || options === void 0 ? void 0 : options.wait) !== null && _options$wait !== void 0 ? _options$wait : 1000;
  var debounced = (0, _react.useMemo)(function () {
    return (0, _debounce["default"])(function () {
      return fnRef.current.apply(fnRef, arguments);
    }, wait, options);
  }, []);
  useUnmount(function () {
    debounced.cancel();
  });
  return {
    run: debounced,
    cancel: debounced.cancel,
    flush: debounced.flush
  };
}

function useDebounce(value, options) {
  var _useState3 = (0, _react.useState)(value),
      _useState4 = _slicedToArray(_useState3, 2),
      debounced = _useState4[0],
      setDebounced = _useState4[1];

  var _useDebounceFn = useDebounceFn(function () {
    setDebounced(value);
  }, options),
      run = _useDebounceFn.run;

  (0, _react.useEffect)(function () {
    run();
  }, [value]);
  return debounced;
}

function useDebouncedEffect(fn, ms, deps) {
  (0, _react.useEffect)(function () {
    var clean = null;
    var timer = setTimeout(function () {
      clean = fn();
    }, ms);
    return function () {
      clearTimeout(timer);
      if (clean) clean();
    };
  }, deps);
} // a