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

3.9 KiB

Observer

(no submodules)

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

import type { ObserverPosition } from "@suaveplan/universe";

const observer: ObserverPosition = {
    kind: "space",
    heliocentricVec: { x: 1, y: 0, z: 0 },
    frame: "icrs",
};

Usage: Advanced Example

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.