@ultimat3/cli 22.4.0 → 22.5.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/package.json +28 -28
- package/src/serve-boot.ts +5 -1
- package/src/serve-drain.ts +20 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/cli",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.5.0",
|
|
4
4
|
"description": "The `x` binary: new, dev, build, verify, generate, db, mcp, doctor, deploy",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -38,33 +38,33 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@babel/core": "^8.0.1",
|
|
41
|
-
"@ultimat3/action": "22.
|
|
42
|
-
"@ultimat3/admin": "22.
|
|
43
|
-
"@ultimat3/ai": "22.
|
|
44
|
-
"@ultimat3/auth": "22.
|
|
45
|
-
"@ultimat3/cache": "22.
|
|
46
|
-
"@ultimat3/core": "22.
|
|
47
|
-
"@ultimat3/db": "22.
|
|
48
|
-
"@ultimat3/entity": "22.
|
|
49
|
-
"@ultimat3/flags": "22.
|
|
50
|
-
"@ultimat3/http": "22.
|
|
51
|
-
"@ultimat3/i18n": "22.
|
|
52
|
-
"@ultimat3/jobs": "22.
|
|
53
|
-
"@ultimat3/mail": "22.
|
|
54
|
-
"@ultimat3/manifest": "22.
|
|
55
|
-
"@ultimat3/mcp": "22.
|
|
56
|
-
"@ultimat3/money": "22.
|
|
57
|
-
"@ultimat3/notify": "22.
|
|
58
|
-
"@ultimat3/policy": "22.
|
|
59
|
-
"@ultimat3/pwa": "22.
|
|
60
|
-
"@ultimat3/query": "22.
|
|
61
|
-
"@ultimat3/realtime": "22.
|
|
62
|
-
"@ultimat3/render": "22.
|
|
63
|
-
"@ultimat3/schema": "22.
|
|
64
|
-
"@ultimat3/seo": "22.
|
|
65
|
-
"@ultimat3/storage": "22.
|
|
66
|
-
"@ultimat3/testing": "22.
|
|
67
|
-
"@ultimat3/time": "22.
|
|
41
|
+
"@ultimat3/action": "22.5.0",
|
|
42
|
+
"@ultimat3/admin": "22.5.0",
|
|
43
|
+
"@ultimat3/ai": "22.5.0",
|
|
44
|
+
"@ultimat3/auth": "22.5.0",
|
|
45
|
+
"@ultimat3/cache": "22.5.0",
|
|
46
|
+
"@ultimat3/core": "22.5.0",
|
|
47
|
+
"@ultimat3/db": "22.5.0",
|
|
48
|
+
"@ultimat3/entity": "22.5.0",
|
|
49
|
+
"@ultimat3/flags": "22.5.0",
|
|
50
|
+
"@ultimat3/http": "22.5.0",
|
|
51
|
+
"@ultimat3/i18n": "22.5.0",
|
|
52
|
+
"@ultimat3/jobs": "22.5.0",
|
|
53
|
+
"@ultimat3/mail": "22.5.0",
|
|
54
|
+
"@ultimat3/manifest": "22.5.0",
|
|
55
|
+
"@ultimat3/mcp": "22.5.0",
|
|
56
|
+
"@ultimat3/money": "22.5.0",
|
|
57
|
+
"@ultimat3/notify": "22.5.0",
|
|
58
|
+
"@ultimat3/policy": "22.5.0",
|
|
59
|
+
"@ultimat3/pwa": "22.5.0",
|
|
60
|
+
"@ultimat3/query": "22.5.0",
|
|
61
|
+
"@ultimat3/realtime": "22.5.0",
|
|
62
|
+
"@ultimat3/render": "22.5.0",
|
|
63
|
+
"@ultimat3/schema": "22.5.0",
|
|
64
|
+
"@ultimat3/seo": "22.5.0",
|
|
65
|
+
"@ultimat3/storage": "22.5.0",
|
|
66
|
+
"@ultimat3/testing": "22.5.0",
|
|
67
|
+
"@ultimat3/time": "22.5.0",
|
|
68
68
|
"babel-preset-solid": "^1.9.15"
|
|
69
69
|
}
|
|
70
70
|
}
|
package/src/serve-boot.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// — are this file's.
|
|
5
5
|
|
|
6
6
|
import type { Role } from '@ultimat3/core';
|
|
7
|
+
import { configureLifecycle } from '@ultimat3/core';
|
|
7
8
|
import type { Route } from '@ultimat3/http';
|
|
8
9
|
import { describeRoutes } from '@ultimat3/render';
|
|
9
10
|
import { createIsrController } from '@ultimat3/render/server';
|
|
@@ -26,7 +27,7 @@ import { replicaOverrides } from './runtime-replica';
|
|
|
26
27
|
import type { RunningServices } from './runtime-services';
|
|
27
28
|
import { servedStorage, storageRoutes } from './runtime-storage';
|
|
28
29
|
import { seoRoutes } from './seo-routes';
|
|
29
|
-
import { loadDrainConfig } from './serve-drain';
|
|
30
|
+
import { loadDrainConfig, loadHealthConfig } from './serve-drain';
|
|
30
31
|
import { configureReporting, containerBinding, metricsPortFor, portFromEnv } from './serve-env';
|
|
31
32
|
import type { ServedApp, ServeOptions } from './serve-types';
|
|
32
33
|
import { loadSiteSettings, publicOrigin } from './site-config';
|
|
@@ -77,6 +78,9 @@ export async function bootRoles(boot: {
|
|
|
77
78
|
// still wins — that is the deploy talking.
|
|
78
79
|
const metricsPort = metricsPortFor(options.env, port, options.metricsPort);
|
|
79
80
|
const drain = await loadDrainConfig(options.root);
|
|
81
|
+
// Process-wide, so every role's `/readyz` — web, sync, worker — answers in the declared mode.
|
|
82
|
+
const health = await loadHealthConfig(options.root);
|
|
83
|
+
if (health?.readiness !== undefined) configureLifecycle({ readiness: health.readiness });
|
|
80
84
|
const replicaOverride = replicaOverrides(options.runtime, runtime.services.db, options.env);
|
|
81
85
|
const running = await startRoles({
|
|
82
86
|
roles: [role],
|
package/src/serve-drain.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
// `app.config.ts`'s `drain`
|
|
2
|
-
// config reader here makes (`theme-boot.ts`, `app-auth.ts`), because the config is a
|
|
1
|
+
// `app.config.ts`'s `drain` and `health` sections, read for the production boot — the same import
|
|
2
|
+
// every other config reader here makes (`theme-boot.ts`, `app-auth.ts`), because the config is a
|
|
3
|
+
// module. Both shape what `/readyz` tells the load balancer.
|
|
3
4
|
|
|
4
|
-
import type { DrainConfig } from '@ultimat3/core';
|
|
5
|
+
import type { DrainConfig, HealthConfig } from '@ultimat3/core';
|
|
5
6
|
import { APP_CONFIG_EXPORT } from './app-auth';
|
|
6
7
|
import { APP_CONFIG_FILE } from './app-root';
|
|
7
8
|
|
|
@@ -22,3 +23,19 @@ export async function loadDrainConfig(root: string): Promise<Partial<DrainConfig
|
|
|
22
23
|
if (!isRecord(drain) || !Object.hasOwn(drain, 'readinessGraceMs')) return undefined;
|
|
23
24
|
return { readinessGraceMs: drain['readinessGraceMs'] as number };
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* `health.readiness`, or `undefined` when the app declares none (core keeps `'dependencies'`). The
|
|
29
|
+
* value is handed to `configureLifecycle` as written, so a bad one is refused by core's own rule.
|
|
30
|
+
*/
|
|
31
|
+
export async function loadHealthConfig(root: string): Promise<Partial<HealthConfig> | undefined> {
|
|
32
|
+
const path = `${root}/${APP_CONFIG_FILE}`;
|
|
33
|
+
if (!(await Bun.file(path).exists())) return undefined;
|
|
34
|
+
const module = (await import(path)) as Record<string, unknown>;
|
|
35
|
+
const config = module[APP_CONFIG_EXPORT];
|
|
36
|
+
const health = isRecord(config)
|
|
37
|
+
? (config['health'] as Partial<HealthConfig> | undefined)
|
|
38
|
+
: undefined;
|
|
39
|
+
if (!isRecord(health) || health.readiness === undefined) return undefined;
|
|
40
|
+
return { readiness: health.readiness };
|
|
41
|
+
}
|