UNPKG

@speckle/shared

Version:

Shared code between various Speckle JS packages

82 lines (67 loc) 2.02 kB
import type { Nullable } from '../helpers/utilityTypes.js' function checkLocalStorageAvailability(): boolean { try { const testKey = '___localStorageAvailabilityTest' const storage = globalThis.localStorage storage.setItem(testKey, testKey) storage.getItem(testKey) storage.removeItem(testKey) return true } catch { return false } } /** * In memory implementation of the Storage interface, for use when LocalStorage * isn't available */ class FakeStorage implements Storage { #internalStorage = new Map<string, string>() clear(): void { this.#internalStorage.clear() } getItem(key: string): string | null { return this.#internalStorage.get(key) || null } key(index: number): string | null { return [...this.#internalStorage.keys()][index] || null } removeItem(key: string): void { this.#internalStorage.delete(key) } setItem(key: string, value: string): void { this.#internalStorage.set(key, value) } get length(): number { return this.#internalStorage.size } } /** * Whether or not the local storage is available in this session */ const isLocalStorageAvailable = checkLocalStorageAvailability() /** * Localstorage (real or faked) to use in this session */ const internalStorage: Storage = isLocalStorageAvailable ? globalThis.localStorage : new FakeStorage() /** * Utility for nicer reads/writes from/to LocalStorage without having to worry about the browser * throwing a hissy fit because the page is opened in Incognito mode or node not having localStorage at all */ export const SafeLocalStorage = { get(key: string): Nullable<string> { return internalStorage.getItem(key) }, set(key: string, value: string): void { internalStorage.setItem(key, value) }, remove(key: string): void { internalStorage.removeItem(key) }, /** * Flag for telling if we're using a real localStorage or faking it with a basic in-memory collection */ isRealLocalStorage: isLocalStorageAvailable }