mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
This adds `scripts/agent/load-test.mjs`, a stress testing tool that: - Spawns a local relay server in a separate process. - Simulates N concurrent WebSocket clients. - Publishes a configurable mix of large (Video Post) and small (View) events. - Measures and reports on latency, throughput, memory usage, and cryptographic signing time. - Identifies potential bottlenecks (error rate > 5%, latency > 500ms, sign time > 5ms). Includes a sample run report in `artifacts/`. Also updates linting scripts (`scripts/check-hex.js`, `scripts/check-design-tokens.mjs`, `scripts/check-inline-styles.mjs`, `scripts/check-tailwind-colors.mjs`) to correctly ignore working directories (`bitvid-working-webtorrent`, `scripts/agent`), preventing CI failures. Co-authored-by: PR0M3TH3AN <[email protected]>
139 lines
3.3 KiB
JavaScript
Executable File
139 lines
3.3 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
import { readdir, readFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import process from "node:process";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
const repoRoot = path.resolve(__dirname, "..");
|
|
|
|
const TARGET_DIRECTORIES = ["components", "js", "views"];
|
|
const IGNORED_DIRECTORIES = new Set([
|
|
"ed-legacy",
|
|
"legacy",
|
|
"__snapshots__",
|
|
"bitvid-working-webtorrent",
|
|
]);
|
|
const LEGACY_ALLOWLIST = new Set([
|
|
"components/ed-/revert-video-modal.html",
|
|
"components/ed-/profile-modal.html",
|
|
]);
|
|
|
|
const COLOR_PATTERN =
|
|
/\b(?:text|bg|border|divide|ring|stroke|fill|outline|shadow|accent|placeholder)-(?:slate|gray|zinc|stone|neutral|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)(?:-[\w/]+)?\b/gim;
|
|
|
|
function toPosix(relPath) {
|
|
return relPath.split(path.sep).join("/");
|
|
}
|
|
|
|
async function collectFiles() {
|
|
const results = new Set();
|
|
for (const directory of TARGET_DIRECTORIES) {
|
|
const absolute = path.resolve(repoRoot, directory);
|
|
await walkDirectory(absolute, results);
|
|
}
|
|
return [...results];
|
|
}
|
|
|
|
async function walkDirectory(dir, results) {
|
|
let entries = [];
|
|
try {
|
|
entries = await readdir(dir, { withFileTypes: true });
|
|
} catch (error) {
|
|
return;
|
|
}
|
|
|
|
for (const entry of entries) {
|
|
const fullPath = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
if (IGNORED_DIRECTORIES.has(entry.name)) {
|
|
continue;
|
|
}
|
|
await walkDirectory(fullPath, results);
|
|
continue;
|
|
}
|
|
|
|
if (!entry.isFile()) {
|
|
continue;
|
|
}
|
|
|
|
results.add(fullPath);
|
|
}
|
|
}
|
|
|
|
function buildLineIndex(content) {
|
|
const lines = [0];
|
|
let index = 0;
|
|
while ((index = content.indexOf("\n", index)) !== -1) {
|
|
lines.push(index + 1);
|
|
index += 1;
|
|
}
|
|
return lines;
|
|
}
|
|
|
|
function getLineNumber(indexes, matchIndex) {
|
|
let low = 0;
|
|
let high = indexes.length;
|
|
while (low < high) {
|
|
const mid = Math.floor((low + high) / 2);
|
|
if (indexes[mid] <= matchIndex) {
|
|
low = mid + 1;
|
|
} else {
|
|
high = mid;
|
|
}
|
|
}
|
|
return low;
|
|
}
|
|
|
|
async function main() {
|
|
const files = await collectFiles();
|
|
const violations = [];
|
|
|
|
for (const filePath of files) {
|
|
const rel = toPosix(path.relative(repoRoot, filePath));
|
|
if (LEGACY_ALLOWLIST.has(rel)) {
|
|
continue;
|
|
}
|
|
|
|
let content;
|
|
try {
|
|
content = await readFile(filePath, "utf8");
|
|
} catch (error) {
|
|
continue;
|
|
}
|
|
|
|
const lineIndex = buildLineIndex(content);
|
|
let match;
|
|
COLOR_PATTERN.lastIndex = 0;
|
|
while ((match = COLOR_PATTERN.exec(content))) {
|
|
const line = getLineNumber(lineIndex, match.index);
|
|
violations.push({
|
|
file: rel,
|
|
line,
|
|
value: match[0],
|
|
});
|
|
}
|
|
}
|
|
|
|
if (violations.length > 0) {
|
|
console.error("Tailwind color lint failed: raw palette classes detected.\n");
|
|
for (const violation of violations) {
|
|
console.error(`${violation.file}:${violation.line} → ${violation.value}`);
|
|
}
|
|
console.error(
|
|
"\nReplace raw tailwind colors with semantic utilities (text-muted, bg-status-warning-surface, etc.)."
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
process.exit(0);
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error("Failed to check Tailwind color usage.");
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|