@vmz/vmz 0.3.12 → 0.3.13
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/delivery-runtime-files.json +1 -0
- package/dist/cli/cli.js +46 -23
- package/dist/cli/format-cmd.d.ts +9 -17
- package/dist/cli/format-cmd.js +37 -49
- package/dist/cli/format-config.d.ts +6 -9
- package/dist/cli/format-config.js +5 -29
- package/dist/delivery/delivery-profile.js +1 -1
- package/dist/dev/dev-session.js +16 -5
- package/dist/document/document-base-css.d.ts +15 -0
- package/dist/document/document-base-css.js +578 -0
- package/dist/document/document-build.d.ts +1 -0
- package/dist/document/document-build.js +94 -78
- package/dist/document/document-client.d.ts +13 -0
- package/dist/document/document-client.js +217 -0
- package/dist/document/document-cmd.js +3 -1
- package/dist/document/document-designs.d.ts +9 -3
- package/dist/document/document-designs.js +20 -34
- package/dist/document/document-enrich.d.ts +9 -0
- package/dist/document/document-enrich.js +55 -0
- package/dist/document/document-highlight.d.ts +26 -0
- package/dist/document/document-highlight.js +54 -0
- package/dist/document/document-integrate.d.ts +5 -0
- package/dist/document/document-integrate.js +1 -0
- package/dist/document/document-interactive.js +10 -2
- package/dist/document/document-layout-render.js +6 -2
- package/dist/document/document-schema.d.ts +5 -0
- package/dist/workspace/build-assemble.js +18 -6
- package/dist/workspace/content-addressed-assets.d.ts +6 -17
- package/dist/workspace/content-addressed-assets.js +10 -95
- package/dist/workspace/delivery-runtime-imports.js +3 -0
- package/dist/workspace/native-addon.d.ts +4 -0
- package/dist/workspace/pack-native.d.ts +139 -0
- package/dist/workspace/pack-native.js +273 -0
- package/dist/workspace/pack.d.ts +112 -32
- package/dist/workspace/pack.js +270 -65
- package/dist/workspace/plugin-host.d.ts +4 -4
- package/dist/workspace/plugin-host.js +6 -6
- package/dist/workspace/production-observability.d.ts +2 -0
- package/dist/workspace/production-observability.js +6 -2
- package/dist/workspace/project-build.js +26 -4
- package/dist/workspace/public-api.d.ts +7 -3
- package/dist/workspace/public-api.js +5 -3
- package/dist/workspace/static-emit.d.ts +30 -0
- package/dist/workspace/static-emit.js +211 -18
- package/dist/workspace/user-config.d.ts +112 -0
- package/dist/workspace/user-config.js +12 -0
- package/host-runtime-files.json +1 -0
- package/locales/en-US/cli.json +5 -4
- package/package.json +20 -20
- package/dist/workspace/pack-client-packages.d.ts +0 -34
- package/dist/workspace/pack-client-packages.js +0 -550
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
{ "src": "browser/resume/resume.js", "out": "browser/resume/resume.js" },
|
|
34
34
|
{ "src": "ssr/render.js", "out": "ssr/render.js" },
|
|
35
35
|
{ "src": "ssr/serialize.js", "out": "ssr/serialize.js" },
|
|
36
|
+
{ "src": "ssr/onmount.js", "out": "ssr/onmount.js" },
|
|
36
37
|
{ "src": "ssr/document.js", "out": "ssr/document.js" }
|
|
37
38
|
]
|
|
38
39
|
}
|
package/dist/cli/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Node CLI command implementations .
|
|
3
3
|
*/
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
|
+
import { existsSync, statSync } from 'node:fs';
|
|
5
6
|
import path from 'node:path';
|
|
6
7
|
import { createCli } from '@vmz/commander';
|
|
7
8
|
import { registerApplicationCommands } from './application-cmd.js';
|
|
@@ -14,7 +15,7 @@ import { buildIntegratedDocuments, projectHasDocuments } from '../document/docum
|
|
|
14
15
|
import { registerExplainCommand } from './explain-cmd.js';
|
|
15
16
|
import { registerGithubActionsCommand } from './github-actions-cmd.js';
|
|
16
17
|
import { registerInitCommands } from './init-cmd.js';
|
|
17
|
-
import { createWorkspace, getProtocolVersions, HOST_PROTOCOL, materializeServeHostRuntime, materializeWechatPackaging,
|
|
18
|
+
import { createWorkspace, getProtocolVersions, HOST_PROTOCOL, materializeServeHostRuntime, materializeWechatPackaging, resolveNativePath, } from '../workspace/public-api.js';
|
|
18
19
|
import { gateGlobalProjectCommand, getInvocationContext, isGlobalAllowedCommand } from '../workspace/invocation.js';
|
|
19
20
|
import { emitLocaleRuntimeModules, localeHasErrors } from '../locale/locale-check.js';
|
|
20
21
|
import { registerLocaleCommands } from '../locale/locale-cmd.js';
|
|
@@ -22,15 +23,17 @@ import { emitLocaleRouteRealization } from '../locale/locale-route-emit.js';
|
|
|
22
23
|
import { log } from '../workspace/log.js';
|
|
23
24
|
import { resolveCliLogLevel, setCliLogLevel } from '../workspace/log-level.js';
|
|
24
25
|
import { parseCliLogStyle, setCliLogStyle } from '../workspace/log-style.js';
|
|
25
|
-
import { packFromDeploymentIr } from '../workspace/pack.js';
|
|
26
|
+
import { ensureRuntimeCompanions, packFromDeploymentIr, packSsrFromDeploymentIr } from '../workspace/pack.js';
|
|
26
27
|
import { registerPlanCommands } from './plan-cmd.js';
|
|
27
28
|
import { loadVmzConfig } from '../workspace/plugin-host.js';
|
|
28
29
|
import { findAvailablePort } from '../workspace/port.js';
|
|
29
30
|
import { registerRefactorCommands } from './refactor-cmd.js';
|
|
30
31
|
import { registerArtifactCommands } from './release-cmd.js';
|
|
31
|
-
import { readPackageMeta, resolveWorkspaceDirs } from '../workspace/resolve.js';
|
|
32
|
+
import { findPackageJson, readPackageMeta, resolveWorkspaceDirs } from '../workspace/resolve.js';
|
|
32
33
|
import { emitRouteCatalog } from '../workspace/route-catalog-emit.js';
|
|
34
|
+
import { resolveCoreRuntimeDist } from '../workspace/runtime-dist.js';
|
|
33
35
|
import { registerTestCommand } from './test-cmd.js';
|
|
36
|
+
import { emitStaticBootstrapEntries } from '../workspace/static-emit.js';
|
|
34
37
|
export function printGlobalHelp() {
|
|
35
38
|
return buildProductCli({ mode: 'global' }).parse(['help']);
|
|
36
39
|
}
|
|
@@ -75,6 +78,7 @@ function buildProductCli(opts = {}) {
|
|
|
75
78
|
withServeExtras(withCoreOpts(cli.command('serve', 'cli.cmd.serve'))).action((options) => cmdServe(options));
|
|
76
79
|
withServeExtras(withCoreOpts(cli.command('dev', 'cli.cmd.dev'))).action((options) => cmdDev(options));
|
|
77
80
|
withCoreOpts(cli.command('format', 'cli.cmd.format'))
|
|
81
|
+
.option('--rust', 'cli.opt.format-rust')
|
|
78
82
|
.option('--no-javascript', 'cli.opt.format-no-javascript')
|
|
79
83
|
.option('--no-rust', 'cli.opt.format-no-rust')
|
|
80
84
|
.option('--no-vmz', 'cli.opt.format-no-vmz')
|
|
@@ -269,8 +273,21 @@ async function cmdBuild(args) {
|
|
|
269
273
|
if (routeCatalog.written.length) {
|
|
270
274
|
log.info(`route catalog (${routeCatalog.written.length} artifact(s))`);
|
|
271
275
|
}
|
|
276
|
+
if (!wechatPack) {
|
|
277
|
+
try {
|
|
278
|
+
// Node graph must be packed before any SSR consumer (document
|
|
279
|
+
// build, static emit, render host) imports a compiled chunk.
|
|
280
|
+
ensureRuntimeCompanions(outDir, resolveCoreRuntimeDist());
|
|
281
|
+
const nodePack = packSsrFromDeploymentIr(outDir, { projectRoot: project });
|
|
282
|
+
log.info(`node pack ok (entries=${nodePack.manifest.entryCount}, chunks=${nodePack.manifest.chunkCount}, digest=${String(nodePack.manifest.packDigest).slice(0, 12)}…)`);
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
log.error(`node pack failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
286
|
+
return 1;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
272
289
|
if (projectHasDocuments(project)) {
|
|
273
|
-
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
|
|
290
|
+
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir, engines: cfg.engines });
|
|
274
291
|
if (!docs.ok)
|
|
275
292
|
return 1;
|
|
276
293
|
}
|
|
@@ -299,21 +316,16 @@ async function cmdBuild(args) {
|
|
|
299
316
|
}
|
|
300
317
|
let pack = null;
|
|
301
318
|
try {
|
|
319
|
+
// Browser pack entries are the static bootstrap modules; static emit
|
|
320
|
+
// runs after pack (HTML resolves `_vmz/pack/`), so write them first.
|
|
321
|
+
emitStaticBootstrapEntries(outDir);
|
|
302
322
|
pack = packFromDeploymentIr(outDir, {
|
|
303
323
|
release: Boolean(args.release),
|
|
304
324
|
profileId: selected.selection.profileId,
|
|
305
325
|
assembly: selected.selection.assembly,
|
|
306
|
-
coreDist: resolveCoreRuntimeDist(),
|
|
307
326
|
projectRoot: project,
|
|
308
327
|
});
|
|
309
|
-
|
|
310
|
-
if (lower?.bareSpecs?.length) {
|
|
311
|
-
log.info(`pack client packages (${lower.bareSpecs.length} bare → vendor; rewritten=${lower.rewrittenFiles})`);
|
|
312
|
-
}
|
|
313
|
-
if (lower?.remainingBareSpecs?.length) {
|
|
314
|
-
log.warn(`pack client packages: ${lower.remainingBareSpecs.length} bare specifier(s) still unresolved for browser: ${lower.remainingBareSpecs.slice(0, 8).join(', ')}${lower.remainingBareSpecs.length > 8 ? '…' : ''}`);
|
|
315
|
-
}
|
|
316
|
-
log.info(`pack ok (units=${pack.manifest.unitCount}, digest=${String(pack.manifest.packDigest).slice(0, 12)}…)`);
|
|
328
|
+
log.info(`pack ok (entries=${pack.manifest.entryCount}, chunks=${pack.manifest.chunkCount}, digest=${String(pack.manifest.packDigest).slice(0, 12)}…)`);
|
|
317
329
|
}
|
|
318
330
|
catch (err) {
|
|
319
331
|
log.error(`pack failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -513,24 +525,35 @@ async function cmdDev(args) {
|
|
|
513
525
|
}
|
|
514
526
|
}
|
|
515
527
|
async function cmdFormat(args) {
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
}
|
|
528
|
+
const rawPath = args._[0];
|
|
529
|
+
if (typeof rawPath !== 'string' || rawPath.trim() === '') {
|
|
530
|
+
log.error('format: explicit <file|dir> path required — no implicit workspace scope (pass `.` for the current directory)');
|
|
531
|
+
return 1;
|
|
532
|
+
}
|
|
533
|
+
const target = path.resolve(process.cwd(), rawPath);
|
|
534
|
+
if (!existsSync(target)) {
|
|
535
|
+
log.error(`format: path does not exist: ${target}`);
|
|
536
|
+
return 1;
|
|
537
|
+
}
|
|
538
|
+
if (args.rust && args['no-rust']) {
|
|
539
|
+
log.error('format: conflicting `--rust` and `--no-rust`');
|
|
540
|
+
return 1;
|
|
541
|
+
}
|
|
542
|
+
const startDir = statSync(target).isDirectory() ? target : path.dirname(target);
|
|
543
|
+
const pkg = findPackageJson(startDir);
|
|
544
|
+
const configRoot = pkg ? path.dirname(pkg) : startDir;
|
|
521
545
|
const checkOnly = Boolean(args.check);
|
|
522
|
-
log.info(`format ${
|
|
546
|
+
log.info(`format ${target}${checkOnly ? ' --check' : ''}`);
|
|
523
547
|
const { runFormatCommand } = await import('./format-cmd.js');
|
|
524
548
|
return runFormatCommand({
|
|
525
|
-
|
|
526
|
-
|
|
549
|
+
target,
|
|
550
|
+
configRoot,
|
|
527
551
|
check: checkOnly,
|
|
528
552
|
overrides: {
|
|
529
553
|
javascript: args['no-javascript'] ? false : undefined,
|
|
530
|
-
rust: args['no-rust'] ? false : undefined,
|
|
554
|
+
rust: args.rust ? true : args['no-rust'] ? false : undefined,
|
|
531
555
|
vmz: args['no-vmz'] ? false : undefined,
|
|
532
556
|
},
|
|
533
|
-
createWorkspace,
|
|
534
557
|
});
|
|
535
558
|
}
|
|
536
559
|
function cmdLint(args) {
|
package/dist/cli/format-cmd.d.ts
CHANGED
|
@@ -1,28 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `vmz format` —
|
|
2
|
+
* `vmz format` — explicit-path formatter.
|
|
3
|
+
*
|
|
4
|
+
* Scope contract: the positional path is the whole scope. A file formats only
|
|
5
|
+
* itself; a directory is walked locally. Nothing ever falls back to a
|
|
6
|
+
* workspace-wide pass, and Rust runs per-file `rustfmt` — never `cargo fmt`.
|
|
3
7
|
*/
|
|
4
8
|
export type FormatCommandOptions = {
|
|
5
|
-
|
|
6
|
-
|
|
9
|
+
/** Absolute explicit file or directory (already validated to exist). */
|
|
10
|
+
target: string;
|
|
11
|
+
/** Project root used to load `vmz.config` and the style config. */
|
|
12
|
+
configRoot: string;
|
|
7
13
|
check: boolean;
|
|
8
14
|
overrides?: {
|
|
9
15
|
javascript?: boolean;
|
|
10
16
|
rust?: boolean;
|
|
11
17
|
vmz?: boolean;
|
|
12
18
|
};
|
|
13
|
-
createWorkspace: (opts: {
|
|
14
|
-
root: string;
|
|
15
|
-
outDir: string;
|
|
16
|
-
}) => {
|
|
17
|
-
format: (checkOnly?: boolean) => {
|
|
18
|
-
filesChecked: number;
|
|
19
|
-
filesWritten: number;
|
|
20
|
-
filesNeedWrite: number;
|
|
21
|
-
diagnostics?: Array<{
|
|
22
|
-
severity?: string;
|
|
23
|
-
}>;
|
|
24
|
-
};
|
|
25
|
-
dispose: () => void;
|
|
26
|
-
};
|
|
27
19
|
};
|
|
28
20
|
export declare function runFormatCommand(opts: FormatCommandOptions): Promise<number>;
|
package/dist/cli/format-cmd.js
CHANGED
|
@@ -1,65 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `vmz format` —
|
|
2
|
+
* `vmz format` — explicit-path formatter.
|
|
3
|
+
*
|
|
4
|
+
* Scope contract: the positional path is the whole scope. A file formats only
|
|
5
|
+
* itself; a directory is walked locally. Nothing ever falls back to a
|
|
6
|
+
* workspace-wide pass, and Rust runs per-file `rustfmt` — never `cargo fmt`.
|
|
3
7
|
*/
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import path from 'node:path';
|
|
4
10
|
import { loadNative } from '../workspace/public-api.js';
|
|
5
11
|
import { loadVmzConfig } from '../workspace/plugin-host.js';
|
|
6
12
|
import { log } from '../workspace/log.js';
|
|
7
13
|
import { resolveFormatConfig } from './format-config.js';
|
|
8
14
|
export async function runFormatCommand(opts) {
|
|
9
|
-
const {
|
|
10
|
-
const { format: formatConfig } = await loadVmzConfig(
|
|
11
|
-
const resolved = resolveFormatConfig(
|
|
12
|
-
if (opts.overrides?.javascript !== undefined)
|
|
13
|
-
resolved.javascript = opts.overrides.javascript;
|
|
14
|
-
if (opts.overrides?.rust !== undefined)
|
|
15
|
-
resolved.rust = opts.overrides.rust;
|
|
16
|
-
if (opts.overrides?.vmz !== undefined)
|
|
17
|
-
resolved.vmz = opts.overrides.vmz;
|
|
15
|
+
const { target, configRoot, check } = opts;
|
|
16
|
+
const { format: formatConfig } = await loadVmzConfig(configRoot);
|
|
17
|
+
const resolved = resolveFormatConfig(formatConfig);
|
|
18
18
|
const native = loadNative();
|
|
19
|
-
let
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
let report;
|
|
20
|
+
try {
|
|
21
|
+
report = native.formatTargetsRun({
|
|
22
|
+
targets: [target],
|
|
23
23
|
check,
|
|
24
|
-
|
|
24
|
+
rust: opts.overrides?.rust,
|
|
25
|
+
javascript: opts.overrides?.javascript,
|
|
26
|
+
vmz: opts.overrides?.vmz,
|
|
25
27
|
excludes: resolved.excludes,
|
|
26
|
-
|
|
27
|
-
javascript: resolved.javascript,
|
|
28
|
-
styleConfig: resolved.style,
|
|
28
|
+
styleConfig: path.resolve(configRoot, resolved.style),
|
|
29
29
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
log.error(err instanceof Error ? err.message : String(err));
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
let exit = 0;
|
|
36
|
+
for (const message of report.errors) {
|
|
37
|
+
log.error(message);
|
|
38
|
+
}
|
|
39
|
+
if (report.errors.length > 0)
|
|
40
|
+
exit = 1;
|
|
41
|
+
if (log.diagnostics(report.diagnostics ?? []))
|
|
42
|
+
exit = 1;
|
|
43
|
+
const scope = fs.statSync(target).isDirectory() ? `${target}${path.sep}` : target;
|
|
44
|
+
if (check) {
|
|
45
|
+
log.info(`format ${scope}: ${report.needWrite} file(s) would change, ${report.unchanged} unchanged`);
|
|
46
|
+
if (report.needWrite > 0)
|
|
34
47
|
exit = 1;
|
|
35
|
-
}
|
|
36
|
-
else if (check && report.formatted === 0 && report.unchanged > 0) {
|
|
37
|
-
log.info(`workspace format: no changes needed (${report.unchanged} file(s) checked)`);
|
|
38
|
-
}
|
|
39
|
-
else if (!check) {
|
|
40
|
-
log.info(`workspace format: ${report.formatted} file(s) updated, ${report.unchanged} unchanged`);
|
|
41
|
-
}
|
|
42
48
|
}
|
|
43
|
-
|
|
44
|
-
log.info(`format
|
|
45
|
-
const ws = createWorkspace({ root: project, outDir });
|
|
46
|
-
try {
|
|
47
|
-
const report = ws.format(check);
|
|
48
|
-
const errors = log.diagnostics(report.diagnostics ?? []);
|
|
49
|
-
if (check) {
|
|
50
|
-
log.info(`checked ${report.filesChecked} .vmz file(s); ${report.filesNeedWrite} need write`);
|
|
51
|
-
if (report.filesNeedWrite > 0)
|
|
52
|
-
exit = 1;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
log.info(`formatted ${report.filesWritten}/${report.filesChecked} .vmz file(s)`);
|
|
56
|
-
}
|
|
57
|
-
if (errors)
|
|
58
|
-
exit = 1;
|
|
59
|
-
}
|
|
60
|
-
finally {
|
|
61
|
-
ws.dispose();
|
|
62
|
-
}
|
|
49
|
+
else {
|
|
50
|
+
log.info(`format ${scope}: ${report.formatted} file(s) updated, ${report.unchanged} unchanged`);
|
|
63
51
|
}
|
|
64
52
|
return exit;
|
|
65
53
|
}
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `vmz.config` `format` resolution for `vmz format`.
|
|
3
|
+
*
|
|
4
|
+
* Scope always comes from the explicit CLI path — config only narrows
|
|
5
|
+
* (`excludes`) and styles. There are no config-driven `includes`.
|
|
3
6
|
*/
|
|
4
|
-
import type { VmzFormatConfig } from '
|
|
7
|
+
import type { VmzFormatConfig } from '../workspace/user-config.js';
|
|
5
8
|
export type ResolvedFormatOptions = {
|
|
6
|
-
includes?: string[];
|
|
7
9
|
excludes: string[];
|
|
8
|
-
rust: boolean;
|
|
9
|
-
javascript: boolean;
|
|
10
|
-
vmz: boolean;
|
|
11
10
|
style: string;
|
|
12
11
|
};
|
|
13
|
-
/**
|
|
14
|
-
export declare
|
|
15
|
-
/** Merge `vmz.config` `format` with framework monorepo defaults. */
|
|
16
|
-
export declare function resolveFormatConfig(projectRoot: string, format?: VmzFormatConfig): ResolvedFormatOptions;
|
|
12
|
+
/** Merge `vmz.config` `format` excludes / style with the defaults. */
|
|
13
|
+
export declare function resolveFormatConfig(format?: VmzFormatConfig | null): ResolvedFormatOptions;
|
|
@@ -1,38 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `vmz.config` `format` resolution for `vmz format`.
|
|
3
|
+
*
|
|
4
|
+
* Scope always comes from the explicit CLI path — config only narrows
|
|
5
|
+
* (`excludes`) and styles. There are no config-driven `includes`.
|
|
3
6
|
*/
|
|
4
|
-
import { existsSync } from 'node:fs';
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
/** VMZ hybrid monorepo — JS/TS surfaces only, never whole-repo walk. */
|
|
7
|
-
export const VMZ_FRAMEWORK_INCLUDES = [
|
|
8
|
-
'scripts/**',
|
|
9
|
-
'packages/runtimes/**',
|
|
10
|
-
'packages/examples/**',
|
|
11
|
-
'packages/editors/**',
|
|
12
|
-
'packages/ui/**',
|
|
13
|
-
'packages/plugins/**',
|
|
14
|
-
'packages/content/**',
|
|
15
|
-
'packages/homepage/**',
|
|
16
|
-
'package.json',
|
|
17
|
-
'biome.json',
|
|
18
|
-
'vmz.config.ts',
|
|
19
|
-
'nifty.config.ts',
|
|
20
|
-
];
|
|
21
7
|
const DEFAULT_EXCLUDES = ['**/fixtures/**', '**/dist/**', '**/node_modules/**', '**/target/**'];
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
/** Merge `vmz.config` `format` with framework monorepo defaults. */
|
|
26
|
-
export function resolveFormatConfig(projectRoot, format) {
|
|
27
|
-
const frameworkRoot = isFrameworkMonorepoRoot(projectRoot);
|
|
28
|
-
const hasCargo = existsSync(path.join(projectRoot, 'Cargo.toml'));
|
|
29
|
-
const hasFormatSection = format !== undefined;
|
|
8
|
+
/** Merge `vmz.config` `format` excludes / style with the defaults. */
|
|
9
|
+
export function resolveFormatConfig(format) {
|
|
30
10
|
return {
|
|
31
|
-
includes: format?.includes ?? (frameworkRoot ? [...VMZ_FRAMEWORK_INCLUDES] : undefined),
|
|
32
11
|
excludes: [...DEFAULT_EXCLUDES, ...(format?.excludes ?? [])],
|
|
33
|
-
rust: format?.rust ?? (hasCargo && (frameworkRoot || hasFormatSection)),
|
|
34
|
-
javascript: format?.javascript ?? (frameworkRoot || hasFormatSection),
|
|
35
|
-
vmz: format?.vmz ?? true,
|
|
36
12
|
style: format?.style ?? 'biome.json',
|
|
37
13
|
};
|
|
38
14
|
}
|
|
@@ -391,7 +391,7 @@ export function semanticIdsForAssembly(assembly) {
|
|
|
391
391
|
case 'rust-embedded':
|
|
392
392
|
return ['site-fallback', 'asset-graph'];
|
|
393
393
|
case 'local-static':
|
|
394
|
-
return ['asset-graph'];
|
|
394
|
+
return ['static-delivery', 'asset-graph'];
|
|
395
395
|
default:
|
|
396
396
|
return [];
|
|
397
397
|
}
|
package/dist/dev/dev-session.js
CHANGED
|
@@ -14,6 +14,7 @@ import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
|
14
14
|
import path from 'node:path';
|
|
15
15
|
import { buildIntegratedDocuments, projectHasDocuments } from '../document/document-integrate.js';
|
|
16
16
|
import { createWorkspace, resolveNativePath } from '../workspace/public-api.js';
|
|
17
|
+
import { loadVmzConfig } from '../workspace/plugin-host.js';
|
|
17
18
|
import { materializeWechatPackaging } from '../workspace/wechat-packaging.js';
|
|
18
19
|
import { emitLocaleRuntimeModules, localeHasErrors } from '../locale/locale-check.js';
|
|
19
20
|
import { log } from '../workspace/log.js';
|
|
@@ -199,6 +200,16 @@ export function createDevSession(options) {
|
|
|
199
200
|
return 'respawn';
|
|
200
201
|
}
|
|
201
202
|
}
|
|
203
|
+
let docEnginesPromise = null;
|
|
204
|
+
/** `engines.code` / `engines.markdown` for the document layer (loaded once per session). */
|
|
205
|
+
function docEngines() {
|
|
206
|
+
if (!docEnginesPromise) {
|
|
207
|
+
docEnginesPromise = loadVmzConfig(project)
|
|
208
|
+
.then((cfg) => cfg.engines)
|
|
209
|
+
.catch(() => undefined);
|
|
210
|
+
}
|
|
211
|
+
return docEnginesPromise;
|
|
212
|
+
}
|
|
202
213
|
async function start() {
|
|
203
214
|
const src = path.join(project, 'src');
|
|
204
215
|
if (!existsSync(src)) {
|
|
@@ -226,7 +237,7 @@ export function createDevSession(options) {
|
|
|
226
237
|
// Reclaim orphan serve-host from a previous crashed launcher (same outDir).
|
|
227
238
|
reclaimStaleDevHost(outDir);
|
|
228
239
|
if (projectHasDocuments(project)) {
|
|
229
|
-
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
|
|
240
|
+
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir, engines: await docEngines() });
|
|
230
241
|
if (!docs.ok) {
|
|
231
242
|
throw new Error('vmz dev: integrated document build failed');
|
|
232
243
|
}
|
|
@@ -533,7 +544,7 @@ export function createDevSession(options) {
|
|
|
533
544
|
}
|
|
534
545
|
dependencyRoots = [...refreshed.dependencyRoots];
|
|
535
546
|
if (batch.docsDirty || projectHasDocuments(project)) {
|
|
536
|
-
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
|
|
547
|
+
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir, engines: await docEngines() });
|
|
537
548
|
if (!docs.ok)
|
|
538
549
|
log.warn('document mount rebuild failed — keeping previous docs');
|
|
539
550
|
}
|
|
@@ -563,7 +574,7 @@ export function createDevSession(options) {
|
|
|
563
574
|
}
|
|
564
575
|
await emitPublicAndTrack();
|
|
565
576
|
if (batch.docsDirty || projectHasDocuments(project)) {
|
|
566
|
-
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
|
|
577
|
+
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir, engines: await docEngines() });
|
|
567
578
|
if (!docs.ok) {
|
|
568
579
|
log.warn('document mount rebuild failed — keeping previous docs');
|
|
569
580
|
}
|
|
@@ -605,7 +616,7 @@ export function createDevSession(options) {
|
|
|
605
616
|
}
|
|
606
617
|
await emitPublicAndTrack();
|
|
607
618
|
if (batch.docsDirty || projectHasDocuments(project)) {
|
|
608
|
-
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
|
|
619
|
+
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir, engines: await docEngines() });
|
|
609
620
|
if (!docs.ok)
|
|
610
621
|
log.warn('document mount rebuild failed — keeping previous docs');
|
|
611
622
|
}
|
|
@@ -646,7 +657,7 @@ export function createDevSession(options) {
|
|
|
646
657
|
}
|
|
647
658
|
if (batch.docsDirty) {
|
|
648
659
|
log.info('documents change detected — rebuilding document mount…');
|
|
649
|
-
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
|
|
660
|
+
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir, engines: await docEngines() });
|
|
650
661
|
if (!docs.ok) {
|
|
651
662
|
log.warn('document mount rebuild failed — keeping previous docs');
|
|
652
663
|
continue;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-owned document base stylesheet (`assets/vmz-document.css`).
|
|
3
|
+
*
|
|
4
|
+
* The single canonical document surface for every site: sidebar + article +
|
|
5
|
+
* toc grid, article type scale, code/table/quote blocks, island shells and the
|
|
6
|
+
* responsive breakpoints. Structural colors come from `--vmz-*` semantic tokens
|
|
7
|
+
* only (site brand flows in through the compiled `vmz-designs.css`); syntax
|
|
8
|
+
* colors inside code blocks come from the Shiki theme and stay identical on
|
|
9
|
+
* every site. Sites do not ship document stylesheets.
|
|
10
|
+
*
|
|
11
|
+
* House rules (规划设计/vmz 05): pure-white base with near-black blocks for
|
|
12
|
+
* rhythm, body text ≥ 16px, small text ≥ 12px at weight ≥ 400, no uppercase
|
|
13
|
+
* letter-spaced micro labels, no 3D / volumetric surfaces.
|
|
14
|
+
*/
|
|
15
|
+
export declare const DOCUMENT_BASE_CSS = "/* vmz document layer \u2014 canonical document surface (token-driven). */\n\n.site--docs {\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n background: var(--vmz-surface-paper, #ffffff);\n}\n\n.site--docs > .doc-body {\n flex: 1 0 auto;\n display: grid;\n grid-template-columns: 17rem minmax(0, 1fr);\n align-items: start;\n width: 100%;\n max-width: 94rem;\n margin: 0 auto;\n}\n\n/* Sidebar -------------------------------------------------------------- */\n\n.doc-sidebar {\n position: sticky;\n top: var(--vmz-layout-header-height-compact, 3.5rem);\n align-self: start;\n max-height: calc(100vh - var(--vmz-layout-header-height-compact, 3.5rem));\n overflow-y: auto;\n padding: 2rem 1.25rem 3rem 1.5rem;\n border-right: 1px solid var(--vmz-line-default, #e5e6eb);\n}\n\n/* Density activation lives in this framework layer: sites only ship tokens. */\n\n:where([data-density=\"compact\"]) .doc-sidebar {\n padding-top: var(--vmz-density-compact-padding-y, 1.5rem);\n padding-bottom: 2rem;\n}\n\n:where([data-density=\"dense\"]) .doc-sidebar {\n padding-top: var(--vmz-density-dense-padding-y, 1rem);\n padding-bottom: 1.5rem;\n}\n\n.doc-sidebar__label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--vmz-text-muted, #6b7178);\n margin: 0 0 var(--vmz-density-control-padding-y, 0.75rem);\n}\n\n.doc-subnav ul {\n list-style: none;\n margin: 0;\n padding: 0;\n display: grid;\n gap: 2px;\n}\n\n.doc-subnav a {\n display: block;\n padding: 0.4375rem 0.625rem;\n font-size: 0.875rem;\n line-height: 1.45;\n color: var(--vmz-text-steel, #51565d);\n text-decoration: none;\n border-left: 2px solid transparent;\n border-radius: 0 4px 4px 0;\n transition: color 120ms ease, background 120ms ease, border-color 120ms ease;\n}\n\n.doc-subnav a:hover {\n color: var(--vmz-text-ink, #1f2329);\n background: var(--vmz-surface-mist, #f7f8fa);\n text-decoration: none;\n}\n\n.doc-subnav a[aria-current=\"page\"] {\n color: var(--vmz-brand-primary, #1677ff);\n border-left-color: var(--vmz-brand-primary, #1677ff);\n background: var(--vmz-surface-paper, #ffffff);\n font-weight: 500;\n}\n\n.doc-search {\n margin-top: 1rem;\n padding-top: 0.75rem;\n border-top: 1px solid var(--vmz-line-default, #e5e6eb);\n position: relative;\n}\n\n.doc-search__input {\n width: 100%;\n box-sizing: border-box;\n padding: 0.4375rem 0.625rem;\n font-size: 0.875rem;\n line-height: 1.4;\n color: var(--vmz-text-ink, #1f2329);\n background: var(--vmz-surface-paper, #ffffff);\n border: 1px solid var(--vmz-line-default, #e5e6eb);\n border-radius: 6px;\n}\n\n.doc-search__input:focus-visible {\n outline: 2px solid var(--vmz-brand-primary, #1677ff);\n outline-offset: 1px;\n}\n\n.doc-search__results {\n list-style: none;\n margin: 0.375rem 0 0;\n padding: 0.25rem;\n display: grid;\n gap: 1px;\n background: var(--vmz-surface-paper, #ffffff);\n border: 1px solid var(--vmz-line-default, #e5e6eb);\n border-radius: 6px;\n max-height: 16rem;\n overflow-y: auto;\n}\n\n.doc-search__results[hidden] {\n display: none;\n}\n\n.doc-search__results a {\n display: block;\n padding: 0.375rem 0.5rem;\n font-size: 0.8125rem;\n line-height: 1.4;\n color: var(--vmz-text-steel, #51565d);\n text-decoration: none;\n border-radius: 4px;\n overflow-wrap: break-word;\n}\n\n.doc-search__ctx {\n color: var(--vmz-text-muted, #6b7178);\n}\n\n.doc-search__results li[aria-selected=\"true\"] a,\n.doc-search__results a:hover {\n background: var(--vmz-surface-mist, #f7f8fa);\n color: var(--vmz-text-ink, #1f2329);\n}\n\n.doc-search__empty {\n padding: 0.375rem 0.5rem;\n font-size: 0.8125rem;\n color: var(--vmz-text-muted, #6b7178);\n}\n\n.doc-search__hint {\n margin: 0.375rem 0 0;\n font-size: 0.75rem;\n line-height: 1.5;\n color: var(--vmz-text-muted, #6b7178);\n}\n\n/* Content grid --------------------------------------------------------- */\n\n.doc-content {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 13rem;\n gap: 3rem;\n padding: 3rem 3rem 4rem;\n min-width: 0;\n}\n\n.doc-content > main {\n min-width: 0;\n max-width: 46rem;\n}\n\n/* Breadcrumb ----------------------------------------------------------- */\n\n.doc-breadcrumb {\n font-size: 0.875rem;\n line-height: 1.5;\n color: var(--vmz-text-muted, #6b7178);\n margin: 0 0 2rem;\n display: flex;\n gap: 0.375rem;\n align-items: baseline;\n}\n\n.doc-breadcrumb a {\n color: var(--vmz-text-steel, #51565d);\n text-decoration: none;\n}\n\n.doc-breadcrumb a:hover {\n color: var(--vmz-brand-primary, #1677ff);\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.doc-breadcrumb [aria-current] {\n color: var(--vmz-text-ink, #1f2329);\n font-weight: 500;\n}\n\n/* On this page --------------------------------------------------------- */\n\n.toc {\n position: sticky;\n top: calc(var(--vmz-layout-header-height-compact, 3.5rem) + 1.25rem);\n align-self: start;\n order: 2;\n border-left: 1px solid var(--vmz-line-subtle, #f0f1f3);\n padding-left: 1rem;\n}\n\n.toc__label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--vmz-text-muted, #6b7178);\n margin: 0 0 0.5rem;\n}\n\n.toc ol {\n list-style: none;\n margin: 0;\n padding: 0;\n display: grid;\n gap: 0.25rem;\n}\n\n.toc a {\n color: var(--vmz-text-steel, #51565d);\n text-decoration: none;\n display: block;\n line-height: 1.4;\n font-size: 0.75rem;\n}\n\n.toc a:hover {\n color: var(--vmz-brand-primary, #1677ff);\n}\n\n.toc .h3 {\n padding-left: 0.75rem;\n color: var(--vmz-text-muted, #6b7178);\n}\n\n/* Article typography --------------------------------------------------- */\n\n.doc-content main h1 {\n font-family: var(--vmz-font-display, var(--vmz-font-sans, sans-serif));\n font-size: clamp(2rem, 2.8vw, 2.5rem);\n font-weight: 650;\n letter-spacing: -0.03em;\n line-height: 1.12;\n margin: 0 0 1.25rem;\n color: var(--vmz-text-ink, #1f2329);\n}\n\n.doc-content main h2 {\n font-size: 1.4375rem;\n letter-spacing: -0.02em;\n margin: 3rem 0 0.875rem;\n color: var(--vmz-text-ink, #1f2329);\n}\n\n.doc-content main h3 {\n font-size: 1.125rem;\n margin: 2rem 0 0.5rem;\n color: var(--vmz-text-ink, #1f2329);\n}\n\n.doc-content main h4 {\n font-size: 1rem;\n margin: 1.75rem 0 0.375rem;\n color: var(--vmz-text-ink, #1f2329);\n}\n\n.doc-content main p,\n.doc-content main li {\n font-size: 1rem;\n line-height: 1.75;\n color: var(--vmz-text-steel, #51565d);\n}\n\n.doc-content main p {\n margin: 0 0 1.125rem;\n}\n\n.doc-content main ul,\n.doc-content main ol {\n margin: 0 0 1.25rem;\n padding-left: 1.375rem;\n}\n\n.doc-content main li + li {\n margin-top: 0.375rem;\n}\n\n.doc-content main li::marker {\n color: var(--vmz-line-strong, #c9cdd4);\n}\n\n.doc-content main a {\n color: var(--vmz-brand-primary, #1677ff);\n text-decoration: underline;\n text-underline-offset: 2px;\n text-decoration-color: var(--vmz-line-strong, #c9cdd4);\n overflow-wrap: break-word;\n}\n\n.doc-content main a:hover {\n text-decoration-color: var(--vmz-brand-primary, #1677ff);\n}\n\n.doc-content main strong {\n color: var(--vmz-text-ink, #1f2329);\n font-weight: 600;\n}\n\n.doc-content main hr {\n border: 0;\n border-top: 1px solid var(--vmz-line-default, #e5e6eb);\n margin: 1.75rem 0;\n}\n\n/* Inline code */\n.doc-content main :not(pre) > code {\n font-family: var(--vmz-font-mono, ui-monospace, monospace);\n font-size: 0.875rem;\n color: var(--vmz-text-ink, #1f2329);\n background: var(--vmz-surface-mist, #f7f8fa);\n border: 1px solid var(--vmz-line-subtle, #f0f1f3);\n border-radius: 4px;\n padding: 0.0625rem 0.3125rem;\n word-break: break-word;\n}\n\n/* Code blocks: near-black surface, token chrome, theme-owned syntax colors */\n.doc-content main pre {\n position: relative;\n margin: 0 0 1.375rem;\n padding: 1.125rem 1.25rem;\n overflow-x: auto;\n border: 1px solid var(--vmz-line-default, #e5e6eb);\n border-radius: 8px;\n background: var(--vmz-surface-code, #0f1115);\n color: var(--vmz-text-on-ink, #f7f8fa);\n font-size: 0.84375rem;\n line-height: 1.7;\n tab-size: 4;\n}\n\n/* Copy button (injected by assets/vmz-document.js; hidden without JS) */\n.doc-copy {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n padding: 0.1875rem 0.5rem;\n font-size: 0.75rem;\n font-weight: 400;\n line-height: 1.4;\n color: var(--vmz-text-muted, #6b7178);\n background: var(--vmz-surface-mist, #f7f8fa);\n border: 1px solid var(--vmz-line-default, #e5e6eb);\n border-radius: 4px;\n cursor: pointer;\n opacity: 0;\n transition: opacity 120ms ease;\n}\n\npre:hover .doc-copy,\npre:focus-within .doc-copy,\n.doc-copy:focus-visible {\n opacity: 1;\n}\n\n.doc-copy--done {\n color: var(--vmz-status-success-accent, #237804);\n}\n\n/* Heading self anchors (build-time, no-JS usable) */\n.h-anchor {\n margin-left: 0.4em;\n font-size: 0.8em;\n font-weight: 400;\n text-decoration: none;\n color: var(--vmz-text-muted, #6b7178);\n opacity: 0;\n transition: opacity 120ms ease;\n}\n\n.doc-content main h2:hover .h-anchor,\n.doc-content main h3:hover .h-anchor,\n.doc-content main h4:hover .h-anchor,\n.h-anchor:focus-visible {\n opacity: 1;\n}\n\n.doc-content main pre code {\n font-family: var(--vmz-font-mono, ui-monospace, monospace);\n font-size: inherit;\n background: transparent;\n border: 0;\n padding: 0;\n color: inherit;\n}\n\n/* Tables */\n.doc-content main table {\n width: 100%;\n border-collapse: separate;\n border-spacing: 0;\n margin: 0.75rem 0 1.5rem;\n font-size: 0.9375rem;\n border: 1px solid var(--vmz-line-default, #e5e6eb);\n border-radius: 10px;\n display: block;\n overflow-x: auto;\n}\n\n.doc-content main thead th {\n background: var(--vmz-surface-mist, #f7f8fa);\n border-bottom: 1px solid var(--vmz-line-default, #e5e6eb);\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--vmz-text-muted, #6b7178);\n text-align: left;\n padding: 0.6875rem 1rem;\n white-space: nowrap;\n}\n\n.doc-content main td,\n.doc-content main tbody th {\n border-bottom: 1px solid var(--vmz-line-subtle, #f0f1f3);\n padding: 0.6875rem 1rem;\n vertical-align: top;\n line-height: 1.6;\n color: var(--vmz-text-steel, #51565d);\n}\n\n.doc-content main tbody tr:last-child td {\n border-bottom: 0;\n}\n\n.doc-content main tbody tr:hover td {\n background: var(--vmz-surface-fill, #fafbfc);\n}\n\n.doc-content main td code {\n font-size: 0.8125rem;\n}\n\n/* Blockquote / callouts */\n.doc-content main blockquote {\n margin: 0 0 1.25rem;\n padding: 0.875rem 1.125rem;\n border: 1px solid var(--vmz-line-default, #e5e6eb);\n border-left: 3px solid var(--vmz-brand-primary, #1677ff);\n border-radius: 0 8px 8px 0;\n background: var(--vmz-surface-mist, #f7f8fa);\n font-size: 1rem;\n color: var(--vmz-text-steel, #51565d);\n}\n\n.doc-content main blockquote p {\n margin: 0;\n font-size: 1rem;\n}\n\n.doc-content main .warn {\n background: var(--vmz-status-warning-background, #fff7e6);\n border: 1px solid var(--vmz-status-warning-border, #ffe7ba);\n border-left: 3px solid var(--vmz-status-warning-accent, #d48806);\n color: var(--vmz-status-warning-foreground, #ad6800);\n padding: 0.875rem 1.125rem;\n border-radius: 0 8px 8px 0;\n margin: 0 0 1.25rem;\n font-size: 0.9375rem;\n line-height: 1.65;\n}\n\n.doc-content main .warn p {\n color: inherit;\n font-size: inherit;\n margin: 0;\n}\n\n/* Playground / island shells */\n.doc-content main [data-vmz-island],\n.doc-content main .doc-playground {\n border: 1px solid var(--vmz-line-default, #e5e6eb);\n border-radius: var(--vmz-radius-xs, 4px);\n background: var(--vmz-surface-fill, #fafbfc);\n padding: 0.75rem;\n margin: 0 0 1rem;\n}\n\n.doc-content main .doc-playground-source,\n.doc-content main .doc-playground-fallback {\n font-size: 0.8125rem;\n color: var(--vmz-text-muted, #6b7178);\n}\n\n/* Standalone mount emits the same .site.site--docs > .doc-body skeleton as\n the integrated shell \u2014 no second DOM shape. */\n\n.skip-link {\n position: absolute;\n left: -999px;\n top: 0.75rem;\n z-index: 50;\n padding: 0.45rem 0.75rem;\n background: var(--vmz-brand-primary, #1677ff);\n color: var(--vmz-text-on-brand, #ffffff);\n text-decoration: none;\n}\n\n.skip-link:focus {\n left: 0.75rem;\n}\n\n/* Responsive ------------------------------------------------------------ */\n\n@media (max-width: 1100px) {\n .doc-content {\n grid-template-columns: minmax(0, 1fr);\n padding: 1.75rem 1.5rem 2.5rem;\n }\n\n .toc {\n position: static;\n order: -1;\n border-left: 0;\n border-bottom: 1px solid var(--vmz-line-subtle, #f0f1f3);\n padding: 0 0 0.75rem;\n margin-bottom: 1.5rem;\n }\n}\n\n@media (max-width: 860px) {\n .site--docs > .doc-body,\n body > .doc-body {\n grid-template-columns: 1fr;\n }\n\n .doc-sidebar {\n position: static;\n max-height: none;\n border-right: 0;\n border-bottom: 1px solid var(--vmz-line-default, #e5e6eb);\n padding: 1rem;\n }\n\n .doc-content {\n padding: 1.25rem 1rem 2rem;\n }\n\n .doc-content main h1 {\n font-size: 1.375rem;\n }\n\n .doc-content main pre {\n font-size: 0.75rem;\n }\n}\n";
|