@svelte-vitals/vite 0.31.0 → 0.32.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.
@@ -41,8 +41,10 @@ function collectA11y(root) {
41
41
  const nestedLandmarks = [];
42
42
  const ids = [];
43
43
  const idRefs = [];
44
+ const elementTags = /* @__PURE__ */ new Set();
44
45
  const walk = (el, ctx) => {
45
46
  const tag = el.rawTagName?.toLowerCase();
47
+ if (tag && ctx.inBody) elementTags.add(tag);
46
48
  const roleAttr = el.getAttribute("role");
47
49
  let landmark;
48
50
  if (roleAttr !== void 0) {
@@ -76,12 +78,13 @@ function collectA11y(root) {
76
78
  const nextCtx = {
77
79
  sectioning: ctx.sectioning + (SECTIONING_TAGS.has(tag) ? 1 : 0),
78
80
  asideDemoting: ctx.asideDemoting + (ASIDE_DEMOTING_TAGS.has(tag) ? 1 : 0),
79
- landmarks: landmark ? [...ctx.landmarks, landmark] : ctx.landmarks
81
+ landmarks: landmark ? [...ctx.landmarks, landmark] : ctx.landmarks,
82
+ inBody: ctx.inBody || tag === "body"
80
83
  };
81
84
  for (const child of el.children) walk(child, nextCtx);
82
85
  };
83
- for (const child of root.children) walk(child, { sectioning: 0, asideDemoting: 0, landmarks: [] });
84
- return { landmarks, nestedLandmarks, ids, idRefs };
86
+ for (const child of root.children) walk(child, { sectioning: 0, asideDemoting: 0, landmarks: [], inBody: false });
87
+ return { landmarks, nestedLandmarks, ids, idRefs, elementTags: [...elementTags] };
85
88
  }
86
89
  function parseHtmlHead(html) {
87
90
  const root = parse(html);
@@ -228,7 +231,10 @@ async function collectRenderedHeads(prerenderPagesDir) {
228
231
  idCandidates: [...new Set(parsed.ids)],
229
232
  // The prerendered document IS the closed world: every id/landmark/reference it can ever
230
233
  // have is already in it, unlike source mode which may hit an unresolved component.
231
- fullyResolved: true
234
+ fullyResolved: true,
235
+ elementTags: parsed.elementTags,
236
+ elementsClosed: true,
237
+ file: rel
232
238
  });
233
239
  }
234
240
  return { heads, headings, images, a11y, htmlLang };
@@ -9,7 +9,7 @@ interface SvelteVitalsHookOptions {
9
9
  rules?: Record<string, RuleSetting>;
10
10
  }
11
11
  /**
12
- * SvelteKit `handle` that analyzes each visited page's rendered `<head>`, in dev only,
12
+ * SvelteKit `handle` that analyzes each visited page's rendered HTML, in dev only,
13
13
  * and (when the live dashboard is enabled) feeds the results in — upgrading that
14
14
  * route's dashboard findings from static (source-only) to `measured` (real rendered
15
15
  * HTML). Add it to `src/hooks.server.ts`, e.g. `sequence(svelteVitalsHandle())`.
@@ -2,7 +2,7 @@ import {
2
2
  isLoopbackOrigin,
3
3
  parseHtmlHead,
4
4
  toOccurrenceMap
5
- } from "../chunk-LTT4HAEL.js";
5
+ } from "../chunk-KII3SU3J.js";
6
6
 
7
7
  // src/hooks/handle.ts
8
8
  import { DEV } from "esm-env";
@@ -10,6 +10,7 @@ import { defineConfig } from "@svelte-vitals/core";
10
10
  import {
11
11
  allRules,
12
12
  applyRuleSeverities,
13
+ defaultProject,
13
14
  effectiveSeverity,
14
15
  formatFailedRuleWarning,
15
16
  isPenalized,
@@ -43,16 +44,7 @@ async function postIngest(origin, route, results, failedRuleIds) {
43
44
  }
44
45
  async function analyzeAndIngest(html, route, origin, rules, config, lastSignature) {
45
46
  try {
46
- const {
47
- tags,
48
- htmlLang,
49
- headings: levels,
50
- images: imgs,
51
- landmarks,
52
- nestedLandmarks,
53
- ids,
54
- idRefs
55
- } = parseHtmlHead(html);
47
+ const { tags, headings: levels, images: imgs, landmarks, nestedLandmarks, ids, idRefs } = parseHtmlHead(html);
56
48
  const head = { route, source: "rendered", tags, file: route };
57
49
  const headings = [
58
50
  { route, headings: levels.map((level) => ({ level, line: 0, file: route })) }
@@ -69,13 +61,12 @@ async function analyzeAndIngest(html, route, origin, rules, config, lastSignatur
69
61
  fullyResolved: true
70
62
  }
71
63
  ];
72
- const project = { hasRobotsTxt: true, hasSitemap: true, htmlLang };
73
64
  const { results: ruleResults, failedRules } = await runRules(rules, {
74
65
  heads: [head],
75
66
  headings,
76
67
  images,
77
68
  a11y,
78
- project,
69
+ project: defaultProject,
79
70
  config
80
71
  });
81
72
  const results = applyRuleSeverities(ruleResults, config);
@@ -99,7 +90,7 @@ function svelteVitalsHandle(options = {}) {
99
90
  metaComponents: options.metaComponents ?? [],
100
91
  rules: options.rules ?? {}
101
92
  });
102
- const rules = selectRules(allRules, config);
93
+ const rules = selectRules(allRules, config).filter((r) => r.scope === "route" && !r.crossRoute);
103
94
  const lastSignature = /* @__PURE__ */ new Map();
104
95
  return ({ event, resolve }) => {
105
96
  let buffer = "";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  collectRenderedHeads,
3
3
  isLoopbackOrigin
4
- } from "./chunk-LTT4HAEL.js";
4
+ } from "./chunk-KII3SU3J.js";
5
5
 
