@sailingnaturali/signalk-dsc 0.5.5 → 0.5.6

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 (2) hide show
  1. package/index.js +28 -40
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -34,6 +34,7 @@ const {
34
34
  buildLogbookText,
35
35
  captureOwnShip,
36
36
  buildObservations,
37
+ createNotifier,
37
38
  unwrap,
38
39
  writeLogbookEntry,
39
40
  } = require('@sailingnaturali/signalk-distress-core');
@@ -142,37 +143,33 @@ module.exports = function makePlugin(app) {
142
143
  };
143
144
  }
144
145
 
146
+ // Notification plumbing (raise/clear/reannounce) is shared with
147
+ // signalk-ais-distress via signalk-distress-core. A non-alarming category
148
+ // (routine/unknown, not in NOTIFICATION_STATES) makes raise a no-op.
149
+ const notifier = createNotifier({
150
+ app,
151
+ pluginId: plugin.id,
152
+ pathFor: (event) => `notifications.dsc.${event.category}`,
153
+ stateFor: (event) => NOTIFICATION_STATES[event.category],
154
+ });
155
+
156
+ // Rebuild the spoken message against the current own-ship position — range
157
+ // and direction shift as we move. Terse on purpose: this string gets spoken;
158
+ // full detail lives in the resource store and the logbook entry.
159
+ function refreshMessage(event) {
160
+ event.message = buildMessage(event, messageContext(event));
161
+ return event;
162
+ }
163
+
145
164
  function notify(event) {
146
- const state = NOTIFICATION_STATES[event.category];
147
- if (!state) return;
148
- app.handleMessage(plugin.id, {
149
- updates: [
150
- {
151
- values: [
152
- {
153
- path: `notifications.dsc.${event.category}`,
154
- value: {
155
- state,
156
- method: ['visual', 'sound'],
157
- // Kept terse on purpose: this string gets spoken by the
158
- // voice pipeline. Full detail lives in the resource store
159
- // and the logbook entry.
160
- message: buildMessage(event, messageContext(event)),
161
- timestamp: event.receivedAt,
162
- },
163
- },
164
- ],
165
- },
166
- ],
167
- });
165
+ refreshMessage(event);
166
+ notifier.raise(event);
168
167
  }
169
168
 
170
169
  /** Clear an active DSC alarm: drop the live notification from our own source
171
170
  * and stamp the stored events so the restart reannounce skips them. */
172
171
  function clearCategory(category) {
173
- app.handleMessage(plugin.id, {
174
- updates: [{ values: [{ path: `notifications.dsc.${category}`, value: null }] }],
175
- });
172
+ notifier.clear(`notifications.dsc.${category}`);
176
173
  store.markCleared((e) => e.category === category, new Date().toISOString());
177
174
  }
178
175
 
@@ -420,23 +417,14 @@ module.exports = function makePlugin(app) {
420
417
  // Survive server restarts mid-incident: re-raise the newest alert per
421
418
  // category that is still fresh (a received MAYDAY must not vanish just
422
419
  // because the server bounced). Delayed so position providers are up and
423
- // the spoken message can say "N miles <direction>" instead of raw
424
- // coordinates.
420
+ // the refreshed spoken message can say "N miles <direction>" instead of raw
421
+ // coordinates. Non-alarming categories are skipped by raise's no-op path.
425
422
  reannounceTimer = setTimeout(() => {
426
423
  if (!started) return;
427
- const now = Date.now();
428
- const reannounced = new Set();
429
- const events = store.list();
430
- for (let i = events.length - 1; i >= 0; i--) {
431
- const event = events[i];
432
- if (!NOTIFICATION_STATES[event.category] || reannounced.has(event.category)) continue;
433
- if (event.clearedAt) continue; // operator-cleared: never resurrect
434
- const at = Date.parse(event.lastReceivedAt || event.receivedAt);
435
- if (now - at <= REANNOUNCE_WINDOW_MS) {
436
- notify(event);
437
- reannounced.add(event.category);
438
- }
439
- }
424
+ notifier.reannounce(store.list(), {
425
+ window: REANNOUNCE_WINDOW_MS,
426
+ prepare: refreshMessage,
427
+ });
440
428
  }, options.reannounceDelayMs ?? 30000);
441
429
  };
442
430
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sailingnaturali/signalk-dsc",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "Receive, log, and alert on DSC (VHF digital selective calling) calls — distress, urgency, safety, routine — from NMEA 0183 ($CDDSC/$CDDSE) and NMEA 2000 (PGN 129808).",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -49,6 +49,6 @@
49
49
  "node": ">=18"
50
50
  },
51
51
  "dependencies": {
52
- "@sailingnaturali/signalk-distress-core": "^0.2.0"
52
+ "@sailingnaturali/signalk-distress-core": "^0.3.0"
53
53
  }
54
54
  }