3.6 KiB
(no submodules)
Purpose
The provider module composes one or more StarCatalogSource instances into a single StarProvider (from @suaveplan/types) that consumers — sky renderers, planetarium UIs, telescope planners — can program against without binding to a specific catalog backend. It implements the cross-source fallback semantics expected by the rest of the geo family.
It also exposes a low-level getVisibleStars helper that returns RawStar records filtered by apparent magnitude, intended for diagnostic tools and tests that operate below the StarProvider abstraction.
Features
- Multi-source aggregation with first-non-empty fallback for
queryCone. - First-hit short-circuit for
getStaracross sources. getVisibleStarsprojects every queried star into anObservedStarwith placeholder altitude/azimuth/extincted-magnitude fields suitable for the contract surface.- Total support for the optional
RawStarcolumns (spectralClass,distance,properMotionRa,properMotionDec,parallax) — present fields are forwarded, absent ones omitted underexactOptionalPropertyTypes. - Pure functions with no global state and no I/O beyond delegated source calls.
Usage: Basic Example
import { createInMemoryCatalogSource, createStarProvider } from "@suaveplan/stars";
const source = createInMemoryCatalogSource([
{ catalogId: "HIP-32349", ra: 101.287, dec: -16.716, apparentMagnitude: -1.46 },
]);
const provider = createStarProvider([source]);
const stars = await provider.queryCone(101, -16, 5);
Usage: Advanced Example
import { createInMemoryCatalogSource, createStarProvider, getVisibleStars } from "@suaveplan/stars";
const primary = createInMemoryCatalogSource([]);
const fallback = createInMemoryCatalogSource([
{ catalogId: "HIP-37279", ra: 114.825, dec: 5.225, apparentMagnitude: 0.4 },
{ catalogId: "HIP-91262", ra: 279.234, dec: 38.784, apparentMagnitude: 0.03 },
]);
const provider = createStarProvider([primary, fallback]);
const visible = await provider.getVisibleStars({
kind: "surface",
planet: { name: "Earth", radius: 6_371_000, rotationPeriod: 86_164 },
coord: { latitude: 51.4779, longitude: -0.0015 },
});
const bright = await getVisibleStars([fallback], { latitude: 0, longitude: 0 }, 0, 1);
API Reference
createStarProvider(sources: StarCatalogSource[]): StarProvider— returns aStarProviderwhosequeryCone(ra, dec, radiusDeg)walkssourcesin order and returns the first non-empty result mapped toCatalogStar; whosegetStar(catalogId)returns the first match across sources ornull; and whosegetVisibleStars(observer)returns every star across all sources projected toObservedStar.getVisibleStars(sources, observer, minAltitudeDeg?, maxMagnitude?): Promise<RawStar[]>— collects raw stars from every source via a 90-degree cone at the celestial origin and filters bymaxMagnitude(default 6).observerandminAltitudeDegare accepted for forward-compatibility but currently unused.
Implementation Notes
toCatalogStar uses guarded Object.assign for optional fields so undefined values do not leak as own properties — this matters under exactOptionalPropertyTypes: true. toObservedStar returns hard-coded altitude/azimuth values; this is a contract-only shim and a real implementation should plug in horizontal-coordinate transforms from @suaveplan/geo. queryCone short-circuits on the first non-empty source, which is appropriate for layered hot/cold caches but wrong for true union semantics; if you need union behaviour, compose sources upstream.