AkurAI Build
Menu

Public repository / 10d19fe0941c186ec244d1f0e2af6b19200dcb0c

AkurAI-Mail / src/lib/webmail/sync.svelte.ts

Latest change 22202d1bde69be4ace8a299dffd91f8ff24378df - Recover deployed webmail frontend (frontend parity with EC2 a6afffc) by Ólafur Búi Ólafsson

import { retryDelay, type SyncErrorKind } from "./sync";

/** Reactive sync state: status, last success, current error and an auto-retry timer. */
export function createSyncState() {
  let status = $state<"idle" | "syncing">("idle");
  let lastSyncAt = $state<number | null>(null);
  let errorKind = $state<SyncErrorKind | null>(null);
  let dismissed = $state(false);
  let retryCount = $state(0);
  let timer: ReturnType<typeof setTimeout> | null = null;

  function clearTimer() {
    if (timer) clearTimeout(timer);
    timer = null;
  }

  /** Records a failure; schedules `retry` with backoff unless the session expired. */
  function reportError(kind: SyncErrorKind, retry?: () => void) {
    status = "idle";
    errorKind = kind;
    dismissed = false;
    clearTimer();
    if (retry && kind !== "auth-expired") {
      const delay = retryDelay(retryCount);
      retryCount += 1;
      timer = setTimeout(retry, delay);
    }
  }

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

  function retryNow(run: () => void) {
    clearTimer();
    run();
  }

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

export type SyncState = ReturnType<typeof createSyncState>;