TypeScript et StorageManager

TypeScript et StorageManager

Cet article explique TypeScript et StorageManager.

Nous fournissons des exemples pratiques pour expliquer TypeScript et StorageManager.

YouTube Video

TypeScript et StorageManager

Qu'est-ce que StorageManager ?

StorageManager est une API qui permet aux applications web d'estimer la quantité de stockage utilisée et la capacité disponible. Elle fournit également une méthode de demande de persistance (persist()) afin d'éviter la suppression automatique des données par l'utilisateur ou le navigateur. Cela permet de contrôler si suffisamment d'espace est disponible ou si les données risquent d'être automatiquement supprimées, par exemple lors du stockage de grandes quantités de données dans IndexedDB pour des applications hors ligne.

Détection des fonctionnalités

Commencez par vérifier si le navigateur prend en charge navigator.storage.

 1// TypeScript: feature detection for StorageManager
 2function supportsStorageManager(): boolean {
 3  return typeof navigator !== "undefined" &&
 4         typeof navigator.storage !== "undefined" &&
 5         typeof navigator.storage.estimate === "function";
 6}
 7
 8// Example usage
 9if (supportsStorageManager()) {
10  console.log("StorageManager is supported.");
11} else {
12  console.warn("StorageManager not supported. Falling back to localStorage or IndexedDB.");
13}
  • Cette fonction vérifie la disponibilité de l'API StorageManager par étapes.
  • Comme navigator.storage n'existe pas dans certains navigateurs, comme Safari, il est important de vérifier son existence en toute sécurité avec typeof.

Estimer l'utilisation du stockage (estimate())

Après avoir vérifié la fonctionnalité avec supportsStorageManager(), obtenez l’utilisation (usage) et le quota (quota) à partir de navigator.storage.estimate().

 1// TypeScript: safely get storage estimate
 2async function getStorageEstimate(): Promise<{ usage: number; quota: number } | null> {
 3  if (!supportsStorageManager()) {
 4    console.warn("StorageManager not supported.");
 5    return null;
 6  }
 7
 8  const estimate = await navigator.storage.estimate();
 9  return { usage: estimate.usage ?? 0, quota: estimate.quota ?? 0 };
10}
11
12// Example usage
13getStorageEstimate().then(result => {
14  if (result) {
15    console.log(`Usage: ${result.usage} bytes / Quota: ${result.quota} bytes`);
16  }
17});
  • Cette fonction fonctionne toujours de manière sûre et retourne null si le navigateur ne la prend pas en charge.
  • usage et quota sont des estimations et peuvent varier selon les navigateurs.

Demander la persistance des données (persist())

Utilisez persist() pour demander la persistance afin que les données importantes (par exemple, le cache hors ligne) ne soient pas supprimées automatiquement par le navigateur. Cependant, cela ne réussit pas dans tous les environnements.

 1// TypeScript: safely request persistent storage
 2async function requestPersistence(): Promise<boolean> {
 3  if (!supportsStorageManager()) {
 4    console.warn("StorageManager not supported.");
 5    return false;
 6  }
 7
 8  if (typeof navigator.storage.persist !== "function") {
 9    console.warn("persist() not available in this browser.");
10    return false;
11  }
12
13  try {
14    const granted = await navigator.storage.persist();
15    return Boolean(granted);
16  } catch (err) {
17    console.error("persist() error:", err);
18    return false;
19  }
20}
21
22// Example usage
23requestPersistence().then(granted => {
24  console.log("Persistence granted?", granted);
25});
  • Si persist() réussit, les données ne seront pas automatiquement supprimées par le navigateur, sauf par intervention manuelle de l'utilisateur. Cependant, les demandes peuvent être refusées selon les actions de l'utilisateur ou les paramètres du navigateur.

Vérifier l'espace de stockage disponible avant d'enregistrer des données

