mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-14 20:34:19 +08:00
74 lines
2.2 KiB
JavaScript
74 lines
2.2 KiB
JavaScript
'use strict';
|
|
/* SPDX-License-Identifier: Apache-2.0 */
|
|
/* Copyright 2025-2026 Lucas Albers <lucas.b.albers@gmail.com> */
|
|
'require baseclass';
|
|
|
|
/**
|
|
* Ring-buffer helpers for luci-app-fwlive poll ingest.
|
|
* LuCI modules must return baseclass.extend(...) — plain objects fail Class.isSubclass.
|
|
*
|
|
* While paused, ingest grows up to fetchLinesMax. Live mode caps at rowLimit.
|
|
* On resume, merge (do not replace) so pause-accumulated rows survive the first
|
|
* live poll — see issue #43 pause→resume data loss.
|
|
*/
|
|
|
|
function ingestCap(paused, rowLimit, fetchLinesMax) {
|
|
return paused ? fetchLinesMax : rowLimit;
|
|
}
|
|
|
|
function mergeById(entries, normalized, cap) {
|
|
if (!normalized || !normalized.length) {
|
|
if (!entries || !entries.length) return [];
|
|
return entries.slice(-cap);
|
|
}
|
|
|
|
const byId = {};
|
|
let i;
|
|
if (entries) {
|
|
for (i = 0; i < entries.length; i++) byId[entries[i].id] = entries[i];
|
|
}
|
|
for (i = 0; i < normalized.length; i++) byId[normalized[i].id] = normalized[i];
|
|
|
|
const merged = Object.keys(byId).map(function (id) {
|
|
return byId[id];
|
|
});
|
|
merged.sort(function (a, b) {
|
|
const ta = a.timestamp || 0;
|
|
const tb = b.timestamp || 0;
|
|
if (ta !== tb) return ta - tb;
|
|
return (a.log_id || 0) - (b.log_id || 0);
|
|
});
|
|
return merged.slice(-cap);
|
|
}
|
|
|
|
/**
|
|
* Apply a poll batch onto the current buffer.
|
|
*
|
|
* @param {object[]} entries - current buffer (oldest-first)
|
|
* @param {object[]} normalized - newly polled rows (oldest-first)
|
|
* @param {{ paused: boolean, resumeMerge: boolean, rowLimit: number, fetchLinesMax: number }} opts
|
|
* @returns {object[]} next buffer
|
|
*/
|
|
function applyFetchedEntries(entries, normalized, opts) {
|
|
const paused = !!(opts && opts.paused);
|
|
const resumeMerge = !!(opts && opts.resumeMerge);
|
|
const rowLimit = (opts && opts.rowLimit) || 0;
|
|
const fetchLinesMax = (opts && opts.fetchLinesMax) || rowLimit;
|
|
const cap = ingestCap(paused, rowLimit, fetchLinesMax);
|
|
const merge = paused || resumeMerge;
|
|
|
|
let next;
|
|
if (merge) next = mergeById(entries, normalized, cap);
|
|
else next = (normalized || []).slice(-cap);
|
|
|
|
if (!paused && next.length > rowLimit) next = next.slice(-rowLimit);
|
|
|
|
return next;
|
|
}
|
|
|
|
return baseclass.extend({
|
|
ingestCap: ingestCap,
|
|
mergeById: mergeById,
|
|
applyFetchedEntries: applyFetchedEntries
|
|
});
|