veles 0.0.7 → 0.0.9

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/index.cjs CHANGED
@@ -21,6 +21,7 @@ var src_exports = {};
21
21
  __export(src_exports, {
22
22
  Fragment: () => Fragment,
23
23
  attachComponent: () => attachComponent,
24
+ createContext: () => createContext,
24
25
  createElement: () => createElement,
25
26
  createRef: () => createRef,
26
27
  createState: () => createState,
@@ -29,56 +30,127 @@ __export(src_exports, {
29
30
  });
30
31
  module.exports = __toCommonJS(src_exports);
31
32
 
32
- // src/_utils.ts
33
- function getComponentVelesNode(component) {
34
- const componentsTree = [];
35
- if ("velesStringElement" in component) {
36
- return {
37
- velesElementNode: component,
38
- componentsTree: []
39
- };
40
- }
41
- let childNode = component;
42
- while ("velesComponent" in childNode) {
43
- componentsTree.push(childNode);
44
- if ("velesStringElement" in childNode.tree) {
45
- return {
46
- velesElementNode: childNode.tree,
47
- componentsTree
48
- };
49
- } else {
50
- childNode = childNode.tree;
51
- }
52
- }
53
- return { velesElementNode: childNode, componentsTree };
33
+ // src/hooks/lifecycle.ts
34
+ var contextStack = [];
35
+ var currentContext = null;
36
+ function addContext(newContext) {
37
+ contextStack.push(newContext);
38
+ currentContext = newContext;
54
39
  }
55
- function callMountHandlers(component) {
56
- if ("velesStringElement" in component) {
57
- return;
58
- }
59
- if ("velesComponent" in component) {
60
- component._privateMethods._callMountHandlers();
61
- callMountHandlers(component.tree);
40
+ function popContext() {
41
+ contextStack.pop();
42
+ currentContext = contextStack[contextStack.length - 1];
43
+ }
44
+ function onMount(cb) {
45
+ if (currentContext) {
46
+ currentContext.onMount(cb);
47
+ } else {
48
+ console.error("missing current context");
62
49
  }
63
- if ("velesNode" in component) {
64
- component.childComponents.forEach(
65
- (childComponent) => callMountHandlers(childComponent)
66
- );
50
+ }
51
+ function onUnmount(cb) {
52
+ if (currentContext) {
53
+ currentContext.onUnmount(cb);
54
+ } else {
55
+ console.error("missing current context");
67
56
  }
68
57
  }
69
- function identity(value1, value2) {
70
- return value1 === value2;
58
+
59
+ // src/create-element/create-text-element.ts
60
+ function createTextElement(text) {
61
+ const mountHandlers = [];
62
+ const unmountHandlers = [];
63
+ return {
64
+ velesStringElement: true,
65
+ // in case there is no text, we create an empty Text node, so we still can
66
+ // have a reference to it, replace it, call lifecycle methods, etc
67
+ html: document.createTextNode(text || ""),
68
+ _privateMethods: {
69
+ _addMountHandler(cb) {
70
+ mountHandlers.push(cb);
71
+ },
72
+ _callMountHandlers() {
73
+ mountHandlers.forEach((cb) => cb());
74
+ },
75
+ _addUnmountHandler: (cb) => {
76
+ unmountHandlers.push(cb);
77
+ },
78
+ _callUnmountHandlers: () => {
79
+ unmountHandlers.forEach((cb) => cb());
80
+ }
81
+ }
82
+ };
71
83
  }
72
- function unique(arr) {
73
- const map = /* @__PURE__ */ new Map();
74
- const resultArr = [];
75
- arr.forEach((element) => {
76
- if (map.has(element))
77
- return;
78
- map.set(element, true);
79
- resultArr.push(element);
80
- });
81
- return resultArr;
84
+
85
+ // src/create-element/parse-component.ts
86
+ function parseComponent({
87
+ element,
88
+ props
89
+ }) {
90
+ const mountCbs = [];
91
+ const unmountCbs = [];
92
+ return {
93
+ velesComponentObject: true,
94
+ element,
95
+ props,
96
+ _privateMethods: {
97
+ _addMountHandler(cb) {
98
+ mountCbs.push(cb);
99
+ },
100
+ _addUnmountHandler: (cb) => {
101
+ unmountCbs.push(cb);
102
+ },
103
+ _callMountHandlers: () => {
104
+ mountCbs.forEach((cb) => cb());
105
+ },
106
+ _callUnmountHandlers: () => {
107
+ unmountCbs.forEach((cb) => cb());
108
+ }
109
+ }
110
+ };
111
+ }
112
+ function executeComponent({
113
+ element,
114
+ props
115
+ }) {
116
+ let componentUnmountCbs = [];
117
+ let componentMountCbs = [];
118
+ const componentAPI = {
119
+ onMount: (cb) => {
120
+ componentMountCbs.push(cb);
121
+ },
122
+ onUnmount: (cb) => {
123
+ componentUnmountCbs.push(cb);
124
+ }
125
+ };
126
+ addContext(componentAPI);
127
+ const _componentTree = element(props, componentAPI);
128
+ const componentTree = typeof _componentTree === "string" || !_componentTree ? createTextElement(_componentTree) : _componentTree;
129
+ popContext();
130
+ const velesComponent = {
131
+ velesComponent: true,
132
+ tree: componentTree,
133
+ _privateMethods: {
134
+ _addMountHandler(cb) {
135
+ componentMountCbs.push(cb);
136
+ },
137
+ _addUnmountHandler: (cb) => {
138
+ componentAPI.onUnmount(cb);
139
+ },
140
+ _callMountHandlers: () => {
141
+ componentMountCbs.forEach((cb) => {
142
+ const mountCbResult = cb();
143
+ if (typeof mountCbResult === "function") {
144
+ componentAPI.onUnmount(mountCbResult);
145
+ }
146
+ });
147
+ },
148
+ _callUnmountHandlers: () => {
149
+ componentUnmountCbs.forEach((cb) => cb());
150
+ }
151
+ }
152
+ };
153
+ return velesComponent;
82
154
  }
83
155
 
84
156
  // src/create-element/parse-children.ts
@@ -91,30 +163,36 @@ function parseChildren({
91
163
  if (children === void 0 || children === null) {
92
164
  return childComponents;
93
165
  }
166
+ let lastInsertedNode = null;
94
167
  (Array.isArray(children) ? children : [children]).forEach(
95
168
  (childComponent) => {
96
169
  if (typeof childComponent === "string") {
97
- const text = document.createTextNode(childComponent);
98
- htmlElement.append(text);
170
+ const textNode = createTextElement(childComponent);
171
+ htmlElement.append(textNode.html);
172
+ lastInsertedNode = textNode.html;
173
+ childComponents.push(textNode);
99
174
  } else if (typeof childComponent === "number") {
100
- const text = document.createTextNode(String(childComponent));
101
- htmlElement.append(text);
175
+ const textNode = createTextElement(String(childComponent));
176
+ htmlElement.append(textNode.html);
177
+ lastInsertedNode = textNode.html;
178
+ childComponents.push(textNode);
102
179
  } else if (typeof childComponent === "object" && childComponent && "velesNode" in childComponent && (childComponent == null ? void 0 : childComponent.velesNode)) {
103
180
  if (childComponent.phantom) {
104
181
  childComponent.childComponents.forEach((childComponentofPhantom) => {
105
182
  if ("velesNode" in childComponentofPhantom) {
106
183
  htmlElement.append(childComponentofPhantom.html);
107
184
  childComponentofPhantom.parentVelesElement = velesNode;
108
- } else {
109
- const { velesElementNode } = getComponentVelesNode(
110
- childComponentofPhantom
111
- );
185
+ lastInsertedNode = childComponentofPhantom.html;
186
+ } else if ("velesStringElement" in childComponentofPhantom) {
187
+ const velesElementNode = childComponentofPhantom;
112
188
  if (!velesElementNode) {
113
189
  console.error("can't find HTML tree in a component chain");
114
190
  } else {
115
191
  htmlElement.append(velesElementNode.html);
192
+ lastInsertedNode = velesElementNode.html;
116
193
  velesElementNode.parentVelesElement = velesNode;
117
194
  }
195
+ } else {
118
196
  }
119
197
  });
120
198
  childComponent.parentVelesElement = velesNode;
@@ -123,39 +201,18 @@ function parseChildren({
123
201
  htmlElement.append(childComponent.html);
124
202
  childComponent.parentVelesElement = velesNode;
125
203
  childComponents.push(childComponent);
204
+ lastInsertedNode = childComponent.html;
126
205
  }
127
- } else if (typeof childComponent === "object" && childComponent && "velesComponent" in childComponent && (childComponent == null ? void 0 : childComponent.velesComponent)) {
128
- const { componentsTree, velesElementNode } = getComponentVelesNode(childComponent);
129
- if (!velesElementNode) {
130
- console.error("can't find HTML tree in a component chain");
131
- } else {
132
- if ("velesNode" in velesElementNode && velesElementNode.phantom) {
133
- velesElementNode.childComponents.forEach(
134
- (childComponentofPhantom) => {
135
- if ("velesNode" in childComponentofPhantom) {
136
- htmlElement.append(childComponentofPhantom.html);
137
- childComponentofPhantom.parentVelesElement = velesNode;
138
- } else {
139
- const { componentsTree: componentsTree2, velesElementNode: velesElementNode2 } = getComponentVelesNode(childComponentofPhantom);
140
- if (!velesElementNode2) {
141
- console.error("can't find HTML tree in a component chain");
142
- } else {
143
- htmlElement.append(velesElementNode2.html);
144
- velesElementNode2.parentVelesElement = velesNode;
145
- }
146
- }
147
- }
148
- );
149
- } else {
150
- htmlElement.append(velesElementNode.html);
151
- }
152
- velesElementNode.parentVelesElement = velesNode;
153
- childComponents.push(childComponent);
154
- }
206
+ } else if (typeof childComponent === "object" && childComponent && "velesComponentObject" in childComponent) {
207
+ childComponent.insertAfter = lastInsertedNode;
208
+ childComponent.parentVelesElement = velesNode;
209
+ childComponents.push(childComponent);
210
+ lastInsertedNode = childComponent;
155
211
  } else if (typeof childComponent === "object" && childComponent && "velesStringElement" in childComponent && (childComponent == null ? void 0 : childComponent.velesStringElement)) {
156
212
  htmlElement.append(childComponent.html);
157
213
  childComponent.parentVelesElement = velesNode;
158
214
  childComponents.push(childComponent);
215
+ lastInsertedNode = childComponent.html;
159
216
  }
160
217
  }
161
218
  );
@@ -172,95 +229,30 @@ function assignAttributes({
172
229
  const isFunction = typeof value === "function";
173
230
  if (isFunction && value.velesAttribute === true) {
174
231
  const attributeValue = value(htmlElement, key, velesNode);
175
- htmlElement.setAttribute(key, attributeValue);
176
- } else if (
177
- // basically, any form of `on` handlers, like `onClick`, `onCopy`, etc
178
- isFunction && key.length > 2 && key.startsWith("on")
179
- ) {
180
- htmlElement.addEventListener(
181
- key[2].toLocaleLowerCase() + key.slice(3),
182
- value
183
- );
232
+ assignAttribute({ key, value: attributeValue, htmlElement });
184
233
  } else {
185
- htmlElement.setAttribute(key, value);
234
+ assignAttribute({ key, value, htmlElement });
186
235
  }
187
236
  });
188
237
  }
189
-
190
- // src/hooks/lifecycle.ts
191
- var contextStack = [];
192
- var currentContext = null;
193
- function addContext(newContext) {
194
- contextStack.push(newContext);
195
- currentContext = newContext;
196
- }
197
- function popContext() {
198
- contextStack.pop();
199
- currentContext = contextStack[contextStack.length - 1];
200
- }
201
- function onMount(cb) {
202
- if (currentContext) {
203
- currentContext.onMount(cb);
204
- } else {
205
- console.error("missing current context");
206
- }
207
- }
208
- function onUnmount(cb) {
209
- if (currentContext) {
210
- currentContext.onUnmount(cb);
211
- } else {
212
- console.error("missing current context");
213
- }
214
- }
215
-
216
- // src/create-element/parse-component.ts
217
- function parseComponent({
218
- element,
219
- props
238
+ function assignAttribute({
239
+ key,
240
+ value,
241
+ htmlElement
220
242
  }) {
221
- const componentUnmountCbs = [];
222
- const componentMountCbs = [];
223
- const componentAPI = {
224
- onMount: (cb) => {
225
- componentMountCbs.push(cb);
226
- },
227
- onUnmount: (cb) => {
228
- componentUnmountCbs.push(cb);
229
- }
230
- };
231
- addContext(componentAPI);
232
- const _componentTree = element(props, componentAPI);
233
- const componentTree = typeof _componentTree === "string" || !_componentTree ? {
234
- velesStringElement: true,
235
- html: document.createTextNode(
236
- typeof _componentTree === "string" ? _componentTree : ""
237
- )
238
- } : _componentTree;
239
- popContext();
240
- const velesComponent = {
241
- velesComponent: true,
242
- tree: componentTree,
243
- _privateMethods: {
244
- _addUnmountHandler: (cb) => {
245
- componentAPI.onUnmount(cb);
246
- },
247
- _callMountHandlers: () => {
248
- componentMountCbs.forEach((cb) => {
249
- const mountCbResult = cb();
250
- if (typeof mountCbResult === "function") {
251
- componentAPI.onUnmount(mountCbResult);
252
- }
253
- });
254
- },
255
- _callUnmountHandlers: () => {
256
- componentUnmountCbs.forEach((cb) => cb());
257
- if ("_privateMethods" in velesComponent.tree) {
258
- velesComponent.tree._privateMethods._callUnmountHandlers();
259
- }
260
- }
243
+ if (
244
+ // basically, any form of `on` handlers, like `onClick`, `onCopy`, etc
245
+ typeof value === "function" && key.startsWith("on")
246
+ ) {
247
+ htmlElement.addEventListener(key.slice(2).toLocaleLowerCase(), value);
248
+ } else {
249
+ if (typeof value === "boolean") {
250
+ if (value)
251
+ htmlElement.setAttribute(key, "");
252
+ } else {
253
+ htmlElement.setAttribute(key, value);
261
254
  }
262
- };
263
- return velesComponent;
255
+ }
264
256
  }
265
257
 
266
258
  // src/create-element/create-element.ts
@@ -277,23 +269,25 @@ function createElement(element, props = {}) {
277
269
  htmlElement: newElement,
278
270
  velesNode
279
271
  });
280
- let unmountHandlers = [];
281
- const callUnmountHandlers = () => {
282
- unmountHandlers.forEach((cb) => cb());
283
- unmountHandlers = [];
284
- childComponents.forEach((childComponent) => {
285
- childComponent._privateMethods._callUnmountHandlers();
286
- });
287
- };
272
+ const unmountHandlers = [];
288
273
  velesNode.html = newElement;
289
274
  velesNode.velesNode = true;
290
275
  velesNode.childComponents = childComponents;
291
276
  velesNode.phantom = phantom;
277
+ const mountHandlers = [];
292
278
  velesNode._privateMethods = {
293
- _addUnmountHandler: (cb) => {
279
+ _addMountHandler(cb) {
280
+ mountHandlers.push(cb);
281
+ },
282
+ _callMountHandlers() {
283
+ mountHandlers.forEach((cb) => cb());
284
+ },
285
+ _addUnmountHandler(cb) {
294
286
  unmountHandlers.push(cb);
295
287
  },
296
- _callUnmountHandlers: callUnmountHandlers
288
+ _callUnmountHandlers() {
289
+ unmountHandlers.forEach((cb) => cb());
290
+ }
297
291
  };
298
292
  assignAttributes({ props: otherProps, htmlElement: newElement, velesNode });
299
293
  return velesNode;
@@ -305,347 +299,766 @@ function createElement(element, props = {}) {
305
299
  );
306
300
  }
307
301
 
302
+ // src/fragment.ts
303
+ function Fragment({ children }) {
304
+ return createElement("div", {
305
+ phantom: true,
306
+ children
307
+ });
308
+ }
309
+
310
+ // src/context/index.ts
311
+ var publicContextStack = [];
312
+ var contextIdCounter = 1;
313
+ function createContext() {
314
+ const contextId = contextIdCounter++;
315
+ function addContext2(value) {
316
+ const currentContextObject = publicContextStack[publicContextStack.length - 1];
317
+ if (!currentContextObject) {
318
+ console.error("cannot add Context due to missing stack value");
319
+ } else {
320
+ publicContextStack[publicContextStack.length - 1] = {
321
+ ...currentContextObject,
322
+ [contextId]: value
323
+ };
324
+ }
325
+ }
326
+ return {
327
+ Provider: ({ value, children }) => {
328
+ addContext2(value);
329
+ return createElement(Fragment, { children });
330
+ },
331
+ addContext: addContext2,
332
+ readContext: () => {
333
+ const currentContext2 = publicContextStack[publicContextStack.length - 1];
334
+ if (!currentContext2) {
335
+ console.error("no Context currently available");
336
+ } else {
337
+ return currentContext2[contextId];
338
+ }
339
+ }
340
+ };
341
+ }
342
+ function addPublicContext(specificContext) {
343
+ if (specificContext) {
344
+ publicContextStack.push(specificContext);
345
+ } else {
346
+ if (publicContextStack.length === 0) {
347
+ publicContextStack.push({});
348
+ } else {
349
+ const currentContext2 = publicContextStack[publicContextStack.length - 1];
350
+ publicContextStack.push(currentContext2);
351
+ }
352
+ }
353
+ }
354
+ function popPublicContext() {
355
+ publicContextStack.pop();
356
+ }
357
+ function getCurrentContext() {
358
+ return publicContextStack[publicContextStack.length - 1];
359
+ }
360
+
361
+ // src/_utils.ts
362
+ function getExecutedComponentVelesNode(component) {
363
+ if ("executedVelesStringElement" in component) {
364
+ return component;
365
+ }
366
+ let childNode = component;
367
+ while ("executedVelesComponent" in childNode) {
368
+ if ("executedVelesStringElement" in childNode.tree) {
369
+ return childNode.tree;
370
+ } else {
371
+ childNode = childNode.tree;
372
+ }
373
+ }
374
+ return childNode;
375
+ }
376
+ function renderTree(component, { parentVelesElement } = {}) {
377
+ if ("velesStringElement" in component) {
378
+ const executedString = {
379
+ executedVelesStringElement: true,
380
+ _privateMethods: component._privateMethods,
381
+ html: component.html,
382
+ parentVelesElement
383
+ };
384
+ if (component.needExecutedVersion) {
385
+ component.executedVersion = executedString;
386
+ }
387
+ return executedString;
388
+ } else if ("velesComponentObject" in component) {
389
+ addPublicContext();
390
+ const componentTree = executeComponent(component);
391
+ const executedComponent = {};
392
+ executedComponent.executedVelesComponent = true;
393
+ executedComponent.tree = renderTree(componentTree.tree);
394
+ popPublicContext();
395
+ executedComponent._privateMethods = {
396
+ ...componentTree._privateMethods,
397
+ _callMountHandlers: () => {
398
+ component._privateMethods._callMountHandlers();
399
+ componentTree._privateMethods._callMountHandlers();
400
+ },
401
+ _callUnmountHandlers: () => {
402
+ component._privateMethods._callUnmountHandlers();
403
+ componentTree._privateMethods._callUnmountHandlers();
404
+ }
405
+ };
406
+ const newNode = getExecutedComponentVelesNode(executedComponent);
407
+ if (parentVelesElement) {
408
+ if (component.insertAfter) {
409
+ if ("velesComponentObject" in component.insertAfter) {
410
+ const lastNode = insertNode({
411
+ velesElement: newNode,
412
+ adjacentNode: component.insertAfter.html,
413
+ parentVelesElement
414
+ });
415
+ component.html = lastNode;
416
+ } else {
417
+ const lastNode = insertNode({
418
+ velesElement: newNode,
419
+ adjacentNode: component.insertAfter,
420
+ parentVelesElement
421
+ });
422
+ component.html = lastNode;
423
+ }
424
+ } else {
425
+ const lastNode = insertNode({
426
+ velesElement: newNode,
427
+ // it means we are inserting the first element
428
+ adjacentNode: null,
429
+ parentVelesElement
430
+ });
431
+ component.html = lastNode;
432
+ }
433
+ newNode.parentVelesElement = parentVelesElement;
434
+ }
435
+ if (component.needExecutedVersion) {
436
+ component.executedVersion = executedComponent;
437
+ }
438
+ return executedComponent;
439
+ } else if ("velesNode" in component) {
440
+ const executedNode = {};
441
+ executedNode.executedVelesNode = true;
442
+ executedNode._privateMethods = component._privateMethods;
443
+ executedNode.html = component.html;
444
+ if (parentVelesElement) {
445
+ executedNode.parentVelesElement = parentVelesElement;
446
+ }
447
+ if (component.phantom) {
448
+ executedNode.phantom = component.phantom;
449
+ }
450
+ executedNode.childComponents = component.childComponents.map(
451
+ (childComponent) => renderTree(childComponent, { parentVelesElement: executedNode })
452
+ );
453
+ if (component.needExecutedVersion) {
454
+ component.executedVersion = executedNode;
455
+ }
456
+ return executedNode;
457
+ }
458
+ }
459
+ function insertNode({
460
+ velesElement,
461
+ adjacentNode,
462
+ parentVelesElement
463
+ }) {
464
+ if (velesElement.phantom) {
465
+ let lastInsertedNode = null;
466
+ velesElement.childComponents.forEach(
467
+ (childComponentofPhantom) => {
468
+ if ("executedVelesNode" in childComponentofPhantom) {
469
+ if (lastInsertedNode) {
470
+ lastInsertedNode.after(childComponentofPhantom.html);
471
+ } else {
472
+ if (adjacentNode) {
473
+ adjacentNode.after(childComponentofPhantom.html);
474
+ } else {
475
+ parentVelesElement.html.prepend(childComponentofPhantom.html);
476
+ }
477
+ }
478
+ childComponentofPhantom.parentVelesElement = parentVelesElement;
479
+ lastInsertedNode = childComponentofPhantom.html;
480
+ } else if ("executedVelesStringElement" in childComponentofPhantom) {
481
+ if (lastInsertedNode) {
482
+ lastInsertedNode.after(childComponentofPhantom.html);
483
+ } else {
484
+ if (adjacentNode) {
485
+ adjacentNode.after(childComponentofPhantom.html);
486
+ } else {
487
+ parentVelesElement.html.prepend(childComponentofPhantom.html);
488
+ }
489
+ }
490
+ childComponentofPhantom.parentVelesElement = parentVelesElement;
491
+ lastInsertedNode = childComponentofPhantom.html;
492
+ } else {
493
+ const executedNode = getExecutedComponentVelesNode(
494
+ childComponentofPhantom
495
+ );
496
+ if (lastInsertedNode) {
497
+ lastInsertedNode.after(executedNode.html);
498
+ } else {
499
+ if (adjacentNode) {
500
+ adjacentNode.after(executedNode.html);
501
+ } else {
502
+ parentVelesElement.html.prepend(executedNode.html);
503
+ }
504
+ }
505
+ executedNode.parentVelesElement = parentVelesElement;
506
+ lastInsertedNode = executedNode.html;
507
+ }
508
+ }
509
+ );
510
+ velesElement.parentVelesElement = parentVelesElement;
511
+ return lastInsertedNode;
512
+ } else {
513
+ if (adjacentNode) {
514
+ adjacentNode.after(velesElement.html);
515
+ } else {
516
+ parentVelesElement.html.prepend(velesElement.html);
517
+ }
518
+ velesElement.parentVelesElement = parentVelesElement;
519
+ return velesElement.html;
520
+ }
521
+ }
522
+ function callMountHandlers(component) {
523
+ component._privateMethods._callMountHandlers();
524
+ if ("executedVelesStringElement" in component) {
525
+ return;
526
+ }
527
+ if ("executedVelesComponent" in component) {
528
+ callMountHandlers(component.tree);
529
+ }
530
+ if ("executedVelesNode" in component) {
531
+ component.childComponents.forEach(
532
+ (childComponent) => callMountHandlers(childComponent)
533
+ );
534
+ }
535
+ }
536
+ function callUnmountHandlers(component) {
537
+ if ("executedVelesStringElement" in component) {
538
+ } else if ("executedVelesComponent" in component) {
539
+ callUnmountHandlers(component.tree);
540
+ } else if ("executedVelesNode" in component) {
541
+ component.childComponents.forEach(
542
+ (childComponent) => callUnmountHandlers(childComponent)
543
+ );
544
+ }
545
+ component._privateMethods._callUnmountHandlers();
546
+ }
547
+ function identity(value1, value2) {
548
+ return value1 === value2;
549
+ }
550
+ function unique(arr) {
551
+ const map = /* @__PURE__ */ new Map();
552
+ const resultArr = [];
553
+ arr.forEach((element) => {
554
+ if (map.has(element))
555
+ return;
556
+ map.set(element, true);
557
+ resultArr.push(element);
558
+ });
559
+ return resultArr;
560
+ }
561
+
308
562
  // src/attach-component.ts
309
563
  function attachComponent({
310
564
  htmlElement,
311
565
  component
312
566
  }) {
313
567
  const wrappedApp = createElement("div", { children: [component] });
314
- const { velesElementNode } = getComponentVelesNode(wrappedApp);
568
+ const wrappedAppTree = renderTree(wrappedApp);
569
+ const velesElementNode = getExecutedComponentVelesNode(wrappedAppTree);
315
570
  htmlElement.appendChild(velesElementNode.html);
316
- callMountHandlers(wrappedApp);
571
+ callMountHandlers(wrappedAppTree);
317
572
  return () => {
573
+ callUnmountHandlers(wrappedAppTree);
318
574
  velesElementNode.html.remove();
319
575
  };
320
576
  }
321
577
 
322
- // src/create-element/create-text-element.ts
323
- function createTextElement(text) {
324
- const unmountHandlers = [];
325
- return {
326
- velesStringElement: true,
327
- // in case there is no text, we create an empty Text node, so we still can
328
- // have a reference to it, replace it, call lifecycle methods, etc
329
- html: document.createTextNode(text || ""),
330
- _privateMethods: {
331
- _addUnmountHandler: (cb) => {
332
- unmountHandlers.push(cb);
333
- },
334
- _callUnmountHandlers: () => {
335
- unmountHandlers.forEach((cb) => cb());
336
- }
337
- }
578
+ // src/create-state/update-usevalue-selector-value.ts
579
+ function updateUseValueSelector({
580
+ value,
581
+ selectorTrackingElement,
582
+ newTrackingSelectorElements,
583
+ trackers,
584
+ getValue
585
+ }) {
586
+ const { selectedValue, selector, cb, node, comparator, savedContext } = selectorTrackingElement;
587
+ const newSelectedValue = selector ? selector(value) : value;
588
+ if (comparator(selectedValue, newSelectedValue)) {
589
+ newTrackingSelectorElements.push(selectorTrackingElement);
590
+ return;
591
+ }
592
+ addPublicContext(savedContext);
593
+ const returnednewNode = cb ? cb(newSelectedValue) : newSelectedValue == void 0 ? "" : String(newSelectedValue);
594
+ const newNode = !returnednewNode || typeof returnednewNode === "string" ? createTextElement(returnednewNode) : returnednewNode;
595
+ const newRenderedNode = renderTree(newNode);
596
+ popPublicContext();
597
+ newNode.executedVersion = newRenderedNode;
598
+ if (!node.executedVersion) {
599
+ console.error("the node was not mounted");
600
+ return;
601
+ }
602
+ const oldVelesElementNode = getExecutedComponentVelesNode(
603
+ node.executedVersion
604
+ );
605
+ const newVelesElementNode = getExecutedComponentVelesNode(newRenderedNode);
606
+ const parentVelesElement = node.parentVelesElement;
607
+ const parentVelesElementRendered = oldVelesElementNode.parentVelesElement;
608
+ const newTrackingSelectorElement = {
609
+ selector,
610
+ selectedValue: newSelectedValue,
611
+ cb,
612
+ node: newNode,
613
+ comparator,
614
+ savedContext
338
615
  };
339
- }
340
-
341
- // src/hooks/create-state.ts
342
- function createState(initialValue, subscribeCallback) {
343
- let value = initialValue;
344
- let previousValue = void 0;
345
- let trackingEffects = [];
346
- let trackingSelectorElements = [];
347
- let trackingAttributes = [];
348
- let trackingIterators = [];
349
- const _triggerUpdates = () => {
350
- const newTrackingSelectorElements = [];
351
- trackingSelectorElements.forEach((selectorTrackingElement) => {
352
- const { selectedValue, selector, cb, node, comparator } = selectorTrackingElement;
353
- const newSelectedValue = selector ? selector(value) : value;
354
- if (comparator(selectedValue, newSelectedValue)) {
355
- newTrackingSelectorElements.push(selectorTrackingElement);
356
- return;
357
- }
358
- const returnednewNode = cb ? cb(newSelectedValue) : String(newSelectedValue);
359
- const newNode = !returnednewNode || typeof returnednewNode === "string" ? createTextElement(returnednewNode) : returnednewNode;
360
- const { velesElementNode: oldVelesElementNode } = getComponentVelesNode(node);
361
- const { velesElementNode: newVelesElementNode } = getComponentVelesNode(newNode);
362
- const parentVelesElement = oldVelesElementNode.parentVelesElement;
363
- const newTrackingSelectorElement = {
364
- selector,
365
- selectedValue: newSelectedValue,
366
- cb,
367
- node: newNode,
368
- comparator
616
+ if (parentVelesElementRendered) {
617
+ newNode.parentVelesElement = parentVelesElement;
618
+ newVelesElementNode.parentVelesElement = parentVelesElementRendered;
619
+ if ("executedVelesNode" in newVelesElementNode && newVelesElementNode.phantom) {
620
+ const insertAllPhantomChildren = (adjacentNode) => {
621
+ newVelesElementNode.childComponents.forEach(
622
+ (childComponentofPhantom) => {
623
+ if ("executedVelesNode" in childComponentofPhantom) {
624
+ adjacentNode.html.before(childComponentofPhantom.html);
625
+ childComponentofPhantom.parentVelesElement = adjacentNode.parentVelesElement;
626
+ } else {
627
+ const velesElementNode = getExecutedComponentVelesNode(
628
+ childComponentofPhantom
629
+ );
630
+ if (!velesElementNode) {
631
+ console.error("can't find HTML tree in a component chain");
632
+ } else {
633
+ adjacentNode.html.before(velesElementNode.html);
634
+ velesElementNode.parentVelesElement = adjacentNode.parentVelesElement;
635
+ }
636
+ }
637
+ }
638
+ );
369
639
  };
370
- if (parentVelesElement) {
371
- newVelesElementNode.parentVelesElement = parentVelesElement;
372
- if ("velesNode" in newVelesElementNode && newVelesElementNode.phantom) {
373
- const insertAllPhantomChildren = (adjacentNode) => {
374
- newVelesElementNode.childComponents.forEach(
375
- (childComponentofPhantom) => {
376
- if ("velesNode" in childComponentofPhantom) {
377
- adjacentNode.html.before(childComponentofPhantom.html);
378
- childComponentofPhantom.parentVelesElement = adjacentNode.parentVelesElement;
379
- } else {
380
- const { velesElementNode } = getComponentVelesNode(
381
- childComponentofPhantom
382
- );
383
- if (!velesElementNode) {
384
- console.error("can't find HTML tree in a component chain");
385
- } else {
386
- adjacentNode.html.before(velesElementNode.html);
387
- velesElementNode.parentVelesElement = adjacentNode.parentVelesElement;
388
- }
389
- }
640
+ if ("executedVelesNode" in oldVelesElementNode && oldVelesElementNode.phantom) {
641
+ let isInserted = false;
642
+ oldVelesElementNode.childComponents.forEach(
643
+ (childComponentofPhantom) => {
644
+ if ("executedVelesNode" in childComponentofPhantom) {
645
+ if (!isInserted) {
646
+ insertAllPhantomChildren(childComponentofPhantom);
647
+ isInserted = true;
390
648
  }
391
- );
392
- };
393
- if ("velesNode" in oldVelesElementNode && oldVelesElementNode.phantom) {
394
- let isInserted = false;
395
- oldVelesElementNode.childComponents.forEach(
396
- (childComponentofPhantom) => {
397
- if ("velesNode" in childComponentofPhantom) {
398
- if (!isInserted) {
399
- insertAllPhantomChildren(childComponentofPhantom);
400
- isInserted = true;
401
- }
402
- childComponentofPhantom.html.remove();
403
- } else {
404
- const { velesElementNode } = getComponentVelesNode(
405
- childComponentofPhantom
406
- );
407
- if (!velesElementNode) {
408
- console.error("can't find HTML tree in a component chain");
409
- } else {
410
- if (!isInserted) {
411
- insertAllPhantomChildren(velesElementNode);
412
- isInserted = true;
413
- }
414
- velesElementNode.html.remove();
415
- }
649
+ childComponentofPhantom.html.remove();
650
+ } else {
651
+ const velesElementNode = getExecutedComponentVelesNode(
652
+ childComponentofPhantom
653
+ );
654
+ if (!velesElementNode) {
655
+ console.error("can't find HTML tree in a component chain");
656
+ } else {
657
+ if (!isInserted) {
658
+ insertAllPhantomChildren(velesElementNode);
659
+ isInserted = true;
416
660
  }
661
+ velesElementNode.html.remove();
417
662
  }
418
- );
419
- } else {
420
- insertAllPhantomChildren(oldVelesElementNode);
421
- oldVelesElementNode.html.remove();
663
+ }
422
664
  }
423
- } else {
424
- if ("velesNode" in oldVelesElementNode && oldVelesElementNode.phantom) {
425
- let isInserted = false;
426
- oldVelesElementNode.childComponents.forEach(
427
- (childComponentofPhantom) => {
428
- if ("velesNode" in childComponentofPhantom) {
429
- if (!isInserted) {
430
- childComponentofPhantom.html.before(
431
- newVelesElementNode.html
432
- );
433
- isInserted = true;
434
- }
435
- childComponentofPhantom.html.remove();
436
- } else {
437
- const { velesElementNode } = getComponentVelesNode(
438
- childComponentofPhantom
439
- );
440
- if (!velesElementNode) {
441
- console.error("can't find HTML tree in a component chain");
442
- } else {
443
- if (!isInserted) {
444
- velesElementNode.html.before(newVelesElementNode.html);
445
- isInserted = true;
446
- }
447
- velesElementNode.html.remove();
448
- }
665
+ );
666
+ } else {
667
+ insertAllPhantomChildren(oldVelesElementNode);
668
+ oldVelesElementNode.html.remove();
669
+ }
670
+ } else {
671
+ if ("executedVelesNode" in oldVelesElementNode && oldVelesElementNode.phantom) {
672
+ let isInserted = false;
673
+ oldVelesElementNode.childComponents.forEach(
674
+ (childComponentofPhantom) => {
675
+ if ("executedVelesNode" in childComponentofPhantom) {
676
+ if (!isInserted) {
677
+ childComponentofPhantom.html.before(newVelesElementNode.html);
678
+ isInserted = true;
679
+ }
680
+ childComponentofPhantom.html.remove();
681
+ } else {
682
+ const velesElementNode = getExecutedComponentVelesNode(
683
+ childComponentofPhantom
684
+ );
685
+ if (!velesElementNode) {
686
+ console.error("can't find HTML tree in a component chain");
687
+ } else {
688
+ if (!isInserted) {
689
+ velesElementNode.html.before(newVelesElementNode.html);
690
+ isInserted = true;
449
691
  }
692
+ velesElementNode.html.remove();
450
693
  }
451
- );
452
- } else {
453
- parentVelesElement.html.replaceChild(
454
- newVelesElementNode.html,
455
- oldVelesElementNode.html
456
- );
694
+ }
457
695
  }
458
- }
459
- parentVelesElement.childComponents = parentVelesElement.childComponents.map(
460
- (childComponent) => childComponent === node ? newNode : node
461
696
  );
462
- node._privateMethods._callUnmountHandlers();
463
- callMountHandlers(newNode);
464
- newNode._privateMethods._addUnmountHandler(() => {
465
- trackingSelectorElements = trackingSelectorElements.filter(
466
- (el) => el !== newTrackingSelectorElement
467
- );
468
- });
469
697
  } else {
470
- console.log("parent node was not found");
698
+ try {
699
+ parentVelesElementRendered.html.replaceChild(
700
+ newVelesElementNode.html,
701
+ oldVelesElementNode.html
702
+ );
703
+ } catch (e) {
704
+ console.error("failed to update...");
705
+ console.log(document.body.innerHTML);
706
+ console.log(oldVelesElementNode.parentVelesElement.html.innerHTML);
707
+ console.log(
708
+ //@ts-expect-error
709
+ oldVelesElementNode.parentVelesElement.childComponents[0].html.textContent
710
+ );
711
+ }
471
712
  }
472
- newTrackingSelectorElements.push(newTrackingSelectorElement);
473
- });
474
- trackingSelectorElements = unique(
475
- trackingSelectorElements.concat(newTrackingSelectorElements)
713
+ }
714
+ parentVelesElementRendered.childComponents = parentVelesElementRendered.childComponents.map(
715
+ (childComponent) => childComponent === node.executedVersion ? newRenderedNode : childComponent
476
716
  );
477
- trackingAttributes.forEach(({ cb, htmlElement, attributeName }) => {
478
- const newAttributeValue = cb ? cb(value) : value;
479
- htmlElement.setAttribute(attributeName, newAttributeValue);
717
+ if (parentVelesElement == null ? void 0 : parentVelesElement.childComponents) {
718
+ parentVelesElement.childComponents = parentVelesElement.childComponents.map(
719
+ (childComponent) => childComponent === node ? newNode : childComponent
720
+ );
721
+ }
722
+ callUnmountHandlers(node.executedVersion);
723
+ addUseValueMountHandler({
724
+ usedValue: value,
725
+ trackers,
726
+ getValue,
727
+ trackingSelectorElement: newTrackingSelectorElement
480
728
  });
481
- trackingEffects.forEach((trackingEffect) => {
482
- const { cb, selectedValue, selector, comparator } = trackingEffect;
483
- const newSelectedValue = selector ? selector(value) : value;
484
- if (comparator ? comparator(selectedValue, newSelectedValue) : selectedValue === newSelectedValue) {
485
- return;
486
- }
487
- cb(newSelectedValue);
488
- trackingEffect.selectedValue = newSelectedValue;
729
+ callMountHandlers(newRenderedNode);
730
+ newNode._privateMethods._addUnmountHandler(() => {
731
+ trackers.trackingSelectorElements = trackers.trackingSelectorElements.filter(
732
+ (el) => el !== newTrackingSelectorElement
733
+ );
489
734
  });
490
- trackingIterators.forEach((trackingIterator) => {
491
- const {
492
- cb,
493
- key,
494
- renderedElements,
495
- elementsByKey,
496
- wrapperComponent,
497
- selector
498
- } = trackingIterator;
499
- if (!wrapperComponent) {
500
- console.error("there is no wrapper component for the iterator");
501
- return;
735
+ } else {
736
+ console.log("parent node was not found");
737
+ }
738
+ newTrackingSelectorElements.push(newTrackingSelectorElement);
739
+ }
740
+ function addUseValueMountHandler({
741
+ usedValue,
742
+ getValue,
743
+ trackers,
744
+ trackingSelectorElement
745
+ }) {
746
+ trackingSelectorElement.node._privateMethods._addMountHandler(() => {
747
+ const currentValue = getValue();
748
+ if (usedValue === currentValue) {
749
+ trackers.trackingSelectorElements.push(trackingSelectorElement);
750
+ trackingSelectorElement.node._privateMethods._addUnmountHandler(() => {
751
+ trackers.trackingSelectorElements = trackers.trackingSelectorElements.filter(
752
+ (el) => trackingSelectorElement !== el
753
+ );
754
+ });
755
+ } else {
756
+ const newTrackingSelectorElements = [];
757
+ updateUseValueSelector({
758
+ value: getValue(),
759
+ trackers,
760
+ selectorTrackingElement: trackingSelectorElement,
761
+ newTrackingSelectorElements,
762
+ getValue
763
+ });
764
+ if (newTrackingSelectorElements[0]) {
765
+ const newTrackingSelectorElement = newTrackingSelectorElements[0];
766
+ if (newTrackingSelectorElement.node === trackingSelectorElement.node) {
767
+ trackers.trackingSelectorElements.push(newTrackingSelectorElement);
768
+ newTrackingSelectorElement.node._privateMethods._addUnmountHandler(
769
+ () => {
770
+ trackers.trackingSelectorElements = trackers.trackingSelectorElements.filter(
771
+ (el) => trackingSelectorElement !== el
772
+ );
773
+ }
774
+ );
775
+ } else {
776
+ }
777
+ } else {
778
+ }
779
+ }
780
+ });
781
+ }
782
+
783
+ // src/create-state/update-useattribute-value.ts
784
+ function updateUseAttributeValue({
785
+ element,
786
+ value
787
+ }) {
788
+ const { cb, htmlElement, attributeName, attributeValue } = element;
789
+ const newAttributeValue = cb ? cb(value) : value;
790
+ if (typeof newAttributeValue === "boolean") {
791
+ if (newAttributeValue) {
792
+ htmlElement.setAttribute(attributeName, "");
793
+ } else {
794
+ htmlElement.removeAttribute(attributeName);
795
+ }
796
+ } else if (attributeName.startsWith("on")) {
797
+ if (attributeValue === newAttributeValue) {
798
+ return;
799
+ }
800
+ const eventName = attributeName.slice(2).toLocaleLowerCase();
801
+ if (attributeValue) {
802
+ htmlElement.removeEventListener(eventName, attributeValue);
803
+ }
804
+ if (newAttributeValue && typeof newAttributeValue === "function") {
805
+ htmlElement.addEventListener(eventName, newAttributeValue);
806
+ }
807
+ element.attributeValue = newAttributeValue;
808
+ } else {
809
+ htmlElement.setAttribute(attributeName, newAttributeValue);
810
+ }
811
+ }
812
+
813
+ // src/create-state/update-usevalueiterator-value.ts
814
+ function updateUseValueIteratorValue({
815
+ value,
816
+ trackingIterator,
817
+ createState: createState2
818
+ }) {
819
+ const {
820
+ cb,
821
+ key,
822
+ renderedElements,
823
+ elementsByKey,
824
+ wrapperComponent,
825
+ selector,
826
+ savedContext
827
+ } = trackingIterator;
828
+ if (!wrapperComponent) {
829
+ console.error("there is no wrapper component for the iterator");
830
+ return;
831
+ }
832
+ if (!wrapperComponent.executedVersion) {
833
+ console.error("it seems the wrapper component was not mounted");
834
+ return;
835
+ }
836
+ const wrapperVelesElementNode = getExecutedComponentVelesNode(
837
+ wrapperComponent.executedVersion
838
+ );
839
+ const parentVelesElement = wrapperVelesElementNode.parentVelesElement;
840
+ if (!parentVelesElement) {
841
+ console.error("there is no parent Veles node for the iterator wrapper");
842
+ return;
843
+ }
844
+ const elements = selector ? selector(value) : value;
845
+ if (Array.isArray(elements)) {
846
+ const newRenderedElements = [];
847
+ const newElementsByKey = {};
848
+ const renderedExistingElements = {};
849
+ elements.forEach((element, index) => {
850
+ let calculatedKey = "";
851
+ if (typeof key === "string" && typeof element === "object" && element !== null && key in element) {
852
+ calculatedKey = element[key];
853
+ } else if (typeof key === "function") {
854
+ calculatedKey = key({ element, index });
855
+ } else {
502
856
  }
503
- const { velesElementNode: wrapperVelesElementNode } = getComponentVelesNode(wrapperComponent);
504
- const parentVelesElement = wrapperVelesElementNode.parentVelesElement;
505
- if (!parentVelesElement) {
506
- console.error("there is no parent Veles node for the iterator wrapper");
857
+ if (!calculatedKey) {
507
858
  return;
508
859
  }
509
- const elements = selector ? selector(value) : value;
510
- if (Array.isArray(elements)) {
511
- const newRenderedElements = [];
512
- const newElementsByKey = {};
513
- const renderedExistingElements = {};
514
- elements.forEach((element, index) => {
515
- let calculatedKey = "";
516
- if (typeof key === "string" && typeof element === "object" && element !== null && key in element) {
517
- calculatedKey = element[key];
518
- } else if (typeof key === "function") {
519
- calculatedKey = key({ element, index });
520
- } else {
521
- }
522
- if (!calculatedKey) {
523
- return;
524
- }
525
- const existingElement = elementsByKey[calculatedKey];
526
- if (existingElement) {
527
- renderedExistingElements[calculatedKey] = true;
528
- const currentValue = existingElement.elementState.getValue();
529
- if (currentValue !== element) {
530
- existingElement.elementState.setValue(element);
531
- }
532
- const currentIndex = existingElement.indexState.getValue();
533
- if (currentIndex !== index) {
534
- existingElement.indexState.setValue(index);
535
- }
536
- newRenderedElements.push([
537
- existingElement.node,
538
- calculatedKey,
539
- existingElement.elementState
540
- ]);
541
- newElementsByKey[calculatedKey] = {
542
- elementState: existingElement.elementState,
543
- indexState: existingElement.indexState,
544
- indexValue: index,
545
- node: existingElement.node
546
- };
860
+ const existingElement = elementsByKey[calculatedKey];
861
+ if (existingElement) {
862
+ renderedExistingElements[calculatedKey] = true;
863
+ const currentValue = existingElement.elementState.getValue();
864
+ if (currentValue !== element) {
865
+ existingElement.elementState.setValue(element);
866
+ }
867
+ const currentIndex = existingElement.indexState.getValue();
868
+ if (currentIndex !== index) {
869
+ existingElement.indexState.setValue(index);
870
+ }
871
+ newRenderedElements.push([
872
+ existingElement.node,
873
+ calculatedKey,
874
+ existingElement.elementState
875
+ ]);
876
+ newElementsByKey[calculatedKey] = {
877
+ elementState: existingElement.elementState,
878
+ indexState: existingElement.indexState,
879
+ indexValue: index,
880
+ node: existingElement.node
881
+ };
882
+ } else {
883
+ const elementState = createState2(element);
884
+ const indexState = createState2(index);
885
+ addPublicContext(savedContext);
886
+ const node = cb({ elementState, indexState });
887
+ const renderedNode = renderTree(node);
888
+ node.executedVersion = renderedNode;
889
+ popPublicContext();
890
+ newRenderedElements.push([node, calculatedKey, elementState]);
891
+ newElementsByKey[calculatedKey] = {
892
+ elementState,
893
+ indexState,
894
+ indexValue: index,
895
+ node
896
+ };
897
+ }
898
+ });
899
+ const newChildRenderedComponents = [];
900
+ const newChildComponents = [];
901
+ const positioningOffset = {};
902
+ let newElementsCount = 0;
903
+ let offset = 0;
904
+ let currentElement = null;
905
+ newRenderedElements.forEach((newRenderedElement, index) => {
906
+ var _a, _b, _c;
907
+ newChildRenderedComponents.push(newRenderedElement[0].executedVersion);
908
+ newChildComponents.push(newRenderedElement[0]);
909
+ if (positioningOffset[index]) {
910
+ offset = offset + positioningOffset[index];
911
+ }
912
+ const [newNode, calculatedKey, newState] = newRenderedElement;
913
+ const existingElement = elementsByKey[calculatedKey];
914
+ if (existingElement) {
915
+ const existingElementNode = getExecutedComponentVelesNode(
916
+ existingElement.node.executedVersion
917
+ );
918
+ if (existingElement.indexValue + offset === index) {
919
+ currentElement = existingElementNode.html;
920
+ return;
921
+ }
922
+ if (existingElement.indexValue + offset > index) {
923
+ if (currentElement) {
924
+ currentElement.after(existingElementNode.html);
925
+ positioningOffset[existingElement.indexValue + 1] = -1;
547
926
  } else {
548
- const elementState = createState(element);
549
- const indexState = createState(index);
550
- const node = cb({ elementState, indexState });
551
- newRenderedElements.push([node, calculatedKey, elementState]);
552
- newElementsByKey[calculatedKey] = {
553
- elementState,
554
- indexState,
555
- indexValue: index,
556
- node
557
- };
558
- }
559
- });
560
- const positioningOffset = {};
561
- let newElementsCount = 0;
562
- let offset = 0;
563
- let currentElement = null;
564
- newRenderedElements.forEach((newRenderedElement, index) => {
565
- var _a, _b, _c;
566
- if (positioningOffset[index]) {
567
- offset = offset + positioningOffset[index];
568
- }
569
- const [newNode, calculatedKey, newState] = newRenderedElement;
570
- const existingElement = elementsByKey[calculatedKey];
571
- if (existingElement) {
572
- const { velesElementNode: existingElementNode } = getComponentVelesNode(existingElement.node);
573
- if (existingElement.indexValue + offset === index) {
574
- currentElement = existingElementNode.html;
575
- return;
576
- }
577
- if (existingElement.indexValue + offset > index) {
578
- if (currentElement) {
579
- currentElement.after(existingElementNode.html);
580
- positioningOffset[existingElement.indexValue + 1] = -1;
581
- } else {
582
- const firstRenderedElement = (_a = renderedElements[0]) == null ? void 0 : _a[0];
583
- if (firstRenderedElement) {
584
- const { velesElementNode: firstRenderedVelesNode } = getComponentVelesNode(firstRenderedElement);
585
- firstRenderedVelesNode.html.before(existingElementNode.html);
586
- } else {
587
- }
588
- }
589
- currentElement = existingElementNode.html;
590
- offset = offset + 1;
927
+ const firstRenderedElement = (_a = renderedElements[0]) == null ? void 0 : _a[0];
928
+ if (firstRenderedElement == null ? void 0 : firstRenderedElement.executedVersion) {
929
+ const firstRenderedVelesNode = getExecutedComponentVelesNode(
930
+ firstRenderedElement.executedVersion
931
+ );
932
+ firstRenderedVelesNode.html.before(existingElementNode.html);
591
933
  } else {
592
- if (currentElement) {
593
- currentElement.after(existingElementNode.html);
594
- positioningOffset[existingElement.indexValue + 1] = 1;
595
- } else {
596
- const firstRenderedElement = (_b = renderedElements[0]) == null ? void 0 : _b[0];
597
- if (firstRenderedElement) {
598
- const { velesElementNode: firstRenderedVelesNode } = getComponentVelesNode(firstRenderedElement);
599
- firstRenderedVelesNode.html.before(existingElementNode.html);
600
- } else {
601
- }
602
- }
603
- currentElement = existingElementNode.html;
604
- offset = offset - 1;
605
934
  }
935
+ }
936
+ currentElement = existingElementNode.html;
937
+ offset = offset + 1;
938
+ } else {
939
+ if (currentElement) {
940
+ currentElement.after(existingElementNode.html);
941
+ positioningOffset[existingElement.indexValue + 1] = 1;
606
942
  } else {
607
- const { velesElementNode: newNodeVelesElement } = getComponentVelesNode(newNode);
608
- newNodeVelesElement.parentVelesElement = parentVelesElement;
609
- if (currentElement) {
610
- currentElement.after(newNodeVelesElement.html);
943
+ const firstRenderedElement = (_b = renderedElements[0]) == null ? void 0 : _b[0];
944
+ if (firstRenderedElement == null ? void 0 : firstRenderedElement.executedVersion) {
945
+ const firstRenderedVelesNode = getExecutedComponentVelesNode(
946
+ firstRenderedElement.executedVersion
947
+ );
948
+ firstRenderedVelesNode.html.before(existingElementNode.html);
611
949
  } else {
612
- const firstRenderedElement = (_c = renderedElements[0]) == null ? void 0 : _c[0];
613
- if (firstRenderedElement) {
614
- const { velesElementNode: firstRenderedVelesNode } = getComponentVelesNode(firstRenderedElement);
615
- firstRenderedVelesNode.html.before(newNodeVelesElement.html);
616
- } else {
617
- parentVelesElement.html.prepend(newNodeVelesElement.html);
618
- }
619
950
  }
620
- offset = offset + 1;
621
- currentElement = newNodeVelesElement.html;
622
- newElementsCount = newElementsCount + 1;
623
- callMountHandlers(newNode);
624
951
  }
625
- });
626
- if (renderedElements.length === newRenderedElements.length + newElementsCount) {
952
+ currentElement = existingElementNode.html;
953
+ offset = offset - 1;
954
+ }
955
+ } else {
956
+ const newNodeVelesElement = getExecutedComponentVelesNode(
957
+ newNode.executedVersion
958
+ );
959
+ newNodeVelesElement.parentVelesElement = parentVelesElement;
960
+ if (currentElement) {
961
+ currentElement.after(newNodeVelesElement.html);
627
962
  } else {
628
- renderedElements.forEach(([oldNode, calculatedKey]) => {
629
- if (renderedExistingElements[calculatedKey] === true) {
630
- return;
631
- } else {
632
- const { velesElementNode: oldRenderedVelesNode } = getComponentVelesNode(oldNode);
633
- oldRenderedVelesNode.html.remove();
634
- oldNode._privateMethods._callUnmountHandlers();
635
- if ("velesNode" in wrapperVelesElementNode) {
636
- wrapperVelesElementNode.childComponents = wrapperVelesElementNode.childComponents.filter(
637
- (childComponent) => childComponent !== oldNode
638
- );
639
- } else {
640
- throw new Error("Wrapper iterator element is a string");
641
- }
642
- }
643
- });
963
+ const firstRenderedElement = (_c = renderedElements[0]) == null ? void 0 : _c[0];
964
+ if (firstRenderedElement == null ? void 0 : firstRenderedElement.executedVersion) {
965
+ const firstRenderedVelesNode = getExecutedComponentVelesNode(
966
+ firstRenderedElement.executedVersion
967
+ );
968
+ firstRenderedVelesNode.html.before(newNodeVelesElement.html);
969
+ } else {
970
+ parentVelesElement.html.prepend(newNodeVelesElement.html);
971
+ }
644
972
  }
645
- trackingIterator.renderedElements = newRenderedElements;
646
- trackingIterator.elementsByKey = newElementsByKey;
973
+ offset = offset + 1;
974
+ currentElement = newNodeVelesElement.html;
975
+ newElementsCount = newElementsCount + 1;
976
+ callMountHandlers(newNode.executedVersion);
647
977
  }
648
978
  });
979
+ if (renderedElements.length === newRenderedElements.length + newElementsCount) {
980
+ } else {
981
+ renderedElements.forEach(([oldNode, calculatedKey]) => {
982
+ if (renderedExistingElements[calculatedKey] === true) {
983
+ return;
984
+ } else {
985
+ const oldRenderedVelesNode = getExecutedComponentVelesNode(
986
+ oldNode.executedVersion
987
+ );
988
+ oldRenderedVelesNode.html.remove();
989
+ callUnmountHandlers(oldNode.executedVersion);
990
+ if ("executedVelesNode" in wrapperVelesElementNode) {
991
+ wrapperVelesElementNode.childComponents = wrapperVelesElementNode.childComponents.filter(
992
+ (childComponent) => childComponent !== oldNode.executedVersion
993
+ );
994
+ } else {
995
+ throw new Error("Wrapper iterator element is a string");
996
+ }
997
+ if ("velesNode" in wrapperComponent) {
998
+ wrapperComponent.childComponents = wrapperComponent.childComponents.filter(
999
+ (childComponent) => childComponent !== oldNode
1000
+ );
1001
+ }
1002
+ }
1003
+ });
1004
+ }
1005
+ if ("executedVelesNode" in wrapperVelesElementNode) {
1006
+ wrapperVelesElementNode.childComponents = newChildRenderedComponents;
1007
+ }
1008
+ if ("velesNode" in wrapperComponent) {
1009
+ wrapperComponent.childComponents = newChildComponents;
1010
+ }
1011
+ trackingIterator.renderedElements = newRenderedElements;
1012
+ trackingIterator.elementsByKey = newElementsByKey;
1013
+ }
1014
+ }
1015
+
1016
+ // src/create-state/trigger-updates.ts
1017
+ function triggerUpdates({
1018
+ value,
1019
+ createState: createState2,
1020
+ trackers,
1021
+ getValue
1022
+ }) {
1023
+ const newTrackingSelectorElements = [];
1024
+ trackers.trackingSelectorElements.forEach(
1025
+ (selectorTrackingElement) => updateUseValueSelector({
1026
+ value,
1027
+ selectorTrackingElement,
1028
+ newTrackingSelectorElements,
1029
+ trackers,
1030
+ getValue
1031
+ })
1032
+ );
1033
+ trackers.trackingSelectorElements = unique(
1034
+ trackers.trackingSelectorElements.concat(newTrackingSelectorElements)
1035
+ );
1036
+ trackers.trackingAttributes.forEach((element) => {
1037
+ updateUseAttributeValue({ element, value });
1038
+ });
1039
+ trackers.trackingEffects.forEach((trackingEffect) => {
1040
+ const { cb, selectedValue, selector, comparator } = trackingEffect;
1041
+ const newSelectedValue = selector ? selector(value) : value;
1042
+ if (comparator ? comparator(selectedValue, newSelectedValue) : selectedValue === newSelectedValue) {
1043
+ return;
1044
+ }
1045
+ cb(newSelectedValue);
1046
+ trackingEffect.selectedValue = newSelectedValue;
1047
+ });
1048
+ trackers.trackingIterators.forEach((trackingIterator) => {
1049
+ updateUseValueIteratorValue({ value, trackingIterator, createState: createState2 });
1050
+ });
1051
+ }
1052
+
1053
+ // src/create-state/index.ts
1054
+ function createState(initialValue, subscribeCallback) {
1055
+ let value = initialValue;
1056
+ let previousValue = void 0;
1057
+ const trackers = {
1058
+ trackingEffects: [],
1059
+ trackingSelectorElements: [],
1060
+ trackingAttributes: [],
1061
+ trackingIterators: []
649
1062
  };
650
1063
  const result = {
651
1064
  // supposed to be used at the component level
@@ -654,7 +1067,7 @@ function createState(initialValue, subscribeCallback) {
654
1067
  },
655
1068
  trackValueSelector(selector, cb, options = {}) {
656
1069
  const trackedValue = selector ? selector(value) : value;
657
- trackingEffects.push({
1070
+ trackers.trackingEffects.push({
658
1071
  cb,
659
1072
  selector,
660
1073
  comparator: options.comparator,
@@ -670,7 +1083,7 @@ function createState(initialValue, subscribeCallback) {
670
1083
  }
671
1084
  }
672
1085
  onUnmount(() => {
673
- trackingEffects = trackingEffects.filter(
1086
+ trackers.trackingEffects = trackers.trackingEffects.filter(
674
1087
  (trackingCallback) => trackingCallback.cb !== cb
675
1088
  );
676
1089
  });
@@ -680,70 +1093,79 @@ function createState(initialValue, subscribeCallback) {
680
1093
  },
681
1094
  useValueSelector(selector, cb, comparator = identity) {
682
1095
  const selectedValue = selector ? selector(value) : value;
683
- const returnedNode = cb ? cb(selectedValue) : String(selectedValue);
1096
+ const returnedNode = cb ? cb(selectedValue) : selectedValue == void 0 ? "" : String(selectedValue);
684
1097
  const node = !returnedNode || typeof returnedNode === "string" ? createTextElement(returnedNode) : returnedNode;
1098
+ const currentContext2 = getCurrentContext();
1099
+ node.needExecutedVersion = true;
685
1100
  const trackingSelectorElement = {
686
1101
  selector,
687
1102
  selectedValue,
688
1103
  cb,
689
1104
  node,
690
- comparator
1105
+ comparator,
1106
+ savedContext: currentContext2
691
1107
  };
692
- trackingSelectorElements.push(trackingSelectorElement);
693
- node._privateMethods._addUnmountHandler(() => {
694
- trackingSelectorElements = trackingSelectorElements.filter(
695
- (el) => trackingSelectorElement !== el
696
- );
1108
+ addUseValueMountHandler({
1109
+ usedValue: value,
1110
+ getValue: () => value,
1111
+ trackers,
1112
+ trackingSelectorElement
697
1113
  });
698
1114
  return node;
699
1115
  },
700
1116
  useValueIterator(options, cb) {
701
- const children = [];
702
- const elementsByKey = {};
703
- const elements = options.selector ? options.selector(value) : value;
704
- if (!Array.isArray(elements)) {
705
- console.error("useValueIterator received non-array value");
706
- return null;
707
- }
708
- elements.forEach((element, index) => {
709
- let calculatedKey = "";
710
- if (typeof options.key === "string" && typeof element === "object" && element !== null && options.key in element) {
711
- calculatedKey = element[options.key];
712
- } else if (typeof options.key === "function") {
713
- calculatedKey = options.key({ element, index });
714
- } else {
715
- }
716
- const elementState = createState(element);
717
- const indexState = createState(index);
718
- if (!calculatedKey) {
719
- return;
720
- }
721
- let node = cb({ elementState, indexState });
722
- elementsByKey[calculatedKey] = {
723
- node,
724
- indexState,
725
- indexValue: index,
726
- elementState
727
- };
728
- children.push([node, calculatedKey, elementState]);
729
- });
1117
+ const currentContext2 = getCurrentContext();
730
1118
  const trackingParams = {};
731
- trackingIterators.push(trackingParams);
732
- const wrapperComponent = createElement(() => {
733
- onUnmount(() => {
734
- trackingIterators = trackingIterators.filter(
735
- (currentTrackingParams) => currentTrackingParams !== trackingParams
736
- );
1119
+ trackingParams.savedContext = currentContext2;
1120
+ const wrapperComponent = createElement((_props, componentAPI) => {
1121
+ const children = [];
1122
+ const elementsByKey = {};
1123
+ const elements = options.selector ? options.selector(value) : value;
1124
+ if (!Array.isArray(elements)) {
1125
+ console.error("useValueIterator received non-array value");
1126
+ return null;
1127
+ }
1128
+ elements.forEach((element, index) => {
1129
+ let calculatedKey = "";
1130
+ if (typeof options.key === "string" && typeof element === "object" && element !== null && options.key in element) {
1131
+ calculatedKey = element[options.key];
1132
+ } else if (typeof options.key === "function") {
1133
+ calculatedKey = options.key({ element, index });
1134
+ } else {
1135
+ }
1136
+ const elementState = createState(element);
1137
+ const indexState = createState(index);
1138
+ if (!calculatedKey) {
1139
+ return;
1140
+ }
1141
+ let node = cb({ elementState, indexState });
1142
+ node.needExecutedVersion = true;
1143
+ elementsByKey[calculatedKey] = {
1144
+ node,
1145
+ indexState,
1146
+ indexValue: index,
1147
+ elementState
1148
+ };
1149
+ children.push([node, calculatedKey, elementState]);
1150
+ });
1151
+ trackingParams.elementsByKey = elementsByKey;
1152
+ trackingParams.renderedElements = children;
1153
+ trackers.trackingIterators.push(trackingParams);
1154
+ onMount(() => {
1155
+ componentAPI.onUnmount(() => {
1156
+ trackers.trackingIterators = trackers.trackingIterators.filter(
1157
+ (currentTrackingParams) => currentTrackingParams !== trackingParams
1158
+ );
1159
+ });
737
1160
  });
738
1161
  return createElement("div", {
739
1162
  phantom: true,
740
1163
  children: children.map((child) => child[0])
741
1164
  });
742
1165
  });
1166
+ wrapperComponent.needExecutedVersion = true;
743
1167
  trackingParams.cb = cb;
744
1168
  trackingParams.key = options.key;
745
- trackingParams.elementsByKey = elementsByKey;
746
- trackingParams.renderedElements = children;
747
1169
  trackingParams.wrapperComponent = wrapperComponent;
748
1170
  if (options.selector) {
749
1171
  trackingParams.selector = options.selector;
@@ -751,14 +1173,30 @@ function createState(initialValue, subscribeCallback) {
751
1173
  return wrapperComponent;
752
1174
  },
753
1175
  useAttribute: (cb) => {
1176
+ const originalValue = value;
1177
+ let wasMounted = false;
754
1178
  const attributeValue = cb ? cb(value) : value;
755
1179
  const attributeHelper = (htmlElement, attributeName, node) => {
756
- const trackingElement = { cb, htmlElement, attributeName };
757
- trackingAttributes.push(trackingElement);
758
- node._privateMethods._addUnmountHandler(() => {
759
- trackingAttributes = trackingAttributes.filter(
760
- (trackingAttribute) => trackingAttribute !== trackingElement
761
- );
1180
+ const trackingElement = {
1181
+ cb,
1182
+ htmlElement,
1183
+ attributeName,
1184
+ attributeValue
1185
+ };
1186
+ node._privateMethods._addMountHandler(() => {
1187
+ trackers.trackingAttributes.push(trackingElement);
1188
+ if (!wasMounted && value === originalValue) {
1189
+ } else {
1190
+ updateUseAttributeValue({ element: trackingElement, value });
1191
+ }
1192
+ if (!wasMounted) {
1193
+ wasMounted = true;
1194
+ }
1195
+ node._privateMethods._addUnmountHandler(() => {
1196
+ trackers.trackingAttributes = trackers.trackingAttributes.filter(
1197
+ (trackingAttribute) => trackingAttribute !== trackingElement
1198
+ );
1199
+ });
762
1200
  });
763
1201
  return attributeValue;
764
1202
  };
@@ -783,7 +1221,7 @@ function createState(initialValue, subscribeCallback) {
783
1221
  if (newValue !== value) {
784
1222
  previousValue = value;
785
1223
  value = newValue;
786
- _triggerUpdates();
1224
+ triggerUpdates({ value, createState, trackers, getValue: () => value });
787
1225
  }
788
1226
  }
789
1227
  };
@@ -803,18 +1241,11 @@ function createRef(initialRefValue = null) {
803
1241
  current: initialRefValue
804
1242
  };
805
1243
  }
806
-
807
- // src/fragment.ts
808
- function Fragment({ children }) {
809
- return createElement("div", {
810
- phantom: true,
811
- children
812
- });
813
- }
814
1244
  // Annotate the CommonJS export names for ESM import in node:
815
1245
  0 && (module.exports = {
816
1246
  Fragment,
817
1247
  attachComponent,
1248
+ createContext,
818
1249
  createElement,
819
1250
  createRef,
820
1251
  createState,