mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
102 lines
4.0 KiB
JavaScript
102 lines
4.0 KiB
JavaScript
// Attribute a built chunk's minified bytes to source npm packages / workspace dirs via its
|
||
// sourcemap (zero-dependency VLQ decoder). The dist-audit companion of the shell chunk-layout
|
||
// decision (.agents/notes/implemented/architecture/2026-08-06-web-shell-dist-chunk-layout.md):
|
||
// verifies vendor/index membership after changing VENDOR_PACKAGES or bumping render deps.
|
||
// Usage: node scripts/attribute-chunk-bytes.mjs <chunk.js> [--top N]
|
||
import { readFileSync } from 'node:fs'
|
||
|
||
const chunkPath = process.argv[2]
|
||
const topN = Number(process.argv[process.argv.indexOf('--top') + 1] || 40)
|
||
const code = readFileSync(chunkPath, 'utf8')
|
||
const map = JSON.parse(readFileSync(chunkPath + '.map', 'utf8'))
|
||
|
||
const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||
const charToInt = new Map([...B64].map((c, i) => [c, i]))
|
||
|
||
// Decode one VLQ-encoded segment list line by line.
|
||
const lines = code.split('\n')
|
||
const bySource = new Float64Array(map.sources.length)
|
||
let unmapped = 0
|
||
|
||
let srcIdx = 0, srcLine = 0, srcCol = 0, nameIdx = 0
|
||
const mappingLines = map.mappings.split(';')
|
||
for (let li = 0; li < mappingLines.length; li++) {
|
||
const lineLen = li < lines.length ? lines[li].length + 1 : 0
|
||
const segsRaw = mappingLines[li]
|
||
if (segsRaw === '') { unmapped += lineLen; continue }
|
||
let genCol = 0
|
||
const segs = []
|
||
for (const segStr of segsRaw.split(',')) {
|
||
const fields = []
|
||
let shift = 0, value = 0
|
||
for (const ch of segStr) {
|
||
const digit = charToInt.get(ch)
|
||
value += (digit & 31) << shift
|
||
if (digit & 32) { shift += 5 } else {
|
||
fields.push((value & 1) ? -(value >>> 1) : (value >>> 1))
|
||
shift = 0; value = 0
|
||
}
|
||
}
|
||
genCol += fields[0]
|
||
if (fields.length > 1) {
|
||
srcIdx += fields[1]; srcLine += fields[2]; srcCol += fields[3]
|
||
if (fields.length > 4) nameIdx += fields[4]
|
||
segs.push([genCol, srcIdx])
|
||
} else {
|
||
segs.push([genCol, -1])
|
||
}
|
||
}
|
||
if (segs[0][0] > 0) unmapped += segs[0][0]
|
||
for (let i = 0; i < segs.length; i++) {
|
||
const end = i + 1 < segs.length ? segs[i + 1][0] : lineLen
|
||
const span = Math.max(0, end - segs[i][0])
|
||
if (segs[i][1] >= 0) bySource[segs[i][1]] += span
|
||
else unmapped += span
|
||
}
|
||
}
|
||
|
||
// Aggregate source path -> package bucket.
|
||
function bucketOf(src) {
|
||
if (src.startsWith(' |