Release review fixes for 0.9.0 - #58
Conversation
- The closure is part of the transform and report keys with Glint off too: the resolver reads an imported component's template to substitute its tag. - A `.ts`/`.js` module's co-located `.hbs` template (next to it or under `templates/components/`) and `/// <reference path>` targets are part of the closure. Without a tsconfig, relative imports still resolve. - The lockfile is found at or above the tsconfig directory (workspace root). A nested directory with its own package.json is not walked for project-wide inputs. - The tsconfig sha covers the whole `extends` chain and is re-validated against the file system; `backendKindFor` makes the same decision as `selectBackend` (a TypeScript 7 package that does not load falls back to ts6 in both). - A result computed after a Glint extraction threw is not cached at any level; the next run retries. - Long-lived hosts: the project-wide input list re-validates on the mtimes of the directories walked; an `index` probe watches the directory it lives in; trailing commas are removed outside strings only; file records keep import lists, not content. - The CLI computes report keys before the Glint preload and preloads the misses only; `dependencySha` is memoised per content under a static file system. `--help` names all three caches. Cowritten by Claude
🏎️ Benchmark Comparison
Full output |
There was a problem hiding this comment.
🔵 Needs a closer look
The changes rewrite cross-file cache-invalidation logic that affects correctness for all consumers, and include a confirmed JSONC parsing regression, so a human should review before approval.
Pull request overview
This PR bundles correctness and performance fixes ahead of the 0.9.0 release, focused on the on-disk cache keys (Glint/transform/report) so that stale-cache paths introduced since v0.8.0 are closed. It makes the import closure part of the cache key even with Glint off, tightens dependency tracking (tsconfig extends chain, lockfile discovery, co-located/classic .hbs peers, /// <reference path> targets), and reorders the CLI so report keys are computed before the Glint preload (preloading only cache misses).
Changes:
lib/deps.ts: broadened dependency scanning/resolution (reference-path directives,.hbspeers, no-tsconfig relative resolution, workspace lockfile lookup), addedtsconfigChainSha, reworked JSONC comma handling, and revised memoization/re-validation.run.ts+transform.ts: precompute report keys, preload only misses, and track files whose Glint extraction threw (__glintUnavailable) so their results are not cached.lib/cache.ts+lib/backend/index.ts: tsconfig sha now covers the wholeextendschain;backendKindForusesloadTsgoto matchselectBackend's decision; cache-key dependency short-circuits only when caching is disabled.
File summaries
| File | Description |
|---|---|
| lib/deps.ts | Core dependency-closure/resolution rewrite: reference-path scanning, .hbs peers, tsconfig chain sha, lockfile discovery, JSONC comma handling, memo re-validation. |
| lib/cache.ts | getTsconfigSha delegates to tsconfigChainSha; key dependency computed unless cache disabled. |
| lib/backend/index.ts | backendKindFor loads tsgo (matching selectBackend) instead of only resolving the package. |
| transform.ts | Adds __glintUnavailable tracking to avoid caching results after a Glint extraction throws. |
| run.ts | Precomputes report keys, preloads only Glint misses, guards report writes on __glintUnavailable. |
| test/deps.test.ts | New tests for peers, reference paths, workspace lockfile, no-tsconfig resolution, chain sha. |
| test/cache.test.ts | Adds assertion that editing the tsconfig changes the report key. |
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 2
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ndows separators Copilot review on #58: the string-safe JSONC scanner only skipped whitespace when looking for the closing bracket, so `{ "a": 1, // note\n }` kept the comma and JSON.parse failed after comment removal. The templates/components peer regex was POSIX-only, dropping the classic-layout peer from the closure on Windows.
The cache-key component loaded typescript-7's sync and ast modules (~30 ms) on every process, including replays that never need a backend. Whether the package loads is decided by its version and the Node version, so both are in the key and the package is only resolved.
Fixes from a review of everything since v0.8.0 (#51, #52, #54–#57), before the 0.9.0 release. Correctness for consumers first.
Stale-cache paths closed
--no-glintstill reads imported component templates (tag substitution), so the import closure is now part of the transform and report keys with Glint off too..ts/.jsmodule's co-located.hbstemplate and/// <reference path>targets are part of the closure. Without a tsconfig, relative imports resolve.extendschain (paths,baseUrl,typesin a base config) and is re-validated against the file system.backendKindFor(transform/report keys) makes the same decision asselectBackend: a TypeScript 7 package that resolves but does not load falls back to ts6 in both..d.tsor augmentation is seen); anindexprobe watches the directory it lives in; trailing commas are removed outside strings only.Performance
dependencyShais memoised per file content under a static file system; file records keep import lists, not content; a nested package directory is not walked.backendKindForloads the TypeScript 7 module so that the key matches the backend that ran.Release notes for 0.9.0 (behaviour a 0.8.0 user notices)
node_modules/.cache/html-validate-ember/: Glint extraction (glint/), transform output (transform/), and forvalidate-gtsthe report of each file (report/).HVE_NO_CACHE=1bypasses all three..d.tsfiles and module augmentations, the lockfile, the tsconfig chain, the html-validate configuration and version, and the plugin. Editing an imported component invalidates its consumers. A.hbstemplate is keyed on everything the registry reaches.validate-gtsreplays the stored report; stderr diagnostics from the transform (parse failures) are printed on the run that computed them, not on replays..htmlvalidate.jsonis part of the key by content; files it references by path (elements,extendspresets) are not.validate-gtsrun went from 10.8 s to under 1 s.Both lanes 326 passed + 1 expected fail;
typecheck:testsclean.Cowritten by Claude