mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-21 05:58:10 +02:00
- Grille : réglages écrits dans le localStorage au plus toutes les 500 ms (immédiatement à la fermeture), tendance réseau et texte de recherche calculés une fois par ligne, courbe de tendance mémorisée, barre du bas abonnée au seul nombre de modifications. - Commandes : appels « franco » 6 par 6 ; dernière réception limitée aux fournisseurs du cadencier (résultats identiques sur la base de test). - Dépendances inutilisées retirées (react-query, @google/genai, ai, react-markdown, remark-gfm, xlsx, @radix-ui/react-dropdown-menu) ; pnpm-lock.yaml supprimé (npm est utilisé par Docker et le README). - Code mort et journaux de build retirés. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AcA129WzGTH6zxPHFBGWmn
55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import { createJSONStorage, type PersistStorage, type StorageValue } from "zustand/middleware";
|
|
|
|
/**
|
|
* Stockage `persist` de zustand qui n'écrit dans le localStorage qu'au plus une
|
|
* fois par `delaiMs`.
|
|
*
|
|
* `persist` réécrit (et resérialise) l'état à chaque `set`, quel que soit le
|
|
* champ modifié : deux fois par changement de gamme, et à chaque mouvement de
|
|
* souris pendant qu'on élargit une colonne. Ici, seule la dernière valeur est
|
|
* écrite, et elle l'est aussitôt quand la page est quittée ou masquée.
|
|
*/
|
|
export function createThrottledJSONStorage<S>(delaiMs = 500): PersistStorage<S> | undefined {
|
|
// Rendu serveur : même repli que zustand par défaut (rien n'est persisté).
|
|
if (typeof window === "undefined") return undefined;
|
|
const inner = createJSONStorage<S>(() => window.localStorage);
|
|
if (!inner) return undefined;
|
|
|
|
let enAttente: { name: string; value: StorageValue<S> } | null = null;
|
|
let minuteur: number | null = null;
|
|
|
|
const ecrire = () => {
|
|
if (minuteur !== null) {
|
|
clearTimeout(minuteur);
|
|
minuteur = null;
|
|
}
|
|
if (!enAttente) return;
|
|
const { name, value } = enAttente;
|
|
enAttente = null;
|
|
try {
|
|
inner.setItem(name, value);
|
|
} catch {
|
|
/* quota dépassé ou stockage bloqué : ignoré, comme avant */
|
|
}
|
|
};
|
|
|
|
window.addEventListener("pagehide", ecrire);
|
|
document.addEventListener("visibilitychange", () => {
|
|
if (document.visibilityState === "hidden") ecrire();
|
|
});
|
|
|
|
return {
|
|
getItem: (name) => (enAttente?.name === name ? enAttente.value : inner.getItem(name)),
|
|
setItem: (name, value) => {
|
|
enAttente = { name, value };
|
|
if (minuteur === null) minuteur = window.setTimeout(ecrire, delaiMs);
|
|
},
|
|
removeItem: (name) => {
|
|
if (enAttente?.name === name) enAttente = null;
|
|
inner.removeItem(name);
|
|
},
|
|
};
|
|
}
|