@pyreon/runtime-dom 0.5.4 → 0.5.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.
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"bebce038-1","name":"delegate.ts"},{"uid":"bebce038-3","name":"hydration-debug.ts"},{"uid":"bebce038-5","name":"devtools.ts"},{"uid":"bebce038-7","name":"nodes.ts"},{"uid":"bebce038-9","name":"props.ts"},{"uid":"bebce038-11","name":"mount.ts"},{"uid":"bebce038-13","name":"hydrate.ts"},{"uid":"bebce038-15","name":"keep-alive.ts"},{"uid":"bebce038-17","name":"template.ts"},{"uid":"bebce038-19","name":"transition.ts"},{"uid":"bebce038-21","name":"transition-group.ts"},{"uid":"bebce038-23","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"bebce038-1":{"renderedLength":1968,"gzipLength":967,"brotliLength":0,"metaUid":"bebce038-0"},"bebce038-3":{"renderedLength":704,"gzipLength":397,"brotliLength":0,"metaUid":"bebce038-2"},"bebce038-5":{"renderedLength":6803,"gzipLength":2095,"brotliLength":0,"metaUid":"bebce038-4"},"bebce038-7":{"renderedLength":16149,"gzipLength":4315,"brotliLength":0,"metaUid":"bebce038-6"},"bebce038-9":{"renderedLength":5779,"gzipLength":2234,"brotliLength":0,"metaUid":"bebce038-8"},"bebce038-11":{"renderedLength":7951,"gzipLength":2338,"brotliLength":0,"metaUid":"bebce038-10"},"bebce038-13":{"renderedLength":7652,"gzipLength":2325,"brotliLength":0,"metaUid":"bebce038-12"},"bebce038-15":{"renderedLength":1447,"gzipLength":692,"brotliLength":0,"metaUid":"bebce038-14"},"bebce038-17":{"renderedLength":4250,"gzipLength":1760,"brotliLength":0,"metaUid":"bebce038-16"},"bebce038-19":{"renderedLength":4007,"gzipLength":1316,"brotliLength":0,"metaUid":"bebce038-18"},"bebce038-21":{"renderedLength":6362,"gzipLength":1937,"brotliLength":0,"metaUid":"bebce038-20"},"bebce038-23":{"renderedLength":811,"gzipLength":491,"brotliLength":0,"metaUid":"bebce038-22"}},"nodeMetas":{"bebce038-0":{"id":"/src/delegate.ts","moduleParts":{"index.js":"bebce038-1"},"imported":[{"uid":"bebce038-24"}],"importedBy":[{"uid":"bebce038-22"},{"uid":"bebce038-12"},{"uid":"bebce038-8"}]},"bebce038-2":{"id":"/src/hydration-debug.ts","moduleParts":{"index.js":"bebce038-3"},"imported":[],"importedBy":[{"uid":"bebce038-22"},{"uid":"bebce038-12"}]},"bebce038-4":{"id":"/src/devtools.ts","moduleParts":{"index.js":"bebce038-5"},"imported":[],"importedBy":[{"uid":"bebce038-22"},{"uid":"bebce038-10"}]},"bebce038-6":{"id":"/src/nodes.ts","moduleParts":{"index.js":"bebce038-7"},"imported":[{"uid":"bebce038-24"}],"importedBy":[{"uid":"bebce038-12"},{"uid":"bebce038-10"}]},"bebce038-8":{"id":"/src/props.ts","moduleParts":{"index.js":"bebce038-9"},"imported":[{"uid":"bebce038-24"},{"uid":"bebce038-0"}],"importedBy":[{"uid":"bebce038-22"},{"uid":"bebce038-12"},{"uid":"bebce038-10"}]},"bebce038-10":{"id":"/src/mount.ts","moduleParts":{"index.js":"bebce038-11"},"imported":[{"uid":"bebce038-25"},{"uid":"bebce038-24"},{"uid":"bebce038-4"},{"uid":"bebce038-6"},{"uid":"bebce038-8"}],"importedBy":[{"uid":"bebce038-22"},{"uid":"bebce038-12"},{"uid":"bebce038-14"},{"uid":"bebce038-20"}]},"bebce038-12":{"id":"/src/hydrate.ts","moduleParts":{"index.js":"bebce038-13"},"imported":[{"uid":"bebce038-25"},{"uid":"bebce038-24"},{"uid":"bebce038-0"},{"uid":"bebce038-2"},{"uid":"bebce038-10"},{"uid":"bebce038-6"},{"uid":"bebce038-8"}],"importedBy":[{"uid":"bebce038-22"}]},"bebce038-14":{"id":"/src/keep-alive.ts","moduleParts":{"index.js":"bebce038-15"},"imported":[{"uid":"bebce038-25"},{"uid":"bebce038-24"},{"uid":"bebce038-10"}],"importedBy":[{"uid":"bebce038-22"}]},"bebce038-16":{"id":"/src/template.ts","moduleParts":{"index.js":"bebce038-17"},"imported":[],"importedBy":[{"uid":"bebce038-22"}]},"bebce038-18":{"id":"/src/transition.ts","moduleParts":{"index.js":"bebce038-19"},"imported":[{"uid":"bebce038-25"},{"uid":"bebce038-24"}],"importedBy":[{"uid":"bebce038-22"}]},"bebce038-20":{"id":"/src/transition-group.ts","moduleParts":{"index.js":"bebce038-21"},"imported":[{"uid":"bebce038-25"},{"uid":"bebce038-24"},{"uid":"bebce038-10"}],"importedBy":[{"uid":"bebce038-22"}]},"bebce038-22":{"id":"/src/index.ts","moduleParts":{"index.js":"bebce038-23"},"imported":[{"uid":"bebce038-0"},{"uid":"bebce038-12"},{"uid":"bebce038-2"},{"uid":"bebce038-14"},{"uid":"bebce038-10"},{"uid":"bebce038-8"},{"uid":"bebce038-16"},{"uid":"bebce038-18"},{"uid":"bebce038-20"},{"uid":"bebce038-4"}],"importedBy":[],"isEntry":true},"bebce038-24":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"bebce038-0"},{"uid":"bebce038-12"},{"uid":"bebce038-14"},{"uid":"bebce038-10"},{"uid":"bebce038-8"},{"uid":"bebce038-18"},{"uid":"bebce038-20"},{"uid":"bebce038-6"}]},"bebce038-25":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"bebce038-12"},{"uid":"bebce038-14"},{"uid":"bebce038-10"},{"uid":"bebce038-18"},{"uid":"bebce038-20"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"b1c3db5e-1","name":"delegate.ts"},{"uid":"b1c3db5e-3","name":"hydration-debug.ts"},{"uid":"b1c3db5e-5","name":"devtools.ts"},{"uid":"b1c3db5e-7","name":"nodes.ts"},{"uid":"b1c3db5e-9","name":"props.ts"},{"uid":"b1c3db5e-11","name":"mount.ts"},{"uid":"b1c3db5e-13","name":"hydrate.ts"},{"uid":"b1c3db5e-15","name":"keep-alive.ts"},{"uid":"b1c3db5e-17","name":"template.ts"},{"uid":"b1c3db5e-19","name":"transition.ts"},{"uid":"b1c3db5e-21","name":"transition-group.ts"},{"uid":"b1c3db5e-23","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"b1c3db5e-1":{"renderedLength":1968,"gzipLength":967,"brotliLength":0,"metaUid":"b1c3db5e-0"},"b1c3db5e-3":{"renderedLength":704,"gzipLength":397,"brotliLength":0,"metaUid":"b1c3db5e-2"},"b1c3db5e-5":{"renderedLength":6803,"gzipLength":2095,"brotliLength":0,"metaUid":"b1c3db5e-4"},"b1c3db5e-7":{"renderedLength":16273,"gzipLength":4364,"brotliLength":0,"metaUid":"b1c3db5e-6"},"b1c3db5e-9":{"renderedLength":6361,"gzipLength":2445,"brotliLength":0,"metaUid":"b1c3db5e-8"},"b1c3db5e-11":{"renderedLength":8893,"gzipLength":2712,"brotliLength":0,"metaUid":"b1c3db5e-10"},"b1c3db5e-13":{"renderedLength":7652,"gzipLength":2325,"brotliLength":0,"metaUid":"b1c3db5e-12"},"b1c3db5e-15":{"renderedLength":1447,"gzipLength":692,"brotliLength":0,"metaUid":"b1c3db5e-14"},"b1c3db5e-17":{"renderedLength":4250,"gzipLength":1760,"brotliLength":0,"metaUid":"b1c3db5e-16"},"b1c3db5e-19":{"renderedLength":4007,"gzipLength":1316,"brotliLength":0,"metaUid":"b1c3db5e-18"},"b1c3db5e-21":{"renderedLength":6362,"gzipLength":1937,"brotliLength":0,"metaUid":"b1c3db5e-20"},"b1c3db5e-23":{"renderedLength":811,"gzipLength":491,"brotliLength":0,"metaUid":"b1c3db5e-22"}},"nodeMetas":{"b1c3db5e-0":{"id":"/src/delegate.ts","moduleParts":{"index.js":"b1c3db5e-1"},"imported":[{"uid":"b1c3db5e-24"}],"importedBy":[{"uid":"b1c3db5e-22"},{"uid":"b1c3db5e-12"},{"uid":"b1c3db5e-8"}]},"b1c3db5e-2":{"id":"/src/hydration-debug.ts","moduleParts":{"index.js":"b1c3db5e-3"},"imported":[],"importedBy":[{"uid":"b1c3db5e-22"},{"uid":"b1c3db5e-12"}]},"b1c3db5e-4":{"id":"/src/devtools.ts","moduleParts":{"index.js":"b1c3db5e-5"},"imported":[],"importedBy":[{"uid":"b1c3db5e-22"},{"uid":"b1c3db5e-10"}]},"b1c3db5e-6":{"id":"/src/nodes.ts","moduleParts":{"index.js":"b1c3db5e-7"},"imported":[{"uid":"b1c3db5e-24"}],"importedBy":[{"uid":"b1c3db5e-12"},{"uid":"b1c3db5e-10"}]},"b1c3db5e-8":{"id":"/src/props.ts","moduleParts":{"index.js":"b1c3db5e-9"},"imported":[{"uid":"b1c3db5e-25"},{"uid":"b1c3db5e-24"},{"uid":"b1c3db5e-0"}],"importedBy":[{"uid":"b1c3db5e-22"},{"uid":"b1c3db5e-12"},{"uid":"b1c3db5e-10"}]},"b1c3db5e-10":{"id":"/src/mount.ts","moduleParts":{"index.js":"b1c3db5e-11"},"imported":[{"uid":"b1c3db5e-25"},{"uid":"b1c3db5e-24"},{"uid":"b1c3db5e-4"},{"uid":"b1c3db5e-6"},{"uid":"b1c3db5e-8"}],"importedBy":[{"uid":"b1c3db5e-22"},{"uid":"b1c3db5e-12"},{"uid":"b1c3db5e-14"},{"uid":"b1c3db5e-20"}]},"b1c3db5e-12":{"id":"/src/hydrate.ts","moduleParts":{"index.js":"b1c3db5e-13"},"imported":[{"uid":"b1c3db5e-25"},{"uid":"b1c3db5e-24"},{"uid":"b1c3db5e-0"},{"uid":"b1c3db5e-2"},{"uid":"b1c3db5e-10"},{"uid":"b1c3db5e-6"},{"uid":"b1c3db5e-8"}],"importedBy":[{"uid":"b1c3db5e-22"}]},"b1c3db5e-14":{"id":"/src/keep-alive.ts","moduleParts":{"index.js":"b1c3db5e-15"},"imported":[{"uid":"b1c3db5e-25"},{"uid":"b1c3db5e-24"},{"uid":"b1c3db5e-10"}],"importedBy":[{"uid":"b1c3db5e-22"}]},"b1c3db5e-16":{"id":"/src/template.ts","moduleParts":{"index.js":"b1c3db5e-17"},"imported":[],"importedBy":[{"uid":"b1c3db5e-22"}]},"b1c3db5e-18":{"id":"/src/transition.ts","moduleParts":{"index.js":"b1c3db5e-19"},"imported":[{"uid":"b1c3db5e-25"},{"uid":"b1c3db5e-24"}],"importedBy":[{"uid":"b1c3db5e-22"}]},"b1c3db5e-20":{"id":"/src/transition-group.ts","moduleParts":{"index.js":"b1c3db5e-21"},"imported":[{"uid":"b1c3db5e-25"},{"uid":"b1c3db5e-24"},{"uid":"b1c3db5e-10"}],"importedBy":[{"uid":"b1c3db5e-22"}]},"b1c3db5e-22":{"id":"/src/index.ts","moduleParts":{"index.js":"b1c3db5e-23"},"imported":[{"uid":"b1c3db5e-0"},{"uid":"b1c3db5e-12"},{"uid":"b1c3db5e-2"},{"uid":"b1c3db5e-14"},{"uid":"b1c3db5e-10"},{"uid":"b1c3db5e-8"},{"uid":"b1c3db5e-16"},{"uid":"b1c3db5e-18"},{"uid":"b1c3db5e-20"},{"uid":"b1c3db5e-4"}],"importedBy":[],"isEntry":true},"b1c3db5e-24":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"b1c3db5e-0"},{"uid":"b1c3db5e-12"},{"uid":"b1c3db5e-14"},{"uid":"b1c3db5e-10"},{"uid":"b1c3db5e-8"},{"uid":"b1c3db5e-18"},{"uid":"b1c3db5e-20"},{"uid":"b1c3db5e-6"}]},"b1c3db5e-25":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"b1c3db5e-12"},{"uid":"b1c3db5e-14"},{"uid":"b1c3db5e-10"},{"uid":"b1c3db5e-8"},{"uid":"b1c3db5e-18"},{"uid":"b1c3db5e-20"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;
package/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { batch, effect, effectScope, renderEffect, runUntracked, setCurrentScope, signal } from "@pyreon/reactivity";
2
- import { EMPTY_PROPS, ForSymbol, Fragment, PortalSymbol, createRef, dispatchToErrorBoundary, h, onMount, onUnmount, propagateError, reportError, runWithHooks } from "@pyreon/core";
2
+ import { EMPTY_PROPS, ForSymbol, Fragment, PortalSymbol, createRef, dispatchToErrorBoundary, h, normalizeStyleValue, onMount, onUnmount, propagateError, reportError, runWithHooks, toKebabCase } from "@pyreon/core";
3
3
 
4
4
  //#region src/delegate.ts
5
5
  /**
@@ -584,8 +584,9 @@ function mountFor(source, getKey, renderItem, parent, anchor, mountChild) {
584
584
  pred: new Int32Array(16),
585
585
  stay: new Uint8Array(16)
586
586
  };
587
- const warnDuplicateKeys = (seen, key) => {
587
+ const warnForKey = (seen, key) => {
588
588
  if (!__DEV__$4 || !seen) return;
589
+ if (key == null) console.warn("[Pyreon] <For> `by` function returned null/undefined. Keys must be strings or numbers. Check your `by` prop.");
589
590
  if (seen.has(key)) console.warn(`[Pyreon] Duplicate key "${String(key)}" in <For> list. Keys must be unique.`);
590
591
  seen.add(key);
591
592
  };
@@ -628,7 +629,7 @@ function mountFor(source, getKey, renderItem, parent, anchor, mountChild) {
628
629
  for (let i = 0; i < n; i++) {
629
630
  const item = items[i];
630
631
  const key = getKey(item);
631
- warnDuplicateKeys(_seenKeys, key);
632
+ warnForKey(_seenKeys, key);
632
633
  keys[i] = key;
633
634
  renderInto(item, key, i, frag, null);
634
635
  }
@@ -641,7 +642,7 @@ function mountFor(source, getKey, renderItem, parent, anchor, mountChild) {
641
642
  const _seenUpdate = __DEV__$4 ? /* @__PURE__ */ new Set() : null;
642
643
  for (let i = 0; i < n; i++) {
643
644
  newKeys[i] = getKey(items[i]);
644
- warnDuplicateKeys(_seenUpdate, newKeys[i]);
645
+ warnForKey(_seenUpdate, newKeys[i]);
645
646
  }
646
647
  return newKeys;
647
648
  };
