@oh-my-pi/omp-stats 12.7.6 → 12.8.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/package.json +4 -3
- package/src/server.ts +8 -74
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/omp-stats",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.8.0",
|
|
4
4
|
"description": "Local observability dashboard for pi AI usage statistics",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -52,8 +52,9 @@
|
|
|
52
52
|
"url": "https://github.com/can1357/oh-my-pi/issues"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@oh-my-pi/pi-ai": "12.
|
|
56
|
-
"@oh-my-pi/pi-utils": "12.
|
|
55
|
+
"@oh-my-pi/pi-ai": "12.8.0",
|
|
56
|
+
"@oh-my-pi/pi-utils": "12.8.0",
|
|
57
|
+
"@tailwindcss/node": "4",
|
|
57
58
|
"chart.js": "4.5.1",
|
|
58
59
|
"date-fns": "^4.1.0",
|
|
59
60
|
"lucide-react": "^0.564.0",
|
package/src/server.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import { $ } from "bun";
|
|
5
5
|
import {
|
|
6
6
|
getDashboardStats,
|
|
7
7
|
getRecentErrors,
|
|
@@ -12,33 +12,6 @@ import {
|
|
|
12
12
|
} from "./aggregator";
|
|
13
13
|
import { EMBEDDED_CLIENT_ARCHIVE_TAR_GZ_BASE64 } from "./embedded-client.generated";
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
* Extract Tailwind class names from source files by scanning for className attributes.
|
|
17
|
-
*/
|
|
18
|
-
async function extractTailwindClasses(dir: string): Promise<Set<string>> {
|
|
19
|
-
const classes = new Set<string>();
|
|
20
|
-
const classPattern = /className\s*=\s*["'`]([^"'`]+)["'`]/g;
|
|
21
|
-
async function scanDir(currentDir: string): Promise<void> {
|
|
22
|
-
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
23
|
-
for (const entry of entries) {
|
|
24
|
-
const fullPath = path.join(currentDir, entry.name);
|
|
25
|
-
if (entry.isDirectory()) {
|
|
26
|
-
await scanDir(fullPath);
|
|
27
|
-
} else if (entry.isFile() && /\.(tsx|ts|jsx|js)$/.test(entry.name)) {
|
|
28
|
-
const content = await Bun.file(fullPath).text();
|
|
29
|
-
const matches = content.matchAll(classPattern);
|
|
30
|
-
for (const match of matches) {
|
|
31
|
-
for (const cls of match[1].split(/\s+/)) {
|
|
32
|
-
if (cls) classes.add(cls);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
await scanDir(dir);
|
|
39
|
-
return classes;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
15
|
const CLIENT_DIR = path.join(import.meta.dir, "client");
|
|
43
16
|
const STATIC_DIR = path.join(import.meta.dir, "..", "dist", "client");
|
|
44
17
|
const IS_BUN_COMPILED =
|
|
@@ -99,33 +72,6 @@ async function getCompiledClientDir(): Promise<string> {
|
|
|
99
72
|
return compiledClientDirPromise;
|
|
100
73
|
}
|
|
101
74
|
|
|
102
|
-
async function buildTailwindCss(inputPath: string, outputPath: string): Promise<void> {
|
|
103
|
-
const sourceCss = await Bun.file(inputPath).text();
|
|
104
|
-
const clientDir = path.dirname(inputPath);
|
|
105
|
-
const candidates = await extractTailwindClasses(clientDir);
|
|
106
|
-
const compiler = await compile(sourceCss, {
|
|
107
|
-
base: clientDir,
|
|
108
|
-
loadStylesheet: async (id: string, base: string) => {
|
|
109
|
-
if (id === "tailwindcss/index.css" || id === "tailwindcss") {
|
|
110
|
-
const tailwindPath = require.resolve("tailwindcss/index.css", { paths: [base] });
|
|
111
|
-
return {
|
|
112
|
-
path: tailwindPath,
|
|
113
|
-
base: path.dirname(tailwindPath),
|
|
114
|
-
content: await Bun.file(tailwindPath).text(),
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
const resolved = path.resolve(base, id);
|
|
118
|
-
return {
|
|
119
|
-
path: resolved,
|
|
120
|
-
base: path.dirname(resolved),
|
|
121
|
-
content: await Bun.file(resolved).text(),
|
|
122
|
-
};
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
const result = compiler.build([...candidates]);
|
|
126
|
-
await Bun.write(outputPath, result);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
75
|
async function getLatestMtime(dir: string): Promise<number> {
|
|
130
76
|
let latest = 0;
|
|
131
77
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
@@ -174,25 +120,13 @@ const ensureClientBuild = async () => {
|
|
|
174
120
|
|
|
175
121
|
await fs.rm(STATIC_DIR, { recursive: true, force: true });
|
|
176
122
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
console.log("Building React app...");
|
|
186
|
-
const result = await Bun.build({
|
|
187
|
-
entrypoints: [path.join(CLIENT_DIR, "index.tsx")],
|
|
188
|
-
outdir: STATIC_DIR,
|
|
189
|
-
minify: true,
|
|
190
|
-
naming: "[dir]/[name].[ext]",
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
if (!result.success) {
|
|
194
|
-
const errors = result.logs.map(log => log.message).join("\n");
|
|
195
|
-
throw new Error(`Failed to build stats client:\n${errors}`);
|
|
123
|
+
console.log("Building stats client...");
|
|
124
|
+
const packageRoot = path.join(import.meta.dir, "..");
|
|
125
|
+
const buildResult = await $`bun run build.ts`.cwd(packageRoot).quiet().nothrow();
|
|
126
|
+
if (buildResult.exitCode !== 0) {
|
|
127
|
+
const output = buildResult.text().trim();
|
|
128
|
+
const details = output ? `\n${output}` : "";
|
|
129
|
+
throw new Error(`Failed to build stats client (exit ${buildResult.exitCode})${details}`);
|
|
196
130
|
}
|
|
197
131
|
|
|
198
132
|
const indexHtml = `<!DOCTYPE html>
|