@svelte-vitals/core 0.21.0 → 0.22.1

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 CHANGED
@@ -743,9 +743,13 @@ declare function escapeHtml(s: string): string;
743
743
  declare function safeHref(url: string): string | null;
744
744
  declare function buildHtmlDocument(report: JsonReport, meta: {
745
745
  version: string;
746
+ coreVersion?: string;
747
+ }, opts?: {
748
+ routeBadges?: Record<string, 'measured' | 'static'>;
746
749
  }): string;
747
750
  declare function formatHtmlReport(results: Result[], config: Config, meta: {
748
751
  version: string;
752
+ coreVersion?: string;
749
753
  }): string;
750
754
 
751
755
  /** Drop rules disabled via config (design §6). */
package/dist/index.js CHANGED
@@ -2665,6 +2665,9 @@ function locationOf(issue, route) {
2665
2665
  if (issue.location) return issue.line !== void 0 ? `${issue.location}:${issue.line}` : issue.location;
2666
2666
  return route ?? "-";
2667
2667
  }
2668
+ function messageWithRecommendation(issue) {
2669
+ return issue.recommendation ? `${issue.title} ${issue.recommendation}` : issue.title;
2670
+ }
2668
2671
  function flattenFindings(report) {
2669
2672
  const findings = [];
2670
2673
  for (const r of report.routes) {
@@ -2673,7 +2676,7 @@ function flattenFindings(report) {
2673
2676
  severity: issue.severity,
2674
2677
  id: issue.id,
2675
2678
  location: locationOf(issue, r.route),
2676
- message: issue.title
2679
+ message: messageWithRecommendation(issue)
2677
2680
  });
2678
2681
  }
2679
2682
  }
@@ -2682,7 +2685,7 @@ function flattenFindings(report) {
2682
2685
  severity: issue.severity,
2683
2686
  id: issue.id,
2684
2687
  location: locationOf(issue, void 0),
2685
- message: issue.title
2688
+ message: messageWithRecommendation(issue)
2686
2689
  });
2687
2690
  }
2688
2691
  return findings.map((f, index) => ({ f, index })).sort((a, b) => SEVERITY_RANK2[a.f.severity] - SEVERITY_RANK2[b.f.severity] || a.index - b.index).map(({ f }) => f);
@@ -2763,7 +2766,8 @@ function renderFinding(issue) {
2763
2766
  }
2764
2767
  function renderTopbar(report, meta) {
2765
2768
  const findings = report.routes.reduce((n, r) => n + r.issues.length, 0) + report.siteIssues.length;
2766
- return `<header class="topbar"><div class="brand"><span class="bolt">\u21AF</span>svelte-<span class="v">vitals</span></div><div class="meta"><span>v${escapeHtml(meta.version)}</span><span>${report.routes.length} routes</span><span>${findings} findings</span></div></header>`;
2769
+ const core = meta.coreVersion ? `<span title="@svelte-vitals/core version">core v${escapeHtml(meta.coreVersion)}</span>` : "";
2770
+ return `<header class="topbar"><div class="brand"><span class="bolt">\u21AF</span>svelte-<span class="v">vitals</span></div><div class="meta"><span>v${escapeHtml(meta.version)}</span>` + core + `<span>${report.routes.length} routes</span><span>${findings} findings</span></div></header>`;
2767
2771
  }
2768
2772
  function renderHero(report) {
2769
2773
  const C = 2 * Math.PI * 58;
@@ -2780,7 +2784,8 @@ function renderHero(report) {
2780
2784
  }).join("");
2781
2785
  return `<section class="hero"><div class="gauge"><svg width="132" height="132" viewBox="0 0 132 132" aria-hidden="true"><circle cx="66" cy="66" r="58" fill="none" stroke="#e4e7ec" stroke-width="11"></circle><circle id="arc" cx="66" cy="66" r="58" fill="none" stroke="${BAND_COLOR[hb]}" stroke-width="11" stroke-linecap="round" stroke-dasharray="${C.toFixed(1)}" stroke-dashoffset="${offset}"></circle></svg><div class="num"><strong id="hnum">${report.score}</strong><span>Health</span></div></div><div class="readout"><div class="eyebrow">SvelteKit \xB7 SEO &amp; Performance</div><div class="tallies"><span class="tally"><span class="dot crit"></span>Critical <span class="n">${s.critical}</span></span><span class="tally"><span class="dot warn"></span>Warning <span class="n">${s.warning}</span></span><span class="tally"><span class="dot info"></span>Info <span class="n">${s.info}</span></span><span class="tally"><span class="dot pass"></span>Passed <span class="n">${s.passed}</span></span>` + dynNote + `</div><div class="cats">${cats}</div></div></section>`;
2782
2786
  }