@@ -947,20 +948,19 @@ const EVENT_RE = /^on[A-Z]/;
947
948
  * Uses for-in instead of Object.keys() to avoid allocating a keys array.
948
949
  */
949
950
  function applyProps(el, props) {
950
- let cleanup = null;
951
+ let first = null;
952
+ let cleanups = null;
951
953
  for (const key in props) {
952
954
  if (key === "key" || key === "ref") continue;
953
955
  const c = applyProp(el, key, props[key]);
954
- if (c) if (!cleanup) cleanup = c;
955
- else {
956
- const prev = cleanup;
957
- cleanup = () => {
958
- prev();
959
- c();
960
- };
961
- }
956
+ if (c) if (!first) first = c;
957
+ else if (!cleanups) cleanups = [first, c];
958
+ else cleanups.push(c);
962
959
  }
963
- return cleanup;
960
+ if (cleanups) return () => {
961
+ for (const c of cleanups) c();
962
+ };
963
+ return first;
964
964
  }
965
965
  /**
966
966
  * Apply a single prop.
@@ -969,21 +969,29 @@ function applyProps(el, props) {
969
969
  * - `() => value` (non-event function) → reactive via effect
970
970
  * - anything else → static attribute / DOM property
971
971
  */
972
- function applyProp(el, key, value) {
973
- if (EVENT_RE.test(key)) {
974
- const eventName = key[2]?.toLowerCase() + key.slice(3);
975
- const handler = value;
976
- if (DELEGATED_EVENTS.has(eventName)) {
977
- const prop = delegatedPropName(eventName);
978
- el[prop] = (e) => batch(() => handler(e));
979
- return () => {
980
- el[prop] = void 0;
981
- };
982
- }
983
- const batched = (e) => batch(() => handler(e));
984
- el.addEventListener(eventName, batched);
985
- return () => el.removeEventListener(eventName, batched);
972
+ /**
973
+ * Bind an event handler (onClick → "click") with batching + delegation support.
974
+ */
975
+ function applyEventProp(el, key, value) {
976
+ if (__DEV__$3 && typeof value !== "function") {
977
+ console.warn(`[Pyreon] Event handler "${key}" received a non-function value (${typeof value}). Expected a function. Did you mean ${key}={() => ...}?`);
978
+ return null;
979
+ }
980
+ const eventName = key[2]?.toLowerCase() + key.slice(3);
981
+ const handler = value;
982
+ if (DELEGATED_EVENTS.has(eventName)) {
983
+ const prop = delegatedPropName(eventName);
984
+ el[prop] = (e) => batch(() => handler(e));
985
+ return () => {
986
+ el[prop] = void 0;
987
+ };
986
988
  }
989
+ const batched = (e) => batch(() => handler(e));
990
+ el.addEventListener(eventName, batched);
991
+ return () => el.removeEventListener(eventName, batched);
992
+ }
993
+ function applyProp(el, key, value) {
994
+ if (EVENT_RE.test(key)) return applyEventProp(el, key, value);
987
995
  if (key === "innerHTML") {
988
996
  if (typeof el.setHTML === "function") el.setHTML(value);
989
997
  else el.innerHTML = sanitizeHtml(value);
@@ -1023,7 +1031,13 @@ const UNSAFE_URL_RE = /^\s*(?:javascript|data):/i;
1023
1031
  /** Apply a style prop (string or object). */
1024
1032
  function applyStyleProp(el, value) {
1025
1033
  if (typeof value === "string") el.style.cssText = value;
1026
- else if (value != null && typeof value === "object") Object.assign(el.style, value);
1034
+ else if (value != null && typeof value === "object") {
1035
+ const obj = value;
1036
+ for (const k in obj) {
1037
+ const css = normalizeStyleValue(k, obj[k]);
1038
+ el.style.setProperty(k.startsWith("--") ? k : toKebabCase(k), css);
1039
+ }
1040
+ }
1027
1041
  }
1028
1042
  function setStaticProp(el, key, value) {
1029
1043
  if (URL_ATTRS.has(key) && typeof value === "string" && UNSAFE_URL_RE.test(value)) {
@@ -1132,14 +1146,35 @@ function mountChild(child, parent, anchor = null) {
1132
1146
  }
1133
1147
  if (vnode.type === PortalSymbol) {
1134
1148
  const { target, children } = vnode.props;
1135
- if (__DEV__$2 && !target) return noop$1;
1149
+ if (__DEV__$2 && !target) {
1150
+ console.warn("[Pyreon] <Portal> received a falsy `target`. Provide a valid DOM element.");
1151
+ return noop$1;
1152
+ }
1153
+ if (__DEV__$2 && !(target instanceof Node)) console.warn(`[Pyreon] <Portal> target must be a DOM node. Received ${typeof target}. Use document.getElementById() or a ref to get the target element.`);
1136
1154
  return mountChild(children, target, null);
1137
1155
  }
1138
1156
  if (typeof vnode.type === "function") return mountComponent(vnode, parent, anchor);
1139
1157
  return mountElement(vnode, parent, anchor);
1140
1158
  }
1159
+ const VOID_ELEMENTS = new Set([
1160
+ "area",
1161
+ "base",
1162
+ "br",
1163
+ "col",
1164
+ "embed",
1165
+ "hr",
1166
+ "img",
1167
+ "input",
1168
+ "link",
1169
+ "meta",
1170
+ "param",
1171
+ "source",
1172
+ "track",
1173
+ "wbr"
1174
+ ]);
1141
1175
  function mountElement(vnode, parent, anchor) {
1142
1176
  const el = document.createElement(vnode.type);
1177
+ if (__DEV__$2 && vnode.children.length > 0 && VOID_ELEMENTS.has(vnode.type)) console.warn(`[Pyreon] <${vnode.type}> is a void element and cannot have children. Children passed to void elements will be ignored by the browser.`);
1143
1178
  const props = vnode.props;
1144
1179
  const propCleanup = props !== EMPTY_PROPS ? applyProps(el, props) : null;
1145
1180
  _elementDepth++;
@@ -1210,7 +1245,10 @@ function mountComponent(vnode, parent, anchor) {
1210
1245
  } finally {
1211
1246
  setCurrentScope(null);
1212
1247
  }
1213
- if (__DEV__$2 && output != null && typeof output === "object" && !("type" in output)) console.warn(`[Pyreon] Component <${componentName}> returned an invalid value. Components must return a VNode, string, null, or function.`);
1248
+ if (__DEV__$2 && output != null && typeof output === "object") {
1249
+ if (output instanceof Promise) console.warn(`[Pyreon] Component <${componentName}> returned a Promise. Components must be synchronous — use lazy() + Suspense for async loading, or fetch data in onMount and store it in a signal.`);
1250
+ else if (!("type" in output)) console.warn(`[Pyreon] Component <${componentName}> returned an invalid value. Components must return a VNode, string, null, or function.`);
1251
+ }
1214
1252
  for (const fn of hooks.update) scope.addUpdateHook(fn);
1215
1253
  let subtreeCleanup = noop$1;
1216
1254
  try {