@vmz/vmz 0.0.0 → 0.0.2

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.
Files changed (75) hide show
  1. package/README.md +48 -2
  2. package/bin/vmz.js +4 -0
  3. package/dist/application-cmd.d.ts +22 -0
  4. package/dist/application-cmd.js +348 -0
  5. package/dist/bundler-adapter.d.ts +64 -0
  6. package/dist/bundler-adapter.js +111 -0
  7. package/dist/cli.d.ts +15 -0
  8. package/dist/cli.js +370 -0
  9. package/dist/dev-session.d.ts +35 -0
  10. package/dist/dev-session.js +290 -0
  11. package/dist/document-build.d.ts +99 -0
  12. package/dist/document-build.js +274 -0
  13. package/dist/document-check.d.ts +44 -0
  14. package/dist/document-check.js +246 -0
  15. package/dist/document-cmd.d.ts +9 -0
  16. package/dist/document-cmd.js +147 -0
  17. package/dist/document-designs.d.ts +9 -0
  18. package/dist/document-designs.js +126 -0
  19. package/dist/document-enrich.d.ts +23 -0
  20. package/dist/document-enrich.js +234 -0
  21. package/dist/document-evidence.d.ts +49 -0
  22. package/dist/document-evidence.js +501 -0
  23. package/dist/document-integrate.d.ts +35 -0
  24. package/dist/document-integrate.js +89 -0
  25. package/dist/document-interactive.d.ts +69 -0
  26. package/dist/document-interactive.js +255 -0
  27. package/dist/document-locale.d.ts +31 -0
  28. package/dist/document-locale.js +59 -0
  29. package/dist/document-markdown.d.ts +13 -0
  30. package/dist/document-markdown.js +39 -0
  31. package/dist/document-scan.d.ts +21 -0
  32. package/dist/document-scan.js +151 -0
  33. package/dist/document-schema.d.ts +87 -0
  34. package/dist/document-schema.js +88 -0
  35. package/dist/explain-cmd.d.ts +5 -0
  36. package/dist/explain-cmd.js +123 -0
  37. package/dist/index.d.ts +808 -0
  38. package/dist/index.js +569 -0
  39. package/dist/locale-check.d.ts +106 -0
  40. package/dist/locale-check.js +737 -0
  41. package/dist/locale-cmd.d.ts +5 -0
  42. package/dist/locale-cmd.js +443 -0
  43. package/dist/locale-delivery.d.ts +298 -0
  44. package/dist/locale-delivery.js +444 -0
  45. package/dist/locale-router.d.ts +207 -0
  46. package/dist/locale-router.js +508 -0
  47. package/dist/locale-runtime.d.ts +406 -0
  48. package/dist/locale-runtime.js +542 -0
  49. package/dist/locale-schema.d.ts +9 -0
  50. package/dist/locale-schema.js +10 -0
  51. package/dist/locale-tooling.d.ts +118 -0
  52. package/dist/locale-tooling.js +358 -0
  53. package/dist/log.d.ts +19 -0
  54. package/dist/log.js +42 -0
  55. package/dist/packages.d.ts +27 -0
  56. package/dist/packages.js +147 -0
  57. package/dist/plugin-host.d.ts +30 -0
  58. package/dist/plugin-host.js +370 -0
  59. package/dist/refactor-cmd.d.ts +8 -0
  60. package/dist/refactor-cmd.js +156 -0
  61. package/dist/resolve.d.ts +25 -0
  62. package/dist/resolve.js +56 -0
  63. package/dist/test-cmd.d.ts +9 -0
  64. package/dist/test-cmd.js +343 -0
  65. package/dist/test-compile.d.ts +2 -0
  66. package/dist/test-compile.js +3 -0
  67. package/dist/test-discover.d.ts +2 -0
  68. package/dist/test-discover.js +3 -0
  69. package/dist/test-logic.d.ts +2 -0
  70. package/dist/test-logic.js +3 -0
  71. package/dist/test-protocol.d.ts +2 -0
  72. package/dist/test-protocol.js +3 -0
  73. package/dist/watch-diff.d.ts +17 -0
  74. package/dist/watch-diff.js +56 -0
  75. package/package.json +86 -4
