Files
skills/docs/geospatial/geo/stars/src/provider/provider.md
2026-05-29 08:20:56 +01:00

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 getStar across sources.
  • getVisibleStars projects every queried star into an ObservedStar with placeholder altitude/azimuth/extincted-magnitude fields suitable for the contract surface.
  • Total support for the optional RawStar columns (spectralClass, distance, properMotionRa, properMotionDec, parallax) — present fields are forwarded, absent ones omitted under exactOptionalPropertyTypes.
  • 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 a StarProvider whose queryCone(ra, dec, radiusDeg) walks sources in order and returns the first non-empty result mapped to CatalogStar; whose getStar(catalogId) returns the first match across sources or null; and whose getVisibleStars(observer) returns every star across all sources projected to ObservedStar.
  • getVisibleStars(sources, observer, minAltitudeDeg?, maxMagnitude?): Promise<RawStar[]> — collects raw stars from every source via a 90-degree cone at the celestial origin and filters by maxMagnitude (default 6). observer and minAltitudeDeg are 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.