Byte-budget truncators and sentence-extraction helpers
extracted from text-utils.ts to keep both modules under the 600-line
drift-guard budget enforced by test/unit/source-file-size.test.js.
This file is the clamping layer of the metadata text pipeline —
after shouldSkipDescriptionLine/stripInlineMarkdown produce a
candidate description / title, the helpers here apply the SEO-budget
shape rules:
truncateDescription — clamp to DESCRIPTION_MAX_LENGTH on a
sentence/word boundary, appending … when truncation occurs.
truncateTitle — clamp to TITLE_MAX_LENGTH on a
clause boundary, returning '' rather than emitting a
mid-sentence ellipsised title.
extractFirstSentence — return the first complete sentence
from a prose paragraph, or '' when no clean terminator is
available within the soft-min window.
Bounded-context rules match text-utils.ts:
No upward imports — pure helpers, no I/O, no globals.
Deterministic — same input always produces same output.
Locale-agnostic — operates on raw prose in any of the 14
publishing languages.
Description
Byte-budget truncators and sentence-extraction helpers extracted from
text-utils.tsto keep both modules under the 600-line drift-guard budget enforced bytest/unit/source-file-size.test.js.This file is the clamping layer of the metadata text pipeline — after
shouldSkipDescriptionLine/stripInlineMarkdownproduce a candidate description / title, the helpers here apply the SEO-budget shape rules:DESCRIPTION_MAX_LENGTHon a sentence/word boundary, appending…when truncation occurs.EXTENDED_DESCRIPTION_MAX_LENGTH(used byog:description).TITLE_MAX_LENGTHon a clause boundary, returning''rather than emitting a mid-sentence ellipsised title.''when no clean terminator is available within the soft-min window.Bounded-context rules match
text-utils.ts: