@zeus-js/runtime-dom 0.0.2 → 0.1.0-beta.1

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * runtime-dom v0.0.2
2
+ * runtime-dom v0.1.0-beta.1
3
3
  * (c) 2026 baicie
4
4
  * Released under the MIT License.
5
5
  **/
@@ -8,7 +8,7 @@ Object.defineProperties(exports, {
8
8
  [Symbol.toStringTag]: { value: "Module" }
9
9
  });
10
10
  let _zeus_js_signal = require("@zeus-js/signal");
11
- //#region packages/runtime-dom/src/template.ts
11
+ //#region packages/core/runtime-dom/src/template.ts
12
12
  function template(html, _isImportNode = false, _isSVG = false, _isMathML = false) {
13
13
  const t = document.createElement("template");
14
14
  t.innerHTML = html;
@@ -17,7 +17,7 @@ function template(html, _isImportNode = false, _isSVG = false, _isMathML = false
17
17
  };
18
18
  }
19
19
  //#endregion
20
- //#region packages/runtime-dom/src/hostContext.ts
20
+ //#region packages/core/runtime-dom/src/hostContext.ts
21
21
  let currentHostContext;
22
22
  function getCurrentHostContext() {
23
23
  return currentHostContext;
@@ -41,7 +41,7 @@ function withCapturedHostContext(fn) {
41
41
  });
42
42
  }
43
43
  //#endregion