Vérifiez l'espace disponible avant d'enregistrer des données volumineuses pour éviter les échecs d'écriture (QuotaExceededError).

 1// TypeScript: ensure enough space before writing
 2async function ensureSpaceAndWrite(neededBytes: number, writeFn: () => Promise<void>): Promise<boolean> {
 3  const estimate = await getStorageEstimate();
 4  if (!estimate) {
 5    console.warn("Cannot check storage space. Proceeding without validation.");
 6    await writeFn();
 7    return true;
 8  }
 9
10  const free = estimate.quota - estimate.usage;
11  if (free < neededBytes) {
12    console.warn(`Not enough space. Free: ${free} bytes, needed: ${neededBytes} bytes.`);
13    return false;
14  }
15
16  await writeFn();
17  return true;
18}
19
20// Example usage
21ensureSpaceAndWrite(10 * 1024 * 1024, async () => {
22  console.log("Saving large data...");
23});
  • En vérifiant l'espace de stockage disponible avant d'enregistrer, vous pouvez réduire les risques d'interruption d'écriture dus à une capacité insuffisante.

Gérer localStorage de manière typée en TypeScript

localStorage est pratique pour stocker des données de configuration légères et des informations similaires.

La classe suivante utilise les génériques pour créer un wrapper à typage sûr.

 1// TypeScript: typed localStorage wrapper
 2type Serializer<T> = {
 3  serialize: (v: T) => string;
 4  deserialize: (s: string) => T;
 5};
 6
 7class TypedLocalStorage<K extends string, V> {
 8  constructor(private storage: Storage, private serializer: Serializer<V>) {}
 9
10  set(key: K, value: V): void {
11    this.storage.setItem(key, this.serializer.serialize(value));
12  }
13
14  get(key: K): V | null {
15    const raw = this.storage.getItem(key);
16    if (raw === null) return null;
17    try {
18      return this.serializer.deserialize(raw);
19    } catch {
20      return null;
21    }
22  }
23
24  remove(key: K): void {
25    this.storage.removeItem(key);
26  }
27
28  clear(): void {
29    this.storage.clear();
30  }
31}
32
33// Example usage
34const jsonSerializer: Serializer<any> = {
35  serialize: v => JSON.stringify(v),
36  deserialize: s => JSON.parse(s),
37};
38
39const appStorage = new TypedLocalStorage<'theme' | 'token', any>(localStorage, jsonSerializer);
40appStorage.set('theme', { dark: true });
41console.log(appStorage.get('theme'));
  • Cette classe aide à réduire le risque de stocker ou d'extraire des données avec un type incorrect.

Considérations pratiques et meilleures pratiques

  • Vérifiez toujours si le navigateur prend en charge StorageManager Comme StorageManager est une API relativement nouvelle, il faut toujours confirmer son existence avant utilisation.

  • Faites attention aux limites de stockage et à la compatibilité La valeur retournée par estimate() varie selon le navigateur et n'est qu'une estimation.

  • Concevez votre code en tenant compte des API asynchrones estimate() et persist() sont des API asynchrones basées sur les promesses. Concevez votre code pour ne pas bloquer l'interface utilisateur.

  • Considérations de sécurité Ne stockez pas d'informations sensibles telles que des jetons d'accès dans localStorage. Envisagez d'utiliser des cookies HttpOnly ou le chiffrement si possible.

  • Conception alternative (fallback) Si supportsStorageManager() renvoie false, prévoyez une logique permettant d'utiliser uniquement localStorage ou IndexedDB.

Résumé

Grâce à la détection des fonctionnalités avec supportsStorageManager(), vous pouvez prendre en charge en toute sécurité tous les environnements, vérifier l'utilisation et le quota avec navigator.storage.estimate(), et demander la persistance avec persist(). En TypeScript, utilisez des fonctions d'enrobage (wrapper) et des définitions de types pour écrire un code lisible et sûr. Le flux de base est : vérifier l'existence, estimer, demander la persistance, et vérifier la capacité avant d'écrire dans le stockage.

Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.

YouTube Video