@briancray/belte 0.5.0 → 0.5.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
package/src/bundleApp.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dirname } from 'node:path'
|
|
1
2
|
import { buildDisconnected } from './buildDisconnected.ts'
|
|
2
3
|
import { compile } from './compile.ts'
|
|
3
4
|
import { ensureWebviewLib } from './lib/bundle/ensureWebviewLib.ts'
|
|
@@ -11,6 +12,7 @@ import { exitOnBuildFailure } from './lib/shared/exitOnBuildFailure.ts'
|
|
|
11
12
|
import { loadSvelteConfig } from './lib/shared/loadSvelteConfig.ts'
|
|
12
13
|
import { log } from './lib/shared/log.ts'
|
|
13
14
|
import { programNameForPackage } from './lib/shared/programNameForPackage.ts'
|
|
15
|
+
import { shippedEnvPath } from './lib/shared/shippedEnvPath.ts'
|
|
14
16
|
import { serverBuildPlugins } from './serverBuildPlugins.ts'
|
|
15
17
|
|
|
16
18
|
const APP_ENTRY = new URL('./appEntry.ts', import.meta.url).pathname
|
|
@@ -57,15 +59,19 @@ export async function bundleApp({ cwd = process.cwd() }: { cwd?: string } = {}):
|
|
|
57
59
|
await compile({ cwd, target, outfile: `${binDir}/${serverBinaryFilename()}` })
|
|
58
60
|
|
|
59
61
|
/*
|
|
60
|
-
Opt-in: ship the project's `.env.bundle` as the
|
|
62
|
+
Opt-in: ship the project's `.env.bundle` as the shipped `.env`, which the
|
|
61
63
|
server loads at boot (loadEnvFromBinaryDir) as its default config layer. A
|
|
62
64
|
dedicated file, never the working `.env` — a compiled bundle is extractable,
|
|
63
65
|
so only ship-safe defaults belong here; user-specific/secret values come from
|
|
64
|
-
the data-dir `.env` instead.
|
|
66
|
+
the data-dir `.env` instead. shippedEnvPath places it under Contents/Resources
|
|
67
|
+
in a macOS `.app` (sealed as a resource, so it survives codesign) and beside
|
|
68
|
+
the binaries otherwise. Skipped when absent.
|
|
65
69
|
*/
|
|
66
70
|
const bundleEnv = Bun.file(`${cwd}/.env.bundle`)
|
|
67
71
|
if (await bundleEnv.exists()) {
|
|
68
|
-
|
|
72
|
+
const envPath = shippedEnvPath(binDir)
|
|
73
|
+
await Bun.$`mkdir -p ${dirname(envPath)}`.quiet()
|
|
74
|
+
await Bun.write(envPath, bundleEnv)
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
// 2. Connect screen — bake dist/bundle-disconnected.html before the launcher
|
|
@@ -9,10 +9,12 @@ import { resolveServerBinary } from './lib/bundle/resolveServerBinary.ts'
|
|
|
9
9
|
import { resolveWebviewLib } from './lib/bundle/resolveWebviewLib.ts'
|
|
10
10
|
import { stableLocalPort } from './lib/bundle/stableLocalPort.ts'
|
|
11
11
|
import { waitForServer } from './lib/bundle/waitForServer.ts'
|
|
12
|
+
import { parsePort } from './lib/server/runtime/parsePort.ts'
|
|
12
13
|
import { appDataDir } from './lib/shared/appDataDir.ts'
|
|
13
14
|
import { log } from './lib/shared/log.ts'
|
|
14
15
|
import { readEnvFile } from './lib/shared/readEnvFile.ts'
|
|
15
16
|
import { serializeEnv } from './lib/shared/serializeEnv.ts'
|
|
17
|
+
import { shippedEnvPath } from './lib/shared/shippedEnvPath.ts'
|
|
16
18
|
|
|
17
19
|
/*
|
|
18
20
|
The bundle's control server, run in a Worker so it owns its own thread.
|
|
@@ -160,9 +162,26 @@ Spawns the sibling server binary on a free port and waits for it to answer,
|
|
|
160
162
|
returning the URL to point the window at. Any previous child is reaped first so
|
|
161
163
|
only one embedded server runs at a time.
|
|
162
164
|
*/
|
|
165
|
+
/*
|
|
166
|
+
The port the embedded server binds. A `PORT` configured in the data-dir `.env`
|
|
167
|
+
(where the config form writes), the shipped binary-dir `.env`, or the launcher's
|
|
168
|
+
own env is honored — so the server answers at a fixed, known address another
|
|
169
|
+
machine can reliably connect to. With none set, a free port is chosen (the
|
|
170
|
+
historical behaviour). Precedence matches the server's own env stack: shell >
|
|
171
|
+
data-dir > binary-dir. A configured port is used as-is and not second-guessed —
|
|
172
|
+
if it's taken, the bind failure surfaces rather than silently moving.
|
|
173
|
+
*/
|
|
174
|
+
async function resolveEmbeddedPort(): Promise<number> {
|
|
175
|
+
const [dataDirEnv, binaryDirEnv] = await Promise.all([
|
|
176
|
+
readEnvFile(dataDirEnvPath()),
|
|
177
|
+
readEnvFile(binaryDirEnvPath()),
|
|
178
|
+
])
|
|
179
|
+
return parsePort(process.env.PORT ?? dataDirEnv.PORT ?? binaryDirEnv.PORT) ?? findFreePort()
|
|
180
|
+
}
|
|
181
|
+
|
|
163
182
|
async function startEmbeddedServer(timeoutMs?: number): Promise<string> {
|
|
164
183
|
killServerChild()
|
|
165
|
-
const port =
|
|
184
|
+
const port = await resolveEmbeddedPort()
|
|
166
185
|
const url = `http://localhost:${port}`
|
|
167
186
|
serverChild = Bun.spawn({
|
|
168
187
|
cmd: [resolveServerBinary()],
|
|
@@ -267,6 +286,13 @@ function dataDirEnvPath(): string {
|
|
|
267
286
|
return join(appDataDir(programName), '.env')
|
|
268
287
|
}
|
|
269
288
|
|
|
289
|
+
// The bundle's shipped `.env` (its default config layer), resolved from the binary
|
|
290
|
+
// directory — same source loadEnvFromBinaryDir reads at boot (dirname of the running
|
|
291
|
+
// binary): beside the binary in the flat layout, under Resources in a `.app`.
|
|
292
|
+
function binaryDirEnvPath(): string {
|
|
293
|
+
return shippedEnvPath(dirname(process.execPath))
|
|
294
|
+
}
|
|
295
|
+
|
|
270
296
|
/*
|
|
271
297
|
Resolves the value to pre-fill each config field with, following the same
|
|
272
298
|
precedence the server applies below the shell: the user's saved data-dir `.env`,
|
|
@@ -279,7 +305,7 @@ async function resolveConfigValues(): Promise<Record<string, string>> {
|
|
|
279
305
|
// Independent reads — fetch together; precedence is applied in the merge below.
|
|
280
306
|
const [dataDirEnv, binaryDirEnv] = await Promise.all([
|
|
281
307
|
readEnvFile(dataDirEnvPath()),
|
|
282
|
-
readEnvFile(
|
|
308
|
+
readEnvFile(binaryDirEnvPath()),
|
|
283
309
|
])
|
|
284
310
|
return Object.fromEntries(
|
|
285
311
|
Object.keys(properties).map((key) => {
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { dirname } from 'node:path'
|
|
2
2
|
import { loadEnvFile } from '../shared/loadEnvFile.ts'
|
|
3
|
+
import { shippedEnvPath } from '../shared/shippedEnvPath.ts'
|
|
3
4
|
|
|
4
5
|
/*
|
|
5
|
-
Loads
|
|
6
|
-
`process.execPath`)
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
Loads the bundle's shipped `.env` into `process.env`, resolved from the running
|
|
7
|
+
binary's directory (`process.execPath`) via shippedEnvPath — beside the binary in
|
|
8
|
+
the flat layout, under `Contents/Resources` in a macOS `.app`. This is the file the
|
|
9
|
+
install tarball ships beside the executable — and, for a bundle, the one `bundleApp`
|
|
10
|
+
copies from the project's `.env.bundle`. It carries the app's shipped defaults; the
|
|
9
11
|
fill-when-unset merge (see loadEnvFile) lets per-shell exports, Bun's CWD
|
|
10
12
|
`.env`, and the user's data-dir config all override it.
|
|
11
13
|
*/
|
|
12
14
|
export async function loadEnvFromBinaryDir(): Promise<void> {
|
|
13
|
-
await loadEnvFile(
|
|
15
|
+
await loadEnvFile(shippedEnvPath(dirname(process.execPath)))
|
|
14
16
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { basename, dirname, join } from 'node:path'
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
Path of the bundle's shipped `.env` — the default config layer written at build
|
|
5
|
+
time and read back at boot. Given the directory holding the binaries, returns
|
|
6
|
+
where that `.env` lives.
|
|
7
|
+
|
|
8
|
+
A macOS `.app` nests binaries under `Contents/MacOS`, but `codesign` seals that
|
|
9
|
+
directory as *code*: a data file there can't survive signing and reloading. So
|
|
10
|
+
for the `.app` layout the `.env` belongs beside the icon in `Contents/Resources`,
|
|
11
|
+
which is sealed as a resource. Every other platform keeps the flat layout, with
|
|
12
|
+
the `.env` next to the binaries. Pure: computes the path, never touches disk.
|
|
13
|
+
*/
|
|
14
|
+
export function shippedEnvPath(binaryDir: string): string {
|
|
15
|
+
const isMacAppBinaryDir =
|
|
16
|
+
basename(binaryDir) === 'MacOS' && basename(dirname(binaryDir)) === 'Contents'
|
|
17
|
+
if (isMacAppBinaryDir) {
|
|
18
|
+
return join(dirname(binaryDir), 'Resources', '.env')
|
|
19
|
+
}
|
|
20
|
+
return join(binaryDir, '.env')
|
|
21
|
+
}
|