@meri-imperiumi/signalk-passage-briefing 0.13.1 → 0.13.2
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/CHANGELOG.md +5 -0
- package/package.json +1 -1
- package/plugin/index.js +17 -3
- package/tests/plugin.test.js +55 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.13.2] - 2026-10-19
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Briefing refresh crashed with 502 `Cannot read properties of undefined (reading '1')` when the course provider reported the vessel navigating the briefed route while still heading to its first waypoint (`navigation.course.activeRoute.pointIndex` 0, forward — e.g. just after engaging a route): the progress trim read `raw[pointIndex - 1]` for a last passed waypoint that does not exist yet. Forward pointIndex 0 now trims to the vessel position with nothing trimmed off (`trimmedFromNm` 0), and without a known vessel position the full untrimmed plan serves.
|
|
9
|
+
|
|
5
10
|
## [0.13.1] - 2026-10-19
|
|
6
11
|
|
|
7
12
|
### Changed
|
package/package.json
CHANGED
package/plugin/index.js
CHANGED
|
@@ -564,12 +564,25 @@ module.exports = (app) => {
|
|
|
564
564
|
) {
|
|
565
565
|
return null; // Not past the first point, or an index we cannot use
|
|
566
566
|
}
|
|
567
|
+
const target = raw[pointIndex];
|
|
568
|
+
const vessel = vesselPosition();
|
|
569
|
+
// Heading to the first waypoint (forward pointIndex 0): no leg of
|
|
570
|
+
// the plan is behind the boat, so there is no last passed waypoint
|
|
571
|
+
// to anchor the trim distance on. The plan starts at the vessel
|
|
572
|
+
// when known (nothing trimmed off, 0 nm in), else serves in full.
|
|
573
|
+
if (!reverse && pointIndex === 0) {
|
|
574
|
+
if (!vessel) {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
return {
|
|
578
|
+
coordinates: [[vessel.lon, vessel.lat], ...raw],
|
|
579
|
+
trimmedFromNm: 0,
|
|
580
|
+
};
|
|
581
|
+
}
|
|
567
582
|
// Travel order decides what remains: forward navigates toward
|
|
568
583
|
// higher indices, reverse toward lower ones (the course provider's
|
|
569
584
|
// `reverse` flag). The start point is the vessel's actual position
|
|
570
585
|
// when available, else the last passed waypoint.
|
|
571
|
-
const target = raw[pointIndex];
|
|
572
|
-
const vessel = vesselPosition();
|
|
573
586
|
const start = vessel
|
|
574
587
|
? [vessel.lon, vessel.lat]
|
|
575
588
|
: reverse
|
|
@@ -579,7 +592,8 @@ module.exports = (app) => {
|
|
|
579
592
|
? raw.slice(0, pointIndex + 1).reverse()
|
|
580
593
|
: raw.slice(pointIndex);
|
|
581
594
|
// Distance along the stored plan from its start to the trim point:
|
|
582
|
-
// the boat sits between the target and the last passed point
|
|
595
|
+
// the boat sits between the target and the last passed point (the
|
|
596
|
+
// forward pointIndex 0 case returned above, so this is defined)
|
|
583
597
|
const reference = reverse ? target : raw[pointIndex - 1];
|
|
584
598
|
const anchorSlice = reverse
|
|
585
599
|
? raw.slice(0, pointIndex + 1)
|
package/tests/plugin.test.js
CHANGED
|
@@ -2802,6 +2802,61 @@ test("route progress: briefing trims to the sailed legs (work doc #28)", async (
|
|
|
2802
2802
|
revPayload.trimmedFromNm > 55 && revPayload.trimmedFromNm < 65,
|
|
2803
2803
|
`reversed trimmedFromNm ${revPayload.trimmedFromNm}`,
|
|
2804
2804
|
);
|
|
2805
|
+
|
|
2806
|
+
// Just engaged, heading to the first waypoint (pointIndex 0): no
|
|
2807
|
+
// waypoint is behind the boat, so the plan starts at the vessel
|
|
2808
|
+
// with nothing trimmed off. Regression: the trim used to read
|
|
2809
|
+
// raw[-1] and crashed the refresh with "Cannot read properties of
|
|
2810
|
+
// undefined (reading '1')" (502 on /api/briefing/refresh)
|
|
2811
|
+
app.getSelfPath = (path) =>
|
|
2812
|
+
path === "navigation.position"
|
|
2813
|
+
? { latitude: -0.05, longitude: 0 }
|
|
2814
|
+
: path === "navigation.course.activeRoute"
|
|
2815
|
+
? {
|
|
2816
|
+
href: "/resources/routes/r1",
|
|
2817
|
+
pointIndex: 0,
|
|
2818
|
+
}
|
|
2819
|
+
: null;
|
|
2820
|
+
const engagedRes = await call("/api/briefing/refresh", {
|
|
2821
|
+
query: { route: "r1" },
|
|
2822
|
+
});
|
|
2823
|
+
assert.equal(
|
|
2824
|
+
engagedRes.code,
|
|
2825
|
+
null,
|
|
2826
|
+
`engaged refresh: ${JSON.stringify(engagedRes.payload)}`,
|
|
2827
|
+
);
|
|
2828
|
+
const engaged = await call("/api/briefing", { query: { route: "r1" } });
|
|
2829
|
+
const engagedPayload = engaged.payload.payload;
|
|
2830
|
+
assert.ok(
|
|
2831
|
+
Math.abs(engagedPayload.waypoints[0].lat + 0.05) < 0.01,
|
|
2832
|
+
`engaged start ${engagedPayload.waypoints[0].lat}`,
|
|
2833
|
+
);
|
|
2834
|
+
assert.equal(engagedPayload.trimmedFromNm, 0);
|
|
2835
|
+
// The full plan follows the boat: last waypoint is the route end
|
|
2836
|
+
assert.ok(
|
|
2837
|
+
Math.abs(engagedPayload.waypoints.at(-1).lat - 1.5) < 0.01,
|
|
2838
|
+
`engaged end ${engagedPayload.waypoints.at(-1).lat}`,
|
|
2839
|
+
);
|
|
2840
|
+
|
|
2841
|
+
// Same pointIndex 0 but no vessel position: no anchor for the
|
|
2842
|
+
// start — the full plan serves untrimmed
|
|
2843
|
+
app.getSelfPath = (path) =>
|
|
2844
|
+
path === "navigation.position"
|
|
2845
|
+
? null
|
|
2846
|
+
: path === "navigation.course.activeRoute"
|
|
2847
|
+
? {
|
|
2848
|
+
href: "/resources/routes/r1",
|
|
2849
|
+
pointIndex: 0,
|
|
2850
|
+
}
|
|
2851
|
+
: null;
|
|
2852
|
+
await call("/api/briefing/refresh", { query: { route: "r1" } });
|
|
2853
|
+
const untrimmed = await call("/api/briefing", { query: { route: "r1" } });
|
|
2854
|
+
const untrimmedPayload = untrimmed.payload.payload;
|
|
2855
|
+
assert.ok(
|
|
2856
|
+
Math.abs(untrimmedPayload.waypoints[0].lat) < 0.01,
|
|
2857
|
+
`untrimmed start ${untrimmedPayload.waypoints[0].lat}`,
|
|
2858
|
+
);
|
|
2859
|
+
assert.equal(untrimmedPayload.trimmedFromNm, undefined);
|
|
2805
2860
|
} finally {
|
|
2806
2861
|
globalThis.fetch = originalFetch;
|
|
2807
2862
|
}
|