package/README.md CHANGED
@@ -1,3 +1,49 @@
1
- # @vmz/vmz
1
+ # VMZ CLI
2
2
 
3
- Placeholder package (0.0.0). Reserved for the VMZ project. Do not depend on this version.
3
+ When a project reaches the point where it has a browser surface, SSR, server work, documents, tests, and several
4
+ deployment concerns, the usual workflow becomes a chain of tools that each see a different version of the application. A
5
+ build may pass while a route boundary is wrong; a browser test may pass while SSR work is replayed; a plugin may
6
+ transform code without anyone being able to explain the delivery result.
7
+
8
+ `vmz` is the command-line home for a different workflow. Development, checking, building, serving, testing, document
9
+ generation, and deployment output all begin from VMZ's understanding of the same application. The useful unit is not
10
+ only a module graph. It is a program with state reads and writes, control regions, routes, server capabilities,
11
+ ownership, and delivery boundaries.
12
+
13
+ That means the CLI can grow into something more useful than a collection of commands: it can say why a change affects a
14
+ region, why code was placed on the client, why a conservative boundary was used, or why a route and its server work
15
+ belong together. ⚡
16
+
17
+ With VMZ, a normal workflow is expected to answer all of these from the same source program:
18
+
19
+ - **Develop:** which application regions are affected by a change?
20
+ - **Check:** which state, route, server, or lifecycle boundary is unsafe?
21
+ - **Build:** what belongs in browser, SSR, resume, and server output?
22
+ - **Test:** what did a user interaction actually cause?
23
+ - **Explain:** why did the compiler make that decision?
24
+
25
+ Use it when you are adopting VMZ as the application model. It is intentionally not a compatibility compiler for
26
+ arbitrary Vue components, React hooks, or legacy VDOM applications; those ecosystems are better served by their native
27
+ toolchains.
28
+
29
+ ## One tool, several views of the same program
30
+
31
+ | Workflow | The question it should answer |
32
+ |---|---|
33
+ | Development | What changed, and which application regions are affected? |
34
+ | Checking | Which state, route, server, or lifetime boundary cannot be proven? |
35
+ | Building | What belongs in browser, SSR, resume, and server output? |
36
+ | Testing | Did the application behave correctly and avoid unrelated work? |
37
+ | Documents | Are project documents connected, localized, and deployable? |
38
+
39
+ ### Designed for the npm world
40
+
41
+ VMZ does not ask users to abandon JavaScript packaging. Node remains the npm, plugin, development-server, and orchestration host. A long-lived N-API bridge connects that ecosystem to Rust and oxc without reducing semantic analysis to a sequence of tiny file transforms.
42
+
43
+ ### More than pass or fail
44
+
45
+ The interesting future of the CLI is explanation. A useful compiler should expose the source span, graph edge, owner, deployment boundary, and fallback reason behind a decision. That is a better developer experience than adding more colored output to an opaque build. 🧭
46
+
47
+ ## License
48
+
49
+ MIT
package/bin/vmz.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from '../dist/cli.js';
3
+ const code = await runCli(process.argv.slice(2));
4
+ process.exit(code ?? 0);
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `vmz application` — Application Collection / Mount (M0–M5).
3
+ * Design: `规划设计/vmz/22`
4
+ */
5
+ /**
6
+ * @param {string[]} argv
7
+ * @returns {Promise<number>}
8
+ */
9
+ export declare function cmdApplication(argv: any): Promise<number>;
10
+ /**
11
+ * @param {string} pathArg
12
+ */
13
+ export declare function runCheck(pathArg: any): {
14
+ project: string;
15
+ json: any;
16
+ data: any;
17
+ };
18
+ /**
19
+ * @param {string} hostRoot
20
+ * @returns {boolean}
21
+ */
22
+ export declare function hasApplicationsConfig(hostRoot: any): boolean;
@@ -0,0 +1,348 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * `vmz application` — Application Collection / Mount (M0–M5).
4
+ * Design: `规划设计/vmz/22`
5
+ */
6
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
7
+ import path from 'node:path';
8
+ import { loadNative } from './index.js';
9
+ import { log } from './log.js';
10
+ import { resolveWorkspacePackages } from './packages.js';
11
+ import { resolveWorkspaceDirs } from './resolve.js';
12
+ /**
13
+ * @param {string[]} argv
14
+ * @returns {Promise<number>}
15
+ */
16
+ export async function cmdApplication(argv) {
17
+ const [sub, ...rest] = argv;
18
+ if (!sub || sub === 'help' || sub === '-h' || sub === '--help') {
19
+ printHelp();
20
+ return 0;
21
+ }
22
+ if (sub === 'check')
23
+ return cmdCheck(rest);
24
+ if (sub === 'list')
25
+ return cmdList(rest);
26
+ if (sub === 'schemas' || sub === 'protocol')
27
+ return cmdSchemas();
28
+ if (sub === 'relocatable')
29
+ return cmdRelocatable(rest);
30
+ if (sub === 'relocate')
31
+ return cmdRelocate(rest);
32
+ if (sub === 'artifacts')
33
+ return cmdArtifacts(rest);
34
+ if (sub === 'isolation')
35
+ return cmdIsolation(rest);
36
+ if (sub === 'composition' || sub === 'compose' || sub === 'host')
37
+ return cmdComposition(rest);
38
+ if (sub === 'dev' || sub === 'sessions' || sub === 'm5')
39
+ return cmdDev(rest);
40
+ log.error(`unknown application subcommand \`${sub}\``);
41
+ printHelp();
42
+ return 1;
43
+ }
44
+ function printHelp() {
45
+ console.log(`vmz application — Application Collection / Mount (M0–M5)
46
+
47
+ Usage:
48
+ vmz application check [host] Validate descriptors + applications.config.json5
49
+ vmz application list [host] List resolved ApplicationIds / collections / mounts
50
+ vmz application schemas Print frozen protocol catalog JSON
51
+ vmz application relocatable [pkg] M1: ApplicationBase / non_relocatable_url proof
52
+ vmz application relocate <manifest.json> M1: apply ApplicationBase to relocation manifest
53
+ vmz application artifacts [host] M2: ApplicationArtifact + MountTable boundary
54
+ vmz application isolation [host] M3: isolation namespaces + failure containment
55
+ vmz application composition [host] M4: catalog consumption + cross-app Link hrefs
56
+ vmz application dev [host] M5: sessions / affected / proxy / mounted tests / deploy
57
+
58
+ Options:
59
+ --json [file] Emit report JSON to stdout or file
60
+ --base <path> ApplicationBase for relocatable / relocate (e.g. /examples/counter)
61
+ --dirty <path> Dirty file path for affected planning (repeatable)
62
+ `);
63
+ }
64
+ /**
65
+ * @param {string[]} argv
66
+ */
67
+ function parseRest(argv) {
68
+ /** @type {Record<string, string | boolean | string[]> & { _: string[] }} */
69
+ const out = { _: [] };
70
+ for (let i = 0; i < argv.length; i++) {
71
+ const a = argv[i];
72
+ if (a.startsWith('--')) {
73
+ const key = a.slice(2);
74
+ const next = argv[i + 1];
75
+ if (key === 'json') {
76
+ if (next && !next.startsWith('-')) {
77
+ out.json = next;
78
+ i += 1;
79
+ }
80
+ else {
81
+ out.json = true;
82
+ }
83
+ continue;
84
+ }
85
+ if (key === 'dirty') {
86
+ if (!Array.isArray(out.dirty))
87
+ out.dirty = [];
88
+ if (next && !next.startsWith('-')) {
89
+ out.dirty.push(next);
90
+ i += 1;
91
+ }
92
+ continue;
93
+ }
94
+ if (next && !next.startsWith('-')) {
95
+ out[key] = next;
96
+ i += 1;
97
+ }
98
+ else {
99
+ out[key] = true;
100
+ }
101
+ continue;
102
+ }
103
+ out._.push(a);
104
+ }
105
+ return out;
106
+ }
107
+ /**
108
+ * @param {{ json?: string | boolean }} args
109
+ * @param {string} json
110
+ * @param {(data: any) => void} [printHuman]
111
+ */
112
+ function emitJson(args, json, printHuman) {
113
+ if (typeof args.json === 'string') {
114
+ writeFileSync(args.json, `${json}\n`, 'utf8');
115
+ return;
116
+ }
117
+ if (args.json === true) {
118
+ console.log(json);
119
+ return;
120
+ }
121
+ if (printHuman)
122
+ printHuman(JSON.parse(json));
123
+ else
124
+ console.log(json);
125
+ }
126
+ function cmdSchemas() {
127
+ const native = loadNative();
128
+ console.log(native.queryApplicationProtocolCatalog());
129
+ return 0;
130
+ }
131
+ /**
132
+ * @param {string[]} argv
133
+ */
134
+ function cmdCheck(argv) {
135
+ const args = parseRest(argv);
136
+ const report = runCheck(args._[0] ?? '.');
137
+ emitJson(args, report.json, (data) => {
138
+ const errors = data.diagnostics.filter((d) => d.severity === 'error');
139
+ log.info(`application check: descriptors=${data.descriptors.length} collections=${data.collections.length} mounts=${data.mounts.length} errors=${errors.length}`);
140
+ for (const d of data.diagnostics) {
141
+ const fn = d.severity === 'error' ? log.error : log.warn;
142
+ fn(`${d.code}: ${d.path}: ${d.message}`);
143
+ }
144
+ });
145
+ return report.data.diagnostics.some((d) => d.severity === 'error') ? 1 : 0;
146
+ }
147
+ /**
148
+ * @param {string[]} argv
149
+ */
150
+ function cmdList(argv) {
151
+ const args = parseRest(argv);
152
+ const report = runCheck(args._[0] ?? '.');
153
+ emitJson(args, report.json, (data) => {
154
+ for (const d of data.descriptors) {
155
+ console.log(`application ${d.id}\t${d.entryRoute}\t${d.packageRoot ?? ''}`);
156
+ }
157
+ for (const m of data.mounts) {
158
+ console.log(`mount ${m.application}\t${m.routeBase}`);
159
+ }
160
+ for (const c of data.collections) {
161
+ const apps = c.groups.flatMap((g) => g.applications).join(',');
162
+ console.log(`collection ${c.id}\t${apps}`);
163
+ }
164
+ });
165
+ return report.data.diagnostics.some((d) => d.severity === 'error') ? 1 : 0;
166
+ }
167
+ /**
168
+ * @param {string[]} argv
169
+ */
170
+ function cmdRelocatable(argv) {
171
+ const args = parseRest(argv);
172
+ const { project } = resolveWorkspaceDirs({ path: args._[0] ?? '.' });
173
+ const native = loadNative();
174
+ if (typeof native.checkApplicationRelocatableJson !== 'function') {
175
+ throw new Error('checkApplicationRelocatableJson missing — rebuild native (pnpm napi:build)');
176
+ }
177
+ const base = typeof args.base === 'string' ? args.base : null;
178
+ const json = native.checkApplicationRelocatableJson(project, base);
179
+ const data = JSON.parse(json);
180
+ emitJson(args, json, () => {
181
+ const errors = data.diagnostics.filter((d) => d.severity === 'error');
182
+ log.info(`application relocatable: entries=${data.manifest?.entries?.length ?? 0} errors=${errors.length}`);
183
+ for (const d of data.diagnostics) {
184
+ const fn = d.severity === 'error' ? log.error : log.warn;
185
+ fn(`${d.code}: ${d.path}: ${d.message}`);
186
+ }
187
+ });
188
+ return data.diagnostics.some((d) => d.severity === 'error') ? 1 : 0;
189
+ }
190
+ /**
191
+ * @param {string[]} argv
192
+ */
193
+ function cmdRelocate(argv) {
194
+ const args = parseRest(argv);
195
+ const manifestPath = args._[0];
196
+ if (!manifestPath) {
197
+ log.error('relocate requires a relocation manifest JSON path');
198
+ return 1;
199
+ }
200
+ if (typeof args.base !== 'string' || !args.base) {
201
+ log.error('relocate requires --base <ApplicationBase>');
202
+ return 1;
203
+ }
204
+ const native = loadNative();
205
+ if (typeof native.relocateApplicationManifestJson !== 'function') {
206
+ throw new Error('relocateApplicationManifestJson missing — rebuild native (pnpm napi:build)');
207
+ }
208
+ const manifestJson = readFileSync(path.resolve(manifestPath), 'utf8');
209
+ const json = native.relocateApplicationManifestJson(manifestJson, args.base);
210
+ emitJson(args, json);
211
+ return 0;
212
+ }
213
+ /**
214
+ * @param {string[]} argv
215
+ */
216
+ function cmdArtifacts(argv) {
217
+ const args = parseRest(argv);
218
+ const report = runHostPackageReport(args._[0] ?? '.', 'checkApplicationArtifactBoundaryJson');
219
+ emitJson(args, report.json, (data) => {
220
+ const errors = data.diagnostics.filter((d) => d.severity === 'error');
221
+ log.info(`application artifacts: artifacts=${data.artifacts?.length ?? 0} mounts=${data.mountTable?.mounts?.length ?? 0} errors=${errors.length}`);
222
+ for (const d of data.diagnostics) {
223
+ const fn = d.severity === 'error' ? log.error : log.warn;
224
+ fn(`${d.code}: ${d.path}: ${d.message}`);
225
+ }
226
+ });
227
+ return report.data.diagnostics.some((d) => d.severity === 'error') ? 1 : 0;
228
+ }
229
+ /**
230
+ * @param {string[]} argv
231
+ */
232
+ function cmdIsolation(argv) {
233
+ const args = parseRest(argv);
234
+ const report = runHostPackageReport(args._[0] ?? '.', 'checkApplicationIsolationJson');
235
+ emitJson(args, report.json, (data) => {
236
+ const errors = data.diagnostics.filter((d) => d.severity === 'error');
237
+ log.info(`application isolation: namespaces=${data.namespaces?.length ?? 0} containment=${data.failureContainment?.length ?? 0} errors=${errors.length}`);
238
+ for (const d of data.diagnostics) {
239
+ const fn = d.severity === 'error' ? log.error : log.warn;
240
+ fn(`${d.code}: ${d.path}: ${d.message}`);
241
+ }
242
+ });
243
+ return report.data.diagnostics.some((d) => d.severity === 'error') ? 1 : 0;
244
+ }
245
+ /**
246
+ * @param {string[]} argv
247
+ */
248
+ function cmdComposition(argv) {
249
+ const args = parseRest(argv);
250
+ const report = runHostPackageReport(args._[0] ?? '.', 'checkApplicationHostCompositionJson');
251
+ emitJson(args, report.json, (data) => {
252
+ const errors = data.diagnostics.filter((d) => d.severity === 'error');
253
+ log.info(`application composition: catalog=${data.catalog?.applications?.length ?? 0} links=${data.crossApplicationLinks?.length ?? 0} errors=${errors.length}`);
254
+ for (const link of data.crossApplicationLinks ?? []) {
255
+ console.log(`link ${link.applicationId}\t${link.routeId}\t${link.href ?? '(unresolved)'}\tdocumentNavigation=${link.documentNavigation}`);
256
+ }
257
+ for (const d of data.diagnostics) {
258
+ const fn = d.severity === 'error' ? log.error : log.warn;
259
+ fn(`${d.code}: ${d.path}: ${d.message}`);
260
+ }
261
+ });
262
+ return report.data.diagnostics.some((d) => d.severity === 'error') ? 1 : 0;
263
+ }
264
+ /**
265
+ * @param {string[]} argv
266
+ */
267
+ function cmdDev(argv) {
268
+ const args = parseRest(argv);
269
+ const pathArg = args._[0] ?? '.';
270
+ const { project } = resolveWorkspaceDirs({ path: pathArg });
271
+ const packages = resolveWorkspacePackages(project);
272
+ const roots = packages.map((p) => p.root);
273
+ if (!roots.includes(project))
274
+ roots.unshift(project);
275
+ const dirty = Array.isArray(args.dirty) ? args.dirty.map((d) => path.resolve(project, String(d))) : [];
276
+ const native = loadNative();
277
+ if (typeof native.checkApplicationDevTestDeployJson !== 'function') {
278
+ log.error('checkApplicationDevTestDeployJson missing — rebuild native (`pnpm napi:build`)');
279
+ return 1;
280
+ }
281
+ const json = native.checkApplicationDevTestDeployJson(project, roots, dirty);
282
+ let data;
283
+ try {
284
+ data = JSON.parse(json);
285
+ }
286
+ catch (e) {
287
+ log.error(`dev report not JSON: ${e}`);
288
+ return 1;
289
+ }
290
+ emitJson(args, json, (report) => {
291
+ const errors = (report.diagnostics || []).filter((d) => d.severity === 'error');
292
+ log.info(`application dev: sessions=${report.sessions?.sessions?.length ?? 0} affected=${report.affected?.units?.length ?? 0} proxy=${report.proxy?.cases?.length ?? 0} errors=${errors.length}`);
293
+ for (const u of report.affected?.units ?? []) {
294
+ console.log(`affected ${u.applicationId}\t${u.reason}`);
295
+ }
296
+ for (const c of report.proxy?.cases ?? []) {
297
+ console.log(`proxy ${c.url}\t${c.applicationId ?? '-'}\t${c.status}\t${c.reason ?? ''}`);
298
+ }
299
+ for (const d of report.diagnostics || []) {
300
+ const fn = d.severity === 'error' ? log.error : log.warn;
301
+ fn(`${d.code}: ${d.path}: ${d.message}`);
302
+ }
303
+ });
304
+ return data.diagnostics.some((d) => d.severity === 'error') ? 1 : 0;
305
+ }
306
+ /**
307
+ * @param {string} pathArg
308
+ * @param {string} nativeFn
309
+ */
310
+ function runHostPackageReport(pathArg, nativeFn) {
311
+ const { project } = resolveWorkspaceDirs({ path: pathArg });
312
+ const packages = resolveWorkspacePackages(project);
313
+ const roots = packages.map((p) => p.root);
314
+ if (!roots.includes(project))
315
+ roots.unshift(project);
316
+ const native = loadNative();
317
+ if (typeof native[nativeFn] !== 'function') {
318
+ throw new Error(`${nativeFn} missing — rebuild native (pnpm napi:build)`);
319
+ }
320
+ const json = native[nativeFn](project, roots);
321
+ const data = JSON.parse(json);
322
+ return { project, json, data };
323
+ }
324
+ /**
325
+ * @param {string} pathArg
326
+ */
327
+ export function runCheck(pathArg) {
328
+ const { project } = resolveWorkspaceDirs({ path: pathArg });
329
+ const packages = resolveWorkspacePackages(project);
330
+ const roots = packages.map((p) => p.root);
331
+ // Always include host root so a local package.json#vmz.application is visible.
332
+ if (!roots.includes(project))
333
+ roots.unshift(project);
334
+ const native = loadNative();
335
+ if (typeof native.checkApplicationsJson !== 'function') {
336
+ throw new Error('checkApplicationsJson missing — rebuild native (pnpm napi:build)');
337
+ }
338
+ const json = native.checkApplicationsJson(project, roots);
339
+ const data = JSON.parse(json);
340
+ return { project, json, data };
341
+ }
342
+ /**
343
+ * @param {string} hostRoot
344
+ * @returns {boolean}
345
+ */
346
+ export function hasApplicationsConfig(hostRoot) {
347
+ return existsSync(path.join(hostRoot, 'applications.config.json5'));
348
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Bundler adapter (N4) — consumes Deployment IR; does not invent VMZ semantics.
3
+ *
4
+ * Design: `规划设计/vmz/14` — VPG/Deployment IR → bundler executes pack/minify/assets.
5
+ * Vite/Rolldown may call these helpers; they must not reverse the arrow.
6
+ */
7
+ /**
8
+ * @typedef {object} DeploymentUnit
9
+ * @property {string} chunkId
10
+ * @property {string} kind
11
+ * @property {string} source
12
+ * @property {string} clientEntry
13
+ * @property {string} programIr
14
+ * @property {string[]} [dependsOn]
15
+ * @property {string[]} [dependedBy]
16
+ * @property {boolean} [rebuilt]
17
+ */
18
+ /**
19
+ * @typedef {object} DeploymentIr
20
+ * @property {string} schema
21
+ * @property {DeploymentUnit[]} units
22
+ * @property {string[]} [affectedChunks]
23
+ * @property {string[]} [seedChunks]
24
+ * @property {boolean} [islandHmr]
25
+ * @property {boolean} [full]
26
+ */
27
+ /**
28
+ * @param {string} outDir
29
+ * @returns {DeploymentIr}
30
+ */
31
+ export declare function loadDeploymentIr(outDir: any): any;
32
+ /**
33
+ * Map Deployment IR → bundler entry points (absolute paths under outDir).
34
+ * @param {string} outDir
35
+ * @param {DeploymentIr} [ir]
36
+ */
37
+ export declare function planBundleInputs(outDir: any, ir?: any): any;
38
+ /**
39
+ * Entries that were rebuilt in the last emit (HMR / incremental pack).
40
+ * @param {string} outDir
41
+ * @param {DeploymentIr} [ir]
42
+ */
43
+ export declare function planAffectedBundleInputs(outDir: any, ir?: any): any;
44
+ /**
45
+ * Thin Vite plugin factory: only reads Deployment IR. No `.vmz` transform hooks.
46
+ * @param {{ outDir?: string, root?: string }} [options]
47
+ */
48
+ export declare function createVitePluginVmzAdapter(options?: {}): {
49
+ name: string;
50
+ buildStart(): void;
51
+ /**
52
+ * Expose IR to other plugins via meta (optional).
53
+ */
54
+ configResolved(): void;
55
+ };
56
+ /**
57
+ * Thin Rolldown plugin factory (N4.2) — same contract as Vite adapter: read Deployment IR only.
58
+ * @param {{ outDir?: string, root?: string }} [options]
59
+ */
60
+ export declare function createRolldownPluginVmzAdapter(options?: {}): {
61
+ name: string;
62
+ buildStart(): void;
63
+ options(inputOptions: any): any;
64
+ };
@@ -0,0 +1,111 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Bundler adapter (N4) — consumes Deployment IR; does not invent VMZ semantics.
4
+ *
5
+ * Design: `规划设计/vmz/14` — VPG/Deployment IR → bundler executes pack/minify/assets.
6
+ * Vite/Rolldown may call these helpers; they must not reverse the arrow.
7
+ */
8
+ import { existsSync, readFileSync } from 'node:fs';
9
+ import path from 'node:path';
10
+ /**
11
+ * @typedef {object} DeploymentUnit
12
+ * @property {string} chunkId
13
+ * @property {string} kind
14
+ * @property {string} source
15
+ * @property {string} clientEntry
16
+ * @property {string} programIr
17
+ * @property {string[]} [dependsOn]
18
+ * @property {string[]} [dependedBy]
19
+ * @property {boolean} [rebuilt]
20
+ */
21
+ /**
22
+ * @typedef {object} DeploymentIr
23
+ * @property {string} schema
24
+ * @property {DeploymentUnit[]} units
25
+ * @property {string[]} [affectedChunks]
26
+ * @property {string[]} [seedChunks]
27
+ * @property {boolean} [islandHmr]
28
+ * @property {boolean} [full]
29
+ */
30
+ /**
31
+ * @param {string} outDir
32
+ * @returns {DeploymentIr}
33
+ */
34
+ export function loadDeploymentIr(outDir) {
35
+ const file = path.join(outDir, 'vmz-deployment.json');
36
+ if (!existsSync(file)) {
37
+ throw new Error(`Deployment IR missing: ${file} (run vmz build first)`);
38
+ }
39
+ const ir = JSON.parse(readFileSync(file, 'utf8'));
40
+ if (ir.schema !== 'vmz.deployment.v0') {
41
+ throw new Error(`unsupported deployment schema: ${ir.schema}`);
42
+ }
43
+ return ir;
44
+ }
45
+ /**
46
+ * Map Deployment IR → bundler entry points (absolute paths under outDir).
47
+ * @param {string} outDir
48
+ * @param {DeploymentIr} [ir]
49
+ */
50
+ export function planBundleInputs(outDir, ir = loadDeploymentIr(outDir)) {
51
+ return (ir.units || []).map((u) => ({
52
+ chunkId: u.chunkId,
53
+ kind: u.kind,
54
+ entry: path.join(outDir, u.clientEntry),
55
+ programIr: path.join(outDir, u.programIr),
56
+ source: u.source,
57
+ rebuilt: Boolean(u.rebuilt),
58
+ }));
59
+ }
60
+ /**
61
+ * Entries that were rebuilt in the last emit (HMR / incremental pack).
62
+ * @param {string} outDir
63
+ * @param {DeploymentIr} [ir]
64
+ */
65
+ export function planAffectedBundleInputs(outDir, ir = loadDeploymentIr(outDir)) {
66
+ const affected = new Set(ir.affectedChunks || []);
67
+ return planBundleInputs(outDir, ir).filter((e) => e.rebuilt || affected.has(e.chunkId));
68
+ }
69
+ /**
70
+ * Thin Vite plugin factory: only reads Deployment IR. No `.vmz` transform hooks.
71
+ * @param {{ outDir?: string, root?: string }} [options]
72
+ */
73
+ export function createVitePluginVmzAdapter(options = {}) {
74
+ const outDir = options.outDir ?? 'dist';
75
+ return {
76
+ name: 'vmz-deployment-adapter',
77
+ // Enforce direction: bundler consumes IR, never owns VMZ semantics.
78
+ buildStart() {
79
+ const abs = path.isAbsolute(outDir) ? outDir : path.join(options.root ?? process.cwd(), outDir);
80
+ if (!existsSync(path.join(abs, 'vmz-deployment.json'))) {
81
+ this.warn?.(`[vmz] ${abs}/vmz-deployment.json missing — run \`vmz build\` before bundling`);
82
+ }
83
+ },
84
+ /**
85
+ * Expose IR to other plugins via meta (optional).
86
+ */
87
+ configResolved() {
88
+ /* no-op — presence documents the adapter surface */
89
+ },
90
+ };
91
+ }
92
+ /**
93
+ * Thin Rolldown plugin factory (N4.2) — same contract as Vite adapter: read Deployment IR only.
94
+ * @param {{ outDir?: string, root?: string }} [options]
95
+ */
96
+ export function createRolldownPluginVmzAdapter(options = {}) {
97
+ const outDir = options.outDir ?? 'dist';
98
+ return {
99
+ name: 'vmz-deployment-adapter-rolldown',
100
+ buildStart() {
101
+ const abs = path.isAbsolute(outDir) ? outDir : path.join(options.root ?? process.cwd(), outDir);
102
+ if (!existsSync(path.join(abs, 'vmz-deployment.json'))) {
103
+ this.warn?.(`[vmz] ${abs}/vmz-deployment.json missing — run \`vmz build\` before bundling`);
104
+ }
105
+ },
106
+ // Rolldown may call `options` / `buildStart`; keep surface identical and semantic-free.
107
+ options(inputOptions) {
108
+ return inputOptions;
109
+ },
110
+ };
111
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Node CLI command implementations (N2).
3
+ */
4
+ /**
5
+ * @param {string[]} argv
6
+ */
7
+ export declare function parseArgs(argv: any): {
8
+ _: any[];
9
+ };
10
+ export declare function printHelp(): void;
11
+ /**
12
+ * @param {string[]} argv
13
+ * @returns {Promise<number>}
14
+ */
15
+ export declare function runCli(argv: any): Promise<any>;