rask-ui 0.3.4 → 0.4.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.
- package/README.md +266 -96
- package/dist/batch.d.ts +7 -0
- package/dist/batch.d.ts.map +1 -0
- package/dist/batch.js +107 -0
- package/dist/component.d.ts +9 -1
- package/dist/component.d.ts.map +1 -1
- package/dist/component.js +42 -12
- package/dist/createComputed.d.ts +4 -0
- package/dist/createComputed.d.ts.map +1 -0
- package/dist/createComputed.js +41 -0
- package/dist/createEffect.d.ts +2 -0
- package/dist/createEffect.d.ts.map +1 -0
- package/dist/createEffect.js +25 -0
- package/dist/createState.d.ts +1 -0
- package/dist/createState.d.ts.map +1 -1
- package/dist/createState.js +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/observation.d.ts +82 -6
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +171 -21
- package/dist/plugin.d.ts +8 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +195 -0
- package/dist/scheduler.d.ts +4 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +107 -0
- package/package.json +1 -1
- package/dist/createRef.d.ts +0 -5
- package/dist/createRef.d.ts.map +0 -1
- package/dist/createRef.js +0 -7
- package/dist/test-setup.d.ts +0 -16
- package/dist/test-setup.d.ts.map +0 -1
- package/dist/test-setup.js +0 -40
- package/dist/vdom/AbstractVNode.d.ts +0 -44
- package/dist/vdom/AbstractVNode.d.ts.map +0 -1
- package/dist/vdom/AbstractVNode.js +0 -256
- package/dist/vdom/ComponentVNode.d.ts +0 -48
- package/dist/vdom/ComponentVNode.d.ts.map +0 -1
- package/dist/vdom/ComponentVNode.js +0 -221
- package/dist/vdom/ElementVNode.d.ts +0 -27
- package/dist/vdom/ElementVNode.d.ts.map +0 -1
- package/dist/vdom/ElementVNode.js +0 -220
- package/dist/vdom/FragmentVNode.d.ts +0 -13
- package/dist/vdom/FragmentVNode.d.ts.map +0 -1
- package/dist/vdom/FragmentVNode.js +0 -49
- package/dist/vdom/RootVNode.d.ts +0 -25
- package/dist/vdom/RootVNode.d.ts.map +0 -1
- package/dist/vdom/RootVNode.js +0 -79
- package/dist/vdom/TextVNode.d.ts +0 -11
- package/dist/vdom/TextVNode.d.ts.map +0 -1
- package/dist/vdom/TextVNode.js +0 -35
- package/dist/vdom/dom-utils.d.ts +0 -14
- package/dist/vdom/dom-utils.d.ts.map +0 -1
- package/dist/vdom/dom-utils.js +0 -103
- package/dist/vdom/index.d.ts +0 -10
- package/dist/vdom/index.d.ts.map +0 -1
- package/dist/vdom/index.js +0 -26
- package/dist/vdom/types.d.ts +0 -20
- package/dist/vdom/types.d.ts.map +0 -1
- package/dist/vdom/types.js +0 -1
- package/dist/vdom/utils.d.ts +0 -6
- package/dist/vdom/utils.d.ts.map +0 -1
- package/dist/vdom/utils.js +0 -63
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { AbstractVNode } from "./AbstractVNode";
|
|
2
|
-
import { RootVNode } from "./RootVNode";
|
|
3
|
-
import { isEventProp, setElementAttr, setElementProp, setElementStyle, setElementClass, } from "./dom-utils";
|
|
4
|
-
import { diffObjectKeys } from "./utils";
|
|
5
|
-
export class ElementVNode extends AbstractVNode {
|
|
6
|
-
tag;
|
|
7
|
-
props;
|
|
8
|
-
children;
|
|
9
|
-
key;
|
|
10
|
-
flags;
|
|
11
|
-
ref;
|
|
12
|
-
eventListeners;
|
|
13
|
-
constructor(tag, { ref, ...props }, children, key) {
|
|
14
|
-
super();
|
|
15
|
-
this.tag = tag;
|
|
16
|
-
this.props = props;
|
|
17
|
-
this.children = children;
|
|
18
|
-
this.key = key;
|
|
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;
|
|
45
|
-
}
|
|
46
|
-
rerender(operations) {
|
|
47
|
-
if (operations) {
|
|
48
|
-
this.applyPatchOperations(this.getHTMLElement(), operations);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
this.syncDOMChildren();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
mount(parent) {
|
|
55
|
-
this.parent = parent;
|
|
56
|
-
if (parent instanceof RootVNode) {
|
|
57
|
-
this.root = parent;
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
this.root = parent?.root;
|
|
61
|
-
}
|
|
62
|
-
const elm = (this.elm = document.createElement(this.tag));
|
|
63
|
-
for (const prop in this.props) {
|
|
64
|
-
this.setProp(prop, this.props[prop]);
|
|
65
|
-
}
|
|
66
|
-
if (this.ref) {
|
|
67
|
-
const ref = this.ref;
|
|
68
|
-
this.root?.queueMount(() => {
|
|
69
|
-
ref(elm);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
this.children.forEach((child) => {
|
|
73
|
-
const childrenElms = child.mount(this);
|
|
74
|
-
if (Array.isArray(childrenElms)) {
|
|
75
|
-
childrenElms.forEach((node) => this.elm.appendChild(node));
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
elm.appendChild(childrenElms);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
return elm;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* An ELEMENT patch goes through three operations
|
|
85
|
-
* - Patch or replace the element
|
|
86
|
-
* - Patch the children
|
|
87
|
-
*/
|
|
88
|
-
patch(newNode) {
|
|
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;
|
|
97
|
-
this.props = newNode.props;
|
|
98
|
-
const { children, hasChangedStructure, operations } = this.patchChildren(newNode.children);
|
|
99
|
-
this.children = children;
|
|
100
|
-
if (hasChangedStructure) {
|
|
101
|
-
this.syncDOMChildren();
|
|
102
|
-
}
|
|
103
|
-
else if (operations?.length) {
|
|
104
|
-
this.applyPatchOperations(this.getHTMLElement(), operations);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
unmount() {
|
|
108
|
-
this.children.forEach((child) => child.unmount());
|
|
109
|
-
this.root?.queueUnmount(() => {
|
|
110
|
-
if (this.eventListeners) {
|
|
111
|
-
for (const type in this.eventListeners) {
|
|
112
|
-
this.elm.removeEventListener(type, this.eventListeners[type]);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
delete this.elm;
|
|
116
|
-
delete this.parent;
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
setProp = (prop, value) => {
|
|
120
|
-
const elm = this.getHTMLElement();
|
|
121
|
-
if (prop === "children") {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
if (prop === "class") {
|
|
125
|
-
setElementClass(elm, value);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
// Skip className if class is present (class takes precedence)
|
|
129
|
-
if (prop === "className" && "class" in this.props) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
if (prop === "style") {
|
|
133
|
-
setElementStyle(elm, value);
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
if (prop.startsWith("data-") || prop.startsWith("aria-")) {
|
|
137
|
-
setElementAttr(elm, prop, value);
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
if (isEventProp(prop)) {
|
|
141
|
-
this.addEventListener(prop.slice(2).toLowerCase(), value);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
setElementProp(elm, prop, value);
|
|
145
|
-
};
|
|
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
|
-
}
|
|
204
|
-
}
|
|
205
|
-
addEventListener(type, cb) {
|
|
206
|
-
if (!this.eventListeners) {
|
|
207
|
-
this.eventListeners = {};
|
|
208
|
-
}
|
|
209
|
-
if (this.eventListeners[type]) {
|
|
210
|
-
this.elm.removeEventListener(type, this.eventListeners[type]);
|
|
211
|
-
}
|
|
212
|
-
if (typeof cb === "function") {
|
|
213
|
-
this.elm.addEventListener(type, cb);
|
|
214
|
-
this.eventListeners[type] = cb;
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
delete this.eventListeners[type];
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { AbstractVNode, PatchOperation } from "./AbstractVNode";
|
|
2
|
-
import { VNode } from "./types";
|
|
3
|
-
export declare const Fragment: unique symbol;
|
|
4
|
-
export declare class FragmentVNode extends AbstractVNode {
|
|
5
|
-
children: VNode[];
|
|
6
|
-
key?: string;
|
|
7
|
-
constructor(children: VNode[], key?: string);
|
|
8
|
-
mount(parent?: VNode): Node[];
|
|
9
|
-
rerender(operations?: PatchOperation[]): void;
|
|
10
|
-
patch(newNode: FragmentVNode): void;
|
|
11
|
-
unmount(): void;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=FragmentVNode.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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,49 +0,0 @@
|
|
|
1
|
-
import { AbstractVNode } from "./AbstractVNode";
|
|
2
|
-
import { RootVNode } from "./RootVNode";
|
|
3
|
-
import { flattenNodes } from "./dom-utils";
|
|
4
|
-
export const Fragment = Symbol("Fragment");
|
|
5
|
-
export class FragmentVNode extends AbstractVNode {
|
|
6
|
-
children;
|
|
7
|
-
key;
|
|
8
|
-
constructor(children, key) {
|
|
9
|
-
super();
|
|
10
|
-
this.children = children;
|
|
11
|
-
this.key = key;
|
|
12
|
-
}
|
|
13
|
-
mount(parent) {
|
|
14
|
-
this.parent = parent;
|
|
15
|
-
if (parent instanceof RootVNode) {
|
|
16
|
-
this.root = parent;
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
this.root = parent?.root;
|
|
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);
|
|
27
|
-
}
|
|
28
|
-
rerender(operations) {
|
|
29
|
-
this.parent?.rerender(operations);
|
|
30
|
-
}
|
|
31
|
-
patch(newNode) {
|
|
32
|
-
const { children, hasChangedStructure, operations } = this.patchChildren(newNode.children);
|
|
33
|
-
this.children = children;
|
|
34
|
-
// So we can safely pass remove/replace operations up to the parent, but add
|
|
35
|
-
// is very tricky as parent has potentially other children as well. This can be
|
|
36
|
-
// handled with some additional detection, changing it to insertBefore. This can be
|
|
37
|
-
// done by passing this vnode up to the parent
|
|
38
|
-
this.rerender(hasChangedStructure ||
|
|
39
|
-
operations?.some((operation) => operation.type === "add")
|
|
40
|
-
? undefined
|
|
41
|
-
: operations);
|
|
42
|
-
}
|
|
43
|
-
unmount() {
|
|
44
|
-
this.children.forEach((child) => child.unmount());
|
|
45
|
-
this.root?.queueUnmount(() => {
|
|
46
|
-
delete this.parent;
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
package/dist/vdom/RootVNode.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { AbstractVNode, PatchOperation } from "./AbstractVNode";
|
|
2
|
-
import { VNode } from "./types";
|
|
3
|
-
import { ComponentInstance } from "./ComponentVNode";
|
|
4
|
-
export declare let currentRoot: RootVNode | undefined;
|
|
5
|
-
export declare class RootVNode extends AbstractVNode {
|
|
6
|
-
children: VNode[];
|
|
7
|
-
componentStack: ComponentInstance[];
|
|
8
|
-
private lifecycleQueue;
|
|
9
|
-
private hasPendingMicroTask;
|
|
10
|
-
private pendingObservers;
|
|
11
|
-
constructor(rootNode: VNode, container: HTMLElement);
|
|
12
|
-
queueMount(cb: () => void): void;
|
|
13
|
-
queueUnmount(cb: () => void): void;
|
|
14
|
-
queueObserver(cb: () => void): void;
|
|
15
|
-
flushLifecycle(): void;
|
|
16
|
-
pushComponent(instance: ComponentInstance): void;
|
|
17
|
-
popComponent(): void;
|
|
18
|
-
setAsCurrent(): void;
|
|
19
|
-
clearCurrent(): void;
|
|
20
|
-
mount(): Node | Node[];
|
|
21
|
-
patch(): void;
|
|
22
|
-
rerender(operations?: PatchOperation[]): void;
|
|
23
|
-
unmount(): void;
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=RootVNode.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { AbstractVNode } from "./AbstractVNode";
|
|
2
|
-
import { flattenNodes } from "./dom-utils";
|
|
3
|
-
// Global reference to the currently executing root
|
|
4
|
-
// Safe because JS is single-threaded - only one render executes at a time
|
|
5
|
-
export let currentRoot;
|
|
6
|
-
export class RootVNode extends AbstractVNode {
|
|
7
|
-
children;
|
|
8
|
-
componentStack = [];
|
|
9
|
-
lifecycleQueue = {
|
|
10
|
-
toMount: [],
|
|
11
|
-
toUnmount: [],
|
|
12
|
-
};
|
|
13
|
-
hasPendingMicroTask = false;
|
|
14
|
-
pendingObservers = [];
|
|
15
|
-
constructor(rootNode, container) {
|
|
16
|
-
super();
|
|
17
|
-
this.elm = container;
|
|
18
|
-
this.children = [rootNode];
|
|
19
|
-
}
|
|
20
|
-
queueMount(cb) {
|
|
21
|
-
this.lifecycleQueue.toMount.push(cb);
|
|
22
|
-
}
|
|
23
|
-
queueUnmount(cb) {
|
|
24
|
-
this.lifecycleQueue.toUnmount.push(cb);
|
|
25
|
-
}
|
|
26
|
-
queueObserver(cb) {
|
|
27
|
-
this.pendingObservers.push(cb);
|
|
28
|
-
if (!this.hasPendingMicroTask) {
|
|
29
|
-
this.hasPendingMicroTask = true;
|
|
30
|
-
queueMicrotask(() => {
|
|
31
|
-
this.hasPendingMicroTask = false;
|
|
32
|
-
const pendingObservers = this.pendingObservers;
|
|
33
|
-
this.pendingObservers = [];
|
|
34
|
-
pendingObservers.forEach((pendingObserver) => pendingObserver());
|
|
35
|
-
this.flushLifecycle();
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
flushLifecycle() {
|
|
40
|
-
this.lifecycleQueue.toUnmount.forEach((cb) => cb());
|
|
41
|
-
this.lifecycleQueue.toUnmount = [];
|
|
42
|
-
this.lifecycleQueue.toMount.forEach((cb) => cb());
|
|
43
|
-
this.lifecycleQueue.toMount = [];
|
|
44
|
-
}
|
|
45
|
-
pushComponent(instance) {
|
|
46
|
-
this.componentStack.unshift(instance);
|
|
47
|
-
}
|
|
48
|
-
popComponent() {
|
|
49
|
-
this.componentStack.shift();
|
|
50
|
-
}
|
|
51
|
-
setAsCurrent() {
|
|
52
|
-
currentRoot = this;
|
|
53
|
-
}
|
|
54
|
-
clearCurrent() {
|
|
55
|
-
if (currentRoot === this) {
|
|
56
|
-
currentRoot = undefined;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
mount() {
|
|
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;
|
|
67
|
-
}
|
|
68
|
-
patch() { }
|
|
69
|
-
rerender(operations) {
|
|
70
|
-
if (operations) {
|
|
71
|
-
this.applyPatchOperations(this.getHTMLElement(), operations);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
this.syncDOMChildren();
|
|
75
|
-
}
|
|
76
|
-
this.flushLifecycle();
|
|
77
|
-
}
|
|
78
|
-
unmount() { }
|
|
79
|
-
}
|
package/dist/vdom/TextVNode.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { AbstractVNode } from "./AbstractVNode";
|
|
2
|
-
import { VNode } from "./types";
|
|
3
|
-
export declare class TextVNode extends AbstractVNode {
|
|
4
|
-
text: string;
|
|
5
|
-
constructor(text: string);
|
|
6
|
-
mount(parent?: VNode): Node;
|
|
7
|
-
patch(newNode: TextVNode): void;
|
|
8
|
-
rerender(): void;
|
|
9
|
-
unmount(): void;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=TextVNode.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TextVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/TextVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,qBAAa,SAAU,SAAQ,aAAa;IAC1C,IAAI,EAAE,MAAM,CAAC;gBACD,IAAI,EAAE,MAAM;IAIxB,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI;IAe3B,KAAK,CAAC,OAAO,EAAE,SAAS;IAQxB,QAAQ,IAAI,IAAI;IAChB,OAAO;CAMR"}
|
package/dist/vdom/TextVNode.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { AbstractVNode } from "./AbstractVNode";
|
|
2
|
-
import { RootVNode } from "./RootVNode";
|
|
3
|
-
export class TextVNode extends AbstractVNode {
|
|
4
|
-
text;
|
|
5
|
-
constructor(text) {
|
|
6
|
-
super();
|
|
7
|
-
this.text = text;
|
|
8
|
-
}
|
|
9
|
-
mount(parent) {
|
|
10
|
-
this.parent = parent;
|
|
11
|
-
if (parent instanceof RootVNode) {
|
|
12
|
-
this.root = parent;
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
this.root = parent?.root;
|
|
16
|
-
}
|
|
17
|
-
const textNode = document.createTextNode(this.text);
|
|
18
|
-
this.elm = textNode;
|
|
19
|
-
return textNode;
|
|
20
|
-
}
|
|
21
|
-
patch(newNode) {
|
|
22
|
-
if (newNode.text === this.text) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
this.text = newNode.text;
|
|
26
|
-
this.elm.textContent = this.text;
|
|
27
|
-
}
|
|
28
|
-
rerender() { }
|
|
29
|
-
unmount() {
|
|
30
|
-
this.root?.queueUnmount(() => {
|
|
31
|
-
delete this.elm;
|
|
32
|
-
delete this.parent;
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
}
|
package/dist/vdom/dom-utils.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
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[];
|
|
6
|
-
export declare function replaceElementsOf(parent: HTMLElement, newChildren: Node | Node[]): void;
|
|
7
|
-
export declare function elementsToFragment(elm: Node | Node[]): Node;
|
|
8
|
-
export declare function removeElementRange(parent: Node, start: Node, end: Node): void;
|
|
9
|
-
export declare function setElementProp(elm: HTMLElement, key: string, value: unknown): void;
|
|
10
|
-
export declare function setElementAttr(elm: HTMLElement, key: string, value: string | null): void;
|
|
11
|
-
export declare function setElementStyle(elm: HTMLElement, value?: string | Record<string, unknown> | null): void;
|
|
12
|
-
export declare function isEventProp(name: string): boolean;
|
|
13
|
-
export declare function setElementClass(elm: HTMLElement, value: string | Record<string, boolean> | null | undefined): void;
|
|
14
|
-
//# sourceMappingURL=dom-utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
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
|
-
}
|
|
20
|
-
export function replaceElementsOf(parent, newChildren) {
|
|
21
|
-
if (Array.isArray(newChildren)) {
|
|
22
|
-
parent.replaceChildren(...newChildren);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
parent.replaceChildren(newChildren);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
export function elementsToFragment(elm) {
|
|
29
|
-
if (Array.isArray(elm) && elm.length === 1) {
|
|
30
|
-
return elm[0];
|
|
31
|
-
}
|
|
32
|
-
if (Array.isArray(elm)) {
|
|
33
|
-
const frag = document.createDocumentFragment();
|
|
34
|
-
for (let i = 0; i < elm.length; i++) {
|
|
35
|
-
frag.appendChild(elm[i]);
|
|
36
|
-
}
|
|
37
|
-
return frag;
|
|
38
|
-
}
|
|
39
|
-
return elm;
|
|
40
|
-
}
|
|
41
|
-
// Inclusive range removal helper
|
|
42
|
-
export function removeElementRange(parent, start, end) {
|
|
43
|
-
let cur = start;
|
|
44
|
-
while (cur) {
|
|
45
|
-
const next = cur === end ? null : cur.nextSibling;
|
|
46
|
-
parent.removeChild(cur);
|
|
47
|
-
if (cur === end)
|
|
48
|
-
break;
|
|
49
|
-
cur = next;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
export function setElementProp(elm, key, value) {
|
|
53
|
-
elm[key] = value;
|
|
54
|
-
}
|
|
55
|
-
export function setElementAttr(elm, key, value) {
|
|
56
|
-
if (value === null) {
|
|
57
|
-
elm.removeAttribute(key);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
elm.setAttribute(key, value);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
export function setElementStyle(elm, value) {
|
|
64
|
-
if (value === null || value === undefined) {
|
|
65
|
-
elm.removeAttribute("style");
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
if (typeof value === "string") {
|
|
69
|
-
elm.setAttribute("style", value);
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
for (const style in value) {
|
|
73
|
-
elm.style[style] = value[style];
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
export function isEventProp(name) {
|
|
77
|
-
return name.length > 2 && name[0] === "o" && name[1] === "n";
|
|
78
|
-
}
|
|
79
|
-
export function setElementClass(elm, value) {
|
|
80
|
-
if (value === null || value === undefined) {
|
|
81
|
-
elm.removeAttribute("class");
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (typeof value === "string") {
|
|
85
|
-
if (value === "") {
|
|
86
|
-
elm.removeAttribute("class");
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
elm.className = value;
|
|
90
|
-
}
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
// Handle object notation: { "class-name": true, "other-class": false }
|
|
94
|
-
const classes = Object.keys(value)
|
|
95
|
-
.filter((key) => value[key])
|
|
96
|
-
.join(" ");
|
|
97
|
-
if (classes === "") {
|
|
98
|
-
elm.removeAttribute("class");
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
elm.className = classes;
|
|
102
|
-
}
|
|
103
|
-
}
|
package/dist/vdom/index.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Component, ComponentVNode } from "./ComponentVNode";
|
|
2
|
-
import { ElementVNode } from "./ElementVNode";
|
|
3
|
-
import { Fragment, FragmentVNode } from "./FragmentVNode";
|
|
4
|
-
import { RootVNode } from "./RootVNode";
|
|
5
|
-
import { Props, VNode } from "./types";
|
|
6
|
-
export declare function jsx(type: string | typeof Fragment | Component<any>, props?: Props, key?: string): ElementVNode | FragmentVNode | ComponentVNode;
|
|
7
|
-
export declare const jsxs: typeof jsx;
|
|
8
|
-
export declare const jsxDEV: typeof jsx;
|
|
9
|
-
export declare function render(vnode: VNode, container: HTMLElement): RootVNode;
|
|
10
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/vdom/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vdom/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGvC,wBAAgB,GAAG,CACjB,IAAI,EAAE,MAAM,GAAG,OAAO,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,EAC/C,KAAK,CAAC,EAAE,KAAK,EACb,GAAG,CAAC,EAAE,MAAM,iDAeb;AACD,eAAO,MAAM,IAAI,YAAM,CAAC;AACxB,eAAO,MAAM,MAAM,YAAM,CAAC;AAE1B,wBAAgB,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,aAM1D"}
|
package/dist/vdom/index.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { ComponentVNode } from "./ComponentVNode";
|
|
2
|
-
import { elementsToFragment } from "./dom-utils";
|
|
3
|
-
import { ElementVNode } from "./ElementVNode";
|
|
4
|
-
import { Fragment, FragmentVNode } from "./FragmentVNode";
|
|
5
|
-
import { RootVNode } from "./RootVNode";
|
|
6
|
-
import { normalizeChildren } from "./utils";
|
|
7
|
-
export function jsx(type, props, key) {
|
|
8
|
-
const { children, ...normalizedProps } = props || {};
|
|
9
|
-
const normalizedChildren = children === undefined ? [] : normalizeChildren(children);
|
|
10
|
-
if (typeof type === "string") {
|
|
11
|
-
return new ElementVNode(type, normalizedProps, normalizedChildren, key);
|
|
12
|
-
}
|
|
13
|
-
if (type === Fragment) {
|
|
14
|
-
return new FragmentVNode(normalizedChildren, key);
|
|
15
|
-
}
|
|
16
|
-
return new ComponentVNode(type, normalizedProps, normalizedChildren, key);
|
|
17
|
-
}
|
|
18
|
-
export const jsxs = jsx;
|
|
19
|
-
export const jsxDEV = jsx;
|
|
20
|
-
export function render(vnode, container) {
|
|
21
|
-
const rootNode = new RootVNode(vnode, container);
|
|
22
|
-
const elms = rootNode.mount();
|
|
23
|
-
container.appendChild(elementsToFragment(elms));
|
|
24
|
-
rootNode.flushLifecycle();
|
|
25
|
-
return rootNode;
|
|
26
|
-
}
|
package/dist/vdom/types.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { ComponentVNode } from "./ComponentVNode";
|
|
2
|
-
import { ElementVNode } from "./ElementVNode";
|
|
3
|
-
import { FragmentVNode } from "./FragmentVNode";
|
|
4
|
-
import { RootVNode } from "./RootVNode";
|
|
5
|
-
import { TextVNode } from "./TextVNode";
|
|
6
|
-
export type VNode = ElementVNode | FragmentVNode | ComponentVNode | TextVNode | RootVNode;
|
|
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
|
-
}
|
|
20
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/vdom/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dist/vdom/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/vdom/utils.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { ComponentVNode } from "./ComponentVNode";
|
|
2
|
-
import { VNode } from "./types";
|
|
3
|
-
export declare function diffObjectKeys(oldObj: Record<string, any>, newObj: Record<string, any>, onChange: (key: string, value: any, oldValue: any) => void): void;
|
|
4
|
-
export declare function normalizeChildren(input: any): any[];
|
|
5
|
-
export declare function findComponentVNode(vnode?: VNode): ComponentVNode | void;
|
|
6
|
-
//# sourceMappingURL=utils.d.ts.map
|
package/dist/vdom/utils.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/vdom/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,IAAI,QAiB3D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE,CA6BnD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,cAAc,GAAG,IAAI,CAcvE"}
|