@svelte-vitals/core 0.36.0 → 0.37.0
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/index.d.ts +21 -3
- package/dist/index.js +58 -35
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -956,6 +956,14 @@ interface RuleContext {
|
|
|
956
956
|
sourceFiles?: string[];
|
|
957
957
|
project: Project;
|
|
958
958
|
config: Config;
|
|
959
|
+
/**
|
|
960
|
+
* Report per-declaration counts of places this rule examined. The engine supplies it and keys the
|
|
961
|
+
* result by rule id; a rule that does not call it gets no entry, which is distinct from an entry of
|
|
962
|
+
* zeros. Absent in contexts a caller builds directly. Silent last-write-wins: calling it more than
|
|
963
|
+
* once keeps only the most recent map, with no merge and no error — call it once, with the complete
|
|
964
|
+
* counts, at the end of `check()`.
|
|
965
|
+
*/
|
|
966
|
+
recordExamined?: (counts: Record<string, number>) => void;
|
|
959
967
|
}
|
|
960
968
|
interface Rule {
|
|
961
969
|
id: string;
|
|
@@ -995,7 +1003,10 @@ declare function isPenalized(detection: Detection, treatDynamicAs: TreatDynamicA
|
|
|
995
1003
|
* Rules are independent, so they run concurrently; results are flattened in
|
|
996
1004
|
* rule order for stable output.
|
|
997
1005
|
*/
|
|
998
|
-
declare function runRules(rules: Rule[], ctx: RuleContext): Promise<
|
|
1006
|
+
declare function runRules(rules: Rule[], ctx: RuleContext): Promise<{
|
|
1007
|
+
results: Result[];
|
|
1008
|
+
examined: Record<string, Record<string, number>>;
|
|
1009
|
+
}>;
|
|
999
1010
|
|
|
1000
1011
|
/**
|
|
1001
1012
|
* seo/title-presence — every route should resolve a non-empty <title> (design §11).
|
|
@@ -1554,15 +1565,22 @@ interface JsonReport {
|
|
|
1554
1565
|
* and floors that sum once, so adding this map's already-floored entries and re-dividing can disagree.
|
|
1555
1566
|
*/
|
|
1556
1567
|
inventories: Record<string, number>;
|
|
1568
|
+
/**
|
|
1569
|
+
* Per-rule, per-declaration counts of places examined. Unlike `rules`, this describes the analysis
|
|
1570
|
+
* rather than the report: `--diff`, `--baseline` and suppressions do not narrow it. Three states: a
|
|
1571
|
+
* rule that reports no counts has no entry; a rule that counts but whose configuration declares
|
|
1572
|
+
* nothing has an empty entry; a declaration that judged nothing has an entry of `0`.
|
|
1573
|
+
*/
|
|
1574
|
+
examined?: Record<string, Record<string, number>>;
|
|
1557
1575
|
}
|
|
1558
1576
|
/** Build the structured JSON report object (design §7). The shape the `json` reporter emits (issue #24). */
|
|
1559
1577
|
declare function buildJsonReport(results: Result[], config: Config, meta: {
|
|
1560
1578
|
version: string;
|
|
1561
|
-
}, ruleIds?: readonly string[]): JsonReport;
|
|
1579
|
+
}, ruleIds?: readonly string[], examined?: Record<string, Record<string, number>>): JsonReport;
|
|
1562
1580
|
/** Render results as the documented JSON report string (design §7). */
|
|
1563
1581
|
declare function formatJsonReport(results: Result[], config: Config, meta: {
|
|
1564
1582
|
version: string;
|
|
1565
|
-
}, ruleIds?: readonly string[]): string;
|
|
1583
|
+
}, ruleIds?: readonly string[], examined?: Record<string, Record<string, number>>): string;
|
|
1566
1584
|
|
|
1567
1585
|
/** Render failing findings as an agent-actionable Markdown remediation document (issue #18). */
|
|
1568
1586
|
declare function formatAgentReport(results: Result[], config: Config): string;
|
package/dist/index.js
CHANGED
|
@@ -2444,8 +2444,11 @@ function isPenalized(detection, treatDynamicAs) {
|
|
|
2444
2444
|
|
|
2445
2445
|
// src/engine.ts
|
|
2446
2446
|
async function runRules(rules, ctx) {
|
|
2447
|
-
const
|
|
2448
|
-
|
|
2447
|
+
const examined = {};
|
|
2448
|
+
const perRule = await Promise.all(
|
|
2449
|
+
rules.map((rule) => rule.check({ ...ctx, recordExamined: (counts) => void (examined[rule.id] = counts) }))
|
|
2450
|
+
);
|
|
2451
|
+
return { results: perRule.flat(), examined };
|
|
2449
2452
|
}
|
|
2450
2453
|
|
|
2451
2454
|
// src/rules/seo/title-presence.ts
|
|
@@ -5470,20 +5473,17 @@ var architectureReservedNamePlacement = {
|
|
|
5470
5473
|
const emptyNames = /* @__PURE__ */ new Map();
|
|
5471
5474
|
for (const map of Object.keys(globalMaps)) {
|
|
5472
5475
|
for (const [name, value] of Object.entries(globalMaps[map])) {
|
|
5473
|
-
const
|
|
5474
|
-
if (
|
|
5476
|
+
const globs = globsOf(value);
|
|
5477
|
+
if (globs.length === 0) {
|
|
5475
5478
|
emptyNames.set(`${map}.${name}`, "names no position at all");
|
|
5476
5479
|
continue;
|
|
5477
5480
|
}
|
|
5478
|
-
for (const glob of
|
|
5481
|
+
for (const glob of globs) globalAlternatives.set(label(map, name, glob), { map, glob });
|
|
5479
5482
|
}
|
|
5480
5483
|
}
|
|
5481
5484
|
const usedAlternatives = /* @__PURE__ */ new Set();
|
|
5482
|
-
const
|
|
5483
|
-
const
|
|
5484
|
-
capitalisedUnitPlacements: [],
|
|
5485
|
-
anyCaseUnitPlacements: []
|
|
5486
|
-
};
|
|
5485
|
+
const examinedCounts = {};
|
|
5486
|
+
for (const key of globalAlternatives.keys()) examinedCounts[key] = 0;
|
|
5487
5487
|
const allDirs = [...dirs].sort();
|
|
5488
5488
|
for (const dir of allDirs) {
|
|
5489
5489
|
const o = resolveRuleOptions(ID7, OPTIONS6, ctx.config, { route: dir, file: dir }, compiledOverrides);
|
|
@@ -5506,17 +5506,24 @@ var architectureReservedNamePlacement = {
|
|
|
5506
5506
|
const parent = parentOf(dir);
|
|
5507
5507
|
if (parent === void 0) continue;
|
|
5508
5508
|
if (isExcluded(dir, ancestorDirs2(dir), excluded)) {
|
|
5509
|
-
if (isExcluded(parent, ancestorDirs2(parent), excluded)) excludedDirs.push(parent);
|
|
5510
5509
|
continue;
|
|
5511
5510
|
}
|
|
5511
|
+
const judged = /* @__PURE__ */ new Set();
|
|
5512
|
+
const resolvedValues = [
|
|
5513
|
+
["placements", placements[name]],
|
|
5514
|
+
["capitalisedUnitPlacements", capUnits[name]],
|
|
5515
|
+
["anyCaseUnitPlacements", anyUnits[name]]
|
|
5516
|
+
];
|
|
5517
|
+
for (const [map, value] of resolvedValues) {
|
|
5518
|
+
if (value === void 0) continue;
|
|
5519
|
+
for (const glob of globsOf(value)) judged.add(label(map, name, glob));
|
|
5520
|
+
}
|
|
5521
|
+
for (const key of judged) if (globalAlternatives.has(key)) examinedCounts[key] = (examinedCounts[key] ?? 0) + 1;
|
|
5512
5522
|
const record = (map, value, qualifies) => {
|
|
5513
5523
|
if (value === void 0) return false;
|
|
5514
5524
|
const { matched } = matchKeys(parent, compile(globsOf(value), true));
|
|
5515
5525
|
if (matched.length === 0) return false;
|
|
5516
|
-
if (!qualifies)
|
|
5517
|
-
if (map !== "placements") nonUnitParents[map].push(parent);
|
|
5518
|
-
return false;
|
|
5519
|
-
}
|
|
5526
|
+
if (!qualifies) return false;
|
|
5520
5527
|
for (const glob of matched) usedAlternatives.add(label(map, name, glob));
|
|
5521
5528
|
return true;
|
|
5522
5529
|
};
|
|
@@ -5544,23 +5551,27 @@ var architectureReservedNamePlacement = {
|
|
|
5544
5551
|
const notes = new Map(emptyNames);
|
|
5545
5552
|
const unusedLabels = [...globalAlternatives.keys()].filter((k) => !usedAlternatives.has(k));
|
|
5546
5553
|
const globOf = (key) => globalAlternatives.get(key)?.glob;
|
|
5547
|
-
for (const map of ["capitalisedUnitPlacements", "anyCaseUnitPlacements"]) {
|
|
5548
|
-
const inMap = unusedLabels.filter((k) => globalAlternatives.get(k)?.map === map);
|
|
5549
|
-
const hit = keysMatchingAny(inMap.map(globOf), nonUnitParents[map], compile);
|
|
5550
|
-
for (const k of inMap) {
|
|
5551
|
-
if (hit.has(globOf(k))) notes.set(k, "matched directories but never a unit");
|
|
5552
|
-
}
|
|
5553
|
-
}
|
|
5554
5554
|
const stillUnused = unusedLabels.filter((k) => !notes.has(k));
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5555
|
+
if (stillUnused.length > 0) {
|
|
5556
|
+
const globalExcluded = compile(listOption(globalOptions, "exclude"));
|
|
5557
|
+
const liveDirs = allDirs.filter((d) => !isExcluded(d, ancestorDirs2(d), globalExcluded));
|
|
5558
|
+
const liveUnits = {
|
|
5559
|
+
capitalisedUnitPlacements: liveDirs.filter((d) => isUnitDir(d, filesIn)),
|
|
5560
|
+
anyCaseUnitPlacements: liveDirs.filter((d) => isAnyCaseUnitDir(d, filesIn))
|
|
5561
|
+
};
|
|
5562
|
+
const globs = [...new Set(stillUnused.map(globOf))];
|
|
5563
|
+
const reachesAny = keysMatchingAny(globs, allDirs, compile);
|
|
5564
|
+
const reachesLive = keysMatchingAny(globs, liveDirs, compile);
|
|
5565
|
+
for (const k of stillUnused) {
|
|
5566
|
+
const glob = globOf(k);
|
|
5567
|
+
if (!reachesAny.has(glob)) notes.set(k, "matched no directory");
|
|
5568
|
+
else if (!reachesLive.has(glob)) notes.set(k, "matched only excluded directories");
|
|
5569
|
+
}
|
|
5570
|
+
for (const map of ["capitalisedUnitPlacements", "anyCaseUnitPlacements"]) {
|
|
5571
|
+
const inMap = stillUnused.filter((k) => !notes.has(k) && globalAlternatives.get(k)?.map === map);
|
|
5572
|
+
const inMapGlobs = [...new Set(inMap.map(globOf))];
|
|
5573
|
+
const reachesUnit = keysMatchingAny(inMapGlobs, liveUnits[map], compile);
|
|
5574
|
+
for (const k of inMap) if (!reachesUnit.has(globOf(k))) notes.set(k, "reaches no unit");
|
|
5564
5575
|
}
|
|
5565
5576
|
}
|
|
5566
5577
|
const reported = [...notes.keys()].sort();
|
|
@@ -5576,6 +5587,7 @@ var architectureReservedNamePlacement = {
|
|
|
5576
5587
|
docsUrl: docsUrl11
|
|
5577
5588
|
});
|
|
5578
5589
|
}
|
|
5590
|
+
ctx.recordExamined?.(examinedCounts);
|
|
5579
5591
|
return out;
|
|
5580
5592
|
}
|
|
5581
5593
|
};
|
|
@@ -6263,7 +6275,7 @@ function ruleEvidence(results, config, ruleIds) {
|
|
|
6263
6275
|
}
|
|
6264
6276
|
return out;
|
|
6265
6277
|
}
|
|
6266
|
-
function buildJsonReport(results, config, meta, ruleIds) {
|
|
6278
|
+
function buildJsonReport(results, config, meta, ruleIds, examined) {
|
|
6267
6279
|
const { health, categories: byCat, weights } = computeHealth(results, config);
|
|
6268
6280
|
const summary = summarize(results, config);
|
|
6269
6281
|
const rules = ruleEvidence(results, config, ruleIds);
|
|
@@ -6293,10 +6305,21 @@ function buildJsonReport(results, config, meta, ruleIds) {
|
|
|
6293
6305
|
const inventories = Object.fromEntries(
|
|
6294
6306
|
[...buildInventory(config)].map(([pair, weight]) => [pair, Math.max(weight, INVENTORY_FLOOR)])
|
|
6295
6307
|
);
|
|
6296
|
-
return {
|
|
6308
|
+
return {
|
|
6309
|
+
version: meta.version,
|
|
6310
|
+
score: health,
|
|
6311
|
+
weights,
|
|
6312
|
+
categories,
|
|
6313
|
+
summary,
|
|
6314
|
+
rules,
|
|
6315
|
+
routes,
|
|
6316
|
+
siteIssues,
|
|
6317
|
+
inventories,
|
|
6318
|
+
...examined && Object.keys(examined).length > 0 ? { examined } : {}
|
|
6319
|
+
};
|
|
6297
6320
|
}
|
|
6298
|
-
function formatJsonReport(results, config, meta, ruleIds) {
|
|
6299
|
-
return JSON.stringify(buildJsonReport(results, config, meta, ruleIds), null, 2);
|
|
6321
|
+
function formatJsonReport(results, config, meta, ruleIds, examined) {
|
|
6322
|
+
return JSON.stringify(buildJsonReport(results, config, meta, ruleIds, examined), null, 2);
|
|
6300
6323
|
}
|
|
6301
6324
|
|
|
6302
6325
|
// src/reporter/agent.ts
|