veles 0.0.9 → 1.0.0-alpha.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 +4 -10
- package/dist/_utils-BZ1SMqm2.js +468 -0
- package/dist/_utils-gPluq0AT.cjs +563 -0
- package/dist/fragment-BdtgAtEr.d.ts +1549 -0
- package/dist/fragment-D252pobF.d.cts +1549 -0
- package/dist/index.cjs +798 -1239
- package/dist/index.d.cts +98 -19
- package/dist/index.d.ts +98 -19
- package/dist/index.js +798 -47
- package/dist/jsx-runtime.cjs +6 -242
- package/dist/jsx-runtime.d.cts +2 -10
- package/dist/jsx-runtime.d.ts +2 -10
- package/dist/jsx-runtime.js +2 -10
- package/package.json +6 -13
- package/dist/chunk-2KPVWPOL.js +0 -285
- package/dist/chunk-VW64LMPA.js +0 -928
- package/dist/index-BkD2Za6F.d.cts +0 -69
- package/dist/index-DBdVF_11.d.ts +0 -69
- package/dist/types.d-CjiJHqth.d.cts +0 -3954
- package/dist/types.d-CjiJHqth.d.ts +0 -3954
- package/dist/utils/index.cjs +0 -1211
- package/dist/utils/index.d.cts +0 -18
- package/dist/utils/index.d.ts +0 -18
- package/dist/utils/index.js +0 -37
package/README.md
CHANGED
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
[](https://bundlephobia.com/result?p=veles)
|
|
5
5
|
[](https://www.npmjs.com/package/veles)
|
|
6
6
|
|
|
7
|
-
> This library is still in early stages, so the API is not 100% finalized
|
|
8
|
-
|
|
9
7
|
`Veles` is a component-based performance-focused UI library. The main goal of this library is to provide a composable way to build highly interactive interfaces, which should be performant out of the box, as long as you follow the recommendations.
|
|
10
8
|
|
|
11
9
|
## Performance
|
|
@@ -30,16 +28,16 @@ Types are installed automatically with the same package.
|
|
|
30
28
|
import { createState } from "veles";
|
|
31
29
|
|
|
32
30
|
function NameComponent() {
|
|
33
|
-
const
|
|
31
|
+
const name$ = createState("");
|
|
34
32
|
return (
|
|
35
33
|
<div>
|
|
36
34
|
<input
|
|
37
35
|
type="text"
|
|
38
36
|
name="name"
|
|
39
|
-
value={
|
|
40
|
-
onInput={(e) =>
|
|
37
|
+
value={name$.attribute()}
|
|
38
|
+
onInput={(e) => name$.set(e.target.value)}
|
|
41
39
|
/>
|
|
42
|
-
<p>{
|
|
40
|
+
<p>{name$.render()}</p>
|
|
43
41
|
</div>
|
|
44
42
|
);
|
|
45
43
|
}
|
|
@@ -55,7 +53,3 @@ This will render an input and will update the Text node dynamically, without re-
|
|
|
55
53
|
- [Differences from other frameworks](https://bloomca.github.io/veles/frameworks-difference.html)
|
|
56
54
|
|
|
57
55
|
There also a companion app ([veles-calendar-app](https://github.com/Bloomca/veles-calendar-app)), which is developed using Veles and is supposed to push it to the limits, identify the issues and ideally improve performance even more.
|
|
58
|
-
|
|
59
|
-
### Features
|
|
60
|
-
|
|
61
|
-
The library is under development, so some features are not available yet. Namely the TypeScript type inferring is not the best (although the library does support TypeScript), and Portals are not implemented yet.
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
//#region src/hooks/lifecycle.ts
|
|
2
|
+
const contextStack = [];
|
|
3
|
+
let currentContext = null;
|
|
4
|
+
function addContext(newContext) {
|
|
5
|
+
contextStack.push(newContext);
|
|
6
|
+
currentContext = newContext;
|
|
7
|
+
}
|
|
8
|
+
function popContext() {
|
|
9
|
+
contextStack.pop();
|
|
10
|
+
currentContext = contextStack[contextStack.length - 1];
|
|
11
|
+
}
|
|
12
|
+
function onMount(cb) {
|
|
13
|
+
if (currentContext) currentContext.onMount(cb);
|
|
14
|
+
else console.error("missing current context");
|
|
15
|
+
}
|
|
16
|
+
function onUnmount(cb) {
|
|
17
|
+
if (currentContext) currentContext.onUnmount(cb);
|
|
18
|
+
else console.error("missing current context");
|
|
19
|
+
}
|
|
20
|
+
function hasCurrentLifecycleContext() {
|
|
21
|
+
return Boolean(currentContext);
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/create-element/create-text-element.ts
|
|
25
|
+
function createTextElement(text) {
|
|
26
|
+
const mountHandlers = [];
|
|
27
|
+
const unmountHandlers = [];
|
|
28
|
+
return {
|
|
29
|
+
velesStringElement: true,
|
|
30
|
+
html: document.createTextNode(text || ""),
|
|
31
|
+
_privateMethods: {
|
|
32
|
+
_addMountHandler(cb) {
|
|
33
|
+
mountHandlers.push(cb);
|
|
34
|
+
},
|
|
35
|
+
_callMountHandlers() {
|
|
36
|
+
mountHandlers.forEach((cb) => cb());
|
|
37
|
+
},
|
|
38
|
+
_addUnmountHandler: (cb) => {
|
|
39
|
+
unmountHandlers.push(cb);
|
|
40
|
+
},
|
|
41
|
+
_callUnmountHandlers: () => {
|
|
42
|
+
unmountHandlers.forEach((cb) => cb());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/create-element/parse-component.ts
|
|
49
|
+
function parseComponent({ element, props }) {
|
|
50
|
+
const mountCbs = [];
|
|
51
|
+
const unmountCbs = [];
|
|
52
|
+
return {
|
|
53
|
+
velesComponentObject: true,
|
|
54
|
+
element,
|
|
55
|
+
props,
|
|
56
|
+
_privateMethods: {
|
|
57
|
+
_addMountHandler(cb) {
|
|
58
|
+
mountCbs.push(cb);
|
|
59
|
+
},
|
|
60
|
+
_addUnmountHandler: (cb) => {
|
|
61
|
+
unmountCbs.push(cb);
|
|
62
|
+
},
|
|
63
|
+
_callMountHandlers: () => {
|
|
64
|
+
mountCbs.forEach((cb) => cb());
|
|
65
|
+
},
|
|
66
|
+
_callUnmountHandlers: () => {
|
|
67
|
+
unmountCbs.forEach((cb) => cb());
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function executeComponent({ element, props }) {
|
|
73
|
+
let componentUnmountCbs = [];
|
|
74
|
+
let componentMountCbs = [];
|
|
75
|
+
const componentAPI = {
|
|
76
|
+
onMount: (cb) => {
|
|
77
|
+
componentMountCbs.push(cb);
|
|
78
|
+
},
|
|
79
|
+
onUnmount: (cb) => {
|
|
80
|
+
componentUnmountCbs.push(cb);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
addContext(componentAPI);
|
|
84
|
+
const _componentTree = element(props, componentAPI);
|
|
85
|
+
const componentTree = typeof _componentTree === "string" || !_componentTree ? createTextElement(_componentTree) : _componentTree;
|
|
86
|
+
popContext();
|
|
87
|
+
return {
|
|
88
|
+
velesComponent: true,
|
|
89
|
+
tree: componentTree,
|
|
90
|
+
_privateMethods: {
|
|
91
|
+
_addMountHandler(cb) {
|
|
92
|
+
componentMountCbs.push(cb);
|
|
93
|
+
},
|
|
94
|
+
_addUnmountHandler: (cb) => {
|
|
95
|
+
componentAPI.onUnmount(cb);
|
|
96
|
+
},
|
|
97
|
+
_callMountHandlers: () => {
|
|
98
|
+
componentMountCbs.forEach((cb) => {
|
|
99
|
+
const mountCbResult = cb();
|
|
100
|
+
if (typeof mountCbResult === "function") componentAPI.onUnmount(mountCbResult);
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
_callUnmountHandlers: () => {
|
|
104
|
+
componentUnmountCbs.forEach((cb) => cb());
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/create-element/parse-children.ts
|
|
111
|
+
function parseChildren({ children, htmlElement, velesNode, portal }) {
|
|
112
|
+
const childComponents = [];
|
|
113
|
+
if (children === void 0 || children === null) return childComponents;
|
|
114
|
+
let lastInsertedNode = null;
|
|
115
|
+
(Array.isArray(children) ? children : [children]).forEach((childComponent) => {
|
|
116
|
+
if (typeof childComponent === "string") {
|
|
117
|
+
const textNode = createTextElement(childComponent);
|
|
118
|
+
htmlElement.append(textNode.html);
|
|
119
|
+
lastInsertedNode = textNode.html;
|
|
120
|
+
childComponents.push(textNode);
|
|
121
|
+
} else if (typeof childComponent === "number") {
|
|
122
|
+
const textNode = createTextElement(String(childComponent));
|
|
123
|
+
htmlElement.append(textNode.html);
|
|
124
|
+
lastInsertedNode = textNode.html;
|
|
125
|
+
childComponents.push(textNode);
|
|
126
|
+
} else if (typeof childComponent === "object" && childComponent && "velesNode" in childComponent && childComponent?.velesNode) if (childComponent.phantom) {
|
|
127
|
+
childComponent.childComponents.forEach((childComponentofPhantom) => {
|
|
128
|
+
if ("velesNode" in childComponentofPhantom) {
|
|
129
|
+
htmlElement.append(childComponentofPhantom.html);
|
|
130
|
+
childComponentofPhantom.parentVelesElement = velesNode;
|
|
131
|
+
lastInsertedNode = childComponentofPhantom.html;
|
|
132
|
+
} else if ("velesStringElement" in childComponentofPhantom) {
|
|
133
|
+
const velesElementNode = childComponentofPhantom;
|
|
134
|
+
if (!velesElementNode) console.error("can't find HTML tree in a component chain");
|
|
135
|
+
else {
|
|
136
|
+
htmlElement.append(velesElementNode.html);
|
|
137
|
+
lastInsertedNode = velesElementNode.html;
|
|
138
|
+
velesElementNode.parentVelesElement = velesNode;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
childComponent.parentVelesElement = velesNode;
|
|
143
|
+
childComponents.push(childComponent);
|
|
144
|
+
} else if (childComponent.portal) {
|
|
145
|
+
childComponent.parentVelesElement = velesNode;
|
|
146
|
+
childComponents.push(childComponent);
|
|
147
|
+
} else {
|
|
148
|
+
htmlElement.append(childComponent.html);
|
|
149
|
+
childComponent.parentVelesElement = velesNode;
|
|
150
|
+
childComponents.push(childComponent);
|
|
151
|
+
lastInsertedNode = childComponent.html;
|
|
152
|
+
}
|
|
153
|
+
else if (typeof childComponent === "object" && childComponent && "velesComponentObject" in childComponent) {
|
|
154
|
+
childComponent.parentVelesElement = velesNode;
|
|
155
|
+
childComponents.push(childComponent);
|
|
156
|
+
if (portal) childComponent.portal = portal;
|
|
157
|
+
else {
|
|
158
|
+
childComponent.insertAfter = lastInsertedNode;
|
|
159
|
+
lastInsertedNode = childComponent;
|
|
160
|
+
}
|
|
161
|
+
} else if (typeof childComponent === "object" && childComponent && "velesStringElement" in childComponent && childComponent?.velesStringElement) {
|
|
162
|
+
htmlElement.append(childComponent.html);
|
|
163
|
+
childComponent.parentVelesElement = velesNode;
|
|
164
|
+
childComponents.push(childComponent);
|
|
165
|
+
lastInsertedNode = childComponent.html;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
return childComponents;
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/create-element/assign-attributes.ts
|
|
172
|
+
function assignAttributes({ props, htmlElement, velesNode }) {
|
|
173
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
174
|
+
if (typeof value === "function" && value.velesAttribute === true) assignAttribute({
|
|
175
|
+
key,
|
|
176
|
+
value: value(htmlElement, key, velesNode),
|
|
177
|
+
htmlElement
|
|
178
|
+
});
|
|
179
|
+
else assignAttribute({
|
|
180
|
+
key,
|
|
181
|
+
value,
|
|
182
|
+
htmlElement
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
function assignAttribute({ key, value, htmlElement }) {
|
|
187
|
+
if (typeof value === "function" && key.startsWith("on")) htmlElement.addEventListener(key.slice(2).toLocaleLowerCase(), value);
|
|
188
|
+
else if (typeof value === "boolean") {
|
|
189
|
+
if (value) htmlElement.setAttribute(key, "");
|
|
190
|
+
} else htmlElement.setAttribute(key, value);
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/create-element/create-element.ts
|
|
194
|
+
function createElement(element, props = {}) {
|
|
195
|
+
if (typeof element === "string") {
|
|
196
|
+
const { children, ref, phantom = false, portal = null, ...otherProps } = props;
|
|
197
|
+
const newElement = document.createElement(element);
|
|
198
|
+
const velesNode = {};
|
|
199
|
+
if (ref?.velesRef) ref.current = newElement;
|
|
200
|
+
const childComponents = parseChildren({
|
|
201
|
+
children,
|
|
202
|
+
htmlElement: newElement,
|
|
203
|
+
velesNode,
|
|
204
|
+
portal
|
|
205
|
+
});
|
|
206
|
+
const unmountHandlers = [];
|
|
207
|
+
velesNode.html = newElement;
|
|
208
|
+
velesNode.velesNode = true;
|
|
209
|
+
velesNode.childComponents = childComponents;
|
|
210
|
+
velesNode.phantom = phantom;
|
|
211
|
+
velesNode.portal = portal;
|
|
212
|
+
const mountHandlers = [];
|
|
213
|
+
velesNode._privateMethods = {
|
|
214
|
+
_addMountHandler(cb) {
|
|
215
|
+
mountHandlers.push(cb);
|
|
216
|
+
},
|
|
217
|
+
_callMountHandlers() {
|
|
218
|
+
mountHandlers.forEach((cb) => cb());
|
|
219
|
+
},
|
|
220
|
+
_addUnmountHandler(cb) {
|
|
221
|
+
unmountHandlers.push(cb);
|
|
222
|
+
},
|
|
223
|
+
_callUnmountHandlers() {
|
|
224
|
+
unmountHandlers.forEach((cb) => cb());
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Since portal node is already mounted in DOM, we can't just attach our HTML to it
|
|
229
|
+
* imediately. So we attach it only when the component is actually mounted, and detach
|
|
230
|
+
* when it is unmounted. This way we don't need to iterate the tree manually and
|
|
231
|
+
* attach/detach in every case we need to change the tree.
|
|
232
|
+
*/
|
|
233
|
+
if (portal) {
|
|
234
|
+
velesNode._privateMethods._addMountHandler(function attachNodeOnMount() {
|
|
235
|
+
velesNode.childComponents.forEach((childComponent) => {
|
|
236
|
+
if ("velesNode" in childComponent) if (childComponent.phantom) childComponent.childComponents.forEach((fragmentChildComponent) => {
|
|
237
|
+
portal.append(fragmentChildComponent.html);
|
|
238
|
+
});
|
|
239
|
+
else portal.append(childComponent.html);
|
|
240
|
+
else if ("velesStringElement" in childComponent) portal.append(childComponent.html);
|
|
241
|
+
else appendComponentToPortal(getExecutedComponentVelesNode(childComponent.executedVersion), portal);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
velesNode._privateMethods._addUnmountHandler(function removeNodeOnUnmount() {
|
|
245
|
+
velesNode.childComponents.forEach((childComponent) => {
|
|
246
|
+
if ("velesNode" in childComponent) childComponent.html.remove();
|
|
247
|
+
else if ("velesStringElement" in childComponent) childComponent.html.remove();
|
|
248
|
+
else cleanupComponentFromPortal(getExecutedComponentVelesNode(childComponent.executedVersion));
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
assignAttributes({
|
|
253
|
+
props: otherProps,
|
|
254
|
+
htmlElement: newElement,
|
|
255
|
+
velesNode
|
|
256
|
+
});
|
|
257
|
+
return velesNode;
|
|
258
|
+
} else if (typeof element === "function") return parseComponent({
|
|
259
|
+
element,
|
|
260
|
+
props
|
|
261
|
+
});
|
|
262
|
+
throw new Error("Veles createElement expects a valid DOM string or another component");
|
|
263
|
+
}
|
|
264
|
+
function appendComponentToPortal(componentNode, portal) {
|
|
265
|
+
if ("executedVelesNode" in componentNode && componentNode.phantom) {
|
|
266
|
+
componentNode.childComponents.forEach((fragmentChildComponent) => {
|
|
267
|
+
if ("executedVelesComponent" in fragmentChildComponent) appendComponentToPortal(getExecutedComponentVelesNode(fragmentChildComponent), portal);
|
|
268
|
+
else portal.append(fragmentChildComponent.html);
|
|
269
|
+
});
|
|
270
|
+
componentNode.phantom;
|
|
271
|
+
} else portal.append(componentNode.html);
|
|
272
|
+
}
|
|
273
|
+
function cleanupComponentFromPortal(componentNode) {
|
|
274
|
+
if ("executedVelesNode" in componentNode && componentNode.phantom) {
|
|
275
|
+
componentNode.childComponents.forEach((fragmentChildComponent) => {
|
|
276
|
+
if ("executedVelesComponent" in fragmentChildComponent) cleanupComponentFromPortal(getExecutedComponentVelesNode(fragmentChildComponent));
|
|
277
|
+
else fragmentChildComponent.html.remove();
|
|
278
|
+
});
|
|
279
|
+
componentNode.phantom;
|
|
280
|
+
} else componentNode.html.remove();
|
|
281
|
+
}
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region src/fragment.ts
|
|
284
|
+
function Fragment({ children }) {
|
|
285
|
+
return createElement("div", {
|
|
286
|
+
phantom: true,
|
|
287
|
+
children
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
//#region src/context/index.ts
|
|
292
|
+
const publicContextStack = [];
|
|
293
|
+
let contextIdCounter = 1;
|
|
294
|
+
function createContext() {
|
|
295
|
+
const contextId = contextIdCounter++;
|
|
296
|
+
function addContext(value) {
|
|
297
|
+
const currentContextObject = publicContextStack[publicContextStack.length - 1];
|
|
298
|
+
if (!currentContextObject) console.error("cannot add Context due to missing stack value");
|
|
299
|
+
else publicContextStack[publicContextStack.length - 1] = {
|
|
300
|
+
...currentContextObject,
|
|
301
|
+
[contextId]: value
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
Provider: ({ value, children }) => {
|
|
306
|
+
addContext(value);
|
|
307
|
+
return createElement(Fragment, { children });
|
|
308
|
+
},
|
|
309
|
+
addContext,
|
|
310
|
+
readContext: () => {
|
|
311
|
+
const currentContext = publicContextStack[publicContextStack.length - 1];
|
|
312
|
+
if (!currentContext) console.error("no Context currently available");
|
|
313
|
+
else return currentContext[contextId];
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function addPublicContext(specificContext) {
|
|
318
|
+
if (specificContext) publicContextStack.push(specificContext);
|
|
319
|
+
else if (publicContextStack.length === 0) publicContextStack.push({});
|
|
320
|
+
else {
|
|
321
|
+
const currentContext = publicContextStack[publicContextStack.length - 1];
|
|
322
|
+
publicContextStack.push(currentContext);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function popPublicContext() {
|
|
326
|
+
publicContextStack.pop();
|
|
327
|
+
}
|
|
328
|
+
function getCurrentContext() {
|
|
329
|
+
return publicContextStack[publicContextStack.length - 1];
|
|
330
|
+
}
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region src/_utils.ts
|
|
333
|
+
function getExecutedComponentVelesNode(component) {
|
|
334
|
+
if ("executedVelesStringElement" in component) return component;
|
|
335
|
+
let childNode = component;
|
|
336
|
+
while ("executedVelesComponent" in childNode) if ("executedVelesStringElement" in childNode.tree) return childNode.tree;
|
|
337
|
+
else childNode = childNode.tree;
|
|
338
|
+
return childNode;
|
|
339
|
+
}
|
|
340
|
+
function renderTree(component, { parentVelesElement } = {}) {
|
|
341
|
+
if ("velesStringElement" in component) {
|
|
342
|
+
const executedString = {
|
|
343
|
+
executedVelesStringElement: true,
|
|
344
|
+
_privateMethods: component._privateMethods,
|
|
345
|
+
html: component.html,
|
|
346
|
+
parentVelesElement
|
|
347
|
+
};
|
|
348
|
+
if (component.needExecutedVersion) component.executedVersion = executedString;
|
|
349
|
+
return executedString;
|
|
350
|
+
} else if ("velesComponentObject" in component) {
|
|
351
|
+
addPublicContext();
|
|
352
|
+
const componentTree = executeComponent(component);
|
|
353
|
+
const executedComponent = {};
|
|
354
|
+
executedComponent.executedVelesComponent = true;
|
|
355
|
+
executedComponent.tree = renderTree(componentTree.tree);
|
|
356
|
+
popPublicContext();
|
|
357
|
+
executedComponent._privateMethods = {
|
|
358
|
+
...componentTree._privateMethods,
|
|
359
|
+
_callMountHandlers: () => {
|
|
360
|
+
component._privateMethods._callMountHandlers();
|
|
361
|
+
componentTree._privateMethods._callMountHandlers();
|
|
362
|
+
},
|
|
363
|
+
_callUnmountHandlers: () => {
|
|
364
|
+
component._privateMethods._callUnmountHandlers();
|
|
365
|
+
componentTree._privateMethods._callUnmountHandlers();
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
const newNode = getExecutedComponentVelesNode(executedComponent);
|
|
369
|
+
if (component.portal) {
|
|
370
|
+
/**
|
|
371
|
+
* Inserting nodes is handled by the portal parent element.
|
|
372
|
+
* We still need to assign `parentVelesElement`, so that
|
|
373
|
+
* `render` updates correctly
|
|
374
|
+
*/
|
|
375
|
+
if (parentVelesElement) newNode.parentVelesElement = parentVelesElement;
|
|
376
|
+
} else if (parentVelesElement) {
|
|
377
|
+
if (component.insertAfter) if ("velesComponentObject" in component.insertAfter) component.html = insertNode({
|
|
378
|
+
velesElement: newNode,
|
|
379
|
+
adjacentNode: component.insertAfter.html,
|
|
380
|
+
parentVelesElement
|
|
381
|
+
});
|
|
382
|
+
else component.html = insertNode({
|
|
383
|
+
velesElement: newNode,
|
|
384
|
+
adjacentNode: component.insertAfter,
|
|
385
|
+
parentVelesElement
|
|
386
|
+
});
|
|
387
|
+
else component.html = insertNode({
|
|
388
|
+
velesElement: newNode,
|
|
389
|
+
adjacentNode: null,
|
|
390
|
+
parentVelesElement
|
|
391
|
+
});
|
|
392
|
+
newNode.parentVelesElement = parentVelesElement;
|
|
393
|
+
}
|
|
394
|
+
if (component.needExecutedVersion || component.portal) component.executedVersion = executedComponent;
|
|
395
|
+
return executedComponent;
|
|
396
|
+
} else if ("velesNode" in component) {
|
|
397
|
+
const executedNode = {};
|
|
398
|
+
executedNode.executedVelesNode = true;
|
|
399
|
+
executedNode._privateMethods = component._privateMethods;
|
|
400
|
+
executedNode.html = component.html;
|
|
401
|
+
if (parentVelesElement) executedNode.parentVelesElement = parentVelesElement;
|
|
402
|
+
if (component.phantom) executedNode.phantom = component.phantom;
|
|
403
|
+
if (component.portal) executedNode.portal = component.portal;
|
|
404
|
+
executedNode.childComponents = component.childComponents.map((childComponent) => renderTree(childComponent, { parentVelesElement: executedNode }));
|
|
405
|
+
if (component.needExecutedVersion) component.executedVersion = executedNode;
|
|
406
|
+
return executedNode;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function insertNode({ velesElement, adjacentNode, parentVelesElement }) {
|
|
410
|
+
if (velesElement.phantom) {
|
|
411
|
+
let lastInsertedNode = null;
|
|
412
|
+
velesElement.childComponents.forEach((childComponentofPhantom) => {
|
|
413
|
+
if ("executedVelesNode" in childComponentofPhantom) {
|
|
414
|
+
if (lastInsertedNode) lastInsertedNode.after(childComponentofPhantom.html);
|
|
415
|
+
else if (adjacentNode) adjacentNode.after(childComponentofPhantom.html);
|
|
416
|
+
else parentVelesElement.html.prepend(childComponentofPhantom.html);
|
|
417
|
+
childComponentofPhantom.parentVelesElement = parentVelesElement;
|
|
418
|
+
lastInsertedNode = childComponentofPhantom.html;
|
|
419
|
+
} else if ("executedVelesStringElement" in childComponentofPhantom) {
|
|
420
|
+
if (lastInsertedNode) lastInsertedNode.after(childComponentofPhantom.html);
|
|
421
|
+
else if (adjacentNode) adjacentNode.after(childComponentofPhantom.html);
|
|
422
|
+
else parentVelesElement.html.prepend(childComponentofPhantom.html);
|
|
423
|
+
childComponentofPhantom.parentVelesElement = parentVelesElement;
|
|
424
|
+
lastInsertedNode = childComponentofPhantom.html;
|
|
425
|
+
} else {
|
|
426
|
+
const executedNode = getExecutedComponentVelesNode(childComponentofPhantom);
|
|
427
|
+
if (lastInsertedNode) lastInsertedNode.after(executedNode.html);
|
|
428
|
+
else if (adjacentNode) adjacentNode.after(executedNode.html);
|
|
429
|
+
else parentVelesElement.html.prepend(executedNode.html);
|
|
430
|
+
executedNode.parentVelesElement = parentVelesElement;
|
|
431
|
+
lastInsertedNode = executedNode.html;
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
velesElement.parentVelesElement = parentVelesElement;
|
|
435
|
+
return lastInsertedNode;
|
|
436
|
+
} else {
|
|
437
|
+
if (adjacentNode) adjacentNode.after(velesElement.html);
|
|
438
|
+
else parentVelesElement.html.prepend(velesElement.html);
|
|
439
|
+
velesElement.parentVelesElement = parentVelesElement;
|
|
440
|
+
return velesElement.html;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
function callMountHandlers(component) {
|
|
444
|
+
component._privateMethods._callMountHandlers();
|
|
445
|
+
if ("executedVelesStringElement" in component) return;
|
|
446
|
+
if ("executedVelesComponent" in component) callMountHandlers(component.tree);
|
|
447
|
+
if ("executedVelesNode" in component) component.childComponents.forEach((childComponent) => callMountHandlers(childComponent));
|
|
448
|
+
}
|
|
449
|
+
function callUnmountHandlers(component) {
|
|
450
|
+
if ("executedVelesStringElement" in component) {} else if ("executedVelesComponent" in component) callUnmountHandlers(component.tree);
|
|
451
|
+
else if ("executedVelesNode" in component) component.childComponents.forEach((childComponent) => callUnmountHandlers(childComponent));
|
|
452
|
+
component._privateMethods._callUnmountHandlers();
|
|
453
|
+
}
|
|
454
|
+
function identity(value1, value2) {
|
|
455
|
+
return value1 === value2;
|
|
456
|
+
}
|
|
457
|
+
function unique(arr) {
|
|
458
|
+
const map = /* @__PURE__ */ new Map();
|
|
459
|
+
const resultArr = [];
|
|
460
|
+
arr.forEach((element) => {
|
|
461
|
+
if (map.has(element)) return;
|
|
462
|
+
map.set(element, true);
|
|
463
|
+
resultArr.push(element);
|
|
464
|
+
});
|
|
465
|
+
return resultArr;
|
|
466
|
+
}
|
|
467
|
+
//#endregion
|
|
468
|
+
export { renderTree as a, createContext as c, Fragment as d, createElement as f, onUnmount as g, onMount as h, identity as i, getCurrentContext as l, hasCurrentLifecycleContext as m, callUnmountHandlers as n, unique as o, createTextElement as p, getExecutedComponentVelesNode as r, addPublicContext as s, callMountHandlers as t, popPublicContext as u };
|