@briancray/belte 0.5.0 → 0.5.1

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": "@briancray/belte",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "description": "Isomorphic multimodal HTTP framework built for humans and machines in a single Bun runtime",
6
6
  "license": "MIT",
@@ -9,6 +9,7 @@ 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'
@@ -160,9 +161,26 @@ Spawns the sibling server binary on a free port and waits for it to answer,
160
161
  returning the URL to point the window at. Any previous child is reaped first so
161
162
  only one embedded server runs at a time.
162
163
  */
164
+ /*
165
+ The port the embedded server binds. A `PORT` configured in the data-dir `.env`
166
+ (where the config form writes), the shipped binary-dir `.env`, or the launcher's
167
+ own env is honored — so the server answers at a fixed, known address another
168
+ machine can reliably connect to. With none set, a free port is chosen (the
169
+ historical behaviour). Precedence matches the server's own env stack: shell >
170
+ data-dir > binary-dir. A configured port is used as-is and not second-guessed —
171
+ if it's taken, the bind failure surfaces rather than silently moving.
172
+ */
173
+ async function resolveEmbeddedPort(): Promise<number> {
174
+ const [dataDirEnv, binaryDirEnv] = await Promise.all([
175
+ readEnvFile(dataDirEnvPath()),
176
+ readEnvFile(binaryDirEnvPath()),
177
+ ])
178
+ return parsePort(process.env.PORT ?? dataDirEnv.PORT ?? binaryDirEnv.PORT) ?? findFreePort()
179
+ }
180
+
163
181
  async function startEmbeddedServer(timeoutMs?: number): Promise<string> {
164
182
  killServerChild()
165
- const port = findFreePort()
183
+ const port = await resolveEmbeddedPort()
166
184
  const url = `http://localhost:${port}`
167
185
  serverChild = Bun.spawn({
168
186
  cmd: [resolveServerBinary()],
@@ -267,6 +285,11 @@ function dataDirEnvPath(): string {
267
285
  return join(appDataDir(programName), '.env')
268
286
  }
269
287
 
288
+ // The shipped `.env` beside the server binary (the bundle's default config layer).
289
+ function binaryDirEnvPath(): string {
290
+ return join(dirname(resolveServerBinary()), '.env')
291
+ }
292
+
270
293
  /*
271
294
  Resolves the value to pre-fill each config field with, following the same
272
295
  precedence the server applies below the shell: the user's saved data-dir `.env`,
@@ -279,7 +302,7 @@ async function resolveConfigValues(): Promise<Record<string, string>> {
279
302
  // Independent reads — fetch together; precedence is applied in the merge below.
280
303
  const [dataDirEnv, binaryDirEnv] = await Promise.all([
281
304
  readEnvFile(dataDirEnvPath()),
282
- readEnvFile(join(dirname(resolveServerBinary()), '.env')),
305
+ readEnvFile(binaryDirEnvPath()),
283
306
  ])
284
307
  return Object.fromEntries(
285
308
  Object.keys(properties).map((key) => {