115 lines
3.9 KiB
Markdown
115 lines
3.9 KiB
Markdown
# Observer
|
|
|
|
<!-- begin:auto-docs -->
|
|
_(no submodules)_
|
|
<!-- end:auto-docs -->
|
|
## Purpose
|
|
|
|
Re-exports the `ObserverPosition` discriminated union that every universe-family entry point consumes. The union has three branches — `SurfaceObserver`, `AtmosphericObserver`, and `SpaceObserver` — distinguished by a `kind` literal field so call sites can narrow exhaustively without runtime type tags or class hierarchies.
|
|
|
|
Centralising these types in one module gives `@suaveplan/universe/client/client`, providers, and frame-conversion utilities a single shape to consume. Because the source declarations live in `@suaveplan/types` (zero-runtime, types-only), this re-export adds no bundle weight; it exists so consumers can import observer shapes without crossing into the foundational types package directly.
|
|
|
|
## Features
|
|
|
|
- `ObserverPosition` — full discriminated union, switch on `kind`.
|
|
- `SurfaceObserver` — planet-bound observer at a `{latitude, longitude}` coordinate.
|
|
- `AtmosphericObserver` — same as surface but with `altitudeMetres` (planes, balloons, drones).
|
|
- `SpaceObserver` — heliocentric vector + reference `frame` (e.g. `"icrs"`).
|
|
- All three branches share the `kind` literal as the discriminator.
|
|
- Pure types — zero runtime cost, tree-shaken to nothing.
|
|
|
|
## Usage: Basic Example
|
|
|
|
```ts
|
|
import type { ObserverPosition } from "@suaveplan/universe";
|
|
|
|
const observer: ObserverPosition = {
|
|
kind: "space",
|
|
heliocentricVec: { x: 1, y: 0, z: 0 },
|
|
frame: "icrs",
|
|
};
|
|
```
|
|
|
|
## Usage: Advanced Example
|
|
|
|
```ts
|
|
import type {
|
|
AtmosphericObserver,
|
|
ObserverPosition,
|
|
SpaceObserver,
|
|
SurfaceObserver,
|
|
} from "@suaveplan/universe";
|
|
|
|
function describe(o: ObserverPosition): string {
|
|
switch (o.kind) {
|
|
case "surface":
|
|
return `surface at ${o.coord.latitude},${o.coord.longitude}`;
|
|
case "atmospheric":
|
|
return `${o.altitudeMetres} m above ${o.planet.name}`;
|
|
case "space":
|
|
return `space, ${o.frame} vector ${JSON.stringify(o.heliocentricVec)}`;
|
|
}
|
|
}
|
|
|
|
const earth = {
|
|
name: "Earth",
|
|
mass: 1,
|
|
radius: 1,
|
|
polarRadius: 1,
|
|
surfaceGravity: 1,
|
|
rotationPeriod: 1,
|
|
axialTilt: 23.4,
|
|
atmosphere: null,
|
|
satellites: [],
|
|
};
|
|
|
|
const surface: SurfaceObserver = {
|
|
kind: "surface",
|
|
planet: earth,
|
|
coord: { latitude: 51.5, longitude: -0.12 },
|
|
};
|
|
const balloon: AtmosphericObserver = {
|
|
kind: "atmospheric",
|
|
planet: earth,
|
|
coord: { latitude: 51.5, longitude: -0.12 },
|
|
altitudeMetres: 12000,
|
|
};
|
|
const probe: SpaceObserver = {
|
|
kind: "space",
|
|
heliocentricVec: { x: 1.0, y: 0.0, z: 0.0 },
|
|
frame: "icrs",
|
|
};
|
|
|
|
[surface, balloon, probe].forEach((o) => describe(o));
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### `type SurfaceObserver`
|
|
|
|
| Property | Type | Description |
|
|
|---|---|---|
|
|
| `kind` | `"surface"` | Discriminator literal. |
|
|
| `planet` | `PlanetConfig` | Host body (mass, radius, axial tilt, satellites …). |
|
|
| `coord` | `{ latitude: number; longitude: number }` | Geographic location in degrees. |
|
|
|
|
### `type AtmosphericObserver`
|
|
|
|
Extends `SurfaceObserver` shape with an additional `altitudeMetres: number` and `kind: "atmospheric"`.
|
|
|
|
### `type SpaceObserver`
|
|
|
|
| Property | Type | Description |
|
|
|---|---|---|
|
|
| `kind` | `"space"` | Discriminator literal. |
|
|
| `heliocentricVec` | `{ x: number; y: number; z: number }` | Cartesian position in AU. |
|
|
| `frame` | `string` | Reference frame label, e.g. `"icrs"`. |
|
|
|
|
### `type ObserverPosition`
|
|
|
|
`SurfaceObserver | AtmosphericObserver | SpaceObserver` — exhaustive switch on `kind`.
|
|
|
|
## Implementation Notes
|
|
|
|
These types are re-exported from `@suaveplan/types`; this module contains no runtime code and contributes nothing to the emitted bundle. Keeping the canonical declarations in `@suaveplan/types` preserves the universe-family rule that any observer-shaped value flowing through providers, the client, frame conversions, or packet codecs is structurally identical no matter which sibling package produced it.
|