# provider _(no submodules)_ ## Purpose Adapts the three tide-prediction backends — TICON-style harmonic constituents, the ADMIRALTY HTTP API, and the equilibrium-tide physics model — to the universal `TidalProvider` shape from `@suaveplan/types`. Every factory returns a pair of methods (`predictHeight`, `getExtremes`) that accept a `PlanetConfig`, a `SphericalCoord`, and a `Date`, so callers can swap backends without changing call sites or domain logic. This is the recommended entry point for any consumer that doesn't need the lower-level station-rooted `AdmiraltyProvider` API. ## Features - `createTiconProvider(constituents, meanSeaLevel?)` — pure, offline, deterministic. Wraps `predictHeight`/`findExtremes` from `@suaveplan/tides/harmonic`. - `createAdmiraltyProvider(options)` — async, network-bound. Routes via `getNearestStation` so callers can pass any UK coordinate. - `createPhysicsBasedProvider()` — zero-config, no network, no constituents. Equilibrium-tide model from `@suaveplan/tides` `physics`. - All three return objects matching `TidalProvider` from `@suaveplan/types`, so they compose with anything in the universe stack expecting that contract. - AbortSignal is forwarded for the ADMIRALTY adapter; ignored for the deterministic backends. ## Usage: Basic Example ```ts import { createTiconProvider } from "@suaveplan/tides"; const provider = createTiconProvider([ { name: "M2", amplitude: 1.0, phase: 0, speed: 28.984104 }, ]); const earth = { name: "Earth", radius: 6_371_000, rotationPeriod: 86_164 }; const height = await provider.predictHeight( earth, { latitude: 51.5074, longitude: -0.1278 }, new Date("2024-06-15T12:00:00Z") ); ``` ## Usage: Advanced Example ```ts import { createAdmiraltyProvider, createPhysicsBasedProvider, createTiconProvider, } from "@suaveplan/tides"; import type { TidalProvider } from "@suaveplan/types"; function pickProvider(input: { apiKey?: string; constituents?: Parameters[0]; }): TidalProvider { if (input.constituents?.length) return createTiconProvider(input.constituents); if (input.apiKey) return createAdmiraltyProvider({ apiKey: input.apiKey }); return createPhysicsBasedProvider(); } ``` ## API Reference - `createTiconProvider(constituents: readonly HarmonicConstituent[], meanSeaLevel?: number): TidalProvider`. - `createAdmiraltyProvider(options: AdmiraltyProviderOptions): TidalProvider` — internally wraps a station-rooted `AdmiraltyProvider`. - `createPhysicsBasedProvider(): TidalProvider`. - Each `TidalProvider` exposes: - `predictHeight(planet, coord, time, signal?): Promise`. - `getExtremes(planet, coord, date, signal?): Promise`. ## Implementation Notes The `_planet` parameter is currently unused by every backend — it is preserved on the contract so future backends (e.g. Mars or exoplanet equilibrium tide models) can vary behaviour without breaking call sites. The ADMIRALTY adapter performs an extra `getNearestStation` round-trip per call; for batch workloads, consider hoisting that to once-per-coord and operating on the station-rooted `AdmiraltyProvider` API directly to amortise it. The TICON and physics adapters are synchronous internally but return Promises to satisfy the universal contract — they never reject and never await, so `await` is essentially zero-cost. `getExtremes` for the TICON adapter scans the full UTC day containing `date` (`startOfDay → +24h`) regardless of the time-of-day component on the input.