feat: name live feed routes and sources for what they serve

The flight, military and vessel feeds were named after the providers the
bundled server uses (/api/opensky, /api/adsblol/mil, /api/ais-live and
their track routes; createOpenSkySource, createAdsbLolSource,
createAisStreamSource). Any server should be able to answer a feed from
its own provider, so the feeds are now:

  /api/flights   /api/flights/track?icao24=
  /api/military  /api/military/track?hex=
  /api/vessels   /api/vessels/track?mmsi=

with createFlightSource, createMilitarySource and createVesselSource. The
old routes are removed. Each server names its provider in X-Feed-Source
(the bundled server sends OpenSky Network, adsb.lol and AISStream, so its
attribution is unchanged) and the military feed's cache state and age in
X-Feed-Cache and X-Feed-Age-Ms. Sources report the provider the server
names and fall back to the feed's name.
This commit is contained in:
Sameh Khamis committed 2026-10-03 23:10:32 -07:00
1 parent 5bf3beea84
commit 60644c5f5d
43 files changed
+564 -312

No files matched your search

+3 -3
View File
@@ -2,7 +2,7 @@ import assert from 'node:assert/strict';
import test from 'node:test';
import { composeCatalog, coreTools } from '../index.js';
import { LiveSourceError } from '../../sources/live/contract.js';
import { createAisStreamSource } from '../../sources/live/standalone.js';
import { createVesselSource } from '../../sources/live/standalone.js';
import { AISSTREAM_CACHE_MAX } from '../../../server/providers/vessels/ais-store.js';
const vessel = (id, latitude, longitude, extra = {}) => ({
@@ -184,7 +184,7 @@ test('a missing AIS key surfaces as an unavailable feed', async () => {
test('vessel searches ask for every vessel the server retains', async () => {
const requested = [];
const source = createAisStreamSource({
const source = createVesselSource({
origin: () => 'http://localhost',
fetchImpl: async (url) => {
requested.push(new URL(url).searchParams.get('maxRows'));
@@ -204,7 +204,7 @@ test('vessel searches ask for every vessel the server retains', async () => {
test('an area search names its area to the server; a vessel lookup asks for every vessel', async () => {
const requested = [];
const source = createAisStreamSource({
const source = createVesselSource({
origin: () => 'http://localhost',
fetchImpl: async (url) => {
requested.push(new URL(url).searchParams);