Hits

CODE

export interface Storage {
  get(key: string): string | null;
 
  set(key: string, value: string): void;
 
  remove(key: string): void;
 
  clear(): void;
}
 
class MemoryStorage implements Storage {
  private storage = new Map<string, string>();
 
  public get(key: string) {
    return this.storage.get(key) || null;
  }
 
  public set(key: string, value: string) {
    this.storage.set(key, value);
  }
 
  public remove(key: string) {
    this.storage.delete(key);
  }
 
  public clear() {
    this.storage.clear();
  }
}
 
class LocalStorage implements Storage {
  public static canUse(): boolean {
    const TEST_KEY = generateTestKey();
 
    try {
      localStorage.setItem(TEST_KEY, "test");
      localStorage.removeItem(TEST_KEY);
      return true;
    } catch (err) {
      return false;
    }
  }
 
  public get(key: string) {
    return localStorage.getItem(key);
  }
 
  public set(key: string, value: string) {
    localStorage.setItem(key, value);
  }
 
  public remove(key: string) {
    localStorage.removeItem(key);
  }
 
  public clear() {
    localStorage.clear();
  }
}
 
class SessionStorage implements Storage {
  public static canUse(): boolean {
    const TEST_KEY = generateTestKey();
 
    try {
      sessionStorage.setItem(TEST_KEY, "test");
      sessionStorage.removeItem(TEST_KEY);
      return true;
    } catch (err) {
      return false;
    }
  }
 
  public get(key: string) {
    return sessionStorage.getItem(key);
  }
 
  public set(key: string, value: string) {
    sessionStorage.setItem(key, value);
  }
 
  public remove(key: string) {
    sessionStorage.removeItem(key);
  }
 
  public clear() {
    sessionStorage.clear();
  }
}
 
function generateTestKey() {
  return new Array(4)
    .fill(null)
    .map(() => Math.random().toString(36).slice(2))
    .join("");
}
 
function generateStorage(): Storage {
  if (LocalStorage.canUse()) {
    return new LocalStorage();
  }
  return new MemoryStorage();
}
 
export function generateSessionStorage(): Storage {
  if (SessionStorage.canUse()) {
    return new SessionStorage();
  }
  return new MemoryStorage();
}
 
export const safeLocalStorage = generateStorage();
export const safeSessionStorage = generateSessionStorage();
export interface Storage {
  get(key: string): string | null;
 
  set(key: string, value: string): void;
 
  remove(key: string): void;
 
  clear(): void;
}
 
class MemoryStorage implements Storage {
  private storage = new Map<string, string>();
 
  public get(key: string) {
    return this.storage.get(key) || null;
  }
 
  public set(key: string, value: string) {
    this.storage.set(key, value);
  }
 
  public remove(key: string) {
    this.storage.delete(key);
  }
 
  public clear() {
    this.storage.clear();
  }
}
 
class LocalStorage implements Storage {
  public static canUse(): boolean {
    const TEST_KEY = generateTestKey();
 
    try {
      localStorage.setItem(TEST_KEY, "test");
      localStorage.removeItem(TEST_KEY);
      return true;
    } catch (err) {
      return false;
    }
  }
 
  public get(key: string) {
    return localStorage.getItem(key);
  }
 
  public set(key: string, value: string) {
    localStorage.setItem(key, value);
  }
 
  public remove(key: string) {
    localStorage.removeItem(key);
  }
 
  public clear() {
    localStorage.clear();
  }
}
 
class SessionStorage implements Storage {
  public static canUse(): boolean {
    const TEST_KEY = generateTestKey();
 
    try {
      sessionStorage.setItem(TEST_KEY, "test");
      sessionStorage.removeItem(TEST_KEY);
      return true;
    } catch (err) {
      return false;
    }
  }
 
  public get(key: string) {
    return sessionStorage.getItem(key);
  }
 
  public set(key: string, value: string) {
    sessionStorage.setItem(key, value);
  }
 
  public remove(key: string) {
    sessionStorage.removeItem(key);
  }
 
  public clear() {
    sessionStorage.clear();
  }
}
 
function generateTestKey() {
  return new Array(4)
    .fill(null)
    .map(() => Math.random().toString(36).slice(2))
    .join("");
}
 
function generateStorage(): Storage {
  if (LocalStorage.canUse()) {
    return new LocalStorage();
  }
  return new MemoryStorage();
}
 
export function generateSessionStorage(): Storage {
  if (SessionStorage.canUse()) {
    return new SessionStorage();
  }
  return new MemoryStorage();
}
 
export const safeLocalStorage = generateStorage();
export const safeSessionStorage = generateSessionStorage();

Reference

https://github.com/toss/slash/blob/main/packages/common/storage/src/storage.ts