svelte-vitals 0.22.0 → 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 +18 -6
- 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 } : {}
|
|
@@ -843,6 +845,8 @@ import mri2 from "mri";
|
|
|
843
845
|
|
|
844
846
|
// src/ci/workflow.ts
|
|
845
847
|
var WORKFLOW_PATH = ".github/workflows/svelte-vitals.yml";
|
|
848
|
+
var CHECKOUT_SHA = "9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0";
|
|
849
|
+
var CHECKOUT_VERSION = "v7.0.0";
|
|
846
850
|
function planWorkflowWrite(existing, force) {
|
|
847
851
|
if (existing === void 0) return { status: "created" };
|
|
848
852
|
if (!force) return { status: "exists" };
|
|
@@ -866,7 +870,7 @@ function buildWorkflowYaml(opts) {
|
|
|
866
870
|
" svelte-vitals:",
|
|
867
871
|
" runs-on: ubuntu-latest",
|
|
868
872
|
" steps:",
|
|
869
|
-
|
|
873
|
+
` - uses: actions/checkout@${CHECKOUT_SHA} # ${CHECKOUT_VERSION}`,
|
|
870
874
|
" with:",
|
|
871
875
|
" fetch-depth: 0",
|
|
872
876
|
` - uses: oekazuma/svelte-vitals/packages/action@${actionSha} # @svelte-vitals/action@${actionVersion}`,
|
|
@@ -878,8 +882,8 @@ function buildWorkflowYaml(opts) {
|
|
|
878
882
|
}
|
|
879
883
|
|
|
880
884
|
// src/ci/action-pin.generated.ts
|
|
881
|
-
var ACTION_SHA = "
|
|
882
|
-
var ACTION_VERSION = "0.2.
|
|
885
|
+
var ACTION_SHA = "caf278cf4030801b017d31b108fa46abc15e8105";
|
|
886
|
+
var ACTION_VERSION = "0.2.2";
|
|
883
887
|
|
|
884
888
|
// src/ci/cli.ts
|
|
885
889
|
var CI_HELP = `svelte-vitals ci \u2014 scaffold CI integration
|
|
@@ -967,6 +971,8 @@ Options:
|
|
|
967
971
|
--weights <pairs> Per-category Health weight overrides, e.g. seo=2,performance=1 (unlisted categories default to 1)
|
|
968
972
|
--score Print only the combined Health score (works with --min-health for gating)
|
|
969
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)
|
|
970
976
|
-h, --help Show this help
|
|
971
977
|
-v, --version Show version
|
|
972
978
|
|
|
@@ -997,7 +1003,7 @@ async function main() {
|
|
|
997
1003
|
}
|
|
998
1004
|
const argv = mri3(process.argv.slice(2), {
|
|
999
1005
|
alias: { h: "help", v: "version" },
|
|
1000
|
-
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"],
|
|
1001
1007
|
string: [
|
|
1002
1008
|
"meta-components",
|
|
1003
1009
|
"treat-dynamic-as",
|
|
@@ -1036,7 +1042,13 @@ async function main() {
|
|
|
1036
1042
|
}
|
|
1037
1043
|
minHealth = n;
|
|
1038
1044
|
}
|
|
1039
|
-
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
|
+
});
|
|
1040
1052
|
process.exit(code);
|
|
1041
1053
|
}
|
|
1042
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"
|