first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
# Providers
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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<CelestialBody[]>` | All major bodies for the observer. |
| `getBody(name, observer, time, signal?)` | `Promise<CelestialBody>` | Single named body. |
| `getSunrise(observer, date, signal?)` | `Promise<Date>` | Sunrise UTC for the date. |
| `getSunset(observer, date, signal?)` | `Promise<Date>` | Sunset UTC for the date. |
### `interface StarProvider`
| Method | Returns | Description |
|---|---|---|
| `getVisibleStars(observer, options?, signal?)` | `Promise<ObservedStar[]>` | Brightness-sorted stars above the observer's horizon. |
| `queryCone(ra, dec, radiusDeg, signal?)` | `Promise<CatalogStar[]>` | Catalog-space cone query. |
| `getStar(catalogId, signal?)` | `Promise<CatalogStar \| null>` | Lookup by catalogue identifier. |
### `interface TidalProvider`
| Method | Returns | Description |
|---|---|---|
| `predictHeight(planet, coord, time, signal?)` | `Promise<number>` | Tidal height in metres above chart datum. |
| `getExtremes(planet, coord, date, signal?)` | `Promise<TideExtreme[]>` | High and low events for the date. |
### `interface WeatherProvider`
| Method | Returns | Description |
|---|---|---|
| `getCurrent(observer, signal?)` | `Promise<WeatherState>` | 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.