fix(markdown-core): treat infinity chunk limit as unbounded

Fix render-aware markdown chunking so `Number.POSITIVE_INFINITY` is treated as an explicit unbounded chunk limit instead of falling back to `1`.

This preserves full Signal media captions and disabled Signal text chunking while keeping invalid non-finite limits on the existing fallback path.

Fixes #92734.
Thanks @yhterrance for the report and fix.
This commit is contained in:
Terrance Chen
2026-06-13 13:29:12 -07:00
committed by GitHub
parent 4e4ea1c16b
commit 15e4fbf593
3 changed files with 31 additions and 0 deletions

View File

@@ -296,6 +296,16 @@ describe("splitSignalFormattedText", () => {
});
describe("markdownToSignalTextChunks", () => {
it("treats Infinity as unbounded for media captions", () => {
const markdown = "Here's **another** photo from today's walk.";
const chunks = markdownToSignalTextChunks(markdown, Number.POSITIVE_INFINITY);
expect(chunks).toHaveLength(1);
expect(chunks[0]?.text).toBe("Here's another photo from today's walk.");
expect(chunks[0]?.styles.map((style) => style.style)).toContain("BOLD");
});
describe("link expansion chunk limit", () => {
it("does not exceed chunk limit after link expansion", () => {
// Create text that is close to limit, with a link that will expand

View File

@@ -84,4 +84,18 @@ describe("renderMarkdownIRChunksWithinLimit", () => {
expect(chunks.map((chunk) => chunk.source.text)).toEqual(["a", "b", "c"]);
expect(chunks.every((chunk) => chunk.rendered.length <= 1)).toBe(true);
});
it("treats Infinity as no size cap and returns a single chunk", () => {
const text = "one two three four five six seven eight nine ten";
const ir = markdownToIR(text);
const chunks = renderMarkdownIRChunksWithinLimit({
ir,
limit: Number.POSITIVE_INFINITY,
renderChunk: renderEscapedHtml,
measureRendered: (rendered) => rendered.length,
});
expect(chunks).toHaveLength(1);
expect(chunks[0]?.source.text).toBe(text);
});
});

View File

@@ -47,6 +47,13 @@ export function renderMarkdownIRChunksWithinLimit<TRendered>(
return [];
}
// Callers pass Infinity to mean "no size cap" (e.g. a media caption that must not be
// split). resolveIntegerOption rejects non-finite values and would fall back to 1,
// shattering the text into one chunk per character; emit the whole IR as one chunk.
if (options.limit === Number.POSITIVE_INFINITY) {
return [{ source: options.ir, rendered: options.renderChunk(options.ir) }];
}
const normalizedLimit = resolveIntegerOption(options.limit, 1, { min: 1 });
const pending = chunkMarkdownIR(options.ir, normalizedLimit);
const finalized: MarkdownIR[] = [];