FarmerHelp / frontend /src /utils /storage.js
Gankit12's picture
All Code
b64de39
Raw
History Blame Contribute Delete
4.37 kB
/**
* LocalStorage wrapper with safe JSON serialization.
*
* All read/write operations are wrapped in try/catch to handle
* environments where localStorage is unavailable (SSR, privacy
* mode, storage quota exceeded, etc.).
*/
// ---------------------------------------------------------------------------
// Availability Check
// ---------------------------------------------------------------------------
/**
* Determine whether localStorage is available and writable.
*
* @returns {boolean}
*/
function isStorageAvailable() {
try {
const testKey = "__storage_test__";
window.localStorage.setItem(testKey, "1");
window.localStorage.removeItem(testKey);
return true;
} catch {
return false;
}
}
const storageAvailable = isStorageAvailable();
// ---------------------------------------------------------------------------
// Core Operations
// ---------------------------------------------------------------------------
/**
* Retrieve a value from localStorage.
*
* @param {string} key - Storage key.
* @param {*} defaultValue - Fallback when the key is absent or unreadable.
* @returns {*} Parsed value or defaultValue.
*/
export function getItem(key, defaultValue = null) {
if (!storageAvailable) {
return defaultValue;
}
try {
const raw = window.localStorage.getItem(key);
if (raw === null) {
return defaultValue;
}
return JSON.parse(raw);
} catch {
return defaultValue;
}
}
/**
* Persist a value to localStorage.
*
* @param {string} key - Storage key.
* @param {*} value - Value to store (will be JSON-serialized).
* @returns {boolean} Whether the write succeeded.
*/
export function setItem(key, value) {
if (!storageAvailable) {
return false;
}
try {
window.localStorage.setItem(key, JSON.stringify(value));
return true;
} catch (err) {
console.error(`[storage] Failed to write key "${key}":`, err);
return false;
}
}
/**
* Remove a key from localStorage.
*
* @param {string} key - Storage key.
* @returns {boolean} Whether the removal succeeded.
*/
export function removeItem(key) {
if (!storageAvailable) {
return false;
}
try {
window.localStorage.removeItem(key);
return true;
} catch {
return false;
}
}
/**
* Clear all FarmHelp-related entries from localStorage.
* Only removes keys that start with "farmhelp_".
*
* @returns {boolean} Whether the operation succeeded.
*/
export function clearAll() {
if (!storageAvailable) {
return false;
}
try {
const keysToRemove = [];
for (let i = 0; i < window.localStorage.length; i++) {
const key = window.localStorage.key(i);
if (key && key.startsWith("farmhelp_")) {
keysToRemove.push(key);
}
}
keysToRemove.forEach((key) => window.localStorage.removeItem(key));
return true;
} catch {
return false;
}
}
// ---------------------------------------------------------------------------
// TTL-Based Cache Operations
// ---------------------------------------------------------------------------
/**
* Store a value with an expiration timestamp.
*
* @param {string} key - Storage key.
* @param {*} value - Value to cache.
* @param {number} ttlMs - Time-to-live in milliseconds.
* @returns {boolean} Whether the write succeeded.
*/
export function setWithTTL(key, value, ttlMs) {
const record = {
value,
expiry: Date.now() + ttlMs,
};
return setItem(key, record);
}
/**
* Retrieve a cached value, returning defaultValue if expired or absent.
*
* @param {string} key - Storage key.
* @param {*} defaultValue - Fallback when expired or absent.
* @returns {*} The cached value or defaultValue.
*/
export function getWithTTL(key, defaultValue = null) {
const record = getItem(key, null);
if (!record || typeof record !== "object" || !record.expiry) {
return defaultValue;
}
if (Date.now() > record.expiry) {
removeItem(key);
return defaultValue;
}
return record.value;
}
// ---------------------------------------------------------------------------
// Convenience Export
// ---------------------------------------------------------------------------
const storage = {
get: getItem,
set: setItem,
remove: removeItem,
clearAll,
setWithTTL,
getWithTTL,
};
export default storage;