@vmz/test 0.1.9 → 0.1.11
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/browser-serve.js +54 -1
- package/dist/browser.js +17 -6
- package/dist/logic.js +8 -10
- package/dist/resume.js +11 -16
- package/dist/ssr.js +10 -16
- package/package.json +3 -3
package/dist/browser-serve.js
CHANGED
|
@@ -2,9 +2,56 @@
|
|
|
2
2
|
* Browser Host U2 — real VMZ serve-host lifecycle + RouteId → path resolution.
|
|
3
3
|
*/
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
5
6
|
import fs from 'node:fs';
|
|
6
7
|
import net from 'node:net';
|
|
7
8
|
import path from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
/** Same discovery as `vmz serve` / conformance `serveHostChildEnv`. */
|
|
12
|
+
function resolveNativeNodePath() {
|
|
13
|
+
const { platform, arch } = process;
|
|
14
|
+
let triple = `${platform}-${arch}`;
|
|
15
|
+
if (platform === 'win32' && arch === 'x64')
|
|
16
|
+
triple = 'win32-x64-msvc';
|
|
17
|
+
else if (platform === 'win32' && arch === 'arm64')
|
|
18
|
+
triple = 'win32-arm64-msvc';
|
|
19
|
+
else if (platform === 'darwin' && arch === 'arm64')
|
|
20
|
+
triple = 'darwin-arm64';
|
|
21
|
+
else if (platform === 'darwin' && arch === 'x64')
|
|
22
|
+
triple = 'darwin-x64';
|
|
23
|
+
else if (platform === 'linux' && arch === 'x64')
|
|
24
|
+
triple = 'linux-x64-gnu';
|
|
25
|
+
else if (platform === 'linux' && arch === 'arm64')
|
|
26
|
+
triple = 'linux-arm64-gnu';
|
|
27
|
+
const short = triple === 'win32-x64-msvc'
|
|
28
|
+
? 'win32-x64'
|
|
29
|
+
: triple === 'win32-arm64-msvc'
|
|
30
|
+
? 'win32-arm64'
|
|
31
|
+
: triple === 'linux-x64-gnu'
|
|
32
|
+
? 'linux-x64'
|
|
33
|
+
: triple === 'linux-arm64-gnu'
|
|
34
|
+
? 'linux-arm64'
|
|
35
|
+
: triple;
|
|
36
|
+
const name = `@vmz/vmz-${short}`;
|
|
37
|
+
/** @type {string[]} */
|
|
38
|
+
const candidates = [];
|
|
39
|
+
try {
|
|
40
|
+
const pkgJson = require.resolve(`${name}/package.json`);
|
|
41
|
+
const dir = path.dirname(pkgJson);
|
|
42
|
+
candidates.push(path.join(dir, `vmz.${triple}.node`), path.join(dir, 'vmz.node'));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
/* optional dep missing */
|
|
46
|
+
}
|
|
47
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
48
|
+
candidates.push(path.join(here, '..', '..', '..', 'runtimes', `vmz-${short}`, `vmz.${triple}.node`), path.join(here, '..', '..', '..', 'runtimes', `vmz-${short}`, 'vmz.node'));
|
|
49
|
+
for (const p of candidates) {
|
|
50
|
+
if (fs.existsSync(p))
|
|
51
|
+
return path.resolve(p);
|
|
52
|
+
}
|
|
53
|
+
throw new Error(`serve host: vmz native addon not found for ${name}. Run pnpm napi:build\nLooked in:\n${candidates.map((c) => ` - ${c}`).join('\n')}`);
|
|
54
|
+
}
|
|
8
55
|
function freePort() {
|
|
9
56
|
return new Promise((resolve, reject) => {
|
|
10
57
|
const s = net.createServer();
|
|
@@ -99,7 +146,13 @@ export async function startServeHost(outDir) {
|
|
|
99
146
|
const port = await freePort();
|
|
100
147
|
const child = spawn(process.execPath, [hostJs], {
|
|
101
148
|
cwd: outDir,
|
|
102
|
-
env: {
|
|
149
|
+
env: {
|
|
150
|
+
...process.env,
|
|
151
|
+
VMZ_DIST: outDir,
|
|
152
|
+
VMZ_HOST: '127.0.0.1',
|
|
153
|
+
VMZ_PORT: String(port),
|
|
154
|
+
VMZ_NATIVE_NODE: resolveNativeNodePath(),
|
|
155
|
+
},
|
|
103
156
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
104
157
|
});
|
|
105
158
|
const kill = () => {
|
package/dist/browser.js
CHANGED
|
@@ -16,6 +16,7 @@ import http from 'node:http';
|
|
|
16
16
|
import net from 'node:net';
|
|
17
17
|
import os from 'node:os';
|
|
18
18
|
import path from 'node:path';
|
|
19
|
+
import { resolveComponentEntries } from '@vmz/core/component-registry';
|
|
19
20
|
import { resolveChunkArtifacts } from './compile.js';
|
|
20
21
|
import { createArtifactsDir, writeFailureEvidence, writeTimingOnly } from './browser-evidence.js';
|
|
21
22
|
import { isServeHostManifest, resolveRoutePath, startServeHost } from './browser-serve.js';
|
|
@@ -304,8 +305,13 @@ export async function runBrowserManifest(manifest, ctx) {
|
|
|
304
305
|
page = await browser.newPage();
|
|
305
306
|
page.setDefaultTimeout(15000);
|
|
306
307
|
page.on('console', (msg) => {
|
|
307
|
-
if (msg.type()
|
|
308
|
-
|
|
308
|
+
if (msg.type() !== 'error')
|
|
309
|
+
return;
|
|
310
|
+
const text = msg.text();
|
|
311
|
+
// Chrome also logs network 404s here; requestfailed gate carries URL + resource-type filters.
|
|
312
|
+
if (/Failed to load resource:.+404/i.test(text))
|
|
313
|
+
return;
|
|
314
|
+
consoleErrors.push(text);
|
|
309
315
|
});
|
|
310
316
|
page.on('pageerror', (err) => {
|
|
311
317
|
consoleErrors.push(err instanceof Error ? err.message : String(err));
|
|
@@ -327,13 +333,18 @@ export async function runBrowserManifest(manifest, ctx) {
|
|
|
327
333
|
}
|
|
328
334
|
else {
|
|
329
335
|
await page.goto(`${origin}/__vmz/harness`, { waitUntil: 'domcontentloaded' });
|
|
330
|
-
const
|
|
336
|
+
const explicitComponents = program.components && typeof program.components === 'object' ? program.components : undefined;
|
|
337
|
+
const registryStrict = process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
|
|
338
|
+
const registryEntries = await resolveComponentEntries(ctx.outDir, explicitComponents, {
|
|
339
|
+
strict: registryStrict,
|
|
340
|
+
closureRoots: [chunkId.replace(/\\/g, '/')],
|
|
341
|
+
});
|
|
331
342
|
const boot = await page.evaluate(async (cfg) => {
|
|
332
343
|
const dom = await import(/* @vite-ignore */ `${cfg.origin}/vmz-dom.js`);
|
|
333
344
|
const Comp = (await import(/* @vite-ignore */ `${cfg.origin}/${cfg.chunkPath}.client.js`)).default;
|
|
334
345
|
const map = {};
|
|
335
|
-
for (const
|
|
336
|
-
map[name] = (await import(/* @vite-ignore */ `${cfg.origin}/${
|
|
346
|
+
for (const { name, entry } of cfg.registry) {
|
|
347
|
+
map[name] = (await import(/* @vite-ignore */ `${cfg.origin}/${entry}`)).default;
|
|
337
348
|
}
|
|
338
349
|
if (Object.keys(map).length && typeof dom.registerComponents === 'function') {
|
|
339
350
|
dom.registerComponents(map);
|
|
@@ -357,7 +368,7 @@ export async function runBrowserManifest(manifest, ctx) {
|
|
|
357
368
|
}, {
|
|
358
369
|
origin,
|
|
359
370
|
chunkPath: chunkId.replace(/\\/g, '/'),
|
|
360
|
-
|
|
371
|
+
registry: registryEntries,
|
|
361
372
|
});
|
|
362
373
|
if (!boot?.ok) {
|
|
363
374
|
fail(`browser boot: ${boot?.error || 'unknown'}`);
|
package/dist/logic.js
CHANGED
|
@@ -5,6 +5,7 @@ import fs from 'node:fs';
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { pathToFileURL } from 'node:url';
|
|
7
7
|
import { createRequire } from 'node:module';
|
|
8
|
+
import { createRenderHost } from '@vmz/core/render-host';
|
|
8
9
|
import { resolveChunkArtifacts } from './compile.js';
|
|
9
10
|
const require = createRequire(import.meta.url);
|
|
10
11
|
function loadLinkedom() {
|
|
@@ -41,16 +42,13 @@ export async function createLogicHost(opts) {
|
|
|
41
42
|
if (!Component?.__vmzDirect || typeof Component.__vmzCreate !== 'function') {
|
|
42
43
|
throw new Error('logic host requires Direct __vmzCreate (rebuild with current compiler)');
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
dom.registerComponents(map);
|
|
53
|
-
}
|
|
45
|
+
const strict = process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
|
|
46
|
+
const renderHost = await createRenderHost(opts.outDir, {
|
|
47
|
+
strictDeployment: strict,
|
|
48
|
+
preload: 'none',
|
|
49
|
+
explicit: opts.components,
|
|
50
|
+
});
|
|
51
|
+
await renderHost.ensureComponents([opts.chunkId.replace(/\\/g, '/')]);
|
|
54
52
|
if (typeof dom.__vmzPrecisionEnable === 'function') {
|
|
55
53
|
dom.__vmzPrecisionEnable(true);
|
|
56
54
|
}
|
package/dist/resume.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Resume host for `vmz test --mode resume` (/ first slice).
|
|
3
3
|
* SSR shell → resume adopt → event patch; onMount must not run.
|
|
4
4
|
*/
|
|
5
|
-
import path from 'node:path';
|
|
6
5
|
import { pathToFileURL } from 'node:url';
|
|
6
|
+
import { createRenderHost } from '@vmz/core/render-host';
|
|
7
7
|
import { resolveChunkArtifacts } from './compile.js';
|
|
8
8
|
import { installHeadlessDocument } from './logic.js';
|
|
9
9
|
export async function runResumeManifest(manifest, ctx) {
|
|
@@ -25,29 +25,24 @@ export async function runResumeManifest(manifest, ctx) {
|
|
|
25
25
|
}
|
|
26
26
|
installHeadlessDocument();
|
|
27
27
|
globalThis.requestIdleCallback = (cb) => setTimeout(() => cb({ didTimeout: false, timeRemaining: () => 1 }), 0);
|
|
28
|
-
|
|
28
|
+
const components = program.components && typeof program.components === 'object' ? program.components : undefined;
|
|
29
|
+
let renderHost;
|
|
29
30
|
let Page;
|
|
31
|
+
let loaded = {};
|
|
30
32
|
try {
|
|
31
|
-
|
|
33
|
+
renderHost = await createRenderHost(ctx.outDir, {
|
|
34
|
+
strictDeployment: process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true',
|
|
35
|
+
preload: 'none',
|
|
36
|
+
explicit: components,
|
|
37
|
+
});
|
|
38
|
+
loaded = await renderHost.ensureComponents([chunkId.replace(/\\/g, '/')]);
|
|
32
39
|
Page = (await import(pathToFileURL(arts.clientPath).href)).default;
|
|
33
40
|
}
|
|
34
41
|
catch (e) {
|
|
35
42
|
fail(`import dist: ${e instanceof Error ? e.message : String(e)}`);
|
|
36
43
|
return { status: 'error', diagnostics, planId: null, programId };
|
|
37
44
|
}
|
|
38
|
-
const
|
|
39
|
-
const loaded = {};
|
|
40
|
-
if (components) {
|
|
41
|
-
for (const [name, chunk] of Object.entries(components)) {
|
|
42
|
-
const cArts = resolveChunkArtifacts(ctx.outDir, chunk);
|
|
43
|
-
if (!cArts.clientPath) {
|
|
44
|
-
fail(`missing component ${chunk}`);
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
loaded[name] = (await import(pathToFileURL(cArts.clientPath).href)).default;
|
|
48
|
-
}
|
|
49
|
-
dom.registerComponents(loaded);
|
|
50
|
-
}
|
|
45
|
+
const dom = renderHost.dom;
|
|
51
46
|
let html = '';
|
|
52
47
|
let island = null;
|
|
53
48
|
let inst = null;
|
package/dist/ssr.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* SSR / hydrate / stream host for `vmz test --mode ssr` .
|
|
3
3
|
* Same Direct schedule as production via linkedom + renderToString / renderToStream / hydrate.
|
|
4
4
|
*/
|
|
5
|
-
import path from 'node:path';
|
|
6
5
|
import { pathToFileURL } from 'node:url';
|
|
6
|
+
import { createRenderHost } from '@vmz/core/render-host';
|
|
7
7
|
import { resolveChunkArtifacts } from './compile.js';
|
|
8
8
|
import { installHeadlessDocument } from './logic.js';
|
|
9
9
|
export async function runSsrManifest(manifest, ctx) {
|
|
@@ -24,29 +24,23 @@ export async function runSsrManifest(manifest, ctx) {
|
|
|
24
24
|
return { status: 'failed', diagnostics, planId: null, programId };
|
|
25
25
|
}
|
|
26
26
|
installHeadlessDocument();
|
|
27
|
-
|
|
27
|
+
const components = program.components && typeof program.components === 'object' ? program.components : undefined;
|
|
28
|
+
let renderHost;
|
|
28
29
|
let Component;
|
|
29
30
|
try {
|
|
30
|
-
|
|
31
|
+
renderHost = await createRenderHost(ctx.outDir, {
|
|
32
|
+
strictDeployment: process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true',
|
|
33
|
+
preload: 'none',
|
|
34
|
+
explicit: components,
|
|
35
|
+
});
|
|
36
|
+
await renderHost.ensureComponents([chunkId.replace(/\\/g, '/')]);
|
|
31
37
|
Component = (await import(pathToFileURL(arts.clientPath).href)).default;
|
|
32
38
|
}
|
|
33
39
|
catch (e) {
|
|
34
40
|
fail(`import dist: ${e instanceof Error ? e.message : String(e)}`);
|
|
35
41
|
return { status: 'error', diagnostics, planId: null, programId };
|
|
36
42
|
}
|
|
37
|
-
const
|
|
38
|
-
if (components) {
|
|
39
|
-
const map = {};
|
|
40
|
-
for (const [name, chunk] of Object.entries(components)) {
|
|
41
|
-
const cArts = resolveChunkArtifacts(ctx.outDir, chunk);
|
|
42
|
-
if (!cArts.clientPath) {
|
|
43
|
-
fail(`missing component ${chunk}`);
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
map[name] = (await import(pathToFileURL(cArts.clientPath).href)).default;
|
|
47
|
-
}
|
|
48
|
-
dom.registerComponents(map);
|
|
49
|
-
}
|
|
43
|
+
const dom = renderHost.dom;
|
|
50
44
|
let html = '';
|
|
51
45
|
let streamChunks = [];
|
|
52
46
|
let streamAborted = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vmz/test",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "VMZ native test protocol + Compile/Logic/Browser/SSR/Resume/Deployment hosts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"build": "tsc -p tsconfig.json"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@vmz/core": "0.1.
|
|
31
|
-
"@vmz/protocol": "0.1.
|
|
30
|
+
"@vmz/core": "0.1.11",
|
|
31
|
+
"@vmz/protocol": "0.1.11",
|
|
32
32
|
"linkedom": "^0.18.13",
|
|
33
33
|
"puppeteer-core": "^24.11.2"
|
|
34
34
|
},
|