a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
101
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(util-text): add ASCII fast-path to grapheme counting

Mary d7a8f603 9ccc7ef6

+79
+5
.changeset/ten-islands-attack.md
··· 1 + --- 2 + '@atcute/util-text': patch 3 + --- 4 + 5 + add ASCII fast-path to grapheme counting
+37
packages/misc/util-text/lib/index.rn.ts
··· 1 1 import { countGraphemes } from 'unicode-segmenter/grapheme'; 2 2 3 + const isAsciiWithoutCr = (text: string): boolean => { 4 + const len = text.length; 5 + let idx = 0; 6 + 7 + while (idx + 3 < len) { 8 + const a = text.charCodeAt(idx); 9 + const b = text.charCodeAt(idx + 1); 10 + const c = text.charCodeAt(idx + 2); 11 + const d = text.charCodeAt(idx + 3); 12 + 13 + if ((a | b | c | d) > 0x7f || a === 0x0d || b === 0x0d || c === 0x0d || d === 0x0d) { 14 + return false; 15 + } 16 + 17 + idx += 4; 18 + } 19 + 20 + while (idx < len) { 21 + const code = text.charCodeAt(idx); 22 + if (code > 0x7f || code === 0x0d) { 23 + return false; 24 + } 25 + 26 + idx++; 27 + } 28 + 29 + return true; 30 + }; 31 + 3 32 /** 4 33 * returns the grapheme length of a string 5 34 * @param text string to count graphemes in 6 35 * @returns grapheme count 7 36 */ 8 37 export const getGraphemeLength = (text: string): number => { 38 + if (isAsciiWithoutCr(text)) { 39 + return text.length; 40 + } 41 + 9 42 return countGraphemes(text); 10 43 }; 11 44 ··· 28 61 // grapheme count is definitely within max 29 62 if (min === 0 && utf16Len <= max) { 30 63 return true; 64 + } 65 + 66 + if (isAsciiWithoutCr(text)) { 67 + return utf16Len <= max; 31 68 } 32 69 33 70 const count = countGraphemes(text);
+37
packages/misc/util-text/lib/index.ts
··· 1 1 const segmenter = new Intl.Segmenter(); 2 2 3 + const isAsciiWithoutCr = (text: string): boolean => { 4 + const len = text.length; 5 + let idx = 0; 6 + 7 + while (idx + 3 < len) { 8 + const a = text.charCodeAt(idx); 9 + const b = text.charCodeAt(idx + 1); 10 + const c = text.charCodeAt(idx + 2); 11 + const d = text.charCodeAt(idx + 3); 12 + 13 + if ((a | b | c | d) > 0x7f || a === 0x0d || b === 0x0d || c === 0x0d || d === 0x0d) { 14 + return false; 15 + } 16 + 17 + idx += 4; 18 + } 19 + 20 + while (idx < len) { 21 + const code = text.charCodeAt(idx); 22 + if (code > 0x7f || code === 0x0d) { 23 + return false; 24 + } 25 + 26 + idx++; 27 + } 28 + 29 + return true; 30 + }; 31 + 3 32 /** 4 33 * returns the grapheme length of a string 5 34 * @param text string to count graphemes in 6 35 * @returns grapheme count 7 36 */ 8 37 export const getGraphemeLength = (text: string): number => { 38 + if (isAsciiWithoutCr(text)) { 39 + return text.length; 40 + } 41 + 9 42 const iterator = segmenter.segment(text)[Symbol.iterator](); 10 43 let count = 0; 11 44 ··· 35 68 // grapheme count is definitely within max 36 69 if (min === 0 && utf16Len <= max) { 37 70 return true; 71 + } 72 + 73 + if (isAsciiWithoutCr(text)) { 74 + return utf16Len <= max; 38 75 } 39 76 40 77 // count graphemes with early termination