@ingissa/navcore-simulator 1.0.8 → 1.0.10

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.
Files changed (170) hide show
  1. package/LICENSE +3 -3
  2. package/README.md +161 -356
  3. package/dist/index.d.mts +87 -0
  4. package/dist/{simulator/src/react-native/useSimulator.d.ts → index.d.ts} +37 -9
  5. package/dist/index.js +1393 -0
  6. package/dist/index.mjs +1383 -0
  7. package/dist/node.d.mts +527 -0
  8. package/dist/node.d.ts +527 -0
  9. package/dist/node.js +957 -0
  10. package/dist/node.mjs +949 -0
  11. package/dist/react-native.d.mts +4 -0
  12. package/dist/react-native.d.ts +4 -0
  13. package/dist/react-native.js +1393 -0
  14. package/dist/react-native.mjs +1383 -0
  15. package/package.json +61 -58
  16. package/dist/core/src/NavCore.d.ts +0 -142
  17. package/dist/core/src/NavCore.d.ts.map +0 -1
  18. package/dist/core/src/NavCore.js +0 -390
  19. package/dist/core/src/bearing/BearingEngine.d.ts +0 -24
  20. package/dist/core/src/bearing/BearingEngine.d.ts.map +0 -1
  21. package/dist/core/src/bearing/BearingEngine.js +0 -50
  22. package/dist/core/src/constants.d.ts +0 -34
  23. package/dist/core/src/constants.d.ts.map +0 -1
  24. package/dist/core/src/constants.js +0 -41
  25. package/dist/core/src/corridor/DeviationDetector.d.ts +0 -33
  26. package/dist/core/src/corridor/DeviationDetector.d.ts.map +0 -1
  27. package/dist/core/src/corridor/DeviationDetector.js +0 -83
  28. package/dist/core/src/corridor/DynamicCorridor.d.ts +0 -13
  29. package/dist/core/src/corridor/DynamicCorridor.d.ts.map +0 -1
  30. package/dist/core/src/corridor/DynamicCorridor.js +0 -26
  31. package/dist/core/src/dead-reckoning/DeadReckoning.d.ts +0 -35
  32. package/dist/core/src/dead-reckoning/DeadReckoning.d.ts.map +0 -1
  33. package/dist/core/src/dead-reckoning/DeadReckoning.js +0 -49
  34. package/dist/core/src/directions/DirectionsProvider.d.ts +0 -70
  35. package/dist/core/src/directions/DirectionsProvider.d.ts.map +0 -1
  36. package/dist/core/src/directions/DirectionsProvider.js +0 -7
  37. package/dist/core/src/directions/OSRMDirectionsProvider.d.ts +0 -26
  38. package/dist/core/src/directions/OSRMDirectionsProvider.d.ts.map +0 -1
  39. package/dist/core/src/directions/OSRMDirectionsProvider.js +0 -90
  40. package/dist/core/src/directions/OpenRouteServiceProvider.d.ts +0 -30
  41. package/dist/core/src/directions/OpenRouteServiceProvider.d.ts.map +0 -1
  42. package/dist/core/src/directions/OpenRouteServiceProvider.js +0 -111
  43. package/dist/core/src/directions/ValhallaDirectionsProvider.d.ts +0 -33
  44. package/dist/core/src/directions/ValhallaDirectionsProvider.d.ts.map +0 -1
  45. package/dist/core/src/directions/ValhallaDirectionsProvider.js +0 -155
  46. package/dist/core/src/eta/ETAEngine.d.ts +0 -61
  47. package/dist/core/src/eta/ETAEngine.d.ts.map +0 -1
  48. package/dist/core/src/eta/ETAEngine.js +0 -74
  49. package/dist/core/src/features.d.ts +0 -76
  50. package/dist/core/src/features.d.ts.map +0 -1
  51. package/dist/core/src/features.js +0 -76
  52. package/dist/core/src/geo/bearing.d.ts +0 -11
  53. package/dist/core/src/geo/bearing.d.ts.map +0 -1
  54. package/dist/core/src/geo/bearing.js +0 -25
  55. package/dist/core/src/geo/cumulative.d.ts +0 -9
  56. package/dist/core/src/geo/cumulative.d.ts.map +0 -1
  57. package/dist/core/src/geo/cumulative.js +0 -20
  58. package/dist/core/src/geo/haversine.d.ts +0 -13
  59. package/dist/core/src/geo/haversine.d.ts.map +0 -1
  60. package/dist/core/src/geo/haversine.js +0 -39
  61. package/dist/core/src/geo/projection.d.ts +0 -7
  62. package/dist/core/src/geo/projection.d.ts.map +0 -1
  63. package/dist/core/src/geo/projection.js +0 -17
  64. package/dist/core/src/geofencing/GeofencingEngine.d.ts +0 -93
  65. package/dist/core/src/geofencing/GeofencingEngine.d.ts.map +0 -1
  66. package/dist/core/src/geofencing/GeofencingEngine.js +0 -154
  67. package/dist/core/src/index.d.ts +0 -66
  68. package/dist/core/src/index.d.ts.map +0 -1
  69. package/dist/core/src/index.js +0 -62
  70. package/dist/core/src/kalman/KalmanFilter2D.d.ts +0 -46
  71. package/dist/core/src/kalman/KalmanFilter2D.d.ts.map +0 -1
  72. package/dist/core/src/kalman/KalmanFilter2D.js +0 -77
  73. package/dist/core/src/license/LicenseManager.d.ts +0 -40
  74. package/dist/core/src/license/LicenseManager.d.ts.map +0 -1
  75. package/dist/core/src/license/LicenseManager.js +0 -119
  76. package/dist/core/src/license/verifyP256Signature.d.ts +0 -2
  77. package/dist/core/src/license/verifyP256Signature.d.ts.map +0 -1
  78. package/dist/core/src/license/verifyP256Signature.js +0 -26
  79. package/dist/core/src/off-route/NavigationFSM.d.ts +0 -42
  80. package/dist/core/src/off-route/NavigationFSM.d.ts.map +0 -1
  81. package/dist/core/src/off-route/NavigationFSM.js +0 -56
  82. package/dist/core/src/off-route/OffRouteFSM.d.ts +0 -70
  83. package/dist/core/src/off-route/OffRouteFSM.d.ts.map +0 -1
  84. package/dist/core/src/off-route/OffRouteFSM.js +0 -151
  85. package/dist/core/src/predictor/RouteOffsetPredictor.d.ts +0 -24
  86. package/dist/core/src/predictor/RouteOffsetPredictor.d.ts.map +0 -1
  87. package/dist/core/src/predictor/RouteOffsetPredictor.js +0 -55
  88. package/dist/core/src/progress/InstructionEditor.d.ts +0 -77
  89. package/dist/core/src/progress/InstructionEditor.d.ts.map +0 -1
  90. package/dist/core/src/progress/InstructionEditor.js +0 -151
  91. package/dist/core/src/progress/InstructionResolver.d.ts +0 -25
  92. package/dist/core/src/progress/InstructionResolver.d.ts.map +0 -1
  93. package/dist/core/src/progress/InstructionResolver.js +0 -78
  94. package/dist/core/src/progress/ProgressTracker.d.ts +0 -12
  95. package/dist/core/src/progress/ProgressTracker.d.ts.map +0 -1
  96. package/dist/core/src/progress/ProgressTracker.js +0 -22
  97. package/dist/core/src/renderer/MapRendererAdapter.d.ts +0 -72
  98. package/dist/core/src/renderer/MapRendererAdapter.d.ts.map +0 -1
  99. package/dist/core/src/renderer/MapRendererAdapter.js +0 -19
  100. package/dist/core/src/route-builder/CustomRouteBuilder.d.ts +0 -83
  101. package/dist/core/src/route-builder/CustomRouteBuilder.d.ts.map +0 -1
  102. package/dist/core/src/route-builder/CustomRouteBuilder.js +0 -160
  103. package/dist/core/src/route-plan/RoutePlan.d.ts +0 -38
  104. package/dist/core/src/route-plan/RoutePlan.d.ts.map +0 -1
  105. package/dist/core/src/route-plan/RoutePlan.js +0 -102
  106. package/dist/core/src/session/NavigationSession.d.ts +0 -81
  107. package/dist/core/src/session/NavigationSession.d.ts.map +0 -1
  108. package/dist/core/src/session/NavigationSession.js +0 -115
  109. package/dist/core/src/snapper/ParallelRoadResolver.d.ts +0 -86
  110. package/dist/core/src/snapper/ParallelRoadResolver.d.ts.map +0 -1
  111. package/dist/core/src/snapper/ParallelRoadResolver.js +0 -83
  112. package/dist/core/src/snapper/RouteSnapper.d.ts +0 -38
  113. package/dist/core/src/snapper/RouteSnapper.d.ts.map +0 -1
  114. package/dist/core/src/snapper/RouteSnapper.js +0 -80
  115. package/dist/core/src/voice/VoiceTriggerEngine.d.ts +0 -80
  116. package/dist/core/src/voice/VoiceTriggerEngine.d.ts.map +0 -1
  117. package/dist/core/src/voice/VoiceTriggerEngine.js +0 -108
  118. package/dist/simulator/src/core/NoiseEngine.d.ts +0 -46
  119. package/dist/simulator/src/core/NoiseEngine.d.ts.map +0 -1
  120. package/dist/simulator/src/core/NoiseEngine.js +0 -106
  121. package/dist/simulator/src/core/RouteWalker.d.ts +0 -78
  122. package/dist/simulator/src/core/RouteWalker.d.ts.map +0 -1
  123. package/dist/simulator/src/core/RouteWalker.js +0 -180
  124. package/dist/simulator/src/core/SimulatorEngine.d.ts +0 -53
  125. package/dist/simulator/src/core/SimulatorEngine.d.ts.map +0 -1
  126. package/dist/simulator/src/core/SimulatorEngine.js +0 -298
  127. package/dist/simulator/src/core/types.d.ts +0 -157
  128. package/dist/simulator/src/core/types.d.ts.map +0 -1
  129. package/dist/simulator/src/core/types.js +0 -7
  130. package/dist/simulator/src/fleet/FleetSimulator.d.ts +0 -60
  131. package/dist/simulator/src/fleet/FleetSimulator.d.ts.map +0 -1
  132. package/dist/simulator/src/fleet/FleetSimulator.js +0 -114
  133. package/dist/simulator/src/index.d.ts +0 -28
  134. package/dist/simulator/src/index.d.ts.map +0 -1
  135. package/dist/simulator/src/index.js +0 -29
  136. package/dist/simulator/src/node.d.ts +0 -26
  137. package/dist/simulator/src/node.d.ts.map +0 -1
  138. package/dist/simulator/src/node.js +0 -25
  139. package/dist/simulator/src/react-native/SimulatorControls.d.ts +0 -35
  140. package/dist/simulator/src/react-native/SimulatorControls.d.ts.map +0 -1
  141. package/dist/simulator/src/react-native/SimulatorControls.js +0 -254
  142. package/dist/simulator/src/react-native/useSimulator.d.ts.map +0 -1
  143. package/dist/simulator/src/react-native/useSimulator.js +0 -100
  144. package/dist/simulator/src/replay/GpxParser.d.ts +0 -40
  145. package/dist/simulator/src/replay/GpxParser.d.ts.map +0 -1
  146. package/dist/simulator/src/replay/GpxParser.js +0 -95
  147. package/dist/simulator/src/replay/SessionRecorder.d.ts +0 -37
  148. package/dist/simulator/src/replay/SessionRecorder.d.ts.map +0 -1
  149. package/dist/simulator/src/replay/SessionRecorder.js +0 -120
  150. package/dist/simulator/src/scenarios/ScenarioInjector.d.ts +0 -55
  151. package/dist/simulator/src/scenarios/ScenarioInjector.d.ts.map +0 -1
  152. package/dist/simulator/src/scenarios/ScenarioInjector.js +0 -150
  153. package/src/__tests__/integration/simulator-pipeline.test.ts +0 -233
  154. package/src/core/NoiseEngine.ts +0 -137
  155. package/src/core/RouteWalker.ts +0 -227
  156. package/src/core/SimulatorEngine.ts +0 -364
  157. package/src/core/__tests__/NoiseEngine.test.ts +0 -131
  158. package/src/core/__tests__/RouteWalker.test.ts +0 -139
  159. package/src/core/__tests__/SimulatorEngine.test.ts +0 -317
  160. package/src/core/types.ts +0 -191
  161. package/src/fleet/FleetSimulator.ts +0 -162
  162. package/src/index.ts +0 -54
  163. package/src/node.ts +0 -48
  164. package/src/react-native/SimulatorControls.tsx +0 -473
  165. package/src/react-native/useSimulator.ts +0 -155
  166. package/src/replay/GpxParser.ts +0 -122
  167. package/src/replay/SessionRecorder.ts +0 -138
  168. package/src/replay/__tests__/GpxParser.test.ts +0 -136
  169. package/src/scenarios/ScenarioInjector.ts +0 -170
  170. package/src/scenarios/__tests__/ScenarioInjector.test.ts +0 -171
