// Base configuration shared across all variants import type { PanelConfig, MapLayers } from '@/types'; // Shared exports (re-exported by all variants) export { SECTORS, COMMODITIES, MARKET_SYMBOLS } from '../markets'; // UNDERSEA_CABLES + AI_DATA_CENTERS intentionally not re-exported (kept off the // eager @/config barrel); consumers import directly from '@/config/geo-map' and // '@/config/ai-datacenters'. (#4404) export { IDLE_PAUSE_MS } from '../idle'; // Refresh intervals (ms) - shared across all variants export const REFRESH_INTERVALS = { feeds: 20 * 60 * 1000, markets: 12 * 60 * 1000, crypto: 12 * 60 * 1000, predictions: 15 * 60 * 1000, forecasts: 30 * 60 * 1000, ais: 15 * 60 * 1000, pizzint: 10 * 60 * 1000, natural: 60 * 60 * 1000, weather: 10 * 60 * 1000, fred: 6 * 60 * 60 * 1000, oil: 6 * 60 * 60 * 1000, spending: 6 * 60 * 60 * 1000, bis: 6 * 60 * 60 * 1000, firms: 30 * 60 * 1000, cables: 30 * 60 * 1000, cableHealth: 2 * 60 * 60 * 1000, flights: 2 * 60 * 60 * 1000, cyberThreats: 10 * 60 * 1000, stockAnalysis: 15 * 60 * 1000, dailyMarketBrief: 60 * 60 * 1000, marketImplications: 3 * 60 * 60 * 1000, stockBacktest: 4 * 60 * 60 * 1000, serviceStatus: 3 * 60 * 1000, stablecoins: 15 * 60 * 1000, etfFlows: 15 * 60 * 1000, macroSignals: 15 * 60 * 1000, fearGreed: 30 * 60 * 1000, strategicPosture: 15 * 60 * 1000, strategicRisk: 5 * 60 * 1000, // Seed cadences are 6-24h and badge decay is computed client-side from // lastUpdate, so 5min loses nothing vs 60s; must stay under the 15min // FRESH_THRESHOLD or synthesized-OK sources (compact health carries no age // for healthy checks) would decay to stale between polls (#4907). healthFreshness: 5 * 60 * 1000, temporalBaseline: 10 * 60 * 1000, tradePolicy: 60 * 60 * 1000, supplyChain: 60 * 60 * 1000, chinaCorridors: 15 * 60 * 1000, chinaActivityNowcast: 15 * 60 * 1000, telegramIntel: 60 * 1000, gulfEconomies: 10 * 60 * 1000, groceryBasket: 6 * 60 * 60 * 1000, fuelPrices: 6 * 60 * 60 * 1000, faoFoodPriceIndex: 24 * 60 * 60 * 1000, // monthly data; refresh daily is sufficient oilInventories: 5 * 60 * 1000, // EIA weekly + EU gas daily; 5min refresh climateNews: 30 * 60 * 1000, // seeded every 30min; match cadence intelligence: 15 * 60 * 1000, correlationEngine: 5 * 60 * 1000, defensePatents: 24 * 60 * 60 * 1000, // 24h — data is weekly, daily poll is sufficient wsbTickers: 10 * 60 * 1000, crossSourceSignals: 15 * 60 * 1000, hormuzTracker: 60 * 60 * 1000, // 1h — data updates daily hyperliquidFlow: 5 * 60 * 1000, // 5min — matches Railway seed cadence energyCrisis: 6 * 60 * 60 * 1000, // 6h — policy data updates infrequently pipelineStatus: 24 * 60 * 60 * 1000, // curated registry reseeds weekly; daily poll keeps long-lived sessions fresh storageFacilityMap: 24 * 60 * 60 * 1000, // curated registry reseeds weekly; daily poll keeps long-lived sessions fresh fuelShortages: 60 * 60 * 1000, // active shortage alerts can change intra-day energyDisruptions: 60 * 60 * 1000, // disruption log is low-volume but needs intra-day freshness energyRiskOverview: 15 * 60 * 1000, // mixed market + supply-chain overview; refresh more often than the underlying weekly registries chokepointStrip: 90 * 60 * 1000, // matches chokepoint client cache TTL / freshness budget macroTiles: 30 * 60 * 1000, fsi: 30 * 60 * 1000, yieldCurve: 30 * 60 * 1000, earningsCalendar: 60 * 60 * 1000, economicCalendar: 60 * 60 * 1000, cotPositioning: 60 * 60 * 1000, goldIntelligence: 5 * 60 * 1000, aaiiSentiment: 60 * 60 * 1000, // weekly data; hourly refresh is sufficient marketBreadth: 60 * 60 * 1000, // seeded daily; hourly refresh is sufficient }; // Monitor colors - shared export const MONITOR_COLORS = [ '#44ff88', '#ff8844', '#4488ff', '#ff44ff', '#ffff44', '#ff4444', '#44ffff', '#88ff44', '#ff88ff', '#88ffff', ]; // Storage keys - shared export const STORAGE_KEYS = { panels: 'worldmonitor-panels', monitors: 'worldmonitor-monitors', mapLayers: 'worldmonitor-layers', disabledFeeds: 'worldmonitor-disabled-feeds', // Schema version for the disabledFeeds set. Bumped on each migration that // mutates the set in a backwards-incompatible way. Currently: // missing/0 → pre-2026-05-01 alphabetical-cap state. Eligible for // one-time recovery of fully-disabled categories. // 1 → recovery has run; the set is post-migration and must NOT be // re-recovered on subsequent loads (otherwise user-explicit // full-category disabling would be silently undone forever). disabledFeedsSchema: 'worldmonitor-disabled-feeds-schema', // `{ [customCategoryKey]: rotationCycle }`. A custom news category is never // in the per-variant server digest, so its capped per-feed fetch rotates // through its sources a window at a time (#5873). The cycle has to survive a // reload or short sessions would replay window 0 forever and the rotation // would never reach sources 4..N — the exact defect it exists to fix. newsFeedRotation: 'worldmonitor-news-feed-rotation', liveChannels: 'worldmonitor-live-channels', mapMode: 'worldmonitor-map-mode', // 'flat' | 'globe' activeChannel: 'worldmonitor-active-channel', webcamPrefs: 'worldmonitor-webcam-prefs', } as const; export type MapModePreference = 'flat' | 'globe'; export const DEFAULT_MAP_MODE: MapModePreference = 'flat'; // Type definitions for variant configs export interface VariantConfig { name: string; description: string; panels: Record; mapLayers: MapLayers; mobileMapLayers: MapLayers; }