mirror of
https://github.com/aphrody-labs/bun-distribution.git
synced 2026-10-13 23:56:39 +00:00
workspace: centralize desktop outputs and verified root dependency installs
This commit is contained in:
1 parent
1e5c6435ff
commit
32e9d4cc2c
12 files changed
+106
-15
No files matched your search
+2
-2
@@ -3,13 +3,13 @@
|
||||
"runtime": {
|
||||
"version": "1.4.4",
|
||||
"repository": "aphrody-labs/bun",
|
||||
"revision": "c62d01d81506a8b78b1d39b44d17edc81b4a6355"
|
||||
"revision": "cb64a09ae6dd618efc300c39b9b03ccfa861cac2"
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"windows-x64": {
|
||||
"version": "1.4.4",
|
||||
"repository": "aphrody-labs/bun",
|
||||
"revision": "c62d01d81506a8b78b1d39b44d17edc81b4a6355"
|
||||
"revision": "cb64a09ae6dd618efc300c39b9b03ccfa861cac2"
|
||||
},
|
||||
"linux-x64": {
|
||||
"version": "1.4.4",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { join, resolve } from "node:path";
|
||||
import { join } from "node:path";
|
||||
import { loadConfig, assertRuntime, repositoryRoot } from "@aphrody/bun-workspace";
|
||||
import { capabilityFor, type Catalog } from "./shared.ts";
|
||||
import { nativeVideoCapabilities } from "@aphrody/bun-video-project/native";
|
||||
|
||||
export const desktopRoot = import.meta.dir;
|
||||
export const desktopOutput = join(repositoryRoot, "build/apps/desktop");
|
||||
|
||||
export async function buildDesktop() {
|
||||
const config = await loadConfig(repositoryRoot);
|
||||
@@ -25,7 +26,7 @@ export async function buildDesktop() {
|
||||
};
|
||||
const web = await Bun.build({
|
||||
entrypoints: [join(desktopRoot, "src/app.ts")],
|
||||
outdir: join(desktopRoot, "dist/web"),
|
||||
outdir: join(desktopOutput, "web"),
|
||||
target: "browser",
|
||||
format: "esm",
|
||||
minify: true,
|
||||
@@ -33,19 +34,19 @@ export async function buildDesktop() {
|
||||
});
|
||||
if (!web.success) throw new AggregateError(web.logs, "Bun frontend build failed");
|
||||
await Promise.all([
|
||||
Bun.write(join(desktopRoot, "dist/web/index.html"), Bun.file(join(desktopRoot, "src/index.html"))),
|
||||
Bun.write(join(desktopRoot, "dist/web/style.css"), Bun.file(join(desktopRoot, "src/style.css"))),
|
||||
Bun.write(join(desktopOutput, "web/index.html"), Bun.file(join(desktopRoot, "src/index.html"))),
|
||||
Bun.write(join(desktopOutput, "web/style.css"), Bun.file(join(desktopRoot, "src/style.css"))),
|
||||
]);
|
||||
const server = await Bun.build({
|
||||
entrypoints: [join(desktopRoot, "server.ts")],
|
||||
outdir: join(desktopRoot, "dist"),
|
||||
outdir: desktopOutput,
|
||||
target: "bun",
|
||||
format: "esm",
|
||||
minify: true,
|
||||
});
|
||||
if (!server.success) throw new AggregateError(server.logs, "Bun backend build failed");
|
||||
console.log("Aphrody: " + catalog.libraries.length + " libraries bundled.");
|
||||
return resolve(desktopRoot, "dist");
|
||||
return desktopOutput;
|
||||
}
|
||||
|
||||
if (import.meta.main) await buildDesktop();
|
||||
@@ -50,7 +50,7 @@ if (command === "build") {
|
||||
target: "bun",
|
||||
minify: true,
|
||||
compile: {
|
||||
outfile: join(desktopRoot, "src-tauri/binaries", filename),
|
||||
outfile: join(output, "native", filename),
|
||||
autoloadDotenv: false,
|
||||
autoloadBunfig: false,
|
||||
autoloadPackageJson: false,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"dependencies": {
|
||||
"@aphrody/bun-video-project": "workspace:*",
|
||||
"@aphrody/bun-workspace": "workspace:*",
|
||||
"@aphrody/tauri": "file:../../toolchains/bun/packages/bun-tauri"
|
||||
"@aphrody/tauri": "catalog:"
|
||||
},
|
||||
"engines": {
|
||||
"bun": "1.4.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "aphrody-bun-desktop"
|
||||
version = "0.1.0"
|
||||
version = "1.4.4"
|
||||
description = "Aphrody desktop library inspector"
|
||||
authors = ["aphrody-dev <contact@aphrody.com>"]
|
||||
edition = "2024"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"productName": "Aphrody",
|
||||
"version": "0.1.0",
|
||||
"version": "1.4.4",
|
||||
"identifier": "com.aphrody.bun",
|
||||
"build": { "frontendDist": "../dist/web" },
|
||||
"build": { "frontendDist": "../../../build/apps/desktop/web" },
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
@@ -22,7 +22,7 @@
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"externalBin": ["binaries/aphrody-server"],
|
||||
"externalBin": ["../../../build/apps/desktop/native/aphrody-server"],
|
||||
"icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"]
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
"@aphrody/bun-artifacts": "workspace:*",
|
||||
"@aphrody/bun-video-project": "workspace:*",
|
||||
"@aphrody/bun-workspace": "workspace:*",
|
||||
"@aphrody/tauri": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aphrody/bun-types": "1.4.4",
|
||||
@@ -20,12 +21,15 @@
|
||||
"dependencies": {
|
||||
"@aphrody/bun-video-project": "workspace:*",
|
||||
"@aphrody/bun-workspace": "workspace:*",
|
||||
"@aphrody/tauri": "file:../../toolchains/bun/packages/bun-tauri",
|
||||
"@aphrody/tauri": "catalog:",
|
||||
},
|
||||
},
|
||||
"packages/bun-app-host": {
|
||||
"name": "@aphrody/bun-app-host",
|
||||
"version": "1.4.4",
|
||||
"bin": {
|
||||
"aphrody-server": "./src/cli.ts",
|
||||
},
|
||||
"dependencies": {
|
||||
"@aphrody/bun-artifacts": "workspace:*",
|
||||
"@aphrody/bun-video-project": "workspace:*",
|
||||
@@ -81,6 +85,9 @@
|
||||
},
|
||||
},
|
||||
},
|
||||
"catalog": {
|
||||
"@aphrody/tauri": "file:toolchains/bun/packages/bun-tauri",
|
||||
},
|
||||
"packages": {
|
||||
"@aphrody/bun-app-host": ["@aphrody/bun-app-host@workspace:packages/bun-app-host"],
|
||||
|
||||
@@ -96,6 +103,8 @@
|
||||
|
||||
"@aphrody/bun-workspace": ["@aphrody/bun-workspace@workspace:packages/bun-workspace"],
|
||||
|
||||
"@aphrody/tauri": ["@aphrody/tauri@file:toolchains/bun/packages/bun-tauri", {}],
|
||||
|
||||
"@bun-os/package-converter": ["@bun-os/package-converter@workspace:packages/package-converter"],
|
||||
|
||||
"@types/node": ["@types/node@26.6.5", "", { "dependencies": { "undici-types": "~8.9.0" } }, "sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg=="],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[install]
|
||||
exact = true
|
||||
linker = "hoisted"
|
||||
|
||||
[run]
|
||||
shell = "bun"
|
||||
@@ -60,11 +60,15 @@
|
||||
"workspace:manifests": "bun scripts/workspace-manifests.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aphrody/tauri": "catalog:",
|
||||
"@aphrody/bun-workspace": "workspace:*",
|
||||
"@aphrody/bun-artifacts": "workspace:*",
|
||||
"@aphrody/bun-video-project": "workspace:*",
|
||||
"@aphrody/bun-app-host": "workspace:*"
|
||||
},
|
||||
"catalog": {
|
||||
"@aphrody/tauri": "file:toolchains/bun/packages/bun-tauri"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aphrody/bun-types": "1.4.4"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bun
|
||||
/** Retire redundant workspace installs after proving the root package owner. */
|
||||
import { lstat, readdir, realpath, rm } from "node:fs/promises";
|
||||
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
||||
import { runProcess } from "../packages/bun-workspace/src/process.ts";
|
||||
|
||||
const root = resolve(import.meta.dir, "..");
|
||||
const product = await Bun.file(join(root, "package.json")).json();
|
||||
const members: string[] = product.workspaces;
|
||||
for (const member of members) {
|
||||
const directory = resolve(root, member, "node_modules");
|
||||
const within = relative(root, directory);
|
||||
if (
|
||||
isAbsolute(within) ||
|
||||
within.startsWith(".." + sep) ||
|
||||
within === ".." ||
|
||||
directory === join(root, "node_modules")
|
||||
)
|
||||
throw new Error("Workspace install target is outside the product root.");
|
||||
const info = await lstat(directory).catch(error => {
|
||||
if (error.code === "ENOENT") return undefined;
|
||||
throw error;
|
||||
});
|
||||
if (!info || info.isSymbolicLink()) continue;
|
||||
const resolvedParent = relative(root, await realpath(dirname(directory)));
|
||||
if (isAbsolute(resolvedParent) || resolvedParent.startsWith(".." + sep) || resolvedParent === "..")
|
||||
throw new Error("Workspace install target resolves outside the product root.");
|
||||
const packageDirectories: { name: string; path: string }[] = [];
|
||||
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
||||
if (entry.name === ".bin") continue;
|
||||
if (entry.name.startsWith("@")) {
|
||||
for (const scoped of await readdir(join(directory, entry.name)))
|
||||
packageDirectories.push({ name: `${entry.name}/${scoped}`, path: join(directory, entry.name, scoped) });
|
||||
} else packageDirectories.push({ name: entry.name, path: join(directory, entry.name) });
|
||||
}
|
||||
for (const installed of packageDirectories) {
|
||||
const canonical = join(root, "node_modules", installed.name);
|
||||
const [local, shared] = await Promise.all([
|
||||
Bun.file(join(installed.path, "package.json")).json(),
|
||||
Bun.file(join(canonical, "package.json")).json(),
|
||||
]);
|
||||
if (local.name !== shared.name || local.version !== shared.version)
|
||||
throw new Error(`Root package does not replace ${installed.name}.`);
|
||||
if (!(await lstat(installed.path)).isSymbolicLink()) {
|
||||
for (const path of new Bun.Glob("**/*").scanSync({ cwd: installed.path, onlyFiles: true, dot: true })) {
|
||||
const source = Bun.file(join(installed.path, path));
|
||||
const target = Bun.file(join(canonical, path));
|
||||
if (
|
||||
!(await target.exists()) ||
|
||||
(await source.arrayBuffer()).byteLength !== target.size ||
|
||||
Bun.CryptoHasher.hash("sha256", await source.arrayBuffer(), "hex") !==
|
||||
Bun.CryptoHasher.hash("sha256", await target.arrayBuffer(), "hex")
|
||||
)
|
||||
throw new Error(`Root package differs from workspace package ${installed.name}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (process.platform === "win32") {
|
||||
const removed = await runProcess(
|
||||
[
|
||||
"powershell.exe",
|
||||
"-NoProfile",
|
||||
"-NonInteractive",
|
||||
"-Command",
|
||||
"& { param([string]$target) Remove-Item -LiteralPath $target -Recurse -ErrorAction Stop }",
|
||||
directory,
|
||||
],
|
||||
root,
|
||||
{ timeoutMs: 30_000, maxOutputBytes: 1024 * 1024 },
|
||||
);
|
||||
if (removed.code !== 0) throw new Error("Workspace install cleanup failed.");
|
||||
} else await rm(directory, { recursive: true });
|
||||
console.log(`Root node_modules now owns ${member}`);
|
||||
}
|
||||
@@ -24,5 +24,6 @@ async function run(argv: string[]): Promise<void> {
|
||||
|
||||
await run(["git", "submodule", "update", "--init", "--depth", "1"]);
|
||||
await run([process.execPath, "install", "--frozen-lockfile"]);
|
||||
await run([process.execPath, "scripts/node-modules.ts"]);
|
||||
const cargo = await inspectCargoWorkspace(await loadConfig(root), { root, timeoutMs: 60_000 });
|
||||
console.log(`Cargo workspace: ${cargo.packageNames.length} packages in ${cargo.workspaceRoot}`);
|
||||
@@ -16,6 +16,7 @@ for (const entry of [{ path: "package.json", manifest: product }, ...entries]) {
|
||||
for (const field of ["dependencies", "devDependencies", "optionalDependencies"]) {
|
||||
for (const name of Object.keys(entry.manifest[field] ?? {})) {
|
||||
if (names.has(name)) entry.manifest[field][name] = "workspace:*";
|
||||
else if (Object.hasOwn(product.catalog ?? {}, name)) entry.manifest[field][name] = "catalog:";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user