# Providers _(no submodules)_ ## Purpose Provider interfaces are the integration surface between `UniverseClient` and any data source — a real-time ephemeris service, a static catalogue, a mocked provider in a test, or a deterministic game-engine implementation. Each interface exposes only the operations the client actually consumes and is shaped so a reasonable mock can be hand-written in a few lines. This module is a re-export of the canonical provider contracts from `@suaveplan/types`. Keeping the declarations in `@suaveplan/types` ensures every consumer in the universe family — client, frame conversions, packet codecs, sibling packages — sees structurally identical types without forming a dependency cycle. Consumers may import from either `@suaveplan/universe` (the package root re-exports the same names) or `@suaveplan/universe/providers/providers` for explicit sub-path imports. ## Features - `SolarProvider` — body positions, sunrise, sunset, single-body lookup. - `StarProvider` — visible stars for an observer, cone queries in catalogue space, single-star lookup. - `TidalProvider` — height prediction and high/low extreme events for a planet/coordinate. - `WeatherProvider` — current conditions snapshot for an observer. - `WeatherState` — value object returned by `WeatherProvider.getCurrent`. - Every async method accepts an optional `AbortSignal` so callers can cancel propagation through the entire client. ## Usage: Basic Example ```ts import type { SolarProvider } from "@suaveplan/universe"; const mockSun: SolarProvider = { async getBodies() { return []; }, async getBody(name) { return { name, type: "star", altitude: 45, azimuth: 180, apparentMagnitude: -26.7, angularDiameterArcmin: 32, distanceAu: 1, heliocentricPosition: { x: 0, y: 0, z: 0 }, }; }, async getSunrise() { return new Date("2026-01-01T06:00:00Z"); }, async getSunset() { return new Date("2026-01-01T18:00:00Z"); }, }; ``` ## Usage: Advanced Example ```ts import { UniverseClient } from "@suaveplan/universe"; import type { SolarProvider, StarProvider, TidalProvider, WeatherProvider, } from "@suaveplan/universe"; declare const realSolar: SolarProvider; declare const realStars: StarProvider; declare const realTides: TidalProvider; declare const realWeather: WeatherProvider; const client = new UniverseClient() .registerSolar(realSolar) .registerStars(realStars) .registerTides(realTides) .registerWeather(realWeather); const controller = new AbortController(); setTimeout(() => controller.abort(), 5000); const scene = await client.getScene( { kind: "surface", planet: { name: "Earth", mass: 1, radius: 1, polarRadius: 1, surfaceGravity: 1, rotationPeriod: 1, axialTilt: 23.4, atmosphere: null, satellites: [], }, coord: { latitude: 51.5, longitude: -0.12 }, }, new Date(), controller.signal ); ``` ## API Reference ### `interface SolarProvider` | Method | Returns | Description | |---|---|---| | `getBodies(observer, time, signal?)` | `Promise` | All major bodies for the observer. | | `getBody(name, observer, time, signal?)` | `Promise` | Single named body. | | `getSunrise(observer, date, signal?)` | `Promise` | Sunrise UTC for the date. | | `getSunset(observer, date, signal?)` | `Promise` | Sunset UTC for the date. | ### `interface StarProvider` | Method | Returns | Description | |---|---|---| | `getVisibleStars(observer, options?, signal?)` | `Promise` | Brightness-sorted stars above the observer's horizon. | | `queryCone(ra, dec, radiusDeg, signal?)` | `Promise` | Catalog-space cone query. | | `getStar(catalogId, signal?)` | `Promise` | Lookup by catalogue identifier. | ### `interface TidalProvider` | Method | Returns | Description | |---|---|---| | `predictHeight(planet, coord, time, signal?)` | `Promise` | Tidal height in metres above chart datum. | | `getExtremes(planet, coord, date, signal?)` | `Promise` | High and low events for the date. | ### `interface WeatherProvider` | Method | Returns | Description | |---|---|---| | `getCurrent(observer, signal?)` | `Promise` | Snapshot of current conditions. | ### `interface WeatherState` | Property | Type | Description | |---|---|---| | `temperature` | `number` | Degrees Celsius. | | `pressure` | `number` | Hectopascals. | | `humidity` | `number` | Percent (0 – 100). | ## Implementation Notes All four contracts are interfaces — there is no abstract base class, no decorator, and no required adapter to implement them. This keeps mocks trivial and lets consumers register remote-API wrappers, deterministic game providers, in-memory caches, or stub fixtures interchangeably. `UniverseClient` does not retry, cache, or fan out; consumers that need those policies should compose them inside the provider implementations so cross-cutting behaviour is contained and testable in isolation. The `signal` parameter is plumbed unconditionally — providers should propagate it into any underlying fetch / database call so an aborted scene request cancels in-flight work.