@ingissa/navcore-simulator 1.0.3 → 1.0.7
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/LICENSE +3 -0
- package/dist/core/src/NavCore.d.ts +142 -0
- package/dist/core/src/NavCore.d.ts.map +1 -0
- package/dist/core/src/NavCore.js +390 -0
- package/dist/core/src/bearing/BearingEngine.d.ts +24 -0
- package/dist/core/src/bearing/BearingEngine.d.ts.map +1 -0
- package/dist/core/src/bearing/BearingEngine.js +50 -0
- package/dist/core/src/constants.d.ts +34 -0
- package/dist/core/src/constants.d.ts.map +1 -0
- package/dist/core/src/constants.js +41 -0
- package/dist/core/src/corridor/DeviationDetector.d.ts +33 -0
- package/dist/core/src/corridor/DeviationDetector.d.ts.map +1 -0
- package/dist/core/src/corridor/DeviationDetector.js +83 -0
- package/dist/core/src/corridor/DynamicCorridor.d.ts +13 -0
- package/dist/core/src/corridor/DynamicCorridor.d.ts.map +1 -0
- package/dist/core/src/corridor/DynamicCorridor.js +26 -0
- package/dist/core/src/dead-reckoning/DeadReckoning.d.ts +35 -0
- package/dist/core/src/dead-reckoning/DeadReckoning.d.ts.map +1 -0
- package/dist/core/src/dead-reckoning/DeadReckoning.js +49 -0
- package/dist/core/src/directions/DirectionsProvider.d.ts +70 -0
- package/dist/core/src/directions/DirectionsProvider.d.ts.map +1 -0
- package/dist/core/src/directions/DirectionsProvider.js +7 -0
- package/dist/core/src/directions/OSRMDirectionsProvider.d.ts +26 -0
- package/dist/core/src/directions/OSRMDirectionsProvider.d.ts.map +1 -0
- package/dist/core/src/directions/OSRMDirectionsProvider.js +90 -0
- package/dist/core/src/directions/OpenRouteServiceProvider.d.ts +30 -0
- package/dist/core/src/directions/OpenRouteServiceProvider.d.ts.map +1 -0
- package/dist/core/src/directions/OpenRouteServiceProvider.js +111 -0
- package/dist/core/src/directions/ValhallaDirectionsProvider.d.ts +33 -0
- package/dist/core/src/directions/ValhallaDirectionsProvider.d.ts.map +1 -0
- package/dist/core/src/directions/ValhallaDirectionsProvider.js +155 -0
- package/dist/core/src/eta/ETAEngine.d.ts +61 -0
- package/dist/core/src/eta/ETAEngine.d.ts.map +1 -0
- package/dist/core/src/eta/ETAEngine.js +74 -0
- package/dist/core/src/features.d.ts +76 -0
- package/dist/core/src/features.d.ts.map +1 -0
- package/dist/core/src/features.js +76 -0
- package/dist/core/src/geo/bearing.d.ts +11 -0
- package/dist/core/src/geo/bearing.d.ts.map +1 -0
- package/dist/core/src/geo/bearing.js +25 -0
- package/dist/core/src/geo/cumulative.d.ts +9 -0
- package/dist/core/src/geo/cumulative.d.ts.map +1 -0
- package/dist/core/src/geo/cumulative.js +20 -0
- package/dist/core/src/geo/haversine.d.ts +13 -0
- package/dist/core/src/geo/haversine.d.ts.map +1 -0
- package/dist/core/src/geo/haversine.js +39 -0
- package/dist/core/src/geo/projection.d.ts +7 -0
- package/dist/core/src/geo/projection.d.ts.map +1 -0
- package/dist/core/src/geo/projection.js +17 -0
- package/dist/core/src/geofencing/GeofencingEngine.d.ts +93 -0
- package/dist/core/src/geofencing/GeofencingEngine.d.ts.map +1 -0
- package/dist/core/src/geofencing/GeofencingEngine.js +154 -0
- package/dist/core/src/index.d.ts +66 -0
- package/dist/core/src/index.d.ts.map +1 -0
- package/dist/core/src/index.js +62 -0
- package/dist/core/src/kalman/KalmanFilter2D.d.ts +46 -0
- package/dist/core/src/kalman/KalmanFilter2D.d.ts.map +1 -0
- package/dist/core/src/kalman/KalmanFilter2D.js +77 -0
- package/dist/core/src/license/LicenseManager.d.ts +40 -0
- package/dist/core/src/license/LicenseManager.d.ts.map +1 -0
- package/dist/core/src/license/LicenseManager.js +119 -0
- package/dist/core/src/license/verifyP256Signature.d.ts +2 -0
- package/dist/core/src/license/verifyP256Signature.d.ts.map +1 -0
- package/dist/core/src/license/verifyP256Signature.js +26 -0
- package/dist/core/src/off-route/NavigationFSM.d.ts +42 -0
- package/dist/core/src/off-route/NavigationFSM.d.ts.map +1 -0
- package/dist/core/src/off-route/NavigationFSM.js +56 -0
- package/dist/core/src/off-route/OffRouteFSM.d.ts +70 -0
- package/dist/core/src/off-route/OffRouteFSM.d.ts.map +1 -0
- package/dist/core/src/off-route/OffRouteFSM.js +151 -0
- package/dist/core/src/predictor/RouteOffsetPredictor.d.ts +24 -0
- package/dist/core/src/predictor/RouteOffsetPredictor.d.ts.map +1 -0
- package/dist/core/src/predictor/RouteOffsetPredictor.js +55 -0
- package/dist/core/src/progress/InstructionEditor.d.ts +77 -0
- package/dist/core/src/progress/InstructionEditor.d.ts.map +1 -0
- package/dist/core/src/progress/InstructionEditor.js +151 -0
- package/dist/core/src/progress/InstructionResolver.d.ts +25 -0
- package/dist/core/src/progress/InstructionResolver.d.ts.map +1 -0
- package/dist/core/src/progress/InstructionResolver.js +78 -0
- package/dist/core/src/progress/ProgressTracker.d.ts +12 -0
- package/dist/core/src/progress/ProgressTracker.d.ts.map +1 -0
- package/dist/core/src/progress/ProgressTracker.js +22 -0
- package/dist/core/src/renderer/MapRendererAdapter.d.ts +72 -0
- package/dist/core/src/renderer/MapRendererAdapter.d.ts.map +1 -0
- package/dist/core/src/renderer/MapRendererAdapter.js +19 -0
- package/dist/core/src/route-builder/CustomRouteBuilder.d.ts +83 -0
- package/dist/core/src/route-builder/CustomRouteBuilder.d.ts.map +1 -0
- package/dist/core/src/route-builder/CustomRouteBuilder.js +160 -0
- package/dist/core/src/route-plan/RoutePlan.d.ts +38 -0
- package/dist/core/src/route-plan/RoutePlan.d.ts.map +1 -0
- package/dist/core/src/route-plan/RoutePlan.js +102 -0
- package/dist/core/src/session/NavigationSession.d.ts +81 -0
- package/dist/core/src/session/NavigationSession.d.ts.map +1 -0
- package/dist/core/src/session/NavigationSession.js +115 -0
- package/dist/core/src/snapper/ParallelRoadResolver.d.ts +86 -0
- package/dist/core/src/snapper/ParallelRoadResolver.d.ts.map +1 -0
- package/dist/core/src/snapper/ParallelRoadResolver.js +83 -0
- package/dist/core/src/snapper/RouteSnapper.d.ts +38 -0
- package/dist/core/src/snapper/RouteSnapper.d.ts.map +1 -0
- package/dist/core/src/snapper/RouteSnapper.js +80 -0
- package/dist/core/src/voice/VoiceTriggerEngine.d.ts +80 -0
- package/dist/core/src/voice/VoiceTriggerEngine.d.ts.map +1 -0
- package/dist/core/src/voice/VoiceTriggerEngine.js +108 -0
- package/dist/{core → simulator/src/core}/NoiseEngine.d.ts +1 -1
- package/dist/simulator/src/core/NoiseEngine.d.ts.map +1 -0
- package/dist/{core → simulator/src/core}/RouteWalker.d.ts +4 -1
- package/dist/simulator/src/core/RouteWalker.d.ts.map +1 -0
- package/dist/{core → simulator/src/core}/RouteWalker.js +3 -0
- package/dist/simulator/src/core/SimulatorEngine.d.ts.map +1 -0
- package/dist/{core → simulator/src/core}/SimulatorEngine.js +23 -8
- package/dist/{core → simulator/src/core}/types.d.ts +30 -2
- package/dist/simulator/src/core/types.d.ts.map +1 -0
- package/dist/simulator/src/fleet/FleetSimulator.d.ts.map +1 -0
- package/dist/{index.d.ts → simulator/src/index.d.ts} +1 -1
- package/dist/simulator/src/index.d.ts.map +1 -0
- package/dist/{node.d.ts → simulator/src/node.d.ts} +1 -1
- package/dist/simulator/src/node.d.ts.map +1 -0
- package/dist/simulator/src/react-native/SimulatorControls.d.ts.map +1 -0
- package/dist/{react-native → simulator/src/react-native}/useSimulator.d.ts +6 -2
- package/dist/simulator/src/react-native/useSimulator.d.ts.map +1 -0
- package/dist/{react-native → simulator/src/react-native}/useSimulator.js +3 -0
- package/dist/{replay → simulator/src/replay}/GpxParser.d.ts +1 -1
- package/dist/simulator/src/replay/GpxParser.d.ts.map +1 -0
- package/dist/simulator/src/replay/SessionRecorder.d.ts.map +1 -0
- package/dist/simulator/src/scenarios/ScenarioInjector.d.ts.map +1 -0
- package/package.json +20 -10
- package/src/__tests__/integration/simulator-pipeline.test.ts +233 -0
- package/src/core/NoiseEngine.ts +137 -0
- package/src/core/RouteWalker.ts +227 -0
- package/src/core/SimulatorEngine.ts +364 -0
- package/src/core/__tests__/NoiseEngine.test.ts +131 -0
- package/src/core/__tests__/RouteWalker.test.ts +139 -0
- package/src/core/__tests__/SimulatorEngine.test.ts +317 -0
- package/src/core/types.ts +191 -0
- package/src/fleet/FleetSimulator.ts +162 -0
- package/src/index.ts +54 -0
- package/src/node.ts +48 -0
- package/src/react-native/SimulatorControls.tsx +473 -0
- package/src/react-native/useSimulator.ts +155 -0
- package/src/replay/GpxParser.ts +122 -0
- package/src/replay/SessionRecorder.ts +138 -0
- package/src/replay/__tests__/GpxParser.test.ts +136 -0
- package/src/scenarios/ScenarioInjector.ts +170 -0
- package/src/scenarios/__tests__/ScenarioInjector.test.ts +171 -0
- package/dist/core/NoiseEngine.d.ts.map +0 -1
- package/dist/core/RouteWalker.d.ts.map +0 -1
- package/dist/core/SimulatorEngine.d.ts.map +0 -1
- package/dist/core/types.d.ts.map +0 -1
- package/dist/fleet/FleetSimulator.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/node.d.ts.map +0 -1
- package/dist/react-native/SimulatorControls.d.ts.map +0 -1
- package/dist/react-native/useSimulator.d.ts.map +0 -1
- package/dist/replay/GpxParser.d.ts.map +0 -1
- package/dist/replay/SessionRecorder.d.ts.map +0 -1
- package/dist/scenarios/ScenarioInjector.d.ts.map +0 -1
- /package/dist/{core → simulator/src/core}/NoiseEngine.js +0 -0
- /package/dist/{core → simulator/src/core}/SimulatorEngine.d.ts +0 -0
- /package/dist/{core → simulator/src/core}/types.js +0 -0
- /package/dist/{fleet → simulator/src/fleet}/FleetSimulator.d.ts +0 -0
- /package/dist/{fleet → simulator/src/fleet}/FleetSimulator.js +0 -0
- /package/dist/{index.js → simulator/src/index.js} +0 -0
- /package/dist/{node.js → simulator/src/node.js} +0 -0
- /package/dist/{react-native → simulator/src/react-native}/SimulatorControls.d.ts +0 -0
- /package/dist/{react-native → simulator/src/react-native}/SimulatorControls.js +0 -0
- /package/dist/{replay → simulator/src/replay}/GpxParser.js +0 -0
- /package/dist/{replay → simulator/src/replay}/SessionRecorder.d.ts +0 -0
- /package/dist/{replay → simulator/src/replay}/SessionRecorder.js +0 -0
- /package/dist/{scenarios → simulator/src/scenarios}/ScenarioInjector.d.ts +0 -0
- /package/dist/{scenarios → simulator/src/scenarios}/ScenarioInjector.js +0 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VoiceTriggerEngine
|
|
3
|
+
*
|
|
4
|
+
* Converts NavCore instruction events into timed voice cues.
|
|
5
|
+
* Handles deduplication, look-ahead windows, and priority levels.
|
|
6
|
+
* Consumer calls TTS — this engine only computes WHEN to speak.
|
|
7
|
+
*
|
|
8
|
+
* FEATURE: VOICE_TRIGGERS
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const voice = new VoiceTriggerEngine({ earlyTriggerMeters: 150 });
|
|
13
|
+
* voice.setInstructions(instructions);
|
|
14
|
+
*
|
|
15
|
+
* engine.on('instruction', (instr) => {
|
|
16
|
+
* const cue = voice.onInstruction(instr, state);
|
|
17
|
+
* if (cue) speakText(cue.text);
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Or poll each GPS tick:
|
|
21
|
+
* const cue = voice.update(state);
|
|
22
|
+
* if (cue) speakText(cue.text);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
import type { NavInstruction } from '../progress/InstructionResolver';
|
|
26
|
+
import type { NavCoreState } from '../NavCore';
|
|
27
|
+
export type VoicePriority = 'low' | 'normal' | 'high' | 'urgent';
|
|
28
|
+
export interface VoiceCue {
|
|
29
|
+
/** The instruction that triggered this cue */
|
|
30
|
+
instruction: NavInstruction;
|
|
31
|
+
/** Text to pass to TTS */
|
|
32
|
+
text: string;
|
|
33
|
+
/** Distance to the instruction point in metres */
|
|
34
|
+
distanceMetres: number;
|
|
35
|
+
/** Priority hint for TTS queue management */
|
|
36
|
+
priority: VoicePriority;
|
|
37
|
+
/** Monotonic trigger ID — use this to deduplicate */
|
|
38
|
+
triggerId: string;
|
|
39
|
+
}
|
|
40
|
+
export interface VoiceTriggerOptions {
|
|
41
|
+
/**
|
|
42
|
+
* Trigger voice this many metres before the instruction point.
|
|
43
|
+
* Default: 120m (comfortable at 50 km/h).
|
|
44
|
+
*/
|
|
45
|
+
earlyTriggerMeters?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Stop trying to trigger if vehicle is already past this many metres.
|
|
48
|
+
* Default: 20m.
|
|
49
|
+
*/
|
|
50
|
+
lateTriggerMeters?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Re-announce if user is still approaching after this distance.
|
|
53
|
+
* Set to 0 to disable re-announcement. Default: 300m.
|
|
54
|
+
*/
|
|
55
|
+
reannounceMeters?: number;
|
|
56
|
+
}
|
|
57
|
+
export declare class VoiceTriggerEngine {
|
|
58
|
+
private instructions;
|
|
59
|
+
private triggeredIds;
|
|
60
|
+
private reannouncedIds;
|
|
61
|
+
private readonly options;
|
|
62
|
+
constructor(options?: VoiceTriggerOptions);
|
|
63
|
+
/** Load the instruction set (call after engine.setRoute) */
|
|
64
|
+
setInstructions(instructions: NavInstruction[]): void;
|
|
65
|
+
/**
|
|
66
|
+
* Poll on every GPS state update.
|
|
67
|
+
* Returns a `VoiceCue` when an instruction should be spoken, or null.
|
|
68
|
+
*/
|
|
69
|
+
update(state: NavCoreState): VoiceCue | null;
|
|
70
|
+
/**
|
|
71
|
+
* Called directly from engine's 'instruction' event.
|
|
72
|
+
* Always fires immediately regardless of distance window.
|
|
73
|
+
*/
|
|
74
|
+
onInstruction(instr: NavInstruction, state: NavCoreState): VoiceCue;
|
|
75
|
+
/** Reset triggered state (call on setRoute / new journey) */
|
|
76
|
+
reset(): void;
|
|
77
|
+
private instrId;
|
|
78
|
+
private makeCue;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=VoiceTriggerEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoiceTriggerEngine.d.ts","sourceRoot":"","sources":["../../../../../core/src/voice/VoiceTriggerEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,QAAQ;IACvB,8CAA8C;IAC9C,WAAW,EAAE,cAAc,CAAC;IAC5B,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,cAAc,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,QAAQ,EAAE,aAAa,CAAC;IACxB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAQD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;gBAE5C,OAAO,CAAC,EAAE,mBAAmB;IAIzC,4DAA4D;IAC5D,eAAe,CAAC,YAAY,EAAE,cAAc,EAAE,GAAG,IAAI;IAMrD;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,QAAQ,GAAG,IAAI;IA6C5C;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,GAAG,QAAQ;IAKnE,6DAA6D;IAC7D,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;CAShB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VoiceTriggerEngine
|
|
3
|
+
*
|
|
4
|
+
* Converts NavCore instruction events into timed voice cues.
|
|
5
|
+
* Handles deduplication, look-ahead windows, and priority levels.
|
|
6
|
+
* Consumer calls TTS — this engine only computes WHEN to speak.
|
|
7
|
+
*
|
|
8
|
+
* FEATURE: VOICE_TRIGGERS
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const voice = new VoiceTriggerEngine({ earlyTriggerMeters: 150 });
|
|
13
|
+
* voice.setInstructions(instructions);
|
|
14
|
+
*
|
|
15
|
+
* engine.on('instruction', (instr) => {
|
|
16
|
+
* const cue = voice.onInstruction(instr, state);
|
|
17
|
+
* if (cue) speakText(cue.text);
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Or poll each GPS tick:
|
|
21
|
+
* const cue = voice.update(state);
|
|
22
|
+
* if (cue) speakText(cue.text);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
const DEFAULTS = {
|
|
26
|
+
earlyTriggerMeters: 120,
|
|
27
|
+
lateTriggerMeters: 20,
|
|
28
|
+
reannounceMeters: 300,
|
|
29
|
+
};
|
|
30
|
+
export class VoiceTriggerEngine {
|
|
31
|
+
constructor(options) {
|
|
32
|
+
this.instructions = [];
|
|
33
|
+
this.triggeredIds = new Set();
|
|
34
|
+
this.reannouncedIds = new Set();
|
|
35
|
+
this.options = { ...DEFAULTS, ...options };
|
|
36
|
+
}
|
|
37
|
+
/** Load the instruction set (call after engine.setRoute) */
|
|
38
|
+
setInstructions(instructions) {
|
|
39
|
+
this.instructions = [...instructions];
|
|
40
|
+
this.triggeredIds.clear();
|
|
41
|
+
this.reannouncedIds.clear();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Poll on every GPS state update.
|
|
45
|
+
* Returns a `VoiceCue` when an instruction should be spoken, or null.
|
|
46
|
+
*/
|
|
47
|
+
update(state) {
|
|
48
|
+
const { distanceToNextInstruction, nextInstructionIndex } = state;
|
|
49
|
+
if (nextInstructionIndex === null ||
|
|
50
|
+
distanceToNextInstruction === null ||
|
|
51
|
+
nextInstructionIndex >= this.instructions.length) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const instr = this.instructions[nextInstructionIndex];
|
|
55
|
+
const id = this.instrId(nextInstructionIndex);
|
|
56
|
+
const dist = distanceToNextInstruction;
|
|
57
|
+
// Already fully triggered — don't repeat
|
|
58
|
+
if (this.triggeredIds.has(id)) {
|
|
59
|
+
// Check re-announce window
|
|
60
|
+
if (this.options.reannounceMeters > 0 &&
|
|
61
|
+
!this.reannouncedIds.has(id) &&
|
|
62
|
+
dist <= this.options.reannounceMeters &&
|
|
63
|
+
dist > this.options.earlyTriggerMeters) {
|
|
64
|
+
this.reannouncedIds.add(id);
|
|
65
|
+
return this.makeCue(instr, dist, 'low');
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
// Too far — not yet
|
|
70
|
+
if (dist > this.options.earlyTriggerMeters)
|
|
71
|
+
return null;
|
|
72
|
+
// Already passed — too late
|
|
73
|
+
if (dist < -this.options.lateTriggerMeters) {
|
|
74
|
+
this.triggeredIds.add(id); // mark so we skip
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
// In the trigger window — fire!
|
|
78
|
+
this.triggeredIds.add(id);
|
|
79
|
+
const priority = dist < 30 ? 'urgent' : dist < 60 ? 'high' : 'normal';
|
|
80
|
+
return this.makeCue(instr, dist, priority);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Called directly from engine's 'instruction' event.
|
|
84
|
+
* Always fires immediately regardless of distance window.
|
|
85
|
+
*/
|
|
86
|
+
onInstruction(instr, state) {
|
|
87
|
+
const dist = state.distanceToNextInstruction ?? 0;
|
|
88
|
+
return this.makeCue(instr, dist, 'high');
|
|
89
|
+
}
|
|
90
|
+
/** Reset triggered state (call on setRoute / new journey) */
|
|
91
|
+
reset() {
|
|
92
|
+
this.triggeredIds.clear();
|
|
93
|
+
this.reannouncedIds.clear();
|
|
94
|
+
}
|
|
95
|
+
instrId(index) {
|
|
96
|
+
const instr = this.instructions[index];
|
|
97
|
+
return `${index}_${instr?.geometryIndex ?? 0}`;
|
|
98
|
+
}
|
|
99
|
+
makeCue(instr, dist, priority) {
|
|
100
|
+
return {
|
|
101
|
+
instruction: instr,
|
|
102
|
+
text: instr.text ?? instr.instruction ?? '',
|
|
103
|
+
distanceMetres: Math.max(0, dist),
|
|
104
|
+
priority,
|
|
105
|
+
triggerId: `${instr.geometryIndex}_${dist.toFixed(0)}`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* 1° latitude ≈ 110540 m
|
|
11
11
|
* 1° longitude ≈ 111320 m (at equator; good enough for noise simulation)
|
|
12
12
|
*/
|
|
13
|
-
import type { Coordinate } from '
|
|
13
|
+
import type { Coordinate } from '@ingissa/navcore-core';
|
|
14
14
|
import type { NoiseProfile } from './types';
|
|
15
15
|
export declare class NoiseEngine {
|
|
16
16
|
private profile;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoiseEngine.d.ts","sourceRoot":"","sources":["../../../../src/core/NoiseEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAyB5C,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,UAAU,CAAK;gBAEX,OAAO,EAAE,YAAY;IAOjC,8CAA8C;IAC9C,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAgC;IAElE,8CAA8C;IAC9C,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAoC;IAEvE,qFAAqF;IACrF,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAqC;IAE3E,kDAAkD;IAClD,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAkC;IAErE,+CAA+C;IAC/C,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAqC;IAI3E;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU;IA6BpC,gDAAgD;IAChD,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAMvC,IAAI,cAAc,IAAI,YAAY,CAEjC;IAID;;;OAGG;IACH,OAAO,CAAC,eAAe;IAcvB,iFAAiF;IACjF,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* ZERO dependencies beyond @navcore/core types.
|
|
8
8
|
*/
|
|
9
|
-
import type { Coordinate } from '
|
|
9
|
+
import type { Coordinate } from '@ingissa/navcore-core';
|
|
10
10
|
export interface WalkerPosition {
|
|
11
11
|
/** Current floating-point index (e.g. 3.75 = between points 3 and 4) */
|
|
12
12
|
index: number;
|
|
@@ -58,6 +58,9 @@ export declare class RouteWalker {
|
|
|
58
58
|
* Uses the pre-computed cumulative distances (O(1)).
|
|
59
59
|
*/
|
|
60
60
|
distanceAtIndex(index: number): number;
|
|
61
|
+
/**
|
|
62
|
+
* Alias for distanceAtIndex.
|
|
63
|
+
*/
|
|
61
64
|
distanceToIndex(index: number): number;
|
|
62
65
|
/**
|
|
63
66
|
* Convert a distance in metres back to a fractional index.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouteWalker.d.ts","sourceRoot":"","sources":["../../../../src/core/RouteWalker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,KAAK,EAAE,UAAU,CAAC;IAClB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAW;IAChD,OAAO,CAAC,WAAW,CAAU;gBAEjB,QAAQ,EAAE,UAAU,EAAE,EAAE,UAAU,SAAI;IAuBlD;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc;IAMtC;;;OAGG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc;IAejD,OAAO,CAAC,gBAAgB;IAUxB;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc;IAOnC;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IAQxD;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAOhC;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAKtC;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAItC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAgCxB,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAID,OAAO,CAAC,gBAAgB;IAexB,2DAA2D;IAC3D,OAAO,CAAC,qBAAqB;CAQ9B"}
|
|
@@ -103,6 +103,9 @@ export class RouteWalker {
|
|
|
103
103
|
const clampedIdx = Math.max(0, Math.min(Math.floor(index), this.geometry.length - 1));
|
|
104
104
|
return this._cumulativeDistances[clampedIdx] ?? 0;
|
|
105
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Alias for distanceAtIndex.
|
|
108
|
+
*/
|
|
106
109
|
distanceToIndex(index) {
|
|
107
110
|
return this.distanceAtIndex(index);
|
|
108
111
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimulatorEngine.d.ts","sourceRoot":"","sources":["../../../../src/core/SimulatorEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAWlF,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;AAErE,qBAAa,eAAe;IAE1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEiF;IAGxG,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAmB;IAGnC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,MAAM,CAA+C;IAC7D,OAAO,CAAC,SAAS,CAAa;IAE9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAM;IAGrC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,kBAAkB,CAAsD;IAChF,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,kBAAkB,CAAK;gBAEnB,MAAM,EAAE,eAAe;IA4CnC,KAAK,IAAI,IAAI;IAOb,IAAI,IAAI,IAAI;IAMZ,KAAK,IAAI,IAAI;IAMb,MAAM,IAAI,IAAI;IAMd;;;OAGG;IACH,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAkBjC,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI;IAUzC,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAIrC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,cAAc,IAAI,IAAI;IAMtB,IAAI,KAAK,IAAI,WAAW,CAEvB;IAED,IAAI,QAAQ,IAAI,WAAW,GAAG,IAAI,CAEjC;IAED,IAAI,QAAQ,IAAI,MAAM,CAGrB;IAID,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IASxC,aAAa,IAAI,UAAU;IAqC3B,OAAO,IAAI,IAAI;IAWf,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,KAAK;IA0Db,OAAO,CAAC,qBAAqB;CAoD9B"}
|
|
@@ -116,7 +116,10 @@ export class SimulatorEngine {
|
|
|
116
116
|
}
|
|
117
117
|
setSpeed(multiplier) {
|
|
118
118
|
this._speedMultiplier = multiplier;
|
|
119
|
-
|
|
119
|
+
if (this._state === 'running') {
|
|
120
|
+
this._stopTimer();
|
|
121
|
+
this._startTimer();
|
|
122
|
+
}
|
|
120
123
|
}
|
|
121
124
|
// ── Scenario management ──────────────────────────────────────────────────────
|
|
122
125
|
addScenario(scenario) {
|
|
@@ -190,7 +193,8 @@ export class SimulatorEngine {
|
|
|
190
193
|
// ── Private ──────────────────────────────────────────────────────────────────
|
|
191
194
|
_startTimer() {
|
|
192
195
|
this._lastTick = Date.now();
|
|
193
|
-
|
|
196
|
+
const intervalMs = Math.round(1000 / this._speedMultiplier);
|
|
197
|
+
this._timer = setInterval(() => this._tick(), intervalMs);
|
|
194
198
|
}
|
|
195
199
|
_stopTimer() {
|
|
196
200
|
if (this._timer !== null) {
|
|
@@ -202,13 +206,9 @@ export class SimulatorEngine {
|
|
|
202
206
|
if (this._state !== 'running')
|
|
203
207
|
return;
|
|
204
208
|
const now = Date.now();
|
|
205
|
-
const deltaMs = now - this._lastTick;
|
|
206
209
|
this._lastTick = now;
|
|
207
|
-
// Calculate physical distance to move in this tick
|
|
208
|
-
// meters = (km/h / 3.6) * seconds * multiplier
|
|
209
210
|
const speedMs = (this.config.speedKmh / 3.6);
|
|
210
|
-
const
|
|
211
|
-
const walkerPos = this.walker.advanceByDistance(distanceToMove);
|
|
211
|
+
const walkerPos = this.walker.advance(1);
|
|
212
212
|
// Fire any scenarios at this index
|
|
213
213
|
const activeScenarioName = this.injector.tick(walkerPos.index);
|
|
214
214
|
// Apply noise (skip if GPS_BLACKOUT scenario is active)
|
|
@@ -257,12 +257,27 @@ export class SimulatorEngine {
|
|
|
257
257
|
_buildAndEmitPosition(coord, bearing, distanceTravelled, isNoisy, opts) {
|
|
258
258
|
const speedMs = opts?.speedMs ?? (this.config.speedKmh / 3.6);
|
|
259
259
|
const accuracy = opts?.accuracy ?? 8;
|
|
260
|
+
const ts = Date.now();
|
|
261
|
+
const locationCoords = {
|
|
262
|
+
latitude: coord[1],
|
|
263
|
+
longitude: coord[0],
|
|
264
|
+
altitude: 0,
|
|
265
|
+
accuracy,
|
|
266
|
+
altitudeAccuracy: null,
|
|
267
|
+
heading: bearing,
|
|
268
|
+
speed: speedMs,
|
|
269
|
+
};
|
|
260
270
|
const pos = {
|
|
261
271
|
coord: coord,
|
|
262
272
|
bearing,
|
|
263
273
|
speed: speedMs,
|
|
264
274
|
accuracy,
|
|
265
|
-
timestamp:
|
|
275
|
+
timestamp: ts,
|
|
276
|
+
coords: locationCoords,
|
|
277
|
+
location: {
|
|
278
|
+
coords: locationCoords,
|
|
279
|
+
timestamp: ts,
|
|
280
|
+
},
|
|
266
281
|
metadata: {
|
|
267
282
|
segmentIndex: opts?.segmentIndex ?? Math.floor(this.walker.currentIndex),
|
|
268
283
|
distanceTravelled,
|
|
@@ -4,11 +4,31 @@
|
|
|
4
4
|
* These types are the foundation of the entire simulator package.
|
|
5
5
|
* All other modules build on top of these definitions.
|
|
6
6
|
*/
|
|
7
|
+
/** [longitude, latitude] — Mapbox/GeoJSON order */
|
|
7
8
|
export type Coordinate = [number, number];
|
|
9
|
+
/**
|
|
10
|
+
* Standard coords conforming to expo-location LocationObject['coords']
|
|
11
|
+
* and @react-native-community/geolocation.
|
|
12
|
+
*/
|
|
13
|
+
export interface SimLocationCoords {
|
|
14
|
+
latitude: number;
|
|
15
|
+
longitude: number;
|
|
16
|
+
altitude: number | null;
|
|
17
|
+
accuracy: number | null;
|
|
18
|
+
altitudeAccuracy: number | null;
|
|
19
|
+
heading: number | null;
|
|
20
|
+
speed: number | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Standard LocationObject conforming to expo-location.
|
|
24
|
+
*/
|
|
25
|
+
export interface SimLocationObject {
|
|
26
|
+
coords: SimLocationCoords;
|
|
27
|
+
timestamp: number;
|
|
28
|
+
}
|
|
8
29
|
/**
|
|
9
30
|
* A single simulated GPS position, emitted by SimulatorEngine on every tick.
|
|
10
|
-
* Shape
|
|
11
|
-
* NavCoreTestScreen so that migration is a search-and-replace.
|
|
31
|
+
* Shape includes standard LocationObject coords for drop-in Expo/React Native usage.
|
|
12
32
|
*/
|
|
13
33
|
export interface SimPosition {
|
|
14
34
|
/** [longitude, latitude] */
|
|
@@ -21,6 +41,14 @@ export interface SimPosition {
|
|
|
21
41
|
accuracy: number;
|
|
22
42
|
/** Unix timestamp in milliseconds */
|
|
23
43
|
timestamp: number;
|
|
44
|
+
/**
|
|
45
|
+
* Standard LocationObject coords conforming to expo-location & React Native geolocation.
|
|
46
|
+
*/
|
|
47
|
+
coords: SimLocationCoords;
|
|
48
|
+
/**
|
|
49
|
+
* Full standard LocationObject conforming to expo-location.
|
|
50
|
+
*/
|
|
51
|
+
location?: SimLocationObject;
|
|
24
52
|
/** Optional debug metadata */
|
|
25
53
|
metadata?: {
|
|
26
54
|
/** Which geometry segment the vehicle is currently on */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FleetSimulator.d.ts","sourceRoot":"","sources":["../../../../src/fleet/FleetSimulator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEjE,MAAM,WAAW,cAAe,SAAQ,OAAO,CAAC,eAAe,CAAC;IAC9D,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,UAAU,CAAC;QACpB,OAAO,EAAE,cAAc,CAAC;KACzB,CAAC,CAAC;IACH,UAAU,EAAE;QACV,2CAA2C;QAC3C,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1C,qEAAqE;QACrE,mBAAmB,EAAE,MAAM,EAAE,CAAC;KAC/B,CAAC;CACH;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4C;IAEvE,OAAO;IAUP;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG;QAClD,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;KAC7B,GACA,cAAc;IAsBjB,uCAAuC;IACvC,KAAK,IAAI,IAAI;IAOb,uBAAuB;IACvB,IAAI,IAAI,IAAI;IAMZ;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe;IAMvC;;OAEG;IACH,MAAM,IAAI,WAAW;IA8CrB,uCAAuC;IACvC,OAAO,IAAI,IAAI;CAKhB"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* React Native consumers also get:
|
|
10
10
|
* import { useSimulator, SimulatorControls } from '@ingissa/navcore-simulator'
|
|
11
11
|
*/
|
|
12
|
-
export type { SimPosition, SimulatorConfig, NoiseProfile, Scenario, SimSession, } from './core/types';
|
|
12
|
+
export type { Coordinate, SimPosition, SimLocationCoords, SimLocationObject, SimulatorConfig, NoiseProfile, Scenario, SimSession, } from './core/types';
|
|
13
13
|
export { SimulatorEngine } from './core/SimulatorEngine';
|
|
14
14
|
export type { EngineState } from './core/SimulatorEngine';
|
|
15
15
|
export { RouteWalker } from './core/RouteWalker';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,YAAY,EACV,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,UAAU,GACX,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAK1E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* from the main barrel:
|
|
11
11
|
* import { useSimulator } from '@ingissa/navcore-simulator' ← full barrel
|
|
12
12
|
*/
|
|
13
|
-
export type { SimPosition, SimulatorConfig, NoiseProfile, Scenario, SimSession, } from './core/types';
|
|
13
|
+
export type { Coordinate, SimPosition, SimLocationCoords, SimLocationObject, SimulatorConfig, NoiseProfile, Scenario, SimSession, } from './core/types';
|
|
14
14
|
export { SimulatorEngine } from './core/SimulatorEngine';
|
|
15
15
|
export type { EngineState } from './core/SimulatorEngine';
|
|
16
16
|
export { RouteWalker } from './core/RouteWalker';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,YAAY,EACV,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,UAAU,GACX,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimulatorControls.d.ts","sourceRoot":"","sources":["../../../../src/react-native/SimulatorControls.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAYH,OAAO,KAAK,EAAE,iBAAiB,IAAI,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAuBhD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,QAAQ,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,uDAAuD;IACvD,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA0MD,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,OAAO,EACP,KAAiB,EACjB,eAAuB,EACvB,mBAA2B,EAC3B,WAAgB,EAChB,YAAgB,EAChB,WAAoB,EACpB,WAAmB,EACnB,eAAe,EACf,cAAc,GACf,EAAE,sBAAsB,2CA6GxB"}
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* config: { speedKmh: 50, noiseProfile: NoiseEngine.STANDARD },
|
|
16
16
|
* })
|
|
17
17
|
*/
|
|
18
|
-
import type { SimPosition, SimulatorConfig, SimSession, Scenario } from '../core/types';
|
|
19
|
-
import type { Coordinate } from '
|
|
18
|
+
import type { SimPosition, SimulatorConfig, SimSession, Scenario, SimLocationObject } from '../core/types';
|
|
19
|
+
import type { Coordinate } from '@ingissa/navcore-core';
|
|
20
20
|
export interface UseSimulatorOptions {
|
|
21
21
|
/** Route geometry to simulate along */
|
|
22
22
|
routeGeometry: Coordinate[] | null;
|
|
@@ -44,6 +44,10 @@ export interface SessionControls {
|
|
|
44
44
|
export interface UseSimulatorResult {
|
|
45
45
|
/** Current simulated position — null when inactive */
|
|
46
46
|
position: SimPosition | null;
|
|
47
|
+
/** Conforms to Expo LocationObject (null when inactive) */
|
|
48
|
+
location: SimLocationObject | null;
|
|
49
|
+
/** Alias for location conforming to Expo LocationObject */
|
|
50
|
+
rawLocation: SimLocationObject | null;
|
|
47
51
|
/** Playback controls */
|
|
48
52
|
controls: SimulatorControls;
|
|
49
53
|
/** Recording controls */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSimulator.d.ts","sourceRoot":"","sources":["../../../../src/react-native/useSimulator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC3G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,aAAa,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACnC,8CAA8C;IAC9C,MAAM,EAAE,OAAO,CAAC;IAChB,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,eAAe,GAAG,kBAAkB,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAClG,+BAA+B;IAC/B,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,mCAAmC;IACnC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC/C,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,MAAM,UAAU,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,2DAA2D;IAC3D,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACtC,wBAAwB;IACxB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,yBAAyB;IACzB,OAAO,EAAE,eAAe,CAAC;IACzB,yCAAyC;IACzC,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAwF7E"}
|
|
@@ -88,8 +88,11 @@ export function useSimulator(options) {
|
|
|
88
88
|
setIsRecording(false);
|
|
89
89
|
return engineRef.current?.stopRecording() ?? null;
|
|
90
90
|
}, []);
|
|
91
|
+
const location = position?.location ?? (position ? { coords: position.coords, timestamp: position.timestamp } : null);
|
|
91
92
|
return {
|
|
92
93
|
position,
|
|
94
|
+
location,
|
|
95
|
+
rawLocation: location,
|
|
93
96
|
controls: { pause, resume, seek, setSpeed },
|
|
94
97
|
session: { start: startSession, stop: stopSession },
|
|
95
98
|
isRecording,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* <trkpt> (track points — most common)
|
|
9
9
|
* <wpt> (waypoints)
|
|
10
10
|
*/
|
|
11
|
-
import type { Coordinate } from '
|
|
11
|
+
import type { Coordinate } from '@ingissa/navcore-core';
|
|
12
12
|
export interface GpxParseResult {
|
|
13
13
|
coordinates: Coordinate[];
|
|
14
14
|
/** Milliseconds since epoch for each coordinate (0 if no time element) */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GpxParser.d.ts","sourceRoot":"","sources":["../../../../src/replay/GpxParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,0EAA0E;IAC1E,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,wCAAwC;QACxC,WAAW,EAAE,MAAM,CAAC;QACpB,mEAAmE;QACnE,UAAU,EAAE,MAAM,CAAC;QACnB,qCAAqC;QACrC,SAAS,EAAE,MAAM,CAAC;QAClB,iDAAiD;QACjD,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,qBAAa,SAAS;IACpB;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc;IAuE/C;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc;CAUlD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionRecorder.d.ts","sourceRoot":"","sources":["../../../../src/replay/SessionRecorder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,eAAe,CAAC;AAW7D,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;AAElD,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,QAAQ,CAA2B;IAE3C;;;;OAIG;IACH,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAM/B;;;;OAIG;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,UAAU;IA0BvC;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM;IAkBpC,OAAO,CAAC,MAAM,CAAC,MAAM;IAqCrB,OAAO,CAAC,MAAM,CAAC,MAAM;CAOtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScenarioInjector.d.ts","sourceRoot":"","sources":["../../../../src/scenarios/ScenarioInjector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;AAChE,MAAM,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;AAE/D,qBAAa,gBAAgB;IAC3B,uCAAuC;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;IACzD,+EAA+E;IAC/E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,wCAAwC;IACxC,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,eAAe,CAA8C;IAErE,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,KAAK,CAAsB;gBAEvB,OAAO,CAAC,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,mBAAmB;IAOvE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAIlC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAS1B,KAAK,IAAI,IAAI;IASb;;;;;OAKG;IACH,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAa9C,IAAI,cAAc,IAAI,QAAQ,GAAG,IAAI,CAEpC;IAED,kCAAkC;IAClC,OAAO,IAAI,IAAI;IAMf;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,QAAQ;IAUjE;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ;IAShE,kEAAkE;IAClE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ;IASvC,4EAA4E;IAC5E,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,SAAO,GAAG,QAAQ;IAUjF;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,QAAQ;IAYxF,OAAO,CAAC,KAAK;IAiBb,OAAO,CAAC,iBAAiB;CAM1B"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ingissa/navcore-simulator",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Headless GPS simulator for NavCore. Works in Node.js, React Native, and CI.",
|
|
5
5
|
"author": "Ingissa <8abnav@gmail.com>",
|
|
6
|
-
"license": "
|
|
7
|
-
"homepage": "https://navcore
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
7
|
+
"homepage": "https://navcore.dev",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/ingissa/
|
|
10
|
+
"url": "git+https://github.com/ingissa/navcore-sdk.git"
|
|
11
11
|
},
|
|
12
12
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/ingissa/
|
|
13
|
+
"url": "https://github.com/ingissa/navcore-sdk/issues"
|
|
14
14
|
},
|
|
15
15
|
"main": "dist/index.js",
|
|
16
16
|
"module": "dist/index.mjs",
|
|
@@ -22,25 +22,35 @@
|
|
|
22
22
|
"types": "./dist/index.d.ts"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
|
-
"files": [
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"src",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
26
30
|
"sideEffects": false,
|
|
27
31
|
"publishConfig": {
|
|
28
32
|
"access": "public"
|
|
29
33
|
},
|
|
30
|
-
"engines": {
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=16"
|
|
36
|
+
},
|
|
31
37
|
"scripts": {
|
|
32
38
|
"build": "tsc -p tsconfig.build.json",
|
|
33
39
|
"lint": "tsc --noEmit",
|
|
34
40
|
"prepublishOnly": "npm run build"
|
|
35
41
|
},
|
|
36
42
|
"peerDependencies": {
|
|
37
|
-
"@ingissa/navcore-core": "^1.0.
|
|
43
|
+
"@ingissa/navcore-core": "^1.0.7",
|
|
38
44
|
"react": ">=18",
|
|
39
45
|
"react-native": ">=0.72"
|
|
40
46
|
},
|
|
41
47
|
"peerDependenciesMeta": {
|
|
42
|
-
"react": {
|
|
43
|
-
|
|
48
|
+
"react": {
|
|
49
|
+
"optional": true
|
|
50
|
+
},
|
|
51
|
+
"react-native": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
44
54
|
},
|
|
45
55
|
"devDependencies": {
|
|
46
56
|
"@types/node": "^25.8.0"
|