6
6
  // src/plugin.ts
7
7
  import { existsSync } from "fs";
@@ -24,6 +24,8 @@ import {
24
24
  selectRules,
25
25
  applyRuleSeverities,
26
26
  applyOverrides,
27
+ applyInlineDirectives,
28
+ unknownDirectiveIds,
27
29
  runRules,
28
30
  withFailedRulesOff,
29
31
  formatFailedRuleWarning,
@@ -199,8 +201,19 @@ async function analyze(prerenderPagesDir, cwd, options, extraProjectFacts, resol
199
201
  kitModules,
200
202
  sourceFiles
201
203
  });
202
- const results = applyOverrides(applyRuleSeverities(rawResults, config), config);
204
+ const directives = /* @__PURE__ */ new Map();
205
+ for (const c of components) directives.set(c.file, c.suppressions ?? []);
206
+ for (const m of kitModules) directives.set(m.file, m.suppressions ?? []);
207
+ if (project.viteMinifyDisabled?.file)
208
+ directives.set(project.viteMinifyDisabled.file, project.viteMinifyDisabled.suppressions ?? []);
209
+ const results = applyInlineDirectives(
210
+ applyOverrides(applyRuleSeverities(rawResults, config), config),
211
+ directives,
212
+ selected,
213
+ config
214
+ );
203
215
  warnings.push(...skippedFileWarnings([...components, ...kitModules]));
216
+ warnings.push(...unknownDirectiveIds(directives, allRules));
204
217
  for (const f of failedRules) warnings.push(formatFailedRuleWarning(f));
205
218
  const scoringConfig = withFailedRulesOff(
206
219
  config,
@@ -235,18 +248,28 @@ Scanned ${components.length} component(s) under src/ for Correctness/Security/Ar
235
248
  // src/minify-flag.ts
236
249
  import { readFile as readFile3 } from "fs/promises";
237
250
  import { relative } from "path";
238
- import { findMinifyDisabled } from "@svelte-vitals/core/internal";
251
+ import {
252
+ collectSuppressions,
253
+ findMinifyDisabled
254
+ } from "@svelte-vitals/core/internal";
239
255
  async function resolveMinifyDisabled(minify, configFile, root) {
240
256
  if (minify !== false) return void 0;
241
257
  if (!configFile) return {};
242
258
  const rel = relative(root, configFile).split("\\").join("/");
243
259
  const file = rel === "" ? configFile.split("\\").join("/") : rel;
244
260
  let line;
261
+ let suppressions;
245
262
  try {
246
- line = findMinifyDisabled(await readFile3(configFile, "utf8"))?.line;
263
+ const source = await readFile3(configFile, "utf8");
264
+ line = findMinifyDisabled(source)?.line;
265
+ suppressions = collectSuppressions(source);
247
266
  } catch {
248
267
  }
249
- return { file, ...line !== void 0 ? { line } : {} };
268
+ return {
269
+ file,
270
+ ...line !== void 0 ? { line } : {},
271
+ ...suppressions !== void 0 ? { suppressions } : {}
272
+ };
250
273
  }
251
274
 
252
275
  // src/ui/middleware.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svelte-vitals/vite",
3
- "version": "0.31.0",
3
+ "version": "0.32.0",
4
4
  "description": "Vite/SvelteKit plugin for svelte-vitals — analyzes prerendered HTML during vite build, plus a live dev dashboard.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -42,8 +42,8 @@
42
42
  "esm-env": "^1.2.2",
43
43
  "node-html-parser": "^9.0.1",
44
44
  "tinyglobby": "^0.2.17",
45
- "@svelte-vitals/core": "0.44.0",
46
- "svelte-vitals": "0.48.0"
45
+ "@svelte-vitals/core": "0.46.0",
46
+ "svelte-vitals": "0.49.0"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@sveltejs/kit": "^2.70.2",