rask-ui 0.2.6 → 0.2.7
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/dist/vdom/AbstractVNode.d.ts.map +1 -1
- package/dist/vdom/AbstractVNode.js +9 -1
- package/dist/vdom/ComponentVNode.d.ts.map +1 -1
- package/dist/vdom/ComponentVNode.js +7 -3
- package/dist/vdom/ElementVNode.d.ts +4 -1
- package/dist/vdom/ElementVNode.d.ts.map +1 -1
- package/dist/vdom/ElementVNode.js +92 -3
- package/dist/vdom/FragmentVNode.d.ts.map +1 -1
- package/dist/vdom/FragmentVNode.js +7 -1
- package/dist/vdom/RootVNode.d.ts.map +1 -1
- package/dist/vdom/RootVNode.js +8 -1
- package/dist/vdom/dom-utils.d.ts +6 -1
- package/dist/vdom/dom-utils.d.ts.map +1 -1
- package/dist/vdom/dom-utils.js +20 -1
- package/dist/vdom/types.d.ts +12 -0
- package/dist/vdom/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/AbstractVNode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;CACpB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;IACtB,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;CACvB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;CACpB,CAAC;AAEN,8BAAsB,aAAa;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;IACnB,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE;IAC7C,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI;IACpC,QAAQ,CAAC,OAAO,IAAI,IAAI;IACxB,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IACtD,SAAS,CAAC,cAAc;IAOxB;;OAEG;IACH,WAAW,IAAI,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"AbstractVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/AbstractVNode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;CACpB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;IACtB,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;CACvB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;CACpB,CAAC;AAEN,8BAAsB,aAAa;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;IACnB,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE;IAC7C,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI;IACpC,QAAQ,CAAC,OAAO,IAAI,IAAI;IACxB,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IACtD,SAAS,CAAC,cAAc;IAOxB;;OAEG;IACH,WAAW,IAAI,IAAI,EAAE;IAmBrB,gBAAgB,IAAI,WAAW;IAiB/B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO;IAoB3D,aAAa,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG;QACnC,QAAQ,EAAE,KAAK,EAAE,CAAC;QAClB,mBAAmB,EAAE,OAAO,CAAC;QAC7B,UAAU,EAAE,cAAc,EAAE,CAAC;KAC9B;IAkJD,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE;IAqCtE;;;;OAIG;IACH,SAAS,CAAC,eAAe;CA6B1B"}
|
|
@@ -21,7 +21,15 @@ export class AbstractVNode {
|
|
|
21
21
|
if (!this.children) {
|
|
22
22
|
throw new Error("This VNode has no element or children");
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
// Optimized: avoid intermediate arrays from map+flat
|
|
25
|
+
const result = [];
|
|
26
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
27
|
+
const childElms = this.children[i].getElements();
|
|
28
|
+
for (let j = 0; j < childElms.length; j++) {
|
|
29
|
+
result.push(childElms[j]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
25
33
|
}
|
|
26
34
|
getParentElement() {
|
|
27
35
|
let parent = this.parent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/ComponentVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,QAAQ,EAAU,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ComponentVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/ComponentVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,QAAQ,EAAU,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAIvC,MAAM,MAAM,cAAc,GACtB,KAAK,GACL,MAAM,GACN,IAAI,GACJ,MAAM,GACN,SAAS,GACT,OAAO,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,cAAc,EAAE,CAAC;AAElE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,KAAK,IACjC,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,iBAAiB,CAAC,GACvC,CAAC,MAAM,MAAM,iBAAiB,CAAC,CAAC;AAEpC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACtC,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC5B,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC,CAAC;AAKF,wBAAgB,mBAAmB,sBAYlC;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,QAYrC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,QAYvC;AAED,qBAAa,cAAe,SAAQ,aAAa;IAC/C,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;IAEb,QAAQ,EAAE,KAAK,EAAE,CAAM;IACvB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;gBAE3B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,EACzB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,KAAK,EAAE,EACjB,GAAG,CAAC,EAAE,MAAM;IAWd,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAG7C,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE;IA6I7B,KAAK,CAAC,OAAO,EAAE,cAAc;IAW7B,OAAO;CAcR"}
|
|
@@ -3,6 +3,7 @@ import { AbstractVNode } from "./AbstractVNode";
|
|
|
3
3
|
import { FragmentVNode } from "./FragmentVNode";
|
|
4
4
|
import { RootVNode } from "./RootVNode";
|
|
5
5
|
import { normalizeChildren } from "./utils";
|
|
6
|
+
import { flattenNodes } from "./dom-utils";
|
|
6
7
|
import { currentRoot } from "./RootVNode";
|
|
7
8
|
export function getCurrentComponent() {
|
|
8
9
|
if (!currentRoot) {
|
|
@@ -158,9 +159,12 @@ export class ComponentVNode extends AbstractVNode {
|
|
|
158
159
|
this.children = executeRender();
|
|
159
160
|
this.root?.popComponent();
|
|
160
161
|
this.root?.clearCurrent();
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
// Optimized: avoid intermediate arrays from map+flat
|
|
163
|
+
const childResults = [];
|
|
164
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
165
|
+
childResults.push(this.children[i].mount(this));
|
|
166
|
+
}
|
|
167
|
+
const childElements = flattenNodes(childResults);
|
|
164
168
|
// Queue onMount callbacks after children are mounted
|
|
165
169
|
// This ensures refs and other child lifecycle hooks run before parent onMount
|
|
166
170
|
instance.onMounts.forEach((cb) => {
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { AbstractVNode, PatchOperation } from "./AbstractVNode";
|
|
2
|
-
import { Props, VNode } from "./types";
|
|
2
|
+
import { Props, VNode, VFlags } from "./types";
|
|
3
3
|
export declare class ElementVNode extends AbstractVNode {
|
|
4
4
|
tag: string;
|
|
5
5
|
props: Props;
|
|
6
6
|
children: VNode[];
|
|
7
7
|
key?: string;
|
|
8
|
+
flags: VFlags;
|
|
8
9
|
private ref?;
|
|
9
10
|
private eventListeners?;
|
|
10
11
|
constructor(tag: string, { ref, ...props }: Props, children: VNode[], key?: string);
|
|
12
|
+
private computeFlags;
|
|
11
13
|
rerender(operations?: PatchOperation[]): void;
|
|
12
14
|
mount(parent?: VNode): Node;
|
|
13
15
|
/**
|
|
@@ -19,6 +21,7 @@ export declare class ElementVNode extends AbstractVNode {
|
|
|
19
21
|
unmount(): void;
|
|
20
22
|
private setProp;
|
|
21
23
|
private patchProps;
|
|
24
|
+
private patchStyle;
|
|
22
25
|
private addEventListener;
|
|
23
26
|
}
|
|
24
27
|
//# sourceMappingURL=ElementVNode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElementVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/ElementVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ElementVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/ElementVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAU/C,qBAAa,YAAa,SAAQ,aAAa;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,CAA0D;IACtE,OAAO,CAAC,cAAc,CAAC,CAA6B;gBAElD,GAAG,EAAE,MAAM,EACX,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,EACxB,QAAQ,EAAE,KAAK,EAAE,EACjB,GAAG,CAAC,EAAE,MAAM;IAad,OAAO,CAAC,YAAY;IAwBpB,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAO7C,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI;IAkC3B;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE,YAAY;IAwB3B,OAAO;IAYP,OAAO,CAAC,OAAO,CAoCb;IACF,OAAO,CAAC,UAAU;IAsClB,OAAO,CAAC,UAAU;IAoClB,OAAO,CAAC,gBAAgB;CAgBzB"}
|
|
@@ -7,6 +7,7 @@ export class ElementVNode extends AbstractVNode {
|
|
|
7
7
|
props;
|
|
8
8
|
children;
|
|
9
9
|
key;
|
|
10
|
+
flags;
|
|
10
11
|
ref;
|
|
11
12
|
eventListeners;
|
|
12
13
|
constructor(tag, { ref, ...props }, children, key) {
|
|
@@ -16,6 +17,31 @@ export class ElementVNode extends AbstractVNode {
|
|
|
16
17
|
this.children = children;
|
|
17
18
|
this.key = key;
|
|
18
19
|
this.ref = ref;
|
|
20
|
+
// Pre-compute flags for fast-path checks during patching
|
|
21
|
+
this.flags = this.computeFlags(props);
|
|
22
|
+
}
|
|
23
|
+
computeFlags(props) {
|
|
24
|
+
let flags = 0 /* VFlags.None */;
|
|
25
|
+
const propKeys = Object.keys(props);
|
|
26
|
+
if (propKeys.length > 0) {
|
|
27
|
+
flags |= 1 /* VFlags.HasProps */;
|
|
28
|
+
for (let i = 0; i < propKeys.length; i++) {
|
|
29
|
+
const key = propKeys[i];
|
|
30
|
+
if (key === "class" || key === "className") {
|
|
31
|
+
flags |= 2 /* VFlags.HasClass */;
|
|
32
|
+
}
|
|
33
|
+
else if (key === "style") {
|
|
34
|
+
flags |= 4 /* VFlags.HasStyle */;
|
|
35
|
+
}
|
|
36
|
+
else if (isEventProp(key)) {
|
|
37
|
+
flags |= 8 /* VFlags.HasEvents */;
|
|
38
|
+
}
|
|
39
|
+
else if (key.startsWith("data-") || key.startsWith("aria-")) {
|
|
40
|
+
flags |= 16 /* VFlags.HasDataAttrs */;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return flags;
|
|
19
45
|
}
|
|
20
46
|
rerender(operations) {
|
|
21
47
|
if (operations) {
|
|
@@ -60,7 +86,14 @@ export class ElementVNode extends AbstractVNode {
|
|
|
60
86
|
* - Patch the children
|
|
61
87
|
*/
|
|
62
88
|
patch(newNode) {
|
|
63
|
-
|
|
89
|
+
// Save old flags before updating
|
|
90
|
+
const oldFlags = this.flags;
|
|
91
|
+
// Only patch props if either old or new node has props
|
|
92
|
+
if ((oldFlags | newNode.flags) & 1 /* VFlags.HasProps */) {
|
|
93
|
+
this.patchProps(newNode.props, oldFlags, newNode.flags);
|
|
94
|
+
}
|
|
95
|
+
// Update flags and props after patching
|
|
96
|
+
this.flags = newNode.flags;
|
|
64
97
|
this.props = newNode.props;
|
|
65
98
|
const { children, hasChangedStructure, operations } = this.patchChildren(newNode.children);
|
|
66
99
|
this.children = children;
|
|
@@ -110,8 +143,64 @@ export class ElementVNode extends AbstractVNode {
|
|
|
110
143
|
}
|
|
111
144
|
setElementProp(elm, prop, value);
|
|
112
145
|
};
|
|
113
|
-
patchProps(newProps) {
|
|
114
|
-
|
|
146
|
+
patchProps(newProps, oldFlags, newFlags) {
|
|
147
|
+
// Early bailout for reference equality
|
|
148
|
+
if (this.props === newProps) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const oldProps = this.props;
|
|
152
|
+
const elm = this.getHTMLElement();
|
|
153
|
+
// Handle class separately for efficiency (check if either old or new has class)
|
|
154
|
+
if ((oldFlags | newFlags) & 2 /* VFlags.HasClass */) {
|
|
155
|
+
const oldClass = oldProps.class ?? oldProps.className;
|
|
156
|
+
const newClass = newProps.class ?? newProps.className;
|
|
157
|
+
if (oldClass !== newClass) {
|
|
158
|
+
setElementClass(elm, newClass);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Handle style separately with per-property diffing (check if either old or new has style)
|
|
162
|
+
if ((oldFlags | newFlags) & 4 /* VFlags.HasStyle */) {
|
|
163
|
+
this.patchStyle(oldProps.style, newProps.style);
|
|
164
|
+
}
|
|
165
|
+
// Handle regular props (excluding class, className, style, children)
|
|
166
|
+
diffObjectKeys(oldProps, newProps, (key, value, oldValue) => {
|
|
167
|
+
// Skip props we've already handled
|
|
168
|
+
if (key === "class" ||
|
|
169
|
+
key === "className" ||
|
|
170
|
+
key === "style" ||
|
|
171
|
+
key === "children") {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
this.setProp(key, value);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
patchStyle(oldStyle, newStyle) {
|
|
178
|
+
// Early bailout for reference equality
|
|
179
|
+
if (oldStyle === newStyle) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const elm = this.getHTMLElement();
|
|
183
|
+
// If either is a string, fall back to full replacement
|
|
184
|
+
if (typeof oldStyle === "string" || typeof newStyle === "string") {
|
|
185
|
+
setElementStyle(elm, newStyle);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// Per-property style diffing for objects
|
|
189
|
+
const os = oldStyle || {};
|
|
190
|
+
const ns = newStyle || {};
|
|
191
|
+
// Remove old styles not in new
|
|
192
|
+
for (const key in os) {
|
|
193
|
+
if (!(key in ns)) {
|
|
194
|
+
elm.style[key] = "";
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Set new/changed styles
|
|
198
|
+
for (const key in ns) {
|
|
199
|
+
const newVal = ns[key];
|
|
200
|
+
if (newVal !== os[key]) {
|
|
201
|
+
elm.style[key] = newVal;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
115
204
|
}
|
|
116
205
|
addEventListener(type, cb) {
|
|
117
206
|
if (!this.eventListeners) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FragmentVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/FragmentVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKhE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"FragmentVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/FragmentVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKhE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,eAAO,MAAM,QAAQ,eAAqB,CAAC;AAE3C,qBAAa,aAAc,SAAQ,aAAa;IAC9C,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;gBAED,QAAQ,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM;IAK3C,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE;IAgB7B,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAG7C,KAAK,CAAC,OAAO,EAAE,aAAa;IAiB5B,OAAO;CAMR"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AbstractVNode } from "./AbstractVNode";
|
|
2
2
|
import { RootVNode } from "./RootVNode";
|
|
3
|
+
import { flattenNodes } from "./dom-utils";
|
|
3
4
|
export const Fragment = Symbol("Fragment");
|
|
4
5
|
export class FragmentVNode extends AbstractVNode {
|
|
5
6
|
children;
|
|
@@ -17,7 +18,12 @@ export class FragmentVNode extends AbstractVNode {
|
|
|
17
18
|
else {
|
|
18
19
|
this.root = parent?.root;
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
+
// Optimized: avoid intermediate arrays from map+flat
|
|
22
|
+
const childResults = [];
|
|
23
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
24
|
+
childResults.push(this.children[i].mount(this));
|
|
25
|
+
}
|
|
26
|
+
return flattenNodes(childResults);
|
|
21
27
|
}
|
|
22
28
|
rerender(operations) {
|
|
23
29
|
this.parent?.rerender(operations);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RootVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/RootVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"RootVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/RootVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAKrD,eAAO,IAAI,WAAW,EAAE,SAAS,GAAG,SAAS,CAAC;AAE9C,qBAAa,SAAU,SAAQ,aAAa;IAC1C,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClB,cAAc,EAAE,iBAAiB,EAAE,CAAM;IACzC,OAAO,CAAC,cAAc,CAGpB;IACF,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,gBAAgB,CAAyB;gBAErC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW;IAMnD,UAAU,CAAC,EAAE,EAAE,MAAM,IAAI;IAIzB,YAAY,CAAC,EAAE,EAAE,MAAM,IAAI;IAG3B,aAAa,CAAC,EAAE,EAAE,MAAM,IAAI;IAa5B,cAAc;IAOd,aAAa,CAAC,QAAQ,EAAE,iBAAiB;IAIzC,YAAY;IAIZ,YAAY;IAIZ,YAAY;IAMZ,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE;IAStB,KAAK,IAAI,IAAI;IACb,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAS7C,OAAO,IAAI,IAAI;CAChB"}
|
package/dist/vdom/RootVNode.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AbstractVNode } from "./AbstractVNode";
|
|
2
|
+
import { flattenNodes } from "./dom-utils";
|
|
2
3
|
// Global reference to the currently executing root
|
|
3
4
|
// Safe because JS is single-threaded - only one render executes at a time
|
|
4
5
|
export let currentRoot;
|
|
@@ -56,7 +57,13 @@ export class RootVNode extends AbstractVNode {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
mount() {
|
|
59
|
-
|
|
60
|
+
// Optimized: avoid intermediate arrays from map+flat
|
|
61
|
+
const childResults = [];
|
|
62
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
63
|
+
childResults.push(this.children[i].mount(this));
|
|
64
|
+
}
|
|
65
|
+
const result = flattenNodes(childResults);
|
|
66
|
+
return result.length === 1 ? result[0] : result;
|
|
60
67
|
}
|
|
61
68
|
patch() { }
|
|
62
69
|
rerender(operations) {
|
package/dist/vdom/dom-utils.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Efficiently flatten a Node or Node[] result without creating intermediate arrays.
|
|
3
|
+
* Used to optimize mount operations that return either Node or Node[].
|
|
4
|
+
*/
|
|
5
|
+
export declare function flattenNodes(items: (Node | Node[])[]): Node[];
|
|
1
6
|
export declare function replaceElementsOf(parent: HTMLElement, newChildren: Node | Node[]): void;
|
|
2
7
|
export declare function elementsToFragment(elm: Node | Node[]): Node;
|
|
3
8
|
export declare function removeElementRange(parent: Node, start: Node, end: Node): void;
|
|
4
9
|
export declare function setElementProp(elm: HTMLElement, key: string, value: unknown): void;
|
|
5
10
|
export declare function setElementAttr(elm: HTMLElement, key: string, value: string | null): void;
|
|
6
|
-
export declare function setElementStyle(elm: HTMLElement, value
|
|
11
|
+
export declare function setElementStyle(elm: HTMLElement, value?: string | Record<string, unknown> | null): void;
|
|
7
12
|
export declare function isEventProp(name: string): boolean;
|
|
8
13
|
export declare function setElementClass(elm: HTMLElement, value: string | Record<string, boolean> | null | undefined): void;
|
|
9
14
|
//# sourceMappingURL=dom-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom-utils.d.ts","sourceRoot":"","sources":["../../src/vdom/dom-utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,IAAI,GAAG,IAAI,EAAE,QAO3B;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAc3D;AAGD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,QAQtE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,QAE3E;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,IAAI,QAOrB;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"dom-utils.d.ts","sourceRoot":"","sources":["../../src/vdom/dom-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAa7D;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,IAAI,GAAG,IAAI,EAAE,QAO3B;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAc3D;AAGD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,QAQtE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,QAE3E;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,IAAI,QAOrB;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,QAehD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,QA0B3D"}
|
package/dist/vdom/dom-utils.js
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Efficiently flatten a Node or Node[] result without creating intermediate arrays.
|
|
3
|
+
* Used to optimize mount operations that return either Node or Node[].
|
|
4
|
+
*/
|
|
5
|
+
export function flattenNodes(items) {
|
|
6
|
+
const result = [];
|
|
7
|
+
for (let i = 0; i < items.length; i++) {
|
|
8
|
+
const item = items[i];
|
|
9
|
+
if (Array.isArray(item)) {
|
|
10
|
+
for (let j = 0; j < item.length; j++) {
|
|
11
|
+
result.push(item[j]);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
result.push(item);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
1
20
|
export function replaceElementsOf(parent, newChildren) {
|
|
2
21
|
if (Array.isArray(newChildren)) {
|
|
3
22
|
parent.replaceChildren(...newChildren);
|
|
@@ -42,7 +61,7 @@ export function setElementAttr(elm, key, value) {
|
|
|
42
61
|
}
|
|
43
62
|
}
|
|
44
63
|
export function setElementStyle(elm, value) {
|
|
45
|
-
if (value === null) {
|
|
64
|
+
if (value === null || value === undefined) {
|
|
46
65
|
elm.removeAttribute("style");
|
|
47
66
|
return;
|
|
48
67
|
}
|
package/dist/vdom/types.d.ts
CHANGED
|
@@ -5,4 +5,16 @@ import { RootVNode } from "./RootVNode";
|
|
|
5
5
|
import { TextVNode } from "./TextVNode";
|
|
6
6
|
export type VNode = ElementVNode | FragmentVNode | ComponentVNode | TextVNode | RootVNode;
|
|
7
7
|
export type Props = Record<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Bit flags to optimize VNode property checks.
|
|
10
|
+
* Pre-computed during VNode creation to avoid repeated conditional checks.
|
|
11
|
+
*/
|
|
12
|
+
export declare const enum VFlags {
|
|
13
|
+
None = 0,
|
|
14
|
+
HasProps = 1,// Has any props at all
|
|
15
|
+
HasClass = 2,// Has class or className prop
|
|
16
|
+
HasStyle = 4,// Has style prop
|
|
17
|
+
HasEvents = 8,// Has event listeners (onXxx props)
|
|
18
|
+
HasDataAttrs = 16
|
|
19
|
+
}
|
|
8
20
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/vdom/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vdom/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,KAAK,GACb,YAAY,GACZ,aAAa,GACb,cAAc,GACd,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vdom/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,KAAK,GACb,YAAY,GACZ,aAAa,GACb,cAAc,GACd,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5C;;;GAGG;AACH,0BAAkB,MAAM;IACtB,IAAI,IAAI;IACR,QAAQ,IAAS,CAAQ,uBAAuB;IAChD,QAAQ,IAAS,CAAQ,8BAA8B;IACvD,QAAQ,IAAS,CAAQ,iBAAiB;IAC1C,SAAS,IAAS,CAAO,oCAAoC;IAC7D,YAAY,KAAS;CACtB"}
|