(content: string)
| 70 | return MD_SYNTAX_RE.test(s.length > 500 ? s.slice(0, 500) : s); |
| 71 | } |
| 72 | function cachedLexer(content: string): { |
| 73 | tokens: Token[]; |
| 74 | cacheKey?: string; |
| 75 | } { |
| 76 | // Fast path: plain text with no markdown syntax → single paragraph token. |
| 77 | // Skips marked.lexer's full GFM parse (~3ms on long content). Not cached — |
| 78 | // reconstruction is a single object allocation, and caching would retain |
| 79 | // 4× content in raw/text fields plus the hash key for zero benefit. |
| 80 | if (!hasMarkdownSyntax(content)) { |
| 81 | return { |
| 82 | tokens: [{ |
| 83 | type: 'paragraph', |
| 84 | raw: content, |
| 85 | text: content, |
| 86 | tokens: [{ |
| 87 | type: 'text', |
| 88 | raw: content, |
| 89 | text: content |
| 90 | }] |
| 91 | } as Token] |
| 92 | }; |
| 93 | } |
| 94 | const key = hashContent(content); |
| 95 | const hit = tokenCache.get(key); |
| 96 | if (hit) { |
| 97 | // Promote to MRU — without this the eviction is FIFO (scrolling back to |
| 98 | // an early message evicts the very item you're looking at). |
| 99 | tokenCache.delete(key); |
| 100 | tokenCache.set(key, hit); |
| 101 | return { |
| 102 | tokens: hit, |
| 103 | cacheKey: key |
| 104 | }; |
| 105 | } |
| 106 | const tokens = lexMarkdownPreservingPreformattedDiagrams(content); |
| 107 | if (tokenCache.size >= TOKEN_CACHE_MAX) { |
| 108 | // LRU-ish: drop oldest. Map preserves insertion order. |
| 109 | const first = tokenCache.keys().next().value; |
| 110 | if (first !== undefined) tokenCache.delete(first); |
| 111 | } |
| 112 | tokenCache.set(key, tokens); |
| 113 | return { |
| 114 | tokens, |
| 115 | cacheKey: key |
| 116 | }; |
| 117 | } |
| 118 | |
| 119 | function buildMarkdownRenderBlocks(tokens: Token[], theme: string, highlight: CliHighlight | null): MarkdownRenderBlock[] { |
| 120 | const buildStartMs = nowMs(); |
no test coverage detected