@vmz/core 0.2.4 → 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,47 @@
1
+ import type { PrecisionState } from '../dom-core.types.js';
2
+ export declare function pushTrace(kind: any, stableKind: any, stableId: any, dep?: any): void;
3
+ export declare function bumpMap(map: any, key: any, n?: number): void;
4
+ export declare const precision: PrecisionState;
5
+ export declare function __vmzPrecisionEnable(on?: boolean): void;
6
+ export declare function __vmzTraceEnable(on?: boolean): void;
7
+ export declare function __vmzPrecisionReset(): void;
8
+ export declare function __vmzTraceReset(): void;
9
+ export declare function __vmzTraceSnapshot(): {
10
+ schema: string;
11
+ events: {
12
+ stableId: {
13
+ kind: string;
14
+ id: string;
15
+ };
16
+ kind: string;
17
+ dep?: string;
18
+ t?: number;
19
+ chunkId?: string | null;
20
+ }[];
21
+ status: string;
22
+ };
23
+ export declare function __vmzPrecisionSnapshot(): {
24
+ enabled: boolean;
25
+ writes: number;
26
+ bindingEvals: number;
27
+ patchExecs: number;
28
+ domCreates: number;
29
+ domMoves: number;
30
+ domRemoves: number;
31
+ componentExecs: number;
32
+ writesByRoot: {
33
+ [x: string]: number;
34
+ };
35
+ bindingEvalsByDep: {
36
+ [x: string]: number;
37
+ };
38
+ patchesByDep: {
39
+ [x: string]: number;
40
+ };
41
+ bindingEvalsByBinding: {
42
+ [x: string]: number;
43
+ };
44
+ patchesByBinding: {
45
+ [x: string]: number;
46
+ };
47
+ };
@@ -0,0 +1,86 @@
1
+ export function pushTrace(kind, stableKind, stableId, dep = null) {
2
+ if (!traceBuf.enabled && !precision.enabled)
3
+ return;
4
+ traceBuf.events.push({
5
+ kind,
6
+ stableId: { kind: stableKind, id: String(stableId) },
7
+ dep: dep == null ? undefined : String(dep),
8
+ t: Date.now(),
9
+ });
10
+ if (traceBuf.events.length > TRACE_CAP) {
11
+ traceBuf.events.splice(0, traceBuf.events.length - TRACE_CAP);
12
+ }
13
+ }
14
+ export function bumpMap(map, key, n = 1) {
15
+ if (key == null || key === '')
16
+ return;
17
+ map[key] = (map[key] || 0) + n;
18
+ }
19
+ export const precision = {
20
+ enabled: false,
21
+ writes: 0,
22
+ bindingEvals: 0,
23
+ patchExecs: 0,
24
+ domCreates: 0,
25
+ domMoves: 0,
26
+ domRemoves: 0,
27
+ componentExecs: 0,
28
+ writesByRoot: Object.create(null),
29
+ bindingEvalsByDep: Object.create(null),
30
+ patchesByDep: Object.create(null),
31
+ bindingEvalsByBinding: Object.create(null),
32
+ patchesByBinding: Object.create(null),
33
+ };
34
+ const TRACE_CAP = 256;
35
+ const traceBuf = {
36
+ enabled: false,
37
+ events: [],
38
+ };
39
+ export function __vmzPrecisionEnable(on = true) {
40
+ precision.enabled = !!on;
41
+ }
42
+ export function __vmzTraceEnable(on = true) {
43
+ traceBuf.enabled = !!on;
44
+ }
45
+ export function __vmzPrecisionReset() {
46
+ precision.writes = 0;
47
+ precision.bindingEvals = 0;
48
+ precision.patchExecs = 0;
49
+ precision.domCreates = 0;
50
+ precision.domMoves = 0;
51
+ precision.domRemoves = 0;
52
+ precision.componentExecs = 0;
53
+ precision.writesByRoot = Object.create(null);
54
+ precision.bindingEvalsByDep = Object.create(null);
55
+ precision.patchesByDep = Object.create(null);
56
+ precision.bindingEvalsByBinding = Object.create(null);
57
+ precision.patchesByBinding = Object.create(null);
58
+ }
59
+ export function __vmzTraceReset() {
60
+ traceBuf.events = [];
61
+ }
62
+ export function __vmzTraceSnapshot() {
63
+ const events = traceBuf.events.map((e) => ({ ...e, stableId: { ...e.stableId } }));
64
+ return {
65
+ schema: 'vmz.dx.trace.v0',
66
+ events,
67
+ status: events.length ? 'ready' : 'empty',
68
+ };
69
+ }
70
+ export function __vmzPrecisionSnapshot() {
71
+ return {
72
+ enabled: precision.enabled,
73
+ writes: precision.writes,
74
+ bindingEvals: precision.bindingEvals,
75
+ patchExecs: precision.patchExecs,
76
+ domCreates: precision.domCreates,
77
+ domMoves: precision.domMoves,
78
+ domRemoves: precision.domRemoves,
79
+ componentExecs: precision.componentExecs,
80
+ writesByRoot: { ...precision.writesByRoot },
81
+ bindingEvalsByDep: { ...precision.bindingEvalsByDep },
82
+ patchesByDep: { ...precision.patchesByDep },
83
+ bindingEvalsByBinding: { ...precision.bindingEvalsByBinding },
84
+ patchesByBinding: { ...precision.patchesByBinding },
85
+ };
86
+ }
@@ -0,0 +1,5 @@
1
+ export declare const BOOLEAN_HTML_ATTRS: Set<string>;
2
+ export declare function applyDomAttr(el: any, name: any, value: any): void;
3
+ export declare function eventPropHandlerName(name: any): string;
4
+ export declare function emitComponentEvent(inst: any, eventName: any, ...payload: any[]): void;
5
+ export declare function isEventPropName(name: any): boolean;
@@ -0,0 +1,102 @@
1
+ import { mergeClassParts, mergeStyleParts } from '../../shared/dom-attr-normalize.js';
2
+ export const BOOLEAN_HTML_ATTRS = new Set([
3
+ 'disabled',
4
+ 'checked',
5
+ 'selected',
6
+ 'readonly',
7
+ 'required',
8
+ 'multiple',
9
+ 'hidden',
10
+ 'autofocus',
11
+ 'autoplay',
12
+ 'controls',
13
+ 'loop',
14
+ 'muted',
15
+ 'open',
16
+ 'novalidate',
17
+ 'formnovalidate',
18
+ 'defer',
19
+ 'async',
20
+ 'ismap',
21
+ 'default',
22
+ 'inert',
23
+ ]);
24
+ export function applyDomAttr(el, name, value) {
25
+ const key = name === 'className' ? 'class' : name;
26
+ if (key === 'class') {
27
+ const s = mergeClassParts(value);
28
+ if (s)
29
+ el.setAttribute('class', s);
30
+ else
31
+ el.removeAttribute('class');
32
+ return;
33
+ }
34
+ if (key === 'style') {
35
+ const s = mergeStyleParts(value);
36
+ if (s)
37
+ el.setAttribute('style', s);
38
+ else
39
+ el.removeAttribute('style');
40
+ return;
41
+ }
42
+ if (BOOLEAN_HTML_ATTRS.has(String(key).toLowerCase())) {
43
+ const on = value === true || value === '';
44
+ if (key === 'checked' && el && el.tagName === 'INPUT' && String(el.type || '').toLowerCase() === 'checkbox') {
45
+ if (el.checked !== on)
46
+ el.checked = on;
47
+ }
48
+ if (value === false || value == null || value === '') {
49
+ el.removeAttribute(key);
50
+ }
51
+ else {
52
+ el.setAttribute(key, value === true ? '' : String(value));
53
+ }
54
+ return;
55
+ }
56
+ // <textarea value="??> as an attribute does not update visible text; INPUT/SELECT
57
+ // also need the IDL `.value` property so controlled updates stay in sync after switches.
58
+ // linkedom `<select>.value` is getter-only ??sync via `option.selected` instead of throwing.
59
+ if (key === 'value' && el && (el.tagName === 'TEXTAREA' || el.tagName === 'INPUT' || el.tagName === 'SELECT')) {
60
+ const next = value == null || value === false ? '' : String(value);
61
+ if (el.tagName === 'SELECT') {
62
+ const opts = el.options || el.querySelectorAll?.('option') || [];
63
+ for (const opt of opts) {
64
+ opt.selected = String(opt.value ?? '') === next;
65
+ }
66
+ }
67
+ else if (el.value !== next) {
68
+ el.value = next;
69
+ }
70
+ if (value == null || value === false)
71
+ el.removeAttribute('value');
72
+ else
73
+ el.setAttribute('value', next);
74
+ return;
75
+ }
76
+ if (value == null || value === false)
77
+ el.removeAttribute(key);
78
+ else
79
+ el.setAttribute(key, value === true ? '' : String(value));
80
+ }
81
+ export function eventPropHandlerName(name) {
82
+ if (typeof name !== 'string' || !name)
83
+ return null;
84
+ if (/^on[A-Z]/.test(name))
85
+ return name;
86
+ return null;
87
+ }
88
+ export function emitComponentEvent(inst, eventName, ...payload) {
89
+ if (!inst || typeof eventName !== 'string' || !eventName)
90
+ return;
91
+ const bag = inst.__vmzComponentListeners;
92
+ const list = bag && bag[eventName];
93
+ if (!Array.isArray(list) || list.length === 0)
94
+ return;
95
+ for (const fn of list) {
96
+ if (typeof fn === 'function')
97
+ fn(...payload);
98
+ }
99
+ }
100
+ export function isEventPropName(name) {
101
+ return eventPropHandlerName(name) != null;
102
+ }
@@ -0,0 +1,11 @@
1
+ export declare function mount(Component: any, container: any, props?: any): Promise<any>;
2
+ export declare function settlePendingChildMounts(inst: any): Promise<void>;
3
+ export declare function runDirectCreate(Component: any, inst: any): any;
4
+ export declare function findOwnedDefaultSlot(root: any): any;
5
+ export declare function findOwnedDefaultSlotTarget(root: any): any;
6
+ export declare function createInstance(Component: any, props?: any): any;
7
+ export declare function destroy(inst: any): void;
8
+ export declare function disposeDomTree(root: any): void;
9
+ export declare function snapshotInstanceState(inst: any): {};
10
+ export declare function applyPreservedState(inst: any, state: any): void;
11
+ export declare function stripFns(obj: any): {};
@@ -0,0 +1,255 @@
1
+ import { precision } from '../diagnostics/precision-trace.js';
2
+ import { emitComponentEvent } from './attributes.js';
3
+ import { directApi } from './direct-api.js';
4
+ import { __vmzCancelTasks } from './lifecycle.js';
5
+ import { flushPending } from '../reactivity/patch-scheduler.js';
6
+ import { __vmzAllowShared, __vmzArrayItemCompoundStride, __vmzArrayMutate, __vmzListTranspose, __vmzReadPath, __vmzTakeShared, __vmzWritePath, __vmzWritePathCompound, __vmzWritePathCompoundItem, __vmzWritePathItem, __vmzWritePathLogical, makeReactive, } from '../reactivity/write-barrier.js';
7
+ export async function mount(Component, container, props = {}) {
8
+ if (container.__vmzInst) {
9
+ destroy(container.__vmzInst);
10
+ container.__vmzInst = null;
11
+ }
12
+ const inst = createInstance(Component, props);
13
+ inst.__vmzBinders = Object.create(null);
14
+ inst.__vmzBindings = Object.create(null);
15
+ inst.__vmzDepToBindings = Object.create(null);
16
+ container.replaceChildren();
17
+ const node = await createFromComponent(Component, inst);
18
+ if (node) {
19
+ inst.__vmzDomRoot = node;
20
+ container.appendChild(node);
21
+ }
22
+ if (typeof inst.onMount === 'function') {
23
+ await inst.onMount();
24
+ }
25
+ await settlePendingChildMounts(inst);
26
+ container.__vmzInst = inst;
27
+ return inst;
28
+ }
29
+ export async function settlePendingChildMounts(inst) {
30
+ if (!inst || !Array.isArray(inst.__vmzPendingChildMounts) || !inst.__vmzPendingChildMounts.length)
31
+ return;
32
+ await Promise.all(inst.__vmzPendingChildMounts);
33
+ inst.__vmzPendingChildMounts = [];
34
+ const hosts = [];
35
+ const root = inst.__vmzDomRoot;
36
+ if (root && root.nodeType === 1) {
37
+ if (root.__vmzInst)
38
+ hosts.push(root.__vmzInst);
39
+ for (const el of root.querySelectorAll('[data-vmz]')) {
40
+ if (el.__vmzInst)
41
+ hosts.push(el.__vmzInst);
42
+ }
43
+ }
44
+ for (const child of hosts) {
45
+ await flushPending(child);
46
+ await settlePendingChildMounts(child);
47
+ }
48
+ }
49
+ async function createFromComponent(Component, inst) {
50
+ if (Component && Component.__vmzDirect && typeof Component.__vmzCreate === 'function') {
51
+ return runDirectCreate(Component, inst);
52
+ }
53
+ throw new Error(`vmz:dom mount requires __vmzCreate (Direct); blueprint render() removed (production Direct emit)`);
54
+ }
55
+ export function runDirectCreate(Component, inst) {
56
+ // Nested component creates (e.g. Button inside parent ifBlock branch) must not
57
+ // leak bindAttr/bindText into the parent's `_branchBinds` / `_itemPatches` sink ?? // that steals numeric BindingIds (0) and corrupts parent deps (density ??type).
58
+ const prevInst = directApi._inst;
59
+ const prevBranch = directApi._branchBinds;
60
+ const prevItems = directApi._itemPatches;
61
+ const prevEach = directApi._eachCtx;
62
+ directApi._inst = inst;
63
+ directApi._branchBinds = null;
64
+ directApi._itemPatches = null;
65
+ directApi._eachCtx = null;
66
+ try {
67
+ return Component.__vmzCreate.call(inst, directApi);
68
+ }
69
+ finally {
70
+ directApi._inst = prevInst;
71
+ directApi._branchBinds = prevBranch;
72
+ directApi._itemPatches = prevItems;
73
+ directApi._eachCtx = prevEach;
74
+ }
75
+ }
76
+ export function findOwnedDefaultSlot(root) {
77
+ if (!root || root.nodeType !== 1)
78
+ return null;
79
+ const tag = String(root.tagName || '').toLowerCase();
80
+ if (tag === 'slot' && !root.getAttribute('name'))
81
+ return root;
82
+ const kids = root.children;
83
+ if (!kids || !kids.length)
84
+ return null;
85
+ for (let i = 0; i < kids.length; i++) {
86
+ const c = kids[i];
87
+ if (c.nodeType !== 1)
88
+ continue;
89
+ if (c.hasAttribute('data-vmz'))
90
+ continue;
91
+ const hit = findOwnedDefaultSlot(c);
92
+ if (hit)
93
+ return hit;
94
+ }
95
+ return null;
96
+ }
97
+ export function findOwnedDefaultSlotTarget(root) {
98
+ const slot = findOwnedDefaultSlot(root);
99
+ if (slot)
100
+ return slot;
101
+ if (!root || root.nodeType !== 1)
102
+ return null;
103
+ const walk = (el) => {
104
+ if (!el || el.nodeType !== 1)
105
+ return null;
106
+ const tag = String(el.tagName || '').toLowerCase();
107
+ if ((tag === 'button' || tag === 'a') && el.getAttribute('data-vmz-ui') === 'button')
108
+ return el;
109
+ if (el.hasAttribute('data-vmz'))
110
+ return null;
111
+ const kids = el.children;
112
+ if (!kids || !kids.length)
113
+ return null;
114
+ for (let i = 0; i < kids.length; i++) {
115
+ const hit = walk(kids[i]);
116
+ if (hit)
117
+ return hit;
118
+ }
119
+ return null;
120
+ };
121
+ return walk(root);
122
+ }
123
+ export function createInstance(Component, props = {}) {
124
+ if (precision.enabled)
125
+ precision.componentExecs++;
126
+ const inst = new Component(props || {});
127
+ if (typeof inst.__vmzApplyProps === 'function' && !Component.__vmzCtorAppliesProps) {
128
+ inst.__vmzApplyProps(props || {});
129
+ }
130
+ inst.__vmzBinders = Object.create(null);
131
+ inst.__vmzBindings = Object.create(null);
132
+ inst.__vmzDepToBindings = Object.create(null);
133
+ inst.__vmzComponentListeners = Object.create(null);
134
+ // Compiler intrinsic surface: `this.emit('submit', payload)` ??not a string bus.
135
+ inst.emit = function emit(eventName, ...payload) {
136
+ return emitComponentEvent(inst, eventName, ...payload);
137
+ };
138
+ makeReactive(inst, Component.__vmzState || []);
139
+ makeReactive(inst, Component.__vmzProps || []);
140
+ // WriteBarrier: install Component helpers once (no import needed in emitted code).
141
+ if (!Component.__vmzWBInstalled) {
142
+ Component.__vmzWBInstalled = true;
143
+ Component.__vmzWritePath = __vmzWritePath;
144
+ Component.__vmzWritePathItem = __vmzWritePathItem;
145
+ Component.__vmzWritePathCompound = __vmzWritePathCompound;
146
+ Component.__vmzWritePathCompoundItem = __vmzWritePathCompoundItem;
147
+ Component.__vmzWritePathLogical = __vmzWritePathLogical;
148
+ Component.__vmzReadPath = __vmzReadPath;
149
+ Component.__vmzArrayMutate = __vmzArrayMutate;
150
+ Component.__vmzArrayItemCompoundStride = __vmzArrayItemCompoundStride;
151
+ Component.__vmzListTranspose = __vmzListTranspose;
152
+ Component.__vmzAllowShared = __vmzAllowShared;
153
+ Component.__vmzTakeShared = __vmzTakeShared;
154
+ }
155
+ return inst;
156
+ }
157
+ export function destroy(inst) {
158
+ if (!inst || inst.__vmzDestroyed)
159
+ return;
160
+ inst.__vmzDestroyed = true;
161
+ inst.__vmzFlushScheduled = false;
162
+ // async cancel: abort in-flight tasks before tearing down DOM.
163
+ __vmzCancelTasks(inst);
164
+ if (inst.__vmzDomRoot) {
165
+ disposeDomTree(inst.__vmzDomRoot);
166
+ inst.__vmzDomRoot = null;
167
+ }
168
+ if (inst.__vmzDirtyNotices)
169
+ inst.__vmzDirtyNotices.length = 0;
170
+ if (inst.__vmzDirtyTrie)
171
+ inst.__vmzDirtyTrie = Object.create(null);
172
+ if (inst.__vmzDirty)
173
+ inst.__vmzDirty.clear();
174
+ inst.__vmzBinders = Object.create(null);
175
+ inst.__vmzBindings = Object.create(null);
176
+ inst.__vmzDepToBindings = Object.create(null);
177
+ if (typeof inst.onDestroy === 'function') {
178
+ try {
179
+ inst.onDestroy();
180
+ }
181
+ catch (err) {
182
+ console.error('vmz:dom onDestroy', err);
183
+ }
184
+ }
185
+ }
186
+ export function disposeDomTree(root) {
187
+ if (!root)
188
+ return;
189
+ const seen = new Set();
190
+ const visit = (node) => {
191
+ if (!node || seen.has(node))
192
+ return;
193
+ seen.add(node);
194
+ if (typeof node.__vmzDispose === 'function') {
195
+ try {
196
+ node.__vmzDispose();
197
+ }
198
+ catch (err) {
199
+ console.error('vmz:dom __vmzDispose', err);
200
+ }
201
+ node.__vmzDispose = null;
202
+ }
203
+ if (node.__vmzInst) {
204
+ const child = node.__vmzInst;
205
+ node.__vmzInst = null;
206
+ destroy(child);
207
+ }
208
+ let child = node.firstChild;
209
+ while (child) {
210
+ const next = child.nextSibling;
211
+ visit(child);
212
+ child = next;
213
+ }
214
+ };
215
+ visit(root);
216
+ }
217
+ export function snapshotInstanceState(inst) {
218
+ if (!inst || inst.__vmzDestroyed)
219
+ return null;
220
+ const Ctor = inst.constructor;
221
+ const keys = [...(Ctor.__vmzState || []), ...(Ctor.__vmzProps || [])];
222
+ const out = {};
223
+ for (const key of keys) {
224
+ if (!key || String(key).startsWith('__'))
225
+ continue;
226
+ try {
227
+ out[key] = inst[key];
228
+ }
229
+ catch {
230
+ /* ignore accessors that throw */
231
+ }
232
+ }
233
+ return out;
234
+ }
235
+ export function applyPreservedState(inst, state) {
236
+ if (!inst || !state)
237
+ return;
238
+ for (const [key, value] of Object.entries(state)) {
239
+ try {
240
+ inst[key] = value;
241
+ }
242
+ catch {
243
+ /* ignore */
244
+ }
245
+ }
246
+ }
247
+ export function stripFns(obj) {
248
+ const out = {};
249
+ for (const [k, v] of Object.entries(obj || {})) {
250
+ if (typeof v === 'function')
251
+ continue;
252
+ out[k] = v;
253
+ }
254
+ return out;
255
+ }
@@ -0,0 +1,66 @@
1
+ import type { BindingId, DirectInstance, PatchFn } from '../direct-api.types.js';
2
+ import type { EachCtx, ResumeAdoptCtx } from '../dom-core.types.js';
3
+ export declare const directApi: {
4
+ _inst: DirectInstance | null;
5
+ _branchBinds: Array<{
6
+ deps: string[];
7
+ fn: PatchFn;
8
+ bindingId?: BindingId;
9
+ }> | null;
10
+ _itemPatches: PatchFn[] | null;
11
+ _eachCtx: EachCtx | null;
12
+ _resumeAdopt: ResumeAdoptCtx | null;
13
+ el(tag: any): any;
14
+ elNS(ns: any, tag: any): Element;
15
+ text(value: any): Text;
16
+ adoptEnter(node: any): boolean;
17
+ adoptLeave(): void;
18
+ frag(): DocumentFragment;
19
+ comment(value: any): Comment;
20
+ insertBefore(parent: any, node: any, ref: any): void;
21
+ removeNode(node: any): void;
22
+ /**
23
+ * Register a generated per-binding patch (0.2.0). No generic get/cf interpreter.
24
+ */
25
+ trackPatch(inst: any, deps: any, patch: any, bindingId?: any): void;
26
+ untrackPatch(inst: any, deps: any, patch: any, bindingId?: any): void;
27
+ disposeTree(root: any): void;
28
+ attr(el: any, name: any, value: any): void;
29
+ mergeClass(...parts: any[]): string;
30
+ mergeStyle(...parts: any[]): string;
31
+ on(el: any, type: any, handler: any): void;
32
+ /**
33
+ * Bind a named instance method (no arrow / Function#toString).
34
+ * Learns `skipFlush` after a sync invocation that schedules no dirty work
35
+ * (stride / transpose self-apply DOM).
36
+ */
37
+ onMethod(el: any, type: any, methodName: any, opts: any): void;
38
+ /**
39
+ * Specialized single-field attr bind (0.1.29): compile-time field name, no generic get closure in artifact.
40
+ */
41
+ specFieldAttr(inst: any, bindingId: any, fieldName: any, el: any, name: any): void;
42
+ /**
43
+ * Specialized single-field text bind (0.1.29): compile-time field name in generated artifact.
44
+ */
45
+ specFieldText(inst: any, bindingId: any, fieldName: any, textNode: any): void;
46
+ setHtml(el: any, value: any): void;
47
+ bindHtml(inst: any, bindingId: any, deps: any, get: any, el: any): void;
48
+ /**
49
+ * Nested component (sync Direct child or island schedule).
50
+ */
51
+ component(hostInst: any, nameOrCtor: any, props: any, client: any): any;
52
+ /**
53
+ * Subscribe to a child component event (`@submit` ??event name `submit`).
54
+ * Orthogonal to function props (`:on-submit` ??prop `onSubmit`).
55
+ */
56
+ onComponentEvent(hostEl: any, eventName: any, handler: any): void;
57
+ /**
58
+ * Keep nested Direct child props live with parent field writes.
59
+ */
60
+ bindComponentProp(hostInst: any, hostEl: any, propName: any, deps: any, get: any): void;
61
+ /**
62
+ * Project parent children into nested Direct component default `<slot>`.
63
+ * Uses {@link findOwnedDefaultSlot} so nested Button/Link slots are not stolen.
64
+ */
65
+ projectDefaultSlot(hostEl: any, node: any): void;
66
+ };