@vmz/core 0.1.10 → 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/list-client-components.js +23 -5
- package/dist/serve-host.mjs +19 -22
- package/dist/server.js +3 -1
- package/package.json +1 -1
|
@@ -7,7 +7,7 @@ import fs from 'node:fs';
|
|
|
7
7
|
import { readdir } from 'node:fs/promises';
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import { pathToFileURL } from 'node:url';
|
|
10
|
-
import { componentEntriesFromDeployment, mergeExplicitComponentEntries, readDeploymentDocument, } from './deployment-registry.js';
|
|
10
|
+
import { componentEntriesFromDeployment, dedupeComponentEntriesByTag, mergeExplicitComponentEntries, readDeploymentDocument, } from './deployment-registry.js';
|
|
11
11
|
export { DEPLOYMENT_SCHEMA, readDeploymentDocument, componentEntriesFromDeployment, collectDependsOnClosure, dedupeComponentEntriesByTag, mergeExplicitComponentEntries, loadComponentEntries, importAndRegisterComponentEntries, bootstrapComponentRegistry, } from './deployment-registry.js';
|
|
12
12
|
export { createRenderHost } from './render-host.js';
|
|
13
13
|
/**
|
|
@@ -16,14 +16,23 @@ export { createRenderHost } from './render-host.js';
|
|
|
16
16
|
* @returns {Promise<Array<{ name: string, entry: string, chunkId?: string }>>}
|
|
17
17
|
*/
|
|
18
18
|
export async function listClientComponents(dir, opts = {}) {
|
|
19
|
-
const
|
|
19
|
+
const strict = opts.strict === true;
|
|
20
|
+
const deployment = readDeploymentDocument(dir, { strict });
|
|
20
21
|
if (deployment) {
|
|
21
|
-
return componentEntriesFromDeployment(deployment).map((e) => ({
|
|
22
|
+
return dedupeComponentEntriesByTag(componentEntriesFromDeployment(deployment).map((e) => ({
|
|
23
|
+
chunkId: e.chunkId,
|
|
24
|
+
name: e.name,
|
|
25
|
+
entry: e.entry,
|
|
26
|
+
source: e.source,
|
|
27
|
+
}))).map((e) => ({
|
|
22
28
|
name: e.name,
|
|
23
29
|
entry: e.entry,
|
|
24
30
|
chunkId: e.chunkId,
|
|
25
31
|
}));
|
|
26
32
|
}
|
|
33
|
+
if (strict) {
|
|
34
|
+
throw new Error(`vmz: missing vmz-deployment.json under ${dir} (strict deployment mode)`);
|
|
35
|
+
}
|
|
27
36
|
const folder = path.join(dir, 'components');
|
|
28
37
|
/** @type {string[]} */
|
|
29
38
|
let files = [];
|
|
@@ -48,14 +57,23 @@ export async function listClientComponents(dir, opts = {}) {
|
|
|
48
57
|
* @returns {Array<{ name: string, entry: string, chunkId?: string }>}
|
|
49
58
|
*/
|
|
50
59
|
export function listClientComponentsSync(dir, opts = {}) {
|
|
51
|
-
const
|
|
60
|
+
const strict = opts.strict === true;
|
|
61
|
+
const deployment = readDeploymentDocument(dir, { strict });
|
|
52
62
|
if (deployment) {
|
|
53
|
-
return componentEntriesFromDeployment(deployment).map((e) => ({
|
|
63
|
+
return dedupeComponentEntriesByTag(componentEntriesFromDeployment(deployment).map((e) => ({
|
|
64
|
+
chunkId: e.chunkId,
|
|
65
|
+
name: e.name,
|
|
66
|
+
entry: e.entry,
|
|
67
|
+
source: e.source,
|
|
68
|
+
}))).map((e) => ({
|
|
54
69
|
name: e.name,
|
|
55
70
|
entry: e.entry,
|
|
56
71
|
chunkId: e.chunkId,
|
|
57
72
|
}));
|
|
58
73
|
}
|
|
74
|
+
if (strict) {
|
|
75
|
+
throw new Error(`vmz: missing vmz-deployment.json under ${dir} (strict deployment mode)`);
|
|
76
|
+
}
|
|
59
77
|
const folder = path.join(dir, 'components');
|
|
60
78
|
/** @type {string[]} */
|
|
61
79
|
let files = [];
|
package/dist/serve-host.mjs
CHANGED
|
@@ -22,7 +22,7 @@ import http from 'node:http';
|
|
|
22
22
|
import { createRequire, registerHooks } from 'node:module';
|
|
23
23
|
import path from 'node:path';
|
|
24
24
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
25
|
-
import {
|
|
25
|
+
import { createRenderHost } from './render-host.js';
|
|
26
26
|
import { listClientComponents } from './list-client-components.js';
|
|
27
27
|
import { handleNodeRequest, setRoutes, setServerModuleResolver } from './vmz-runtime.js';
|
|
28
28
|
const require = createRequire(import.meta.url);
|
|
@@ -76,6 +76,8 @@ if (isDev) {
|
|
|
76
76
|
}
|
|
77
77
|
/** @type {number} */
|
|
78
78
|
let reloadToken = Date.now();
|
|
79
|
+
/** @type {Awaited<ReturnType<typeof createRenderHost>> | null} */
|
|
80
|
+
let ssrRenderHost = null;
|
|
79
81
|
/** @type {string | null} Correlatable build id from vmz dev (Living §12.8). */
|
|
80
82
|
let lastDevBuildId = null;
|
|
81
83
|
/** @type {Array<{ chunkId: string, pageRel: string, segs: ReturnType<typeof parseChunkSegments> }>} */
|
|
@@ -503,9 +505,17 @@ async function* emitPageHtml(Page, chunkId, eventOnlyShell, props = {}, opts = {
|
|
|
503
505
|
const pageDocMeta = resolvePageDocumentMeta(Page);
|
|
504
506
|
const prevLocaleHint = globalThis.__vmzLocaleIdHint;
|
|
505
507
|
globalThis.__vmzLocaleIdHint = localeId;
|
|
508
|
+
if (!ssrRenderHost) {
|
|
509
|
+
ssrRenderHost = await createRenderHost(distDir, {
|
|
510
|
+
strictDeployment: !isDev,
|
|
511
|
+
preload: 'none',
|
|
512
|
+
cacheBust: reloadToken,
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
await ssrRenderHost.ensureComponents([chunkId, ...layoutChain]);
|
|
506
516
|
let bodyHtml = '';
|
|
507
517
|
try {
|
|
508
|
-
for await (const chunk of renderToStream(Page, props, { signal })) {
|
|
518
|
+
for await (const chunk of ssrRenderHost.renderToStream(Page, props, { signal })) {
|
|
509
519
|
if (signal?.aborted)
|
|
510
520
|
return;
|
|
511
521
|
bodyHtml += chunk;
|
|
@@ -517,7 +527,7 @@ async function* emitPageHtml(Page, chunkId, eventOnlyShell, props = {}, opts = {
|
|
|
517
527
|
const Layout = await loadPageCtor(layoutChain[i]);
|
|
518
528
|
if (!Layout)
|
|
519
529
|
continue;
|
|
520
|
-
bodyHtml = await renderToString(Layout, {}, { signal, slotHtml: bodyHtml });
|
|
530
|
+
bodyHtml = await ssrRenderHost.renderToString(Layout, {}, { signal, slotHtml: bodyHtml });
|
|
521
531
|
if (signal?.aborted)
|
|
522
532
|
return;
|
|
523
533
|
}
|
|
@@ -709,28 +719,18 @@ async function softReload(opts = {}) {
|
|
|
709
719
|
catch {
|
|
710
720
|
localeArtifact = null;
|
|
711
721
|
}
|
|
712
|
-
const componentEntries = await listClientComponents(distDir);
|
|
722
|
+
const componentEntries = await listClientComponents(distDir, { strict: !isDev });
|
|
723
|
+
ssrRenderHost = await createRenderHost(distDir, {
|
|
724
|
+
strictDeployment: !isDev,
|
|
725
|
+
preload: 'none',
|
|
726
|
+
cacheBust: nextToken,
|
|
727
|
+
});
|
|
713
728
|
const nextCatalog = await listPageClientFiles(distDir);
|
|
714
729
|
if (!nextCatalog.length) {
|
|
715
730
|
throw new Error(`vmz serve: no pages/**/*.client.js in ${distDir}`);
|
|
716
731
|
}
|
|
717
|
-
/** @type {Record<string, any>} */
|
|
718
|
-
const components = {};
|
|
719
732
|
/** @type {Map<string, any>} */
|
|
720
733
|
const nextCtors = new Map();
|
|
721
|
-
const affectedNames = new Set(affected
|
|
722
|
-
.map((c) => String(c))
|
|
723
|
-
.filter((c) => c.startsWith('components/') || !c.includes('/'))
|
|
724
|
-
.map((c) => c.split('/').pop())
|
|
725
|
-
.filter(Boolean));
|
|
726
|
-
for (const entry of componentEntries) {
|
|
727
|
-
if (islandHmr && affectedNames.size > 0 && !affectedNames.has(entry.name)) {
|
|
728
|
-
continue;
|
|
729
|
-
}
|
|
730
|
-
const href = bustUrl(pathToFileURL(path.join(distDir, entry.entry)).href);
|
|
731
|
-
const mod = await import(href);
|
|
732
|
-
components[entry.name] = mod.default;
|
|
733
|
-
}
|
|
734
734
|
if (!islandHmr) {
|
|
735
735
|
const pagesToLoad = reloadAllPages ? nextCatalog : nextCatalog.filter((p) => pageNeedsReload(p.chunkId, affected));
|
|
736
736
|
for (const p of pagesToLoad) {
|
|
@@ -758,9 +758,6 @@ async function softReload(opts = {}) {
|
|
|
758
758
|
}
|
|
759
759
|
}
|
|
760
760
|
}
|
|
761
|
-
if (Object.keys(components).length) {
|
|
762
|
-
registerComponents(components);
|
|
763
|
-
}
|
|
764
761
|
const indexChunk = pageCatalog.find((p) => p.chunkId === 'pages/index')?.chunkId || pageCatalog[0].chunkId;
|
|
765
762
|
const resumeEntries = await loadPageResumeEntries(distDir, indexChunk);
|
|
766
763
|
const styleMeta = await loadDeploymentStyle(distDir);
|
package/dist/server.js
CHANGED
|
@@ -231,7 +231,9 @@ export async function handleNodeRequest(req, res, opts = {}) {
|
|
|
231
231
|
if (verb === 'GET' && opts.distDir) {
|
|
232
232
|
const nodePath = await import('node:path');
|
|
233
233
|
const { readFile, stat } = await import('node:fs/promises');
|
|
234
|
-
const file = await resolveDistStatic(opts.distDir, url.pathname, nodePath, stat
|
|
234
|
+
const file = await resolveDistStatic(opts.distDir, url.pathname, nodePath, stat, {
|
|
235
|
+
cookieHeader: String(req.headers.cookie || ''),
|
|
236
|
+
});
|
|
235
237
|
const hasSsr = typeof opts.renderPageStream === 'function' ||
|
|
236
238
|
typeof opts.renderPage === 'function' ||
|
|
237
239
|
typeof opts.renderIndexStream === 'function' ||
|