@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.
- package/lib/analysis/index.js.html +1 -1
- package/lib/index.js +69 -31
- package/lib/index.js.map +1 -1
- package/lib/types/index.d.ts +50 -30
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/hydrate.ts +1 -1
- package/src/mount.ts +48 -6
- package/src/nodes.ts +9 -3
- package/src/props.ts +47 -29
- package/src/tests/coverage.test.ts +42 -0
- package/src/tests/mount.test.ts +17 -1
- package/src/transition-group.ts +0 -1
|
@@ -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":"
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 (!
|
|
955
|
-
else
|
|
956
|
-
|
|
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
|
|
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
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
const
|
|
984
|
-
el
|
|
985
|
-
return () =>
|
|
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")
|
|
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)
|
|
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"
|
|
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 {
|