Extract testable type core, add JS tests, decompose hot spots
Tests for the unification/matching core (review item #1):
- Move the pure TypeArg unification/matching functions out of viewer.js
into data/typecore.js, a DOM-free module exposing the data-free helpers
directly and the data-dependent ones (reduceTypeArg, substTypeArg,
findMatchingInstances) via makeTypeCore(env). viewer.js binds them to the
program's family index + instance list and destructures the names it uses.
- data/typecore.js is embedded into the page (Render.hs + viewer.html) as a
<script> before viewer.js, and required directly by the Node test-suite.
- test/typecore.test.js: 19 fixtures covering one-sided instance matching
incl. multi-param projection, closed/open family reduction, and the
data-family / chain rewrite (replaceFamilyApp).
- test/views.test.js + test/harness.js: a stub DOM/Cytoscape harness loads
viewer.js headlessly and exercises buildInstanceView (satisfied vs
external superclass edges). test/snapshot-views.js dumps every builder's
output for before/after refactor diffs.
- package.json: `npm test` → `node --test test/*.test.js` (22 tests, no deps).
Decomposition (review item #2):
- Extract.hs: split typeArg into typeArg / tyConArg / dataFamilyRepArg.
Verified behaviour-preserving — demo dumps are byte-identical.
- viewer.js: lift the three per-instance phases (context, associated
families, superclass requirements) out of buildInstanceView's row loop
into named inner helpers. Verified byte-identical view output across all
23 demo views via the snapshot harness.
Warning (review item #3):
- Render.hs: rename the `head` binding in familyNodeLabel that shadowed
Prelude.head (clears the -Wname-shadowing warning).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>