AkurAI Build
Menu

Public repository / 10d19fe0941c186ec244d1f0e2af6b19200dcb0c

AkurAI-Mail / src/framework/sync-state.js

Latest change 7a6a24a4e46f9f1d964c5593c076f9bdf638fea0 - Fix svelte-check errors in framework signal-badge and sync-state by Ólafur Búi Ólafsson

// Sync status store on the framework signals runtime (replaces the Svelte-rune sync.svelte.ts).
import { signal } from "./vendor/signals.js";
import { retryDelay } from "../lib/webmail/sync";

/**
 * @param {() => number} [now]
 * @param {(fn: () => void, ms: number) => any} [schedule]
 * @param {(id: any) => void} [cancel]
 */
export function createSyncState(now = Date.now, schedule = setTimeout, cancel = clearTimeout) {
  const status = signal(/** @type {"idle"|"syncing"} */ ("idle"));
  const lastSyncAt = signal(/** @type {number|null} */ (null));
  const errorKind = signal(/** @type {string|null} */ (null));
  const dismissed = signal(false);
  const retryCount = signal(0);
  /** @type {unknown} */
  let timer = null;

  function clearTimer() {
    if (timer !== null) cancel(timer);
    timer = null;
  }

  /** @param {string} kind @param {() => void} [retry] */
  function reportError(kind, retry) {
    status("idle");
    errorKind(kind);
    dismissed(false);
    clearTimer();
    if (retry && kind !== "auth-expired") {
      const delay = retryDelay(retryCount());
      retryCount(retryCount() + 1);
      timer = schedule(retry, delay);
    }
  }

  function reportSuccess() {
    status("idle");
    errorKind(null);
    retryCount(0);
    lastSyncAt(now());
    clearTimer();
  }

  /** @param {() => void} run */
  function retryNow(run) {
    clearTimer();
    run();
  }

  return { status, lastSyncAt, errorKind, dismissed, retryCount, reportError, reportSuccess, retryNow, dismiss: () => dismissed(true) };
}