@nativedesktop/host 0.1.0 → 0.1.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nativedesktop/host",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Resolves the prebuilt NativeDesktop host binary for the current platform",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -12,16 +12,18 @@
12
12
  "homepage": "https://github.com/FormalSnake/NativeDesktop#readme",
13
13
  "bugs": "https://github.com/FormalSnake/NativeDesktop/issues",
14
14
  "publishConfig": {
15
- "access": "public"
16
- },
17
- "files": ["src"],
18
- "main": "./src/index.ts",
19
- "types": "./src/index.ts",
20
- "exports": {
21
- ".": "./src/index.ts"
22
- },
23
- "optionalDependencies": {
24
- "@nativedesktop/host-darwin-arm64": "0.1.0",
25
- "@nativedesktop/host-linux-x64": "0.1.0"
26
- }
15
+ "access": "public"
16
+ },
17
+ "files": [
18
+ "src"
19
+ ],
20
+ "main": "./src/index.ts",
21
+ "types": "./src/index.ts",
22
+ "exports": {
23
+ ".": "./src/index.ts"
24
+ },
25
+ "optionalDependencies": {
26
+ "@nativedesktop/host-darwin-arm64": "0.1.2",
27
+ "@nativedesktop/host-linux-x64": "0.1.2"
28
+ }
27
29
  }
package/src/index.test.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  // layout. Run with: bun test packages/host/
4
4
  import { test, expect } from "bun:test";
5
5
  import { resolve } from "node:path";
6
- import { hostBinaryCandidates, hostPackageName, hostPlatformKey, resolveBackend } from "./index.ts";
6
+ import { hostBinaryCandidates, hostPackageName, hostPlatformKey, resolveBackend, resolveHostBinary } from "./index.ts";
7
7
 
8
8
  // --- backend selection: platform × env × flag ------------------------------
9
9
 
@@ -82,3 +82,40 @@ test("hostPlatformKey rejects unsupported platforms", () => {
82
82
  expect(hostPlatformKey("darwin", "arm64")).toBe("darwin-arm64");
83
83
  expect(() => hostPlatformKey("sunos", "arm64")).toThrow(/unsupported platform/);
84
84
  });
85
+
86
+ // --- resolveHostBinary error path: gtk on macOS, installed (not a checkout) ---
87
+
88
+ test("ND_HOST_BINARY wins over resolution, and a missing path errors", async () => {
89
+ const self = resolve(import.meta.dir, "index.test.ts");
90
+ const prev = process.env.ND_HOST_BINARY;
91
+ try {
92
+ process.env.ND_HOST_BINARY = self;
93
+ // gtk+darwin has no prebuilt and this packageDir is no checkout, so every
94
+ // other arm of the resolver would throw.
95
+ expect(
96
+ await resolveHostBinary({ backend: "gtk", platform: "darwin", arch: "arm64", packageDir: "/tmp/not-a-checkout/node_modules/@nativedesktop/host" }),
97
+ ).toBe(self);
98
+
99
+ process.env.ND_HOST_BINARY = "/tmp/no-such-nd-host-binary";
100
+ const err = await resolveHostBinary({ backend: "gtk", platform: "linux", arch: "x64" }).catch((e: Error) => e);
101
+ expect((err as Error).message).toContain("ND_HOST_BINARY");
102
+ } finally {
103
+ if (prev === undefined) delete process.env.ND_HOST_BINARY;
104
+ else process.env.ND_HOST_BINARY = prev;
105
+ }
106
+ });
107
+
108
+ test("gtk on darwin outside a source checkout states the three real options", async () => {
109
+ // packageDir has no build.zig/swift two levels up, so isSourceCheckout is
110
+ // false -- the shape of an installed copy inside some other project's
111
+ // node_modules (packageName is already undefined for gtk+darwin regardless
112
+ // of packageDir, since PLATFORM_PACKAGES has no entry for it).
113
+ const err = await resolveHostBinary({ backend: "gtk", platform: "darwin", arch: "arm64", packageDir: "/tmp/not-a-checkout/node_modules/@nativedesktop/host" }).catch(
114
+ (e: Error) => e,
115
+ );
116
+ expect(err).toBeInstanceOf(Error);
117
+ const message = (err as Error).message;
118
+ expect(message).toContain("by design");
119
+ expect(message).toContain("source checkout");
120
+ expect(message).toContain("explicit binary path");
121
+ });
package/src/index.ts CHANGED
@@ -6,6 +6,10 @@
6
6
  // ND_BACKEND env var.
7
7
  //
