Skip to content

Instantly share code, notes, and snippets.

@MakStashkevich
Forked from stramel/storage.ts
Created February 11, 2025 15:28
Show Gist options
  • Save MakStashkevich/0576ed19d7507fe83af8caa88d0bb478 to your computer and use it in GitHub Desktop.
Save MakStashkevich/0576ed19d7507fe83af8caa88d0bb478 to your computer and use it in GitHub Desktop.

Revisions

  1. @stramel stramel created this gist Feb 7, 2024.
    58 changes: 58 additions & 0 deletions storage.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@
    /**
    * Checks if the specified Web Storage API exists and is accessible
    * @param storage - Web Storage API
    * @returns true, if the Web Storage API is accessible
    */
    const isStorageEnabled = (storage?: Storage): storage is Storage => {
    if (!storage) return false;
    try {
    const key = `__storage__test`;
    storage.setItem(key, '');
    storage.removeItem(key);
    return true;
    } catch {
    return false;
    }
    };

    /**
    * Utilizes a `Map` cache backed Web Storage API when the specified Web Storage API isn't accessible
    * @param storage - possible Web Storage API
    * @returns a Web Storage API implementation
    */
    const createStorage = (storage?: Storage): Storage => {
    if (isStorageEnabled(storage)) {
    return storage;
    }

    const storageFallbackCache = new Map<string, string>();

    return {
    clear(): void {
    storageFallbackCache.clear();
    },
    getItem(key: string): string | null {
    // eslint-disable-next-line unicorn/no-null
    return storageFallbackCache.get(key) ?? null;
    },
    key(index: number): string | null {
    // eslint-disable-next-line unicorn/no-null
    return [...storageFallbackCache.values()][index] ?? null;
    },
    get length() {
    return storageFallbackCache.size;
    },
    removeItem(key: string): void {
    storageFallbackCache.delete(key);
    },
    setItem(key: string, value: string): void {
    storageFallbackCache.set(key, value);
    },
    };
    };

    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    export const localStorage = createStorage(window?.localStorage);

    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    export const sessionStorage = createStorage(window?.sessionStorage);