@ingissa/navcore-core 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,279 +1,279 @@
1
- # @ingissa/navcore-core
2
-
3
- > **The navigation layer you own.** A framework-agnostic, zero-dependency navigation engine that runs everywhere — browsers, React Native, Node.js, and CI/CD.
4
-
5
- [![npm version](https://img.shields.io/npm/v/@ingissa/navcore-core)](https://www.npmjs.com/package/@ingissa/navcore-core)
6
- [![License](https://img.shields.io/badge/license-MIT%20%2F%20Commercial-purple)](https://navcore.dev/pricing)
7
- [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)](https://www.typescriptlang.org/)
8
- [![Zero deps](https://img.shields.io/badge/runtime_deps-0-brightgreen)](https://www.npmjs.com/package/@ingissa/navcore-core)
9
-
10
- ---
11
-
12
- ## Why NavCore?
13
-
14
- | Feature | NavCore | Mapbox Nav SDK | Google Maps |
15
- |---|---|---|---|
16
- | **Framework** | Any (pure TS) | React Native only | Platform-locked |
17
- | **Runtime deps** | 0 | 50+ | N/A |
18
- | **Map renderer** | BYO (adapter) | Mapbox GL only | Google Maps only |
19
- | **Directions** | BYO (adapter) | Mapbox API only | Google API only |
20
- | **Off-route detection** | Built-in FSM | Basic | Basic |
21
- | **U-turn protection** | ✅ Bearing penalty | ❌ | ❌ |
22
- | **Parallel road resolver** | ✅ Built-in | ❌ | ❌ |
23
- | **Dead reckoning** | ✅ Built-in | ❌ | ❌ |
24
- | **Geofencing** | ✅ Built-in | ❌ | Paid API |
25
- | **ETA** | ✅ Offline | API only | API only |
26
- | **Voice triggers** | ✅ Built-in | SDK only | ❌ |
27
- | **Headless testing** | ✅ Full pipeline | ❌ | ❌ |
28
- | **Custom routes** | ✅ GPX/GeoJSON/Builder | ❌ | ❌ |
29
- | **License** | Core MIT / Pro commercial | Commercial | Commercial |
30
-
31
- ---
32
-
33
- ## Tier Model
34
-
35
- NavCore uses a two-tier model controlled by a signed license key:
36
-
37
- | Tier | Import | License | Includes |
38
- |---|---|---|---|
39
- | **Core** | `@ingissa/navcore-core/core` | MIT — free forever | Geo utils, Kalman filter, route snapping, directions adapters, route builder |
40
- | **Pro** | `@ingissa/navcore-core/pro` | Commercial key required | Dead reckoning, advanced bearing, deviation detection, FSMs, voice, ETA, geofencing |
41
- | **Engine** | `@ingissa/navcore-core` | Gated internally at runtime | Full `NavCore` orchestrator (license key unlocks Pro features) |
42
-
43
- ---
44
-
45
- ## Installation
46
-
47
- ```bash
48
- npm install @ingissa/navcore-core
49
- ```
50
-
51
- ---
52
-
53
- ## Quick Start
54
-
55
- ### Core tier (no license needed)
56
-
57
- ```typescript
58
- import { NavCore } from '@ingissa/navcore-core';
59
- import { OSRMDirectionsProvider } from '@ingissa/navcore-core/core';
60
-
61
- // 1. Get a route from your self-hosted OSRM (free)
62
- const provider = new OSRMDirectionsProvider({ baseUrl: 'http://router.project-osrm.org' });
63
- const route = await provider.getRoute([[2.3522, 48.8566], [2.3400, 48.8700]]);
64
-
65
- // 2. Create engine (Core features work without a key)
66
- const engine = new NavCore();
67
- engine.setRoute(route.geometry);
68
- engine.startNavigation();
69
-
70
- // 3. Feed GPS updates
71
- engine.on('arrival', () => console.log('Arrived!'));
72
-
73
- navigator.geolocation.watchPosition(({ coords }) => {
74
- const state = engine.update({
75
- coord: [coords.longitude, coords.latitude],
76
- accuracy: coords.accuracy,
77
- bearing: coords.heading,
78
- speed: coords.speed ?? 0,
79
- timestamp: Date.now(),
80
- });
81
-
82
- console.log('Distance remaining:', state.distanceToDestination, 'm');
83
- });
84
- ```
85
-
86
- ### Pro tier (with license key)
87
-
88
- ```typescript
89
- import { NavCore } from '@ingissa/navcore-core';
90
-
91
- // Pro features unlock automatically with a valid key
92
- const engine = new NavCore({ licenseKey: 'your-signed-license-key' });
93
- engine.setRoute(routeCoords, instructions);
94
- engine.startNavigation();
95
-
96
- engine.on('instruction', (instr) => speak(instr.text)); // voice cues (PRO)
97
- engine.on('deviation', ({ anchorIndex }) => recalculate(anchorIndex));
98
- engine.on('arrival', () => console.log('Arrived!'));
99
- ```
100
-
101
- ### Using subpath imports directly
102
-
103
- ```typescript
104
- // Free MIT tier
105
- import { KalmanFilter2D } from '@ingissa/navcore-core/core';
106
- import { OSRMDirectionsProvider } from '@ingissa/navcore-core/core';
107
- import { CustomRouteBuilder } from '@ingissa/navcore-core/core';
108
-
109
- // Commercial Pro tier
110
- import { DeadReckoningEngine } from '@ingissa/navcore-core/pro';
111
- import { VoiceTriggerEngine } from '@ingissa/navcore-core/pro';
112
- import { ETAEngine } from '@ingissa/navcore-core/pro';
113
- import { GeofencingEngine } from '@ingissa/navcore-core/pro';
114
- ```
115
-
116
- ---
117
-
118
- ## Directions Providers (built-in, no extra install)
119
-
120
- ```typescript
121
- import {
122
- OSRMDirectionsProvider, // Self-hosted OSRM (recommended, free)
123
- ValhallaDirectionsProvider, // Self-hosted Valhalla (free)
124
- OpenRouteServiceProvider, // openrouteservice.org (free tier)
125
- } from '@ingissa/navcore-core/core';
126
-
127
- // OSRM
128
- const osrm = new OSRMDirectionsProvider({ baseUrl: 'http://router.project-osrm.org' });
129
- const route = await osrm.getRoute([[lng1, lat1], [lng2, lat2]]);
130
-
131
- // Valhalla
132
- const valhalla = new ValhallaDirectionsProvider({ baseUrl: 'https://valhalla1.openstreetmap.de' });
133
- const route = await valhalla.getRoute([[lng1, lat1], [lng2, lat2]], { costing: 'auto' });
134
- ```
135
-
136
- ---
137
-
138
- ## Renderer Adapters (separate packages)
139
-
140
- ```bash
141
- npm install @ingissa/navcore-maplibre # Web + MapLibre GL
142
- npm install @ingissa/navcore-leaflet # Web + Leaflet.js
143
- npm install @ingissa/navcore-google-maps # Google Maps JS API
144
- npm install @ingissa/navcore-mapbox # React Native + @rnmapbox/maps
145
- npm install @ingissa/navcore-react-native # React Native bindings
146
- npm install @ingissa/navcore-headless # Node.js / CI testing
147
- ```
148
-
149
- > ⚠️ Renderer adapter packages require a commercial license. [Get yours at navcore.dev/pricing](https://navcore.dev/pricing)
150
-
151
- ---
152
-
153
- ## Feature Reference
154
-
155
- ### CORE — free, MIT
156
-
157
- | Feature | API |
158
- |---|---|
159
- | GPS smoothing | `KalmanFilter2D` |
160
- | Route snapping | `RouteSnapper` |
161
- | Haversine & bearing | `haversineDistance`, `getBearingBetweenPoints` |
162
- | Cumulative distances | `buildForwardCumulativeDistances` |
163
- | Route builder | `CustomRouteBuilder` |
164
- | Directions — OSRM | `OSRMDirectionsProvider` |
165
- | Directions — Valhalla | `ValhallaDirectionsProvider` |
166
- | Directions — ORS | `OpenRouteServiceProvider` |
167
- | Renderer interface | `MapRendererAdapter` |
168
- | License verification | `LicenseManager` |
169
-
170
- ### PRO — commercial license required
171
-
172
- | Feature | API | FEATURES key |
173
- |---|---|---|
174
- | Advanced snapping (bearing + inertia) | `RouteSnapper` options | `ADVANCED_SNAPPING` |
175
- | Parallel road resolver | `ParallelRoadResolver` | `PARALLEL_ROAD_RESOLUTION` |
176
- | Dead reckoning | `DeadReckoningEngine` | `DEAD_RECKONING` |
177
- | Compound deviation detection | `DeviationDetector` | `COMPOUND_DEVIATION` |
178
- | Advanced bearing engine | `BearingEngine` | `ADVANCED_BEARING` |
179
- | Progress anti-regression | `ProgressTracker` | `PROGRESS_TRACKING` |
180
- | Route offset predictor | `RouteOffsetPredictor` | `ROUTE_OFFSET` |
181
- | Navigation lifecycle FSM | `NavigationFSM` | — |
182
- | Off-route FSM | `OffRouteFSM` | — |
183
- | Instruction editor | `InstructionEditor` | — |
184
- | Voice trigger engine | `VoiceTriggerEngine` | `VOICE_TRIGGERS` |
185
- | ETA engine (offline) | `ETAEngine` | `ETA` |
186
- | Geofencing engine | `GeofencingEngine` | `GEOFENCING` |
187
-
188
- ---
189
-
190
- ## License Gate Behaviour
191
-
192
- | Condition | Result |
193
- |---|---|
194
- | No `licenseKey` | Core features work; Pro features blocked with `console.warn` |
195
- | Valid Pro key | All features unlocked; `🔑 [NavCore] License validation complete. Plan: pro` logged |
196
- | `isDev: true` | All features bypassed (development mode) |
197
- | Expired / tampered key | Pro features blocked; status: `EXPIRED` / `INVALID` |
198
-
199
- License keys are verified **offline** using ECDSA P-256 — no network calls, no tracking.
200
-
201
- ---
202
-
203
- ## NavCore Engine API
204
-
205
- ```typescript
206
- const engine = new NavCore(options?: NavCoreOptions);
207
-
208
- // Setup
209
- engine.setRoute(coords: Coordinate[], instructions?: NavInstruction[]);
210
- engine.startNavigation();
211
-
212
- // GPS update (returns state snapshot)
213
- const state: NavCoreState = engine.update(gpsUpdate: NavGpsUpdate);
214
-
215
- // Render tick (call at ~60fps between GPS updates)
216
- engine.tick(nowMs: number);
217
-
218
- // Events
219
- engine.on('instruction', (instr: NavInstruction) => void);
220
- engine.on('deviation', ({ anchorIndex, ghostCoord }) => void);
221
- engine.on('arrival', () => void);
222
- engine.on('routeLoaded', ({ routeLength }) => void);
223
- engine.off(event, handler);
224
-
225
- // State & introspection
226
- engine.getState(): NavCoreState;
227
- engine.getLicenseManager(): LicenseManager;
228
- engine.getRoute(): ReadonlyArray<Coordinate>;
229
- engine.destroy();
230
- ```
231
-
232
- ### NavCoreState
233
-
234
- ```typescript
235
- interface NavCoreState {
236
- snappedCoord: Coordinate | null; // GPS-snapped position on route
237
- rawGpsCoord: Coordinate | null; // Raw GPS position
238
- bearing: number; // Smoothed heading (degrees)
239
- routeIndex: number; // Current segment index
240
- distanceToRoute: number; // Distance from route (metres)
241
- corridor: number; // Dynamic off-route threshold (metres)
242
- isOffRoute: boolean; // True when deviation confirmed
243
- hasArrived: boolean;
244
- distanceToDestination: number | null; // Remaining distance (metres)
245
- distanceToNextInstruction: number | null; // Distance to next turn
246
- nextInstructionIndex: number | null;
247
- currentSpeed: number; // m/s
248
- isGpsStale: boolean;
249
- gpsAgeMs: number;
250
- licenseStatus: string; // 'VALID' | 'INVALID' | 'EXPIRED' | 'MISSING'
251
- }
252
- ```
253
-
254
- ---
255
-
256
- ## Documentation
257
-
258
- | Guide | Link |
259
- |---|---|
260
- | Architecture | [docs/architecture.md](./docs/architecture.md) |
261
- | Getting Started | [docs/getting-started.md](./docs/getting-started.md) |
262
- | Directions Providers | [docs/directions-providers.md](./docs/directions-providers.md) |
263
- | Renderer Adapters | [docs/renderer-adapters.md](./docs/renderer-adapters.md) |
264
- | API Reference | [docs/api-reference.md](./docs/api-reference.md) |
265
- | Custom Routes | [docs/custom-routes.md](./docs/custom-routes.md) |
266
- | Instructions & Voice | [docs/instructions.md](./docs/instructions.md) |
267
- | Pro Features | [docs/p3-features.md](./docs/p3-features.md) |
268
- | Testing Guide | [docs/testing.md](./docs/testing.md) |
269
-
270
- ---
271
-
272
- ## License
273
-
274
- - **Core engine** (`@ingissa/navcore-core`): [MIT](./LICENSE) for open-source projects
275
- - **Pro features & adapters**: Commercial license required — [navcore.dev/pricing](https://navcore.dev/pricing)
276
-
277
- ---
278
-
279
- © Ingissa · [navcore.dev](https://navcore.dev) · [contact@navcore.dev](mailto:contact@navcore.dev)
1
+ # @ingissa/navcore-core
2
+
3
+ > **The navigation layer you own.** A framework-agnostic, zero-dependency navigation engine that runs everywhere — browsers, React Native, Node.js, and CI/CD.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@ingissa/navcore-core)](https://www.npmjs.com/package/@ingissa/navcore-core)
6
+ [![License](https://img.shields.io/badge/license-MIT%20%2F%20Commercial-purple)]()
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)](https://www.typescriptlang.org/)
8
+ [![Zero deps](https://img.shields.io/badge/runtime_deps-0-brightgreen)](https://www.npmjs.com/package/@ingissa/navcore-core)
9
+
10
+ ---
11
+
12
+ ## Why NavCore?
13
+
14
+ | Feature | NavCore | Mapbox Nav SDK | Google Maps |
15
+ |---|---|---|---|
16
+ | **Framework** | Any (pure TS) | React Native only | Platform-locked |
17
+ | **Runtime deps** | 0 | 50+ | N/A |
18
+ | **Map renderer** | BYO (adapter) | Mapbox GL only | Google Maps only |
19
+ | **Directions** | BYO (adapter) | Mapbox API only | Google API only |
20
+ | **Off-route detection** | Built-in FSM | Basic | Basic |
21
+ | **U-turn protection** | ✅ Bearing penalty | ❌ | ❌ |
22
+ | **Parallel road resolver** | ✅ Built-in | ❌ | ❌ |
23
+ | **Dead reckoning** | ✅ Built-in | ❌ | ❌ |
24
+ | **Geofencing** | ✅ Built-in | ❌ | Paid API |
25
+ | **ETA** | ✅ Offline | API only | API only |
26
+ | **Voice triggers** | ✅ Built-in | SDK only | ❌ |
27
+ | **Headless testing** | ✅ Full pipeline | ❌ | ❌ |
28
+ | **Custom routes** | ✅ GPX/GeoJSON/Builder | ❌ | ❌ |
29
+ | **License** | Core MIT / Pro commercial | Commercial | Commercial |
30
+
31
+ ---
32
+
33
+ ## Tier Model
34
+
35
+ NavCore uses a two-tier model controlled by a signed license key:
36
+
37
+ | Tier | Import | License | Includes |
38
+ |---|---|---|---|
39
+ | **Core** | `@ingissa/navcore-core/core` | MIT — free forever | Geo utils, Kalman filter, route snapping, directions adapters, route builder |
40
+ | **Pro** | `@ingissa/navcore-core/pro` | Commercial key required | Dead reckoning, advanced bearing, deviation detection, FSMs, voice, ETA, geofencing |
41
+ | **Engine** | `@ingissa/navcore-core` | Gated internally at runtime | Full `NavCore` orchestrator (license key unlocks Pro features) |
42
+
43
+ ---
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ npm install @ingissa/navcore-core
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Quick Start
54
+
55
+ ### Core tier (no license needed)
56
+
57
+ ```typescript
58
+ import { NavCore } from '@ingissa/navcore-core';
59
+ import { OSRMDirectionsProvider } from '@ingissa/navcore-core/core';
60
+
61
+ // 1. Get a route from your self-hosted OSRM (free)
62
+ const provider = new OSRMDirectionsProvider({ baseUrl: 'http://router.project-osrm.org' });
63
+ const route = await provider.getRoute([[2.3522, 48.8566], [2.3400, 48.8700]]);
64
+
65
+ // 2. Create engine (Core features work without a key)
66
+ const engine = new NavCore();
67
+ engine.setRoute(route.geometry);
68
+ engine.startNavigation();
69
+
70
+ // 3. Feed GPS updates
71
+ engine.on('arrival', () => console.log('Arrived!'));
72
+
73
+ navigator.geolocation.watchPosition(({ coords }) => {
74
+ const state = engine.update({
75
+ coord: [coords.longitude, coords.latitude],
76
+ accuracy: coords.accuracy,
77
+ bearing: coords.heading,
78
+ speed: coords.speed ?? 0,
79
+ timestamp: Date.now(),
80
+ });
81
+
82
+ console.log('Distance remaining:', state.distanceToDestination, 'm');
83
+ });
84
+ ```
85
+
86
+ ### Pro tier (with license key)
87
+
88
+ ```typescript
89
+ import { NavCore } from '@ingissa/navcore-core';
90
+
91
+ // Pro features unlock automatically with a valid key
92
+ const engine = new NavCore({ licenseKey: 'your-signed-license-key' });
93
+ engine.setRoute(routeCoords, instructions);
94
+ engine.startNavigation();
95
+
96
+ engine.on('instruction', (instr) => speak(instr.text)); // voice cues (PRO)
97
+ engine.on('deviation', ({ anchorIndex }) => recalculate(anchorIndex));
98
+ engine.on('arrival', () => console.log('Arrived!'));
99
+ ```
100
+
101
+ ### Using subpath imports directly
102
+
103
+ ```typescript
104
+ // Free MIT tier
105
+ import { KalmanFilter2D } from '@ingissa/navcore-core/core';
106
+ import { OSRMDirectionsProvider } from '@ingissa/navcore-core/core';
107
+ import { CustomRouteBuilder } from '@ingissa/navcore-core/core';
108
+
109
+ // Commercial Pro tier
110
+ import { DeadReckoningEngine } from '@ingissa/navcore-core/pro';
111
+ import { VoiceTriggerEngine } from '@ingissa/navcore-core/pro';
112
+ import { ETAEngine } from '@ingissa/navcore-core/pro';
113
+ import { GeofencingEngine } from '@ingissa/navcore-core/pro';
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Directions Providers (built-in, no extra install)
119
+
120
+ ```typescript
121
+ import {
122
+ OSRMDirectionsProvider, // Self-hosted OSRM (recommended, free)
123
+ ValhallaDirectionsProvider, // Self-hosted Valhalla (free)
124
+ OpenRouteServiceProvider, // openrouteservice.org (free tier)
125
+ } from '@ingissa/navcore-core/core';
126
+
127
+ // OSRM
128
+ const osrm = new OSRMDirectionsProvider({ baseUrl: 'http://router.project-osrm.org' });
129
+ const route = await osrm.getRoute([[lng1, lat1], [lng2, lat2]]);
130
+
131
+ // Valhalla
132
+ const valhalla = new ValhallaDirectionsProvider({ baseUrl: 'https://valhalla1.openstreetmap.de' });
133
+ const route = await valhalla.getRoute([[lng1, lat1], [lng2, lat2]], { costing: 'auto' });
134
+ ```
135
+
136
+ ---
137
+
138
+ ## Renderer Adapters (separate packages)
139
+
140
+ ```bash
141
+ npm install @ingissa/navcore-maplibre # Web + MapLibre GL
142
+ npm install @ingissa/navcore-leaflet # Web + Leaflet.js
143
+ npm install @ingissa/navcore-google-maps # Google Maps JS API
144
+ npm install @ingissa/navcore-mapbox # React Native + @rnmapbox/maps
145
+ npm install @ingissa/navcore-react-native # React Native bindings
146
+ npm install @ingissa/navcore-headless # Node.js / CI testing
147
+ ```
148
+
149
+ > ⚠️ Renderer adapter packages require a commercial license. [Get yours at Not yet available]()
150
+
151
+ ---
152
+
153
+ ## Feature Reference
154
+
155
+ ### CORE — free, MIT
156
+
157
+ | Feature | API |
158
+ |---|---|
159
+ | GPS smoothing | `KalmanFilter2D` |
160
+ | Route snapping | `RouteSnapper` |
161
+ | Haversine & bearing | `haversineDistance`, `getBearingBetweenPoints` |
162
+ | Cumulative distances | `buildForwardCumulativeDistances` |
163
+ | Route builder | `CustomRouteBuilder` |
164
+ | Directions — OSRM | `OSRMDirectionsProvider` |
165
+ | Directions — Valhalla | `ValhallaDirectionsProvider` |
166
+ | Directions — ORS | `OpenRouteServiceProvider` |
167
+ | Renderer interface | `MapRendererAdapter` |
168
+ | License verification | `LicenseManager` |
169
+
170
+ ### PRO — commercial license required
171
+
172
+ | Feature | API | FEATURES key |
173
+ |---|---|---|
174
+ | Advanced snapping (bearing + inertia) | `RouteSnapper` options | `ADVANCED_SNAPPING` |
175
+ | Parallel road resolver | `ParallelRoadResolver` | `PARALLEL_ROAD_RESOLUTION` |
176
+ | Dead reckoning | `DeadReckoningEngine` | `DEAD_RECKONING` |
177
+ | Compound deviation detection | `DeviationDetector` | `COMPOUND_DEVIATION` |
178
+ | Advanced bearing engine | `BearingEngine` | `ADVANCED_BEARING` |
179
+ | Progress anti-regression | `ProgressTracker` | `PROGRESS_TRACKING` |
180
+ | Route offset predictor | `RouteOffsetPredictor` | `ROUTE_OFFSET` |
181
+ | Navigation lifecycle FSM | `NavigationFSM` | — |
182
+ | Off-route FSM | `OffRouteFSM` | — |
183
+ | Instruction editor | `InstructionEditor` | — |
184
+ | Voice trigger engine | `VoiceTriggerEngine` | `VOICE_TRIGGERS` |
185
+ | ETA engine (offline) | `ETAEngine` | `ETA` |
186
+ | Geofencing engine | `GeofencingEngine` | `GEOFENCING` |
187
+
188
+ ---
189
+
190
+ ## License Gate Behaviour
191
+
192
+ | Condition | Result |
193
+ |---|---|
194
+ | No `licenseKey` | Core features work; Pro features blocked with `console.warn` |
195
+ | Valid Pro key | All features unlocked; `🔑 [NavCore] License validation complete. Plan: pro` logged |
196
+ | `isDev: true` | All features bypassed (development mode) |
197
+ | Expired / tampered key | Pro features blocked; status: `EXPIRED` / `INVALID` |
198
+
199
+ License keys are verified **offline** using ECDSA P-256 — no network calls, no tracking.
200
+
201
+ ---
202
+
203
+ ## NavCore Engine API
204
+
205
+ ```typescript
206
+ const engine = new NavCore(options?: NavCoreOptions);
207
+
208
+ // Setup
209
+ engine.setRoute(coords: Coordinate[], instructions?: NavInstruction[]);
210
+ engine.startNavigation();
211
+
212
+ // GPS update (returns state snapshot)
213
+ const state: NavCoreState = engine.update(gpsUpdate: NavGpsUpdate);
214
+
215
+ // Render tick (call at ~60fps between GPS updates)
216
+ engine.tick(nowMs: number);
217
+
218
+ // Events
219
+ engine.on('instruction', (instr: NavInstruction) => void);
220
+ engine.on('deviation', ({ anchorIndex, ghostCoord }) => void);
221
+ engine.on('arrival', () => void);
222
+ engine.on('routeLoaded', ({ routeLength }) => void);
223
+ engine.off(event, handler);
224
+
225
+ // State & introspection
226
+ engine.getState(): NavCoreState;
227
+ engine.getLicenseManager(): LicenseManager;
228
+ engine.getRoute(): ReadonlyArray<Coordinate>;
229
+ engine.destroy();
230
+ ```
231
+
232
+ ### NavCoreState
233
+
234
+ ```typescript
235
+ interface NavCoreState {
236
+ snappedCoord: Coordinate | null; // GPS-snapped position on route
237
+ rawGpsCoord: Coordinate | null; // Raw GPS position
238
+ bearing: number; // Smoothed heading (degrees)
239
+ routeIndex: number; // Current segment index
240
+ distanceToRoute: number; // Distance from route (metres)
241
+ corridor: number; // Dynamic off-route threshold (metres)
242
+ isOffRoute: boolean; // True when deviation confirmed
243
+ hasArrived: boolean;
244
+ distanceToDestination: number | null; // Remaining distance (metres)
245
+ distanceToNextInstruction: number | null; // Distance to next turn
246
+ nextInstructionIndex: number | null;
247
+ currentSpeed: number; // m/s
248
+ isGpsStale: boolean;
249
+ gpsAgeMs: number;
250
+ licenseStatus: string; // 'VALID' | 'INVALID' | 'EXPIRED' | 'MISSING'
251
+ }
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Documentation
257
+
258
+ | Guide | Link |
259
+ |---|---|
260
+ | Architecture | [docs/architecture.md](./docs/architecture.md) |
261
+ | Getting Started | [docs/getting-started.md](./docs/getting-started.md) |
262
+ | Directions Providers | [docs/directions-providers.md](./docs/directions-providers.md) |
263
+ | Renderer Adapters | [docs/renderer-adapters.md](./docs/renderer-adapters.md) |
264
+ | API Reference | [docs/api-reference.md](./docs/api-reference.md) |
265
+ | Custom Routes | [docs/custom-routes.md](./docs/custom-routes.md) |
266
+ | Instructions & Voice | [docs/instructions.md](./docs/instructions.md) |
267
+ | Pro Features | [docs/p3-features.md](./docs/p3-features.md) |
268
+ | Testing Guide | [docs/testing.md](./docs/testing.md) |
269
+
270
+ ---
271
+
272
+ ## License
273
+
274
+ - **Core engine** (`@ingissa/navcore-core`): [MIT](./LICENSE) for open-source projects
275
+ - **Pro features & adapters**: Commercial license required — [Not yet available]()
276
+
277
+ ---
278
+
279
+ © Ingissa · [8abnav@gmail.com](mailto:8abnav@gmail.com)