/* * types.ts — the routing contracts (D-01, D-03, D-05, D-07, D-11). * ---------------------------------------------------------------- * RoutePoint / RouteRequest / RouteResult / RoutingSource are the seam * every backend implements: the build-time fixture corpus (backend #1, * "fixture", this phase), the client-side WASM router (backend #2, * "wasm-router" — OSS track, post-v1; origin+destination never touch a * server), and Valhalla-on-VPS (backend #3, documented provision path, * not shipped). The ladder is DOCUMENTED, not switchable: no env read, * no config read, no dynamic backend registry (T-05-04) — the import * site constructs the backend in code (plan 05-04). * * THE NULL CONTRACT IS LOAD-BEARING (D-03): route() resolving to NULL is * the honest "router pending" state — an unknown destination, or an * origin outside the fixture corpus's tolerance. Never a blank map, * never a fake route, never a thrown error for a normal miss. * * No logging, no storage, no network (D-05/D-12/D-15 analog): request * coordinates never leave the caller's frame. */ /** A WGS84 point. */ export interface RoutePoint { lat: number; lng: number; } /** A routing request. The origin is the live fix (memory only — GEO-03/D-07). */ export interface RouteRequest { origin: RoutePoint; /** The gazetteer id resolved by the Phase 4 destination resolver. */ destinationId: string; } /** Distance/duration summary. Distances in meters, durations in seconds. */ export interface RouteSummary { distanceM: number; durationS: number; } /** * A maneuver step — DAY-ONE FIELD (D-07, GUID-05/06 upstream obligation). * Fixture-world steps are ALWAYS empty arrays (D-10 defers instructions to * Phase 6): an empty array is honest "not wired"; a fabricated step list * would not be. Real step geometry arrives with backends #2/#3. */ export interface RouteStep { distanceM?: number; durationS?: number; name?: string; /** polyline6-encoded step geometry (backend #2/#3 populate this). */ geometry?: string; /** * Maneuver kind — Engine A populates this (06-01); fixture-world steps * stay empty arrays (D-10). */ kind?: | "depart" | "straight" | "left" | "right" | "slight-left" | "slight-right" | "uturn" | "arrive"; } /** * Decoded geometry + the snapped-progress support field — DAY-ONE FIELD * (D-07, GUID-05/06 upstream obligation): Phase 6's guidance walks a live * fix along cumulativeDistanceM instead of re-deriving it per fix. */ export interface RouteGeometry { points: RoutePoint[]; /** Same length as points; [0] === 0; non-decreasing. Meters along the line. */ cumulativeDistanceM: number[]; } /** One routable alternative. options[0] of a result is the BEST route. */ export interface RouteOption { geometry: RouteGeometry; summary: RouteSummary; steps: RouteStep[]; } export interface RouteResult { destinationId: string; origin: RoutePoint; /** 1..3 options, index 0 = best (order preserved from the backend). */ options: RouteOption[]; /** === the RoutingSource name that produced it. */ backend: string; } /** * The pluggable routing seam (D-01). Backends: "fixture" (this phase) → * "wasm-router" (OSS track, backend #2 — client-side, origin+destination * never touch a server) → "valhalla" (VPS, backend #3). Backends #2/#3 do * NOT ship in this phase — the interface exists so they slot in without a * client rewrite, exactly parallel to SearchSource's ladder (D-03/D-04). * * THE NULL CONTRACT IS LOAD-BEARING (D-03): route() resolving to NULL is * the honest "router pending" state — an unknown destination, or an origin * outside the fixture corpus's tolerance. Never a blank map, never a fake * route, never a thrown error for a normal miss. * * No logging, no storage, no network (D-05/D-12/D-15 analog): request * coordinates never leave the caller's frame. */ export interface RoutingSource { readonly name: string; route(req: RouteRequest): Promise; } /** One committed fixture route — the polyline6 string stored VERBATIM * from the build-time OSRM demo response (RESEARCH Finding 1). */ export interface FixtureRoute { /** polyline6, stored VERBATIM from the OSRM demo response. */ geometry: string; distanceM: number; durationS: number; } /** One golden origin→destination pair of the fixture corpus (D-02). */ export interface FixturePair { /** "-to-", slug charset — also the ?fixpair= knob value. */ pairId: string; origin: { lat: number; lng: number; label: string }; destinationId: string; /** Best-first, 1..3 entries (OSRM demo returns best-first; preserved). */ routes: FixtureRoute[]; } /** The committed dataset envelope (route-fixtures.json) — the ODbL * attribution travels INSIDE the file, the gazetteer's three-surfaces * pattern (T-05-06). Tests inject synthetic values of this shape. */ export interface RouteFixturesFile { _license: string; _attribution: string; _notice: string; _source: string; version: number; originToleranceM: number; pairs: FixturePair[]; }