@vmz/core 0.2.5 → 0.2.6

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 (77) hide show
  1. package/dist/browser/client-nav.d.ts +5 -55
  2. package/dist/browser/client-nav.js +5 -769
  3. package/dist/browser/diagnostics/precision-trace.d.ts +47 -0
  4. package/dist/browser/diagnostics/precision-trace.js +86 -0
  5. package/dist/browser/dom/attributes.d.ts +5 -0
  6. package/dist/browser/dom/attributes.js +102 -0
  7. package/dist/browser/dom/component.d.ts +11 -0
  8. package/dist/browser/dom/component.js +255 -0
  9. package/dist/browser/dom/direct-api.d.ts +66 -0
  10. package/dist/browser/dom/direct-api.js +446 -0
  11. package/dist/browser/dom/lifecycle.d.ts +9 -0
  12. package/dist/browser/dom/lifecycle.js +161 -0
  13. package/dist/browser/dom/registry.d.ts +5 -0
  14. package/dist/browser/dom/registry.js +16 -0
  15. package/dist/browser/dom-core.d.ts +51 -249
  16. package/dist/browser/dom-core.js +51 -2521
  17. package/dist/browser/navigation/client-navigation.d.ts +44 -0
  18. package/dist/browser/navigation/client-navigation.js +277 -0
  19. package/dist/browser/navigation/extract-html.d.ts +1 -0
  20. package/dist/browser/navigation/extract-html.js +5 -0
  21. package/dist/browser/navigation/layout-retain.d.ts +3 -0
  22. package/dist/browser/navigation/layout-retain.js +34 -0
  23. package/dist/browser/navigation/locale-transition.d.ts +24 -0
  24. package/dist/browser/navigation/locale-transition.js +323 -0
  25. package/dist/browser/navigation/scroll-focus.d.ts +14 -0
  26. package/dist/browser/navigation/scroll-focus.js +87 -0
  27. package/dist/browser/reactivity/patch-scheduler.d.ts +12 -0
  28. package/dist/browser/reactivity/patch-scheduler.js +720 -0
  29. package/dist/browser/reactivity/write-barrier.d.ts +16 -0
  30. package/dist/browser/reactivity/write-barrier.js +546 -0
  31. package/dist/browser/resume/adopt.d.ts +1 -0
  32. package/dist/browser/resume/adopt.js +168 -0
  33. package/dist/browser/resume/hydrate.d.ts +4 -0
  34. package/dist/browser/resume/hydrate.js +107 -0
  35. package/dist/browser/resume/resume.d.ts +3 -0
  36. package/dist/browser/resume/resume.js +102 -0
  37. package/dist/faces/dom.browser.d.ts +2 -1
  38. package/dist/faces/dom.browser.js +2 -1
  39. package/dist/host/{deployment-registry.d.ts → deployment/deployment-registry.d.ts} +1 -1
  40. package/dist/host/{deployment-registry.js → deployment/deployment-registry.js} +1 -1
  41. package/dist/host/list-client-components.d.ts +2 -2
  42. package/dist/host/list-client-components.js +4 -4
  43. package/dist/host/{render-host.d.ts → render/render-host.d.ts} +2 -2
  44. package/dist/host/{render-host.js → render/render-host.js} +1 -1
  45. package/dist/host/{route-layout-chain.js → render/route-layout-chain.js} +1 -1
  46. package/dist/host/serve/bootstrap.d.ts +1 -0
  47. package/dist/host/serve/bootstrap.js +25 -0
  48. package/dist/host/serve/constants.d.ts +6 -0
  49. package/dist/host/serve/constants.js +6 -0
  50. package/dist/host/serve/hmr-dev.d.ts +34 -0
  51. package/dist/host/serve/hmr-dev.js +294 -0
  52. package/dist/host/serve/http.d.ts +1 -0
  53. package/dist/host/serve/http.js +124 -0
  54. package/dist/host/serve/locale-theme.d.ts +19 -0
  55. package/dist/host/serve/locale-theme.js +169 -0
  56. package/dist/host/serve/page-catalog.d.ts +14 -0
  57. package/dist/host/serve/page-catalog.js +105 -0
  58. package/dist/host/serve/page-render.d.ts +17 -0
  59. package/dist/host/serve/page-render.js +419 -0
  60. package/dist/host/serve/paths.d.ts +3 -0
  61. package/dist/host/serve/paths.js +74 -0
  62. package/dist/host/serve/route-catalog.d.ts +6 -0
  63. package/dist/host/serve/route-catalog.js +108 -0
  64. package/dist/host/serve/state.d.ts +30 -0
  65. package/dist/host/serve/state.js +36 -0
  66. package/dist/host/serve-host.d.ts +0 -17
  67. package/dist/host/serve-host.mjs +4 -1420
  68. package/dist/ssr/document.d.ts +2 -0
  69. package/dist/ssr/document.js +71 -0
  70. package/dist/ssr/dom-ssr.d.ts +10 -47
  71. package/dist/ssr/dom-ssr.js +10 -1284
  72. package/dist/ssr/render.d.ts +2 -0
  73. package/dist/ssr/render.js +78 -0
  74. package/dist/ssr/serialize.d.ts +3 -0
  75. package/dist/ssr/serialize.js +678 -0
  76. package/package.json +11 -11
  77. /package/dist/host/{route-layout-chain.d.ts → render/route-layout-chain.d.ts} +0 -0
