// Streaming invariant check: for every file, several fixed chunk sizes must give the whole-input output and errors. // Usage: node stream-sweep.mjs [maxSmall=1024] [shard/shards] // Chunk sizes 1 and 2 only for files up to maxSmall chars; run shards 0/4..3/4 in parallel for a big tree. import fs from "node:fs"; import path from "node:path"; process.env.TYPESTRIP_ERASE_WASM ??= "build/erase.wasm"; const root = new URL("../..", import.meta.url).pathname.replace(/\/$/, ""); const { transformSync } = await import(root + "/src/index.js"); const dir = process.argv[2]; const maxSmall = Number(process.argv[3] ?? 1024); const [shard, shards] = (process.argv[4] ?? "0/1").split("/").map(Number); function* walk(d) { let entries; try { entries = fs.readdirSync(d, { withFileTypes: true }); } catch { return; } for (const e of entries) { if (e.name.startsWith(".")) continue; const full = path.join(d, e.name); if (e.isDirectory()) yield* walk(full); else if (/\.[cm]?ts$/.test(e.name)) yield full; } } function* parts(src, n) { for (let i = 0; i < src.length; i += n) yield src.slice(i, i + n); } function streamed(src, n) { const errs = []; let out = ""; for (const piece of transformSync(parts(src, n), { onError: (e) => errs.push(e.start) })) out += piece; return { out, errs: errs.join() }; } const seen = new Set(); let files = 0, bad = 0, index = 0; const t0 = performance.now(); for (const f of walk(dir)) { let src; try { src = fs.readFileSync(f, "utf8"); } catch { continue; } if (seen.has(src)) continue; seen.add(src); if (index++ % shards !== shard) continue; const we = []; let whole; try { whole = transformSync(src, { onError: (e) => we.push(e.start) }); } catch { continue; } files++; const sizes = src.length <= maxSmall ? [1, 2, 7, 61, 509, 4093] : [7, 61, 509, 4093]; for (const n of sizes) { let r; try { r = streamed(src, n); } catch (e) { console.log(`THREW chunk ${n}: ${f}`); bad++; break; } if (r.out !== whole || r.errs !== we.join()) { let j = 0; while (r.out[j] === whole[j]) j++; console.log(`DIFF chunk ${n}: ${f} at ${j}${r.out === whole ? " (errors only)" : ""}`); bad++; break; } } } console.log(`${files} files, ${bad} streaming divergences in ${((performance.now() - t0) / 1000).toFixed(0)}s`);