TypeScript i StorageManager
Ten artykuł wyjaśnia TypeScript i StorageManager.
Udostępniamy praktyczne przykłady wyjaśniające TypeScript i StorageManager.
YouTube Video
TypeScript i StorageManager
Czym jest StorageManager?
StorageManager to API, które pozwala aplikacjom internetowym oszacować, ile pamięci jest używanych oraz ile jest dostępnych zasobów. Zapewnia także metodę żądania trwałości danych (persist()), aby zapobiec automatycznemu usunięciu danych przez użytkownika lub przeglądarkę. Umożliwia to kontrolowanie, czy jest wystarczająco dużo wolnego miejsca oraz czy dane mogą być automatycznie usunięte, na przykład podczas przechowywania dużych ilości danych w IndexedDB dla aplikacji offline.
Wykrywanie funkcji
Najpierw sprawdź, czy przeglądarka obsługuje 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}- Ta funkcja sprawdza dostępność API StorageManager etapami.
- Ponieważ
navigator.storagenie istnieje w niektórych przeglądarkach, takich jak Safari, ważne jest, aby bezpiecznie sprawdzić jego istnienie za pomocątypeof.
Szacowanie wykorzystania pamięci (estimate())
Po sprawdzeniu dostępności funkcji za pomocą supportsStorageManager() uzyskaj wartości użycia (usage) i limitu (quota) poprzez 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});- Ta funkcja zawsze działa bezpiecznie i zwraca
null, jeśli przeglądarka jej nie obsługuje. usageiquotato wartości szacunkowe i mogą się różnić w zależności od przeglądarki.
Żądanie trwałości danych (persist())
Użyj persist(), aby poprosić o trwałość, dzięki czemu ważne dane (np. pamięć podręczna offline) nie zostaną automatycznie usunięte przez przeglądarkę. Nie działa to jednak we wszystkich środowiskach.
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});- Jeśli
persist()zakończy się sukcesem, dane nie będą automatycznie usuwane przez przeglądarkę, z wyjątkiem ręcznej interwencji użytkownika. Jednak żądania mogą zostać odrzucone w zależności od działań użytkownika lub ustawień przeglądarki.
Sprawdź dostępność pamięci przed zapisem danych
Sprawdź dostępne miejsce przed zapisaniem dużej ilości danych, aby zapobiec błędom zapisu (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});- Sprawdzanie dostępnej pamięci przed zapisem pozwala zmniejszyć ryzyko przerwania zapisu z powodu niewystarczającej pojemności.
Bezpieczne typowanie obsługi localStorage w TypeScript
localStorage jest wygodnym sposobem przechowywania lekkich danych konfiguracyjnych oraz podobnych informacji.
Poniższa klasa wykorzystuje typy generyczne do stworzenia bezpiecznego typowo wrappera.
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'));- Ta klasa pomaga zmniejszyć ryzyko przechowywania lub pobierania danych o niewłaściwym typie.
Wskazówki praktyczne i najlepsze praktyki
-
Zawsze sprawdzaj, czy przeglądarka obsługuje StorageManager Ponieważ StorageManager jest stosunkowo nowym API, zawsze potwierdź jego istnienie przed użyciem.
-
Zwracaj uwagę na limity pamięci i kompatybilność Wartość zwracana przez
estimate()różni się w zależności od przeglądarki i jest tylko szacunkowa. -
Projektuj z myślą o asynchronicznych API
estimate()ipersist()to asynchroniczne API oparte na obietnicach (Promise). Projektuj kod tak, aby nie blokować interfejsu użytkownika (UI). -
Względy bezpieczeństwa Nie przechowuj wrażliwych informacji, takich jak tokeny dostępu, w
localStorage. Zaleca się użycie ciasteczek HttpOnly lub szyfrowania, jeśli to możliwe. -
Projektowanie mechanizmów zapasowych (fallback) Jeżeli
supportsStorageManager()zwraca false, zapewnij logikę przełączenia na użycie tylkolocalStoragelubIndexedDB.
Podsumowanie
Dzięki wykrywaniu możliwości za pomocą supportsStorageManager() możesz bezpiecznie obsłużyć wszystkie środowiska, sprawdzać użycie i dostępny limit przez navigator.storage.estimate() oraz żądać trwałości przez persist(). W TypeScript używaj funkcji opakowujących (wrapperów) oraz definicji typów, aby pisać czytelny i bezpieczny kod. Podstawowy schemat to: sprawdź istnienie, oszacuj zasoby, żądaj trwałości oraz sprawdź pojemność przed zapisem do pamięci.
Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.