mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 05:11:13 -05:00
Refactor code structure and remove redundant changes
This commit is contained in:
176
src-old/lib/localStorage.ts
Normal file
176
src-old/lib/localStorage.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* Safe localStorage wrapper with proper error handling and validation
|
||||
*
|
||||
* Handles:
|
||||
* - Private browsing mode (localStorage unavailable)
|
||||
* - Storage quota exceeded
|
||||
* - JSON parse errors
|
||||
* - Cross-origin restrictions
|
||||
*/
|
||||
|
||||
import { logger } from './logger';
|
||||
|
||||
export class LocalStorageError extends Error {
|
||||
constructor(message: string, public readonly cause?: Error) {
|
||||
super(message);
|
||||
this.name = 'LocalStorageError';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if localStorage is available
|
||||
*/
|
||||
export function isLocalStorageAvailable(): boolean {
|
||||
try {
|
||||
const testKey = '__localStorage_test__';
|
||||
localStorage.setItem(testKey, 'test');
|
||||
localStorage.removeItem(testKey);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely get an item from localStorage
|
||||
*/
|
||||
export function getItem(key: string): string | null {
|
||||
try {
|
||||
if (!isLocalStorageAvailable()) {
|
||||
return null;
|
||||
}
|
||||
return localStorage.getItem(key);
|
||||
} catch (error) {
|
||||
logger.warn(`Failed to get localStorage item: ${key}`, { error });
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely set an item in localStorage
|
||||
*/
|
||||
export function setItem(key: string, value: string): boolean {
|
||||
try {
|
||||
if (!isLocalStorageAvailable()) {
|
||||
return false;
|
||||
}
|
||||
localStorage.setItem(key, value);
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.name === 'QuotaExceededError') {
|
||||
logger.warn('localStorage quota exceeded', { key });
|
||||
} else {
|
||||
logger.warn(`Failed to set localStorage item: ${key}`, { error });
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely remove an item from localStorage
|
||||
*/
|
||||
export function removeItem(key: string): boolean {
|
||||
try {
|
||||
if (!isLocalStorageAvailable()) {
|
||||
return false;
|
||||
}
|
||||
localStorage.removeItem(key);
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.warn(`Failed to remove localStorage item: ${key}`, { error });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely clear all localStorage
|
||||
*/
|
||||
export function clear(): boolean {
|
||||
try {
|
||||
if (!isLocalStorageAvailable()) {
|
||||
return false;
|
||||
}
|
||||
localStorage.clear();
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.warn('Failed to clear localStorage', { error });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and parse a JSON object from localStorage
|
||||
*/
|
||||
export function getJSON<T>(key: string, defaultValue: T): T {
|
||||
try {
|
||||
const item = getItem(key);
|
||||
if (!item) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
const parsed = JSON.parse(item);
|
||||
return parsed as T;
|
||||
} catch (error) {
|
||||
logger.warn(`Failed to parse localStorage JSON for key: ${key}`, { error });
|
||||
// Remove corrupted data
|
||||
removeItem(key);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stringify and set a JSON object in localStorage
|
||||
*/
|
||||
export function setJSON<T>(key: string, value: T): boolean {
|
||||
try {
|
||||
const serialized = JSON.stringify(value);
|
||||
return setItem(key, serialized);
|
||||
} catch (error) {
|
||||
logger.warn(`Failed to stringify localStorage JSON for key: ${key}`, { error });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a key exists in localStorage
|
||||
*/
|
||||
export function hasItem(key: string): boolean {
|
||||
return getItem(key) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple items at once
|
||||
*/
|
||||
export function getItems(keys: string[]): Record<string, string | null> {
|
||||
const result: Record<string, string | null> = {};
|
||||
for (const key of keys) {
|
||||
result[key] = getItem(key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set multiple items at once
|
||||
*/
|
||||
export function setItems(items: Record<string, string>): boolean {
|
||||
let allSuccessful = true;
|
||||
for (const [key, value] of Object.entries(items)) {
|
||||
if (!setItem(key, value)) {
|
||||
allSuccessful = false;
|
||||
}
|
||||
}
|
||||
return allSuccessful;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove multiple items at once
|
||||
*/
|
||||
export function removeItems(keys: string[]): boolean {
|
||||
let allSuccessful = true;
|
||||
for (const key of keys) {
|
||||
if (!removeItem(key)) {
|
||||
allSuccessful = false;
|
||||
}
|
||||
}
|
||||
return allSuccessful;
|
||||
}
|
||||
Reference in New Issue
Block a user