riksdagsmonitor 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +999 -0
- package/SECURITY.md +154 -0
- package/dist/lib/chart-factory.d.ts +45 -0
- package/dist/lib/chart-factory.d.ts.map +1 -0
- package/dist/lib/chart-factory.js +220 -0
- package/dist/lib/chart-factory.js.map +1 -0
- package/dist/lib/data-loader.d.ts +44 -0
- package/dist/lib/data-loader.d.ts.map +1 -0
- package/dist/lib/data-loader.js +159 -0
- package/dist/lib/data-loader.js.map +1 -0
- package/dist/lib/dom-utils.d.ts +58 -0
- package/dist/lib/dom-utils.d.ts.map +1 -0
- package/dist/lib/dom-utils.js +153 -0
- package/dist/lib/dom-utils.js.map +1 -0
- package/dist/lib/error-boundary.d.ts +43 -0
- package/dist/lib/error-boundary.d.ts.map +1 -0
- package/dist/lib/error-boundary.js +101 -0
- package/dist/lib/error-boundary.js.map +1 -0
- package/dist/lib/fallback-ui.d.ts +28 -0
- package/dist/lib/fallback-ui.d.ts.map +1 -0
- package/dist/lib/fallback-ui.js +65 -0
- package/dist/lib/fallback-ui.js.map +1 -0
- package/dist/lib/index.d.ts +20 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +20 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/logger.d.ts +19 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +31 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/theme.d.ts +107 -0
- package/dist/lib/theme.d.ts.map +1 -0
- package/dist/lib/theme.js +207 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/lib/types.d.ts +95 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +14 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +140 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Shared/Theme
|
|
3
|
+
* @description Cyberpunk design system theme constants with dark/light mode support.
|
|
4
|
+
* Single source of truth for colors, breakpoints, and typography used across all dashboards.
|
|
5
|
+
*
|
|
6
|
+
* Theme architecture:
|
|
7
|
+
* – `DARK_THEME_COLORS` → Ingress-inspired neon palette (matches html[data-theme="dark"])
|
|
8
|
+
* – `LIGHT_THEME_COLORS` → Professional green palette (matches html[data-theme="light"] / :root)
|
|
9
|
+
* – `THEME_COLORS` → Deprecated constant alias of `DARK_THEME_COLORS` (kept for backwards compatibility; not runtime-resolved)
|
|
10
|
+
*
|
|
11
|
+
* WCAG 2.1 AA compliance:
|
|
12
|
+
* Dark #001a1a / #f0f0f0 → 18.1:1 ✅ Cyan #00d9ff / #001a1a → 9.4:1 ✅
|
|
13
|
+
* Light #f5f5f5 / #1a1a1a → 16.1:1 ✅ Cyan #0077b6 / #f5f5f5 → 5.2:1 ✅
|
|
14
|
+
*
|
|
15
|
+
* @intelligence Visual intelligence presentation standards — cyberpunk design system encoding
|
|
16
|
+
* risk severity (CRITICAL red → LOW green), classification levels, and intelligence hierarchy
|
|
17
|
+
* through consistent color semantics and typography.
|
|
18
|
+
*
|
|
19
|
+
* @business Brand identity infrastructure — the cyberpunk theme is a key differentiator
|
|
20
|
+
* creating instant visual recognition. Design system consistency reduces development cost
|
|
21
|
+
* for new features and ensures professional appearance across all 14 language versions.
|
|
22
|
+
*
|
|
23
|
+
* @marketing Brand consistency engine — ensures every screenshot, embed, and shared
|
|
24
|
+
* visualization carries the distinctive Riksdagsmonitor visual identity. CSS custom
|
|
25
|
+
* properties enable white-label customization for enterprise/B2G clients.
|
|
26
|
+
*/
|
|
27
|
+
import type { ThemeColors, Breakpoints } from './types.js';
|
|
28
|
+
/**
|
|
29
|
+
* Dark cyberpunk theme.
|
|
30
|
+
* Matches CSS custom properties under `html[data-theme="dark"]` in styles.css.
|
|
31
|
+
* All values pass WCAG 2.1 AA (≥ 4.5:1) against the dark background #001a1a.
|
|
32
|
+
*/
|
|
33
|
+
export declare const DARK_THEME_COLORS: ThemeColors;
|
|
34
|
+
/**
|
|
35
|
+
* Light professional theme.
|
|
36
|
+
* Matches CSS custom properties under `html[data-theme="light"]` in styles.css.
|
|
37
|
+
* All values pass WCAG 2.1 AA (≥ 4.5:1) against the light background #f5f5f5.
|
|
38
|
+
*/
|
|
39
|
+
export declare const LIGHT_THEME_COLORS: ThemeColors;
|
|
40
|
+
/**
|
|
41
|
+
* Returns the active ThemeColors based on the current `data-theme` attribute
|
|
42
|
+
* on `<html>`. When the attribute is absent (e.g. before the anti-flash
|
|
43
|
+
* snippet runs), falls back to `prefers-color-scheme` — consistent with the
|
|
44
|
+
* CSS `@media (prefers-color-scheme: dark)` default. Defaults to
|
|
45
|
+
* `DARK_THEME_COLORS` only in SSR / test environments where `document` is
|
|
46
|
+
* undefined; in a browser without `matchMedia` support it defaults to
|
|
47
|
+
* `LIGHT_THEME_COLORS` (matching the CSS `:root` base styles).
|
|
48
|
+
*
|
|
49
|
+
* Call this wherever Chart.js datasets need the current palette, e.g.:
|
|
50
|
+
* ```ts
|
|
51
|
+
* const colors = getActiveThemeColors();
|
|
52
|
+
* chart.data.datasets[0].backgroundColor = colors.cyan;
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function getActiveThemeColors(): ThemeColors;
|
|
56
|
+
/**
|
|
57
|
+
* Cyberpunk (dark) theme color palette — kept as the default export for
|
|
58
|
+
* backwards compatibility with existing Chart.js consumers.
|
|
59
|
+
*
|
|
60
|
+
* @deprecated Prefer `getActiveThemeColors()` which returns the correct palette for the
|
|
61
|
+
* current `data-theme` value. Migration:
|
|
62
|
+
* ```ts
|
|
63
|
+
* // Before
|
|
64
|
+
* import { THEME_COLORS } from './theme.js';
|
|
65
|
+
* chart.data.datasets[0].borderColor = THEME_COLORS.cyan;
|
|
66
|
+
*
|
|
67
|
+
* // After
|
|
68
|
+
* import { getActiveThemeColors } from './theme.js';
|
|
69
|
+
* chart.data.datasets[0].borderColor = getActiveThemeColors().cyan;
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare const THEME_COLORS: ThemeColors;
|
|
73
|
+
/**
|
|
74
|
+
* Responsive breakpoints (mobile-first, in px).
|
|
75
|
+
*/
|
|
76
|
+
export declare const BREAKPOINTS: Breakpoints;
|
|
77
|
+
/**
|
|
78
|
+
* Chart color palette for sequential data series (dark theme).
|
|
79
|
+
*/
|
|
80
|
+
export declare const CHART_PALETTE: readonly [string, string, string, string, string, string, string, string];
|
|
81
|
+
/**
|
|
82
|
+
* Chart color palette for sequential data series (light theme).
|
|
83
|
+
*/
|
|
84
|
+
export declare const CHART_PALETTE_LIGHT: readonly [string, string, string, string, string, string, string, string];
|
|
85
|
+
/**
|
|
86
|
+
* Returns the appropriate chart palette for the current theme.
|
|
87
|
+
*/
|
|
88
|
+
export declare function getChartPalette(): readonly string[];
|
|
89
|
+
/**
|
|
90
|
+
* Get party color by party abbreviation.
|
|
91
|
+
* Party colors are theme-invariant (official brand colours).
|
|
92
|
+
* Falls back to the active theme's cyan for unknown parties.
|
|
93
|
+
*/
|
|
94
|
+
export declare function getPartyColor(party: string): string;
|
|
95
|
+
/**
|
|
96
|
+
* Subscribe to theme changes and invoke the callback with the new ThemeColors.
|
|
97
|
+
* Returns an unsubscribe function.
|
|
98
|
+
*
|
|
99
|
+
* ```ts
|
|
100
|
+
* const unsub = onThemeChange((colors) => {
|
|
101
|
+
* chart.data.datasets[0].backgroundColor = colors.cyan;
|
|
102
|
+
* chart.update();
|
|
103
|
+
* });
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export declare function onThemeChange(callback: (colors: ThemeColors) => void): () => void;
|
|
107
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/browser/shared/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAiB3D;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,WActB,CAAC;AAIX;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAcvB,CAAC;AAIX;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,IAAI,WAAW,CAWlD;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,EAAE,WAA+B,CAAC;AAI3D;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,WAKhB,CAAC;AAIX;;GAEG;AACH,eAAO,MAAM,aAAa,2EAShB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,mBAAmB,2EAStB,CAAC;AAEX;;GAEG;AACH,wBAAgB,eAAe,IAAI,SAAS,MAAM,EAAE,CAInD;AAID;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GACtC,MAAM,IAAI,CAeZ"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Shared/Theme
|
|
3
|
+
* @description Cyberpunk design system theme constants with dark/light mode support.
|
|
4
|
+
* Single source of truth for colors, breakpoints, and typography used across all dashboards.
|
|
5
|
+
*
|
|
6
|
+
* Theme architecture:
|
|
7
|
+
* – `DARK_THEME_COLORS` → Ingress-inspired neon palette (matches html[data-theme="dark"])
|
|
8
|
+
* – `LIGHT_THEME_COLORS` → Professional green palette (matches html[data-theme="light"] / :root)
|
|
9
|
+
* – `THEME_COLORS` → Deprecated constant alias of `DARK_THEME_COLORS` (kept for backwards compatibility; not runtime-resolved)
|
|
10
|
+
*
|
|
11
|
+
* WCAG 2.1 AA compliance:
|
|
12
|
+
* Dark #001a1a / #f0f0f0 → 18.1:1 ✅ Cyan #00d9ff / #001a1a → 9.4:1 ✅
|
|
13
|
+
* Light #f5f5f5 / #1a1a1a → 16.1:1 ✅ Cyan #0077b6 / #f5f5f5 → 5.2:1 ✅
|
|
14
|
+
*
|
|
15
|
+
* @intelligence Visual intelligence presentation standards — cyberpunk design system encoding
|
|
16
|
+
* risk severity (CRITICAL red → LOW green), classification levels, and intelligence hierarchy
|
|
17
|
+
* through consistent color semantics and typography.
|
|
18
|
+
*
|
|
19
|
+
* @business Brand identity infrastructure — the cyberpunk theme is a key differentiator
|
|
20
|
+
* creating instant visual recognition. Design system consistency reduces development cost
|
|
21
|
+
* for new features and ensures professional appearance across all 14 language versions.
|
|
22
|
+
*
|
|
23
|
+
* @marketing Brand consistency engine — ensures every screenshot, embed, and shared
|
|
24
|
+
* visualization carries the distinctive Riksdagsmonitor visual identity. CSS custom
|
|
25
|
+
* properties enable white-label customization for enterprise/B2G clients.
|
|
26
|
+
*/
|
|
27
|
+
/* ── Party colour palette (theme-invariant) ─────────────────────────────── */
|
|
28
|
+
const PARTY_COLORS = {
|
|
29
|
+
S: '#E8112d',
|
|
30
|
+
M: '#52BDEC',
|
|
31
|
+
SD: '#DDDD00',
|
|
32
|
+
C: '#009933',
|
|
33
|
+
V: '#DA291C',
|
|
34
|
+
KD: '#000077',
|
|
35
|
+
L: '#006AB3',
|
|
36
|
+
MP: '#83CF39',
|
|
37
|
+
};
|
|
38
|
+
/* ── Dark theme (Ingress-inspired, neon) ────────────────────────────────── */
|
|
39
|
+
/**
|
|
40
|
+
* Dark cyberpunk theme.
|
|
41
|
+
* Matches CSS custom properties under `html[data-theme="dark"]` in styles.css.
|
|
42
|
+
* All values pass WCAG 2.1 AA (≥ 4.5:1) against the dark background #001a1a.
|
|
43
|
+
*/
|
|
44
|
+
export const DARK_THEME_COLORS = {
|
|
45
|
+
cyan: '#00d9ff', // 9.4:1 on #001a1a ✅
|
|
46
|
+
magenta: '#ff006e',
|
|
47
|
+
yellow: '#ffbe0b',
|
|
48
|
+
green: '#06d6a0',
|
|
49
|
+
orange: '#fb8500',
|
|
50
|
+
purple: '#bd93f9',
|
|
51
|
+
red: '#ef476f',
|
|
52
|
+
blue: '#58a6ff',
|
|
53
|
+
tooltipBg: 'rgba(10, 14, 39, 0.95)',
|
|
54
|
+
bodyText: '#e0e0e0',
|
|
55
|
+
tickColor: '#a0a0a0',
|
|
56
|
+
gridColor: 'rgba(255,255,255,0.07)',
|
|
57
|
+
parties: PARTY_COLORS,
|
|
58
|
+
};
|
|
59
|
+
/* ── Light theme (professional green) ──────────────────────────────────── */
|
|
60
|
+
/**
|
|
61
|
+
* Light professional theme.
|
|
62
|
+
* Matches CSS custom properties under `html[data-theme="light"]` in styles.css.
|
|
63
|
+
* All values pass WCAG 2.1 AA (≥ 4.5:1) against the light background #f5f5f5.
|
|
64
|
+
*/
|
|
65
|
+
export const LIGHT_THEME_COLORS = {
|
|
66
|
+
cyan: '#0077b6', // 5.2:1 on #f5f5f5 ✅ (--primary-cyan light per spec)
|
|
67
|
+
magenta: '#c2185b',
|
|
68
|
+
yellow: '#b35a00', // accessible amber
|
|
69
|
+
green: '#006633',
|
|
70
|
+
orange: '#cc5200',
|
|
71
|
+
purple: '#7B2CBF',
|
|
72
|
+
red: '#DC3545',
|
|
73
|
+
blue: '#007744',
|
|
74
|
+
tooltipBg: 'rgba(245, 245, 245, 0.95)',
|
|
75
|
+
bodyText: '#1a1e3d',
|
|
76
|
+
tickColor: '#555555',
|
|
77
|
+
gridColor: 'rgba(0,0,0,0.08)',
|
|
78
|
+
parties: PARTY_COLORS,
|
|
79
|
+
};
|
|
80
|
+
/* ── Runtime theme resolution ───────────────────────────────────────────── */
|
|
81
|
+
/**
|
|
82
|
+
* Returns the active ThemeColors based on the current `data-theme` attribute
|
|
83
|
+
* on `<html>`. When the attribute is absent (e.g. before the anti-flash
|
|
84
|
+
* snippet runs), falls back to `prefers-color-scheme` — consistent with the
|
|
85
|
+
* CSS `@media (prefers-color-scheme: dark)` default. Defaults to
|
|
86
|
+
* `DARK_THEME_COLORS` only in SSR / test environments where `document` is
|
|
87
|
+
* undefined; in a browser without `matchMedia` support it defaults to
|
|
88
|
+
* `LIGHT_THEME_COLORS` (matching the CSS `:root` base styles).
|
|
89
|
+
*
|
|
90
|
+
* Call this wherever Chart.js datasets need the current palette, e.g.:
|
|
91
|
+
* ```ts
|
|
92
|
+
* const colors = getActiveThemeColors();
|
|
93
|
+
* chart.data.datasets[0].backgroundColor = colors.cyan;
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export function getActiveThemeColors() {
|
|
97
|
+
if (typeof document === 'undefined')
|
|
98
|
+
return DARK_THEME_COLORS; // SSR / test guard
|
|
99
|
+
const theme = document.documentElement.getAttribute('data-theme');
|
|
100
|
+
if (theme === 'light')
|
|
101
|
+
return LIGHT_THEME_COLORS;
|
|
102
|
+
if (theme === 'dark')
|
|
103
|
+
return DARK_THEME_COLORS;
|
|
104
|
+
// data-theme not set — mirror the CSS prefers-color-scheme behaviour
|
|
105
|
+
if (typeof window !== 'undefined' && window.matchMedia &&
|
|
106
|
+
window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
107
|
+
return DARK_THEME_COLORS;
|
|
108
|
+
}
|
|
109
|
+
return LIGHT_THEME_COLORS;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Cyberpunk (dark) theme color palette — kept as the default export for
|
|
113
|
+
* backwards compatibility with existing Chart.js consumers.
|
|
114
|
+
*
|
|
115
|
+
* @deprecated Prefer `getActiveThemeColors()` which returns the correct palette for the
|
|
116
|
+
* current `data-theme` value. Migration:
|
|
117
|
+
* ```ts
|
|
118
|
+
* // Before
|
|
119
|
+
* import { THEME_COLORS } from './theme.js';
|
|
120
|
+
* chart.data.datasets[0].borderColor = THEME_COLORS.cyan;
|
|
121
|
+
*
|
|
122
|
+
* // After
|
|
123
|
+
* import { getActiveThemeColors } from './theme.js';
|
|
124
|
+
* chart.data.datasets[0].borderColor = getActiveThemeColors().cyan;
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export const THEME_COLORS = DARK_THEME_COLORS;
|
|
128
|
+
/* ── Breakpoints ────────────────────────────────────────────────────────── */
|
|
129
|
+
/**
|
|
130
|
+
* Responsive breakpoints (mobile-first, in px).
|
|
131
|
+
*/
|
|
132
|
+
export const BREAKPOINTS = {
|
|
133
|
+
mobile: 320,
|
|
134
|
+
tablet: 768,
|
|
135
|
+
desktop: 1024,
|
|
136
|
+
large: 1440,
|
|
137
|
+
};
|
|
138
|
+
/* ── Chart palettes ─────────────────────────────────────────────────────── */
|
|
139
|
+
/**
|
|
140
|
+
* Chart color palette for sequential data series (dark theme).
|
|
141
|
+
*/
|
|
142
|
+
export const CHART_PALETTE = [
|
|
143
|
+
DARK_THEME_COLORS.cyan,
|
|
144
|
+
DARK_THEME_COLORS.magenta,
|
|
145
|
+
DARK_THEME_COLORS.yellow,
|
|
146
|
+
DARK_THEME_COLORS.green,
|
|
147
|
+
DARK_THEME_COLORS.orange,
|
|
148
|
+
DARK_THEME_COLORS.purple,
|
|
149
|
+
DARK_THEME_COLORS.red,
|
|
150
|
+
DARK_THEME_COLORS.blue,
|
|
151
|
+
];
|
|
152
|
+
/**
|
|
153
|
+
* Chart color palette for sequential data series (light theme).
|
|
154
|
+
*/
|
|
155
|
+
export const CHART_PALETTE_LIGHT = [
|
|
156
|
+
LIGHT_THEME_COLORS.cyan,
|
|
157
|
+
LIGHT_THEME_COLORS.magenta,
|
|
158
|
+
LIGHT_THEME_COLORS.yellow,
|
|
159
|
+
LIGHT_THEME_COLORS.green,
|
|
160
|
+
LIGHT_THEME_COLORS.orange,
|
|
161
|
+
LIGHT_THEME_COLORS.purple,
|
|
162
|
+
LIGHT_THEME_COLORS.red,
|
|
163
|
+
LIGHT_THEME_COLORS.blue,
|
|
164
|
+
];
|
|
165
|
+
/**
|
|
166
|
+
* Returns the appropriate chart palette for the current theme.
|
|
167
|
+
*/
|
|
168
|
+
export function getChartPalette() {
|
|
169
|
+
return getActiveThemeColors() === LIGHT_THEME_COLORS
|
|
170
|
+
? CHART_PALETTE_LIGHT
|
|
171
|
+
: CHART_PALETTE;
|
|
172
|
+
}
|
|
173
|
+
/* ── Utilities ──────────────────────────────────────────────────────────── */
|
|
174
|
+
/**
|
|
175
|
+
* Get party color by party abbreviation.
|
|
176
|
+
* Party colors are theme-invariant (official brand colours).
|
|
177
|
+
* Falls back to the active theme's cyan for unknown parties.
|
|
178
|
+
*/
|
|
179
|
+
export function getPartyColor(party) {
|
|
180
|
+
return PARTY_COLORS[party] ?? getActiveThemeColors().cyan;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Subscribe to theme changes and invoke the callback with the new ThemeColors.
|
|
184
|
+
* Returns an unsubscribe function.
|
|
185
|
+
*
|
|
186
|
+
* ```ts
|
|
187
|
+
* const unsub = onThemeChange((colors) => {
|
|
188
|
+
* chart.data.datasets[0].backgroundColor = colors.cyan;
|
|
189
|
+
* chart.update();
|
|
190
|
+
* });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
export function onThemeChange(callback) {
|
|
194
|
+
if (typeof MutationObserver === 'undefined' || typeof document === 'undefined')
|
|
195
|
+
return () => { };
|
|
196
|
+
const observer = new MutationObserver((mutations) => {
|
|
197
|
+
for (const m of mutations) {
|
|
198
|
+
if (m.attributeName === 'data-theme') {
|
|
199
|
+
callback(getActiveThemeColors());
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
observer.observe(document.documentElement, { attributes: true });
|
|
205
|
+
return () => observer.disconnect();
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/browser/shared/theme.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Shared/Types
|
|
3
|
+
* @description Core type definitions for Riksdagsmonitor browser modules.
|
|
4
|
+
* Provides shared interfaces for chart configuration, data loading, and dashboard components.
|
|
5
|
+
|
|
6
|
+
*
|
|
7
|
+
* @intelligence Intelligence domain type system — canonical data models for political entities (MPs, parties, coalitions, voting records), risk scoring dimensions, and intelligence product schemas. Ensures type-safe data flow from CIA Platform CSV exports through analysis pipelines to visualization output.
|
|
8
|
+
*
|
|
9
|
+
* @business Developer experience investment — strong typing reduces integration bugs, accelerates onboarding for contributors, and makes the API surface self-documenting. Critical for future developer ecosystem (API consumers, plugin authors, third-party integrations).
|
|
10
|
+
*
|
|
11
|
+
* @marketing Technical credibility asset — TypeScript type definitions demonstrate engineering maturity to technical audiences (CTOs, developers, open-source community). Publishable as npm types package for ecosystem growth.
|
|
12
|
+
* */
|
|
13
|
+
export interface ThemeColors {
|
|
14
|
+
readonly cyan: string;
|
|
15
|
+
readonly magenta: string;
|
|
16
|
+
readonly yellow: string;
|
|
17
|
+
readonly green: string;
|
|
18
|
+
readonly orange: string;
|
|
19
|
+
readonly purple: string;
|
|
20
|
+
readonly red: string;
|
|
21
|
+
readonly blue: string;
|
|
22
|
+
readonly tooltipBg: string;
|
|
23
|
+
readonly bodyText: string;
|
|
24
|
+
/** Muted color for chart axis tick labels. */
|
|
25
|
+
readonly tickColor: string;
|
|
26
|
+
/** Color for chart grid lines (semi-transparent). */
|
|
27
|
+
readonly gridColor: string;
|
|
28
|
+
readonly parties: Readonly<Record<string, string>>;
|
|
29
|
+
}
|
|
30
|
+
export interface Breakpoints {
|
|
31
|
+
readonly mobile: number;
|
|
32
|
+
readonly tablet: number;
|
|
33
|
+
readonly desktop: number;
|
|
34
|
+
readonly large: number;
|
|
35
|
+
}
|
|
36
|
+
export interface ChartOptions {
|
|
37
|
+
responsive?: boolean;
|
|
38
|
+
maintainAspectRatio?: boolean;
|
|
39
|
+
animation?: boolean | {
|
|
40
|
+
duration: number;
|
|
41
|
+
};
|
|
42
|
+
plugins?: Record<string, unknown>;
|
|
43
|
+
scales?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
export interface DataSource {
|
|
46
|
+
/** Primary URL (local/relative) */
|
|
47
|
+
primary: string;
|
|
48
|
+
/** Fallback URLs (remote CDN, GitHub raw, etc.) */
|
|
49
|
+
fallbacks?: string[];
|
|
50
|
+
}
|
|
51
|
+
export interface LoadOptions {
|
|
52
|
+
/** Cache key for localStorage caching */
|
|
53
|
+
cacheKey?: string;
|
|
54
|
+
/** Cache TTL in milliseconds (default: 7 days) */
|
|
55
|
+
cacheTTL?: number;
|
|
56
|
+
/** Number of retry attempts (default: 3) */
|
|
57
|
+
retries?: number;
|
|
58
|
+
/** Retry backoff in milliseconds (default: 2000) */
|
|
59
|
+
retryBackoff?: number;
|
|
60
|
+
/** Parse as CSV using d3.csvParse (default: false) */
|
|
61
|
+
parseCSV?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface LoadResult<T> {
|
|
64
|
+
data: T;
|
|
65
|
+
source: 'cache' | 'network';
|
|
66
|
+
url: string;
|
|
67
|
+
}
|
|
68
|
+
export interface DashboardModule {
|
|
69
|
+
/** Initialize the dashboard, finding its DOM container and loading data */
|
|
70
|
+
init(): Promise<void>;
|
|
71
|
+
/** Optional cleanup/destroy */
|
|
72
|
+
destroy?(): void;
|
|
73
|
+
}
|
|
74
|
+
export interface DashboardConfig {
|
|
75
|
+
/** CSS selector for the dashboard container */
|
|
76
|
+
containerId: string;
|
|
77
|
+
/** Data sources for the dashboard */
|
|
78
|
+
dataSources: DataSource[];
|
|
79
|
+
/** Whether to show loading state on init */
|
|
80
|
+
showLoading?: boolean;
|
|
81
|
+
}
|
|
82
|
+
export interface CSVRow {
|
|
83
|
+
[key: string]: string;
|
|
84
|
+
}
|
|
85
|
+
export interface NewsArticleMetadata {
|
|
86
|
+
slug: string;
|
|
87
|
+
date: string;
|
|
88
|
+
type: string;
|
|
89
|
+
languages: string[];
|
|
90
|
+
title: Record<string, string>;
|
|
91
|
+
description: Record<string, string>;
|
|
92
|
+
section: string;
|
|
93
|
+
author: string;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/browser/shared/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Shared/Types
|
|
3
|
+
* @description Core type definitions for Riksdagsmonitor browser modules.
|
|
4
|
+
* Provides shared interfaces for chart configuration, data loading, and dashboard components.
|
|
5
|
+
|
|
6
|
+
*
|
|
7
|
+
* @intelligence Intelligence domain type system — canonical data models for political entities (MPs, parties, coalitions, voting records), risk scoring dimensions, and intelligence product schemas. Ensures type-safe data flow from CIA Platform CSV exports through analysis pipelines to visualization output.
|
|
8
|
+
*
|
|
9
|
+
* @business Developer experience investment — strong typing reduces integration bugs, accelerates onboarding for contributors, and makes the API surface self-documenting. Critical for future developer ecosystem (API consumers, plugin authors, third-party integrations).
|
|
10
|
+
*
|
|
11
|
+
* @marketing Technical credibility asset — TypeScript type definitions demonstrate engineering maturity to technical audiences (CTOs, developers, open-source community). Publishable as npm types package for ecosystem growth.
|
|
12
|
+
* */
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/browser/shared/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;KAWK"}
|
package/package.json
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "riksdagsmonitor",
|
|
3
|
+
"version": "0.8.5",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Swedish Parliament Intelligence Platform - Monitor political activity with systematic transparency",
|
|
6
|
+
"main": "dist/lib/index.js",
|
|
7
|
+
"types": "dist/lib/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/lib/index.js",
|
|
11
|
+
"types": "./dist/lib/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/lib",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"SECURITY.md"
|
|
19
|
+
],
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public",
|
|
22
|
+
"provenance": true,
|
|
23
|
+
"registry": "https://registry.npmjs.org/"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dev": "vite",
|
|
27
|
+
"prebuild": "npx tsx scripts/generate-news-indexes/index.ts && npx tsx scripts/extract-news-metadata.ts && npx tsx scripts/generate-sitemap-html.ts && npx tsx scripts/generate-rss.ts && npx tsx scripts/generate-sitemap.ts",
|
|
28
|
+
"build": "vite build",
|
|
29
|
+
"build:lib": "tsc -p tsconfig.lib.json",
|
|
30
|
+
"postbuild": "cp rss.xml dist/rss.xml && cp sitemap.xml dist/sitemap.xml",
|
|
31
|
+
"preview": "vite preview",
|
|
32
|
+
"test": "NODE_OPTIONS='--max-old-space-size=2048' vitest run",
|
|
33
|
+
"test:watch": "vitest",
|
|
34
|
+
"test:ui": "vitest --ui",
|
|
35
|
+
"test:coverage": "vitest run --coverage",
|
|
36
|
+
"cypress:open": "cypress open",
|
|
37
|
+
"cypress:run": "cypress run --config video=false",
|
|
38
|
+
"cypress:run:fast": "cypress run --config video=false --quiet --browser chrome",
|
|
39
|
+
"cypress:run:critical": "cypress run --spec 'cypress/e2e/homepage.cy.js,cypress/e2e/accessibility.cy.js' --config video=false",
|
|
40
|
+
"e2e": "npm run build && start-server-and-test preview http://localhost:4173 cypress:run",
|
|
41
|
+
"e2e:fast": "npm run build && start-server-and-test preview http://localhost:4173 cypress:run:fast",
|
|
42
|
+
"sync-schemas": "npx tsx scripts/sync-cia-schemas.ts",
|
|
43
|
+
"validate-data": "npx tsx scripts/validate-against-cia-schemas.ts",
|
|
44
|
+
"check-updates": "npx tsx scripts/check-cia-schema-updates.ts",
|
|
45
|
+
"generate-types": "npx tsx scripts/generate-types-from-cia-schemas.ts",
|
|
46
|
+
"validate-translations": "npx tsx scripts/validate-translations.ts",
|
|
47
|
+
"validate-news": "node scripts/validate-news-translations.ts",
|
|
48
|
+
"validate-all": "npm run htmlhint && npm run validate-translations && npm run validate-news",
|
|
49
|
+
"generate-news": "node scripts/generate-news-enhanced.ts",
|
|
50
|
+
"generate-news-indexes": "node scripts/generate-news-indexes.ts",
|
|
51
|
+
"generate-sitemap": "node scripts/generate-sitemap.ts",
|
|
52
|
+
"generate-sitemap-html": "npx tsx scripts/generate-sitemap-html.ts",
|
|
53
|
+
"generate-rss": "npx tsx scripts/generate-rss.ts",
|
|
54
|
+
"generate-news-backport": "node scripts/generate-news-backport.ts",
|
|
55
|
+
"htmlhint": "sh -c 'htmlhint *.html; set -- news/*.html; if [ -e \"$1\" ]; then htmlhint \"$@\"; else echo \"No news/*.html files to lint\"; fi'",
|
|
56
|
+
"lint": "eslint .",
|
|
57
|
+
"lint:fix": "eslint . --fix",
|
|
58
|
+
"typedoc": "typedoc",
|
|
59
|
+
"typedoc:validate": "npm run typedoc && vitest run tests/jsdoc-validation.test.js",
|
|
60
|
+
"coverage": "vitest run --coverage",
|
|
61
|
+
"docs:dependencies": "mkdir -p docs/dependencies && (npm list --all --json > docs/dependencies/dependency-tree.json 2> docs/dependencies/dependency-tree.log || true) && (npm list --all > docs/dependencies/dependency-tree.txt 2>> docs/dependencies/dependency-tree.log || true)",
|
|
62
|
+
"docs:diagrams": "echo 'Architecture diagrams generation placeholder - implement with graphviz if needed'",
|
|
63
|
+
"test:e2ereportmerge": "echo 'Cypress report merge placeholder - mochawesome-merge if multi-spec reports exist'",
|
|
64
|
+
"test:e2ereporthtmlall": "echo 'Cypress HTML report generation placeholder - mochawesome-report-generator'",
|
|
65
|
+
"build:test-reports": "mkdir -p docs/test-results docs/cypress docs/coverage && ([ -d builds/coverage ] && [ -n \"$(ls -A builds/coverage 2>/dev/null)\" ] && cp -r builds/coverage/* docs/coverage/ || echo 'No coverage directory to copy') && ([ -d builds/test-results ] && [ -n \"$(ls -A builds/test-results 2>/dev/null)\" ] && cp -r builds/test-results/* docs/test-results/ || echo 'No test-results directory to copy') && ([ -d builds/cypress ] && [ -n \"$(ls -A builds/cypress 2>/dev/null)\" ] && cp -r builds/cypress/* docs/cypress/ || echo 'No cypress directory to copy') && echo 'Test reports copied to docs/'",
|
|
66
|
+
"docs:sitemap": "node scripts/generate-sitemap.ts",
|
|
67
|
+
"serve": "python3 -m http.server 8080",
|
|
68
|
+
"linkcheck": "linkinator http://localhost:8080/ --recurse",
|
|
69
|
+
"prepublishOnly": "npm run lint && npm run build:lib && npm test",
|
|
70
|
+
"prepack": "echo 'Prepack: build artifacts should already be generated (see prepublishOnly/CI)'"
|
|
71
|
+
},
|
|
72
|
+
"repository": {
|
|
73
|
+
"type": "git",
|
|
74
|
+
"url": "git+https://github.com/Hack23/riksdagsmonitor.git"
|
|
75
|
+
},
|
|
76
|
+
"keywords": [
|
|
77
|
+
"riksdag",
|
|
78
|
+
"parliament",
|
|
79
|
+
"sweden",
|
|
80
|
+
"politics",
|
|
81
|
+
"osint",
|
|
82
|
+
"transparency",
|
|
83
|
+
"intelligence",
|
|
84
|
+
"chart.js",
|
|
85
|
+
"d3",
|
|
86
|
+
"dashboard",
|
|
87
|
+
"theme",
|
|
88
|
+
"typescript",
|
|
89
|
+
"political-data"
|
|
90
|
+
],
|
|
91
|
+
"author": "Hack23 AB",
|
|
92
|
+
"license": "Apache-2.0",
|
|
93
|
+
"bugs": {
|
|
94
|
+
"url": "https://github.com/Hack23/riksdagsmonitor/issues"
|
|
95
|
+
},
|
|
96
|
+
"homepage": "https://riksdagsmonitor.com",
|
|
97
|
+
"dependencies": {
|
|
98
|
+
"ajv": "^8.18.0",
|
|
99
|
+
"ajv-formats": "^3.0.1",
|
|
100
|
+
"chart.js": "^4.5.1",
|
|
101
|
+
"chartjs-plugin-annotation": "^3.1.0",
|
|
102
|
+
"d3": "^7.9.0",
|
|
103
|
+
"papaparse": "^5.5.3"
|
|
104
|
+
},
|
|
105
|
+
"devDependencies": {
|
|
106
|
+
"@eslint/js": "^10.0.1",
|
|
107
|
+
"@types/d3": "^7.4.3",
|
|
108
|
+
"@types/node": "^25.5.0",
|
|
109
|
+
"@types/papaparse": "^5.5.2",
|
|
110
|
+
"@vitest/coverage-v8": "^4.1.1",
|
|
111
|
+
"@vitest/ui": "^4.0.18",
|
|
112
|
+
"eslint": "^10.1.0",
|
|
113
|
+
"globals": "^17.4.0",
|
|
114
|
+
"happy-dom": "^20.8.7",
|
|
115
|
+
"htmlhint": "^1.9.2",
|
|
116
|
+
"js-yaml": "^4.1.1",
|
|
117
|
+
"json-schema-to-typescript": "^15.0.4",
|
|
118
|
+
"knip": "^6.0.4",
|
|
119
|
+
"playwright": "^1.58.2",
|
|
120
|
+
"start-server-and-test": "^2.1.5",
|
|
121
|
+
"tsx": "^4.21.0",
|
|
122
|
+
"typedoc": "^0.28.18",
|
|
123
|
+
"typedoc-plugin-mdn-links": "^5.1.1",
|
|
124
|
+
"typescript": "^5.9.3",
|
|
125
|
+
"typescript-eslint": "^8.57.2",
|
|
126
|
+
"vite": "^8.0.2",
|
|
127
|
+
"vite-plugin-sri-gen": "^1.3.2",
|
|
128
|
+
"vitest": "^4.0.18",
|
|
129
|
+
"worldbank-mcp": "1.0.1"
|
|
130
|
+
},
|
|
131
|
+
"optionalDependencies": {
|
|
132
|
+
"cypress": "^15.12.0"
|
|
133
|
+
},
|
|
134
|
+
"overrides": {
|
|
135
|
+
"glob": "^13.0.0"
|
|
136
|
+
},
|
|
137
|
+
"engines": {
|
|
138
|
+
"node": ">=25"
|
|
139
|
+
}
|
|
140
|
+
}
|