@junejs/server 0.0.4 → 0.0.6
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 +4 -6
- package/src/app.ts +11 -0
- package/src/dev.ts +21 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@junejs/server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "June host adapters + dev server. Host-coupled; depends on the pure @junejs/core contract layer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,16 +29,14 @@
|
|
|
29
29
|
"typecheck": "tsc --noEmit"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@junejs/core": "0.0.
|
|
33
|
-
"marked": "^18.0.5"
|
|
32
|
+
"@junejs/core": "0.0.6",
|
|
33
|
+
"marked": "^18.0.5",
|
|
34
|
+
"rolldown": "^1.1.0"
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"react": "^19.2.0",
|
|
37
38
|
"react-dom": "^19.2.0"
|
|
38
39
|
},
|
|
39
|
-
"devDependencies": {
|
|
40
|
-
"rolldown": "^1.1.0"
|
|
41
|
-
},
|
|
42
40
|
"repository": {
|
|
43
41
|
"type": "git",
|
|
44
42
|
"url": "https://github.com/junebuild/june"
|
package/src/app.ts
CHANGED
|
@@ -138,6 +138,17 @@ export function createApp({ appDir: appDirInput, config = {} }: CreateAppOptions
|
|
|
138
138
|
new Response(code, {
|
|
139
139
|
headers: { "content-type": "text/javascript; charset=utf-8" },
|
|
140
140
|
}),
|
|
141
|
+
(err: unknown) => {
|
|
142
|
+
// A rejected bundle must answer, not hang the request (Bun.serve
|
|
143
|
+
// times the handler out) — and must not be memoized, or the error
|
|
144
|
+
// outlives its cause.
|
|
145
|
+
clientBundle = undefined;
|
|
146
|
+
console.error("[june] client bundle failed:", err);
|
|
147
|
+
return new Response(`client bundle failed: ${err instanceof Error ? err.message : String(err)}\n`, {
|
|
148
|
+
status: 500,
|
|
149
|
+
headers: { "content-type": "text/plain; charset=utf-8" },
|
|
150
|
+
});
|
|
151
|
+
},
|
|
141
152
|
);
|
|
142
153
|
}
|
|
143
154
|
return runWithTrace(newTrace(), async () => (await getPipeline()).fetch(request));
|
package/src/dev.ts
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
// work), load june.config.ts from the app root (the config the PoC forgot to
|
|
5
5
|
// read), build the app, and serve through the detected JuneHost.
|
|
6
6
|
|
|
7
|
+
import { createServer as createNetServer } from "node:net";
|
|
8
|
+
|
|
7
9
|
import { loadJuneConfig } from "./config-loader";
|
|
8
10
|
import { installAsyncContext } from "./instrumentation";
|
|
9
11
|
import { createApp } from "./app";
|
|
@@ -18,6 +20,21 @@ export type DevServerOptions = {
|
|
|
18
20
|
|
|
19
21
|
export type DevServer = ServeHandle & { url: string };
|
|
20
22
|
|
|
23
|
+
// A taken default port must not be a dead end in dev — walk forward until a
|
|
24
|
+
// port binds (the Vite convention). Probed with node:net, which both hosts
|
|
25
|
+
// implement, so the host interface stays untouched.
|
|
26
|
+
async function findFreePort(start: number, tries = 20): Promise<number> {
|
|
27
|
+
for (let p = start; p < start + tries; p++) {
|
|
28
|
+
const free = await new Promise<boolean>((resolve) => {
|
|
29
|
+
const probe = createNetServer();
|
|
30
|
+
probe.once("error", () => resolve(false));
|
|
31
|
+
probe.listen(p, () => probe.close(() => resolve(true)));
|
|
32
|
+
});
|
|
33
|
+
if (free) return p;
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`june dev: no free port between ${start} and ${start + tries - 1}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
21
38
|
export async function startDevServer({
|
|
22
39
|
appDir,
|
|
23
40
|
port = 3000,
|
|
@@ -28,6 +45,10 @@ export async function startDevServer({
|
|
|
28
45
|
const app = createApp({ appDir, config });
|
|
29
46
|
await app.warmup();
|
|
30
47
|
|
|
48
|
+
const freePort = await findFreePort(port);
|
|
49
|
+
if (freePort !== port) console.log(`[june] port ${port} is taken → using ${freePort}`);
|
|
50
|
+
port = freePort;
|
|
51
|
+
|
|
31
52
|
// Live reload wraps the DEV SERVER only — the pipeline (and therefore
|
|
32
53
|
// dev/built parity) never sees it. See dev-reload.ts.
|
|
33
54
|
const handle = host.serve(withLiveReload((req) => app.fetch(req)), {
|