"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.once = exports.limitCalls = exports.arrayOfKeysMemoize = exports.singleArgMemoize = void 0;

var _object = require("./object");

// dead simple memoization. Only skips
// compute if first arg is same only
// stores one answer
const singleArgMemoize = fn => {
  let answer;
  let lastArg;
  let hasRun = false;
  return arg1 => {
    if (arg1 === lastArg && hasRun) {
      return answer;
    }

    hasRun = true;
    answer = fn(arg1);
    lastArg = arg1;
    return answer;
  };
};

exports.singleArgMemoize = singleArgMemoize;

const serialize = (obj, keys) => {
  let buff = '';

  for (let i = 0, l = keys.length; i < l; i++) {
    const key = keys[i];
    buff += "".concat(key, ":").concat(obj[key]);
  }

  return buff;
};

const arrayOfKeysMemoize = keys => {
  let answer;
  let lastArg;
  let hasRun = false;
  return obj => {
    const serialized = serialize(obj, keys);

    if (serialized === lastArg && hasRun) {
      return answer;
    }

    hasRun = true;
    answer = (0, _object.pluck)(obj, keys);
    lastArg = serialized;
    return answer;
  };
};

exports.arrayOfKeysMemoize = arrayOfKeysMemoize;

const limitCalls = (fn, times) => {
  let memo;
  return function () {
    if (times-- > 0) {
      memo = fn.apply(this, arguments);
    } else {
      fn = null;
    }

    return memo;
  };
};

exports.limitCalls = limitCalls;

const once = fn => limitCalls(fn, 1);

exports.once = once;