@volter/world-runtime 3.0.100 → 3.0.102
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/cli-commands.js +1 -1
- package/dist/src/configs.js +1 -1
- package/dist/src/mongodb-backing.d.ts +3 -2
- package/dist/src/mongodb-backing.js +16 -11
- package/dist/src/pglite-backing.js +57 -16
- package/dist/src/pglite-host.mjs +12 -1
- package/dist/src/process-signal.mjs +13 -4
- package/dist/src/redis-backing.js +31 -3
- package/dist/src/runtime.js +77 -112
- package/dist/src/schema.d.ts +4 -6
- package/dist/src/schema.js +4 -10
- package/dist/src/service-exit.d.ts +0 -3
- package/dist/src/service-exit.js +0 -5
- package/dist/src/up-cli.js +11 -0
- package/package.json +4 -4
- package/src/cli-commands.ts +1 -1
- package/src/configs.ts +1 -1
- package/src/mongodb-backing.ts +10 -8
- package/src/pglite-backing.ts +48 -16
- package/src/pglite-host.mjs +12 -1
- package/src/process-signal.mjs +13 -4
- package/src/redis-backing.ts +25 -3
- package/src/runtime.ts +72 -98
- package/src/schema.ts +8 -15
- package/src/service-exit.ts +0 -6
- package/src/up-cli.ts +10 -0
package/src/schema.ts
CHANGED
|
@@ -97,16 +97,15 @@ export type WorldExternalDiscover = {
|
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
-
* Optional readiness probe, polled after `up` until it passes or `timeoutMs` elapses
|
|
101
|
-
*
|
|
102
|
-
* - `
|
|
103
|
-
* - `
|
|
100
|
+
* Optional readiness probe, polled after `up` until it passes or `timeoutMs` elapses: the service answering its own
|
|
101
|
+
* protocol (architecture D9). Exactly one of:
|
|
102
|
+
* - `command`/`args`: a command that asks the service and exits 0 when it answers,
|
|
103
|
+
* - `httpUrl`: an HTTP(S) URL that must return a 2xx/3xx response.
|
|
104
104
|
*/
|
|
105
105
|
export type WorldExternalReadyWhen = {
|
|
106
106
|
command?: string;
|
|
107
107
|
args?: string[];
|
|
108
108
|
httpUrl?: string;
|
|
109
|
-
stdoutMatch?: string;
|
|
110
109
|
timeoutMs?: number;
|
|
111
110
|
intervalMs?: number;
|
|
112
111
|
};
|
|
@@ -224,7 +223,6 @@ export type WorldServiceConfig = {
|
|
|
224
223
|
* service truly serves, so `up` returning means "ready" (no post-up re-polling needed):
|
|
225
224
|
* - `{ httpUrl }` — poll until 2xx/3xx. `${url}`/`${host}`/`${port}` resolve to the allocated port.
|
|
226
225
|
* - `{ command, args }` — poll until the command exits 0 (runs with the service env, incl. `PORT`).
|
|
227
|
-
* - `{ stdoutMatch }` — poll until a regex matches the service's stdout/stderr log.
|
|
228
226
|
* 'external' services use `external.readyWhen` instead.
|
|
229
227
|
*/
|
|
230
228
|
ready?: 'tcp' | WorldExternalReadyWhen;
|
|
@@ -461,26 +459,21 @@ function assertValidRegex(pattern: string, what: string, path: string): void {
|
|
|
461
459
|
}
|
|
462
460
|
|
|
463
461
|
/** Shared validator for a readiness probe — used by both `external.readyWhen` and a process/twin
|
|
464
|
-
* service's `ready` object. Exactly one of command/httpUrl
|
|
465
|
-
* stdoutMatch regex must compile (so a typo fails at config time, not mid-boot). */
|
|
462
|
+
* service's `ready` object. Exactly one of command/httpUrl, with correct types. */
|
|
466
463
|
function assertReadyWhen(ready: unknown, what: string, path: string): void {
|
|
467
464
|
if (!ready || typeof ready !== 'object' || Array.isArray(ready)) {
|
|
468
465
|
throw new Error(`${what} must be an object in ${path}`);
|
|
469
466
|
}
|
|
470
|
-
assertKeys(ready as Record<string, unknown>, ['command', 'args', 'httpUrl', '
|
|
467
|
+
assertKeys(ready as Record<string, unknown>, ['command', 'args', 'httpUrl', 'timeoutMs', 'intervalMs'], what, path);
|
|
471
468
|
const r = ready as WorldExternalReadyWhen;
|
|
472
|
-
const probes = [r.command !== undefined, r.httpUrl !== undefined
|
|
469
|
+
const probes = [r.command !== undefined, r.httpUrl !== undefined].filter(Boolean).length;
|
|
473
470
|
if (probes !== 1) {
|
|
474
|
-
throw new Error(`${what} must set exactly one of command/httpUrl
|
|
471
|
+
throw new Error(`${what} must set exactly one of command/httpUrl in ${path}`);
|
|
475
472
|
}
|
|
476
473
|
if (r.command !== undefined && typeof r.command !== 'string') throw new Error(`${what}.command must be a string in ${path}`);
|
|
477
474
|
if (r.args !== undefined && (!Array.isArray(r.args) || r.args.some((arg) => typeof arg !== 'string'))) throw new Error(`${what}.args must be a string array in ${path}`);
|
|
478
475
|
if (r.args !== undefined && r.command === undefined) throw new Error(`${what}.args requires command in ${path}`);
|
|
479
476
|
if (r.httpUrl !== undefined && typeof r.httpUrl !== 'string') throw new Error(`${what}.httpUrl must be a string in ${path}`);
|
|
480
|
-
if (r.stdoutMatch !== undefined) {
|
|
481
|
-
if (typeof r.stdoutMatch !== 'string') throw new Error(`${what}.stdoutMatch must be a string in ${path}`);
|
|
482
|
-
assertValidRegex(r.stdoutMatch, `${what}.stdoutMatch`, path);
|
|
483
|
-
}
|
|
484
477
|
for (const key of ['timeoutMs', 'intervalMs'] as const) {
|
|
485
478
|
if (r[key] !== undefined && (!Number.isInteger(r[key]) || r[key]! <= 0)) throw new Error(`${what}.${key} must be a positive integer in ${path}`);
|
|
486
479
|
}
|
package/src/service-exit.ts
CHANGED
|
@@ -83,12 +83,6 @@ function split(line: string): { output: string; record?: { event?: unknown; at?:
|
|
|
83
83
|
try { return { output: line.slice(0, at), record: JSON.parse(line.slice(at)) as { event?: unknown; at?: unknown } }; } catch { return { output: line }; }
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
/** A log's text as the service wrote it, without the recorder's records: what a `stdoutMatch` readiness pattern is
|
|
87
|
-
* matched against. */
|
|
88
|
-
export function serviceOutput(text: string): string {
|
|
89
|
-
return text.includes(MARK) ? text.split('\n').map((line) => split(line).output).join('\n') : text;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
86
|
/** The last run's end in a service log: its start, its exit record (absent while it runs, or when its parent was killed
|
|
93
87
|
* with it), and the output it wrote last. Undefined for a log the parent never wrote to (a co-located twin's host log),
|
|
94
88
|
* which has no runs to tell apart. A run is bounded by its start record or, for a spawn that failed before starting
|
package/src/up-cli.ts
CHANGED
|
@@ -22,7 +22,17 @@ export async function upCommand(subject: string | undefined, rest: string[], roo
|
|
|
22
22
|
// --keep-state: boot over the state the World's directory already holds (a World carried somewhere else, e.g. a
|
|
23
23
|
// browser tab's image, comes up over its data instead of starting empty, as a fresh `up` does)
|
|
24
24
|
const keepState = rest.includes('--keep-state');
|
|
25
|
+
// --app-url: where the booter serves the app, recorded as `volter-world app-url --set` records it, once the World is
|
|
26
|
+
// up and in this process: a booter that knows the address before the app listens (a browser tab's preview origin)
|
|
27
|
+
// saves a whole command between up and the app's start.
|
|
28
|
+
const appUrl = optionValue(rest, '--app-url') || undefined;
|
|
29
|
+
if (appUrl !== undefined && !(URL.canParse(appUrl) && /^https?:$/.test(new URL(appUrl).protocol))) throw new Error(`volter-world up: --app-url "${appUrl}" must be an http(s) URL`);
|
|
25
30
|
const instance = await superviseWorldUp(subject, { name, root, mode, envFile, forceEnvOutput: rest.includes('--force'), owner: ownerOption(rest), ...(isolation ? { isolation } : {}), ...(keepState ? { keepState: true } : {}) });
|
|
31
|
+
if (appUrl !== undefined) {
|
|
32
|
+
const { setAppUrl } = await import('./app-url.ts');
|
|
33
|
+
setAppUrl(instance.name, appUrl, { root });
|
|
34
|
+
process.stderr.write(`volter-world up ${instance.name}: app url recorded: ${appUrl}\n`);
|
|
35
|
+
}
|
|
26
36
|
if (rest.includes('--json')) process.stdout.write(JSON.stringify(instance, null, 2) + '\n');
|
|
27
37
|
else printReady(instance);
|
|
28
38
|
}
|