@akanjs/devkit 3.0.0-alpha.97 → 3.0.0-alpha.99
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/DEV_RUNTIME_KNOBS.md +11 -4
- package/executors.test.ts +5 -0
- package/executors.ts +9 -1
- package/package.json +2 -2
package/DEV_RUNTIME_KNOBS.md
CHANGED
|
@@ -97,12 +97,19 @@ sized against idle suspend being on**; setting it to `0` keeps every builder res
|
|
|
97
97
|
|
|
98
98
|
Two things bound the peak rather than the floor:
|
|
99
99
|
|
|
100
|
-
- **`--concurrency` (default
|
|
101
|
-
reports ready. A cold boot build is the builder's peak, so booting `n` apps at once
|
|
102
|
-
peaks — which is what OOM-kills a container that would have been fine with them
|
|
100
|
+
- **`--concurrency` (default: what the machine allows).** Apps boot in waves, and the next wave starts only
|
|
101
|
+
once the previous one reports ready. A cold boot build is the builder's peak, so booting `n` apps at once
|
|
102
|
+
means `n` overlapping peaks — which is what OOM-kills a container that would have been fine with them
|
|
103
|
+
staggered. Unset, the wave is `min(apps, half the memory budget / 900MB per app, cores / 4)`, never below
|
|
104
|
+
one, and the session prints which — so a laptop boots its apps together and a 1.2GB container still
|
|
105
|
+
staggers them. The memory budget is the smaller of the host's RAM and `AKAN_MEMORY_LIMIT` / the cgroup
|
|
106
|
+
limit; `os.freemem()` is not consulted, because it counts free pages rather than reclaimable ones and
|
|
107
|
+
reports ~0.3GB on an idle 48GB laptop.
|
|
103
108
|
- **`AKAN_MEMORY_LIMIT` is per process, not per session.** Each dev host derives its builder and RSC-worker
|
|
104
109
|
ceilings from it independently, so a limit sized for one app does not become a budget for four. Divide it
|
|
105
|
-
yourself, or leave it unset on a laptop.
|
|
110
|
+
yourself, or leave it unset on a laptop. The one place it is read as a session ceiling is the boot wave
|
|
111
|
+
above, and only downward: a session cannot outgrow the container it runs in, whatever each process inside
|
|
112
|
+
it was told it may take.
|
|
106
113
|
|
|
107
114
|
## Sizing a small sandbox
|
|
108
115
|
|
package/executors.test.ts
CHANGED
|
@@ -315,6 +315,11 @@ describe("Workspace and app executor environment contracts", () => {
|
|
|
315
315
|
const prepared = await app.prepareCommand("build");
|
|
316
316
|
expect(prepared.env.AKAN_COMMAND_TYPE).toBe("build");
|
|
317
317
|
expect(prepared.env.AKAN_PUBLIC_BASE_PATHS).toBe("admin");
|
|
318
|
+
// Bundling reads `process.env` through getPublicEnv and `define`s every AKAN_PUBLIC_* into a literal, so a
|
|
319
|
+
// dev port published here would be baked into the artifact and outrank the PORT the container is run with.
|
|
320
|
+
expect(process.env.AKAN_PUBLIC_APP_NAME).toBe("demo");
|
|
321
|
+
expect(process.env.AKAN_PUBLIC_CLIENT_PORT).toBeUndefined();
|
|
322
|
+
expect(process.env.AKAN_PUBLIC_SERVER_PORT).toBeUndefined();
|
|
318
323
|
expect((await stat(path.join(root, "dist/apps/demo/private"))).isDirectory()).toBe(true);
|
|
319
324
|
expect((await stat(path.join(root, "dist/apps/demo/public"))).isDirectory()).toBe(true);
|
|
320
325
|
});
|
package/executors.ts
CHANGED
|
@@ -1455,7 +1455,15 @@ export class AppExecutor extends SysExecutor {
|
|
|
1455
1455
|
// which filters to AKAN_PUBLIC_*) sees AKAN_PUBLIC_APP_NAME — otherwise SSR throws
|
|
1456
1456
|
// "environment variable AKAN_PUBLIC_APP_NAME is required". Only AKAN_PUBLIC_* is baked into bundles, so
|
|
1457
1457
|
// this does not leak non-public env.
|
|
1458
|
-
|
|
1458
|
+
// The port keys are this machine's dev allocation, and `define` turns an `AKAN_PUBLIC_*` into a literal the
|
|
1459
|
+
// artifact can never be run with a different value for — a baked port would outrank the `PORT` the container
|
|
1460
|
+
// is started with and send every SSR self-call to a port nothing bound.
|
|
1461
|
+
if (type === "build") {
|
|
1462
|
+
const buildEnv = { ...env };
|
|
1463
|
+
delete buildEnv.AKAN_PUBLIC_CLIENT_PORT;
|
|
1464
|
+
delete buildEnv.AKAN_PUBLIC_SERVER_PORT;
|
|
1465
|
+
Object.assign(process.env, buildEnv);
|
|
1466
|
+
}
|
|
1459
1467
|
return { env };
|
|
1460
1468
|
}
|
|
1461
1469
|
#publicEnv: Record<string, string> | null = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/devkit",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.99",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@langchain/openai": "^1.4.6",
|
|
45
45
|
"@tailwindcss/node": "^4.3.0",
|
|
46
46
|
"@trapezedev/project": "^7.1.4",
|
|
47
|
-
"akanjs": "3.0.0-alpha.
|
|
47
|
+
"akanjs": "3.0.0-alpha.99",
|
|
48
48
|
"chalk": "^5.6.2",
|
|
49
49
|
"commander": "^14.0.3",
|
|
50
50
|
"dayjs": "^1.11.20",
|