@@ -0,0 +1,168 @@
1
+ import { directApi, noteDomCreate, runDirectCreate, } from '../dom-core.js';
2
+ function createResumeAdopt(pool, rootEl) {
3
+ const used = new WeakSet();
4
+ const scopeStack = [pool];
5
+ const walkTexts = (root, visit) => {
6
+ if (!root)
7
+ return;
8
+ if (root.nodeType === 3) {
9
+ visit(root);
10
+ return;
11
+ }
12
+ if (root.nodeType !== 1)
13
+ return;
14
+ for (let c = root.firstChild; c; c = c.nextSibling)
15
+ walkTexts(c, visit);
16
+ };
17
+ const currentScope = () => scopeStack[scopeStack.length - 1] || pool;
18
+ const markElement = (n) => {
19
+ used.add(n);
20
+ if (typeof n.getAttribute === 'function') {
21
+ const k = n.getAttribute('data-vmz-key');
22
+ if (k != null && n.__vmzKey == null)
23
+ n.__vmzKey = k;
24
+ }
25
+ // Private child pool ??never dump into the parent/global pool (that let
26
+ // if branches reclaim Drawer/sibling hosts parked as uncles).
27
+ const childPool = document.createDocumentFragment();
28
+ while (n.firstChild)
29
+ childPool.appendChild(n.firstChild);
30
+ n.__vmzResumePool = childPool;
31
+ return n;
32
+ };
33
+ function* elementCandidates() {
34
+ const scope = currentScope();
35
+ if (scope === pool && rootEl && !used.has(rootEl))
36
+ yield rootEl;
37
+ // Snapshot ??adopt may move nodes out of scope while iterating.
38
+ const kids = [...scope.childNodes];
39
+ for (const n of kids) {
40
+ if (n.nodeType === 1 && !used.has(n)) {
41
+ yield n;
42
+ }
43
+ }
44
+ }
45
+ function* textCandidates() {
46
+ const scope = currentScope();
47
+ const kids = [...scope.childNodes];
48
+ for (const n of kids) {
49
+ const found = [];
50
+ walkTexts(n, (t) => {
51
+ if (!used.has(t))
52
+ found.push(t);
53
+ });
54
+ for (const t of found)
55
+ yield t;
56
+ }
57
+ }
58
+ const adoptElement = (tag) => {
59
+ const want = String(tag || 'div').toLowerCase();
60
+ for (const el of elementCandidates()) {
61
+ if (String(el.tagName).toLowerCase() === want)
62
+ return markElement(el);
63
+ }
64
+ noteDomCreate();
65
+ return document.createElement(tag || 'div');
66
+ };
67
+ const adoptText = (value) => {
68
+ for (const n of textCandidates()) {
69
+ used.add(n);
70
+ if (value != null && value !== '')
71
+ n.textContent = String(value);
72
+ return n;
73
+ }
74
+ noteDomCreate();
75
+ return document.createTextNode(value == null ? '' : String(value));
76
+ };
77
+ const componentHost = (name) => {
78
+ const want = String(name || '');
79
+ for (const el of elementCandidates()) {
80
+ if (String(el.tagName).toLowerCase() !== 'div')
81
+ continue;
82
+ if (el.getAttribute('data-vmz') !== want)
83
+ continue;
84
+ return markElement(el);
85
+ }
86
+ return null;
87
+ };
88
+ const enter = (node) => {
89
+ if (!node || !node.__vmzResumePool)
90
+ return false;
91
+ scopeStack.push(node.__vmzResumePool);
92
+ return true;
93
+ };
94
+ const leave = () => {
95
+ if (scopeStack.length <= 1)
96
+ return;
97
+ scopeStack.pop();
98
+ };
99
+ const scopeDepth = () => scopeStack.length;
100
+ const rewindScope = (depth) => {
101
+ const d = Math.max(1, Number(depth) || 1);
102
+ while (scopeStack.length > d)
103
+ scopeStack.pop();
104
+ };
105
+ /**
106
+ * Isolate the next top-level SSR sibling as the only candidates for an
107
+ * if/else branch create (commercial Card: Empty branch must not adopt Drawer).
108
+ */
109
+ const beginBranchScope = () => {
110
+ const parent = currentScope();
111
+ const branchPool = document.createDocumentFragment();
112
+ for (const n of [...parent.childNodes]) {
113
+ if (n.nodeType === 1 && !used.has(n)) {
114
+ branchPool.appendChild(n);
115
+ break;
116
+ }
117
+ }
118
+ scopeStack.push(branchPool);
119
+ const depth = scopeStack.length;
120
+ return () => {
121
+ while (branchPool.firstChild)
122
+ branchPool.removeChild(branchPool.firstChild);
123
+ rewindScope(depth - 1);
124
+ };
125
+ };
126
+ return {
127
+ el: adoptElement,
128
+ text: adoptText,
129
+ componentHost,
130
+ enter,
131
+ leave,
132
+ scopeDepth,
133
+ rewindScope,
134
+ beginBranchScope,
135
+ };
136
+ }
137
+ export function runDirectResume(Component, inst, container) {
138
+ const rootEl = [...container.childNodes].find((n) => n.nodeType === 1 || (n.nodeType === 3 && String(n.textContent).trim() !== ''));
139
+ if (!rootEl || rootEl.nodeType !== 1) {
140
+ return runDirectCreate(Component, inst);
141
+ }
142
+ // Park SSR descendants so create can append if/each structure without orphan siblings.
143
+ const pool = document.createDocumentFragment();
144
+ while (rootEl.firstChild)
145
+ pool.appendChild(rootEl.firstChild);
146
+ const prevInst = directApi._inst;
147
+ const prevBranch = directApi._branchBinds;
148
+ const prevItems = directApi._itemPatches;
149
+ const prevEach = directApi._eachCtx;
150
+ const prevAdopt = directApi._resumeAdopt;
151
+ directApi._inst = inst;
152
+ directApi._branchBinds = null;
153
+ directApi._itemPatches = null;
154
+ directApi._eachCtx = null;
155
+ directApi._resumeAdopt = createResumeAdopt(pool, rootEl);
156
+ try {
157
+ return Component.__vmzCreate.call(inst, directApi);
158
+ }
159
+ finally {
160
+ directApi._resumeAdopt = prevAdopt;
161
+ directApi._inst = prevInst;
162
+ directApi._branchBinds = prevBranch;
163
+ directApi._itemPatches = prevItems;
164
+ directApi._eachCtx = prevEach;
165
+ while (pool.firstChild)
166
+ pool.removeChild(pool.firstChild);
167
+ }
168
+ }
@@ -0,0 +1,4 @@
1
+ export declare function hydrateRoute(Page: any, container: any, props?: {}, layoutCtors?: any[], opts?: {}): Promise<any>;
2
+ export declare function hydrateRoutePage(Page: any, container: any, props?: any, opts?: any): Promise<any>;
3
+ export declare function hydrate(Component: any, container: any, props?: any, opts?: any): Promise<any>;
4
+ export declare function hydrateIslands(root?: Document): void;
@@ -0,0 +1,107 @@
1
+ import { applyPreservedState, createInstance, destroy, findOwnedDefaultSlot, hasMeaningfulChild, mount, runDirectCreate, settlePendingChildMounts, snapshotInstanceState, } from '../dom-core.js';
2
+ import { runDirectResume } from './adopt.js';
3
+ import { resumeIslands } from './resume.js';
4
+ export async function hydrateRoute(Page, container, props = {}, layoutCtors = [], opts = {}) {
5
+ if (typeof document === 'undefined') {
6
+ throw new Error('vmz:dom hydrateRoute() requires a document (browser)');
7
+ }
8
+ if (container.__vmzInst) {
9
+ destroy(container.__vmzInst);
10
+ container.__vmzInst = null;
11
+ }
12
+ container.__vmzPageHost = null;
13
+ container.__vmzLayoutInsts = null;
14
+ const layoutInsts = [];
15
+ let host = container;
16
+ const ctors = Array.isArray(layoutCtors) ? layoutCtors.filter(Boolean) : [];
17
+ for (const Layout of ctors) {
18
+ const inst = await mount(Layout, host, {});
19
+ layoutInsts.push(inst);
20
+ const slot = findOwnedDefaultSlot(inst.__vmzDomRoot);
21
+ const outlet = document.createElement('div');
22
+ outlet.setAttribute('data-vmz-outlet', '');
23
+ if (slot && slot.parentNode)
24
+ slot.replaceWith(outlet);
25
+ else if (inst.__vmzDomRoot && typeof inst.__vmzDomRoot.appendChild === 'function') {
26
+ inst.__vmzDomRoot.appendChild(outlet);
27
+ }
28
+ else {
29
+ host.appendChild(outlet);
30
+ }
31
+ host = outlet;
32
+ }
33
+ const pageInst = await hydrate(Page, host, props, opts);
34
+ container.__vmzPageHost = host;
35
+ container.__vmzLayoutInsts = layoutInsts;
36
+ // Outer layout (or page if no layouts) owns the #app instance for destroy().
37
+ container.__vmzInst = layoutInsts[0] || pageInst;
38
+ return pageInst;
39
+ }
40
+ export async function hydrateRoutePage(Page, container, props = {}, opts = {}) {
41
+ if (typeof document === 'undefined') {
42
+ throw new Error('vmz:dom hydrateRoutePage() requires a document (browser)');
43
+ }
44
+ const pageHost = container.__vmzPageHost || container;
45
+ if (pageHost.__vmzInst) {
46
+ destroy(pageHost.__vmzInst);
47
+ pageHost.__vmzInst = null;
48
+ }
49
+ const pageInst = await hydrate(Page, pageHost, props, opts);
50
+ container.__vmzPageHost = pageHost;
51
+ const layouts = container.__vmzLayoutInsts;
52
+ if (!Array.isArray(layouts) || layouts.length === 0) {
53
+ container.__vmzInst = pageInst;
54
+ }
55
+ return pageInst;
56
+ }
57
+ export async function hydrate(Component, container, props = {}, opts = {}) {
58
+ if (typeof document === 'undefined') {
59
+ throw new Error('vmz:dom hydrate() requires a document (browser)');
60
+ }
61
+ let preserved = null;
62
+ if (opts.preserveState && typeof opts.preserveState === 'object') {
63
+ preserved = opts.preserveState;
64
+ }
65
+ else if (opts.preserveState === true && container.__vmzInst) {
66
+ preserved = snapshotInstanceState(container.__vmzInst);
67
+ }
68
+ if (container.__vmzInst) {
69
+ destroy(container.__vmzInst);
70
+ container.__vmzInst = null;
71
+ }
72
+ const inst = createInstance(Component, props);
73
+ if (preserved) {
74
+ applyPreservedState(inst, preserved);
75
+ }
76
+ // production Direct emit: hydrate uses the same Direct schedule as resume (no render).
77
+ if (!(Component && Component.__vmzDirect && typeof Component.__vmzCreate === 'function')) {
78
+ throw new Error(`vmz:dom hydrate() requires __vmzCreate (Direct); blueprint render() removed (production Direct emit)`);
79
+ }
80
+ // Wire DOM + events BEFORE awaiting onMount. SSR shell is already visible; if we
81
+ // wait on RPC/bootstrap first, buttons look real but have no listeners (dead UI).
82
+ // onMount may still patch state / redirect afterwards (same end state as SSR order).
83
+ if (!hasMeaningfulChild(container)) {
84
+ const node = runDirectCreate(Component, inst);
85
+ if (node) {
86
+ inst.__vmzDomRoot = node;
87
+ container.appendChild(node);
88
+ }
89
+ }
90
+ else {
91
+ // Deep adopt: park SSR children, rebuild schedule, reclaim nodes (no orphan siblings).
92
+ const node = runDirectResume(Component, inst, container);
93
+ if (node)
94
+ inst.__vmzDomRoot = node;
95
+ }
96
+ await settlePendingChildMounts(inst);
97
+ container.__vmzInst = inst;
98
+ const runMount = opts.skipOnMount !== true && !preserved && typeof inst.onMount === 'function';
99
+ if (runMount) {
100
+ await inst.onMount();
101
+ }
102
+ return inst;
103
+ }
104
+ export function hydrateIslands(root = globalThis.document) {
105
+ // resume: hydrateIslands is an alias for resumeIslands (same Plan attach).
106
+ return resumeIslands(root);
107
+ }
@@ -0,0 +1,3 @@
1
+ export declare function resume(Component: any, container: any, slice?: any): Promise<any>;
2
+ export declare function resumeIslands(root?: Document): void;
3
+ export declare function attachEventEntries(root?: Document): void;
@@ -0,0 +1,102 @@
1
+ import { applyDirectHostBox } from '../direct-host-box.js';
2
+ import { applyPreservedState, createInstance, destroy, hasMeaningfulChild, isEventEntryStrategy, resolveComponent, runDirectCreate, scheduleClientOn, } from '../dom-core.js';
3
+ import { markUnknownComponentHost } from '../unknown-component.js';
4
+ import { runDirectResume } from './adopt.js';
5
+ export async function resume(Component, container, slice = null) {
6
+ if (typeof document === 'undefined') {
7
+ throw new Error('vmz:dom resume() requires a document (browser)');
8
+ }
9
+ let parsed = slice;
10
+ if (!parsed) {
11
+ const raw = container.getAttribute('data-vmz-resume');
12
+ if (raw) {
13
+ try {
14
+ parsed = JSON.parse(raw);
15
+ }
16
+ catch {
17
+ parsed = null;
18
+ }
19
+ }
20
+ }
21
+ if (!parsed) {
22
+ let props = {};
23
+ try {
24
+ props = JSON.parse(container.getAttribute('data-vmz-props') || '{}');
25
+ }
26
+ catch {
27
+ props = {};
28
+ }
29
+ parsed = { props, state: {} };
30
+ }
31
+ if (container.__vmzInst) {
32
+ destroy(container.__vmzInst);
33
+ container.__vmzInst = null;
34
+ }
35
+ const hostName = container.getAttribute('data-vmz') || container.getAttribute('data-vmz-island') || Component.name || '';
36
+ applyDirectHostBox(container, hostName, Component);
37
+ const props = parsed.props || {};
38
+ const inst = createInstance(Component, props);
39
+ if (parsed.state)
40
+ applyPreservedState(inst, parsed.state);
41
+ // Intentionally never call onMount ??SSR already completed that work.
42
+ if (Component.__vmzDirect && typeof Component.__vmzCreate === 'function') {
43
+ if (!hasMeaningfulChild(container)) {
44
+ const node = runDirectCreate(Component, inst);
45
+ if (node) {
46
+ inst.__vmzDomRoot = node;
47
+ container.appendChild(node);
48
+ }
49
+ }
50
+ else {
51
+ // Island leaf adopt: preserve Element identity (resume nodeIdentity).
52
+ const node = runDirectResume(Component, inst, container);
53
+ if (node)
54
+ inst.__vmzDomRoot = node;
55
+ }
56
+ }
57
+ else {
58
+ throw new Error(`vmz:dom resume() requires __vmzCreate (Direct); blueprint render() removed (production Direct emit)`);
59
+ }
60
+ container.__vmzInst = inst;
61
+ container.__vmzResumed = true;
62
+ return inst;
63
+ }
64
+ export function resumeIslands(root = globalThis.document) {
65
+ if (!root || typeof root.querySelectorAll !== 'function') {
66
+ throw new Error('vmz:dom resumeIslands() requires a DOM root');
67
+ }
68
+ const nodes = [...root.querySelectorAll('[data-vmz-island]')];
69
+ for (const el of nodes) {
70
+ const name = el.getAttribute('data-vmz-island');
71
+ const strategy = el.getAttribute('data-vmz-client') || 'load';
72
+ scheduleClientOn(el, strategy, async () => {
73
+ const Ctor = await resolveComponent(name);
74
+ if (!Ctor) {
75
+ markUnknownComponentHost(el, name, 'resume');
76
+ return;
77
+ }
78
+ await resume(Ctor, el);
79
+ });
80
+ }
81
+ }
82
+ export function attachEventEntries(root = globalThis.document) {
83
+ if (!root || typeof root.querySelectorAll !== 'function') {
84
+ throw new Error('vmz:dom attachEventEntries() requires a DOM root');
85
+ }
86
+ const nodes = [...root.querySelectorAll('[data-vmz-island]')];
87
+ for (const el of nodes) {
88
+ const strategy = el.getAttribute('data-vmz-client') || '';
89
+ if (!isEventEntryStrategy(strategy))
90
+ continue;
91
+ const name = el.getAttribute('data-vmz-island');
92
+ el.setAttribute('data-vmz-entry', 'event');
93
+ scheduleClientOn(el, strategy, async () => {
94
+ const Ctor = await resolveComponent(name);
95
+ if (!Ctor) {
96
+ markUnknownComponentHost(el, name, 'event-entry');
97
+ return;
98
+ }
99
+ await resume(Ctor, el);
100
+ });
101
+ }
102
+ }
@@ -4,4 +4,5 @@
4
4
  * Full barrel remains `@vmz/core/dom` (`dom.js` / dist `vmz-dom.js`) for Node host.
