Ensure chat history fetches full message limit (#428)

This commit is contained in:
l5y
2025-11-11 22:33:30 +01:00
committed by GitHub
parent 8b090cb238
commit e40c0d9078
3 changed files with 90 additions and 4 deletions
@@ -0,0 +1,41 @@
/*
* Copyright © 2025-26 l5yth & contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import test from 'node:test';
import assert from 'node:assert/strict';
import { MESSAGE_LIMIT, normaliseMessageLimit } from '../message-limit.js';
test('normaliseMessageLimit defaults to the message limit for invalid input', () => {
assert.equal(normaliseMessageLimit(undefined), MESSAGE_LIMIT);
assert.equal(normaliseMessageLimit(null), MESSAGE_LIMIT);
assert.equal(normaliseMessageLimit(''), MESSAGE_LIMIT);
assert.equal(normaliseMessageLimit('abc'), MESSAGE_LIMIT);
assert.equal(normaliseMessageLimit(-100), MESSAGE_LIMIT);
assert.equal(normaliseMessageLimit(0), MESSAGE_LIMIT);
assert.equal(normaliseMessageLimit(Number.POSITIVE_INFINITY), MESSAGE_LIMIT);
});
test('normaliseMessageLimit clamps numeric input to the upper bound', () => {
assert.equal(normaliseMessageLimit(MESSAGE_LIMIT + 1), MESSAGE_LIMIT);
assert.equal(normaliseMessageLimit(MESSAGE_LIMIT * 2), MESSAGE_LIMIT);
});
test('normaliseMessageLimit accepts positive finite values', () => {
assert.equal(normaliseMessageLimit(250), 250);
assert.equal(normaliseMessageLimit('750'), 750);
assert.equal(normaliseMessageLimit(42.9), 42);
});
+6 -4
View File
@@ -38,6 +38,7 @@ import {
formatChatPresetTag
} from './chat-format.js';
import { initializeInstanceSelector } from './instance-selector.js';
import { MESSAGE_LIMIT, normaliseMessageLimit } from './message-limit.js';
import { CHAT_LOG_ENTRY_TYPES, buildChatTabModel, MAX_CHANNEL_INDEX } from './chat-log-tabs.js';
import { renderChatTabs } from './chat-tabs.js';
import { formatPositionHighlights, formatTelemetryHighlights } from './chat-log-highlights.js';
@@ -142,7 +143,7 @@ let messagesById = new Map();
logger: console,
});
const NODE_LIMIT = 1000;
const CHAT_LIMIT = 1000;
const CHAT_LIMIT = MESSAGE_LIMIT;
const CHAT_RECENT_WINDOW_SECONDS = 7 * 24 * 60 * 60;
const REFRESH_MS = config.refreshMs;
const CHAT_ENABLED = Boolean(config.chatEnabled);
@@ -2997,9 +2998,10 @@ let messagesById = new Map();
* @param {number} [limit=NODE_LIMIT] Maximum number of rows.
* @returns {Promise<Array<Object>>} Parsed message payloads.
*/
async function fetchMessages(limit = NODE_LIMIT) {
async function fetchMessages(limit = MESSAGE_LIMIT) {
if (!CHAT_ENABLED) return [];
const r = await fetch(`/api/messages?limit=${limit}`, { cache: 'no-store' });
const safeLimit = normaliseMessageLimit(limit);
const r = await fetch(`/api/messages?limit=${safeLimit}`, { cache: 'no-store' });
if (!r.ok) throw new Error('HTTP ' + r.status);
return r.json();
}
@@ -3636,7 +3638,7 @@ let messagesById = new Map();
fetchNodes(),
positionsPromise,
neighborPromise,
fetchMessages(),
fetchMessages(MESSAGE_LIMIT),
telemetryPromise,
]);
nodes.forEach(applyNodeNameFallback);
+43
View File
@@ -0,0 +1,43 @@
/*
* Copyright © 2025-26 l5yth & contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Maximum number of chat messages that the API can return in a single request.
* @type {number}
*/
export const MESSAGE_LIMIT = 1000;
/**
* Normalise a candidate limit for the messages API to remain within supported bounds.
*
* The API clamps responses to {@link MESSAGE_LIMIT}, so this helper ensures the
* frontend always requests an allowed value while defaulting to the upper bound
* when callers omit or provide invalid data.
*
* @param {*} limit Candidate limit value supplied by the caller.
* @returns {number} Safe, positive limit capped at {@link MESSAGE_LIMIT}.
*/
export function normaliseMessageLimit(limit) {
const parsed = Number.parseFloat(limit);
if (!Number.isFinite(parsed) || parsed <= 0) {
return MESSAGE_LIMIT;
}
const floored = Math.floor(parsed);
if (floored <= 0) {
return MESSAGE_LIMIT;
}
return Math.min(floored, MESSAGE_LIMIT);
}