- graph.ts: decodeGraph/encodeGraph over the pinned little-endian CSR layout; header magic+version+exact byte-size validation BEFORE any view allocation (T-06-03/T-06-03b fail-honest null); zero-copy typed-array views; street-name pool with UNNAMED_NAME_ID sentinel - header padded 60 -> 64 bytes so f64 views are 8-byte aligned — unaligned Float64Array throws RangeError, making plan-literal offsets incompatible with the plan's own zero-copy law (documented deviation; field order/content/endian unchanged; consumers inherit via encodeGraph) - build-mini-graph.mjs + committed mini-graph.bin: hand-built 5x5 grid, 25 nodes, 80 directed edges, 3 named streets, exactly ONE oneway pair, two speed classes (60/30 km/h) — the A* ground truth (G7 pins it) - types.ts: RouteStep gains optional kind (8 turn kinds) — Engine A populates it (06-01); fixture-world steps stay empty arrays (D-10)
146 lines
5.0 KiB
TypeScript
146 lines
5.0 KiB
TypeScript
/*
|
|
* 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<RouteResult | null>;
|
|
}
|
|
|
|
/** 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 {
|
|
/** "<origin-id>-to-<dest-id>", 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[];
|
|
}
|