@volter/world-runtime 3.0.159 → 3.0.161
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/dist/src/pack-facts.d.ts +1 -0
- package/dist/src/runtime.js +1 -1
- package/dist/src/service-command.d.ts +3 -0
- package/dist/src/service-command.js +38 -0
- package/dist/src/service-recorder.js +2 -1
- package/package.json +3 -3
- package/src/pack-facts.ts +1 -1
- package/src/runtime.ts +1 -1
- package/src/service-command.ts +29 -0
- package/src/service-recorder.ts +2 -1
package/dist/src/pack-facts.d.ts
CHANGED
package/dist/src/runtime.js
CHANGED
|
@@ -1562,7 +1562,7 @@ async function sidePortsFor(vendor, args, allocatedPorts) {
|
|
|
1562
1562
|
const given = at >= 0 ? Number(args[at + 1]) : Number.NaN;
|
|
1563
1563
|
const pinned = Number.isInteger(given) && given > 0;
|
|
1564
1564
|
const port = pinned ? given : await allocatePort(allocatedPorts);
|
|
1565
|
-
out.push({ name: side.name, option: side.option, flag: side.flag, port, pinned, url:
|
|
1565
|
+
out.push({ name: side.name, option: side.option, flag: side.flag, port, pinned, url: `${side.scheme ?? 'http'}://127.0.0.1:${port}${side.path ?? ''}` });
|
|
1566
1566
|
}
|
|
1567
1567
|
return out;
|
|
1568
1568
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Process services run without a shell. On Windows npm's Bun command is a .cmd
|
|
2
|
+
// shim, whose native package executable must be selected before Node spawns it.
|
|
3
|
+
import { readFileSync, statSync } from 'node:fs';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
5
|
+
const file = (path) => {
|
|
6
|
+
try {
|
|
7
|
+
return statSync(path).isFile();
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
/** Resolve only the known npm Bun layout, never execute or interpret a command
|
|
14
|
+
* script. Keep explicit paths, other commands and non-Windows behavior intact. */
|
|
15
|
+
export function serviceExecutable(command, env) {
|
|
16
|
+
if (process.platform !== 'win32' || command.toLowerCase() !== 'bun')
|
|
17
|
+
return command;
|
|
18
|
+
const path = Object.entries(env).find(([key]) => key.toUpperCase() === 'PATH')?.[1] ?? '';
|
|
19
|
+
const directories = [process.cwd(), ...path.split(';').map((value) => value.replace(/^"(.*)"$/, '$1'))];
|
|
20
|
+
for (const directory of directories) {
|
|
21
|
+
const native = resolve(directory, 'bun.exe');
|
|
22
|
+
if (file(native))
|
|
23
|
+
return native;
|
|
24
|
+
if (!file(resolve(directory, 'bun.cmd')))
|
|
25
|
+
continue;
|
|
26
|
+
const installed = resolve(directory, 'node_modules', 'bun');
|
|
27
|
+
const executable = join(installed, 'bin', 'bun.exe');
|
|
28
|
+
if (!file(executable))
|
|
29
|
+
continue;
|
|
30
|
+
try {
|
|
31
|
+
const manifest = JSON.parse(readFileSync(join(installed, 'package.json'), 'utf8'));
|
|
32
|
+
if (manifest.name === 'bun' && manifest.bin?.bun === 'bin/bun.exe')
|
|
33
|
+
return executable;
|
|
34
|
+
}
|
|
35
|
+
catch { /* An incomplete installation follows the ordinary spawn-error path. */ }
|
|
36
|
+
}
|
|
37
|
+
return command;
|
|
38
|
+
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
// The World's NODE_OPTIONS (the injector) is for the service, not this parent: it arrives renamed and is restored.
|
|
18
18
|
import { signalChild } from './process-signal.mjs';
|
|
19
19
|
import { errorMessage } from "./error-message.js";
|
|
20
|
+
import { serviceExecutable } from "./service-command.js";
|
|
20
21
|
import { spawn } from 'node:child_process';
|
|
21
22
|
import { constants } from 'node:os';
|
|
22
23
|
import { appendFileSync, closeSync, fstatSync, openSync, readSync, statSync, truncateSync, writeFileSync } from 'node:fs';
|
|
@@ -61,7 +62,7 @@ const record = (entry, then) => {
|
|
|
61
62
|
process.stdout.write(`${logEnd().atLineStart ? '' : '\n'}${line}`, () => then?.());
|
|
62
63
|
};
|
|
63
64
|
const started = Date.now();
|
|
64
|
-
const child = spawn(command, args, { windowsHide: true, stdio: 'inherit', env });
|
|
65
|
+
const child = spawn(serviceExecutable(command, env), args, { windowsHide: true, stdio: 'inherit', env });
|
|
65
66
|
if (child.pid !== undefined)
|
|
66
67
|
record({ event: 'world.service.started', pid: child.pid, parentPid: process.pid });
|
|
67
68
|
/** The log's last `bytes` (from a line start) as the rotation `<log>.1`: however far a runaway writer overshot the cap,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-runtime",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.161",
|
|
4
4
|
"description": "World configs for twins: boot named local runtimes, allocate ports, generate world.env/instance.json, and run apps against fake-key twin worlds.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"twin",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"node": ">=22.3"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
|
-
"@volter/world-core": "3.0.
|
|
73
|
+
"@volter/world-core": "3.0.153",
|
|
74
74
|
"@volter/world-console": "3.0.150"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"@volter/browser-runtime": "0.1.104",
|
|
81
81
|
"@volter/browser-sandboxes": "0.1.84",
|
|
82
82
|
"@volter/world-access": "3.0.1",
|
|
83
|
-
"@volter/world-core": "3.0.
|
|
83
|
+
"@volter/world-core": "3.0.153",
|
|
84
84
|
"modern-screenshot": "4.7.0",
|
|
85
85
|
"mongodb": "~6.20.0",
|
|
86
86
|
"pg-gateway": "0.3.0-beta.4",
|
package/src/pack-facts.ts
CHANGED
|
@@ -38,7 +38,7 @@ export type PackFacts = {
|
|
|
38
38
|
/** The World's managed database the runtime binds the twin to at boot (TwinPack.managedDatabase). */
|
|
39
39
|
managedDatabase?: { kind: 'postgres'; arg: string; note: string };
|
|
40
40
|
/** Listeners the twin opens beside its main port, allocated and recorded by the runtime (TwinPack.sidePorts). */
|
|
41
|
-
sidePorts?: Array<{ name: string; option: string; flag: string; path?: string; note: string }>;
|
|
41
|
+
sidePorts?: Array<{ name: string; option: string; flag: string; path?: string; scheme?: string; note: string }>;
|
|
42
42
|
/** R16: the protocol major the package targets and its standing against the kernel that compiled the artifact. */
|
|
43
43
|
protocol?: { declared?: string; major: number; standing: 'current' | 'deprecated' | 'refused' | 'assumed' };
|
|
44
44
|
};
|
package/src/runtime.ts
CHANGED
|
@@ -1535,7 +1535,7 @@ async function sidePortsFor(vendor: string, args: readonly string[], allocatedPo
|
|
|
1535
1535
|
const given = at >= 0 ? Number(args[at + 1]) : Number.NaN;
|
|
1536
1536
|
const pinned = Number.isInteger(given) && given > 0;
|
|
1537
1537
|
const port = pinned ? given : await allocatePort(allocatedPorts);
|
|
1538
|
-
out.push({ name: side.name, option: side.option, flag: side.flag, port, pinned, url:
|
|
1538
|
+
out.push({ name: side.name, option: side.option, flag: side.flag, port, pinned, url: `${side.scheme ?? 'http'}://127.0.0.1:${port}${side.path ?? ''}` });
|
|
1539
1539
|
}
|
|
1540
1540
|
return out;
|
|
1541
1541
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Process services run without a shell. On Windows npm's Bun command is a .cmd
|
|
2
|
+
// shim, whose native package executable must be selected before Node spawns it.
|
|
3
|
+
import { readFileSync, statSync } from 'node:fs';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
5
|
+
|
|
6
|
+
const file = (path: string): boolean => {
|
|
7
|
+
try { return statSync(path).isFile(); } catch { return false; }
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/** Resolve only the known npm Bun layout, never execute or interpret a command
|
|
11
|
+
* script. Keep explicit paths, other commands and non-Windows behavior intact. */
|
|
12
|
+
export function serviceExecutable(command: string, env: NodeJS.ProcessEnv): string {
|
|
13
|
+
if (process.platform !== 'win32' || command.toLowerCase() !== 'bun') return command;
|
|
14
|
+
const path = Object.entries(env).find(([key]) => key.toUpperCase() === 'PATH')?.[1] ?? '';
|
|
15
|
+
const directories = [process.cwd(), ...path.split(';').map((value) => value.replace(/^"(.*)"$/, '$1'))];
|
|
16
|
+
for (const directory of directories) {
|
|
17
|
+
const native = resolve(directory, 'bun.exe');
|
|
18
|
+
if (file(native)) return native;
|
|
19
|
+
if (!file(resolve(directory, 'bun.cmd'))) continue;
|
|
20
|
+
const installed = resolve(directory, 'node_modules', 'bun');
|
|
21
|
+
const executable = join(installed, 'bin', 'bun.exe');
|
|
22
|
+
if (!file(executable)) continue;
|
|
23
|
+
try {
|
|
24
|
+
const manifest = JSON.parse(readFileSync(join(installed, 'package.json'), 'utf8')) as { name?: unknown; bin?: { bun?: unknown } };
|
|
25
|
+
if (manifest.name === 'bun' && manifest.bin?.bun === 'bin/bun.exe') return executable;
|
|
26
|
+
} catch { /* An incomplete installation follows the ordinary spawn-error path. */ }
|
|
27
|
+
}
|
|
28
|
+
return command;
|
|
29
|
+
}
|
package/src/service-recorder.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
// The World's NODE_OPTIONS (the injector) is for the service, not this parent: it arrives renamed and is restored.
|
|
18
18
|
import { signalChild } from './process-signal.mjs';
|
|
19
19
|
import { errorMessage } from './error-message.ts';
|
|
20
|
+
import { serviceExecutable } from './service-command.ts';
|
|
20
21
|
import { spawn } from 'node:child_process';
|
|
21
22
|
import { constants } from 'node:os';
|
|
22
23
|
import { appendFileSync, closeSync, fstatSync, openSync, readSync, statSync, truncateSync, writeFileSync } from 'node:fs';
|
|
@@ -48,7 +49,7 @@ const record = (entry: Record<string, unknown>, then?: () => void): void => {
|
|
|
48
49
|
};
|
|
49
50
|
|
|
50
51
|
const started = Date.now();
|
|
51
|
-
const child = spawn(command, args, { windowsHide: true, stdio: 'inherit', env });
|
|
52
|
+
const child = spawn(serviceExecutable(command, env), args, { windowsHide: true, stdio: 'inherit', env });
|
|
52
53
|
if (child.pid !== undefined) record({ event: 'world.service.started', pid: child.pid, parentPid: process.pid });
|
|
53
54
|
|
|
54
55
|
/** The log's last `bytes` (from a line start) as the rotation `<log>.1`: however far a runaway writer overshot the cap,
|