@cosmicdrift/kumiko-dev-server 0.372.0 → 0.374.0
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/bin/kumiko-build.ts +11 -3
- package/dist/build-server-bundle.js +1 -0
- package/dist/build.d.ts +1 -0
- package/dist/build.js +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/write-server-lockfile.d.ts +15 -0
- package/dist/write-server-lockfile.js +47 -0
- package/package.json +9 -9
- package/src/changes.json +7 -0
- package/templates/deploy/Dockerfile.template +4 -3
package/bin/kumiko-build.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
//
|
|
4
4
|
// package.json "kumiko.clientEntries"/"kumiko.clientEntry",
|
|
5
5
|
// or src/client.tsx | src/styles.css | public/ → client bundle (dist/)
|
|
6
|
-
// bin/main.ts → server bundle (dist-server
|
|
6
|
+
// bin/main.ts → server bundle (dist-server/,
|
|
7
|
+
// incl. bun.lock seeded from the app's bun.lock)
|
|
7
8
|
//
|
|
8
9
|
// Both are built when their conventions match, otherwise skipped. A workspace
|
|
9
10
|
// with only bin/main.ts gets just the server bundle, a browser-only sample
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
// kumiko-build --entry bin/remote-probe.ts
|
|
22
23
|
|
|
23
24
|
import { existsSync } from "node:fs";
|
|
24
|
-
import { join, resolve } from "node:path";
|
|
25
|
+
import { join, relative, resolve } from "node:path";
|
|
25
26
|
import {
|
|
26
27
|
buildProdBundle,
|
|
27
28
|
buildServerBundle,
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
readClientEntriesConfig,
|
|
33
34
|
readExtraRuntimeExternals,
|
|
34
35
|
resolveClientEntries,
|
|
36
|
+
writeServerLockfile,
|
|
35
37
|
} from "@cosmicdrift/kumiko-dev-server/cli";
|
|
36
38
|
|
|
37
39
|
if (process.argv.slice(2).some((arg) => arg === "--help" || arg === "-h")) {
|
|
@@ -43,6 +45,7 @@ if (process.argv.slice(2).some((arg) => arg === "--help" || arg === "-h")) {
|
|
|
43
45
|
|
|
44
46
|
const red = "\x1b[31m";
|
|
45
47
|
const yellow = "\x1b[33m";
|
|
48
|
+
const dim = "\x1b[2m";
|
|
46
49
|
const reset = "\x1b[0m";
|
|
47
50
|
|
|
48
51
|
try {
|
|
@@ -85,8 +88,13 @@ try {
|
|
|
85
88
|
...(buildArgs.extraEntries.length > 0 && { extraEntries: buildArgs.extraEntries }),
|
|
86
89
|
});
|
|
87
90
|
const ms = Math.round(performance.now() - t0);
|
|
91
|
+
const lock = await writeServerLockfile({ cwd, outDir: result.outDir });
|
|
92
|
+
const lockLine =
|
|
93
|
+
lock.mode === "seeded"
|
|
94
|
+
? ` ${dim}bun.lock seeded from ${relative(cwd, lock.seedLockfile) || "bun.lock"}${reset}`
|
|
95
|
+
: ` ${yellow}!${reset} bun.lock resolved fresh – no bun.lock found above ${cwd}`;
|
|
88
96
|
// biome-ignore lint/suspicious/noConsole: CLI-Output, einziger Weg
|
|
89
|
-
console.log(formatServerBuildResult(result, ms));
|
|
97
|
+
console.log(`${formatServerBuildResult(result, ms)}\n${lockLine}`);
|
|
90
98
|
}
|
|
91
99
|
} catch (err) {
|
|
92
100
|
// biome-ignore lint/suspicious/noConsole: CLI-Output, einziger Weg
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
// <basename>.js ← one per extraEntries path
|
|
32
32
|
// chunk-*.js ← geteilte Framework-Chunks
|
|
33
33
|
// package.json ← runtime-deps mit gepinnten Versionen
|
|
34
|
+
// bun.lock ← written by writeServerLockfile (kumiko-build), not by buildServerBundle
|
|
34
35
|
//
|
|
35
36
|
// Externals — Pakete die NICHT ins Bundle gebakt werden, sondern via
|
|
36
37
|
// `bun install` im Runtime-Container nachgeholt werden:
|
package/dist/build.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { ASSETS_DIR, type BuildManifest, type BuildProdBundleOptions, type BuildResult, buildProdBundle, type ClientEntry, type ClientEntryDeclaration, discoverHtmlTemplate, formatBuildResult, injectAssetTags, readClientEntriesConfig, resolveClientEntries, } from "@cosmicdrift/kumiko-server-runtime/build-prod-bundle";
|
|
2
2
|
export { type BuildServerBundleEntry, type BuildServerBundleOptions, type BuildServerBundleResult, buildServerBundle, discoverServerEntry, formatServerBuildResult, type KumikoBuildArgs, parseKumikoBuildArgs, readExtraRuntimeExternals, } from "./build-server-bundle.ts";
|
|
3
|
+
export { type ServerLockfileResult, type WriteServerLockfileOptions, writeServerLockfile, } from "./write-server-lockfile.ts";
|
package/dist/build.js
CHANGED
|
@@ -3,3 +3,4 @@
|
|
|
3
3
|
// (z.B. wenn drizzle-kit die App-Config unter Node lädt).
|
|
4
4
|
export { ASSETS_DIR, buildProdBundle, discoverHtmlTemplate, formatBuildResult, injectAssetTags, readClientEntriesConfig, resolveClientEntries, } from "@cosmicdrift/kumiko-server-runtime/build-prod-bundle";
|
|
5
5
|
export { buildServerBundle, discoverServerEntry, formatServerBuildResult, parseKumikoBuildArgs, readExtraRuntimeExternals, } from "./build-server-bundle.js";
|
|
6
|
+
export { writeServerLockfile, } from "./write-server-lockfile.js";
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { buildProdBundle, buildServerBundle, discoverServerEntry, formatBuildResult, formatServerBuildResult, parseKumikoBuildArgs, readClientEntriesConfig, readExtraRuntimeExternals, resolveClientEntries, } from "./build.ts";
|
|
1
|
+
export { buildProdBundle, buildServerBundle, discoverServerEntry, formatBuildResult, formatServerBuildResult, parseKumikoBuildArgs, readClientEntriesConfig, readExtraRuntimeExternals, resolveClientEntries, writeServerLockfile, } from "./build.ts";
|
|
2
2
|
export { createCrashTracker } from "./crash-tracker.ts";
|
|
3
3
|
export { runInitDeployCli } from "./init-deploy-cli.ts";
|
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
// the package self-reference (`@cosmicdrift/kumiko-dev-server/cli`) so they
|
|
3
3
|
// resolve to src in the workspace and to dist once installed from the
|
|
4
4
|
// tarball, where `src` is not shipped.
|
|
5
|
-
export { buildProdBundle, buildServerBundle, discoverServerEntry, formatBuildResult, formatServerBuildResult, parseKumikoBuildArgs, readClientEntriesConfig, readExtraRuntimeExternals, resolveClientEntries, } from "./build.js";
|
|
5
|
+
export { buildProdBundle, buildServerBundle, discoverServerEntry, formatBuildResult, formatServerBuildResult, parseKumikoBuildArgs, readClientEntriesConfig, readExtraRuntimeExternals, resolveClientEntries, writeServerLockfile, } from "./build.js";
|
|
6
6
|
export { createCrashTracker } from "./crash-tracker.js";
|
|
7
7
|
export { runInitDeployCli } from "./init-deploy-cli.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type WriteServerLockfileOptions = {
|
|
2
|
+
/** App directory: the search for a seed bun.lock starts here and walks up. */
|
|
3
|
+
readonly cwd: string;
|
|
4
|
+
/** Server bundle directory holding the generated package.json. */
|
|
5
|
+
readonly outDir: string;
|
|
6
|
+
};
|
|
7
|
+
export type ServerLockfileResult = {
|
|
8
|
+
readonly lockfile: string;
|
|
9
|
+
} & ({
|
|
10
|
+
readonly mode: "seeded";
|
|
11
|
+
readonly seedLockfile: string;
|
|
12
|
+
} | {
|
|
13
|
+
readonly mode: "resolved";
|
|
14
|
+
});
|
|
15
|
+
export declare function writeServerLockfile(options: WriteServerLockfileOptions): Promise<ServerLockfileResult>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Pins dist-server/ to the dependency versions the app was tested with. The runtime image
|
|
2
|
+
// installs from dist-server/package.json, whose ranges alone resolve to whatever is newest
|
|
3
|
+
// on the registry at image-build time. Seeding the app's bun.lock keeps already-locked
|
|
4
|
+
// packages at their locked versions; packages the app lock does not carry resolve fresh.
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { copyFile } from "node:fs/promises";
|
|
7
|
+
import { dirname, join, resolve } from "node:path";
|
|
8
|
+
function findSeedLockfile(startDir) {
|
|
9
|
+
let dir = resolve(startDir);
|
|
10
|
+
for (;;) {
|
|
11
|
+
const candidate = join(dir, "bun.lock");
|
|
12
|
+
if (existsSync(candidate))
|
|
13
|
+
return candidate;
|
|
14
|
+
const parent = dirname(dir);
|
|
15
|
+
if (parent === dir)
|
|
16
|
+
return undefined;
|
|
17
|
+
dir = parent;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function writeServerLockfile(options) {
|
|
21
|
+
const outDir = resolve(options.outDir);
|
|
22
|
+
const lockfile = join(outDir, "bun.lock");
|
|
23
|
+
const seedLockfile = findSeedLockfile(options.cwd);
|
|
24
|
+
if (seedLockfile !== undefined)
|
|
25
|
+
await copyFile(seedLockfile, lockfile);
|
|
26
|
+
// process.execPath: the lock format has to match the Bun that built the bundle.
|
|
27
|
+
const install = Bun.spawn({
|
|
28
|
+
cmd: [process.execPath, "install", "--lockfile-only"],
|
|
29
|
+
cwd: outDir,
|
|
30
|
+
stdout: "pipe",
|
|
31
|
+
stderr: "pipe",
|
|
32
|
+
});
|
|
33
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
34
|
+
install.exited,
|
|
35
|
+
new Response(install.stdout).text(),
|
|
36
|
+
new Response(install.stderr).text(),
|
|
37
|
+
]);
|
|
38
|
+
if (exitCode !== 0) {
|
|
39
|
+
throw new Error(`bun install --lockfile-only failed in ${outDir} (exit ${exitCode}); shipping dist-server without a lockfile would leave runtime versions unpinned.\n${stderr.trim() || stdout.trim()}`);
|
|
40
|
+
}
|
|
41
|
+
if (!existsSync(lockfile)) {
|
|
42
|
+
throw new Error(`bun install --lockfile-only did not write ${lockfile}`);
|
|
43
|
+
}
|
|
44
|
+
return seedLockfile === undefined
|
|
45
|
+
? { mode: "resolved", lockfile }
|
|
46
|
+
: { mode: "seeded", seedLockfile, lockfile };
|
|
47
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-dev-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.374.0",
|
|
4
4
|
"description": "Dev-tooling for Kumiko apps: local dev-server bootstrap (runDevApp), scaffolding. Its compose-stacks/env-schema subpaths are consumed at prod boot too — see @cosmicdrift/kumiko-server-runtime for the prod runner itself.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -72,14 +72,14 @@
|
|
|
72
72
|
"kumiko-upgrade": "./bin/kumiko-upgrade.ts"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@cosmicdrift/kumiko-bundled-features": "0.
|
|
76
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
77
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
78
|
-
"@cosmicdrift/kumiko-renderer-mail-html": "0.
|
|
79
|
-
"@cosmicdrift/kumiko-renderer-web": "0.
|
|
80
|
-
"@cosmicdrift/kumiko-server-runtime": "0.
|
|
81
|
-
"@cosmicdrift/kumiko-testing": "0.
|
|
82
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
75
|
+
"@cosmicdrift/kumiko-bundled-features": "0.374.0",
|
|
76
|
+
"@cosmicdrift/kumiko-framework": "0.374.0",
|
|
77
|
+
"@cosmicdrift/kumiko-headless": "0.374.0",
|
|
78
|
+
"@cosmicdrift/kumiko-renderer-mail-html": "0.374.0",
|
|
79
|
+
"@cosmicdrift/kumiko-renderer-web": "0.374.0",
|
|
80
|
+
"@cosmicdrift/kumiko-server-runtime": "0.374.0",
|
|
81
|
+
"@cosmicdrift/kumiko-testing": "0.374.0",
|
|
82
|
+
"@cosmicdrift/kumiko-types": "0.374.0",
|
|
83
83
|
"bun-types": "^1.3.13",
|
|
84
84
|
"ts-morph": "^28.0.0",
|
|
85
85
|
"zod": "^4.4.3"
|
package/src/changes.json
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.373.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "kumiko-build pins dist-server dependencies with a bun.lock seeded from the app's bun.lock",
|
|
6
|
+
"detail": "The lock is written by writeServerLockfile after the bundle build and needs network or a warm Bun cache. The scaffolded Dockerfile runs bun install --production --frozen-lockfile in the runtime stage.",
|
|
7
|
+
"migration": "Apps with their own Dockerfile should run `bun install --production --frozen-lockfile` in dist-server instead of `bun install --production`."
|
|
8
|
+
},
|
|
2
9
|
{
|
|
3
10
|
"version": "0.372.0",
|
|
4
11
|
"type": "improvement",
|
|
@@ -60,10 +60,11 @@ WORKDIR /app
|
|
|
60
60
|
|
|
61
61
|
RUN addgroup -S app && adduser -S app -G app
|
|
62
62
|
|
|
63
|
-
# Server bundle + its minimal package.json
|
|
64
|
-
#
|
|
63
|
+
# Server bundle + its minimal package.json and the bun.lock kumiko-build wrote
|
|
64
|
+
# next to it. `--frozen-lockfile` installs exactly the locked externals and
|
|
65
|
+
# fails on drift instead of resolving newer versions.
|
|
65
66
|
COPY --from=build --chown=app:app /app/dist-server ./
|
|
66
|
-
RUN bun install --production
|
|
67
|
+
RUN bun install --production --frozen-lockfile
|
|
67
68
|
|
|
68
69
|
# Client build (static assets) — served by runProdApp.staticDir.
|
|
69
70
|
COPY --from=build --chown=app:app /app/dist ./dist
|