2783
- function renderRoutes(report) {
2787
+ var ROUTE_BADGES = ["measured", "static"];
2788
+ function renderRoutes(report, routeBadges) {
2784
2789
  if (report.routes.length === 0) return "";
2785
2790
  const rows = report.routes.map((r) => {
2786
2791
  const b = scoreBand(r.score);
@@ -2793,7 +2798,10 @@ function renderRoutes(report) {
2793
2798
  if (info) parts.push(`${info} info`);
2794
2799
  const sum = parts.length ? parts.join(" \xB7 ") : '<span class="none">no issues</span>';
2795
2800
  const body = r.issues.length ? r.issues.map(renderFinding).join("") : '<p class="empty">No issues found on this route.</p>';
2796
- return `<details class="route" id="${slug(r.route)}" data-score="${r.score}"${r.issues.length ? " open" : ""}><summary><span class="route-name"><span class="path">${escapeHtml(r.route)}</span></span><span class="issue-sum">${sum}</span><span class="score-chip"><span class="ring" style="background:${BAND_COLOR[b]}"></span>${r.score}</span><span class="chev">\u203A</span></summary><div class="route-body">${body}</div></details>`;
2801
+ const rawBadge = routeBadges?.[r.route];
2802
+ const badge = rawBadge && ROUTE_BADGES.includes(rawBadge) ? rawBadge : void 0;
2803
+ const badgeHtml = badge ? ` <span class="badge badge-${badge}">${escapeHtml(badge)}</span>` : "";
2804
+ return `<details class="route" id="${slug(r.route)}" data-score="${r.score}"${r.issues.length ? " open" : ""}><summary><span class="route-name"><span class="path">${escapeHtml(r.route)}</span>${badgeHtml}</span><span class="issue-sum">${sum}</span><span class="score-chip"><span class="ring" style="background:${BAND_COLOR[b]}"></span>${r.score}</span><span class="chev">\u203A</span></summary><div class="route-body">${body}</div></details>`;
2797
2805
  }).join("");
2798
2806
  return `<section class="section"><h2>Routes</h2><div class="routes">${rows}</div></section>`;
2799
2807
  }
@@ -2846,8 +2854,11 @@ body{margin:0;background:var(--ground);color:var(--ink);font-family:var(--sans);
2846
2854
  .route>summary{display:grid;grid-template-columns:1fr auto auto auto;gap:16px;align-items:center;padding:13px 16px;cursor:pointer;list-style:none}
2847
2855
  .route>summary::-webkit-details-marker{display:none}
2848
2856
  .route>summary:hover{background:#fbfcfd}
2849
- .route-name{font-family:var(--mono);font-size:13.5px;min-width:0}
2857
+ .route-name{font-family:var(--mono);font-size:13.5px;min-width:0;display:flex;align-items:center;gap:8px}
2850
2858
  .route-name .path{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
2859
+ .badge{font-family:var(--sans);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;padding:2px 7px;border-radius:999px;flex-shrink:0}
2860
+ .badge-measured{background:rgba(47,169,104,.14);color:var(--good)}
2861
+ .badge-static{background:rgba(140,149,163,.18);color:var(--muted)}
2851
2862
  .issue-sum{font-size:12.5px;color:var(--muted);font-family:var(--mono);white-space:nowrap}.issue-sum .none{color:var(--good)}
2852
2863
  .score-chip{display:inline-flex;align-items:center;gap:7px;font-family:var(--mono);font-weight:600;font-variant-numeric:tabular-nums;font-size:14px}
2853
2864
  .score-chip .ring{width:10px;height:10px;border-radius:50%}
@@ -2909,8 +2920,8 @@ var SCRIPT = `
2909
2920
  });
2910
2921
  })();
2911
2922
  `;
2912
- function buildHtmlDocument(report, meta) {
2913
- return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>svelte-vitals report</title><style>${STYLE}</style></head><body><div class="wrap">` + renderTopbar(report, meta) + renderHero(report) + renderFilters(report) + renderRoutes(report) + renderSiteChecks(report) + `<footer class="foot"><span>Generated by svelte-vitals \xB7 static analysis, no browser</span><span>oekazuma.github.io/svelte-vitals</span></footer></div><script>${SCRIPT}</script></body></html>`;
2923
+ function buildHtmlDocument(report, meta, opts) {
2924
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>svelte-vitals report</title><style>${STYLE}</style></head><body><div class="wrap">` + renderTopbar(report, meta) + renderHero(report) + renderFilters(report) + renderRoutes(report, opts?.routeBadges) + renderSiteChecks(report) + `<footer class="foot"><span>Generated by svelte-vitals \xB7 static analysis, no browser</span><span>oekazuma.github.io/svelte-vitals</span></footer></div><script>${SCRIPT}</script></body></html>`;
2914
2925
  }
2915
2926
  function formatHtmlReport(results, config, meta) {
2916
2927
  return buildHtmlDocument(buildJsonReport(results, config, meta), meta);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svelte-vitals/core",
3
- "version": "0.21.0",
3
+ "version": "0.22.1",
4
4
  "description": "Shared, runtime-agnostic core for svelte-vitals (types, rule engine, scorer, reporter).",
5
5
  "type": "module",
6
6
  "license": "MIT",