diff --git a/packages/natives/src/clipboard/index.ts b/packages/natives/src/clipboard/index.ts index 29201e366..d8ca51695 100644 --- a/packages/natives/src/clipboard/index.ts +++ b/packages/natives/src/clipboard/index.ts @@ -27,7 +27,7 @@ const hasDisplay = process.platform !== "linux" || Boolean(process.env.DISPLAY | */ export async function copyToClipboard(text: string): Promise { if (process.stdout.isTTY) { - const encoded = Buffer.from(text).toString("base64"); + const encoded = btoa(text); const osc52 = `\x1b]52;c;${encoded}\x07`; const onError = (err: unknown) => { process.stdout.off("error", onError); diff --git a/packages/stats/scripts/generate-client-bundle.ts b/packages/stats/scripts/generate-client-bundle.ts index 57bc28ab6..b9c3e2d42 100644 --- a/packages/stats/scripts/generate-client-bundle.ts +++ b/packages/stats/scripts/generate-client-bundle.ts @@ -5,7 +5,7 @@ import * as fs from "node:fs/promises"; import * as path from "node:path"; import * as os from "node:os"; -const GENERATED_FILE = path.join("src", "embedded-client.generated.ts"); +const GENERATED_FILE = path.join("src", "embedded-client.generated.txt"); const DIST_CLIENT_DIR = path.join("dist", "client"); function placeholderContent(): string { @@ -55,17 +55,6 @@ async function buildArchiveBase64(dir: string): Promise { } } -async function writeGeneratedBundle(base64Bundle: string): Promise { - const content = `/** - * Embedded stats dashboard bundle for compiled binaries. - * - * Generated by \`bun --cwd=packages/stats scripts/generate-client-bundle.ts\`. - */ -export const EMBEDDED_CLIENT_ARCHIVE_TAR_GZ_BASE64 = ${JSON.stringify(base64Bundle)}; -`; - await Bun.write(GENERATED_FILE, content); -} - async function main(): Promise { if (process.argv.includes("--reset")) { await Bun.write(GENERATED_FILE, placeholderContent()); @@ -75,7 +64,7 @@ async function main(): Promise { await $`bun run build`; const archiveBase64 = await buildArchiveBase64(DIST_CLIENT_DIR); - await writeGeneratedBundle(archiveBase64); + await Bun.write(GENERATED_FILE, archiveBase64); console.log(`Generated ${GENERATED_FILE}`); } diff --git a/packages/stats/src/embedded-client.generated.ts b/packages/stats/src/embedded-client.generated.ts deleted file mode 100644 index 1b560f034..000000000 --- a/packages/stats/src/embedded-client.generated.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Embedded stats dashboard bundle for compiled binaries. - * - * This file is generated by `bun --cwd=packages/stats scripts/generate-client-bundle.ts` during - * binary builds. The checked-in value is intentionally empty. - */ -export const EMBEDDED_CLIENT_ARCHIVE_TAR_GZ_BASE64 = ""; diff --git a/packages/stats/src/embedded-client.generated.txt b/packages/stats/src/embedded-client.generated.txt new file mode 100644 index 000000000..e69de29bb diff --git a/packages/stats/src/server.ts b/packages/stats/src/server.ts index 911e9b8e5..eac69d73f 100644 --- a/packages/stats/src/server.ts +++ b/packages/stats/src/server.ts @@ -10,7 +10,13 @@ import { getTotalMessageCount, syncAllSessions, } from "./aggregator"; -import { EMBEDDED_CLIENT_ARCHIVE_TAR_GZ_BASE64 } from "./embedded-client.generated"; +import embeddedClientArchiveTxt from "./embedded-client.generated.txt"; + +const getEmbeddedClientArchive = (() => { + const txt = embeddedClientArchiveTxt.replaceAll(/[\s\r\n]/g, "").trim(); + if (!txt) return null; + return () => Buffer.from(txt, "base64"); +})(); const CLIENT_DIR = path.join(import.meta.dir, "client"); const STATIC_DIR = path.join(import.meta.dir, "..", "dist", "client"); @@ -30,8 +36,7 @@ function sanitizeArchivePath(archivePath: string): string | null { return normalized; } -async function extractEmbeddedClientArchive(outputDir: string): Promise { - const archiveBytes = Buffer.from(EMBEDDED_CLIENT_ARCHIVE_TAR_GZ_BASE64, "base64"); +async function extractEmbeddedClientArchive(archiveBytes: Buffer, outputDir: string): Promise { const archive = new Bun.Archive(archiveBytes); const files = await archive.files(); const extractRoot = path.resolve(outputDir); @@ -49,13 +54,15 @@ async function extractEmbeddedClientArchive(outputDir: string): Promise { async function getCompiledClientDir(): Promise { if (!IS_BUN_COMPILED) return STATIC_DIR; - if (!EMBEDDED_CLIENT_ARCHIVE_TAR_GZ_BASE64) { - throw new Error("Compiled stats client bundle missing. Rebuild binary with embedded stats assets."); - } if (compiledClientDirPromise) return compiledClientDirPromise; + const archiveBytes = getEmbeddedClientArchive?.(); + if (!archiveBytes) { + throw new Error("Compiled stats client bundle missing. Rebuild binary with embedded stats assets."); + } + compiledClientDirPromise = (async () => { - const bundleHash = Bun.hash(EMBEDDED_CLIENT_ARCHIVE_TAR_GZ_BASE64).toString(16); + const bundleHash = Bun.hash(archiveBytes).toString(16); const outputDir = path.join(COMPILED_CLIENT_DIR_ROOT, bundleHash); const markerPath = path.join(outputDir, "index.html"); try { @@ -65,7 +72,7 @@ async function getCompiledClientDir(): Promise { await fs.rm(outputDir, { recursive: true, force: true }); await fs.mkdir(outputDir, { recursive: true }); - await extractEmbeddedClientArchive(outputDir); + await extractEmbeddedClientArchive(archiveBytes, outputDir); return outputDir; })(); @@ -73,19 +80,26 @@ async function getCompiledClientDir(): Promise { } async function getLatestMtime(dir: string): Promise { - let latest = 0; const entries = await fs.readdir(dir, { withFileTypes: true }); + const promises = []; for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { - latest = Math.max(latest, await getLatestMtime(fullPath)); + promises.push(getLatestMtime(fullPath)); } else if (entry.isFile()) { - const stats = await fs.stat(fullPath); - latest = Math.max(latest, stats.mtimeMs); + promises.push(fs.stat(fullPath).then(stats => stats.mtimeMs)); } } + let latest = 0; + await Promise.allSettled(promises).then(results => { + for (const result of results) { + if (result.status === "fulfilled") { + latest = Math.max(latest, result.value); + } + } + }); return latest; }