File size: 5,696 Bytes
9d2d895 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | // 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<string, PanelConfig>;
mapLayers: MapLayers;
mobileMapLayers: MapLayers;
}
|