@vmz/core 0.1.17 → 0.1.19

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.
@@ -153,14 +153,14 @@ export declare const directApi: {
153
153
  */
154
154
  projectDefaultSlot(hostEl: any, node: any): void;
155
155
  /**
156
- * Direct if/else — no blueprint `kind: "if"` dispatch.
156
+ * Direct if/else — comment anchors (no empty `span[data-vmz-if]` layout box).
157
157
  * @param {object} inst
158
158
  * @param {number|string|null} bindingId
159
159
  * @param {string[]} deps
160
160
  * @param {Array<{ cond?: => any, create: (api: typeof directApi) => Node }>} branches
161
161
  * @param {number|string|null} [regionId]
162
162
  */
163
- ifBlock(inst: any, bindingId: any, deps: any, branches: any, regionId?: any): HTMLSpanElement;
163
+ ifBlock(inst: any, bindingId: any, deps: any, branches: any, regionId?: any): DocumentFragment;
164
164
  /**
165
165
  * Direct keyed each — no blueprint `kind: "each"` dispatch.
166
166
  * /: Set/Map + Fragment batch insert; item-local binds; host field dispatch; event delegate.
package/dist/dom-core.js CHANGED
@@ -9,6 +9,12 @@
9
9
  */
10
10
  /** @type {Record<string, new (props?: object) => any>} */
11
11
  const components = Object.create(null);
12
+ /**
13
+ * Inline chip hosts that opt into `display: contents` (`ui-direct-host-box`).
14
+ * Block surfaces (DataTable / shells / overlays) must keep a real layout box.
15
+ * @type {Set<string>}
16
+ */
17
+ const INLINE_HOST_CONTENTS = new Set(['Button', 'Badge', 'Link', 'Tag', 'Icon']);
12
18
  /**
13
19
  * Precision lab counters (test / MCP / benchmarks — not a user API).
14
20
  * Primary keys: BindingId (IR). `*ByDep` is transitional stable-string adapter.
@@ -455,6 +461,13 @@ export const directApi = {
455
461
  const Ctor = components[name];
456
462
  if (!Ctor)
457
463
  throw new Error(`vmz:dom unknown component <${name} />`);
464
+ // Inline chips opt into no-box host (`ui-direct-host-box`). Block surfaces
465
+ // (tables/shells/overlays) keep a real box — default `contents` breaks
466
+ // hit-testing / slot hosts (DataTable select timed out in ui-automation).
467
+ const hostBox = Ctor.__vmzHostBox;
468
+ if (hostBox === 'contents' || (hostBox == null && INLINE_HOST_CONTENTS.has(String(name)))) {
469
+ host.style.display = 'contents';
470
+ }
458
471
  const child = createInstance(Ctor, resolved);
459
472
  if (!(Ctor.__vmzDirect && typeof Ctor.__vmzCreate === 'function')) {
460
473
  throw new Error(`vmz:dom direct component <${name}> requires __vmzCreate (rebuild child with Direct)`);
@@ -540,7 +553,7 @@ export const directApi = {
540
553
  hostEl.appendChild(node);
541
554
  },
542
555
  /**
543
- * Direct if/else — no blueprint `kind: "if"` dispatch.
556
+ * Direct if/else — comment anchors (no empty `span[data-vmz-if]` layout box).
544
557
  * @param {object} inst
545
558
  * @param {number|string|null} bindingId
546
559
  * @param {string[]} deps
@@ -549,10 +562,22 @@ export const directApi = {
549
562
  */
550
563
  ifBlock(inst, bindingId, deps, branches, regionId = null) {
551
564
  noteDomCreate();
552
- const host = document.createElement('span');
553
- host.setAttribute('data-vmz-if', '');
565
+ const start = document.createComment('vmz-if');
566
+ const end = document.createComment('/vmz-if');
554
567
  if (regionId != null)
555
- host.setAttribute('data-vmz-region', String(regionId));
568
+ start.__vmzRegion = regionId;
569
+ const frag = document.createDocumentFragment();
570
+ frag.appendChild(start);
571
+ /** @type {HTMLElement | null} */
572
+ let regionHost = null;
573
+ if (regionId != null) {
574
+ // Queryable region marker without a layout box (`display: contents`).
575
+ regionHost = document.createElement('span');
576
+ regionHost.style.display = 'contents';
577
+ regionHost.setAttribute('data-vmz-region', String(regionId));
578
+ frag.appendChild(regionHost);
579
+ }
580
+ frag.appendChild(end);
556
581
  /** @type {Array<Node | null>} */
557
582
  const cached = branches.map(() => null);
558
583
  /** @type {Array<Array<{ deps: string[], fn: => any, bindingId?: number|string|null }>>} */
@@ -635,14 +660,18 @@ export const directApi = {
635
660
  if (next < 0)
636
661
  return;
637
662
  wireBranch(next);
638
- if (cached[next])
639
- host.appendChild(cached[next]);
663
+ if (cached[next] && end.parentNode) {
664
+ if (regionHost)
665
+ regionHost.appendChild(cached[next]);
666
+ else
667
+ end.parentNode.insertBefore(cached[next], end);
668
+ }
640
669
  };
641
670
  registerBind(inst, deps || [], apply, bindingId);
642
671
  if (directApi._itemPatches)
643
672
  directApi._itemPatches.push(apply);
644
673
  // parent destroy disposes all cached branch trees (pause ≠ destroy on switch).
645
- host.__vmzDispose = () => {
674
+ start.__vmzDispose = () => {
646
675
  for (let i = 0; i < cached.length; i++) {
647
676
  unwireBranch(i);
648
677
  if (cached[i])
@@ -652,7 +681,7 @@ export const directApi = {
652
681
  active = -1;
653
682
  };
654
683
  apply();
655
- return host;
684
+ return frag;
656
685
  },
657
686
  /**
658
687
  * Direct keyed each — no blueprint `kind: "each"` dispatch.
package/dist/dom-ssr.js CHANGED
@@ -671,16 +671,8 @@ const serializeApi = {
671
671
  el.children = [];
672
672
  },
673
673
  ifBlock(inst, bindingId, deps, branches) {
674
- const host = {
675
- __kind: 'el',
676
- tag: 'span',
677
- attrs: { 'data-vmz-if': '' },
678
- children: [],
679
- appendChild(c) {
680
- if (c != null)
681
- this.children.push(c);
682
- },
683
- };
674
+ // No empty `span[data-vmz-if]` box (`ui-vif-dom`): false → empty frag.
675
+ const frag = serializeApi.frag();
684
676
  let idx = -1;
685
677
  for (let i = 0; i < branches.length; i++) {
686
678
  const b = branches[i];
@@ -701,9 +693,9 @@ const serializeApi = {
701
693
  if (idx >= 0 && branches[idx].create) {
702
694
  const created = branches[idx].create.call(inst, serializeApi);
703
695
  if (created)
704
- host.children.push(created);
696
+ frag.appendChild(created);
705
697
  }
706
- return host;
698
+ return frag;
707
699
  },
708
700
  eachBlock(inst, bindingId, deps, spec) {
709
701
  const frag = serializeApi.frag();
@@ -816,10 +808,17 @@ const serializeApi = {
816
808
  serializeApi._inst = child;
817
809
  try {
818
810
  const node = Ctor.__vmzCreate.call(child, serializeApi);
811
+ /** @type {Record<string, string>} */
812
+ const attrs = { 'data-vmz': name };
813
+ const hostBox = Ctor.__vmzHostBox;
814
+ if (hostBox === 'contents' ||
815
+ (hostBox == null && (name === 'Button' || name === 'Badge' || name === 'Link' || name === 'Tag' || name === 'Icon'))) {
816
+ attrs.style = 'display:contents';
817
+ }
819
818
  return {
820
819
  __kind: 'el',
821
820
  tag: 'div',
822
- attrs: { 'data-vmz': name },
821
+ attrs,
823
822
  children: node ? [node] : [],
824
823
  appendChild(c) {
825
824
  if (c != null)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vmz/core",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "type": "module",
5
5
  "description": "VMZ production runtime core — DOM / SSR / HTTP / WriteBarrier (no compiler)",
6
6
  "exports": {
@@ -58,12 +58,12 @@
58
58
  "linkedom": "^0.18.13"
59
59
  },
60
60
  "optionalDependencies": {
61
- "@vmz/vmz-win32-x64": "0.1.17",
62
- "@vmz/vmz-win32-arm64": "0.1.17",
63
- "@vmz/vmz-darwin-x64": "0.1.17",
64
- "@vmz/vmz-darwin-arm64": "0.1.17",
65
- "@vmz/vmz-linux-x64": "0.1.17",
66
- "@vmz/vmz-linux-arm64": "0.1.17"
61
+ "@vmz/vmz-win32-x64": "0.1.19",
62
+ "@vmz/vmz-win32-arm64": "0.1.19",
63
+ "@vmz/vmz-darwin-x64": "0.1.19",
64
+ "@vmz/vmz-darwin-arm64": "0.1.19",
65
+ "@vmz/vmz-linux-x64": "0.1.19",
66
+ "@vmz/vmz-linux-arm64": "0.1.19"
67
67
  },
68
68
  "publishConfig": {
69
69
  "access": "public"