Skip to content

Commit b7e26b6

Browse files
perf(desktop): omit unused Cua SDK payloads
1 parent e69e1e9 commit b7e26b6

2 files changed

Lines changed: 93 additions & 21 deletions

File tree

‎scripts/build-desktop-artifact.test.ts‎

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as NodeCrypto from "node:crypto";
33
import * as NodePath from "node:path";
44

55
import * as NodeServices from "@effect/platform-node/NodeServices";
6-
import { createPackageWithOptions, extractFile, statFile } from "@electron/asar";
6+
import { createPackageWithOptions, extractFile, listPackage, statFile } from "@electron/asar";
77
import { vi } from "vite-plus/test";
88
import * as CuaRelease from "@t3tools/shared/cuaDriverRelease";
99
import { assert, it } from "@effect/vitest";
@@ -13,6 +13,7 @@ import * as Effect from "effect/Effect";
1313
import * as Layer from "effect/Layer";
1414
import * as Option from "effect/Option";
1515
import * as Path from "effect/Path";
16+
import * as Schema from "effect/Schema";
1617
import * as Sink from "effect/Sink";
1718
import * as Stream from "effect/Stream";
1819
import { ChildProcess, ChildProcessSpawner } from "effect/process";
@@ -45,6 +46,7 @@ import {
4546
MacPasskeySigningConfigurationResolutionError,
4647
MissingMacPasskeyProvisioningProfileError,
4748
packWindowsServerAsar,
49+
stageWindowsServerSidecar,
4850
preflightLinuxDesktopBuild,
4951
preflightMacDesktopBuild,
5052
preflightWindowsDesktopBuild,
@@ -401,22 +403,21 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {
401403
} else {
402404
const companions =
403405
platform === "win"
404-
? [
405-
"cua-driver.exe",
406-
"cua-driver-uia.exe",
407-
"cua-cursor-theme.exe",
408-
"cua_driver_sdk.dll",
409-
"cua_driver_node_runtime.node",
410-
]
406+
? ["cua-driver.exe", "cua-driver-uia.exe", "cua-cursor-theme.exe"]
411407
: [
412408
"cua-driver",
413409
"cua-cursor-theme",
414-
"libcua_driver_sdk.so",
415-
"cua_driver_node_runtime.node",
410+
"wayland-helper/README.md",
416411
"wayland-helper/install.sh",
417412
"wayland-helper/winrects@cua/metadata.json",
418413
"wayland-helper/winrects@cua/extension.js",
419414
];
415+
assert.deepStrictEqual(
416+
(yield* h.fs.readDirectory(destination)).sort(),
417+
platform === "win"
418+
? [...companions].sort()
419+
: ["cua-cursor-theme", "cua-driver", "wayland-helper"],
420+
);
420421
for (const member of companions) {
421422
assert.equal(yield* h.fs.readFileString(h.path.join(destination, member)), member);
422423
}
@@ -1193,7 +1194,7 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {
11931194
]);
11941195
});
11951196

