text: export const delay = (ms) => new Promise((f) => setTimeout(f, ms));
  
  const defaults = {
    maxRetry: Infinity,
    interval: 500,
    intervalMultiplicator: 1.1
  };
  
  export function retry(f, options = defaults) {
    const { maxRetry, interval, intervalMultiplicator } = { ...defaults, ...options };
  
    function rec(remainingTry, i) {
      const result = f();
      if (remainingTry <= 0) {
        return result;
      }
      // In case of failure, wait the interval, retry the action
      return result.catch(() => {
        return delay(i).then(() => rec(remainingTry - 1, i * intervalMultiplicator));
      });
    }
  
    return rec(maxRetry, interval);
  }
  
  export const promisify = (fn) => (...args) => {
    return new Promise((resolve, reject) =>
      fn(...args, (err, res) => {
        if (err) return reject(err);
        return resolve(res);
      })
    );
  };
  
  export const debounce = (fn, ms) => {
    let timeout;
    let resolveRefs = [];
    let rejectRefs = [];
    return (...args) => {
      const promise = new Promise((resolve, reject) => {
        resolveRefs.push(resolve);
        rejectRefs.push(reject);
      });
      if (timeout) {
        clearTimeout(timeout);
      }
      timeout = setTimeout(async () => {
        try {
          const res = await fn(...args);
          resolveRefs.forEach((r) => r(res));
        } catch (err) {
          rejectRefs.forEach((r) => r(err));
        }
        resolveRefs = [];
        rejectRefs = [];
      }, ms);
      return promise;
    };
  };
  