35 lines
1.0 KiB
TypeScript
35 lines
1.0 KiB
TypeScript
export function chunkTextByBreakResolver(
|
|
text: string,
|
|
limit: number,
|
|
resolveBreakIndex: (window: string) => number,
|
|
): string[] {
|
|
if (!text) {
|
|
return [];
|
|
}
|
|
if (limit <= 0 || text.length <= limit) {
|
|
return [text];
|
|
}
|
|
const chunks: string[] = [];
|
|
let remaining = text;
|
|
while (remaining.length > limit) {
|
|
const window = remaining.slice(0, limit);
|
|
const candidateBreak = resolveBreakIndex(window);
|
|
const breakIdx =
|
|
Number.isFinite(candidateBreak) && candidateBreak > 0 && candidateBreak <= limit
|
|
? candidateBreak
|
|
: limit;
|
|
const rawChunk = remaining.slice(0, breakIdx);
|
|
const chunk = rawChunk.trimEnd();
|
|
if (chunk.length > 0) {
|
|
chunks.push(chunk);
|
|
}
|
|
const brokeOnSeparator = breakIdx < remaining.length && /\s/.test(remaining[breakIdx]);
|
|
const nextStart = Math.min(remaining.length, breakIdx + (brokeOnSeparator ? 1 : 0));
|
|
remaining = remaining.slice(nextStart).trimStart();
|
|
}
|
|
if (remaining.length) {
|
|
chunks.push(remaining);
|
|
}
|
|
return chunks;
|
|
}
|