UNPKG

signalk-server

Version:

An implementation of a [Signal K](http://signalk.org) server for boats.

91 lines 3.34 kB
"use strict"; /** * LatestValuesAccumulator - Accumulates Signal K delta values during backpressure, * keeping only the latest value for each unique context:path:$source combination. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.accumulateLatestValue = accumulateLatestValue; exports.buildFlushDeltas = buildFlushDeltas; const server_api_1 = require("@signalk/server-api"); /** * Accumulate latest value per context:path:$source during backpressure. * Only keeps the most recent value for each unique combination, dropping intermediate updates. * * @param accumulator - Map to store accumulated values, keyed by context:path:$source * @param delta - Signal K delta to accumulate */ function accumulateLatestValue(accumulator, delta) { if (!delta.updates) return; for (const update of delta.updates) { if (!(0, server_api_1.hasValues)(update)) continue; for (const pv of update.values) { const key = `${delta.context}:${pv.path}:${update.$source || 'unknown'}`; accumulator.set(key, { context: delta.context, path: pv.path, value: pv.value, $source: update.$source, timestamp: update.timestamp }); } } } /** * Convert accumulated values to spec-compliant deltas. * Groups values by context and $source for proper delta structure. * * @param accumulator - Map of accumulated values * @param duration - How long backpressure was active in milliseconds * @returns Array of deltas, one per context, with $backpressure indicator */ function buildFlushDeltas(accumulator, duration) { if (accumulator.size === 0) return []; const countBefore = accumulator.size; // Group by context const byContext = new Map(); for (const [, item] of accumulator) { if (!byContext.has(item.context)) { byContext.set(item.context, new Map()); } // Group by $source within context const bySource = byContext.get(item.context); const sourceKey = item.$source || 'unknown'; if (!bySource.has(sourceKey)) { bySource.set(sourceKey, { $source: item.$source, timestamp: item.timestamp, values: [] }); } const update = bySource.get(sourceKey); if ((0, server_api_1.hasValues)(update)) { update.values.push({ path: item.path, // eslint-disable-next-line @typescript-eslint/no-explicit-any value: item.value }); // Use the most recent timestamp for this source if (item.timestamp && (!update.timestamp || item.timestamp > update.timestamp)) { update.timestamp = item.timestamp; } } } // Build one delta per context with backpressure indicator const deltas = []; for (const [context, bySourceTime] of byContext) { deltas.push({ context, updates: Array.from(bySourceTime.values()), $backpressure: { accumulated: countBefore, duration } }); } return deltas; } //# sourceMappingURL=LatestValuesAccumulator.js.map