L’offline-first est structurel dès la V1. Le SDK écrit d’abord en local, puis envoie en arrière-plan. Un réseau instable ne provoque ni perte ni doublon.

File locale

  • Chaque événement est écrit immédiatement dans une file locale (IndexedDB, fallback localStorage) avant toute tentative réseau.
  • track() / page() se résolvent dès la persistance en file, sans attendre le réseau — l’UI n’est jamais bloquée.

Batch & scheduler

  • Envoi par batch : déclenché au premier des deux seuils atteint.
    • Intervalle : flushIntervalMs (défaut 5000 ms).
    • Taille : flushBatchSize (défaut 10 événements).
  • Flush aussi sur visibilitychange / pagehide (best-effort via keepalive / sendBeacon).
  • flush() force une tentative immédiate.

Retry avec backoff

Defaults : maxRetries: 10, retryBaseDelayMs: 1000, retryMaxDelayMs: 60000.

Idempotence par UUID

Chaque événement porte un eventId (UUID v4) généré côté client et jamais regénéré au retry. Côté ingestion, la déduplication (ON CONFLICT DO NOTHING) garantit qu’un batch rejoué après un échec réseau ne crée aucun doublon.
La file n’est jamais purgée avant l’ACK serveur. Seuls les eventIds confirmés sont retirés localement.

Tester le comportement offline

1

Couper la connexion

Passez l’onglet en mode hors-ligne (DevTools → Network → Offline).
2

Générer des événements

Naviguez, cliquez, appelez track(). Les événements s’accumulent en file.
3

Reconnecter

Rétablissez la connexion. Le scheduler renvoie la file au prochain flush.
4

Vérifier l'absence de doublon

Comptez les eventId reçus côté ingestion : chaque UUID n’apparaît qu’une fois.