refactor(hud): share the warning line and trim the summary helpers

One provenanceLine() builds STATE | text | LAYERS for the HUD and
get_hud_caption. hasWord is one lookaround regex, capAtWord one grapheme
pass. Feed-state helpers are imported from layerSnapshot.js directly, and the
kept-whole sanitizer cases are one table.
This commit is contained in:
German Khokhlov committed 2026-11-03 14:45:32 +04:00
1 parent ab8691383b
commit 03c168d7c9
6 files changed
+93 -117

No files matched your search

+11 -16
View File
@@ -1,5 +1,5 @@
import { SNAPSHOT_FEED_STATES } from '../../../src/data/layerSnapshot.js';
import {
HUD_SUMMARY_FEED_STATES,
HUD_SUMMARY_MAX_CHARS,
HUD_SUMMARY_MAX_UNSPACED_CHARS,
HUD_SUMMARY_RESPONSE_FORMAT,
@@ -33,7 +33,7 @@ function parseHudSummaryReply(text, locale) {
} catch {
/* not JSON: no summary */
}
const feedState = HUD_SUMMARY_FEED_STATES.includes(reply?.feedState)
const feedState = SNAPSHOT_FEED_STATES.includes(reply?.feedState)
? reply.feedState
: null;
return {
@@ -64,24 +64,19 @@ function toHudSummary(value, requested) {
* than that is cut where the cap falls.
*/
function capAtWord(text, max, locale) {
const graphemes = (value) => [
...new Intl.Segmenter(locale, { granularity: 'grapheme' }).segment(value),
const graphemes = [
...new Intl.Segmenter(locale, { granularity: 'grapheme' }).segment(text),
];
if (graphemes(text).length <= max) return text;
let kept = '';
for (const { segment } of new Intl.Segmenter(locale, {
if (graphemes.length <= max) return text;
const cut = graphemes[max].index;
let end = 0;
for (const { index, segment } of new Intl.Segmenter(locale, {
granularity: 'word',
}).segment(text)) {
if (graphemes(kept + segment).length > max) break;
kept += segment;
if (index + segment.length > cut) break;
end = index + segment.length;
}
return (
kept.trim() ||
graphemes(text)
.slice(0, max)
.map(({ segment }) => segment)
.join('')
);
return text.slice(0, end).trim() || text.slice(0, cut);
}
async function handleHudSummary(req, res) {