196 lines
No EOL
4.8 KiB
JavaScript
196 lines
No EOL
4.8 KiB
JavaScript
import { STORAGE_KEY, DEFAULT_HISTORY_DAYS, CACHE_TTL } from '../utils/constants';
|
|
|
|
/**
|
|
* Get the storage object from localStorage
|
|
* @returns {Object} The storage object
|
|
*/
|
|
function getStorage() {
|
|
try {
|
|
const stored = localStorage.getItem(STORAGE_KEY);
|
|
return stored ? JSON.parse(stored) : { briefings: {}, cache: {} };
|
|
} catch (error) {
|
|
console.error('Error reading from localStorage:', error);
|
|
return { briefings: {}, cache: {} };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save the storage object to localStorage
|
|
* @param {Object} storage - The storage object to save
|
|
*/
|
|
function saveStorage(storage) {
|
|
try {
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(storage));
|
|
} catch (error) {
|
|
console.error('Error saving to localStorage:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save today's briefing with condensed summary
|
|
* @param {string} date - Date in YYYY-MM-DD format
|
|
* @param {string} briefingText - The generated briefing text
|
|
* @param {Object} sourceData - Raw data from all sources
|
|
* @param {string} condensedSummary - Condensed summary for historical context (optional)
|
|
*/
|
|
export function saveBriefing(date, briefingText, sourceData, condensedSummary = null) {
|
|
const storage = getStorage();
|
|
|
|
storage.briefings[date] = {
|
|
timestamp: Date.now(),
|
|
briefing: briefingText,
|
|
sources: sourceData,
|
|
condensedSummary: condensedSummary // Store condensed version for historical lookups
|
|
};
|
|
|
|
saveStorage(storage);
|
|
|
|
// Clean up old data after saving
|
|
cleanupOldData();
|
|
}
|
|
|
|
/**
|
|
* Get a previous briefing
|
|
* @param {number} daysAgo - How many days ago
|
|
* @returns {Object|null} The briefing object or null if not found
|
|
*/
|
|
export function getPreviousBriefing(daysAgo = 1) {
|
|
const storage = getStorage();
|
|
const date = new Date();
|
|
date.setDate(date.getDate() - daysAgo);
|
|
const dateKey = date.toISOString().split('T')[0];
|
|
|
|
return storage.briefings[dateKey] || null;
|
|
}
|
|
|
|
/**
|
|
* Cache fetched source data with timestamp
|
|
* @param {string} sourceKey - Unique key for the source
|
|
* @param {any} data - Data to cache
|
|
* @param {number} ttlMinutes - Time to live in minutes
|
|
*/
|
|
export function cacheSourceData(sourceKey, data, ttlMinutes = CACHE_TTL) {
|
|
const storage = getStorage();
|
|
|
|
storage.cache[sourceKey] = {
|
|
data: data,
|
|
timestamp: Date.now(),
|
|
ttl: ttlMinutes * 60 * 1000 // Convert to milliseconds
|
|
};
|
|
|
|
saveStorage(storage);
|
|
}
|
|
|
|
/**
|
|
* Get cached data if still fresh
|
|
* @param {string} sourceKey - Unique key for the source
|
|
* @returns {any|null} Cached data or null if expired/not found
|
|
*/
|
|
export function getCachedData(sourceKey) {
|
|
const storage = getStorage();
|
|
const cached = storage.cache[sourceKey];
|
|
|
|
if (!cached) {
|
|
return null;
|
|
}
|
|
|
|
const now = Date.now();
|
|
const age = now - cached.timestamp;
|
|
|
|
if (age > cached.ttl) {
|
|
// Cache expired
|
|
delete storage.cache[sourceKey];
|
|
saveStorage(storage);
|
|
return null;
|
|
}
|
|
|
|
return cached.data;
|
|
}
|
|
|
|
/**
|
|
* Clean up old data (keep only last N days)
|
|
* @param {number} daysToKeep - Number of days to keep
|
|
*/
|
|
export function cleanupOldData(daysToKeep = null) {
|
|
const storage = getStorage();
|
|
const days = daysToKeep || parseInt(import.meta.env.REACT_APP_HISTORY_DAYS) || DEFAULT_HISTORY_DAYS;
|
|
|
|
const cutoffDate = new Date();
|
|
cutoffDate.setDate(cutoffDate.getDate() - days);
|
|
|
|
// Clean old briefings
|
|
if (storage.briefings) {
|
|
Object.keys(storage.briefings).forEach(date => {
|
|
if (new Date(date) < cutoffDate) {
|
|
delete storage.briefings[date];
|
|
}
|
|
});
|
|
}
|
|
|
|
// Clean expired cache entries
|
|
const now = Date.now();
|
|
if (storage.cache) {
|
|
Object.keys(storage.cache).forEach(key => {
|
|
const cached = storage.cache[key];
|
|
if (cached && (now - cached.timestamp) > cached.ttl) {
|
|
delete storage.cache[key];
|
|
}
|
|
});
|
|
}
|
|
|
|
saveStorage(storage);
|
|
}
|
|
|
|
/**
|
|
* Export all data for debugging
|
|
* @returns {Object} All stored data
|
|
*/
|
|
export function exportAllData() {
|
|
return getStorage();
|
|
}
|
|
|
|
/**
|
|
* Import dummy data (dev mode)
|
|
* @param {Object} jsonData - Data to import
|
|
*/
|
|
export function importDummyData(jsonData) {
|
|
if (jsonData && typeof jsonData === 'object') {
|
|
saveStorage(jsonData);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear all stored data
|
|
*/
|
|
export function clearAllData() {
|
|
localStorage.removeItem(STORAGE_KEY);
|
|
}
|
|
|
|
/**
|
|
* Get all briefings
|
|
* @returns {Object} All briefings
|
|
*/
|
|
export function getAllBriefings() {
|
|
const storage = getStorage();
|
|
return storage.briefings || {};
|
|
}
|
|
|
|
/**
|
|
* Check if we have a briefing for today
|
|
* @returns {boolean} True if today's briefing exists
|
|
*/
|
|
export function hasTodaysBriefing() {
|
|
const storage = getStorage();
|
|
const today = new Date().toISOString().split('T')[0];
|
|
return !!storage.briefings[today];
|
|
}
|
|
|
|
/**
|
|
* Get today's briefing
|
|
* @returns {Object|null} Today's briefing or null
|
|
*/
|
|
export function getTodaysBriefing() {
|
|
const storage = getStorage();
|
|
const today = new Date().toISOString().split('T')[0];
|
|
return storage.briefings[today] || null;
|
|
} |