5
5
  */
6
6
  export * from '../browser/dom-core.js';
7
- export { attachEventEntries, hydrate, hydrateIslands, hydrateRoute, hydrateRoutePage, resume, resumeIslands } from '../ssr/dom-ssr.js';
7
+ export { hydrate, hydrateIslands, hydrateRoute, hydrateRoutePage } from '../browser/resume/hydrate.js';
8
+ export { attachEventEntries, resume, resumeIslands } from '../browser/resume/resume.js';
@@ -4,4 +4,5 @@
4
4
  * Full barrel remains `@vmz/core/dom` (`dom.js` / dist `vmz-dom.js`) for Node host.
5
5
  */
6
6
  export * from '../browser/dom-core.js';
7
- export { attachEventEntries, hydrate, hydrateIslands, hydrateRoute, hydrateRoutePage, resume, resumeIslands } from '../ssr/dom-ssr.js';
7
+ export { hydrate, hydrateIslands, hydrateRoute, hydrateRoutePage } from '../browser/resume/hydrate.js';
8
+ export { attachEventEntries, resume, resumeIslands } from '../browser/resume/resume.js';
@@ -2,7 +2,7 @@
2
2
  * Deployment graph — component registry bootstrap (shared by all SSR/DOM hosts).
3
3
  * Parse/validate and graph queries delegate to Rust vmz-artifacts via N-API.
