@nylorun/runtime 0.10.0-beta → 0.12.0-beta

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.
Files changed (194) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +53 -51
  3. package/dist/adapters/execution/restate.d.ts +130 -0
  4. package/dist/adapters/execution/restate.js +442 -0
  5. package/dist/adapters/sandbox/virtual.js +1 -1
  6. package/dist/adapters/streams/s2.d.ts +18 -0
  7. package/dist/adapters/streams/s2.js +361 -0
  8. package/dist/core/executors.d.ts +4 -1
  9. package/dist/core/executors.js +20 -1
  10. package/dist/core/flow-host.d.ts +93 -132
  11. package/dist/core/flow-host.js +282 -547
  12. package/dist/core/sandbox-routes.d.ts +13 -4
  13. package/dist/core/sandbox-routes.js +14 -12
  14. package/dist/execution/memory.d.ts +54 -0
  15. package/dist/execution/memory.js +217 -0
  16. package/dist/execution/types.d.ts +125 -0
  17. package/dist/execution/types.js +52 -0
  18. package/dist/host/config-for.d.ts +2 -1
  19. package/dist/host/config-for.js +3 -21
  20. package/dist/host/config.d.ts +0 -8
  21. package/dist/host/create-host.d.ts +36 -1
  22. package/dist/host/create-host.js +51 -24
  23. package/dist/host/execution.d.ts +61 -0
  24. package/dist/host/execution.js +69 -0
  25. package/dist/host/http.d.ts +4 -0
  26. package/dist/host/http.js +6 -0
  27. package/dist/host/index.d.ts +3 -1
  28. package/dist/host/index.js +2 -0
  29. package/dist/host/main.js +106 -47
  30. package/dist/host/stack-config.d.ts +72 -0
  31. package/dist/host/stack-config.js +193 -0
  32. package/dist/index.d.ts +1 -1
  33. package/dist/infra/database.d.ts +16 -0
  34. package/dist/infra/database.js +31 -0
  35. package/dist/infra/execution.d.ts +39 -0
  36. package/dist/infra/execution.js +68 -0
  37. package/dist/infra/index.d.ts +42 -0
  38. package/dist/infra/index.js +56 -0
  39. package/dist/infra/readiness.d.ts +33 -0
  40. package/dist/infra/readiness.js +53 -0
  41. package/dist/infra/streams.d.ts +17 -0
  42. package/dist/infra/streams.js +33 -0
  43. package/dist/infra/workers.d.ts +39 -0
  44. package/dist/infra/workers.js +31 -0
  45. package/dist/model/pi-model.d.ts +2 -2
  46. package/dist/model/pi-model.js +5 -5
  47. package/dist/sandbox/manager.d.ts +26 -8
  48. package/dist/sandbox/manager.js +95 -47
  49. package/dist/sandbox/select.d.ts +1 -1
  50. package/dist/sandbox/select.js +4 -5
  51. package/dist/sandbox/types.d.ts +2 -2
  52. package/dist/store/canonical.d.ts +5 -0
  53. package/dist/store/canonical.js +17 -0
  54. package/dist/store/cursor.d.ts +9 -0
  55. package/dist/store/cursor.js +18 -0
  56. package/dist/store/memory.d.ts +57 -0
  57. package/dist/store/memory.js +645 -0
  58. package/dist/store/ownership.d.ts +19 -0
  59. package/dist/store/ownership.js +33 -0
  60. package/dist/store/postgres/connect.d.ts +25 -0
  61. package/dist/store/postgres/connect.js +25 -0
  62. package/dist/store/postgres/locking.d.ts +16 -0
  63. package/dist/store/postgres/locking.js +22 -0
  64. package/dist/store/postgres/migrations/001_initial.d.ts +27 -0
  65. package/dist/store/postgres/migrations/001_initial.js +196 -0
  66. package/dist/store/postgres/migrations/002_session_owner.d.ts +6 -0
  67. package/dist/store/postgres/migrations/002_session_owner.js +13 -0
  68. package/dist/store/postgres/migrations/index.d.ts +49 -0
  69. package/dist/store/postgres/migrations/index.js +76 -0
  70. package/dist/store/postgres/names.d.ts +11 -0
  71. package/dist/store/postgres/names.js +42 -0
  72. package/dist/store/postgres/store.d.ts +11 -0
  73. package/dist/store/postgres/store.js +797 -0
  74. package/dist/store/postgres/tenants.d.ts +90 -0
  75. package/dist/store/postgres/tenants.js +214 -0
  76. package/dist/store/types.d.ts +442 -0
  77. package/dist/store/types.js +10 -0
  78. package/dist/streams/basin.d.ts +23 -0
  79. package/dist/streams/basin.js +51 -0
  80. package/dist/streams/memory.d.ts +25 -0
  81. package/dist/streams/memory.js +124 -0
  82. package/dist/streams/relay.d.ts +37 -0
  83. package/dist/streams/relay.js +254 -0
  84. package/dist/streams/types.d.ts +115 -0
  85. package/dist/streams/types.js +86 -0
  86. package/dist/tenant/actions.d.ts +153 -0
  87. package/dist/tenant/actions.js +191 -0
  88. package/dist/tenant/advance.d.ts +15 -0
  89. package/dist/tenant/advance.js +439 -0
  90. package/dist/tenant/auth.d.ts +32 -0
  91. package/dist/tenant/auth.js +169 -0
  92. package/dist/tenant/commands.d.ts +3 -0
  93. package/dist/tenant/commands.js +393 -0
  94. package/dist/tenant/context.d.ts +147 -0
  95. package/dist/tenant/context.js +48 -0
  96. package/dist/tenant/effects.d.ts +20 -0
  97. package/dist/tenant/effects.js +564 -0
  98. package/dist/tenant/envelope.d.ts +0 -3
  99. package/dist/tenant/envelope.js +2 -34
  100. package/dist/tenant/ephemeral.d.ts +15 -4
  101. package/dist/tenant/ephemeral.js +106 -38
  102. package/dist/tenant/http.d.ts +38 -0
  103. package/dist/tenant/http.js +53 -0
  104. package/dist/tenant/live.d.ts +92 -0
  105. package/dist/tenant/live.js +290 -0
  106. package/dist/tenant/model-setting.d.ts +16 -0
  107. package/dist/tenant/model-setting.js +12 -0
  108. package/dist/tenant/module.d.ts +29 -8
  109. package/dist/tenant/module.js +165 -158
  110. package/dist/tenant/paths.d.ts +12 -8
  111. package/dist/tenant/paths.js +38 -12
  112. package/dist/tenant/principals.d.ts +12 -13
  113. package/dist/tenant/principals.js +50 -38
  114. package/dist/tenant/quarantine-error.d.ts +1 -1
  115. package/dist/tenant/quarantine-error.js +2 -8
  116. package/dist/tenant/quarantine.d.ts +0 -8
  117. package/dist/tenant/quarantine.js +8 -30
  118. package/dist/tenant/reset.d.ts +7 -6
  119. package/dist/tenant/reset.js +7 -51
  120. package/dist/tenant/routes-tenant.d.ts +12 -0
  121. package/dist/tenant/routes-tenant.js +137 -0
  122. package/dist/tenant/routes.d.ts +9 -0
  123. package/dist/tenant/routes.js +151 -0
  124. package/dist/tenant/runtime.d.ts +59 -58
  125. package/dist/tenant/runtime.js +243 -2201
  126. package/dist/tenant/scheduler.d.ts +25 -0
  127. package/dist/tenant/scheduler.js +84 -0
  128. package/dist/tenant/session.d.ts +60 -0
  129. package/dist/tenant/session.js +94 -0
  130. package/dist/tenant/sessions.d.ts +40 -0
  131. package/dist/tenant/sessions.js +163 -0
  132. package/dist/tenant/status.d.ts +13 -4
  133. package/dist/tenant/status.js +76 -41
  134. package/dist/tenant/store-memory.d.ts +9 -12
  135. package/dist/tenant/store-memory.js +79 -68
  136. package/dist/tenant/store-pg.d.ts +15 -0
  137. package/dist/tenant/store-pg.js +140 -0
  138. package/dist/tenant/streams.d.ts +126 -0
  139. package/dist/tenant/streams.js +419 -0
  140. package/dist/tenant/sweep.d.ts +15 -0
  141. package/dist/tenant/sweep.js +122 -0
  142. package/dist/tenant/transcript.d.ts +104 -0
  143. package/dist/tenant/transcript.js +58 -0
  144. package/dist/tenant/types.d.ts +101 -15
  145. package/dist/tenant/types.js +23 -1
  146. package/dist/tenant/worker.d.ts +84 -0
  147. package/dist/tenant/worker.js +189 -0
  148. package/dist/vault/service.d.ts +44 -31
  149. package/dist/vault/service.js +454 -360
  150. package/dist/version.d.ts +1 -1
  151. package/dist/version.js +1 -1
  152. package/package.json +15 -14
  153. package/dist/adapters/sandbox/microsandbox.d.ts +0 -2
  154. package/dist/adapters/sandbox/microsandbox.js +0 -238
  155. package/dist/core/store.d.ts +0 -32
  156. package/dist/core/store.js +0 -143
  157. package/dist/launcher/commands.d.ts +0 -24
  158. package/dist/launcher/commands.js +0 -260
  159. package/dist/launcher/ensure-config.d.ts +0 -16
  160. package/dist/launcher/ensure-config.js +0 -79
  161. package/dist/launcher/errors.d.ts +0 -12
  162. package/dist/launcher/errors.js +0 -22
  163. package/dist/launcher/host-config.d.ts +0 -17
  164. package/dist/launcher/host-config.js +0 -64
  165. package/dist/launcher/host-state.d.ts +0 -17
  166. package/dist/launcher/host-state.js +0 -61
  167. package/dist/launcher/lifecycle.d.ts +0 -66
  168. package/dist/launcher/lifecycle.js +0 -407
  169. package/dist/launcher/locks.d.ts +0 -26
  170. package/dist/launcher/locks.js +0 -117
  171. package/dist/launcher/logs.d.ts +0 -18
  172. package/dist/launcher/logs.js +0 -117
  173. package/dist/launcher/main.d.ts +0 -2
  174. package/dist/launcher/main.js +0 -66
  175. package/dist/launcher/output.d.ts +0 -11
  176. package/dist/launcher/output.js +0 -68
  177. package/dist/launcher/paths.d.ts +0 -20
  178. package/dist/launcher/paths.js +0 -36
  179. package/dist/launcher/probe.d.ts +0 -23
  180. package/dist/launcher/probe.js +0 -72
  181. package/dist/launcher/protocol.d.ts +0 -62
  182. package/dist/launcher/protocol.js +0 -1
  183. package/dist/launcher/schema-guard.d.ts +0 -6
  184. package/dist/launcher/schema-guard.js +0 -36
  185. package/dist/launcher/spawn.d.ts +0 -22
  186. package/dist/launcher/spawn.js +0 -85
  187. package/dist/launcher/status.d.ts +0 -6
  188. package/dist/launcher/status.js +0 -65
  189. package/dist/tenant/migration.d.ts +0 -16
  190. package/dist/tenant/migration.js +0 -116
  191. package/dist/tenant/schema.d.ts +0 -23
  192. package/dist/tenant/schema.js +0 -151
  193. package/dist/tenant/store-fs.d.ts +0 -16
  194. package/dist/tenant/store-fs.js +0 -205
