sync: 2026-03-14 17:28 — 45 files from Alexandria
Some checks failed
Some checks failed
RoadChain-SHA2048: abc9be08a46f52c2 RoadChain-Identity: alexa@sovereign RoadChain-Full: abc9be08a46f52c20e45ae95233112ee88407ca3a606ec0ef568784041b755a56343cf4d7b817f2f4f7a11ec3f34ce826f607b2150a77248ade06b449e5b7e281b4be665ab148c46e3b71c9c029ee4d77f120e5919a7b87b0b7b6ed45f12c87f420fdda633f3bae4c5f7b851979bb52c725913fa63300772174263d1e64a02aa3356f73819e1110ad94d16836fa9f24b40e60e2da2f252506fbf02f82acc5fb8e03fd6ec08691ea60dea318ce5099a93d8ead7f9ef45b13a1ab533f592b60c702a0ba854b243e94be7eece0bfab14f822a928f8681c8777dc6a881da7e2ec324d6ace471f6c3f77ad83a22bfea01760be75f191128aa0a100d497dd0f0801ea8
This commit is contained in:
188
workers/stats-blackroad-src/worker.js
Normal file
188
workers/stats-blackroad-src/worker.js
Normal file
@@ -0,0 +1,188 @@
|
||||
// BlackRoad Stats API — Central live data hub for all BlackRoad websites
|
||||
// KV-backed, pushed from Mac cron, consumed by all frontends
|
||||
//
|
||||
// GET /fleet — node status, specs, services
|
||||
// GET /infra — infrastructure counts (tunnels, DBs, ports, etc.)
|
||||
// GET /github — live GitHub data (proxied + cached)
|
||||
// GET /analytics — proxied from analytics worker
|
||||
// GET /all — combined payload for single-fetch
|
||||
// POST /push — push data from collector (requires STATS_KEY)
|
||||
// GET /health — uptime check
|
||||
|
||||
const CORS = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type,Authorization',
|
||||
'Cache-Control': 'public, max-age=30',
|
||||
};
|
||||
|
||||
function json(data, status = 200) {
|
||||
return new Response(JSON.stringify(data), {
|
||||
status,
|
||||
headers: { ...CORS, 'Content-Type': 'application/json' },
|
||||
});
|
||||
}
|
||||
|
||||
const GITHUB_USER = 'blackboxprogramming';
|
||||
const ANALYTICS_URL = 'https://analytics-blackroad.amundsonalexa.workers.dev';
|
||||
|
||||
export default {
|
||||
async fetch(request, env) {
|
||||
const url = new URL(request.url);
|
||||
const path = url.pathname;
|
||||
|
||||
if (request.method === 'OPTIONS') {
|
||||
return new Response(null, { headers: CORS });
|
||||
}
|
||||
|
||||
try {
|
||||
// ── Push data from collector ──
|
||||
if (path === '/push' && request.method === 'POST') {
|
||||
const authKey = request.headers.get('Authorization')?.replace('Bearer ', '') ||
|
||||
url.searchParams.get('key');
|
||||
if (authKey !== env.STATS_KEY) return json({ error: 'unauthorized' }, 401);
|
||||
|
||||
const body = await request.json();
|
||||
const { category, data } = body;
|
||||
if (!category || !data) return json({ error: 'category and data required' }, 400);
|
||||
|
||||
// Store with timestamp
|
||||
const payload = { data, updated_at: new Date().toISOString() };
|
||||
await env.STATS.put(`stats:${category}`, JSON.stringify(payload));
|
||||
return json({ ok: true, category });
|
||||
}
|
||||
|
||||
// ── Fleet status ──
|
||||
if (path === '/fleet') {
|
||||
const raw = await env.STATS.get('stats:fleet');
|
||||
if (!raw) return json({ error: 'no fleet data yet', hint: 'run collector' }, 404);
|
||||
return json(JSON.parse(raw));
|
||||
}
|
||||
|
||||
// ── Infrastructure counts ──
|
||||
if (path === '/infra') {
|
||||
const raw = await env.STATS.get('stats:infra');
|
||||
if (!raw) return json({ error: 'no infra data yet' }, 404);
|
||||
return json(JSON.parse(raw));
|
||||
}
|
||||
|
||||
// ── GitHub data (proxied + cached 5min) ──
|
||||
if (path === '/github') {
|
||||
const cached = await env.STATS.get('cache:github');
|
||||
if (cached) return json(JSON.parse(cached));
|
||||
|
||||
// Fetch repos (2 pages to get all)
|
||||
const [p1, p2] = await Promise.all([
|
||||
fetch(`https://api.github.com/users/${GITHUB_USER}/repos?per_page=100&page=1&sort=updated`, {
|
||||
headers: { 'User-Agent': 'BlackRoad-Stats/1.0', ...(env.GITHUB_TOKEN ? { 'Authorization': `token ${env.GITHUB_TOKEN}` } : {}) }
|
||||
}),
|
||||
fetch(`https://api.github.com/users/${GITHUB_USER}/repos?per_page=100&page=2&sort=updated`, {
|
||||
headers: { 'User-Agent': 'BlackRoad-Stats/1.0', ...(env.GITHUB_TOKEN ? { 'Authorization': `token ${env.GITHUB_TOKEN}` } : {}) }
|
||||
}),
|
||||
]);
|
||||
const repos1 = await p1.json();
|
||||
const repos2 = await p2.json();
|
||||
const allRepos = [...(Array.isArray(repos1) ? repos1 : []), ...(Array.isArray(repos2) ? repos2 : [])];
|
||||
const nonFork = allRepos.filter(r => !r.fork);
|
||||
|
||||
const result = {
|
||||
total_repos: allRepos.length,
|
||||
non_fork_repos: nonFork.length,
|
||||
forks: allRepos.length - nonFork.length,
|
||||
total_stars: nonFork.reduce((s, r) => s + (r.stargazers_count || 0), 0),
|
||||
total_size_kb: nonFork.reduce((s, r) => s + (r.size || 0), 0),
|
||||
languages: [...new Set(nonFork.map(r => r.language).filter(Boolean))],
|
||||
most_recent: nonFork.slice(0, 5).map(r => ({
|
||||
name: r.name,
|
||||
updated: r.updated_at,
|
||||
language: r.language,
|
||||
stars: r.stargazers_count,
|
||||
})),
|
||||
fetched_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
await env.STATS.put('cache:github', JSON.stringify(result), { expirationTtl: 300 });
|
||||
return json(result);
|
||||
}
|
||||
|
||||
// ── Analytics proxy ──
|
||||
if (path === '/analytics') {
|
||||
const range = url.searchParams.get('range') || '24h';
|
||||
const cached = await env.STATS.get(`cache:analytics:${range}`);
|
||||
if (cached) return json(JSON.parse(cached));
|
||||
|
||||
const res = await fetch(`${ANALYTICS_URL}/stats?range=${range}`);
|
||||
if (!res.ok) return json({ error: 'analytics unavailable' }, 502);
|
||||
const data = await res.json();
|
||||
await env.STATS.put(`cache:analytics:${range}`, JSON.stringify(data), { expirationTtl: 60 });
|
||||
return json(data);
|
||||
}
|
||||
|
||||
// ── Combined payload ──
|
||||
if (path === '/all') {
|
||||
const [fleet, infra, github, analytics] = await Promise.all([
|
||||
env.STATS.get('stats:fleet'),
|
||||
env.STATS.get('stats:infra'),
|
||||
env.STATS.get('cache:github').then(c => c || fetchGitHub(env)),
|
||||
env.STATS.get('cache:analytics:24h').then(c => c || env.STATS.get('stats:analytics')).then(c => c || fetchAnalytics(env)),
|
||||
]);
|
||||
|
||||
return json({
|
||||
fleet: fleet ? JSON.parse(fleet) : null,
|
||||
infra: infra ? JSON.parse(infra) : null,
|
||||
github: github ? (typeof github === 'string' ? JSON.parse(github) : github) : null,
|
||||
analytics: analytics ? (typeof analytics === 'string' ? JSON.parse(analytics) : analytics) : null,
|
||||
});
|
||||
}
|
||||
|
||||
// ── Health ──
|
||||
if (path === '/health') {
|
||||
const fleet = await env.STATS.get('stats:fleet');
|
||||
const fleetAge = fleet ? JSON.parse(fleet).updated_at : null;
|
||||
return json({
|
||||
status: 'up',
|
||||
fleet_data: fleetAge ? `last updated ${fleetAge}` : 'no data yet',
|
||||
});
|
||||
}
|
||||
|
||||
return json({ error: 'not found', endpoints: ['/fleet', '/infra', '/github', '/analytics', '/all', '/push', '/health'] }, 404);
|
||||
|
||||
} catch (err) {
|
||||
return json({ error: err.message }, 500);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
async function fetchGitHub(env) {
|
||||
try {
|
||||
const [p1, p2] = await Promise.all([
|
||||
fetch(`https://api.github.com/users/${GITHUB_USER}/repos?per_page=100&page=1&sort=updated`, {
|
||||
headers: { 'User-Agent': 'BlackRoad-Stats/1.0', ...(env.GITHUB_TOKEN ? { 'Authorization': `token ${env.GITHUB_TOKEN}` } : {}) }
|
||||
}),
|
||||
fetch(`https://api.github.com/users/${GITHUB_USER}/repos?per_page=100&page=2&sort=updated`, {
|
||||
headers: { 'User-Agent': 'BlackRoad-Stats/1.0', ...(env.GITHUB_TOKEN ? { 'Authorization': `token ${env.GITHUB_TOKEN}` } : {}) }
|
||||
}),
|
||||
]);
|
||||
const repos = [...await p1.json(), ...await p2.json()];
|
||||
const nonFork = repos.filter(r => !r.fork);
|
||||
const result = {
|
||||
total_repos: repos.length,
|
||||
non_fork_repos: nonFork.length,
|
||||
forks: repos.length - nonFork.length,
|
||||
total_stars: nonFork.reduce((s, r) => s + (r.stargazers_count || 0), 0),
|
||||
languages: [...new Set(nonFork.map(r => r.language).filter(Boolean))],
|
||||
fetched_at: new Date().toISOString(),
|
||||
};
|
||||
await env.STATS.put('cache:github', JSON.stringify(result), { expirationTtl: 300 });
|
||||
return JSON.stringify(result);
|
||||
} catch { return null; }
|
||||
}
|
||||
|
||||
async function fetchAnalytics(env) {
|
||||
try {
|
||||
const res = await fetch(`${ANALYTICS_URL}/stats?range=24h`);
|
||||
const data = await res.json();
|
||||
await env.STATS.put('cache:analytics:24h', JSON.stringify(data), { expirationTtl: 60 });
|
||||
return JSON.stringify(data);
|
||||
} catch { return null; }
|
||||
}
|
||||
Reference in New Issue
Block a user