@@ -1,40 +0,0 @@
1
- /**
2
- * LicenseManager — Handles offline asymmetric license verification
3
- * using P-256 + granular feature licensing.
4
- *
5
- * Matching nav-sdk/src/shared/LicenseManager.ts contract exactly.
6
- */
7
- import { FeatureKey } from '../features';
8
- export type LicenseStatus = 'VALID' | 'INVALID' | 'EXPIRED' | 'MISSING';
9
- export interface LicensePayload {
10
- /** Legacy tier — 'pro' grants all features ('*') */
11
- t?: 'core' | 'pro';
12
- /** Expiration timestamp (ms since epoch) */
13
- exp: number;
14
- /** Bundle ID / domain */
15
- bid: string;
16
- /** Granular feature flags */
17
- f?: string[];
18
- }
19
- export declare class LicenseManager {
20
- private status;
21
- private payload;
22
- private enabledFeatures;
23
- private warnedFeatures;
24
- private isDev;
25
- private static PUBLIC_KEY_RAW;
26
- constructor(licenseKey?: string, isDev?: boolean);
27
- validate(key: string): Promise<LicenseStatus>;
28
- private extractFeatures;
29
- hasFeature(feature: FeatureKey): boolean;
30
- /** Warn once per feature when a consumer tries to use a gated feature. */
31
- warnOnce(feature: FeatureKey): void;
32
- /** Returns true if the license grants the full Pro tier (all features). */
33
- isProEnabled(): boolean;
34
- isAIEnabled(): boolean;
35
- getStatus(): LicenseStatus;
36
- getPayload(): LicensePayload | null;
37
- getEnabledFeatures(): string[];
38
- private verifySignature;
39
- }
40
- //# sourceMappingURL=LicenseManager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LicenseManager.d.ts","sourceRoot":"","sources":["../../../../../core/src/license/LicenseManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAY,UAAU,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAExE,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,CAAC,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACnB,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,6BAA6B;IAC7B,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;CACd;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,KAAK,CAAkB;IAG/B,OAAO,CAAC,MAAM,CAAC,cAAc,CACgE;gBAEjF,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;IASnC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA4C1D,OAAO,CAAC,eAAe;IAiBhB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO;IAO/C,0EAA0E;IACnE,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAU1C,2EAA2E;IACpE,YAAY,IAAI,OAAO;IAKvB,WAAW,IAAI,OAAO;IAItB,SAAS,IAAI,aAAa;IAI1B,UAAU,IAAI,cAAc,GAAG,IAAI;IAInC,kBAAkB,IAAI,MAAM,EAAE;YAMvB,eAAe;CAe9B"}
@@ -1,119 +0,0 @@
1
- /**
2
- * LicenseManager — Handles offline asymmetric license verification
3
- * using P-256 + granular feature licensing.
4
- *
5
- * Matching nav-sdk/src/shared/LicenseManager.ts contract exactly.
6
- */
7
- import { FEATURES } from '../features';
8
- import { verifyP256Signature } from './verifyP256Signature';
9
- export class LicenseManager {
10
- constructor(licenseKey, isDev) {
11
- this.status = 'MISSING';
12
- this.payload = null;
13
- this.enabledFeatures = new Set();
14
- this.warnedFeatures = new Set();
15
- this.isDev = false;
16
- this.isDev = isDev ?? false;
17
- if (licenseKey) {
18
- this.validate(licenseKey);
19
- }
20
- }
21
- // ── Validation ──────────────────────────────────────────────────────────────
22
- async validate(key) {
23
- try {
24
- if (this.status === 'VALID' && this.payload?.bid === 'dev.bypass') {
25
- return 'VALID'; // Already bypassed synchronously
26
- }
27
- const [payloadB64, signatureB64] = key.split('.');
28
- if (!payloadB64 || !signatureB64) {
29
- this.status = 'INVALID';
30
- return this.status;
31
- }
32
- const payloadStr = atob(payloadB64);
33
- this.payload = JSON.parse(payloadStr);
34
- // Expiration check
35
- if (!this.payload || this.payload.exp < Date.now()) {
36
- this.status = 'EXPIRED';
37
- return this.status;
38
- }
39
- // Signature check
40
- const isValid = await this.verifySignature(payloadB64, signatureB64);
41
- if (!isValid) {
42
- this.status = 'INVALID';
43
- return this.status;
44
- }
45
- this.status = 'VALID';
46
- this.extractFeatures();
47
- console.log(`🔑 [NavCore] License validation complete. Plan: ${this.isProEnabled() ? 'pro' : 'core'}`);
48
- }
49
- catch {
50
- this.status = 'INVALID';
51
- }
52
- return this.status;
53
- }
54
- // ── Feature system ──────────────────────────────────────────────────────────
55
- extractFeatures() {
56
- this.enabledFeatures.clear();
57
- if (!this.payload)
58
- return;
59
- // New granular feature flags
60
- if (Array.isArray(this.payload.f)) {
61
- for (const f of this.payload.f) {
62
- this.enabledFeatures.add(f);
63
- }
64
- }
65
- // Backward compatibility: pro tier = all features
66
- if (this.payload.t === 'pro') {
67
- this.enabledFeatures.add('*');
68
- }
69
- }
70
- hasFeature(feature) {
71
- if (this.isDev)
72
- return true;
73
- if (this.status !== 'VALID')
74
- return false;
75
- if (this.enabledFeatures.has('*'))
76
- return true;
77
- return this.enabledFeatures.has(feature);
78
- }
79
- /** Warn once per feature when a consumer tries to use a gated feature. */
80
- warnOnce(feature) {
81
- if (this.warnedFeatures.has(feature))
82
- return;
83
- console.warn(`[NavCore] Feature '${feature}' requires a Pro license`);
84
- this.warnedFeatures.add(feature);
85
- }
86
- // ── Legacy / convenience helpers ────────────────────────────────────────────
87
- /** Returns true if the license grants the full Pro tier (all features). */
88
- isProEnabled() {
89
- // Matches nav-sdk: checks for the wildcard '*' grant, not a specific feature
90
- return this.hasFeature('*');
91
- }
92
- isAIEnabled() {
93
- return this.hasFeature(FEATURES.NAV_AI);
94
- }
95
- getStatus() {
96
- return this.status;
97
- }
98
- getPayload() {
99
- return this.payload;
100
- }
101
- getEnabledFeatures() {
102
- return Array.from(this.enabledFeatures);
103
- }
104
- // ── Crypto ──────────────────────────────────────────────────────────────────
105
- async verifySignature(data, signature) {
106
- try {
107
- const encoder = new TextEncoder();
108
- const encodedData = encoder.encode(data);
109
- const signatureBin = Uint8Array.from(atob(signature), c => c.charCodeAt(0));
110
- const publicKeyBin = Uint8Array.from(atob(LicenseManager.PUBLIC_KEY_RAW), c => c.charCodeAt(0));
111
- return await verifyP256Signature(encodedData, signatureBin, publicKeyBin);
112
- }
113
- catch {
114
- return false;
115
- }
116
- }
117
- }
118
- // SEC1 uncompressed form of the shared ECDSA P-256 public key.
119
- LicenseManager.PUBLIC_KEY_RAW = 'BJOqJyZiZFrURbrIkkuvXXHTjV+MS9kp5uAGTvnWI0sp3yYi+Me7axMvNDCJi37ZJwVk/6iNM+6MeEO1TS97Xug=';
@@ -1,2 +0,0 @@
1
- export declare function verifyP256Signature(message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): Promise<boolean>;
2
- //# sourceMappingURL=verifyP256Signature.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"verifyP256Signature.d.ts","sourceRoot":"","sources":["../../../../../core/src/license/verifyP256Signature.ts"],"names":[],"mappings":"AAQA,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,UAAU,EACrB,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,OAAO,CAAC,CA+BlB"}
@@ -1,26 +0,0 @@
1
- import { p256 } from '@noble/curves/nist.js';
2
- function toArrayBuffer(bytes) {
3
- const buffer = new ArrayBuffer(bytes.byteLength);
4
- new Uint8Array(buffer).set(bytes);
5
- return buffer;
6
- }
7
- export async function verifyP256Signature(message, signature, publicKey) {
8
- if (signature.length !== 64 || publicKey.length !== 65 || publicKey[0] !== 4) {
9
- return false;
10
- }
11
- try {
12
- const subtle = typeof crypto !== 'undefined' ? crypto.subtle : undefined;
13
- if (subtle) {
14
- const importedKey = await subtle.importKey('raw', toArrayBuffer(publicKey), { name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify']);
15
- return await subtle.verify({ name: 'ECDSA', hash: { name: 'SHA-256' } }, importedKey, toArrayBuffer(signature), toArrayBuffer(message));
16
- }
17
- return p256.verify(signature, message, publicKey, {
18
- format: 'compact',
19
- lowS: false,
20
- prehash: true,
21
- });
22
- }
23
- catch {
24
- return false;
25
- }
26
- }
@@ -1,42 +0,0 @@
1
- /**
2
- * Module 9a: NavigationFSM
3
- * Navigation lifecycle state machine. Pure deterministic transitions.
4
- */
5
- export type NavLifecycleState = 'IDLE' | 'OVERVIEW' | 'APPROACHING_ROUTE' | 'ON_ROUTE';
6
- export type LifecycleEvent = {
7
- type: 'ROUTE_LOADED';
8
- } | {
9
- type: 'USER_START_NAVIGATION';
10
- } | {
11
- type: 'ROUTE_JOINED';
12
- data: {
13
- index: number;
14
- };
15
- } | {
16
- type: 'NAVIGATION_FINISHED';
17
- } | {
18
- type: 'CANCEL_NAVIGATION';
19
- } | {
20
- type: 'RESET';
21
- };
22
- export interface LifecycleContext {
23
- resumeIndex: number | null;
24
- }
25
- export interface LifecycleOutput {
26
- state: NavLifecycleState;
27
- context: LifecycleContext;
28
- }
29
- /**
30
- * Pure lifecycle FSM — no React, no side effects.
31
- */
32
- export declare class NavigationFSM {
33
- private _state;
34
- private _context;
35
- get state(): NavLifecycleState;
36
- get context(): LifecycleContext;
37
- /** Dispatch an event and return the new output */
38
- dispatch(event: LifecycleEvent): LifecycleOutput;
39
- /** Reset to initial state */
40
- reset(): void;
41
- }
42
- //# sourceMappingURL=NavigationFSM.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NavigationFSM.d.ts","sourceRoot":"","sources":["../../../../../core/src/off-route/NavigationFSM.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,UAAU,GACV,mBAAmB,GACnB,UAAU,CAAC;AAEf,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,uBAAuB,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtB,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,iBAAiB,CAAC;IACzB,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,QAAQ,CAA2C;IAE3D,IAAI,KAAK,IAAI,iBAAiB,CAAwB;IACtD,IAAI,OAAO,IAAI,gBAAgB,CAAiC;IAEhE,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe;IAqChD,6BAA6B;IAC7B,KAAK,IAAI,IAAI;CAId"}
@@ -1,56 +0,0 @@
1
- /**
2
- * Module 9a: NavigationFSM
3
- * Navigation lifecycle state machine. Pure deterministic transitions.
4
- */
5
- /**
6
- * Pure lifecycle FSM — no React, no side effects.
7
- */
8
- export class NavigationFSM {
9
- constructor() {
10
- this._state = 'IDLE';
11
- this._context = { resumeIndex: null };
12
- }
13
- get state() { return this._state; }
14
- get context() { return { ...this._context }; }
15
- /** Dispatch an event and return the new output */
16
- dispatch(event) {
17
- const prev = this._state;
18
- switch (prev) {
19
- case 'IDLE':
20
- if (event.type === 'ROUTE_LOADED')
21
- this._state = 'OVERVIEW';
22
- if (event.type === 'USER_START_NAVIGATION')
23
- this._state = 'APPROACHING_ROUTE';
24
- break;
25
- case 'OVERVIEW':
26
- if (event.type === 'USER_START_NAVIGATION')
27
- this._state = 'APPROACHING_ROUTE';
28
- break;
29
- case 'APPROACHING_ROUTE':
30
- if (event.type === 'ROUTE_JOINED') {
31
- this._state = 'ON_ROUTE';
32
- this._context.resumeIndex = event.data.index;
33
- }
34
- if (event.type === 'NAVIGATION_FINISHED')
35
- this._state = 'IDLE';
36
- break;
37
- case 'ON_ROUTE':
38
- if (event.type === 'NAVIGATION_FINISHED')
39
- this._state = 'IDLE';
40
- if (event.type === 'ROUTE_JOINED') {
41
- this._context.resumeIndex = event.data.index;
42
- }
43
- break;
44
- }
45
- if (event.type === 'RESET' || event.type === 'CANCEL_NAVIGATION') {
46
- this._state = 'IDLE';
47
- this._context = { resumeIndex: null };
48
- }
49
- return { state: this._state, context: { ...this._context } };
50
- }
51
- /** Reset to initial state */
52
- reset() {
53
- this._state = 'IDLE';
54
- this._context = { resumeIndex: null };
55
- }
56
- }
@@ -1,70 +0,0 @@
1
- /**
2
- * Module 9b: OffRouteFSM
3
- * Deviation → Reroute → Rejoin state machine. Pure deterministic transitions.
4
- * Extracted from useOffRouteSystem / NavigationStateManager (stripped of React).
5
- */
6
- import type { Coordinate } from '../geo/haversine';
7
- export type OffRouteState = 'ON_ROUTE' | 'DEVIATING' | 'OFF_ROUTE' | 'REROUTING' | 'REJOINING' | 'REJOINED' | 'FAILED';
8
- export interface TempRoute {
9
- geometry: Coordinate[];
10
- distance: number;
11
- duration: number;
12
- }
13
- export interface RejoinTarget {
14
- coordinates: Coordinate;
15
- index: number;
16
- }
17
- export interface OffRouteContext {
18
- deviationSegmentIdx: number | null;
19
- deviationStartMs: number | null;
20
- tempRoute: TempRoute | null;
21
- rejoinTarget: RejoinTarget | null;
22
- lastRerouteMs: number | null;
23
- rejoinedAtMs: number | null;
24
- rejoinDwellFrames: number;
25
- failureReason: string | null;
26
- }
27
- export type OffRouteEvent = {
28
- type: 'DEVIATION_SUSPECTED';
29
- deviationSegmentIdx: number;
30
- } | {
31
- type: 'DEVIATION_CONFIRMED';
32
- deviationSegmentIdx: number;
33
- } | {
34
- type: 'REROUTE_STARTED';
35
- } | {
36
- type: 'REROUTE_SUCCESS';
37
- tempRoute: TempRoute;
38
- rejoinTarget: RejoinTarget;
39
- } | {
40
- type: 'REROUTE_FAILED';
41
- reason: string;
42
- } | {
43
- type: 'REJOIN_DETECTED';
44
- } | {
45
- type: 'REJOIN_CONFIRMED';
46
- } | {
47
- type: 'RESUME';
48
- } | {
49
- type: 'RESET';
50
- };
51
- export interface OffRouteOutput {
52
- state: OffRouteState;
53
- context: OffRouteContext;
54
- }
55
- /**
56
- * Pure off-route FSM — no React, no side effects.
57
- */
58
- export declare class OffRouteFSM {
59
- private _state;
60
- private _context;
61
- get state(): OffRouteState;
62
- get context(): OffRouteContext;
63
- /** Dispatch an event and return the new output */
64
- dispatch(event: OffRouteEvent, nowMs?: number): OffRouteOutput;
65
- /** Full reset */
66
- reset(): void;
67
- /** Check if deviation confirmation time has elapsed */
68
- isDeviationConfirmed(nowMs?: number): boolean;
69
- }
70
- //# sourceMappingURL=OffRouteFSM.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OffRouteFSM.d.ts","sourceRoot":"","sources":["../../../../../core/src/off-route/OffRouteFSM.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,UAAU,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,YAAY,CAAA;CAAE,GAC7E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtB,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,eAAe,CAAC;CAC1B;AAgBD;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,QAAQ,CAA2C;IAE3D,IAAI,KAAK,IAAI,aAAa,CAAwB;IAClD,IAAI,OAAO,IAAI,eAAe,CAAiC;IAE/D,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc;IAwH9D,iBAAiB;IACjB,KAAK,IAAI,IAAI;IAKb,uDAAuD;IACvD,oBAAoB,CAAC,KAAK,GAAE,MAAmB,GAAG,OAAO;CAI1D"}
@@ -1,151 +0,0 @@
1
- /**
2
- * Module 9b: OffRouteFSM
3
- * Deviation → Reroute → Rejoin state machine. Pure deterministic transitions.
4
- * Extracted from useOffRouteSystem / NavigationStateManager (stripped of React).
5
- */
6
- const INITIAL_CONTEXT = {
7
- deviationSegmentIdx: null,
8
- deviationStartMs: null,
9
- tempRoute: null,
10
- rejoinTarget: null,
11
- lastRerouteMs: null,
12
- rejoinedAtMs: null,
13
- rejoinDwellFrames: 0,
14
- failureReason: null,
15
- };
16
- const DEVIATION_CONFIRM_MS = 2000;
17
- const REJOIN_DWELL_THRESHOLD = 3;
18
- /**
19
- * Pure off-route FSM — no React, no side effects.
20
- */
21
- export class OffRouteFSM {
22
- constructor() {
23
- this._state = 'ON_ROUTE';
24
- this._context = { ...INITIAL_CONTEXT };
25
- }
26
- get state() { return this._state; }
27
- get context() { return { ...this._context }; }
28
- /** Dispatch an event and return the new output */
29
- dispatch(event, nowMs) {
30
- const now = nowMs ?? Date.now();
31
- switch (this._state) {
32
- case 'ON_ROUTE':
33
- if (event.type === 'DEVIATION_SUSPECTED') {
34
- this._state = 'DEVIATING';
35
- this._context.deviationSegmentIdx = event.deviationSegmentIdx;
36
- this._context.deviationStartMs = now;
37
- }
38
- break;
39
- case 'DEVIATING':
40
- if (event.type === 'DEVIATION_CONFIRMED') {
41
- const elapsed = this._context.deviationStartMs !== null
42
- ? now - this._context.deviationStartMs
43
- : 0;
44
- if (elapsed >= DEVIATION_CONFIRM_MS) {
45
- this._state = 'OFF_ROUTE';
46
- this._context.deviationSegmentIdx = event.deviationSegmentIdx;
47
- }
48
- }
49
- if (event.type === 'RESUME' || event.type === 'RESET') {
50
- this._state = 'ON_ROUTE';
51
- // RESUME preserves lastRerouteMs (cooldown), RESET clears everything
52
- if (event.type === 'RESET') {
53
- this._context = { ...INITIAL_CONTEXT };
54
- }
55
- else {
56
- this._context.deviationSegmentIdx = null;
57
- this._context.deviationStartMs = null;
58
- }
59
- }
60
- break;
61
- case 'OFF_ROUTE':
62
- if (event.type === 'REROUTE_STARTED') {
63
- this._state = 'REROUTING';
64
- this._context.lastRerouteMs = now;
65
- }
66
- if (event.type === 'RESUME') {
67
- this._state = 'ON_ROUTE';
68
- this._context.deviationSegmentIdx = null;
69
- this._context.deviationStartMs = null;
70
- }
71
- if (event.type === 'RESET') {
72
- this._state = 'ON_ROUTE';
73
- this._context = { ...INITIAL_CONTEXT };
74
- }
75
- break;
76
- case 'REROUTING':
77
- if (event.type === 'REROUTE_SUCCESS') {
78
- this._state = 'REJOINING';
79
- this._context.tempRoute = event.tempRoute;
80
- this._context.rejoinTarget = event.rejoinTarget;
81
- }
82
- if (event.type === 'REROUTE_FAILED') {
83
- this._state = 'FAILED';
84
- this._context.failureReason = event.reason;
85
- }
86
- break;
87
- case 'REJOINING':
88
- if (event.type === 'REJOIN_DETECTED') {
89
- this._context.rejoinDwellFrames++;
90
- }
91
- if (event.type === 'REJOIN_CONFIRMED' ||
92
- this._context.rejoinDwellFrames >= REJOIN_DWELL_THRESHOLD) {
93
- this._state = 'REJOINED';
94
- this._context.rejoinedAtMs = now;
95
- this._context.rejoinDwellFrames = 0;
96
- }
97
- if (event.type === 'RESUME') {
98
- this._state = 'ON_ROUTE';
99
- this._context.tempRoute = null;
100
- this._context.rejoinTarget = null;
101
- this._context.rejoinedAtMs = null;
102
- this._context.deviationSegmentIdx = null;
103
- this._context.deviationStartMs = null;
104
- this._context.rejoinDwellFrames = 0;
105
- }
106
- if (event.type === 'RESET') {
107
- this._state = 'ON_ROUTE';
108
- this._context = { ...INITIAL_CONTEXT };
109
- }
110
- break;
111
- case 'REJOINED':
112
- if (event.type === 'RESUME') {
113
- this._state = 'ON_ROUTE';
114
- this._context.tempRoute = null;
115
- this._context.rejoinTarget = null;
116
- this._context.rejoinedAtMs = null;
117
- this._context.deviationSegmentIdx = null;
118
- this._context.deviationStartMs = null;
119
- }
120
- if (event.type === 'RESET') {
121
- this._state = 'ON_ROUTE';
122
- this._context = { ...INITIAL_CONTEXT };
123
- }
124
- break;
125
- case 'FAILED':
126
- if (event.type === 'RESUME') {
127
- this._state = 'ON_ROUTE';
128
- this._context.failureReason = null;
129
- this._context.deviationSegmentIdx = null;
130
- this._context.deviationStartMs = null;
131
- }
132
- if (event.type === 'RESET') {
133
- this._state = 'ON_ROUTE';
134
- this._context = { ...INITIAL_CONTEXT };
135
- }
136
- break;
137
- }
138
- return { state: this._state, context: { ...this._context } };
139
- }
140
- /** Full reset */
141
- reset() {
142
- this._state = 'ON_ROUTE';
143
- this._context = { ...INITIAL_CONTEXT };
144
- }
145
- /** Check if deviation confirmation time has elapsed */
146
- isDeviationConfirmed(nowMs = Date.now()) {
147
- if (!this._context.deviationStartMs)
148
- return false;
149
- return (nowMs - this._context.deviationStartMs) >= DEVIATION_CONFIRM_MS;
150
- }
151
- }
@@ -1,24 +0,0 @@
1
- /**
2
- * Module 8: RouteOffsetPredictor
3
- * Linear distance-based position predictor for smooth rendering between GPS fixes.
4
- */
5
- import { type Coordinate } from '../geo/haversine';
6
- /**
7
- * Advance the predictor's offset by speed * dt.
8
- */
9
- export declare function advancePredictor(currentOffset: number, speedMps: number, dtSec: number): number;
10
- /**
11
- * Correct the predictor when a new GPS fix arrives.
12
- * Blend towards the actual measured offset using betaCorrection.
13
- */
14
- export declare function applyGpsCorrection(predictedOffset: number, measuredOffset: number, betaCorrection?: number): number;
15
- /**
16
- * Given a linear offset (metres from route start), find the [lng, lat] on the route.
17
- *
18
- * @param offset Linear distance from route start in metres
19
- * @param cumulativeDistances Forward cumulative distance array
20
- * @param route Route coordinates
21
- * @returns Interpolated coordinate on the route
22
- */
23
- export declare function pointAtOffset(offset: number, cumulativeDistances: Float64Array, route: Coordinate[]): Coordinate;
24
- //# sourceMappingURL=RouteOffsetPredictor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RouteOffsetPredictor.d.ts","sourceRoot":"","sources":["../../../../../core/src/predictor/RouteOffsetPredictor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,cAAc,GAAE,MAAa,GAC5B,MAAM,CAGR;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,YAAY,EACjC,KAAK,EAAE,UAAU,EAAE,GAClB,UAAU,CA2BZ"}
@@ -1,55 +0,0 @@
1
- /**
2
- * Module 8: RouteOffsetPredictor
3
- * Linear distance-based position predictor for smooth rendering between GPS fixes.
4
- */
5
- import { interpolatePoint } from '../geo/bearing';
6
- /**
7
- * Advance the predictor's offset by speed * dt.
8
- */
9
- export function advancePredictor(currentOffset, speedMps, dtSec) {
10
- return currentOffset + speedMps * dtSec;
11
- }
12
- /**
13
- * Correct the predictor when a new GPS fix arrives.
14
- * Blend towards the actual measured offset using betaCorrection.
15
- */
16
- export function applyGpsCorrection(predictedOffset, measuredOffset, betaCorrection = 0.15) {
17
- const error = measuredOffset - predictedOffset;
18
- return predictedOffset + betaCorrection * error;
19
- }
20
- /**
21
- * Given a linear offset (metres from route start), find the [lng, lat] on the route.
22
- *
23
- * @param offset Linear distance from route start in metres
24
- * @param cumulativeDistances Forward cumulative distance array
25
- * @param route Route coordinates
26
- * @returns Interpolated coordinate on the route
27
- */
28
- export function pointAtOffset(offset, cumulativeDistances, route) {
29
- if (route.length === 0)
30
- return [0, 0];
31
- if (offset <= 0)
32
- return route[0];
33
- const totalLength = cumulativeDistances[cumulativeDistances.length - 1] ?? 0;
34
- if (offset >= totalLength)
35
- return route[route.length - 1];
36
- // Binary search for the segment containing this offset
37
- let lo = 0;
38
- let hi = cumulativeDistances.length - 1;
39
- while (lo < hi - 1) {
40
- const mid = (lo + hi) >> 1;
41
- if (cumulativeDistances[mid] <= offset) {
42
- lo = mid;
43
- }
44
- else {
45
- hi = mid;
46
- }
47
- }
48
- const segStart = cumulativeDistances[lo];
49
- const segEnd = cumulativeDistances[hi];
50
- const segLength = segEnd - segStart;
51
- if (segLength === 0)
52
- return route[lo];
53
- const t = (offset - segStart) / segLength;
54
- return interpolatePoint(route[lo], route[hi], t);
55
- }