44
- //#region packages/runtime-dom/src/range.ts
44
+ //#region packages/core/runtime-dom/src/range.ts
45
45
  var DynamicRange = class {
46
46
  constructor(parent, marker) {
47
47
  this.parent = parent;
@@ -63,7 +63,7 @@ var DynamicRange = class {
63
63
  return this.nodes;
64
64
  }
65
65
  };
66
- function insertTracked(parent, value, marker) {
66
+ function insertTracked(parent, value, marker = null) {
67
67
  if (value === void 0 || value == null || value === false || value === true) return [];
68
68
  if (Array.isArray(value)) {
69
69
  const nodes = [];
@@ -80,11 +80,11 @@ function removeNodes$1(nodes) {
80
80
  (_node$parentNode2 = node.parentNode) === null || _node$parentNode2 === void 0 || _node$parentNode2.removeChild(node);
81
81
  }
82
82
  }
83
- function moveRangeBefore(nodes, parent, marker) {
83
+ function moveRangeBefore(nodes, parent, marker = null) {
84
84
  for (const node of nodes) parent.insertBefore(node, marker);
85
85
  }
86
86
  //#endregion
87
- //#region packages/runtime-dom/src/insert.ts
87
+ //#region packages/core/runtime-dom/src/insert.ts
88
88
  function insert(parent, value, marker = null) {
89
89
  if (value === void 0) {
90
90
  console.warn("[Zeus runtime] insert received `undefined`, which is ignored. Use `null` or a fallback value explicitly if you want to suppress this warning.");
@@ -106,7 +106,7 @@ function mountDynamic(parent, marker, value) {
106
106
  }, true);
107
107
  }
108
108
  //#endregion
109
- //#region packages/runtime-dom/src/context.ts
109
+ //#region packages/core/runtime-dom/src/context.ts
110
110
  let currentOwner;
111
111
  function getCurrentOwner() {
112
112
  return currentOwner;
@@ -245,14 +245,14 @@ function resolveValue$3(value) {
245
245
  return typeof value === "function" ? value() : value !== null && value !== void 0 ? value : null;
246
246
  }
247
247
  //#endregion
248
- //#region packages/runtime-dom/src/devtools.ts
248
+ //#region packages/core/runtime-dom/src/devtools.ts
249
249
  function emitDevtoolsEvent(event) {
250
250
  var _window$__ZEUS_DEVTOO;
251
251
  if (typeof window === "undefined") return;
252
252
  (_window$__ZEUS_DEVTOO = window.__ZEUS_DEVTOOLS_HOOK__) === null || _window$__ZEUS_DEVTOO === void 0 || _window$__ZEUS_DEVTOO.emit(event);
253
253
  }
254
254
  //#endregion
255
- //#region packages/runtime-dom/src/render.ts
255
+ //#region packages/core/runtime-dom/src/render.ts
256
256
  function render(value, container, options = {}) {
257
257
  var _options$owner;
258
258
  const renderScope = (0, _zeus_js_signal.scope)();
@@ -279,7 +279,7 @@ function resolveValue$2(value) {
279
279
  return typeof value === "function" ? value() : value !== null && value !== void 0 ? value : null;
280
280
  }
281
281
  //#endregion
282
- //#region packages/runtime-dom/src/dom.ts
282
+ //#region packages/core/runtime-dom/src/dom.ts
283
283
  function marker(parent, index) {
284
284
  let seen = 0;
285
285
  for (const node of parent.childNodes) {
@@ -303,7 +303,7 @@ function removeNodes(nodes) {
303
303
  }
304
304
  }
305
305
  //#endregion
306
- //#region packages/runtime-dom/src/bindings.ts
306
+ //#region packages/core/runtime-dom/src/bindings.ts
307
307
  function bindText(node, value) {
308
308
  (0, _zeus_js_signal.effect)(() => {
309
309
  node.data = stringifyText(value());
@@ -324,17 +324,43 @@ function stringifyText(value) {
324
324
  return String(value);
325
325
  }
326
326
  function setAttr(el, name, value) {
327
+ const attrName = normalizeAttrName(name);
328
+ const propName = getBooleanDomPropertyName(name);
329
+ if (propName && el instanceof HTMLElement) {
330
+ el[propName] = Boolean(value);
331
+ if (value == null || value === false) el.removeAttribute(attrName);
332
+ else if (value === true) el.setAttribute(attrName, "");
333
+ else el.setAttribute(attrName, String(value));
334
+ return;
335
+ }
327
336
  if (value == null || value === false) {
328
- el.removeAttribute(normalizeAttrName(name));
337
+ el.removeAttribute(attrName);
329
338
  return;
330
339
  }
331
- const attrName = normalizeAttrName(name);
332
340
  if (value === true) {
333
341
  el.setAttribute(attrName, "");
334
342
  return;
335
343
  }
336
344
  el.setAttribute(attrName, String(value));
337
345
  }
346
+ function getBooleanDomPropertyName(name) {
347
+ return BOOLEAN_DOM_PROPERTY_NAME[name];
348
+ }
349
+ const BOOLEAN_DOM_PROPERTY_NAME = {
350
+ hidden: "hidden",
351
+ disabled: "disabled",
352
+ readonly: "readOnly",
353
+ readOnly: "readOnly",
354
+ multiple: "multiple",
355
+ selected: "selected",
356
+ checked: "checked",
357
+ open: "open",
358
+ autofocus: "autofocus",
359
+ autoFocus: "autofocus",
360
+ indeterminate: "indeterminate",
361
+ noValidate: "noValidate",
362
+ novalidate: "noValidate"
363
+ };
338
364
  function normalizeAttrName(name) {
339
365
  return name === "className" ? "class" : name;
340
366
  }
@@ -413,7 +439,7 @@ function toKebabCase$1(value) {
413
439
  return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
414
440
  }
415
441
  //#endregion
416
- //#region packages/runtime-dom/src/events.ts
442
+ //#region packages/core/runtime-dom/src/events.ts
417
443
  const delegatedEvents = /* @__PURE__ */ new Set();
418
444
  const delegatedListeners = [];
419
445
  const nonBubblingEventMap = {
@@ -488,7 +514,7 @@ function callDelegatedHandler(el, handler, event) {
488
514
  }
489
515
  }
490
516
  //#endregion
491
- //#region packages/runtime-dom/src/refs.ts
517
+ //#region packages/core/runtime-dom/src/refs.ts
492
518
  function setRef(target, value) {
493
519
  if (target == null) return;
494
520
  if (typeof target === "function") {
@@ -512,12 +538,12 @@ function bindRef(el, target) {
512
538
  }, true);
513
539
  }
514
540
  //#endregion
515
- //#region packages/runtime-dom/src/component.ts
541
+ //#region packages/core/runtime-dom/src/component.ts
516
542
  function createComponent(component, props) {
517
543
  return runWithOwner(createOwner(), () => component(props));
518
544
  }
519
545
  //#endregion
520
- //#region packages/runtime-dom/src/list.ts
546
+ //#region packages/core/runtime-dom/src/list.ts
521
547
  function mountFor$1(parent, marker, each, key, render) {
522
548
  if (!key) {
523
549
  mountIndexFor(parent, marker, each, render);
@@ -575,7 +601,7 @@ function mountKeyedFor(parent, marker, each, key, render) {
575
601
  }
576
602
  emitDevtoolsEvent({
577
603
  type: "mount-for",
578
- length: records.length
604
+ length: nextRecords.length
579
605
  });
580
606
  records = nextRecords;
581
607
  });
@@ -586,7 +612,7 @@ function mountKeyedFor(parent, marker, each, key, render) {
586
612
  }, true);
587
613
  }
588
614
  //#endregion
589
- //#region packages/runtime-dom/src/controlFlow.ts
615
+ //#region packages/core/runtime-dom/src/controlFlow.ts
590
616
  function Show(props) {
591
617
  return resolveValue(props.when ? props.children : props.fallback);
592
618
  }
@@ -605,7 +631,43 @@ function mountFor(parent, marker, each, key, render) {
605
631
  mountFor$1(parent, marker, each, key, render);
606
632
  }
607
633
  //#endregion
608
- //#region packages/runtime-dom/src/defineElement.ts
634
+ //#region packages/core/runtime-dom/src/defineElement.ts
635
+ function createPropStore(defs) {
636
+ const slots = /* @__PURE__ */ new Map();
637
+ const props = {};
638
+ for (const def of defs) {
639
+ const slot = (0, _zeus_js_signal.state)();
640
+ slots.set(def.key, slot);
641
+ Object.defineProperty(props, def.key, {
642
+ configurable: false,
643
+ enumerable: true,
644
+ get() {
645
+ return slot.value;
646
+ },
647
+ set(value) {
648
+ slot.value = value;
649
+ }
650
+ });
651
+ }
652
+ return {
653
+ props,
654
+ get(key) {
655
+ var _slots$get;
656
+ return (_slots$get = slots.get(key)) === null || _slots$get === void 0 ? void 0 : _slots$get.value;
657
+ },
658
+ set(key, value) {
659
+ const slot = slots.get(key);
660
+ if (!slot) {
661
+ console.warn(`[Zeus custom-element] Unknown prop "${key}" was written.`);
662
+ return;
663
+ }
664
+ slot.value = value;
665
+ },
666
+ has(key) {
667
+ return slots.has(key);
668
+ }
669
+ };
670
+ }
609
671
  function defineElement(tagName, options, setup) {
610
672
  var _options$props;
611
673
  const propDefs = normalizePropDefinitions((_options$props = options.props) !== null && _options$props !== void 0 ? _options$props : {});
@@ -616,12 +678,13 @@ function defineElement(tagName, options, setup) {
616
678
  }
617
679
  constructor() {
618
680
  super();
619
- this.props = (0, _zeus_js_signal.state)({});
620
681
  this.lightChildren = [];
621
682
  this.capturedLightChildren = false;
622
683
  this.reflecting = false;
623
- applyPropDefaults(this.props, propDefs);
624
- definePropAccessors(this, this.props, propDefs);
684
+ this.propStore = createPropStore(propDefs);
685
+ this.props = this.propStore.props;
686
+ applyPropDefaults(this.propStore, propDefs);
687
+ definePropAccessors(this, this.propStore, propDefs);
625
688
  }
626
689
  connectedCallback() {
627
690
  var _options$shadow, _options$consumes;
@@ -659,22 +722,17 @@ function defineElement(tagName, options, setup) {
659
722
  };
660
723
  this.dispose = render(() => runWithOwner(owner, () => withHostContext(hostContext, () => setup(this.props, setupContext))), target, { owner });
661
724
  mountStyles(target, options.styles);
662
- (0, _zeus_js_signal.onScopeDispose)(() => {
663
- var _this$dispose;
664
- (_this$dispose = this.dispose) === null || _this$dispose === void 0 || _this$dispose.call(this);
665
- this.dispose = void 0;
666
- }, true);
667
725
  }
668
726
  disconnectedCallback() {
669
- var _this$dispose2;
670
- (_this$dispose2 = this.dispose) === null || _this$dispose2 === void 0 || _this$dispose2.call(this);
727
+ var _this$dispose;
728
+ (_this$dispose = this.dispose) === null || _this$dispose === void 0 || _this$dispose.call(this);
671
729
  this.dispose = void 0;
672
730
  }
673
731
  attributeChangedCallback(name, oldValue, newValue) {
674
732
  if (oldValue === newValue || this.reflecting) return;
675
733
  const def = propDefs.find((item) => item.attr === name);
676
734
  if (!def) return;
677
- this.props[def.key] = castAttributeValue(newValue, def);
735
+ this.propStore.set(def.key, castAttributeValue(newValue, def));
678
736
  }
679
737
  resolveRenderTarget(shadow) {
680
738
  if (this.target) return this.target;
@@ -689,12 +747,12 @@ function defineElement(tagName, options, setup) {
689
747
  for (const def of defs) {
690
748
  if (def.attr === false) continue;
691
749
  const value = this.getAttribute(def.attr);
692
- if (value !== null || def.type === Boolean) this.props[def.key] = castAttributeValue(value, def);
750
+ if (value !== null || def.type === Boolean) this.propStore.set(def.key, castAttributeValue(value, def));
693
751
  }
694
752
  }
695
753
  _writePropFromProperty(key, value) {
696
754
  const def = propDefs.find((item) => item.key === key);
697
- this.props[key] = value;
755
+ this.propStore.set(key, value);
698
756
  if ((def === null || def === void 0 ? void 0 : def.reflect) && def.attr !== false) {
699
757
  this.reflecting = true;
700
758
  try {
@@ -726,26 +784,35 @@ function normalizePropDefinitions(props) {
726
784
  };
727
785
  });
728
786
  }
729
- function applyPropDefaults(props, defs) {
787
+ function applyPropDefaults(store, defs) {
730
788
  for (const def of defs) {
731
789
  if (!("default" in def)) continue;
732
790
  const value = typeof def.default === "function" ? def.default() : def.default;
733
- props[def.key] = value;
791
+ store.set(def.key, value);
734
792
  }
735
793
  }
736
- function definePropAccessors(element, props, defs) {
794
+ function definePropAccessors(element, store, defs) {
737
795
  for (const def of defs) {
738
- if (def.key in element) continue;
739
- Object.defineProperty(element, def.key, {
796
+ const key = def.key;
797
+ const hadOwnValue = Object.prototype.hasOwnProperty.call(element, key);
798
+ const ownValue = hadOwnValue ? element[key] : void 0;
799
+ if (hadOwnValue) delete element[key];
800
+ const existing = Object.getOwnPropertyDescriptor(element, key);
801
+ if (existing && existing.configurable === false) {
802
+ console.warn(`[Zeus custom-element] Cannot define prop "${key}" because an own non-configurable property already exists.`);
803
+ continue;
804
+ }
805
+ Object.defineProperty(element, key, {
740
806
  configurable: true,
741
807
  enumerable: true,
742
808
  get() {
743
- return props[def.key];
809
+ return store.get(key);
744
810
  },
745
811
  set(value) {
746
- element._writePropFromProperty(def.key, value);
812
+ element._writePropFromProperty(key, value);
747
813
  }
748
814
  });
815
+ if (hadOwnValue) element._writePropFromProperty(key, ownValue);
749
816
  }
750
817
  }
751
818
  function castAttributeValue(value, def) {
@@ -790,7 +857,7 @@ function toKebabCase(value) {
790
857
  return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
791
858
  }
792
859
  //#endregion
793
- //#region packages/runtime-dom/src/slot.ts
860
+ //#region packages/core/runtime-dom/src/slot.ts
794
861
  function createSlot(name, fallback) {
795
862
  const context = getCurrentHostContext();
796
863
  if (!context) return createNativeSlot(name, fallback);
@@ -822,16 +889,96 @@ function isMeaningfulTextNode(node) {
822
889
  return Boolean((_node$textContent = node.textContent) === null || _node$textContent === void 0 ? void 0 : _node$textContent.trim());
823
890
  }
824
891
  //#endregion
825
- //#region packages/runtime-dom/src/webComponents.ts
892
+ //#region packages/core/runtime-dom/src/webComponents.ts
893
+ const HOST_RESERVED_KEYS = new Set([
894
+ "children",
895
+ "ref",
896
+ "class",
897
+ "className",
898
+ "style",
899
+ "_elements"
900
+ ]);
826
901
  function Host(props) {
902
+ const context = getCurrentHostContext();
903
+ if (context) bindHostProps(context.host, props);
827
904
  return resolveValue$1(props.children);
828
905
  }
829
906
  function Slot(props) {
830
907
  return createSlot(props.name, () => resolveValue$1(props.children));
831
908
  }
909
+ function bindHostProps(host, props) {
910
+ bindHostRef(host, props);
911
+ bindHostClass(host, props);
912
+ bindHostStyle(host, props);
913
+ bindHostAttributes(host, props);
914
+ if ("_elements" in props) bindHostElementBindings(host, props);
915
+ }
916
+ function bindHostRef(host, props) {
917
+ if (!("ref" in props)) return;
918
+ bindRef(host, props.ref);
919
+ }
920
+ function bindHostClass(host, props) {
921
+ if (!("class" in props) && !("className" in props)) return;
922
+ const value = props.className !== void 0 ? props.className : props.class;
923
+ bindClass(host, () => {
924
+ return resolveHostValue(value);
925
+ });
926
+ }
927
+ function bindHostStyle(host, props) {
928
+ if (!("style" in props)) return;
929
+ bindStyle(host, () => {
930
+ return resolveHostValue(props.style);
931
+ });
932
+ }
933
+ function bindHostAttributes(host, props) {
934
+ for (const key of Object.keys(props)) {
935
+ if (HOST_RESERVED_KEYS.has(key)) continue;
936
+ if (isEventLikeProp(key)) continue;
937
+ const value = props[key];
938
+ bindAttr(host, normalizeHostAttrName(key), () => {
939
+ return resolveHostValue(value);
940
+ });
941
+ }
942
+ }
943
+ function bindHostElementBindings(host, props) {
944
+ const elements = props._elements;
945
+ for (const _key of Object.keys(elements)) {
946
+ const getEl = elements[_key];
947
+ const el = getEl();
948
+ if (!el) continue;
949
+ for (const attrKey of Object.keys(props)) {
950
+ if (HOST_RESERVED_KEYS.has(attrKey)) continue;
951
+ if (isEventLikeProp(attrKey)) continue;
952
+ const value = props[attrKey];
953
+ bindAttr(el, normalizeHostAttrName(attrKey), () => {
954
+ return resolveHostValue(value);
955
+ });
956
+ }
957
+ }
958
+ }
959
+ function resolveHostValue(value) {
960
+ if (typeof value === "function") return value();
961
+ return value;
962
+ }
832
963
  function resolveValue$1(value) {
833
964
  return typeof value === "function" ? value() : value;
834
965
  }
966
+ function isEventLikeProp(key) {
967
+ /**
968
+ * Host Phase 1 does not bind event listeners.
969
+ * Keep event handling inside component template + emit().
970
+ */
971
+ return /^on[A-Z]/.test(key) || key.startsWith("on:");
972
+ }
973
+ function normalizeHostAttrName(name) {
974
+ switch (name) {
975
+ case "className": return "class";
976
+ case "htmlFor": return "for";
977
+ case "tabIndex": return "tabindex";
978
+ case "readOnly": return "readonly";
979
+ default: return name;
980
+ }
981
+ }
835
982
  //#endregion
836
983
  exports.For = For;
837
984
  exports.Host = Host;
@@ -859,6 +1006,7 @@ exports.getCurrentHostContext = getCurrentHostContext;
859
1006
  exports.getCurrentOwner = getCurrentOwner;
860
1007
  exports.inject = inject;
861
1008
  exports.insert = insert;
1009
+ exports.insertTracked = insertTracked;
862
1010
  exports.marker = marker;
863
1011
  exports.mountDynamic = mountDynamic;
864
1012
  exports.mountFor = mountFor;