@cloudcome/utils-core
Version: 
cloudcome core utils
120 lines (119 loc) • 2.68 kB
JavaScript
const STATUS_READY = 0;
const STATUS_START = 1;
const STATUS_PAUSE = 2;
const STATUS_STOP = 3;
function makeInterval(nextTime, effect) {
  let startAt = 0;
  let lastAt = 0;
  let stopAt = 0;
  let pauseAt = 0;
  let resumeAt = 0;
  let times = 0;
  let status = STATUS_READY;
  let runningTime = 0;
  const execute = () => {
    if (status >= STATUS_PAUSE) return;
    const now = Date.now();
    const intervalTime = lastAt > 0 ? now - lastAt : 0;
    runningTime += intervalTime;
    lastAt = now;
    const state = {
      times: ++times,
      startAt,
      stopAt,
      pauseAt,
      resumeAt,
      currentAt: now,
      elapsedTime: startAt > 0 ? now - startAt : 0,
      runningTime,
      intervalTime
    };
    if (effect.length === 2) {
      effect(state, () => {
        nextTime(execute);
      });
    } else {
      effect(state);
      nextTime(execute);
    }
  };
  const canStart = () => status === STATUS_READY;
  const start = () => {
    if (!canStart()) return;
    status = STATUS_START;
    startAt = Date.now();
    execute();
  };
  const canStop = () => status === STATUS_START;
  const stop = () => {
    if (!canStop()) return;
    status = STATUS_STOP;
    stopAt = Date.now();
  };
  const canPause = () => status === STATUS_START;
  const pause = () => {
    if (!canPause()) return;
    status = STATUS_PAUSE;
    pauseAt = Date.now();
  };
  const canResume = () => status === STATUS_PAUSE;
  const resume = () => {
    if (!canResume()) return;
    status = STATUS_START;
    resumeAt = Date.now();
    lastAt = resumeAt;
    execute();
  };
  return {
    canStart,
    canStop,
    canPause,
    canResume,
    start,
    stop,
    pause,
    resume,
    execute
  };
}
function timeInterval(callback, interval, options) {
  let timeId;
  const { canStart, canStop, canPause, canResume, start, stop, pause, resume, execute } = makeInterval((call) => {
    timeId = setTimeout(call, interval);
  }, callback);
  return {
    start() {
      if (!canStart()) return;
      if (options?.leading) {
        start();
      } else {
        timeId = setTimeout(start, interval);
      }
    },
    stop() {
      if (!canStop()) return;
      if (options?.trailing) execute();
      clearTimeout(timeId);
      stop();
    },
    pause() {
      if (!canPause()) return;
      if (options?.trailing) execute();
      clearTimeout(timeId);
      pause();
    },
    resume(immediate) {
      if (!canResume()) return;
      if (immediate || options?.leading) {
        resume();
      } else {
        timeId = setTimeout(resume, interval);
      }
    }
  };
}
export {
  makeInterval,
  timeInterval
};
//# sourceMappingURL=timer.mjs.map