fix: Fix multiple bugs with new authentication flow

This commit is contained in:
2026-06-07 15:04:21 +02:00
parent 9fc26b1ccf
commit 83456c018c
137 changed files with 4710 additions and 281 deletions

202
tools/perf-diag-viewer.js Normal file
View File

@@ -0,0 +1,202 @@
#!/usr/bin/env node
'use strict';
const fs = require('fs');
const path = require('path');
const os = require('os');
const args = process.argv.slice(2);
function readArg(name) {
const index = args.indexOf(name);
if (index === -1) {
return null;
}
return args[index + 1] ?? null;
}
function hasFlag(name) {
return args.includes(name);
}
function resolveCandidateUserDataDirs() {
const home = os.homedir();
const appNames = ['Toju', 'metoyou'];
if (process.platform === 'win32') {
const base = process.env.APPDATA || path.join(home, 'AppData', 'Roaming');
return appNames.map((name) => path.join(base, name));
}
if (process.platform === 'darwin') {
const base = path.join(home, 'Library', 'Application Support');
return appNames.map((name) => path.join(base, name));
}
const base = process.env.XDG_CONFIG_HOME || path.join(home, '.config');
return appNames.map((name) => path.join(base, name));
}
function resolveDefaultDiagnosticsDir() {
const candidates = resolveCandidateUserDataDirs()
.map((userDataDir) => path.join(userDataDir, 'diagnostics'))
.filter((dir) => fs.existsSync(dir));
if (candidates.length === 0) {
return path.join(resolveCandidateUserDataDirs()[0], 'diagnostics');
}
return candidates
.map((dir) => ({ dir, mtimeMs: fs.statSync(dir).mtimeMs }))
.sort((left, right) => right.mtimeMs - left.mtimeMs)[0].dir;
}
function parseJsonLines(content) {
return content
.split('\n')
.map((line) => line.trim())
.filter(Boolean)
.map((line) => {
try {
return JSON.parse(line);
} catch {
return null;
}
})
.filter(Boolean);
}
function formatKb(kb) {
if (kb == null) {
return 'n/a';
}
return `${Math.round(kb / 1024)} MB`;
}
function summarize(entries) {
const latestProcess = [...entries].reverse().find((entry) => entry.type === 'process');
const latestStore = [...entries].reverse().find((entry) => entry.type === 'store');
const latestComponents = [...entries].reverse().find((entry) => entry.type === 'components');
const latestHeap = [...entries].reverse().find((entry) => entry.type === 'heap');
if (latestProcess) {
console.log(`Process RSS total: ${formatKb(latestProcess.payload.totalWorkingSetKb)}`);
}
if (latestHeap) {
console.log(`Renderer JS heap: ${latestHeap.payload.usedJsHeapMb ?? 'n/a'} MB`);
}
if (latestStore?.payload?.domains) {
console.log('Store domains (estimated bytes):');
for (const [domain, bytes] of Object.entries(latestStore.payload.domains).sort((a, b) => b[1] - a[1])) {
console.log(` ${domain}: ${bytes}`);
}
}
if (latestComponents?.payload?.domains) {
console.log('Live components by domain:');
for (const [domain, count] of Object.entries(latestComponents.payload.domains).sort((a, b) => b[1] - a[1])) {
console.log(` ${domain}: ${count}`);
}
}
const leaks = latestComponents?.payload?.suspectedLeaks;
if (Array.isArray(leaks) && leaks.length > 0) {
console.log('Suspected component leaks:');
for (const leak of leaks) {
console.log(` ${leak.name}: ${leak.count} (expected ${leak.expected})`);
}
}
}
function main() {
const dir = readArg('--dir') || resolveDefaultDiagnosticsDir();
const file = readArg('--file');
if (!fs.existsSync(dir) && !file) {
console.error(`Diagnostics directory not found: ${dir}`);
process.exit(1);
}
const targetFile = file || findLatestFile(dir);
if (!targetFile) {
console.error(`No diagnostics files found in ${dir}`);
process.exit(1);
}
console.log(`Reading ${targetFile}`);
if (hasFlag('--tail')) {
tailFile(targetFile);
return;
}
const entries = parseJsonLines(fs.readFileSync(targetFile, 'utf8'));
summarize(entries);
}
function findLatestFile(dir) {
if (!fs.existsSync(dir)) {
return null;
}
return fs.readdirSync(dir)
.filter((name) => name.startsWith('perf-') && name.endsWith('.jsonl'))
.map((name) => path.join(dir, name))
.sort((left, right) => fs.statSync(right).mtimeMs - fs.statSync(left).mtimeMs)[0] ?? null;
}
function tailFile(targetFile) {
let position = 0;
const printNewLines = () => {
const stats = fs.statSync(targetFile);
const nextSize = stats.size;
if (nextSize < position) {
position = 0;
}
if (nextSize === position) {
return;
}
const fd = fs.openSync(targetFile, 'r');
const length = nextSize - position;
const buffer = Buffer.alloc(length);
fs.readSync(fd, buffer, 0, length, position);
fs.closeSync(fd);
position = nextSize;
for (const line of buffer.toString('utf8').split('\n')) {
if (!line.trim()) {
continue;
}
try {
const entry = JSON.parse(line);
console.log(`[${entry.type}] ${JSON.stringify(entry.payload)}`);
} catch {
console.log(line);
}
}
};
printNewLines();
setInterval(printNewLines, 1000);
}
main();