@drskillissue/ganko 0.2.6 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-FTIRRRQY.js → chunk-WY5MMHK2.js} +195 -82
- package/dist/chunk-WY5MMHK2.js.map +1 -0
- package/dist/eslint-plugin.cjs +189 -81
- package/dist/eslint-plugin.cjs.map +1 -1
- package/dist/eslint-plugin.js +1 -1
- package/dist/index.cjs +214 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.js +23 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
- package/dist/chunk-FTIRRRQY.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -215,6 +215,13 @@ declare class TypeResolver {
|
|
|
215
215
|
* Detects Array<T>, T[], ReadonlyArray<T>, and tuple types.
|
|
216
216
|
*/
|
|
217
217
|
isArrayType(node: ts.Node): boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Strict array check: only matches Array<T>, T[], ReadonlyArray<T>, and tuples.
|
|
220
|
+
* Does NOT match typed arrays (Uint8Array, Buffer, etc.) or other types with
|
|
221
|
+
* a numeric index signature.
|
|
222
|
+
*/
|
|
223
|
+
isStrictArrayType(node: ts.Node): boolean;
|
|
224
|
+
private checkIsStrictArrayType;
|
|
218
225
|
private checkIsArrayType;
|
|
219
226
|
/**
|
|
220
227
|
* Check if a node's type is callable (has call signatures).
|
|
@@ -2843,6 +2850,14 @@ interface LayoutGraphTopology {
|
|
|
2843
2850
|
readonly elementRefsBySolidFileAndId: ReadonlyMap<string, ReadonlyMap<number, LayoutElementRef>>;
|
|
2844
2851
|
readonly elementsByTagName: ReadonlyMap<string, readonly LayoutElementNode[]>;
|
|
2845
2852
|
readonly measurementNodeByRootKey: ReadonlyMap<string, LayoutElementNode>;
|
|
2853
|
+
/**
|
|
2854
|
+
* Maps component call-site nodes to their resolved host DOM element reference.
|
|
2855
|
+
* Only populated for nodes that represent a component resolved to a concrete DOM
|
|
2856
|
+
* element. Native DOM element nodes and unresolvable components are absent.
|
|
2857
|
+
* Used by rules that need to inspect the host element's JSX attributes (e.g.
|
|
2858
|
+
* dynamic `width`/`height` expressions not capturable as static strings).
|
|
2859
|
+
*/
|
|
2860
|
+
readonly hostElementRefsByNode: ReadonlyMap<LayoutElementNode, LayoutElementRef>;
|
|
2846
2861
|
}
|
|
2847
2862
|
interface LayoutGraphCascade {
|
|
2848
2863
|
readonly styleRules: readonly LayoutStyleRuleNode[];
|
|
@@ -3131,8 +3146,8 @@ declare function scanDependencyCustomProperties(projectRoot: string): ReadonlySe
|
|
|
3131
3146
|
* W3C Low Vision Needs.
|
|
3132
3147
|
*/
|
|
3133
3148
|
|
|
3134
|
-
/** Set the active policy for all policy rules. */
|
|
3135
|
-
declare function setActivePolicy(name: string): void;
|
|
3149
|
+
/** Set the active policy for all policy rules. Pass null to disable. */
|
|
3150
|
+
declare function setActivePolicy(name: string | null): void;
|
|
3136
3151
|
|
|
3137
3152
|
declare function buildLayoutGraph(solids: readonly SolidGraph[], css: CSSGraph, logger?: Logger): LayoutGraph;
|
|
3138
3153
|
|
package/dist/index.d.ts
CHANGED
|
@@ -215,6 +215,13 @@ declare class TypeResolver {
|
|
|
215
215
|
* Detects Array<T>, T[], ReadonlyArray<T>, and tuple types.
|
|
216
216
|
*/
|
|
217
217
|
isArrayType(node: ts.Node): boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Strict array check: only matches Array<T>, T[], ReadonlyArray<T>, and tuples.
|
|
220
|
+
* Does NOT match typed arrays (Uint8Array, Buffer, etc.) or other types with
|
|
221
|
+
* a numeric index signature.
|
|
222
|
+
*/
|
|
223
|
+
isStrictArrayType(node: ts.Node): boolean;
|
|
224
|
+
private checkIsStrictArrayType;
|
|
218
225
|
private checkIsArrayType;
|
|
219
226
|
/**
|
|
220
227
|
* Check if a node's type is callable (has call signatures).
|
|
@@ -2843,6 +2850,14 @@ interface LayoutGraphTopology {
|
|
|
2843
2850
|
readonly elementRefsBySolidFileAndId: ReadonlyMap<string, ReadonlyMap<number, LayoutElementRef>>;
|
|
2844
2851
|
readonly elementsByTagName: ReadonlyMap<string, readonly LayoutElementNode[]>;
|
|
2845
2852
|
readonly measurementNodeByRootKey: ReadonlyMap<string, LayoutElementNode>;
|
|
2853
|
+
/**
|
|
2854
|
+
* Maps component call-site nodes to their resolved host DOM element reference.
|
|
2855
|
+
* Only populated for nodes that represent a component resolved to a concrete DOM
|
|
2856
|
+
* element. Native DOM element nodes and unresolvable components are absent.
|
|
2857
|
+
* Used by rules that need to inspect the host element's JSX attributes (e.g.
|
|
2858
|
+
* dynamic `width`/`height` expressions not capturable as static strings).
|
|
2859
|
+
*/
|
|
2860
|
+
readonly hostElementRefsByNode: ReadonlyMap<LayoutElementNode, LayoutElementRef>;
|
|
2846
2861
|
}
|
|
2847
2862
|
interface LayoutGraphCascade {
|
|
2848
2863
|
readonly styleRules: readonly LayoutStyleRuleNode[];
|
|
@@ -3131,8 +3146,8 @@ declare function scanDependencyCustomProperties(projectRoot: string): ReadonlySe
|
|
|
3131
3146
|
* W3C Low Vision Needs.
|
|
3132
3147
|
*/
|
|
3133
3148
|
|
|
3134
|
-
/** Set the active policy for all policy rules. */
|
|
3135
|
-
declare function setActivePolicy(name: string): void;
|
|
3149
|
+
/** Set the active policy for all policy rules. Pass null to disable. */
|
|
3150
|
+
declare function setActivePolicy(name: string | null): void;
|
|
3136
3151
|
|
|
3137
3152
|
declare function buildLayoutGraph(solids: readonly SolidGraph[], css: CSSGraph, logger?: Logger): LayoutGraph;
|
|
3138
3153
|
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-5OEDGKHL.js";
|
|
6
6
|
import {
|
|
7
7
|
CSSPlugin,
|
|
8
|
+
Level,
|
|
8
9
|
SolidPlugin,
|
|
9
10
|
analyzeInput,
|
|
10
11
|
buildCSSGraph,
|
|
@@ -19,7 +20,7 @@ import {
|
|
|
19
20
|
runSolidRules,
|
|
20
21
|
scanDependencyCustomProperties,
|
|
21
22
|
setActivePolicy
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-WY5MMHK2.js";
|
|
23
24
|
import "./chunk-EGRHWZRV.js";
|
|
24
25
|
|
|
25
26
|
// src/runner.ts
|
|
@@ -87,7 +88,7 @@ var GraphCache = class {
|
|
|
87
88
|
const key = canonicalPath(path);
|
|
88
89
|
const cached = this.solids.get(key);
|
|
89
90
|
const hit = cached !== void 0 && cached.version === version;
|
|
90
|
-
if (this.log.
|
|
91
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`hasSolidGraph: ${key} v=${version} cached=${cached?.version ?? "none"} hit=${hit} (${this.solids.size} total)`);
|
|
91
92
|
return hit;
|
|
92
93
|
}
|
|
93
94
|
/**
|
|
@@ -104,7 +105,7 @@ var GraphCache = class {
|
|
|
104
105
|
const key = canonicalPath(path);
|
|
105
106
|
this.solids.set(key, { version, graph });
|
|
106
107
|
this.solidGeneration++;
|
|
107
|
-
if (this.log.
|
|
108
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`setSolidGraph: ${key} v=${version} (${this.solids.size} total) solidGen=${this.solidGeneration}`);
|
|
108
109
|
}
|
|
109
110
|
/**
|
|
110
111
|
* Get a cached SolidGraph without building on miss.
|
|
@@ -120,10 +121,10 @@ var GraphCache = class {
|
|
|
120
121
|
const key = canonicalPath(path);
|
|
121
122
|
const cached = this.solids.get(key);
|
|
122
123
|
if (cached !== void 0 && cached.version === version) {
|
|
123
|
-
if (this.log.
|
|
124
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCachedSolidGraph HIT: ${key} v=${version}`);
|
|
124
125
|
return cached.graph;
|
|
125
126
|
}
|
|
126
|
-
if (this.log.
|
|
127
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCachedSolidGraph MISS: ${key} v=${version}`);
|
|
127
128
|
return null;
|
|
128
129
|
}
|
|
129
130
|
/**
|
|
@@ -140,15 +141,15 @@ var GraphCache = class {
|
|
|
140
141
|
const key = canonicalPath(path);
|
|
141
142
|
const cached = this.solids.get(key);
|
|
142
143
|
if (cached !== void 0 && cached.version === version) {
|
|
143
|
-
if (this.log.
|
|
144
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getSolidGraph HIT: ${key} v=${version}`);
|
|
144
145
|
return cached.graph;
|
|
145
146
|
}
|
|
146
|
-
if (this.log.
|
|
147
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getSolidGraph MISS: ${key} v=${version} (was ${cached?.version ?? "uncached"})`);
|
|
147
148
|
const t0 = performance.now();
|
|
148
149
|
const graph = build();
|
|
149
150
|
this.solids.set(key, { version, graph });
|
|
150
151
|
this.solidGeneration++;
|
|
151
|
-
if (this.log.
|
|
152
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getSolidGraph BUILT: ${key} v=${version} in ${performance.now() - t0}ms (${this.solids.size} total) solidGen=${this.solidGeneration}`);
|
|
152
153
|
return graph;
|
|
153
154
|
}
|
|
154
155
|
/**
|
|
@@ -162,14 +163,14 @@ var GraphCache = class {
|
|
|
162
163
|
*/
|
|
163
164
|
getCSSGraph(build) {
|
|
164
165
|
if (this.css !== null && this.css.generation === this.cssGeneration) {
|
|
165
|
-
if (this.log.
|
|
166
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCSSGraph HIT: gen=${this.cssGeneration}`);
|
|
166
167
|
return this.css.graph;
|
|
167
168
|
}
|
|
168
|
-
if (this.log.
|
|
169
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCSSGraph MISS: currentGen=${this.cssGeneration} cachedGen=${this.css?.generation ?? "none"}`);
|
|
169
170
|
const t0 = performance.now();
|
|
170
171
|
const graph = build();
|
|
171
172
|
this.css = { generation: this.cssGeneration, graph };
|
|
172
|
-
if (this.log.
|
|
173
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCSSGraph BUILT: gen=${this.cssGeneration} in ${performance.now() - t0}ms`);
|
|
173
174
|
return graph;
|
|
174
175
|
}
|
|
175
176
|
/**
|
|
@@ -184,10 +185,10 @@ var GraphCache = class {
|
|
|
184
185
|
const solidGen = this.solidGeneration;
|
|
185
186
|
const cssGen = this.cssGeneration;
|
|
186
187
|
if (this.layout !== null && this.layout.solidGeneration === solidGen && this.layout.cssGeneration === cssGen) {
|
|
187
|
-
if (this.log.
|
|
188
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getLayoutGraph HIT: solidGen=${solidGen} cssGen=${cssGen}`);
|
|
188
189
|
return this.layout.graph;
|
|
189
190
|
}
|
|
190
|
-
if (this.log.
|
|
191
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(
|
|
191
192
|
`getLayoutGraph MISS: solidGen=${solidGen} cssGen=${cssGen} cached=${this.layout !== null}`
|
|
192
193
|
);
|
|
193
194
|
const t0 = performance.now();
|
|
@@ -197,7 +198,7 @@ var GraphCache = class {
|
|
|
197
198
|
cssGeneration: cssGen,
|
|
198
199
|
graph
|
|
199
200
|
};
|
|
200
|
-
if (this.log.
|
|
201
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getLayoutGraph BUILT: in ${performance.now() - t0}ms`);
|
|
201
202
|
return graph;
|
|
202
203
|
}
|
|
203
204
|
/**
|
|
@@ -212,7 +213,7 @@ var GraphCache = class {
|
|
|
212
213
|
invalidate(path) {
|
|
213
214
|
const key = canonicalPath(path);
|
|
214
215
|
const kind = classifyFile(key);
|
|
215
|
-
if (this.log.
|
|
216
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`invalidate: ${key} kind=${kind} solids=${this.solids.size} hasCrossFileResults=${this.crossFileResults !== null} hasLayout=${this.layout !== null}`);
|
|
216
217
|
if (kind === "solid") {
|
|
217
218
|
const had = this.solids.has(key);
|
|
218
219
|
this.solids.delete(key);
|
|
@@ -220,7 +221,7 @@ var GraphCache = class {
|
|
|
220
221
|
this.crossFileResults = null;
|
|
221
222
|
this.solidGeneration++;
|
|
222
223
|
this.layout = null;
|
|
223
|
-
if (this.log.
|
|
224
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`invalidate SOLID: ${key} wasInCache=${had} solids=${this.solids.size} solidGen=${this.solidGeneration}`);
|
|
224
225
|
}
|
|
225
226
|
if (kind === "css") {
|
|
226
227
|
this.crossFileDiagnostics.delete(key);
|
|
@@ -228,7 +229,7 @@ var GraphCache = class {
|
|
|
228
229
|
this.cssGeneration++;
|
|
229
230
|
this.css = null;
|
|
230
231
|
this.layout = null;
|
|
231
|
-
if (this.log.
|
|
232
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`invalidate CSS: ${key} newCssGen=${this.cssGeneration}`);
|
|
232
233
|
}
|
|
233
234
|
}
|
|
234
235
|
/**
|
|
@@ -237,7 +238,7 @@ var GraphCache = class {
|
|
|
237
238
|
* Called on workspace-level events like config changes.
|
|
238
239
|
*/
|
|
239
240
|
invalidateAll() {
|
|
240
|
-
if (this.log.
|
|
241
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`invalidateAll: solids=${this.solids.size} solidGen=${this.solidGeneration} cssGen=${this.cssGeneration}`);
|
|
241
242
|
this.solids.clear();
|
|
242
243
|
this.crossFileDiagnostics.clear();
|
|
243
244
|
this.crossFileResults = null;
|
|
@@ -253,7 +254,7 @@ var GraphCache = class {
|
|
|
253
254
|
* Used by cross-file analysis which needs all SolidGraphs.
|
|
254
255
|
*/
|
|
255
256
|
getAllSolidGraphs() {
|
|
256
|
-
if (this.log.
|
|
257
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getAllSolidGraphs: ${this.solids.size} graphs`);
|
|
257
258
|
const out = new Array(this.solids.size);
|
|
258
259
|
let i = 0;
|
|
259
260
|
for (const entry of this.solids.values()) {
|
|
@@ -309,10 +310,10 @@ var GraphCache = class {
|
|
|
309
310
|
const solidMatch = this.crossFileResults.solidGeneration === this.solidGeneration;
|
|
310
311
|
const cssMatch = this.crossFileResults.cssGeneration === this.cssGeneration;
|
|
311
312
|
if (solidMatch && cssMatch) {
|
|
312
|
-
if (this.log.
|
|
313
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCachedCrossFileResults HIT: ${this.crossFileResults?.byFile.size} files`);
|
|
313
314
|
return this.crossFileResults.byFile;
|
|
314
315
|
}
|
|
315
|
-
if (this.log.
|
|
316
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(
|
|
316
317
|
`getCachedCrossFileResults MISS: solidMatch=${solidMatch} cssMatch=${cssMatch} cachedSolidGen=${this.crossFileResults?.solidGeneration} currentSolidGen=${this.solidGeneration} cachedCssGen=${this.crossFileResults?.cssGeneration} currentCssGen=${this.cssGeneration}`
|
|
317
318
|
);
|
|
318
319
|
return null;
|
|
@@ -343,7 +344,7 @@ var GraphCache = class {
|
|
|
343
344
|
cssGeneration: this.cssGeneration,
|
|
344
345
|
byFile
|
|
345
346
|
};
|
|
346
|
-
if (this.log.
|
|
347
|
+
if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(
|
|
347
348
|
`setCachedCrossFileResults: ${allDiagnostics.length} diags across ${byFile.size} files solidGen=${this.solidGeneration} cssGen=${this.cssGeneration}`
|
|
348
349
|
);
|
|
349
350
|
this.crossFileDiagnostics.clear();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runner.ts","../src/cache.ts"],"sourcesContent":["/**\n * Runner - Plugin-agnostic runner for ganko\n *\n * The runner takes a configuration with plugins and runs them against files.\n * It never stores typed graphs - plugins handle their own graph building\n * and rule execution internally via the analyze() method.\n *\n * Rule overrides allow callers (LSP, CLI) to disable rules or remap their\n * severity without modifying rule definitions. The runner intercepts the\n * Emit callback to enforce overrides before diagnostics reach the caller.\n */\nimport type ts from \"typescript\"\nimport type { Diagnostic } from \"./diagnostic\"\nimport type { Plugin, Emit } from \"./graph\"\nimport type { RuleOverrides } from \"@drskillissue/ganko-shared\"\n\n/** Runner configuration */\nexport interface RunnerConfig {\n readonly plugins: readonly Plugin<string>[]\n readonly rules?: RuleOverrides\n readonly program?: ts.Program\n}\n\n/** Runner interface */\nexport interface Runner {\n run(files: readonly string[]): readonly Diagnostic[]\n /** Replace rule overrides. Takes effect on the next run() call. */\n setRuleOverrides(overrides: RuleOverrides): void\n /** Replace the TypeScript program. Takes effect on the next run() call. */\n setProgram(program: ts.Program): void\n}\n\n/**\n * Build an Emit wrapper that enforces rule overrides.\n *\n * @param target - The underlying emit that collects diagnostics\n * @param overrides - Current rule override map\n * @returns Wrapped emit that suppresses/remaps per overrides\n */\nexport function createOverrideEmit(target: Emit, overrides: RuleOverrides): Emit {\n return (d) => {\n const override = overrides[d.rule]\n if (override === undefined) { target(d); return }\n if (override === \"off\") return\n if (override !== d.severity) {\n target({ ...d, severity: override })\n return\n }\n target(d)\n }\n}\n\n/**\n * Create a runner from configuration.\n */\nexport function createRunner(config: RunnerConfig): Runner {\n let overrides: RuleOverrides = config.rules ?? {}\n let program: ts.Program | undefined = config.program\n\n return {\n run(files) {\n const diagnostics: Diagnostic[] = []\n const raw: Emit = (d) => diagnostics.push(d)\n const hasOverrides = Object.keys(overrides).length > 0\n const emit = hasOverrides ? createOverrideEmit(raw, overrides) : raw\n const context = program ? { program } : undefined\n for (const plugin of config.plugins) {\n plugin.analyze(files, emit, context)\n }\n return diagnostics\n },\n\n setRuleOverrides(next) {\n overrides = next\n },\n\n setProgram(next) {\n program = next\n },\n }\n}\n","/**\n * GraphCache — Versioned cache for SolidGraph, CSSGraph, and LayoutGraph instances.\n *\n * Eliminates redundant graph construction in the LSP server by caching\n * per-file SolidGraphs (keyed by path + script version), a single\n * CSSGraph invalidated via a monotonic generation counter, and a\n * LayoutGraph invalidated by Solid/CSS signatures.\n *\n * The cache does not perform I/O or parsing — callers supply builder\n * functions that are invoked only on cache miss.\n */\nimport { canonicalPath, classifyFile, noopLogger } from \"@drskillissue/ganko-shared\"\nimport type { Logger } from \"@drskillissue/ganko-shared\"\nimport type { Diagnostic } from \"./diagnostic\"\nimport type { SolidGraph } from \"./solid/impl\"\nimport type { CSSGraph } from \"./css/impl\"\nimport type { LayoutGraph } from \"./cross-file/layout/graph\"\n\ninterface CachedSolid {\n readonly version: string\n readonly graph: SolidGraph\n}\n\ninterface CachedCSS {\n readonly generation: number\n readonly graph: CSSGraph\n}\n\ninterface CachedLayout {\n readonly solidGeneration: number\n readonly cssGeneration: number\n readonly graph: LayoutGraph\n}\n\ninterface CachedCrossFileResults {\n readonly solidGeneration: number\n readonly cssGeneration: number\n readonly byFile: ReadonlyMap<string, readonly Diagnostic[]>\n}\n\n/**\n * Versioned cache for SolidGraph, CSSGraph, and LayoutGraph instances.\n *\n * SolidGraphs are cached per file path with a version string.\n * The CSSGraph is a single instance covering all CSS files,\n * invalidated via a monotonic generation counter bumped by\n * `invalidate()` or `invalidateAll()`.\n */\nexport class GraphCache {\n private readonly log: Logger\n private readonly solids = new Map<string, CachedSolid>()\n private readonly crossFileDiagnostics = new Map<string, readonly Diagnostic[]>()\n private crossFileResults: CachedCrossFileResults | null = null\n private css: CachedCSS | null = null\n private solidGeneration = 0\n private cssGeneration = 0\n private layout: CachedLayout | null = null\n\n constructor(log?: Logger) {\n this.log = log ?? noopLogger\n }\n\n /**\n * Check if a SolidGraph is cached and current for a file path.\n *\n * Allows callers to skip builder allocation when the cache is warm.\n *\n * @param path Absolute file path\n * @param version Script version string from the TS project service\n */\n hasSolidGraph(path: string, version: string): boolean {\n const key = canonicalPath(path)\n const cached = this.solids.get(key)\n const hit = cached !== undefined && cached.version === version\n if (this.log.enabled) this.log.debug(`hasSolidGraph: ${key} v=${version} cached=${cached?.version ?? \"none\"} hit=${hit} (${this.solids.size} total)`)\n return hit\n }\n\n /**\n * Store a pre-built SolidGraph in the cache.\n *\n * Used by the CLI lint command which builds graphs during single-file\n * analysis and pre-populates the cache for cross-file reuse.\n *\n * @param path Absolute file path\n * @param version Script version string from the TS project service\n * @param graph Pre-built SolidGraph\n */\n setSolidGraph(path: string, version: string, graph: SolidGraph): void {\n const key = canonicalPath(path)\n this.solids.set(key, { version, graph })\n this.solidGeneration++\n if (this.log.enabled) this.log.debug(`setSolidGraph: ${key} v=${version} (${this.solids.size} total) solidGen=${this.solidGeneration}`)\n }\n\n /**\n * Get a cached SolidGraph without building on miss.\n *\n * Returns the cached graph if the version matches, null otherwise.\n * Use when the caller has already confirmed the entry exists via\n * `hasSolidGraph` and wants to avoid allocating a builder closure.\n *\n * @param path Absolute file path\n * @param version Script version string from the TS project service\n */\n getCachedSolidGraph(path: string, version: string): SolidGraph | null {\n const key = canonicalPath(path)\n const cached = this.solids.get(key)\n if (cached !== undefined && cached.version === version) {\n if (this.log.enabled) this.log.debug(`getCachedSolidGraph HIT: ${key} v=${version}`)\n return cached.graph\n }\n if (this.log.enabled) this.log.debug(`getCachedSolidGraph MISS: ${key} v=${version}`)\n return null\n }\n\n /**\n * Get or build a SolidGraph for a file path.\n *\n * Returns the cached graph if the version matches.\n * Otherwise invokes the builder, caches the result, and returns it.\n *\n * @param path Absolute file path\n * @param version Script version string from the TS project service\n * @param build Builder function invoked on cache miss\n */\n getSolidGraph(path: string, version: string, build: () => SolidGraph): SolidGraph {\n const key = canonicalPath(path)\n const cached = this.solids.get(key)\n if (cached !== undefined && cached.version === version) {\n if (this.log.enabled) this.log.debug(`getSolidGraph HIT: ${key} v=${version}`)\n return cached.graph\n }\n\n if (this.log.enabled) this.log.debug(`getSolidGraph MISS: ${key} v=${version} (was ${cached?.version ?? \"uncached\"})`)\n const t0 = performance.now()\n const graph = build()\n this.solids.set(key, { version, graph })\n this.solidGeneration++\n if (this.log.enabled) this.log.debug(`getSolidGraph BUILT: ${key} v=${version} in ${performance.now() - t0}ms (${this.solids.size} total) solidGen=${this.solidGeneration}`)\n return graph\n }\n\n /**\n * Get the cached CSSGraph, or rebuild it.\n *\n * Returns the cached graph if the generation matches the current\n * CSS generation counter. Otherwise invokes the builder, caches\n * the result at the current generation, and returns it.\n *\n * @param build Builder function invoked on cache miss\n */\n getCSSGraph(build: () => CSSGraph): CSSGraph {\n if (this.css !== null && this.css.generation === this.cssGeneration) {\n if (this.log.enabled) this.log.debug(`getCSSGraph HIT: gen=${this.cssGeneration}`)\n return this.css.graph\n }\n\n if (this.log.enabled) this.log.debug(`getCSSGraph MISS: currentGen=${this.cssGeneration} cachedGen=${this.css?.generation ?? \"none\"}`)\n const t0 = performance.now()\n const graph = build()\n this.css = { generation: this.cssGeneration, graph }\n if (this.log.enabled) this.log.debug(`getCSSGraph BUILT: gen=${this.cssGeneration} in ${performance.now() - t0}ms`)\n return graph\n }\n\n /**\n * Get or build a LayoutGraph for current Solid/CSS cache state.\n *\n * Returns cached LayoutGraph when both Solid signature (path+version)\n * and CSS generation match. Otherwise invokes the builder.\n *\n * @param build Builder function invoked on cache miss\n */\n getLayoutGraph(build: () => LayoutGraph): LayoutGraph {\n const solidGen = this.solidGeneration\n const cssGen = this.cssGeneration\n\n if (\n this.layout !== null\n && this.layout.solidGeneration === solidGen\n && this.layout.cssGeneration === cssGen\n ) {\n if (this.log.enabled) this.log.debug(`getLayoutGraph HIT: solidGen=${solidGen} cssGen=${cssGen}`)\n return this.layout.graph\n }\n\n if (this.log.enabled) this.log.debug(\n `getLayoutGraph MISS: solidGen=${solidGen} cssGen=${cssGen} `\n + `cached=${this.layout !== null}`,\n )\n\n const t0 = performance.now()\n const graph = build()\n this.layout = {\n solidGeneration: solidGen,\n cssGeneration: cssGen,\n graph,\n }\n if (this.log.enabled) this.log.debug(`getLayoutGraph BUILT: in ${performance.now() - t0}ms`)\n return graph\n }\n\n /**\n * Invalidate cached graphs affected by a file change.\n *\n * Classifies the path and invalidates the appropriate cache:\n * solid files evict their per-file SolidGraph, CSS files bump\n * the CSSGraph generation counter.\n *\n * @param path Absolute file path that changed\n */\n invalidate(path: string): void {\n const key = canonicalPath(path)\n const kind = classifyFile(key)\n if (this.log.enabled) this.log.debug(`invalidate: ${key} kind=${kind} solids=${this.solids.size} hasCrossFileResults=${this.crossFileResults !== null} hasLayout=${this.layout !== null}`)\n if (kind === \"solid\") {\n const had = this.solids.has(key)\n this.solids.delete(key)\n this.crossFileDiagnostics.delete(key)\n this.crossFileResults = null\n this.solidGeneration++\n this.layout = null\n if (this.log.enabled) this.log.debug(`invalidate SOLID: ${key} wasInCache=${had} solids=${this.solids.size} solidGen=${this.solidGeneration}`)\n }\n if (kind === \"css\") {\n this.crossFileDiagnostics.delete(key)\n this.crossFileResults = null\n this.cssGeneration++\n this.css = null\n this.layout = null\n if (this.log.enabled) this.log.debug(`invalidate CSS: ${key} newCssGen=${this.cssGeneration}`)\n }\n }\n\n /**\n * Invalidate all cached graphs.\n *\n * Called on workspace-level events like config changes.\n */\n invalidateAll(): void {\n if (this.log.enabled) this.log.debug(`invalidateAll: solids=${this.solids.size} solidGen=${this.solidGeneration} cssGen=${this.cssGeneration}`)\n this.solids.clear()\n this.crossFileDiagnostics.clear()\n this.crossFileResults = null\n this.solidGeneration++\n this.cssGeneration++\n this.css = null\n this.layout = null\n }\n\n /**\n * Get all cached SolidGraphs.\n *\n * Returns a snapshot array of all currently-cached graphs.\n * Used by cross-file analysis which needs all SolidGraphs.\n */\n getAllSolidGraphs(): readonly SolidGraph[] {\n if (this.log.enabled) this.log.debug(`getAllSolidGraphs: ${this.solids.size} graphs`)\n const out: SolidGraph[] = new Array(this.solids.size)\n let i = 0\n for (const entry of this.solids.values()) {\n out[i++] = entry.graph\n }\n return out\n }\n\n /**\n * Get the cached CSSGraph, or null if not cached.\n */\n getCachedCSSGraph(): CSSGraph | null {\n return this.css?.graph ?? null\n }\n\n /**\n * Get the cached LayoutGraph, or null if not cached.\n */\n getCachedLayoutGraph(): LayoutGraph | null {\n return this.layout?.graph ?? null\n }\n\n /**\n * Get cached cross-file diagnostics for a file path.\n *\n * Returns the previous cross-file results so single-file-only\n * re-analysis (during typing) can merge them without re-running\n * cross-file rules.\n *\n * @param path Absolute file path\n */\n getCachedCrossFileDiagnostics(path: string): readonly Diagnostic[] {\n return this.crossFileDiagnostics.get(canonicalPath(path)) ?? []\n }\n\n /**\n * Store cross-file diagnostics for a file path.\n *\n * @param path Absolute file path\n * @param diagnostics Cross-file diagnostics for this path\n */\n setCachedCrossFileDiagnostics(path: string, diagnostics: readonly Diagnostic[]): void {\n this.crossFileDiagnostics.set(canonicalPath(path), diagnostics)\n }\n\n /**\n * Get workspace-level cross-file results if the underlying graphs haven't changed.\n *\n * Returns the full per-file map when the solid signature and CSS generation\n * match, meaning no graphs were rebuilt since the last run. Returns null\n * when results are stale and `runCrossFileRules` must re-execute.\n */\n getCachedCrossFileResults(): ReadonlyMap<string, readonly Diagnostic[]> | null {\n if (this.crossFileResults === null) {\n this.log.debug(\"getCachedCrossFileResults: null (no cached results)\")\n return null\n }\n const solidMatch = this.crossFileResults.solidGeneration === this.solidGeneration\n const cssMatch = this.crossFileResults.cssGeneration === this.cssGeneration\n if (solidMatch && cssMatch) {\n if (this.log.enabled) this.log.debug(`getCachedCrossFileResults HIT: ${this.crossFileResults?.byFile.size} files`)\n return this.crossFileResults.byFile\n }\n if (this.log.enabled) this.log.debug(\n `getCachedCrossFileResults MISS: solidMatch=${solidMatch} cssMatch=${cssMatch} `\n + `cachedSolidGen=${this.crossFileResults?.solidGeneration} currentSolidGen=${this.solidGeneration} `\n + `cachedCssGen=${this.crossFileResults?.cssGeneration} currentCssGen=${this.cssGeneration}`,\n )\n return null\n }\n\n /**\n * Store workspace-level cross-file results bucketed by file.\n *\n * Called after `runCrossFileRules` completes. Captures the current\n * solid signature and CSS generation so subsequent lookups are O(1)\n * until a graph changes.\n *\n * @param allDiagnostics All cross-file diagnostics from the workspace run\n */\n setCachedCrossFileResults(allDiagnostics: readonly Diagnostic[]): void {\n const byFile = new Map<string, Diagnostic[]>()\n for (let i = 0, len = allDiagnostics.length; i < len; i++) {\n const d = allDiagnostics[i]\n if (!d) continue\n let arr = byFile.get(d.file)\n if (!arr) {\n arr = []\n byFile.set(d.file, arr)\n }\n arr.push(d)\n }\n this.crossFileResults = {\n solidGeneration: this.solidGeneration,\n cssGeneration: this.cssGeneration,\n byFile,\n }\n if (this.log.enabled) this.log.debug(\n `setCachedCrossFileResults: ${allDiagnostics.length} diags across ${byFile.size} files `\n + `solidGen=${this.solidGeneration} cssGen=${this.cssGeneration}`,\n )\n /* Replace the per-file cache used during typing (when cross-file\n analysis is skipped and previous results are reused). Must clear\n first — files that previously had cross-file diagnostics but no\n longer do must not retain stale entries. */\n this.crossFileDiagnostics.clear()\n for (const [file, diagnostics] of byFile) {\n this.crossFileDiagnostics.set(file, diagnostics)\n }\n }\n\n /** Number of cached SolidGraphs. */\n get solidCount(): number {\n return this.solids.size\n }\n\n /** The logger instance used by this cache. */\n get logger(): Logger {\n return this.log\n }\n\n\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/runner.ts","../src/cache.ts"],"sourcesContent":["/**\n * Runner - Plugin-agnostic runner for ganko\n *\n * The runner takes a configuration with plugins and runs them against files.\n * It never stores typed graphs - plugins handle their own graph building\n * and rule execution internally via the analyze() method.\n *\n * Rule overrides allow callers (LSP, CLI) to disable rules or remap their\n * severity without modifying rule definitions. The runner intercepts the\n * Emit callback to enforce overrides before diagnostics reach the caller.\n */\nimport type ts from \"typescript\"\nimport type { Diagnostic } from \"./diagnostic\"\nimport type { Plugin, Emit } from \"./graph\"\nimport type { RuleOverrides } from \"@drskillissue/ganko-shared\"\n\n/** Runner configuration */\nexport interface RunnerConfig {\n readonly plugins: readonly Plugin<string>[]\n readonly rules?: RuleOverrides\n readonly program?: ts.Program\n}\n\n/** Runner interface */\nexport interface Runner {\n run(files: readonly string[]): readonly Diagnostic[]\n /** Replace rule overrides. Takes effect on the next run() call. */\n setRuleOverrides(overrides: RuleOverrides): void\n /** Replace the TypeScript program. Takes effect on the next run() call. */\n setProgram(program: ts.Program): void\n}\n\n/**\n * Build an Emit wrapper that enforces rule overrides.\n *\n * @param target - The underlying emit that collects diagnostics\n * @param overrides - Current rule override map\n * @returns Wrapped emit that suppresses/remaps per overrides\n */\nexport function createOverrideEmit(target: Emit, overrides: RuleOverrides): Emit {\n return (d) => {\n const override = overrides[d.rule]\n if (override === undefined) { target(d); return }\n if (override === \"off\") return\n if (override !== d.severity) {\n target({ ...d, severity: override })\n return\n }\n target(d)\n }\n}\n\n/**\n * Create a runner from configuration.\n */\nexport function createRunner(config: RunnerConfig): Runner {\n let overrides: RuleOverrides = config.rules ?? {}\n let program: ts.Program | undefined = config.program\n\n return {\n run(files) {\n const diagnostics: Diagnostic[] = []\n const raw: Emit = (d) => diagnostics.push(d)\n const hasOverrides = Object.keys(overrides).length > 0\n const emit = hasOverrides ? createOverrideEmit(raw, overrides) : raw\n const context = program ? { program } : undefined\n for (const plugin of config.plugins) {\n plugin.analyze(files, emit, context)\n }\n return diagnostics\n },\n\n setRuleOverrides(next) {\n overrides = next\n },\n\n setProgram(next) {\n program = next\n },\n }\n}\n","/**\n * GraphCache — Versioned cache for SolidGraph, CSSGraph, and LayoutGraph instances.\n *\n * Eliminates redundant graph construction in the LSP server by caching\n * per-file SolidGraphs (keyed by path + script version), a single\n * CSSGraph invalidated via a monotonic generation counter, and a\n * LayoutGraph invalidated by Solid/CSS signatures.\n *\n * The cache does not perform I/O or parsing — callers supply builder\n * functions that are invoked only on cache miss.\n */\nimport { canonicalPath, classifyFile, noopLogger, Level } from \"@drskillissue/ganko-shared\"\nimport type { Logger } from \"@drskillissue/ganko-shared\"\nimport type { Diagnostic } from \"./diagnostic\"\nimport type { SolidGraph } from \"./solid/impl\"\nimport type { CSSGraph } from \"./css/impl\"\nimport type { LayoutGraph } from \"./cross-file/layout/graph\"\n\ninterface CachedSolid {\n readonly version: string\n readonly graph: SolidGraph\n}\n\ninterface CachedCSS {\n readonly generation: number\n readonly graph: CSSGraph\n}\n\ninterface CachedLayout {\n readonly solidGeneration: number\n readonly cssGeneration: number\n readonly graph: LayoutGraph\n}\n\ninterface CachedCrossFileResults {\n readonly solidGeneration: number\n readonly cssGeneration: number\n readonly byFile: ReadonlyMap<string, readonly Diagnostic[]>\n}\n\n/**\n * Versioned cache for SolidGraph, CSSGraph, and LayoutGraph instances.\n *\n * SolidGraphs are cached per file path with a version string.\n * The CSSGraph is a single instance covering all CSS files,\n * invalidated via a monotonic generation counter bumped by\n * `invalidate()` or `invalidateAll()`.\n */\nexport class GraphCache {\n private readonly log: Logger\n private readonly solids = new Map<string, CachedSolid>()\n private readonly crossFileDiagnostics = new Map<string, readonly Diagnostic[]>()\n private crossFileResults: CachedCrossFileResults | null = null\n private css: CachedCSS | null = null\n private solidGeneration = 0\n private cssGeneration = 0\n private layout: CachedLayout | null = null\n\n constructor(log?: Logger) {\n this.log = log ?? noopLogger\n }\n\n /**\n * Check if a SolidGraph is cached and current for a file path.\n *\n * Allows callers to skip builder allocation when the cache is warm.\n *\n * @param path Absolute file path\n * @param version Script version string from the TS project service\n */\n hasSolidGraph(path: string, version: string): boolean {\n const key = canonicalPath(path)\n const cached = this.solids.get(key)\n const hit = cached !== undefined && cached.version === version\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`hasSolidGraph: ${key} v=${version} cached=${cached?.version ?? \"none\"} hit=${hit} (${this.solids.size} total)`)\n return hit\n }\n\n /**\n * Store a pre-built SolidGraph in the cache.\n *\n * Used by the CLI lint command which builds graphs during single-file\n * analysis and pre-populates the cache for cross-file reuse.\n *\n * @param path Absolute file path\n * @param version Script version string from the TS project service\n * @param graph Pre-built SolidGraph\n */\n setSolidGraph(path: string, version: string, graph: SolidGraph): void {\n const key = canonicalPath(path)\n this.solids.set(key, { version, graph })\n this.solidGeneration++\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`setSolidGraph: ${key} v=${version} (${this.solids.size} total) solidGen=${this.solidGeneration}`)\n }\n\n /**\n * Get a cached SolidGraph without building on miss.\n *\n * Returns the cached graph if the version matches, null otherwise.\n * Use when the caller has already confirmed the entry exists via\n * `hasSolidGraph` and wants to avoid allocating a builder closure.\n *\n * @param path Absolute file path\n * @param version Script version string from the TS project service\n */\n getCachedSolidGraph(path: string, version: string): SolidGraph | null {\n const key = canonicalPath(path)\n const cached = this.solids.get(key)\n if (cached !== undefined && cached.version === version) {\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCachedSolidGraph HIT: ${key} v=${version}`)\n return cached.graph\n }\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCachedSolidGraph MISS: ${key} v=${version}`)\n return null\n }\n\n /**\n * Get or build a SolidGraph for a file path.\n *\n * Returns the cached graph if the version matches.\n * Otherwise invokes the builder, caches the result, and returns it.\n *\n * @param path Absolute file path\n * @param version Script version string from the TS project service\n * @param build Builder function invoked on cache miss\n */\n getSolidGraph(path: string, version: string, build: () => SolidGraph): SolidGraph {\n const key = canonicalPath(path)\n const cached = this.solids.get(key)\n if (cached !== undefined && cached.version === version) {\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getSolidGraph HIT: ${key} v=${version}`)\n return cached.graph\n }\n\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getSolidGraph MISS: ${key} v=${version} (was ${cached?.version ?? \"uncached\"})`)\n const t0 = performance.now()\n const graph = build()\n this.solids.set(key, { version, graph })\n this.solidGeneration++\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getSolidGraph BUILT: ${key} v=${version} in ${performance.now() - t0}ms (${this.solids.size} total) solidGen=${this.solidGeneration}`)\n return graph\n }\n\n /**\n * Get the cached CSSGraph, or rebuild it.\n *\n * Returns the cached graph if the generation matches the current\n * CSS generation counter. Otherwise invokes the builder, caches\n * the result at the current generation, and returns it.\n *\n * @param build Builder function invoked on cache miss\n */\n getCSSGraph(build: () => CSSGraph): CSSGraph {\n if (this.css !== null && this.css.generation === this.cssGeneration) {\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCSSGraph HIT: gen=${this.cssGeneration}`)\n return this.css.graph\n }\n\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCSSGraph MISS: currentGen=${this.cssGeneration} cachedGen=${this.css?.generation ?? \"none\"}`)\n const t0 = performance.now()\n const graph = build()\n this.css = { generation: this.cssGeneration, graph }\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCSSGraph BUILT: gen=${this.cssGeneration} in ${performance.now() - t0}ms`)\n return graph\n }\n\n /**\n * Get or build a LayoutGraph for current Solid/CSS cache state.\n *\n * Returns cached LayoutGraph when both Solid signature (path+version)\n * and CSS generation match. Otherwise invokes the builder.\n *\n * @param build Builder function invoked on cache miss\n */\n getLayoutGraph(build: () => LayoutGraph): LayoutGraph {\n const solidGen = this.solidGeneration\n const cssGen = this.cssGeneration\n\n if (\n this.layout !== null\n && this.layout.solidGeneration === solidGen\n && this.layout.cssGeneration === cssGen\n ) {\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getLayoutGraph HIT: solidGen=${solidGen} cssGen=${cssGen}`)\n return this.layout.graph\n }\n\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(\n `getLayoutGraph MISS: solidGen=${solidGen} cssGen=${cssGen} `\n + `cached=${this.layout !== null}`,\n )\n\n const t0 = performance.now()\n const graph = build()\n this.layout = {\n solidGeneration: solidGen,\n cssGeneration: cssGen,\n graph,\n }\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getLayoutGraph BUILT: in ${performance.now() - t0}ms`)\n return graph\n }\n\n /**\n * Invalidate cached graphs affected by a file change.\n *\n * Classifies the path and invalidates the appropriate cache:\n * solid files evict their per-file SolidGraph, CSS files bump\n * the CSSGraph generation counter.\n *\n * @param path Absolute file path that changed\n */\n invalidate(path: string): void {\n const key = canonicalPath(path)\n const kind = classifyFile(key)\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`invalidate: ${key} kind=${kind} solids=${this.solids.size} hasCrossFileResults=${this.crossFileResults !== null} hasLayout=${this.layout !== null}`)\n if (kind === \"solid\") {\n const had = this.solids.has(key)\n this.solids.delete(key)\n this.crossFileDiagnostics.delete(key)\n this.crossFileResults = null\n this.solidGeneration++\n this.layout = null\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`invalidate SOLID: ${key} wasInCache=${had} solids=${this.solids.size} solidGen=${this.solidGeneration}`)\n }\n if (kind === \"css\") {\n this.crossFileDiagnostics.delete(key)\n this.crossFileResults = null\n this.cssGeneration++\n this.css = null\n this.layout = null\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`invalidate CSS: ${key} newCssGen=${this.cssGeneration}`)\n }\n }\n\n /**\n * Invalidate all cached graphs.\n *\n * Called on workspace-level events like config changes.\n */\n invalidateAll(): void {\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`invalidateAll: solids=${this.solids.size} solidGen=${this.solidGeneration} cssGen=${this.cssGeneration}`)\n this.solids.clear()\n this.crossFileDiagnostics.clear()\n this.crossFileResults = null\n this.solidGeneration++\n this.cssGeneration++\n this.css = null\n this.layout = null\n }\n\n /**\n * Get all cached SolidGraphs.\n *\n * Returns a snapshot array of all currently-cached graphs.\n * Used by cross-file analysis which needs all SolidGraphs.\n */\n getAllSolidGraphs(): readonly SolidGraph[] {\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getAllSolidGraphs: ${this.solids.size} graphs`)\n const out: SolidGraph[] = new Array(this.solids.size)\n let i = 0\n for (const entry of this.solids.values()) {\n out[i++] = entry.graph\n }\n return out\n }\n\n /**\n * Get the cached CSSGraph, or null if not cached.\n */\n getCachedCSSGraph(): CSSGraph | null {\n return this.css?.graph ?? null\n }\n\n /**\n * Get the cached LayoutGraph, or null if not cached.\n */\n getCachedLayoutGraph(): LayoutGraph | null {\n return this.layout?.graph ?? null\n }\n\n /**\n * Get cached cross-file diagnostics for a file path.\n *\n * Returns the previous cross-file results so single-file-only\n * re-analysis (during typing) can merge them without re-running\n * cross-file rules.\n *\n * @param path Absolute file path\n */\n getCachedCrossFileDiagnostics(path: string): readonly Diagnostic[] {\n return this.crossFileDiagnostics.get(canonicalPath(path)) ?? []\n }\n\n /**\n * Store cross-file diagnostics for a file path.\n *\n * @param path Absolute file path\n * @param diagnostics Cross-file diagnostics for this path\n */\n setCachedCrossFileDiagnostics(path: string, diagnostics: readonly Diagnostic[]): void {\n this.crossFileDiagnostics.set(canonicalPath(path), diagnostics)\n }\n\n /**\n * Get workspace-level cross-file results if the underlying graphs haven't changed.\n *\n * Returns the full per-file map when the solid signature and CSS generation\n * match, meaning no graphs were rebuilt since the last run. Returns null\n * when results are stale and `runCrossFileRules` must re-execute.\n */\n getCachedCrossFileResults(): ReadonlyMap<string, readonly Diagnostic[]> | null {\n if (this.crossFileResults === null) {\n this.log.debug(\"getCachedCrossFileResults: null (no cached results)\")\n return null\n }\n const solidMatch = this.crossFileResults.solidGeneration === this.solidGeneration\n const cssMatch = this.crossFileResults.cssGeneration === this.cssGeneration\n if (solidMatch && cssMatch) {\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(`getCachedCrossFileResults HIT: ${this.crossFileResults?.byFile.size} files`)\n return this.crossFileResults.byFile\n }\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(\n `getCachedCrossFileResults MISS: solidMatch=${solidMatch} cssMatch=${cssMatch} `\n + `cachedSolidGen=${this.crossFileResults?.solidGeneration} currentSolidGen=${this.solidGeneration} `\n + `cachedCssGen=${this.crossFileResults?.cssGeneration} currentCssGen=${this.cssGeneration}`,\n )\n return null\n }\n\n /**\n * Store workspace-level cross-file results bucketed by file.\n *\n * Called after `runCrossFileRules` completes. Captures the current\n * solid signature and CSS generation so subsequent lookups are O(1)\n * until a graph changes.\n *\n * @param allDiagnostics All cross-file diagnostics from the workspace run\n */\n setCachedCrossFileResults(allDiagnostics: readonly Diagnostic[]): void {\n const byFile = new Map<string, Diagnostic[]>()\n for (let i = 0, len = allDiagnostics.length; i < len; i++) {\n const d = allDiagnostics[i]\n if (!d) continue\n let arr = byFile.get(d.file)\n if (!arr) {\n arr = []\n byFile.set(d.file, arr)\n }\n arr.push(d)\n }\n this.crossFileResults = {\n solidGeneration: this.solidGeneration,\n cssGeneration: this.cssGeneration,\n byFile,\n }\n if (this.log.isLevelEnabled(Level.Debug)) this.log.debug(\n `setCachedCrossFileResults: ${allDiagnostics.length} diags across ${byFile.size} files `\n + `solidGen=${this.solidGeneration} cssGen=${this.cssGeneration}`,\n )\n /* Replace the per-file cache used during typing (when cross-file\n analysis is skipped and previous results are reused). Must clear\n first — files that previously had cross-file diagnostics but no\n longer do must not retain stale entries. */\n this.crossFileDiagnostics.clear()\n for (const [file, diagnostics] of byFile) {\n this.crossFileDiagnostics.set(file, diagnostics)\n }\n }\n\n /** Number of cached SolidGraphs. */\n get solidCount(): number {\n return this.solids.size\n }\n\n /** The logger instance used by this cache. */\n get logger(): Logger {\n return this.log\n }\n\n\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drskillissue/ganko",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Static analysis SDK for Solid.js — graphs, rules, ESLint adapter",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -88,7 +88,6 @@
|
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
90
|
"@drskillissue/ganko-shared": "workspace:^",
|
|
91
|
-
"@typescript-eslint/rule-tester": "^8.57.0",
|
|
92
91
|
"@typescript-eslint/utils": "^8.57.0"
|
|
93
92
|
},
|
|
94
93
|
"author": "DrSkillIssue",
|