All files / src/browser main.ts

0% Statements 0/20
0% Branches 0/4
0% Functions 0/5
0% Lines 0/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                                                                                                                                                                                           
/**
 * @module Main
 * @description Single entry point for main Riksdagsmonitor pages (index*.html).
 * Replaces 18 individual script tags with one module import.
 *
 * Each dashboard is initialized independently — if one fails, others continue.
 * Libraries (Chart.js, D3) are imported via Vite bundling from npm packages.
 
 *
 * @intelligence Central intelligence platform orchestrator — coordinates 12 analytical dashboards covering OSINT data acquisition, political risk assessment, coalition dynamics, electoral forecasting, and behavioral anomaly detection across 349 Swedish MPs and 8 parties.
 *
 * @business Core platform entry point delivering the primary user value proposition: comprehensive political transparency as a service. Each successfully loaded dashboard directly increases user engagement time (target: 8+ min average session), driving conversion from casual visitors to regular users and API subscribers.
 *
 * @marketing Landing page intelligence showcase — first impression for all 5 target audiences (citizens, journalists, researchers, NGOs, corporations). Each dashboard module is a demonstrable feature for content marketing, social media screenshots, and press coverage. Supports 14-language SEO via separate index files.
 * */
 
// ─── Library Imports (Vite bundles these from node_modules) ──────────────────
// Register Chart.js, D3.js, and Papa Parse on globalThis so dashboard modules can access them.
// Must be imported before any dashboard module that reads (globalThis as any).Chart / .d3 / .Papa.
import './shared/register-globals.js';
 
// ─── UI Components ───────────────────────────────────────────────────────────
import { initBackToTop } from './ui/back-to-top.js';
 
// ─── Dashboard Modules ──────────────────────────────────────────────────────
import { init as initStats } from './dashboards/stats-loader.js';
import { init as initRisk } from './dashboards/risk-dashboard.js';
import { init as initParty } from './dashboards/party-dashboard.js';
import { init as initMinistry } from './dashboards/ministry-dashboard.js';
import { init as initCoalitionLoader } from './dashboards/coalition-loader.js';
import { init as initCoalitionDashboard } from './dashboards/coalition-dashboard.js';
import { init as initCommittees } from './dashboards/committees-dashboard.js';
import { init as initElectionCycle } from './dashboards/election-cycle.js';
import { init as initSeasonalPatterns } from './dashboards/seasonal-patterns.js';
import { init as initPreElection } from './dashboards/pre-election.js';
import { init as initAnomalyDetection } from './dashboards/anomaly-detection.js';
import { init as initPolitician } from './dashboards/politician-dashboard.js';
 
import { logger } from './shared/logger.js';
 
// ─── Dashboard Registry ─────────────────────────────────────────────────────
// Each entry: [name, init function]
// Order matters for perceived loading (stats & risk first as they're above the fold)
const DASHBOARDS: Array<[string, () => Promise<void>]> = [
  ['stats', initStats],
  ['risk', initRisk],
  ['coalition-loader', initCoalitionLoader],
  ['party', initParty],
  ['coalition-dashboard', initCoalitionDashboard],
  ['committees', initCommittees],
  ['ministry', initMinistry],
  ['election-cycle', initElectionCycle],
  ['seasonal-patterns', initSeasonalPatterns],
  ['pre-election', initPreElection],
  ['anomaly-detection', initAnomalyDetection],
  ['politician', initPolitician],
];
 
// ─── Initialization ─────────────────────────────────────────────────────────
 
async function initAll(): Promise<void> {
  logger.info('Riksdagsmonitor initializing...');
  const start = performance.now();
 
  // Init UI components (sync, fast)
  initBackToTop();
 
  // Init dashboards in parallel — each is independent
  const results = await Promise.allSettled(
    DASHBOARDS.map(async ([name, initFn]) => {
      try {
        await initFn();
        logger.debug(`✓ ${name} initialized`);
      } catch (error) {
        logger.error(`✗ ${name} failed:`, error);
        throw error;
      }
    }),
  );
 
  const succeeded = results.filter((r) => r.status === 'fulfilled').length;
  const failed = results.filter((r) => r.status === 'rejected').length;
  const elapsed = (performance.now() - start).toFixed(0);
 
  logger.info(`Initialized ${succeeded}/${DASHBOARDS.length} dashboards in ${elapsed}ms${failed > 0 ? ` (${failed} failed)` : ''}`);
}
 
// Wait for DOM then initialize
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', () => void initAll());
} else {
  void initAll();
}