@meri-imperiumi/signalk-mob-notifier 1.1.7 → 1.1.8

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.
@@ -19,12 +19,13 @@ jobs:
19
19
  publish-npm:
20
20
  needs: build
21
21
  runs-on: ubuntu-latest
22
+ permissions:
23
+ id-token: write # Required for OIDC
24
+ contents: read
22
25
  steps:
23
26
  - uses: actions/checkout@v5
24
27
  - uses: actions/setup-node@v6
25
28
  with:
26
- node-version: 22
29
+ node-version: 24
27
30
  registry-url: https://registry.npmjs.org/
28
31
  - run: npm publish
29
- env:
30
- NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
package/CHANGELOG.md CHANGED
@@ -1,20 +1,44 @@
1
- * 1.1.7 (2026-06-16)
2
- - Added application icon
3
- * 1.1.6 (2026-01-20)
4
- - Round distance to beacon with single decimal
5
- - Use EPIRB and SART terms for shorter notifications
6
- * 1.1.5 (2025-11-15)
7
- - Bump release
8
- * 1.1.4 (2025-11-12)
9
- - Fix reading MOB vessel data structure
10
- * 1.1.3 (2025-11-02)
11
- - Fix detection of beacon type (MOB/SART/EPIRB)
12
- * 1.1.2 (2025-11-01)
13
- - Better approach at getting MOB coordinates
14
- * 1.1.1 (2025-09-18)
15
- - Notifications include position when available
16
- * 1.1.0 (2025-09-04)
17
- - Notification is not re-published if it already exists
18
- * 1.0.0 (2025-08-25)
19
- - Initial release
1
+ # Changelog
20
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [1.1.8] - 2026-10-05
6
+ ### Changed
7
+ - Bump the `where` dependency to `^0.4.3`, which normalizes its bearing/direction longitude delta across the antimeridian (the upstream fix). The MOB message's distance and direction were already seam-safe — the haversine and bearing trig folds the seam — so this is a stay-current bump, pinning the upstream antimeridian-hardened version
8
+
9
+ ## [1.1.7] - 2026-06-16
10
+ ### Added
11
+ - Added application icon
12
+
13
+ ## [1.1.6] - 2026-01-20
14
+ ### Changed
15
+ - Round distance to beacon with single decimal
16
+ - Use EPIRB and SART terms for shorter notifications
17
+
18
+ ## [1.1.5] - 2025-11-15
19
+ ### Changed
20
+ - Bump release
21
+
22
+ ## [1.1.4] - 2025-11-12
23
+ ### Fixed
24
+ - Fix reading MOB vessel data structure
25
+
26
+ ## [1.1.3] - 2025-11-02
27
+ ### Fixed
28
+ - Fix detection of beacon type (MOB/SART/EPIRB)
29
+
30
+ ## [1.1.2] - 2025-11-01
31
+ ### Fixed
32
+ - Better approach at getting MOB coordinates
33
+
34
+ ## [1.1.1] - 2025-09-18
35
+ ### Changed
36
+ - Notifications include position when available
37
+
38
+ ## [1.1.0] - 2025-09-04
39
+ ### Changed
40
+ - Notification is not re-published if it already exists
41
+
42
+ ## [1.0.0] - 2025-08-25
43
+ ### Added
44
+ - Initial release
package/README.md CHANGED
@@ -11,4 +11,4 @@ Please note that this plugin aims to aid with noticing and locating crew overboa
11
11
 
12
12
  ## Changes
13
13
 
14
- See <CHANGELOG.md>
14
+ See [Changelog](CHANGELOG.md)
Binary file
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@meri-imperiumi/signalk-mob-notifier",
3
- "version": "1.1.7",
3
+ "version": "1.1.8",
4
4
  "description": "Create Signal K notifications for discovered AIS MOB, EPIRB, and SART beacons",
5
5
  "main": "plugin/index.js",
6
6
  "scripts": {
7
- "test": "eslint ."
7
+ "pretest": "eslint .",
8
+ "test": "node --test"
8
9
  },
9
10
  "repository": {
10
11
  "type": "git",
@@ -30,11 +31,11 @@
30
31
  "eslint-plugin-import": "^2.32.0"
31
32
  },
