@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.
@@ -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 1).** Apps boot in waves, and the next wave starts only once the previous one
101
- reports ready. A cold boot build is the builder's peak, so booting `n` apps at once means `n` overlapping
102
- peaks — which is what OOM-kills a container that would have been fine with them staggered.
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
- if (type === "build") Object.assign(process.env, env);
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.97",
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.97",
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",