Skip to content

Commit c9ea247

Browse files
perf(truncate): optimize grapheme truncation for large strings
1 parent 2729230 commit c9ea247

2 files changed

Lines changed: 27 additions & 3 deletions

File tree

packages/helpers/src/strings.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,15 @@ export function truncate(str, maxLength) {
2929

3030
const ellipsis = ELLIPSIS.slice(0, maxLength);
3131

32-
const graphemes = Array.from(graphemeSegmenter.segment(str), (s) => s.segment);
33-
if (graphemes.length < maxLength) return str;
32+
const graphemes = [];
3433

35-
return trimEnd(graphemes.slice(0, maxLength - ellipsis.length).join('')) + ellipsis;
34+
for (const s of graphemeSegmenter.segment(str)) {
35+
if (graphemes.length > maxLength) {
36+
return trimEnd(graphemes.slice(0, maxLength - ellipsis.length).join('')) + ellipsis;
37+
}
38+
39+
graphemes.push(s.segment);
40+
}
41+
42+
return str;
3643
}

packages/helpers/src/strings.test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,22 @@ describe('helpers', () => {
116116
expect(truncate(input, 19)).toBe('Truncate this 👩‍❤️‍💋‍👨...');
117117
expect(truncate(input, 20)).toBe('Truncate this 👩‍❤️‍💋‍👨 s...');
118118
});
119+
120+
it('should handle very long strings efficiently and correctly', () => {
121+
const longString = '👩‍❤️‍💋‍👨a'.repeat(100_000); // > 1MB
122+
const result = truncate(longString, 100);
123+
124+
expect.soft(result.endsWith('...')).toBeTruthy();
125+
expect.soft(result.startsWith('👩‍❤️‍💋‍👨a'.repeat(48))).toBeTruthy();
126+
expect.soft(result === '👩‍❤️‍💋‍👨a'.repeat(48) + '👩‍❤️‍💋‍👨' + '...').toBeTruthy();
127+
128+
// Truncate to a length less than ellipsis
129+
const result2 = truncate(longString, 2);
130+
expect.soft(result2).toBe('..');
131+
132+
// Truncate to a length greater than the string
133+
const result3 = truncate(longString, 200_000);
134+
expect(result3).toBe(longString);
135+
}, 100);
119136
});
120137
});

0 commit comments

Comments
 (0)