/** * Live render check. Not a unit test — this draws to your real terminal. * * node --experimental-strip-types test/render-demo.ts * * Pass: a red rectangle appears, then the text below it redraws 20 times * without the image blinking or the screen clearing. */ import { resolveCellSize } from "../src/cell-size.ts"; import { imageDimensions } from "../src/dimensions.ts"; import { deleteVirtual, fitToGrid, placeholderRows, transmitVirtual } from "../src/placeholder.ts"; import { allocateImageId } from "../src/placeholder.ts"; import { deflateSync } from "node:zlib"; function png(w: number, h: number, rgb: [number, number, number]): Buffer { const crcTable = Array.from({ length: 256 }, (_, n) => { let c = n; for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; return c >>> 0; }); const crc32 = (buf: Buffer) => { let c = 0xffffffff; for (const byte of buf) c = crcTable[(c ^ byte) & 0xff]! ^ (c >>> 8); return (c ^ 0xffffffff) >>> 0; }; const chunk = (type: string, data: Buffer) => { const body = Buffer.concat([Buffer.from(type, "ascii"), data]); const len = Buffer.alloc(4); len.writeUInt32BE(data.length); const crc = Buffer.alloc(4); crc.writeUInt32BE(crc32(body)); return Buffer.concat([len, body, crc]); }; const ihdr = Buffer.alloc(13); ihdr.writeUInt32BE(w, 0); ihdr.writeUInt32BE(h, 4); ihdr[8] = 8; ihdr[9] = 2; const row = Buffer.concat([Buffer.from([0]), Buffer.from(Array(w).fill(rgb).flat())]); const raw = Buffer.concat(Array(h).fill(row)); return Buffer.concat([ Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]), chunk("IHDR", ihdr), chunk("IDAT", deflateSync(raw)), chunk("IEND", Buffer.alloc(0)), ]); } const bytes = png(240, 160, [220, 60, 60]); const cell = await resolveCellSize(); const dims = imageDimensions(bytes); const grid = fitToGrid(dims.widthPx, dims.heightPx, cell, 30, 15); const id = allocateImageId(); console.log(`cell=${cell.widthPx}x${cell.heightPx}px image=${dims.widthPx}x${dims.heightPx}px grid=${grid.cols}x${grid.rows} cells id=${id}`); console.log(""); process.stdout.write(transmitVirtual(bytes.toString("base64"), id, grid)); for (const row of placeholderRows(id, grid)) console.log(row); // Redraw the line under the image repeatedly. The image must not flicker, // because nothing about it is retransmitted or cleared. let n = 0; const timer = setInterval(() => { n++; process.stdout.write(`\rredraw ${n}/20 — image should be rock steady `); if (n >= 20) { clearInterval(timer); console.log("\n\nPass if the red block never blinked."); console.log("Press enter to free the image."); process.stdin.once("data", () => { process.stdout.write(deleteVirtual(id)); process.exit(0); }); process.stdin.resume(); } }, 100);