4
4
  */
5
- import type { BootstrapComponentRegistryOpts, ComponentEntry, ComponentRegistryMap, DedupeComponentEntriesOpts, DeploymentDocument, ImportComponentEntriesOpts, LoadComponentEntriesOpts } from '../shared/host.types.js';
5
+ import type { BootstrapComponentRegistryOpts, ComponentEntry, ComponentRegistryMap, DedupeComponentEntriesOpts, DeploymentDocument, ImportComponentEntriesOpts, LoadComponentEntriesOpts } from '../../shared/host.types.js';
6
6
  export declare const DEPLOYMENT_SCHEMA = "vmz.deployment.v0";
7
7
  export declare function readDeploymentDocument(distDir: string, opts?: {
8
8
  strict?: boolean;
@@ -5,7 +5,7 @@
5
5
  import fs from 'node:fs';
6
6
  import path from 'node:path';
7
7
  import { pathToFileURL } from 'node:url';
8
- import { requireNativeFn } from './native-addon.js';
8
+ import { requireNativeFn } from '../native-addon.js';
9
9
  export const DEPLOYMENT_SCHEMA = 'vmz.deployment.v0';
10
10
  function parseDeploymentJson(jsonText) {
11
11
  requireNativeFn('deploymentValidate')(jsonText);
@@ -3,8 +3,8 @@
3
3
  * Shared by serve-host SSR, static emit, and test hosts (plan-only host).
4
4
  */
5
5
  import type { ClientComponentListEntry, ComponentRegistryMap, ListClientComponentsOpts, PreloadComponentRegistryOpts } from '../shared/host.types.js';
6
- export { DEPLOYMENT_SCHEMA, readDeploymentDocument, componentEntriesFromDeployment, collectDependsOnClosure, dedupeComponentEntriesByTag, mergeExplicitComponentEntries, loadComponentEntries, importAndRegisterComponentEntries, bootstrapComponentRegistry, } from './deployment-registry.js';
7
- export { createRenderHost } from './render-host.js';
6
+ export { DEPLOYMENT_SCHEMA, readDeploymentDocument, componentEntriesFromDeployment, collectDependsOnClosure, dedupeComponentEntriesByTag, mergeExplicitComponentEntries, loadComponentEntries, importAndRegisterComponentEntries, bootstrapComponentRegistry, } from './deployment/deployment-registry.js';
7
+ export { createRenderHost } from './render/render-host.js';
8
8
  export declare function listClientComponents(dir: string, opts?: ListClientComponentsOpts): Promise<ClientComponentListEntry[]>;
9
9
  export declare function listClientComponentsSync(dir: string, opts?: ListClientComponentsOpts): ClientComponentListEntry[];
10
10
  export declare function mergeComponentEntries(entries: ClientComponentListEntry[], explicit?: Record<string, string>): ClientComponentListEntry[];
@@ -4,9 +4,9 @@
4
4
  */
5
5
  import path from 'node:path';
6
6
  import { pathToFileURL } from 'node:url';
7
- import { componentEntriesFromDeployment, dedupeComponentEntriesByTag, mergeExplicitComponentEntries, readDeploymentDocument, } from './deployment-registry.js';
8
- export { DEPLOYMENT_SCHEMA, readDeploymentDocument, componentEntriesFromDeployment, collectDependsOnClosure, dedupeComponentEntriesByTag, mergeExplicitComponentEntries, loadComponentEntries, importAndRegisterComponentEntries, bootstrapComponentRegistry, } from './deployment-registry.js';
9
- export { createRenderHost } from './render-host.js';
7
+ import { componentEntriesFromDeployment, dedupeComponentEntriesByTag, mergeExplicitComponentEntries, readDeploymentDocument, } from './deployment/deployment-registry.js';
8
+ export { DEPLOYMENT_SCHEMA, readDeploymentDocument, componentEntriesFromDeployment, collectDependsOnClosure, dedupeComponentEntriesByTag, mergeExplicitComponentEntries, loadComponentEntries, importAndRegisterComponentEntries, bootstrapComponentRegistry, } from './deployment/deployment-registry.js';
9
+ export { createRenderHost } from './render/render-host.js';
10
10
  export async function listClientComponents(dir, opts = {}) {
11
11
  const strict = opts.strict === true;
12
12
  const deployment = readDeploymentDocument(dir, { strict });
@@ -60,7 +60,7 @@ export function mergeComponentEntries(entries, explicit) {
60
60
  }));
61
61
  }
62
62
  export async function resolveComponentEntries(distDir, explicit, opts = {}) {
63
- const { loadComponentEntries } = await import('./deployment-registry.js');
63
+ const { loadComponentEntries } = await import('./deployment/deployment-registry.js');
64
64
  const entries = await loadComponentEntries(distDir, {
65
65
  strict: opts.strict,
66
66
  closureRoots: opts.closureRoots,
@@ -4,10 +4,10 @@
4
4
  */
5
5
  export declare function createRenderHost(distDir: string, opts?: Record<string, unknown>): Promise<{
6
6
  distDir: string;
7
- deployment: import("../shared/host.types.js").DeploymentDocument;
7
+ deployment: import("../../shared/host.types.js").DeploymentDocument;
8
8
  dom: any;
9
9
  loadedChunkIds: Set<string>;
10
- ensureComponents: (rootChunkIds?: string[] | null) => Promise<import("../shared/host.types.js").ComponentRegistryMap>;
10
+ ensureComponents: (rootChunkIds?: string[] | null) => Promise<import("../../shared/host.types.js").ComponentRegistryMap>;
11
11
  closureChunkIds: (rootChunkIds?: string[] | null) => Set<string>;
12
12
  renderToString: any;
13
13
  renderToStream: any;
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import path from 'node:path';
6
6
  import { pathToFileURL } from 'node:url';
7
- import { bootstrapComponentRegistry, collectDependsOnClosure, importAndRegisterComponentEntries, loadComponentEntries, readDeploymentDocument, } from './deployment-registry.js';
7
+ import { bootstrapComponentRegistry, collectDependsOnClosure, importAndRegisterComponentEntries, loadComponentEntries, readDeploymentDocument, } from '../deployment/deployment-registry.js';
8
8
  export async function createRenderHost(distDir, opts = {}) {
9
9
  const strict = opts.strictDeployment === true || opts.strict === true;
10
10
  const domPath = path.join(distDir, 'vmz-dom.js');
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Layout chain from Deployment Plan only (plan-only host).
3
3
  */
4
- import { readDeploymentDocument } from './deployment-registry.js';
4
+ import { readDeploymentDocument } from '../deployment/deployment-registry.js';
5
5
  /** Chunk id for `src/Application.vmz` emit (`Application.client.js`). */
6
6
  export const APPLICATION_SHELL_CHUNK = 'Application';
7
7
  /**
@@ -0,0 +1 @@
1
+ export declare function bootstrapServeHost(): Promise<void>;
@@ -0,0 +1,25 @@
1
+ import path from 'node:path';
2
+ import { pathToFileURL } from 'node:url';
3
+ import { setServerModuleResolver } from '../../faces/vmz-runtime.js';
4
+ import { installDevImportTokenHooks, normalizeDevError, softReload } from './hmr-dev.js';
5
+ import { bustUrl } from './page-catalog.js';
6
+ import { installAppModuleResolveHooks } from './paths.js';
7
+ import { serveState } from './state.js';
8
+ export async function bootstrapServeHost() {
9
+ installAppModuleResolveHooks();
10
+ globalThis.__VMZ_RPC_ORIGIN = `http://${serveState.host}:${serveState.port}`;
11
+ installDevImportTokenHooks();
12
+ setServerModuleResolver((moduleId) => {
13
+ const rel = moduleId.replace(/^#server\//, '') + '.js';
14
+ return bustUrl(pathToFileURL(path.join(serveState.distDir, '#server', rel)).href);
15
+ });
16
+ try {
17
+ await softReload({ quiet: true });
18
+ serveState.ready = true;
19
+ }
20
+ catch (err) {
21
+ serveState.lastDevError = normalizeDevError(err);
22
+ serveState.ready = true;
23
+ console.error('vmz serve: initial load failed (dev host stays up)', serveState.lastDevError.message);
24
+ }
25
+ }
@@ -0,0 +1,6 @@
1
+ export declare const ROUTE_CATALOG_SCHEMA = "vmz.route.catalog.v0";
2
+ export declare const ROUTE_CATALOG_REL = "_vmz/route-catalog.json";
3
+ export declare const LOCALE_LINK_PLAN_REL = "_vmz/locale-link-plan.json";
4
+ export declare const THEME_STORE_KEY = "vmz-theme";
5
+ export declare const LOCALE_STORE_KEY = "vmz.locale";
6
+ export declare const SHUTDOWN_TIMEOUT_MS: number;
@@ -0,0 +1,6 @@
1
+ export const ROUTE_CATALOG_SCHEMA = 'vmz.route.catalog.v0';
2
+ export const ROUTE_CATALOG_REL = '_vmz/route-catalog.json';
3
+ export const LOCALE_LINK_PLAN_REL = '_vmz/locale-link-plan.json';
4
+ export const THEME_STORE_KEY = 'vmz-theme';
5
+ export const LOCALE_STORE_KEY = 'vmz.locale';
6
+ export const SHUTDOWN_TIMEOUT_MS = Number(process.env.VMZ_SHUTDOWN_TIMEOUT_MS || 10000);
@@ -0,0 +1,34 @@
1
+ export declare function installDevImportTokenHooks(): void;
2
+ export declare function notifySse(event: string): void;
3
+ export declare function normalizeDevError(err: unknown): {
4
+ message: string;
5
+ stack: string;
6
+ at: number;
7
+ } | {
8
+ message: string;
9
+ at: number;
10
+ stack?: undefined;
11
+ };
12
+ export declare function emitDevErrorHtml(err: {
13
+ message?: string;
14
+ stack?: string;
15
+ }): AsyncGenerator<any, void, unknown>;
16
+ export declare function softReload(opts?: {
17
+ quiet?: boolean;
18
+ payload?: Record<string, unknown>;
19
+ }): Promise<{
20
+ affectedChunks: string[];
21
+ seedChunks: string[];
22
+ full: boolean;
23
+ islandHmr: boolean;
24
+ mode: string;
25
+ eventOnlyShell: boolean;
26
+ pageCount: number;
27
+ reloadedPages: number;
28
+ reloadAllPages: boolean;
29
+ buildId: string;
30
+ sourceRevision: string;
31
+ bundleRevision: string;
32
+ serveRevision: string;
33
+ token: number;
34
+ }>;