v0.9.5: The Voltron Update — modular architecture, stable IDs, parallelized boot

- Parallelized startup (60s → 15s) via ThreadPoolExecutor
- Adaptive polling engine with ETag caching (no more bbox interrupts)
- useCallback optimization for interpolation functions
- Sliding LAYERS/INTEL edge panels replace bulky Record Panel
- Modular fetcher architecture (flights, geo, infrastructure, financial, earth_observation)
- Stable entity IDs for GDELT & News popups (PR #63, credit @csysp)
- Admin auth (X-Admin-Key), rate limiting (slowapi), auto-updater
- Docker Swarm secrets support, env_check.py validation
- 85+ vitest tests, CI pipeline, geoJSON builder extraction
- Server-side viewport bbox filtering reduces payloads 80%+

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Former-commit-id: f2883150b5bc78ebc139d89cc966a76f7d7c0408
This commit is contained in:
anoracleofra-code
2026-03-14 14:01:54 -06:00
parent 60c90661d4
commit 90c2e90e2c
63 changed files with 6015 additions and 2756 deletions
+35 -18
View File
@@ -1,4 +1,5 @@
const WebSocket = require('ws');
const readline = require('readline');
const args = process.argv.slice(2);
const API_KEY = args[0] || process.env.AIS_API_KEY;
@@ -8,22 +9,15 @@ if (!API_KEY) {
process.exit(1);
}
const FILTER = [
// US Aircraft Carriers and major naval groups
{ "MMSI": 338000000 }, { "MMSI": 338100000 }, // US Navy general prefixes
// Plus let's grab some global shipping for density
{ "BoundingBoxes": [[[-90, -180], [90, 180]]] }
];
// Start with global coverage, until frontend updates it
let currentBboxes = [[[-90, -180], [90, 180]]];
let activeWs = null;
function connect() {
const ws = new WebSocket('wss://stream.aisstream.io/v0/stream');
ws.on('open', () => {
function sendSub(ws) {
if (ws && ws.readyState === WebSocket.OPEN) {
const subMsg = {
APIKey: API_KEY,
BoundingBoxes: [
[[-90, -180], [90, 180]]
],
BoundingBoxes: currentBboxes,
FilterMessageTypes: [
"PositionReport",
"ShipStaticData",
@@ -31,17 +25,39 @@ function connect() {
]
};
ws.send(JSON.stringify(subMsg));
}
}
// Listen for dynamic bounding box updates via stdin from Python orchestrator
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
rl.on('line', (line) => {
try {
const cmd = JSON.parse(line);
if (cmd.type === "update_bbox" && cmd.bboxes) {
currentBboxes = cmd.bboxes;
if (activeWs) sendSub(activeWs); // Resend subscription (swap and replace)
}
} catch (e) {}
});
function connect() {
const ws = new WebSocket('wss://stream.aisstream.io/v0/stream');
activeWs = ws;
ws.on('open', () => {
sendSub(ws);
});
ws.on('message', (data) => {
// Output raw AIS message JSON to stdout so Python can consume it
// We ensure exactly one JSON object per line.
try {
const parsed = JSON.parse(data);
console.log(JSON.stringify(parsed));
} catch (e) {
// ignore non-json
}
} catch (e) {}
});
ws.on('error', (err) => {
@@ -49,6 +65,7 @@ function connect() {
});
ws.on('close', () => {
activeWs = null;
console.error("WebSocket Proxy Closed. Reconnecting in 5s...");
setTimeout(connect, 5000);
});