Spaces:
Running
Running
| /** | |
| * Adaptive Tactics - Persistence Layer | |
| * Handles localStorage with graceful fallback to in-memory storage | |
| */ | |
| // In-memory fallback storage | |
| const memoryStorage = new Map(); | |
| // Check if localStorage is available | |
| let storageAvailable = false; | |
| try { | |
| const testKey = '__at_test__'; | |
| localStorage.setItem(testKey, testKey); | |
| localStorage.removeItem(testKey); | |
| storageAvailable = true; | |
| } catch (e) { | |
| console.warn('localStorage not available, using in-memory storage'); | |
| storageAvailable = false; | |
| } | |
| /** | |
| * Save data to storage | |
| * @param {string} key - Storage key | |
| * @param {any} data - Data to store (will be JSON serialized) | |
| * @returns {boolean} Success status | |
| */ | |
| export function save(key, data) { | |
| try { | |
| const serialized = JSON.stringify(data); | |
| if (storageAvailable) { | |
| localStorage.setItem(key, serialized); | |
| } else { | |
| memoryStorage.set(key, serialized); | |
| } | |
| return true; | |
| } catch (e) { | |
| console.error(`Failed to save data for key "${key}":`, e); | |
| return false; | |
| } | |
| } | |
| /** | |
| * Load data from storage | |
| * @param {string} key - Storage key | |
| * @returns {any|null} Parsed data or null if not found | |
| */ | |
| export function load(key) { | |
| try { | |
| let serialized; | |
| if (storageAvailable) { | |
| serialized = localStorage.getItem(key); | |
| } else { | |
| serialized = memoryStorage.get(key); | |
| } | |
| if (serialized === null || serialized === undefined) { | |
| return null; | |
| } | |
| return JSON.parse(serialized); | |
| } catch (e) { | |
| console.error(`Failed to load data for key "${key}":`, e); | |
| return null; | |
| } | |
| } | |
| /** | |
| * Remove data from storage | |
| * @param {string} key - Storage key | |
| * @returns {boolean} Success status | |
| */ | |
| export function remove(key) { | |
| try { | |
| if (storageAvailable) { | |
| localStorage.removeItem(key); | |
| } else { | |
| memoryStorage.delete(key); | |
| } | |
| return true; | |
| } catch (e) { | |
| console.error(`Failed to remove data for key "${key}":`, e); | |
| return false; | |
| } | |
| } | |
| /** | |
| * Clear all game-related storage | |
| * @returns {boolean} Success status | |
| */ | |
| export function clearAll() { | |
| try { | |
| if (storageAvailable) { | |
| // Only clear our keys, not all localStorage | |
| const keysToRemove = []; | |
| for (let i = 0; i < localStorage.length; i++) { | |
| const key = localStorage.key(i); | |
| if (key && key.startsWith('at_')) { | |
| keysToRemove.push(key); | |
| } | |
| } | |
| keysToRemove.forEach(key => localStorage.removeItem(key)); | |
| } else { | |
| memoryStorage.clear(); | |
| } | |
| return true; | |
| } catch (e) { | |
| console.error('Failed to clear storage:', e); | |
| return false; | |
| } | |
| } | |
| /** | |
| * Check if storage is persistent (localStorage) or temporary (memory) | |
| * @returns {boolean} True if using localStorage | |
| */ | |
| export function isPersistent() { | |
| return storageAvailable; | |
| } | |