@vmz/core 0.2.1 → 0.2.3

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.
@@ -81,6 +81,8 @@ export declare function runDirectCreate(Component: any, inst: any): any;
81
81
  * projects parent siblings into the wrong host (commercial Drawer into Create btn).
82
82
  */
83
83
  export declare function findOwnedDefaultSlot(root: any): any;
84
+ /** Button/Link shell when `<slot>` is absent (SSR-flattened or resume adopt). */
85
+ export declare function findOwnedDefaultSlotTarget(root: any): any;
84
86
  export declare const directApi: {
85
87
  _inst: DirectInstance | null;
86
88
  _branchBinds: Array<{
@@ -92,6 +94,7 @@ export declare const directApi: {
92
94
  _eachCtx: EachCtx | null;
93
95
  _resumeAdopt: ResumeAdoptCtx | null;
94
96
  el(tag: any): any;
97
+ elNS(ns: any, tag: any): Element;
95
98
  text(value: any): Text;
96
99
  adoptEnter(node: any): boolean;
97
100
  adoptLeave(): void;
@@ -262,6 +262,33 @@ export function findOwnedDefaultSlot(root) {
262
262
  }
263
263
  return null;
264
264
  }
265
+ /** Button/Link shell when `<slot>` is absent (SSR-flattened or resume adopt). */
266
+ export function findOwnedDefaultSlotTarget(root) {
267
+ const slot = findOwnedDefaultSlot(root);
268
+ if (slot)
269
+ return slot;
270
+ if (!root || root.nodeType !== 1)
271
+ return null;
272
+ const walk = (el) => {
273
+ if (!el || el.nodeType !== 1)
274
+ return null;
275
+ const tag = String(el.tagName || '').toLowerCase();
276
+ if ((tag === 'button' || tag === 'a') && el.getAttribute('data-vmz-ui') === 'button')
277
+ return el;
278
+ if (el.hasAttribute('data-vmz'))
279
+ return null;
280
+ const kids = el.children;
281
+ if (!kids || !kids.length)
282
+ return null;
283
+ for (let i = 0; i < kids.length; i++) {
284
+ const hit = walk(kids[i]);
285
+ if (hit)
286
+ return hit;
287
+ }
288
+ return null;
289
+ };
290
+ return walk(root);
291
+ }
265
292
  export const directApi = {
266
293
  _inst: null,
267
294
  _branchBinds: null,
@@ -274,6 +301,13 @@ export const directApi = {
274
301
  noteDomCreate();
275
302
  return document.createElement(tag || 'div');
276
303
  },
304
+ elNS(ns, tag) {
305
+ if (directApi._resumeAdopt && typeof directApi._resumeAdopt.elNS === 'function') {
306
+ return directApi._resumeAdopt.elNS(ns, tag);
307
+ }
308
+ noteDomCreate();
309
+ return document.createElementNS(ns || 'http://www.w3.org/2000/svg', tag || 'g');
310
+ },
277
311
  text(value) {
278
312
  if (directApi._resumeAdopt)
279
313
  return directApi._resumeAdopt.text(value);
@@ -677,12 +711,13 @@ export const directApi = {
677
711
  // Emptied DocumentFragment after append must not receive slot kids.
678
712
  if (!root || root.nodeType !== 1)
679
713
  root = hostEl;
680
- let slot = null;
681
- if (root && root.nodeType === 1) {
682
- slot = findOwnedDefaultSlot(root);
683
- }
684
- if (slot && slot.parentNode) {
685
- slot.replaceWith(node);
714
+ const target = root && root.nodeType === 1 ? findOwnedDefaultSlotTarget(root) : null;
715
+ if (target && target.parentNode) {
716
+ if (String(target.tagName || '').toLowerCase() === 'slot') {
717
+ target.replaceWith(node);
718
+ return;
719
+ }
720
+ target.appendChild(node);
686
721
  return;
687
722
  }
688
723
  if (root && root.nodeType === 1 && typeof root.appendChild === 'function')
@@ -70,6 +70,7 @@ export type TraceBuffer = {
70
70
  };
71
71
  export type ResumeAdoptCtx = {
72
72
  el: (tag: string) => Element;
73
+ elNS?: (ns: string, tag: string) => Element;
73
74
  text: (value?: unknown) => Text;
74
75
  componentHost?: (name: string) => HTMLElement | null;
75
76
  enter?: (node: Element) => boolean;
@@ -549,7 +549,16 @@ const serializeApi = {
549
549
  return child;
550
550
  },
551
551
  el(tag) {
552
- return makeVirtualEl(tag);
552
+ const node = makeVirtualEl(tag);
553
+ if (String(tag || '').toLowerCase() === 'svg') {
554
+ node.namespaceURI = 'http://www.w3.org/2000/svg';
555
+ }
556
+ return node;
557
+ },
558
+ elNS(ns, tag) {
559
+ const node = makeVirtualEl(tag);
560
+ node.namespaceURI = ns || 'http://www.w3.org/2000/svg';
561
+ return node;
553
562
  },
554
563
  text(value) {
555
564
  const node = { __kind: 'text', value: value == null ? '' : String(value), parentNode: null };
@@ -691,7 +700,17 @@ const serializeApi = {
691
700
  // serializeApi.component returns a serialize el tree (or island shell).
692
701
  const root = hostEl.__kind === 'el' ? hostEl : null;
693
702
  const findOwnedSlot = (n) => {
694
- if (!n || n.__kind !== 'el')
703
+ if (!n || typeof n !== 'object')
704
+ return null;
705
+ if (n.__kind === 'frag') {
706
+ for (const c of n.children || []) {
707
+ const hit = findOwnedSlot(c);
708
+ if (hit)
709
+ return hit;
710
+ }
711
+ return null;
712
+ }
713
+ if (n.__kind !== 'el')
695
714
  return null;
696
715
  if (n.tag === 'slot' && !(n.attrs && n.attrs.name))
697
716
  return n;
@@ -704,26 +723,52 @@ const serializeApi = {
704
723
  }
705
724
  return null;
706
725
  };
726
+ const findOwnedSlotTarget = (n) => {
727
+ const slot = findOwnedSlot(n);
728
+ if (slot)
729
+ return slot;
730
+ if (!n || n.__kind !== 'el')
731
+ return null;
732
+ const tag = String(n.tag || '').toLowerCase();
733
+ if ((tag === 'button' || tag === 'a') && n.attrs && n.attrs['data-vmz-ui'] === 'button')
734
+ return n;
735
+ if (n.attrs && n.attrs['data-vmz'] != null)
736
+ return null;
737
+ for (const c of n.children || []) {
738
+ if (c && c.__kind === 'el' && c.attrs && c.attrs['data-vmz'] != null)
739
+ continue;
740
+ const hit = findOwnedSlotTarget(c);
741
+ if (hit)
742
+ return hit;
743
+ }
744
+ return null;
745
+ };
707
746
  // Prefer searching the component body (first child of host wrapper).
708
- let slot = null;
747
+ let target = null;
709
748
  if (root) {
710
749
  for (const c of root.children || []) {
711
750
  if (c && c.__kind === 'el' && c.attrs && c.attrs['data-vmz'] != null)
712
751
  continue;
713
- slot = findOwnedSlot(c);
714
- if (slot)
752
+ target = findOwnedSlotTarget(c);
753
+ if (target)
715
754
  break;
716
755
  }
717
- if (!slot)
718
- slot = findOwnedSlot(root);
756
+ if (!target)
757
+ target = findOwnedSlotTarget(root);
719
758
  }
720
- if (slot) {
721
- slot.__rawHtml = null;
722
- if (!Array.isArray(slot.children))
723
- slot.children = [];
724
- // Append ??multiple projectDefaultSlot calls must accumulate (SSR).
725
- // Client path replaces the live <slot> then appends siblings; serialize must push.
726
- slot.children.push(node);
759
+ if (target) {
760
+ if (target.tag === 'slot') {
761
+ target.__rawHtml = null;
762
+ if (!Array.isArray(target.children))
763
+ target.children = [];
764
+ // Append ??multiple projectDefaultSlot calls must accumulate (SSR).
765
+ // Client path replaces the live <slot> then appends siblings; serialize must push.
766
+ target.children.push(node);
767
+ return;
768
+ }
769
+ if (!Array.isArray(target.children))
770
+ target.children = [];
771
+ target.children.push(node);
727
772
  return;
728
773
  }
729
774
  if (root)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vmz/core",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "VMZ production runtime core — DOM / SSR / HTTP / WriteBarrier (no compiler)",
6
6
  "exports": {
@@ -70,12 +70,12 @@
70
70
  "linkedom": "^0.18.13"
71
71
  },
72
72
  "optionalDependencies": {
73
- "@vmz/vmz-win32-x64": "0.2.1",
74
- "@vmz/vmz-win32-arm64": "0.2.1",
75
- "@vmz/vmz-darwin-x64": "0.2.1",
76
- "@vmz/vmz-darwin-arm64": "0.2.1",
77
- "@vmz/vmz-linux-x64": "0.2.1",
78
- "@vmz/vmz-linux-arm64": "0.2.1"
73
+ "@vmz/vmz-win32-x64": "0.2.3",
74
+ "@vmz/vmz-win32-arm64": "0.2.3",
75
+ "@vmz/vmz-darwin-x64": "0.2.3",
76
+ "@vmz/vmz-darwin-arm64": "0.2.3",
77
+ "@vmz/vmz-linux-x64": "0.2.3",
78
+ "@vmz/vmz-linux-arm64": "0.2.3"
79
79
  },
80
80
  "publishConfig": {
81
81
  "access": "public"