1// static/js/storage.js 2// Centralized localStorage access with key constants and JSON parse safety 3 4// ââ Key constants ââ 5export const KEYS = { 6 THEME: 'odysseus-theme', 7 TOGGLES: 'odysseus-toggles', 8 SIDEBAR_COLLAPSED: 'sidebar-collapsed', 9 SIDEBAR_WIDTH: 'sidebar-width', 10 SIDEBAR_SIDE: 'sidebar-side', 11 CURRENT_SESSION: 'currentSessionId', 12 COMPARE_SAVE: 'compare-save-results', 13 COMPARE_CHAT: 'compare-continue-chat', 14 COMPARE_BLIND: 'compare-blind', 15 COMPARE_RANDOM: 'compare-randomize', 16 MODELS_EXPANDED: 'odysseus-model-expanded', 17 MODEL_ENDPOINTS: 'odysseus-model-endpoints', 18 MODEL_SELECTED: 'odysseus-selected-model', 19 SORT_ORDER: 'odysseus-sessions-sort', 20 CHAT_SEARCH_SCOPE: 'odysseus-search-scope', 21 INCOGNITO: 'odysseus-incognito', 22 RAG_ACTIVE: 'odysseus-rag-active', 23 MCP_ACTIVE: 'odysseus-mcp-active', 24 SECTION_ORDER: 'sidebar-section-order', 25 ADMIN_LAST_TAB: 'admin-last-tab', 26 DENSITY: 'odysseus-density', 27 UI_SCALE: 'odysseus-ui-scale', 28 WORKSPACE: 'odysseus-workspace' 29}; 30 31/** 32 * Safely get and parse a JSON value from localStorage. 33 * Returns fallback on any error. 34 */ 35export function getJSON(key, fallback) { 36 try { 37 const raw = localStorage.getItem(key); 38 if (raw === null) return fallback !== undefined ? fallback : null; 39 return JSON.parse(raw); 40 } catch (e) { 41 console.warn('[Storage] Failed to parse key "' + key + '":', e.message); 42 return fallback !== undefined ? fallback : null; 43 } 44} 45 46/** 47 * Set a JSON-serialized value in localStorage. 48 */ 49export function setJSON(key, value) { 50 try { 51 localStorage.setItem(key, JSON.stringify(value)); 52 } catch (e) { 53 console.warn('[Storage] Failed to set key "' + key + '":', e.message); 54 } 55} 56 57/** 58 * Get a raw string value from localStorage. 59 */ 60export function get(key, fallback) { 61 try { 62 const val = localStorage.getItem(key); 63 return val !== null ? val : (fallback !== undefined ? fallback : null); 64 } catch (e) { 65 return fallback !== undefined ? fallback : null; 66 } 67} 68 69/** 70 * Set a raw string value in localStorage. 71 */ 72export function set(key, value) { 73 try { 74 localStorage.setItem(key, value); 75 } catch (e) { 76 console.warn('[Storage] Failed to set key "' + key + '":', e.message); 77 } 78} 79 80/** 81 * Remove a key from localStorage. 82 */ 83export function remove(key) { 84 try { 85 localStorage.removeItem(key); 86 } catch (e) { 87 // Ignore removal errors 88 } 89} 90 91// ââ Toggle state helpers ââ 92 93export function loadToggleState() { 94 return getJSON(KEYS.TOGGLES, {}); 95} 96 97export function saveToggleState(state) { 98 setJSON(KEYS.TOGGLES, state); 99} 100 101export function getToggle(name, fallback) { 102 const state = loadToggleState(); 103 return state[name] !== undefined ? state[name] : (fallback !== undefined ? fallback : false); 104} 105 106export function setToggle(name, value) { 107 const state = loadToggleState(); 108 state[name] = value; 109 saveToggleState(state); 110} 111 112const Storage = { 113 KEYS, 114 getJSON, 115 setJSON, 116 get, 117 set, 118 remove, 119 loadToggleState, 120 saveToggleState, 121 getToggle, 122 setToggle 123}; 124 125export default Storage;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.