veles 0.0.7 → 0.0.8

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