1196-
it.effect("unpacks target Windows natives while excluding the other architecture", () =>
1197+
it.effect("stages Windows sidecar externals and unpacks target natives", () =>
11971198
Effect.scoped(
11981199
Effect.gen(function* () {
11991200
const fs = yield* FileSystem.FileSystem;
@@ -1211,15 +1212,60 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {
12111212
"node_modules/node-pty/prebuilds/linux-x64/pty.node",
12121213
];
12131214

1214-
for (const nativeFile of nativeFiles) {
1215-
const nativePath = path.join(sourceDir, nativeFile);
1216-
yield* fs.makeDirectory(path.dirname(nativePath), { recursive: true });
1217-
yield* fs.writeFileString(nativePath, nativeFile.includes("linux") ? "\x7fELF" : "MZ");
1218-
}
1219-
1215+
const decodeDependencies = Schema.decodeUnknownEffect(
1216+
Schema.fromJsonString(
1217+
Schema.Struct({ dependencies: Schema.Record(Schema.String, Schema.String) }),
1218+
),
1219+
);
1220+
const installSpawner = ChildProcessSpawner.make(() =>
1221+
Effect.gen(function* () {
1222+
const { dependencies } = yield* decodeDependencies(
1223+
yield* fs.readFileString(path.join(sourceDir, "package.json")),
1224+
).pipe(Effect.orDie);
1225+
const installedFiles = Object.keys(dependencies).map(
1226+
(name) => `node_modules/${name}/package.json`,
1227+
);
1228+
if (Object.hasOwn(dependencies, "node-pty")) installedFiles.push(...nativeFiles);
1229+
if (Object.hasOwn(dependencies, "@trycua/cua-driver")) {
1230+
installedFiles.push(
1231+
"node_modules/@trycua/cua-driver-win32-x64-msvc/cua_driver_sdk.dll",
1232+
);
1233+
}
1234+
for (const file of installedFiles) {
1235+
const filePath = path.join(sourceDir, file);
1236+
yield* fs.makeDirectory(path.dirname(filePath), { recursive: true });
1237+
yield* fs.writeFileString(filePath, file.includes("linux") ? "\x7fELF" : "MZ");
1238+
}
1239+
return mockProcess(0);
1240+
}),
1241+
);
1242+
const serverDistDir = path.join(tempDir, "dist");
1243+
yield* fs.makeDirectory(serverDistDir);
1244+
yield* fs.writeFileString(path.join(serverDistDir, "bin.mjs"), "console.log('server');");
12201245
const asarPath = path.join(tempDir, "server.asar");
1221-
yield* packWindowsServerAsar({ sourceDir, asarPath, arch: "x64" });
1246+
yield* stageWindowsServerSidecar({
1247+
stageRoot: tempDir,
1248+
repoRoot: tempDir,
1249+
serverDistDir,
1250+
arch: "x64",
1251+
appVersion: WINDOWS_PAYLOAD_FIXTURE_VERSION,
1252+
runtimeExternalDependencies: { "node-pty": "1.1.0", "@trycua/cua-driver": "0.34.1" },
1253+
fffNodeVersion: "0.9.4",
1254+
allowBuilds: {},
1255+
patchedDependencies: {},
1256+
overrides: {},
1257+
asarPath,
1258+
verbose: false,
1259+
}).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, installSpawner));
12221260
const unpackedRoot = `${asarPath}.unpacked`;
1261+
assert.deepStrictEqual(
1262+
(yield* decodeDependencies(extractFile(asarPath, "package.json").toString()))
1263+
.dependencies,
1264+
{ "node-pty": "1.1.0", "@ff-labs/fff-bin-win32-x64": "0.9.4" },
1265+
);
1266+
assert.isFalse(
1267+
listPackage(asarPath, { isPack: false }).some((file) => file.includes("@trycua")),
1268+
);
12231269

12241270
assert.isTrue(
12251271
yield* fs.exists(

‎scripts/build-desktop-artifact.ts‎

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,7 +2455,20 @@ export const stageCuaDriverExecutable = Effect.fn("stageCuaDriverExecutable")(fu
24552455
? ChildProcess.make("unzip", ["-q", archivePath, "-d", extracted])
24562456
: ChildProcess.make("tar", ["-xf", archivePath, "-C", extracted]);
24572457
yield* runCommand(command, { label: "extract Cua Driver", verbose: input.verbose });
2458-
for (const file of input.platform === "mac" ? [release.executable] : release.requiredFiles) {
2458+
const requiredFiles = [
2459+
release.executable,
2460+
...(input.platform === "win"
2461+
? ["cua-driver-uia.exe", "cua-cursor-theme.exe"]
2462+
: input.platform === "linux"
2463+
? [
2464+
"cua-cursor-theme",
2465+
"wayland-helper/install.sh",
2466+
"wayland-helper/winrects@cua/metadata.json",
2467+
"wayland-helper/winrects@cua/extension.js",
2468+
]
2469+
: []),
2470+
];
2471+
for (const file of requiredFiles) {
24592472
if ((yield* fs.stat(path.join(extracted, file))).type !== "File") {
24602473
return yield* new CuaDriverArtifactError({
24612474
message: `Cua Driver release is missing ${file}.`,
@@ -2469,7 +2482,15 @@ export const stageCuaDriverExecutable = Effect.fn("stageCuaDriverExecutable")(fu
24692482
yield* fs.copyFile(path.join(extracted, release.executable), destination);
24702483
yield* fs.chmod(destination, 0o755);
24712484
} else {
2472-
yield* fs.copy(extracted, destination);
2485+
yield* fs.makeDirectory(destination, { recursive: true });
2486+
// SDK libraries come from the app's npm dependencies, not this release.
2487+
const entries =
2488+
input.platform === "linux"
2489+
? [release.executable, "cua-cursor-theme", "wayland-helper"]
2490+
: requiredFiles;
2491+
for (const entry of entries) {
2492+
yield* fs.copy(path.join(extracted, entry), path.join(destination, entry));
2493+
}
24732494
if (input.platform === "linux") {
24742495
for (const executable of [release.executable, "cua-cursor-theme"]) {
24752496
yield* fs.chmod(path.join(destination, executable), 0o755);
@@ -3129,7 +3150,12 @@ export const stageWindowsServerSidecar = Effect.fn("stageWindowsServerSidecar")(
31293150
yield* fs.copy(input.serverDistDir, path.join(serverStageDir, "apps/server/dist"));
31303151

31313152
const sidecarDependencies = {
3132-
...input.runtimeExternalDependencies,
3153+
// The desktop host owns Cua; this server reaches it through telemetry IPC.
3154+
...Object.fromEntries(
3155+
Object.entries(input.runtimeExternalDependencies).filter(
3156+
([name]) => name !== "@trycua/cua-driver",
3157+
),
3158+
),
31333159
...resolveFffNativeDependencies("win", input.arch, input.fffNodeVersion),
31343160
};
31353161
const sidecarPatchedDependencies = createStagePatchedDependencies(

0 commit comments

Comments
 (0)