32
33
  "dependencies": {
33
- "where": "^0.4.2"
34
+ "where": "^0.4.3"
34
35
  },
35
36
  "signalk-plugin-enabled-by-default": true,
36
37
  "signalk": {
37
- "appIcon": "./doc/appicon.png",
38
+ "appIcon": "./doc/appicon-256.png",
38
39
  "displayName": "AIS MOB and EPIRB notifier",
39
40
  "screenshots": [
40
41
  "./doc/alert.png"
package/plugin/index.js CHANGED
@@ -165,7 +165,7 @@ module.exports = (app) => {
165
165
  });
166
166
  notified.push(mmsi);
167
167
  });
168
- }, settings.interval * 1000);
168
+ }, settings.interval ? settings.interval * 1000 : 30000);
169
169
  };
170
170
 
171
171
  plugin.stop = () => {
@@ -0,0 +1,85 @@
1
+ const { describe, it } = require('node:test');
2
+ const assert = require('node:assert/strict');
3
+
4
+ const pluginFactory = require('../plugin/index');
5
+
6
+ describe('plugin', () => {
7
+ const app = { debug: () => {}, error: () => {} };
8
+ const plugin = pluginFactory(app);
9
+
10
+ it('has required interface', () => {
11
+ assert.equal(typeof plugin.start, 'function');
12
+ assert.equal(typeof plugin.stop, 'function');
13
+ assert.ok(plugin.id);
14
+ });
15
+
16
+ it('starts and stops without error', () => {
17
+ plugin.start({}, () => {});
18
+ plugin.stop();
19
+ });
20
+ });
21
+
22
+ describe('MOB message across the antimeridian', () => {
23
+ it('reports the short-way distance and direction across 180°', () => {
24
+ // Vessel just east of the antimeridian, MOB beacon just west of it:
25
+ // the beacon is ~22 km east (over the seam), not half a world away.
26
+ const messages = [];
27
+ const statuses = [];
28
+ const raised = {};
29
+ const app = {
30
+ debug: () => {},
31
+ error: () => {},
32
+ selfId: 'urn:mrn:imo:mmsi:230099999',
33
+ getSelfPath: (path) => {
34
+ if (path === 'navigation.position') {
35
+ return { latitude: -14, longitude: 179.9 };
36
+ }
37
+ // The plugin dedups against the live notification subtree
38
+ return raised[path] ? { value: raised[path] } : undefined;
39
+ },
40
+ signalk: {
41
+ root: {
42
+ vessels: {
43
+ 'urn:mrn:imo:mmsi:972123456': {
44
+ navigation: {
45
+ position: { value: { latitude: -14, longitude: -179.9 } },
46
+ },
47
+ },
48
+ },
49
+ },
50
+ },
51
+ setPluginStatus: (s) => statuses.push(s),
52
+ handleMessage: (source, delta) => {
53
+ messages.push(delta);
54
+ delta.updates.forEach((u) => u.values.forEach((v) => {
55
+ if (v.path.startsWith('notifications.mob.') && v.value) {
56
+ raised[v.path] = v.value;
57
+ }
58
+ }));
59
+ },
60
+ };
61
+ const plugin = pluginFactory(app);
62
+ plugin.start({ interval: 0.01 });
63
+ return new Promise((resolve) => {
64
+ setTimeout(() => {
65
+ plugin.stop();
66
+ const notifications = messages
67
+ .flatMap((d) => d.updates)
68
+ .flatMap((u) => u.values)
69
+ .filter((v) => v.path.startsWith('notifications.mob.'));
70
+ assert.equal(notifications.length, 1, 'one MOB notification raised');
71
+ const { message } = notifications[0].value;
72
+ const meters = Number(message.match(/([\d.]+) meters/)[1]);
73
+ assert.ok(
74
+ meters > 20000 && meters < 24000,
75
+ `distance ${meters} m; expected ~22 km over the seam`,
76
+ );
77
+ assert.ok(
78
+ /to (east|southeast|northeast)/.test(message),
79
+ `direction in "${message}" should read across the seam as east`,
80
+ );
81
+ resolve();
82
+ }, 50);
83
+ });
84
+ });
85
+ });