@@ -1,66 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Launcher process entry: the `nylorun-runtime` bin of `@nylorun/runtime`.
4
- *
5
- * The only file under runtime/src/launcher/ allowed to read ambient process/OS
6
- * state (process.env, process.cwd(), os.homedir(), os.tmpdir()). Values are
7
- * resolved here and passed down explicitly.
8
- */
9
- import { homedir } from "node:os";
10
- import { resolve } from "node:path";
11
- import { runLauncher } from "./commands.js";
12
- function resolveHome(env) {
13
- const fromEnv = env.NYLORUN_HOME;
14
- if (fromEnv !== undefined && fromEnv.trim() !== "")
15
- return resolve(fromEnv);
16
- return resolve(homedir(), ".nylorun");
17
- }
18
- /** Copy allowlisted ambient keys for Host spawn (Tenants §12). */
19
- function baselineFromEnv(env) {
20
- const out = {};
21
- for (const key of Object.keys(env)) {
22
- if (key === "PATH" || key === "LANG" || key === "TZ" || key.startsWith("LC_")) {
23
- out[key] = env[key];
24
- }
25
- }
26
- // Release/dev smokes set NYLORUN_DEV_MODEL=fixture; pass through so the Host
27
- // can open Tenants with the credential-free fixture provider.
28
- const devModel = env.NYLORUN_DEV_MODEL?.trim();
29
- if (devModel)
30
- out.NYLORUN_DEV_MODEL = devModel;
31
- return out;
32
- }
33
- export async function main(argv = process.argv.slice(2), env = process.env) {
34
- return runLauncher(argv, {
35
- home: resolveHome(env),
36
- platform: process.platform,
37
- // The Host runs on the same Node as the launcher; no Node is bundled.
38
- nodeBinary: process.execPath,
39
- nodeVersion: process.versions.node,
40
- baselineEnv: baselineFromEnv(env),
41
- sink: {
42
- json: false,
43
- stdout: (line) => {
44
- process.stdout.write(`${line}\n`);
45
- },
46
- stderr: (line) => {
47
- process.stderr.write(`${line}\n`);
48
- },
49
- },
50
- });
51
- }
52
- const entry = process.argv[1];
53
- // Windows argv paths use backslashes; normalize before suffix checks so the
54
- // npm `.cmd` shim (`node.exe …\launcher\main.js`) still counts as the entry.
55
- // POSIX npm installs link `bin/nylorun-runtime` to this file.
56
- const normalizedEntry = entry?.replaceAll("\\", "/");
57
- const isEntry = normalizedEntry !== undefined &&
58
- (normalizedEntry.endsWith("launcher/main.ts") ||
59
- normalizedEntry.endsWith("launcher/main.js") ||
60
- normalizedEntry.endsWith("nylorun-runtime") ||
61
- normalizedEntry.endsWith("nylorun-runtime.cmd"));
62
- if (isEntry) {
63
- main().then((code) => {
64
- process.exitCode = code;
65
- });
66
- }
@@ -1,11 +0,0 @@
1
- import { LauncherError, UsageError } from "./errors.js";
2
- import type { LauncherEvent } from "./protocol.js";
3
- export interface OutputSink {
4
- stdout: (line: string) => void;
5
- stderr: (line: string) => void;
6
- json: boolean;
7
- }
8
- export declare function emitEvent(sink: OutputSink, event: LauncherEvent): void;
9
- export declare function emitResult(sink: OutputSink, fields: Record<string, unknown>): void;
10
- export declare function emitError(sink: OutputSink, error: LauncherError | UsageError | Error): void;
11
- export declare function exitCodeFor(error: unknown): 1 | 2;
@@ -1,68 +0,0 @@
1
- import { LauncherError, UsageError } from "./errors.js";
2
- export function emitEvent(sink, event) {
3
- if (sink.json) {
4
- sink.stdout(JSON.stringify(event));
5
- return;
6
- }
7
- switch (event.type) {
8
- case "progress": {
9
- const parts = [event.phase];
10
- if (event.message)
11
- parts.push(event.message);
12
- sink.stderr(parts.join(" "));
13
- return;
14
- }
15
- case "result": {
16
- sink.stdout(JSON.stringify(event, null, 2));
17
- return;
18
- }
19
- case "error": {
20
- sink.stderr(`${event.message}\n${event.remedy}`);
21
- return;
22
- }
23
- case "log": {
24
- if (event.source === "tenant" && event.tenantId) {
25
- sink.stdout(`[${event.tenantId}] ${event.line}`);
26
- }
27
- else {
28
- sink.stdout(event.line);
29
- }
30
- return;
31
- }
32
- }
33
- }
34
- export function emitResult(sink, fields) {
35
- emitEvent(sink, { type: "result", ...fields });
36
- }
37
- export function emitError(sink, error) {
38
- if (error instanceof LauncherError) {
39
- emitEvent(sink, {
40
- type: "error",
41
- code: error.code,
42
- message: error.message,
43
- remedy: error.remedy,
44
- ...(error.details !== undefined ? { details: error.details } : {}),
45
- });
46
- return;
47
- }
48
- if (error instanceof UsageError) {
49
- // Usage is exit 2. No ErrorCode fits; print message+remedy on stderr even
50
- // with --json so we do not mint a fake registry code.
51
- const text = error.remedy
52
- ? `${error.message}\n${error.remedy}`
53
- : error.message;
54
- sink.stderr(text);
55
- return;
56
- }
57
- emitEvent(sink, {
58
- type: "error",
59
- code: "launcher_failed",
60
- message: error.message,
61
- remedy: "Retry the command. If it keeps failing, check runtime.log.",
62
- });
63
- }
64
- export function exitCodeFor(error) {
65
- if (error instanceof UsageError)
66
- return 2;
67
- return 1;
68
- }
@@ -1,20 +0,0 @@
1
- /** Layout under the Host root (matches design D§3.6). */
2
- export interface HostPaths {
3
- root: string;
4
- config: string;
5
- state: string;
6
- credentials: string;
7
- log: string;
8
- home: string;
9
- tmp: string;
10
- tenants: string;
11
- trash: string;
12
- lifecycleLock: string;
13
- }
14
- export declare function hostPaths(hostRoot: string): HostPaths;
15
- export declare function ensureHostLayout(paths: HostPaths): Promise<void>;
16
- export declare function ensureDirSync(path: string): void;
17
- export declare function hostUrl(config: {
18
- host: string;
19
- port: number;
20
- }): string;
@@ -1,36 +0,0 @@
1
- import { existsSync, mkdirSync } from "node:fs";
2
- import { mkdir } from "node:fs/promises";
3
- import { join, resolve } from "node:path";
4
- export function hostPaths(hostRoot) {
5
- const root = resolve(hostRoot);
6
- return {
7
- root,
8
- config: join(root, "host.json"),
9
- state: join(root, "host-state.json"),
10
- credentials: join(root, "host-credentials.json"),
11
- log: join(root, "runtime.log"),
12
- home: join(root, "home"),
13
- tmp: join(root, "tmp"),
14
- tenants: join(root, "tenants"),
15
- trash: join(root, "trash"),
16
- lifecycleLock: join(root, ".lifecycle.lock"),
17
- };
18
- }
19
- export async function ensureHostLayout(paths) {
20
- for (const dir of [
21
- paths.root,
22
- paths.home,
23
- paths.tmp,
24
- paths.tenants,
25
- paths.trash,
26
- ]) {
27
- await mkdir(dir, { recursive: true, mode: 0o700 });
28
- }
29
- }
30
- export function ensureDirSync(path) {
31
- if (!existsSync(path))
32
- mkdirSync(path, { recursive: true, mode: 0o700 });
33
- }
34
- export function hostUrl(config) {
35
- return `http://${config.host}:${config.port}`;
36
- }
@@ -1,23 +0,0 @@
1
- import { processAlive } from "./locks.js";
2
- export interface ProbeHealthResult {
3
- reachable: boolean;
4
- health?: {
5
- status: string;
6
- service: string;
7
- version?: string;
8
- hostId?: string;
9
- pid?: number;
10
- protocol?: {
11
- min: number;
12
- max: number;
13
- features: string[];
14
- };
15
- };
16
- /** Something answered but is not a Nylorun Runtime Host. */
17
- foreign?: boolean;
18
- }
19
- export declare function probeHostHealth(url: string, timeoutMs?: number): Promise<ProbeHealthResult>;
20
- /** True when the address accepts a new listen (nothing bound). */
21
- export declare function portBindable(host: string, port: number): Promise<boolean>;
22
- export declare function probeReady(url: string, timeoutMs?: number): Promise<boolean>;
23
- export { processAlive };
@@ -1,72 +0,0 @@
1
- import { createServer } from "node:net";
2
- import { processAlive } from "./locks.js";
3
- export async function probeHostHealth(url, timeoutMs = 2000) {
4
- const signal = AbortSignal.timeout(timeoutMs);
5
- let response;
6
- try {
7
- response = await fetch(`${url}/health`, { signal });
8
- }
9
- catch {
10
- return { reachable: false };
11
- }
12
- if (!response.ok)
13
- return { reachable: true, foreign: true };
14
- try {
15
- const body = (await response.json());
16
- if (body?.status !== "ok" || typeof body.service !== "string") {
17
- return { reachable: true, foreign: true };
18
- }
19
- if (body.service !== "oss-runtime" && body.service !== "nylorun-runtime") {
20
- return { reachable: true, foreign: true };
21
- }
22
- const protocol = body.protocol;
23
- return {
24
- reachable: true,
25
- health: {
26
- status: "ok",
27
- service: body.service,
28
- ...(typeof body.version === "string" ? { version: body.version } : {}),
29
- ...(typeof body.hostId === "string" ? { hostId: body.hostId } : {}),
30
- ...(typeof body.pid === "number" ? { pid: body.pid } : {}),
31
- ...(protocol &&
32
- typeof protocol.min === "number" &&
33
- typeof protocol.max === "number" &&
34
- Array.isArray(protocol.features)
35
- ? {
36
- protocol: {
37
- min: protocol.min,
38
- max: protocol.max,
39
- features: protocol.features.map(String),
40
- },
41
- }
42
- : {}),
43
- },
44
- };
45
- }
46
- catch {
47
- return { reachable: true, foreign: true };
48
- }
49
- }
50
- /** True when the address accepts a new listen (nothing bound). */
51
- export async function portBindable(host, port) {
52
- const server = createServer();
53
- return await new Promise((resolvePromise) => {
54
- server.once("error", () => resolvePromise(false));
55
- server.listen(port, host, () => server.close(() => resolvePromise(true)));
56
- });
57
- }
58
- export async function probeReady(url, timeoutMs = 2000) {
59
- try {
60
- const response = await fetch(`${url}/ready`, {
61
- signal: AbortSignal.timeout(timeoutMs),
62
- });
63
- if (!response.ok)
64
- return false;
65
- const body = (await response.json());
66
- return body.status === "ready";
67
- }
68
- catch {
69
- return false;
70
- }
71
- }
72
- export { processAlive };
@@ -1,62 +0,0 @@
1
- import type { ErrorCode, ProtocolRange } from "@nylorun/core/compatibility";
2
- export type LauncherEvent = {
3
- type: "progress";
4
- phase: "start" | "stop" | "wait";
5
- message?: string;
6
- } | {
7
- type: "result";
8
- [field: string]: unknown;
9
- } | {
10
- type: "error";
11
- code: ErrorCode;
12
- message: string;
13
- remedy: string;
14
- details?: unknown;
15
- } | {
16
- type: "log";
17
- source: "host" | "tenant";
18
- tenantId?: string;
19
- line: string;
20
- };
21
- export interface UpResult {
22
- url: string;
23
- hostId: string;
24
- pid: number;
25
- version: string;
26
- started: boolean;
27
- }
28
- export interface DownResult {
29
- stopped: boolean;
30
- }
31
- export interface StatusResult {
32
- launcherProtocol: 1;
33
- home: string;
34
- state: "running" | "stopped" | "absent" | "unresponsive" | "foreign-port";
35
- url?: string;
36
- hostId?: string;
37
- pid?: number;
38
- version?: string;
39
- runtimeVersion?: string;
40
- /** Version of the installed `@nylorun/runtime` running this launcher. */
41
- launcherVersion: string;
42
- }
43
- /** `nylorun-runtime version`: what is installed and what it speaks. */
44
- export interface VersionResult {
45
- runtimeVersion: string;
46
- launcherProtocol: 1;
47
- protocol: ProtocolRange;
48
- node: string;
49
- }
50
- export interface HostConfigFileV1 {
51
- format: 1;
52
- hostId: string;
53
- host: string;
54
- port: number;
55
- runtimeVersion?: string;
56
- allowNonLoopback?: boolean;
57
- proxy?: {
58
- httpsProxy?: string;
59
- noProxy?: string;
60
- nodeExtraCaCerts?: string;
61
- };
62
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,6 +0,0 @@
1
- import type { HostPaths } from "./paths.js";
2
- /**
3
- * Every tenants/<id>/tenant.json schemaVersion must be at most the target
4
- * installed Runtime's Tenant schema.
5
- */
6
- export declare function assertSchemaGuard(paths: HostPaths, tenantSchemaMax: number): void;
@@ -1,36 +0,0 @@
1
- import { existsSync, readdirSync, readFileSync } from "node:fs";
2
- import { join } from "node:path";
3
- import { LauncherError } from "./errors.js";
4
- /**
5
- * Every tenants/<id>/tenant.json schemaVersion must be at most the target
6
- * installed Runtime's Tenant schema.
7
- */
8
- export function assertSchemaGuard(paths, tenantSchemaMax) {
9
- let names;
10
- try {
11
- names = readdirSync(paths.tenants);
12
- }
13
- catch {
14
- return;
15
- }
16
- for (const id of names) {
17
- if (id.startsWith("."))
18
- continue;
19
- const tenantJson = join(paths.tenants, id, "tenant.json");
20
- if (!existsSync(tenantJson))
21
- continue;
22
- let schemaVersion;
23
- try {
24
- const body = JSON.parse(readFileSync(tenantJson, "utf8"));
25
- if (typeof body.schemaVersion === "number") {
26
- schemaVersion = body.schemaVersion;
27
- }
28
- }
29
- catch {
30
- continue;
31
- }
32
- if (schemaVersion !== undefined && schemaVersion > tenantSchemaMax) {
33
- throw new LauncherError("host_schema_newer", `Tenant ${id} has schemaVersion ${schemaVersion}, which is newer than the installed Runtime supports (max ${tenantSchemaMax}).`, "Install a Runtime that supports this Tenant schema (npm install --global @nylorun/runtime@latest), or restore the Tenant from its migration snapshot.", { tenantId: id, schemaVersion, tenantSchemaMax });
34
- }
35
- }
36
- }
@@ -1,22 +0,0 @@
1
- import { type ChildProcess } from "node:child_process";
2
- export interface SpawnHostInput {
3
- nodeBinary: string;
4
- entry: string;
5
- environment: NodeJS.ProcessEnv;
6
- cwd: string;
7
- detached: boolean;
8
- logPath?: string;
9
- platform?: NodeJS.Platform;
10
- }
11
- /**
12
- * Spawn the Host on the launcher's own Node (`process.execPath`). Detached background Hosts survive after
13
- * `up` exits (including Windows — without detached the Host dies with the
14
- * launcher parent and createTenant sees ECONNREFUSED). stdout/stderr append to
15
- * runtime.log when logPath is set.
16
- */
17
- export declare function spawnHostProcess(input: SpawnHostInput): ChildProcess;
18
- /**
19
- * Force-kill a Host process. SIGKILL / process group on POSIX; taskkill on Windows.
20
- * Exported for Windows-path unit coverage (E14).
21
- */
22
- export declare function forceKillHost(pid: number, platform?: NodeJS.Platform): void;
@@ -1,85 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { closeSync, openSync } from "node:fs";
3
- /**
4
- * Spawn the Host on the launcher's own Node (`process.execPath`). Detached background Hosts survive after
5
- * `up` exits (including Windows — without detached the Host dies with the
6
- * launcher parent and createTenant sees ECONNREFUSED). stdout/stderr append to
7
- * runtime.log when logPath is set.
8
- */
9
- export function spawnHostProcess(input) {
10
- const detached = input.detached;
11
- if (input.logPath) {
12
- const fd = openSync(input.logPath, "a", 0o600);
13
- try {
14
- const child = spawn(input.nodeBinary, [input.entry], {
15
- detached,
16
- windowsHide: true,
17
- cwd: input.cwd,
18
- env: input.environment,
19
- stdio: ["ignore", fd, fd],
20
- });
21
- child.once("exit", () => {
22
- try {
23
- closeSync(fd);
24
- }
25
- catch {
26
- /* already closed */
27
- }
28
- });
29
- return child;
30
- }
31
- catch (error) {
32
- closeSync(fd);
33
- throw error;
34
- }
35
- }
36
- return spawn(input.nodeBinary, [input.entry], {
37
- cwd: input.cwd,
38
- env: input.environment,
39
- windowsHide: true,
40
- stdio: ["ignore", "inherit", "inherit"],
41
- ...(detached ? { detached: true } : {}),
42
- });
43
- }
44
- /**
45
- * Force-kill a Host process. SIGKILL / process group on POSIX; taskkill on Windows.
46
- * Exported for Windows-path unit coverage (E14).
47
- */
48
- export function forceKillHost(pid, platform = process.platform) {
49
- if (platform === "win32") {
50
- try {
51
- const child = spawn("taskkill", ["/PID", String(pid), "/T", "/F"], {
52
- stdio: "ignore",
53
- windowsHide: true,
54
- });
55
- child.on("error", () => {
56
- try {
57
- process.kill(pid);
58
- }
59
- catch {
60
- /* gone */
61
- }
62
- });
63
- }
64
- catch {
65
- try {
66
- process.kill(pid);
67
- }
68
- catch {
69
- /* gone */
70
- }
71
- }
72
- return;
73
- }
74
- try {
75
- process.kill(-pid, "SIGKILL");
76
- }
77
- catch {
78
- try {
79
- process.kill(pid, "SIGKILL");
80
- }
81
- catch {
82
- /* gone */
83
- }
84
- }
85
- }
@@ -1,6 +0,0 @@
1
- import { type HostPaths } from "./paths.js";
2
- import type { StatusResult } from "./protocol.js";
3
- /**
4
- * Status with no lock and no mutation (D§9.3).
5
- */
6
- export declare function status(paths: HostPaths, launcherVersion: string): Promise<StatusResult>;
@@ -1,65 +0,0 @@
1
- import { LAUNCHER_PROTOCOL } from "@nylorun/core/compatibility";
2
- import { readHostConfig } from "./host-config.js";
3
- import { readHostState } from "./host-state.js";
4
- import { processAlive } from "./locks.js";
5
- import { hostUrl } from "./paths.js";
6
- import { portBindable, probeHostHealth } from "./probe.js";
7
- /**
8
- * Status with no lock and no mutation (D§9.3).
9
- */
10
- export async function status(paths, launcherVersion) {
11
- const config = await readHostConfig(paths);
12
- const stateFile = await readHostState(paths);
13
- const runtimeVersion = config && typeof config.runtimeVersion === "string"
14
- ? config.runtimeVersion
15
- : undefined;
16
- const base = {
17
- launcherProtocol: LAUNCHER_PROTOCOL,
18
- home: paths.root,
19
- state: "absent",
20
- launcherVersion,
21
- ...(runtimeVersion ? { runtimeVersion } : {}),
22
- };
23
- if (!config) {
24
- return base;
25
- }
26
- const url = hostUrl(config);
27
- const withConfig = {
28
- ...base,
29
- state: "stopped",
30
- url,
31
- hostId: config.hostId,
32
- ...(stateFile?.pid ? { pid: stateFile.pid } : {}),
33
- ...(stateFile?.version ? { version: stateFile.version } : {}),
34
- };
35
- const probe = await probeHostHealth(url);
36
- const ours = probe.health !== undefined &&
37
- (probe.health.hostId === undefined ||
38
- probe.health.hostId === config.hostId);
39
- if (probe.foreign) {
40
- return { ...withConfig, state: "foreign-port" };
41
- }
42
- if (probe.health && ours) {
43
- return {
44
- ...withConfig,
45
- state: "running",
46
- ...(probe.health.version ? { version: probe.health.version } : {}),
47
- ...(probe.health.hostId ? { hostId: probe.health.hostId } : {}),
48
- ...(probe.health.pid ? { pid: probe.health.pid } : {}),
49
- };
50
- }
51
- if (probe.health && !ours) {
52
- return {
53
- ...withConfig,
54
- state: "foreign-port",
55
- ...(probe.health.hostId ? { hostId: probe.health.hostId } : {}),
56
- };
57
- }
58
- if (stateFile && processAlive(stateFile.pid)) {
59
- return { ...withConfig, state: "unresponsive", pid: stateFile.pid };
60
- }
61
- if (!(await portBindable(config.host, config.port))) {
62
- return { ...withConfig, state: "foreign-port" };
63
- }
64
- return withConfig;
65
- }
@@ -1,16 +0,0 @@
1
- import { DatabaseSync } from "node:sqlite";
2
- import type { TenantPaths } from "./types.js";
3
- import type { TenantEnvelope } from "@nylorun/core/contracts";
4
- export interface MigrationHooks {
5
- schemaVersionOf?: (db: DatabaseSync) => number;
6
- migrateTenantDatabase?: (db: DatabaseSync) => {
7
- from: number;
8
- to: number;
9
- };
10
- targetVersion?: number;
11
- }
12
- /**
13
- * Checkpoint WAL, snapshot database + envelope + KEK, migrate, update envelope.
14
- * On failure restore the snapshot, keep diagnostics, and throw migration-failed.
15
- */
16
- export declare function migrateTenantWithSnapshot(paths: TenantPaths, envelope: TenantEnvelope, hooks?: MigrationHooks, now?: Date): TenantEnvelope;