You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: restore Reporter.withoutCache() — removing it was breaking
3.1.0 (e05416f) shipped Reporter.withoutCache() as the per-diagnostic
opt-out for findings whose correctness depends on inputs the cache
doesn't track. Dropping it in 47f5410 silently broke any rule that
relied on it — the call site would hit a TypeError at runtime, or
fail to type-check if written in TS.
Restore the API with semantics that match the original:
- Diagnostic is still returned for the current run.
- cache-flow filters it out before serialising the rule entry to
disk, so the next warm hit on this file won't replay it (rule has
to re-run to surface it again).
Marker is a Symbol.for('@tsslint/no-cache') stamped on the diagnostic
in core. Symbol-keyed → invisible to JSON.stringify and to
{...spread}, so it doesn't leak into the on-disk cache. Test 17
covers that explicitly.
README's "Caching" section is rewritten to describe the new two-layer
model and explain when withoutCache() still makes sense (external
inputs / fs-driven side reads); for cross-file types, the recommended
path is to read ctx.program once so layer 2 handles invalidation.
Tests:
- cache-flow.test #15: marked diagnostic returned but not persisted
- cache-flow.test #16: warm replay drops the marked one
- cache-flow.test #17: marker doesn't leak through serialisation
Copy file name to clipboardExpand all lines: README.md
+8-3Lines changed: 8 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -163,11 +163,16 @@ defineConfig({
163
163
164
164
### Caching
165
165
166
-
Diagnostics are cached on disk under `os.tmpdir()/tsslint-cache/`, keyed by file mtime. The cache is shared across rules and survives between editor sessions.
166
+
Diagnostics are cached on disk under `os.tmpdir()/tsslint-cache/` in two layers, picked per rule:
167
167
168
-
A diagnostic whose correctness depends on more than one file's mtime (e.g. anything that reads `ctx.program` for cross-file resolution and reports on the cached side) should opt out per-diagnostic via `.withoutCache()` on the reporter — the cached entry would otherwise go stale when an unrelated dependency file changes without invalidating its consumers' mtime.
168
+
-**Layer 1** — invalidated by the linted file's mtime. Used for rules that don't read `ctx.program` (purely syntactic).
169
+
-**Layer 2** — invalidated by TypeScript's `BuilderProgram` affected-file diff (transitive, includes ambient `.d.ts`). Used for rules that touch `ctx.program`. The first time a rule reads `ctx.program` it's classified type-aware and stays type-aware across sessions.
169
170
170
-
Pass `--force` to the CLI to ignore the cache.
171
+
A diagnostic whose correctness depends on inputs neither layer tracks — external resources, env vars, sibling files the rule reads directly via `fs` — should opt out per-diagnostic via `.withoutCache()` on the reporter. The diagnostic still surfaces on the current run; it just isn't written to disk, so the next warm hit on this file won't replay it (the rule has to re-run to surface it again).
172
+
173
+
For diagnostics that depend on cross-file types, prefer reading `ctx.program` once instead — that re-classifies the rule type-aware and layer 2 handles invalidation properly.
174
+
175
+
Pass `--force` to the CLI to ignore the cache. `--list-rules` prints each rule's classification (type-aware vs syntactic) after the run.
0 commit comments