返回 DeepSeek-Reasonix
markdownByteEstimate.ts
根目录 / desktop / frontend / src / lib / markdownByteEstimate.ts
1 import type { RootContent as HastRootContent } from "hast";
2 import type { SelectionProjectionBlock } from "./markdownSelectionProjection";
3
4 /** Allocation-free byte-weight estimate for parsed transcript Markdown. */
5 export function estimateHastBytes(blocks: readonly SelectionProjectionBlock[]): number {
6 let bytes = 0;
7 const walk = (node: HastRootContent): void => {
8 bytes += 48;
9 if (node.type === "text" || node.type === "comment") {
10 bytes += (node.value?.length ?? 0) * 2;
11 return;
12 }
13 if (node.type === "element") {
14 bytes += node.tagName.length * 2;
15 for (const key in node.properties) {
16 if (!Object.prototype.hasOwnProperty.call(node.properties, key)) continue;
17 const value = node.properties[key];
18 bytes += key.length * 2;
19 if (typeof value === "string") bytes += value.length * 2;
20 else if (Array.isArray(value)) bytes += value.length * 16;
21 else bytes += 16;
22 }
23 for (const child of node.children) walk(child);
24 }
25 };
26 for (const block of blocks) {
27 if (block.virtualTable) {
28 bytes += block.virtualTable.header.reduce((total, cell) => total + 24 + cell.length * 2, 0);
29 bytes += block.virtualTable.rows.reduce(
30 (total, row) => total + 24 + row.reduce((rowTotal, cell) => rowTotal + 24 + cell.length * 2, 0),
31 0,
32 );
33 }
34 for (const child of block.children) walk(child);
35 }
36 return bytes;
37 }
38
38 lines TYPESCRIPT