muse/esp32-eink-display

A 55×46 mm two-layer ESP32-S3 e-paper controller board with USB‑C power/programming, buck regulation, FPC display connector, UC8179-style boost/charge-pump circuitry, ESD protection, controls, and routed passive components.

Version
1.3.4
License
unset
Stars
0

scripts/verify-webgpu.mjs

// Exercises the exact compiler embedded in the exported worker, without a DOM/GPU.
import assert from "node:assert/strict";
import {readFileSync, writeFileSync} from "node:fs";
import vm from "node:vm";
import {findWorker} from "./webgpu-bundle-utils.mjs";
const root = new URL("../", import.meta.url);
const patch = JSON.parse(readFileSync(new URL("renderer-fix/bundle-patch.json", root)));
const bundle = readFileSync(new URL("dist/standalone.min.js", root), "utf8");
const worker = findWorker(bundle).text;
assert(worker.includes(patch.branch), "Exported site is missing the WebGPU compatibility fix");
function loadCompiler(text) {
  assert(text.trimEnd().endsWith("})();"), "Unexpected worker wrapper");
  const context = vm.createContext({self: {}, setTimeout});
  vm.runInContext(text.trimEnd().slice(0, -5) + `globalThis.compile = ${patch.compileFunction};})();`, context, {timeout: 5000});
  return context.compile;
}
const compile = loadCompiler(worker);
const before = loadCompiler(worker.replace(patch.branch, ""));
const circuit = JSON.parse(readFileSync(new URL("dist/index/circuit.json", root)));
const oldScene = before(circuit);
const unsupportedSlots = circuit.filter(e => e.type === "pcb_plated_hole" && e.shape === "rotated_pill_hole_with_rect_pad").length;
assert.equal(oldScene.diagnostics.length, unsupportedSlots, "Unexpected baseline compiler diagnostics");
assert(oldScene.diagnostics.every((d) => d.message.includes("rotated_pill_hole_with_rect_pad")));
const scene = compile(circuit);
assert.equal(scene.diagnostics.length, 0, JSON.stringify(scene.diagnostics));
assert(scene.triangleCount > 0);
for (const layer of scene.layers)
  for (const mesh of [layer.paint, layer.erase]) {
    assert([...mesh.vertices].every(Number.isFinite));
    assert([...mesh.indices].every((i) => i < mesh.vertices.length / 8));
  }
const unaffected = circuit.filter((e) => e.shape !== "rotated_pill_hole_with_rect_pad");
const a = compile(unaffected), b = before(unaffected);
assert.equal(a.triangleCount, b.triangleCount);
assert.equal(a.layers.length, b.layers.length);
for (const [i, layer] of a.layers.entries()) {
  assert.equal(layer.name, b.layers[i].name);
  for (const kind of ["paint", "erase"]) {
    assert.deepEqual([...layer[kind].vertices], [...b.layers[i][kind].vertices]);
    assert.deepEqual([...layer[kind].indices], [...b.layers[i][kind].indices]);
  }
}
function bounds(mesh) {
  const xs = [], ys = [];
  for (let i = 0; i < mesh.vertices.length; i += 8) {xs.push(mesh.vertices[i]); ys.push(mesh.vertices[i + 1]);}
  return [Math.min(...xs), Math.max(...xs), Math.min(...ys), Math.max(...ys)];
}
for (const holeShape of [undefined, "rotated_pill"]) {
  const fixture = [{
    type: "pcb_plated_hole", pcb_plated_hole_id: "slot", x: 10, y: 20,
    shape: "rotated_pill_hole_with_rect_pad", hole_shape: holeShape,
    rect_pad_width: 8, rect_pad_height: 6, rect_ccw_rotation: 90,
    hole_width: 4, hole_height: 2, hole_ccw_rotation: 0,
    hole_offset_x: 0.5, hole_offset_y: -0.25, layers: ["top", "bottom"],
  }];
  const baseline = before(fixture);
  assert.equal(baseline.diagnostics.length, 1, "Slot regression must fail without the compatibility fix");
  assert(baseline.diagnostics[0].message.includes("rotated_pill_hole_with_rect_pad"));
  const slot = compile(fixture);
  assert.equal(slot.diagnostics.length, 0);
  const layer = slot.layers.find((l) => l.name === "top");
  assert.deepEqual(bounds(layer.paint), [7, 13, 16, 24]);
  bounds(layer.erase).forEach((v, i) => assert(Math.abs(v - [8.5, 12.5, 18.75, 20.75][i]) < 0.005));
}
const report = {
  package: "@tscircuit/circuit-json-webgpu", runframeVersion: patch.runframeVersion,
  originalUnsupportedShapes: oldScene.diagnostics.length, unsupportedShapes: scene.diagnostics.length,
  triangleCount: scene.triangleCount, layerCount: scene.layers.length,
  slotRegressionFixtures: 2, unchangedOtherGeometry: true, independentRotationsAndOffsets: true,
};
writeFileSync(new URL("dist/webgpu-validation.json", root), JSON.stringify(report, null, 2) + "\n");
console.log(JSON.stringify(report, null, 2));