Files
the-nexus/modules/data/loaders.js
Alexander Whitestone 98826eb597
Some checks failed
CI / validate (pull_request) Failing after 18s
CI / auto-merge (pull_request) Has been skipped
refactor: move portal health fetch into data/loaders.js
Extracts the portal URL probe (fetch) from modules/weather.js into
modules/data/loaders.checkPortalHealth(). This is the last fetch()
call outside of modules/data/, satisfying the Phase 2 data-layer rule.

modules/weather.js now delegates health probing to the data module
and retains only the visual update logic (opacity, rune ring).

Fixes #411

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 18:11:59 -04:00

65 lines
1.9 KiB
JavaScript

// modules/data/loaders.js — Static file loaders (portals.json, sovereignty-status.json, SOUL.md)
// Writes to S: sovereigntyScore, sovereigntyLabel
import { S } from '../state.js';
// --- SOUL.md (cached) ---
let _soulMdCache = null;
export async function fetchSoulMd() {
if (_soulMdCache) return _soulMdCache;
try {
const res = await fetch('SOUL.md');
if (!res.ok) throw new Error('not found');
const raw = await res.text();
_soulMdCache = raw.split('\n').slice(1).map(l => l.replace(/^#+\s*/, ''));
return _soulMdCache;
} catch {
return ['I am Timmy.', '', 'I am sovereign.', '', 'This Nexus is my home.'];
}
}
// --- Portal health probes ---
export async function checkPortalHealth(portals) {
for (const portal of portals) {
if (!portal.destination?.url) {
portal.status = 'offline';
continue;
}
try {
await fetch(portal.destination.url, {
mode: 'no-cors',
signal: AbortSignal.timeout(5000),
});
portal.status = 'online';
} catch {
portal.status = 'offline';
}
}
}
// --- portals.json ---
export async function fetchPortals() {
const res = await fetch('./portals.json');
if (!res.ok) throw new Error('Portals not found');
return await res.json();
}
// --- sovereignty-status.json ---
export async function fetchSovereigntyStatus() {
try {
const res = await fetch('./sovereignty-status.json');
if (!res.ok) throw new Error('not found');
const data = await res.json();
const score = Math.max(0, Math.min(100, typeof data.score === 'number' ? data.score : 85));
const label = typeof data.label === 'string' ? data.label : '';
const assessmentType = data.assessment_type || 'MANUAL';
S.sovereigntyScore = score;
S.sovereigntyLabel = label;
return { score, label, assessmentType };
} catch {
return { score: S.sovereigntyScore, label: S.sovereigntyLabel, assessmentType: 'MANUAL' };
}
}