svelte-vitals 0.22.1 → 0.23.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/README.md +2 -4
- package/dist/bin.js +15 -5
- package/dist/{chunk-KSJZLF5U.js → chunk-HYTPZVSU.js} +63 -2
- package/dist/index.d.ts +8 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -34,14 +34,12 @@ Critical (1)
|
|
|
34
34
|
src/routes/none/+page.svelte
|
|
35
35
|
|
|
36
36
|
Passed (3)
|
|
37
|
-
────────────────────────
|
|
38
|
-
✓ SEO001 <title> /blog
|
|
39
|
-
✓ SEO001 <title> ↯ dynamic /dynamic
|
|
40
|
-
✓ SEO001 <title> /static
|
|
41
37
|
|
|
42
38
|
↯ = set dynamically (verified at runtime).
|
|
43
39
|
```
|
|
44
40
|
|
|
41
|
+
By default, console output groups failures by rule (top 5 per severity, each with one example location and an "…and N more" count) and collapses the Passed section to a bare count, so large projects don't flood the terminal. Pass `--verbose` to see every finding uncapped and ungrouped, with each passed item listed individually. On an interactive, color-capable terminal the Health score plays a short reveal animation; pass `--no-animation` to disable it.
|
|
42
|
+
|
|
45
43
|
### Exit codes
|
|
46
44
|
|
|
47
45
|
| Code | Meaning |
|
package/dist/bin.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
readCoreVersion,
|
|
8
8
|
readPackageVersion,
|
|
9
9
|
run
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-HYTPZVSU.js";
|
|
11
11
|
|
|
12
12
|
// src/bin.ts
|
|
13
13
|
import mri3 from "mri";
|
|
@@ -134,6 +134,7 @@ function resolveArgs(argv) {
|
|
|
134
134
|
if (score && (argv.json || typeof argv.reporter === "string")) {
|
|
135
135
|
warnings.push("svelte-vitals: --score overrides --reporter; reporter output suppressed.");
|
|
136
136
|
}
|
|
137
|
+
const verbose = Boolean(argv["verbose"]);
|
|
137
138
|
const rulesConfig = buildRulesConfig(allow, ignore);
|
|
138
139
|
const rules = Object.keys(rulesConfig).length > 0 ? rulesConfig : void 0;
|
|
139
140
|
if (errors.length > 0) return { options: null, warnings, errors };
|
|
@@ -154,6 +155,7 @@ function resolveArgs(argv) {
|
|
|
154
155
|
...weights !== void 0 ? { weights } : {},
|
|
155
156
|
...categories !== void 0 ? { categories } : {},
|
|
156
157
|
...score ? { score } : {},
|
|
158
|
+
...verbose ? { verbose } : {},
|
|
157
159
|
...diffBase !== void 0 ? { diffBase } : {},
|
|
158
160
|
...staged ? { staged } : {},
|
|
159
161
|
...baselineRef !== void 0 ? { baseline: baselineRef } : {}
|
|
@@ -880,8 +882,8 @@ function buildWorkflowYaml(opts) {
|
|
|
880
882
|
}
|
|
881
883
|
|
|
882
884
|
// src/ci/action-pin.generated.ts
|
|
883
|
-
var ACTION_SHA = "
|
|
884
|
-
var ACTION_VERSION = "0.2.
|
|
885
|
+
var ACTION_SHA = "caf278cf4030801b017d31b108fa46abc15e8105";
|
|
886
|
+
var ACTION_VERSION = "0.2.2";
|
|
885
887
|
|
|
886
888
|
// src/ci/cli.ts
|
|
887
889
|
var CI_HELP = `svelte-vitals ci \u2014 scaffold CI integration
|
|
@@ -969,6 +971,8 @@ Options:
|
|
|
969
971
|
--weights <pairs> Per-category Health weight overrides, e.g. seo=2,performance=1 (unlisted categories default to 1)
|
|
970
972
|
--score Print only the combined Health score (works with --min-health for gating)
|
|
971
973
|
--no-color Disable ANSI color in console output
|
|
974
|
+
--no-animation Disable the Health-score reveal animation on an interactive terminal
|
|
975
|
+
--verbose Show every finding uncapped and ungrouped (default: capped, grouped by rule)
|
|
972
976
|
-h, --help Show this help
|
|
973
977
|
-v, --version Show version
|
|
974
978
|
|
|
@@ -999,7 +1003,7 @@ async function main() {
|
|
|
999
1003
|
}
|
|
1000
1004
|
const argv = mri3(process.argv.slice(2), {
|
|
1001
1005
|
alias: { h: "help", v: "version" },
|
|
1002
|
-
boolean: ["by-route", "json", "fail-on-warning", "staged", "no-color", "score"],
|
|
1006
|
+
boolean: ["by-route", "json", "fail-on-warning", "staged", "no-color", "score", "verbose", "no-animation"],
|
|
1003
1007
|
string: [
|
|
1004
1008
|
"meta-components",
|
|
1005
1009
|
"treat-dynamic-as",
|
|
@@ -1038,7 +1042,13 @@ async function main() {
|
|
|
1038
1042
|
}
|
|
1039
1043
|
minHealth = n;
|
|
1040
1044
|
}
|
|
1041
|
-
const code = await run({
|
|
1045
|
+
const code = await run({
|
|
1046
|
+
...options,
|
|
1047
|
+
minHealth,
|
|
1048
|
+
noColor: argv["no-color"],
|
|
1049
|
+
noAnimation: argv["no-animation"],
|
|
1050
|
+
selectApp
|
|
1051
|
+
});
|
|
1042
1052
|
process.exit(code);
|
|
1043
1053
|
}
|
|
1044
1054
|
void main();
|
|
@@ -702,6 +702,9 @@ function isAgentEnv(env = process.env) {
|
|
|
702
702
|
function isGithubActionsEnv(env = process.env) {
|
|
703
703
|
return env.GITHUB_ACTIONS === "true";
|
|
704
704
|
}
|
|
705
|
+
function isCiEnv(env = process.env) {
|
|
706
|
+
return env.CI === "true" || env.CI === "1";
|
|
707
|
+
}
|
|
705
708
|
function resolveReporter(explicit, env = process.env) {
|
|
706
709
|
if (explicit) return explicit;
|
|
707
710
|
const fromEnv = env.SVELTE_VITALS_REPORTER;
|
|
@@ -953,6 +956,40 @@ async function loadConfigFile(cwd) {
|
|
|
953
956
|
return validateConfigFile(mod.default, found);
|
|
954
957
|
}
|
|
955
958
|
|
|
959
|
+
// src/pulse-animation.ts
|
|
960
|
+
import { scoreColor } from "@svelte-vitals/core";
|
|
961
|
+
var FRAME_COUNT = 6;
|
|
962
|
+
var FRAME_DELAY_MS = 200;
|
|
963
|
+
var WAVE_FRAMES = [
|
|
964
|
+
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2571\u2572\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
965
|
+
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2571\u2572\u2500\u2500\u2571\u2572\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
966
|
+
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2571\u2572\u2500\u2500\u2500\u2500\u2500\u2500\u2571\u2572\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
967
|
+
"\u2500\u2500\u2500\u2500\u2500\u2500\u2571\u2572\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2572\u2500\u2500\u2500\u2500\u2500",
|
|
968
|
+
"\u2500\u2500\u2500\u2500\u2571\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2572\u2500\u2500\u2500\u2500",
|
|
969
|
+
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
|
|
970
|
+
];
|
|
971
|
+
function sleep(ms) {
|
|
972
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
973
|
+
}
|
|
974
|
+
async function playScoreAnimation(opts) {
|
|
975
|
+
const frameDelayMs = opts.frameDelayMs ?? FRAME_DELAY_MS;
|
|
976
|
+
for (let frame = 0; frame < FRAME_COUNT; frame++) {
|
|
977
|
+
const progress = frame / (FRAME_COUNT - 1);
|
|
978
|
+
const displayScore = Math.round(opts.score * progress);
|
|
979
|
+
const isFinalFrame = frame === FRAME_COUNT - 1;
|
|
980
|
+
const wave = WAVE_FRAMES[frame];
|
|
981
|
+
const scoreText = isFinalFrame ? scoreColor(opts.palette, opts.score)(`${displayScore}/100`) : opts.palette.dim(`${displayScore}/100`);
|
|
982
|
+
const cursorUp = frame === 0 ? "" : "\x1B[2A";
|
|
983
|
+
opts.stream.write(`${cursorUp}\r ${wave}\x1B[K
|
|
984
|
+
\r Health: ${scoreText}\x1B[K
|
|
985
|
+
`);
|
|
986
|
+
if (!isFinalFrame) await sleep(frameDelayMs);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
function scoreAnimationEnabled(opts) {
|
|
990
|
+
return opts.reporter === "console" && opts.stdoutIsTTY && !opts.noAnimationFlag && !isAgentEnv(opts.env) && !isCiEnv(opts.env) && colorEnabled({ reporter: opts.reporter, isTTY: opts.stdoutIsTTY, env: opts.env, noColorFlag: opts.noColorFlag });
|
|
991
|
+
}
|
|
992
|
+
|
|
956
993
|
// src/index.ts
|
|
957
994
|
import { defineConfig as defineConfig2 } from "@svelte-vitals/core";
|
|
958
995
|
function spinnerEnabled(opts) {
|
|
@@ -1172,13 +1209,37 @@ async function run(opts = {}) {
|
|
|
1172
1209
|
} else if (reporter === "md") {
|
|
1173
1210
|
log(formatMarkdownReport(results, config, { version }));
|
|
1174
1211
|
} else {
|
|
1212
|
+
const stdoutIsTTY = opts.stdoutIsTTY ?? !!process.stdout.isTTY;
|
|
1175
1213
|
const colorOn = colorEnabled({
|
|
1176
1214
|
reporter,
|
|
1177
|
-
isTTY:
|
|
1215
|
+
isTTY: stdoutIsTTY,
|
|
1178
1216
|
env,
|
|
1179
1217
|
noColorFlag: opts.noColor
|
|
1180
1218
|
});
|
|
1181
|
-
|
|
1219
|
+
const palette = paletteFor(colorOn);
|
|
1220
|
+
const animate = scoreAnimationEnabled({
|
|
1221
|
+
reporter,
|
|
1222
|
+
stdoutIsTTY,
|
|
1223
|
+
env,
|
|
1224
|
+
noColorFlag: opts.noColor,
|
|
1225
|
+
noAnimationFlag: opts.noAnimation
|
|
1226
|
+
});
|
|
1227
|
+
if (animate) {
|
|
1228
|
+
await playScoreAnimation({
|
|
1229
|
+
score: computeHealth(results, config).health,
|
|
1230
|
+
palette,
|
|
1231
|
+
stream: opts.stdoutStream ?? process.stdout,
|
|
1232
|
+
frameDelayMs: opts.animationFrameDelayMs
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
log(
|
|
1236
|
+
formatConsoleReport(results, config, {
|
|
1237
|
+
byRoute: opts.byRoute ?? false,
|
|
1238
|
+
verbose: opts.verbose ?? false,
|
|
1239
|
+
palette,
|
|
1240
|
+
omitHeader: animate
|
|
1241
|
+
})
|
|
1242
|
+
);
|
|
1182
1243
|
}
|
|
1183
1244
|
}
|
|
1184
1245
|
const summary = summarize(results, config);
|
package/dist/index.d.ts
CHANGED
|
@@ -89,6 +89,14 @@ interface RunOptions {
|
|
|
89
89
|
explicitPath?: boolean;
|
|
90
90
|
/** Injected picker for the monorepo app selector (bin.ts wires a clack implementation; null = cancelled). */
|
|
91
91
|
selectApp?: (apps: string[]) => Promise<string | null>;
|
|
92
|
+
/** Show every finding uncapped and ungrouped in console output (default false — capped, grouped by rule). */
|
|
93
|
+
verbose?: boolean;
|
|
94
|
+
/** Disable the Health-score reveal animation even on an interactive stdout. */
|
|
95
|
+
noAnimation?: boolean;
|
|
96
|
+
/** Override the stream the score animation writes to (tests). Defaults to process.stdout. */
|
|
97
|
+
stdoutStream?: NodeJS.WriteStream;
|
|
98
|
+
/** Override the animation's per-frame delay in ms (tests — 0 runs the real frame loop near-instantly). Defaults to the animation module's own constant. */
|
|
99
|
+
animationFrameDelayMs?: number;
|
|
92
100
|
}
|
|
93
101
|
/**
|
|
94
102
|
* Whether the "Analyzing…" spinner should run. Unlike color, the spinner animates
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-vitals",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "A SvelteKit SEO checker — not a runtime Web Vitals reporter. Static analysis of your routes' head metadata.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"smol-toml": "^1.7.0",
|
|
46
46
|
"svelte": "^5.56.4",
|
|
47
47
|
"tinyglobby": "^0.2.17",
|
|
48
|
-
"@svelte-vitals/core": "0.
|
|
48
|
+
"@svelte-vitals/core": "0.23.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/node": "^24.13.2"
|