8
8
  // How binaries get resolved:
9
+ // - ND_HOST_BINARY: an explicit path, ahead of everything else. For hosts
10
+ // where no prebuilt can run (NixOS rejects generic dynamically linked
11
+ // executables) or none ships (gtk on macOS), pointing at a source-built
12
+ // binary is the only way through `nd dev`, which resolves its own host.
9
13
  // - published install: the binary ships in a per-platform package
10
14
  // (@nativedesktop/host-darwin-arm64, @nativedesktop/host-linux-x64) listed
11
15
  // as optionalDependencies of this package, the Electron/esbuild model. npm
@@ -133,15 +137,25 @@ function isSourceCheckout(repoRoot: string): boolean {
133
137
  /**
134
138
  * Absolute path to the host binary for the requested backend, building it on
135
139
  * first run when inside a source checkout. Resolution order per backend:
140
+ * 0. ND_HOST_BINARY, an explicit path that wins outright
136
141
  * 1. prebuilt binary from the installed @nativedesktop/host-<os>-<arch> package
137
142
  * 2. (source checkout only) freshly built zig-out / swift .build artifacts
138
143
  * 3. (source checkout only) build the backend, then return the built artifact
139
144
  * Outside a checkout with no prebuilt, throws naming the missing platform
140
145
  * package (or the supported target list when none exists for this machine).
141
146
  */
142
- export async function resolveHostBinary(opts: { backend?: Backend } = {}): Promise<string> {
147
+ export async function resolveHostBinary(
148
+ opts: { backend?: Backend; platform?: string; arch?: string; packageDir?: string } = {},
149
+ ): Promise<string> {
150
+ const explicit = process.env.ND_HOST_BINARY;
151
+ if (explicit) {
152
+ if (!existsSync(explicit)) {
153
+ throw new Error(`@nativedesktop/host: ND_HOST_BINARY points at "${explicit}", which does not exist`);
154
+ }
155
+ return resolve(explicit);
156
+ }
143
157
  const backend = resolveBackend(opts);
144
- const { packageName, binaryName, repoRoot, fresh } = hostBinaryCandidates(backend);
158
+ const { packageName, binaryName, repoRoot, fresh } = hostBinaryCandidates(backend, opts);
145
159
  const prebuilt = prebuiltHostBinary(backend);
146
160
  const source = isSourceCheckout(repoRoot);
147
161
 
@@ -163,12 +177,26 @@ export async function resolveHostBinary(opts: { backend?: Backend } = {}): Promi
163
177
  return buildBackend(backend, repoRoot, fresh);
164
178
  }
165
179
 
180
+ const key = hostPlatformKey(opts.platform, opts.arch);
181
+ // gtk-on-macOS is the one combination that will never get a package entry
182
+ // (see PLATFORM_PACKAGES above), so the generic "unsupported target" hint
183
+ // below reads as a dead end instead of the three real ways forward. State
184
+ // them explicitly: this is by design, not missing packaging.
185
+ if (!packageName && backend === "gtk" && key.startsWith("darwin-")) {
186
+ throw new Error(
187
+ `@nativedesktop/host: no gtk host binary for "${key}". The gtk backend ships no macOS prebuilt ` +
188
+ `by design (it links Homebrew paths). Either build one from a NativeDesktop source checkout ` +
189
+ `(${backendBuildHint(backend)}), or pass an explicit binary path instead of resolving one ` +
190
+ `(ND_HOST_BINARY=<path>, or launchApp({ hostBinary }) in @nativedesktop/test).`,
191
+ );
192
+ }
166
193
  const hint = packageName
167
194
  ? `Expected ${packageName}/bin/${binaryName} (an optionalDependency of @nativedesktop/host); ` +
168
195
  `reinstall without --no-optional, or build in a NativeDesktop checkout (${backendBuildHint(backend)}).`
169
196
  : `No prebuilt package exists for this target; supported targets are darwin-arm64 (appkit) and ` +
170
- `linux-x64 (gtk). Build in a NativeDesktop checkout (${backendBuildHint(backend)}).`;
171
- throw new Error(`@nativedesktop/host: no ${backend} host binary for "${hostPlatformKey()}". ${hint}`);
197
+ `linux-x64 (gtk). Build in a NativeDesktop checkout (${backendBuildHint(backend)}) and point ` +
198
+ `ND_HOST_BINARY at it.`;
199
+ throw new Error(`@nativedesktop/host: no ${backend} host binary for "${key}". ${hint}`);
172
200
  }
173
201
 
174
202
  function backendBuildHint(backend: Backend): string {