solarite 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/Solarite-debug.js +380 -504
  2. package/dist/Solarite.js +363 -487
  3. package/dist/Solarite.min.js +2 -2
  4. package/package.json +5 -6
  5. package/readme.md +1 -1
  6. package/src/{solarite/ExprPath.js → ExprPath.js} +23 -49
  7. package/src/{solarite/Globals.js → Globals.js} +4 -4
  8. package/src/{util/MultiValueMap.js → MultiValueMap.js} +1 -32
  9. package/src/{solarite/NodeGroup.js → NodeGroup.js} +25 -21
  10. package/src/{solarite/Shell.js → Shell.js} +8 -7
  11. package/src/Solarite.d.ts +62 -0
  12. package/src/{solarite/Solarite.js → Solarite.js} +13 -15
  13. package/src/{solarite/Template.js → Template.js} +1 -1
  14. package/src/{solarite/Util.js → Util.js} +49 -45
  15. package/src/{solarite/createSolarite.js → createSolarite.js} +12 -10
  16. package/src/{solarite/getArg.js → getArg.js} +24 -3
  17. package/src/{solarite/h.js → h.js} +4 -12
  18. package/src/unused/FastLookupArray.js +54 -0
  19. package/src/unused/Hashes.js +339 -0
  20. package/src/unused/InUse.test.js +92 -0
  21. package/src/unused/InUseMap.js +98 -0
  22. package/src/unused/LinkedList.js +117 -0
  23. package/src/unused/LinkedList.test.js +115 -0
  24. package/src/unused/Misc.js +13 -0
  25. package/src/unused/Perf.js +47 -0
  26. package/src/unused/TrackedArray.js +54 -0
  27. package/src/unused/WeakArray.js +33 -0
  28. package/src/{solarite/watch.js → watch.js} +4 -4
  29. package/src/util/Util.js +0 -101
  30. /package/src/{solarite/HtmlParser.js → HtmlParser.js} +0 -0
  31. /package/src/{util/Errors.js → assert.js} +0 -0
  32. /package/src/{util/delve.js → delve.js} +0 -0
  33. /package/src/{solarite/hash.js → hash.js} +0 -0
  34. /package/src/{solarite/udomdiff.js → udomdiff.js} +0 -0
@@ -1,98 +1,101 @@
1
- /**
2
- * @typedef {Array|function(...*)} Callbacks
3
- * @property {function(function)} push
4
- * @property {function()} remove
5
- * @property {function()} pause
6
- * @property {function()} resume
7
- * */
1
+ //#IFDEV
2
+ /*@__NO_SIDE_EFFECTS__*/
3
+ function assert(val) {
4
+ if (!val) {
5
+ debugger;
6
+ throw new Error('Assertion failed: ' + val);
7
+ }
8
+ }
8
9
 
10
+ //#ENDIF
11
+
12
+ let lastObjectId = 1>>>0; // Is a 32-bit int faster to increment than JavaScript's Number, which is a 64-bit float?
13
+ let objectIds = new WeakMap();
9
14
 
10
15
  /**
11
- * A place for functions that have no other home. */
12
- var Util$1 = {
16
+ * @param obj {Object|string|Node}
17
+ * @returns {string} */
18
+ function getObjectId(obj) {
19
+ // if (typeof obj === 'function')
20
+ // return obj.toString(); // This fails to detect when a function's bound variables changes.
21
+
22
+ let result = objectIds.get(obj);
23
+ if (!result) { // convert to string, store in result, then add 1 to lastObjectId.
24
+ result = '~\f' + (lastObjectId++); // We use a unique, 2-byte prefix to ensure it doesn't collide w/ strings not from getObjectId()
25
+ objectIds.set(obj, result);
26
+ }
27
+ return result;
28
+ }
13
29
 
14
- /**
15
- * Create an array-like object that stores a group of callbacks.
16
- * Supports all array functions and properties like push() and .length.
17
- * Can be called directly.
18
- *
19
- * @param functions {function[]}
20
- * @return {Callbacks|function}
21
- *
22
- * @example
23
- * var c = Util.callback();
24
- * var f = () => console.log(3);
25
- * c.push(f);
26
- * c();
27
- * c.remove(f);
28
- * c();
29
- */
30
- callback(...functions) {
31
- var paused = false;
32
-
33
- // Make it callable. When we call it, call all callbacks() with the given args.
34
- let result = async function(...args) {
35
- let result2 = [];
36
- if (!paused)
37
- for (let i=0; i<result.length; i++)
38
- result2.push(result[i](...args));
39
- return await Promise.all(result2);
40
- };
41
-
42
- // Make it iterable.
43
- result[Symbol.iterator] = function() {
44
- let index = 0;
45
- return {
46
- next: () => index < result.length
47
- ? {value: result[index++], done: false}
48
- : {done: true}
49
- };
50
- };
30
+ /**
31
+ * Control how JSON.stringify() handles Nodes and Functions.
32
+ * Normally, we'd pass a replacer() function argument to JSON.stringify() to handle Nodes and Functions.
33
+ * But that makes JSON.stringify() take twice as long to run.
34
+ * Adding a toJSON method globally on these object prototypes doesn't incur that performance penalty. */
35
+ let isHashing = true;
36
+ function toJSON() {
37
+ return isHashing ? getObjectId(this) : this
38
+ }
51
39
 
52
- // Use properties from Array
53
- for (let prop of Object.getOwnPropertyNames(Array.prototype))
54
- if (prop !== 'length' && prop !== 'constructor')
55
- result[prop] = Array.prototype[prop];
56
40
 
57
- result.l = 0; // Internal length
58
- Object.defineProperty(result, 'length', {
59
- get() { return result.l },
60
- set(val) { result.l = val;}
61
- });
41
+ // Node.prototype.toJSON = toJSON;
42
+ // Function.prototype.toJSON = toJSON;
62
43
 
63
- // Add the remove() function.
64
- result.remove = func => {
65
- let idx = result.findIndex(item => item === func);
66
- if (idx !== -1)
67
- result.splice(idx, 1);
68
- };
69
- result.pause = () => paused = true;
70
44
 
71
- result.resume = () => paused = false;
45
+ /**
46
+ * Get a string that uniquely maps to the values of the given object.
47
+ * If a value in obj changes, calling getObjectHash(obj) will then return a different hash.
48
+ * This is used by NodeGroupManager to create a hash that represents the current values of a NodeGroup.
49
+ *
50
+ * Relies on the Node and Function prototypes being overridden above.
51
+ *
52
+ * Note that passing an integer may collide with the number we get from hashing an object.
53
+ * But we don't handle that case because we need max performance and Solarite never passes integers to this function.
54
+ *
55
+ * @param obj {*}
56
+ * @returns {string} */
57
+ function getObjectHash(obj) {
72
58
 
73
- // Add initial functions
74
- for (let f of functions)
75
- result.push(f);
59
+ // Sometimes these get unassigned by Chrome and Brave 119, as well as Firefox, seemingly randomly!
60
+ // The same tests sometimes pass, sometimes fail, even after browser and OS restarts.
61
+ // So we check the assignments on every run of getObjectHash()
62
+ if (Node.prototype.toJSON !== toJSON) {
63
+ Node.prototype.toJSON = toJSON;
64
+ if (Function.prototype.toJSON !== toJSON) // Will it only unmap one but not the other?
65
+ Function.prototype.toJSON = toJSON;
66
+ }
76
67
 
77
- return result;
78
- },
68
+ let result;
69
+ isHashing = true;
70
+ try {
71
+ result = JSON.stringify(obj);
72
+ }
73
+ catch(e) {
74
+ result = getObjectHashCircular(obj);
75
+ }
76
+ isHashing = false;
77
+ return result;
78
+ }
79
79
 
80
- /**
81
- * Use an array as the value of a map, appending to it when we add.
82
- * Used by watch.js.
83
- * @param map {Map|WeakMap|Object}
84
- * @param key
85
- * @param value */
86
- mapArrayAdd(map, key, value) {
87
- let result = map.get(key);
88
- if (!result) {
89
- result = [value];
90
- map.set(key, result);
80
+ /**
81
+ * Slower hashing method that supports.
82
+ * @param obj
83
+ * @returns {string} */
84
+ function getObjectHashCircular(obj) {
85
+
86
+ //console.log('circular')
87
+ // Slower version that handles circular references.
88
+ // Just adding any callback at all, even one that just returns the value, makes JSON.stringify() twice as slow.
89
+ const seen = new Set();
90
+ return JSON.stringify(obj, (key, value) => {
91
+ if (typeof value === 'object' && value !== null) {
92
+ if (seen.has(value))
93
+ return getObjectId(value);
94
+ seen.add(value);
91
95
  }
92
- else
93
- result.push(value);
94
- },
95
- };
96
+ return value;
97
+ });
98
+ }
96
99
 
97
100
  var Globals;
98
101
 
@@ -119,15 +122,15 @@ function reset() {
119
122
  div: document.createElement("div"),
120
123
 
121
124
  /**
122
- * @type {Object<string, Class<Node>>} A map from built-in tag names to the constructors that create them. */
125
+ * @type {Record<string, Class<Node>>} A map from built-in tag names to the constructors that create them. */
123
126
  elementClasses: {},
124
127
 
125
- /** @type {Object<string, boolean>} Key is tag-name.propName. Value is whether it's an attribute.*/
128
+ /** @type {Record<string, boolean>} Key is tag-name.propName. Value is whether it's an attribute.*/
126
129
  htmlProps: {},
127
130
 
128
131
  /**
129
132
  * Used by ExprPath.applyEventAttrib()
130
- * @type {WeakMap<Node, Object<eventName:string, [original:function, bound:function, args:*[]]>>} */
133
+ * @type {WeakMap<Node, Record<eventName:string, [original:function, bound:function, args:*[]]>>} */
131
134
  nodeEvents: new WeakMap(),
132
135
 
133
136
  /**
@@ -162,7 +165,7 @@ function reset() {
162
165
  * A map of individual untagged strings to their Templates.
163
166
  * This way we don't keep creating new Templates for the same string when re-rendering.
164
167
  * This is used by ExprPath.applyExactNodes()
165
- * @type {Object<string, Template>} */
168
+ * @type {Record<string, Template>} */
166
169
  //stringTemplates: {},
167
170
 
168
171
  reset,
@@ -221,6 +224,21 @@ let d = {};
221
224
 
222
225
  let Util = {
223
226
 
227
+ /**
228
+ * Returns true if they're the same.
229
+ * @param a
230
+ * @param b
231
+ * @returns {boolean} */
232
+ arraySame(a, b) {
233
+ let aLength = a.length;
234
+ if (aLength !== b.length)
235
+ return false;
236
+ for (let i=0; i<aLength; i++)
237
+ if (a[i] !== b[i])
238
+ return false;
239
+ return true; // the same.
240
+ },
241
+
224
242
  bindId(root, el) {
225
243
  let id = el.getAttribute('data-id') || el.getAttribute('id');
226
244
  if (id) { // If something hasn't removed the id.
@@ -261,7 +279,6 @@ let Util = {
261
279
  }
262
280
  },
263
281
 
264
-
265
282
  /**
266
283
  * Convert a Proper Case name to a name with dashes.
267
284
  * Dashes will be placed between letters and numbers.
@@ -329,17 +346,17 @@ let Util = {
329
346
  * for (const item of flatten(complexArray))
330
347
  * console.log(item); // Outputs: 1, 2, 3, 4, 5, 6, { a: 'object' }, 7, 8, 9
331
348
  */
332
- *flatten(value) {
333
- if (Array.isArray(value)) {
334
- for (const item of value) {
335
- yield* Util.flatten(item); // Recursively flatten arrays
336
- }
337
- } else if (typeof value === 'function') {
338
- const result = value();
339
- yield* Util.flatten(result); // Recursively flatten the result of a function
340
- } else
341
- yield value; // Yield primitive values as is
342
- },
349
+ // *flatten(value) {
350
+ // if (Array.isArray(value)) {
351
+ // for (const item of value) {
352
+ // yield* Util.flatten(item); // Recursively flatten arrays
353
+ // }
354
+ // } else if (typeof value === 'function') {
355
+ // const result = value();
356
+ // yield* Util.flatten(result); // Recursively flatten the result of a function
357
+ // } else
358
+ // yield value; // Yield primitive values as is
359
+ // },
343
360
 
344
361
  /**
345
362
  * Get the value of an input as the most appropriate JavaScript type.
@@ -361,6 +378,10 @@ let Util = {
361
378
  return node.value; // String
362
379
  },
363
380
 
381
+ isEvent(attrName) {
382
+ return attrName.startsWith('on') && attrName in Globals$1.div;
383
+ },
384
+
364
385
  /**
365
386
  * @param el {HTMLElement}
366
387
  * @param prop {string}
@@ -400,9 +421,10 @@ let Util = {
400
421
  return val === undefined || val === false || val === null;
401
422
  },
402
423
 
424
+ /*
403
425
  isPrimitive(val) {
404
426
  return typeof val === 'string' || typeof val === 'number'
405
- },
427
+ },*/
406
428
 
407
429
  /**
408
430
  * If val is a function, evaluate it recursively until the result is not a function.
@@ -420,6 +442,22 @@ let Util = {
420
442
  return val;
421
443
  },
422
444
 
445
+ /**
446
+ * Use an array as the value of a map, appending to it when we add.
447
+ * Used by watch.js.
448
+ * @param map {Map|WeakMap|Object}
449
+ * @param key
450
+ * @param value */
451
+ mapArrayAdd(map, key, value) {
452
+ let result = map.get(key);
453
+ if (!result) {
454
+ result = [value];
455
+ map.set(key, result);
456
+ }
457
+ else
458
+ result.push(value);
459
+ },
460
+
423
461
  /**
424
462
  * Remove nodes from the beginning and end that are not:
425
463
  * 1. Elements.
@@ -448,31 +486,6 @@ let Util = {
448
486
 
449
487
 
450
488
 
451
- let isEvent = attrName => attrName.startsWith('on') && attrName in Globals$1.div;
452
-
453
-
454
-
455
-
456
-
457
- /**
458
- * Returns true if they're the same.
459
- * @param a
460
- * @param b
461
- * @returns {boolean} */
462
- function arraySame(a, b) {
463
- let aLength = a.length;
464
- if (aLength !== b.length)
465
- return false;
466
- for (let i=0; i<aLength; i++)
467
- if (a[i] !== b[i])
468
- return false;
469
- return true; // the same.
470
- }
471
-
472
-
473
-
474
-
475
-
476
489
  // For debugging only
477
490
  //#IFDEV
478
491
  function setIndent(items, level=1) {
@@ -519,273 +532,25 @@ function nodeToArrayTree(node, callback=null) {
519
532
  }
520
533
 
521
534
 
522
- function flattenAndIndent(inputArray, indent = "") {
523
- let result = [];
524
-
525
- for (let item of inputArray) {
526
- if (Array.isArray(item)) {
527
- // Recursively handle nested arrays with increased indentation
528
- result = result.concat(flattenAndIndent(item, indent + " "));
529
- } else {
530
- result.push(indent + item);
531
- }
532
- }
533
-
534
- return result;
535
- }
536
- //#ENDIF
537
-
538
- function defineClass(Class, tagName, extendsTag) {
539
- if (!customElements[getName](Class)) { // If not previously defined.
540
- tagName = tagName || Util.camelToDashes(Class.name);
541
- if (!tagName.includes('-'))
542
- tagName += '-element';
543
-
544
- let options = null;
545
- if (extendsTag)
546
- options = {extends: extendsTag};
547
-
548
- customElements[define](tagName, Class, options);
549
- }
550
- }
551
-
552
- /**
553
- * Create a version of the Solarite class that extends from the given tag name.
554
- * Reasons to inherit from this instead of HTMLElement. None of these are all that useful.
555
- * 1. customElements.define() is called automatically when you create the first instance.
556
- * 2. Calls render() when added to the DOM, if it hasn't been called already.
557
- * 3. Child elements are added before constructor is called. But they're also passed to the constructor. (deprecated?)
558
- * 4. We can use this.html = r`...` to set html. (deprecated)
559
- * 5. We have the onConnect, onFirstConnect, and onDisconnect methods.
560
- * Can't figure out how to have these work standalone though, and still be synchronous.
561
- * 6. Can we extend from other element types like TR?
562
- * 7. Shows default text if render() function isn't defined.
563
- *
564
- * Advantages to inheriting from HTMLElement
565
- * 1. Minimization won't break when it renames the Class and we call customElements.define() on the wrong name.
566
- * 2. We can inherit from things like HTMLTableRowElement directly.
567
- * 3. There's less magic, since everyone is familiar with defining custom elements.
568
- *
569
- * @param extendsTag {?string}
570
- * @return {Class} */
571
- function createSolarite(extendsTag=null) {
572
-
573
- let BaseClass = HTMLElement;
574
- if (extendsTag && !extendsTag.includes('-')) {
575
- extendsTag = extendsTag.toLowerCase();
576
-
577
- BaseClass = Globals$1.elementClasses[extendsTag];
578
- if (!BaseClass) { // TODO: Use Cache
579
- BaseClass = document.createElement(extendsTag).constructor;
580
- Globals$1.elementClasses[extendsTag] = BaseClass;
581
- }
582
- }
583
-
584
- /**
585
- * Intercept the construct call to auto-define the class before the constructor is called.
586
- * @type {HTMLElement} */
587
- let HTMLElementAutoDefine = new Proxy(BaseClass, {
588
- construct(Parent, args, Class) {
589
- defineClass(Class, null, extendsTag);
590
-
591
- // This is a good place to manipulate any args before they're sent to the constructor.
592
- // Such as loading them from attributes, if I could find a way to do so.
593
-
594
- // This line is equivalent the to super() call.
595
- return Reflect.construct(Parent, args, Class);
596
- }
597
- });
598
-
599
- return class Solarite extends HTMLElementAutoDefine {
600
-
601
-
602
- /**
603
- * TODO: Make these standalone functions.
604
- * Callbacks.
605
- * Use onConnect.push(() => ...); to add new callbacks. */
606
- onConnect = Util$1.callback();
607
-
608
- onFirstConnect = Util$1.callback();
609
- onDisconnect = Util$1.callback();
610
-
611
- /**
612
- * @param options {RenderOptions} */
613
- constructor(options={}) {
614
- super();
615
-
616
- // TODO: Is options.render ever used?
617
- if (options.render===true)
618
- this.render();
619
-
620
- else if (options.render===false)
621
- Globals$1.rendered.add(this); // Don't render on connectedCallback()
622
-
623
- // Add slot children before constructor code executes.
624
- // This breaks the styleStaticNested test.
625
- // PendingChildren is setup in NodeGroup.createNewComponent()
626
- // TODO: Match named slots.
627
- //let ch = Globals.pendingChildren.pop();
628
- //if (ch) // TODO: how could there be a slot before render is called?
629
- // (this.querySelector('slot') || this).append(...ch);
630
-
631
- /** @deprecated
632
- Object.defineProperty(this, 'html', {
633
- set(html) {
634
- Globals.rendered.add(this);
635
- if (typeof html === 'string') {
636
- console.warn("Assigning to this.html without the r template prefix.")
637
- this.innerHTML = html;
638
- }
639
- else
640
- this.modifications = r(this, html, options);
641
- }
642
- })*/
643
-
644
- /*
645
- let pthis = new Proxy(this, {
646
- get(obj, prop) {
647
- return Reflect.get(obj, prop)
648
- }
649
- });
650
- this.render = this.render.bind(pthis);
651
- */
652
- }
653
-
654
- /**
655
- * Call render() only if it hasn't already been called. */
656
- renderFirstTime() {
657
- if (!Globals$1.rendered.has(this) && this.render)
658
- this.render();
659
- }
660
-
661
- /**
662
- * Called automatically by the browser. */
663
- connectedCallback() {
664
- this.renderFirstTime();
665
- if (!Globals$1.connected.has(this)) {
666
- Globals$1.connected.add(this);
667
- this.onFirstConnect();
668
- }
669
- this.onConnect();
670
- }
671
-
672
- disconnectedCallback() {
673
- this.onDisconnect();
674
- }
675
-
676
-
677
- static define(tagName=null) {
678
- defineClass(this, tagName, extendsTag);
679
- }
680
- }
681
- }
682
-
683
- // Trick to prevent minifier from renaming this method.
684
- let define = 'define';
685
- let getName = 'getName';
686
-
687
- //#IFDEV
688
- /*@__NO_SIDE_EFFECTS__*/
689
- function assert(val) {
690
- if (!val) {
691
- debugger;
692
- throw new Error('Assertion failed: ' + val);
693
- }
694
- }
695
-
696
- //#ENDIF
697
-
698
- let lastObjectId = 1>>>0; // Is a 32-bit int faster to increment than JavaScript's Number, which is a 64-bit float?
699
- let objectIds = new WeakMap();
700
-
701
- /**
702
- * @param obj {Object|string|Node}
703
- * @returns {string} */
704
- function getObjectId(obj) {
705
- // if (typeof obj === 'function')
706
- // return obj.toString(); // This fails to detect when a function's bound variables changes.
707
-
708
- let result = objectIds.get(obj);
709
- if (!result) { // convert to string, store in result, then add 1 to lastObjectId.
710
- result = '~\f' + (lastObjectId++); // We use a unique, 2-byte prefix to ensure it doesn't collide w/ strings not from getObjectId()
711
- objectIds.set(obj, result);
712
- }
713
- return result;
714
- }
715
-
716
- /**
717
- * Control how JSON.stringify() handles Nodes and Functions.
718
- * Normally, we'd pass a replacer() function argument to JSON.stringify() to handle Nodes and Functions.
719
- * But that makes JSON.stringify() take twice as long to run.
720
- * Adding a toJSON method globally on these object prototypes doesn't incur that performance penalty. */
721
- let isHashing = true;
722
- function toJSON() {
723
- return isHashing ? getObjectId(this) : this
724
- }
725
-
726
-
727
- // Node.prototype.toJSON = toJSON;
728
- // Function.prototype.toJSON = toJSON;
729
-
730
-
731
- /**
732
- * Get a string that uniquely maps to the values of the given object.
733
- * If a value in obj changes, calling getObjectHash(obj) will then return a different hash.
734
- * This is used by NodeGroupManager to create a hash that represents the current values of a NodeGroup.
735
- *
736
- * Relies on the Node and Function prototypes being overridden above.
737
- *
738
- * Note that passing an integer may collide with the number we get from hashing an object.
739
- * But we don't handle that case because we need max performance and Solarite never passes integers to this function.
740
- *
741
- * @param obj {*}
742
- * @returns {string} */
743
- function getObjectHash(obj) {
744
-
745
- // Sometimes these get unassigned by Chrome and Brave 119, as well as Firefox, seemingly randomly!
746
- // The same tests sometimes pass, sometimes fail, even after browser and OS restarts.
747
- // So we check the assignments on every run of getObjectHash()
748
- if (Node.prototype.toJSON !== toJSON) {
749
- Node.prototype.toJSON = toJSON;
750
- if (Function.prototype.toJSON !== toJSON) // Will it only unmap one but not the other?
751
- Function.prototype.toJSON = toJSON;
752
- }
753
-
754
- let result;
755
- isHashing = true;
756
- try {
757
- result = JSON.stringify(obj);
758
- }
759
- catch(e) {
760
- result = getObjectHashCircular(obj);
761
- }
762
- isHashing = false;
763
- return result;
764
- }
765
-
766
- /**
767
- * Slower hashing method that supports.
768
- * @param obj
769
- * @returns {string} */
770
- function getObjectHashCircular(obj) {
771
-
772
- //console.log('circular')
773
- // Slower version that handles circular references.
774
- // Just adding any callback at all, even one that just returns the value, makes JSON.stringify() twice as slow.
775
- const seen = new Set();
776
- return JSON.stringify(obj, (key, value) => {
777
- if (typeof value === 'object' && value !== null) {
778
- if (seen.has(value))
779
- return getObjectId(value);
780
- seen.add(value);
535
+ function flattenAndIndent(inputArray, indent = "") {
536
+ let result = [];
537
+
538
+ for (let item of inputArray) {
539
+ if (Array.isArray(item)) {
540
+ // Recursively handle nested arrays with increased indentation
541
+ result = result.concat(flattenAndIndent(item, indent + " "));
542
+ } else {
543
+ result.push(indent + item);
781
544
  }
782
- return value;
783
- });
784
- }
545
+ }
546
+
547
+ return result;
548
+ }
549
+ //#ENDIF
785
550
 
786
551
  class MultiValueMap {
787
552
 
788
- /** @type {Object<string, Set>} */
553
+ /** @type {Record<string, Set>} */
789
554
  data = {};
790
555
 
791
556
  // Set a new value for a key
@@ -879,37 +644,6 @@ class MultiValueMap {
879
644
  return result;
880
645
  }
881
646
 
882
-
883
- /**
884
- * Try to delete an item that matches the key and the isPreferred function.
885
- * if not the latter, just delete any item that matches the key.
886
- * @param key {string}
887
- * @returns {*|undefined} The deleted item. */
888
- deletePreferred(key, parent) {
889
- let result;
890
- let data = this.data;
891
- let set = data[key];
892
- if (!set)
893
- return undefined;
894
-
895
- for (let val of set) {
896
- if (val?.parentNode === parent) {
897
- set.delete(val);
898
- result = val;
899
- break;
900
- }
901
- }
902
- if (!result) {
903
- [result] = set;
904
- set.delete(result);
905
- }
906
-
907
- if (set.size === 0)
908
- delete data[key];
909
-
910
- return result;
911
- }
912
-
913
647
  hasValue(val) {
914
648
  let data = this.data;
915
649
  let names = [];
@@ -1349,7 +1083,7 @@ class ExprPath {
1349
1083
 
1350
1084
 
1351
1085
  // This pre-check makes it a few percent faster?
1352
- let same = arraySame(oldNodes, newNodes);
1086
+ let same = Util.arraySame(oldNodes, newNodes);
1353
1087
  if (!same) {
1354
1088
 
1355
1089
  path.nodesCache = newNodes; // Replaces value set by path.getNodes()
@@ -1371,6 +1105,20 @@ class ExprPath {
1371
1105
  for (let ng of oldNodeGroups)
1372
1106
  if (!ng.startNode.parentNode)
1373
1107
  ng.removeAndSaveOrphans();
1108
+
1109
+
1110
+
1111
+
1112
+ // Instantiate components created within ${...} expressions.
1113
+ // Embedded style tags are handled elsewhere, but where?
1114
+ for (let el of newNodes) {
1115
+ if (el instanceof HTMLElement) {
1116
+ if (el.hasAttribute('solarite-placeholder'))
1117
+ this.parentNg.instantiateComponent(el);
1118
+ for (let child of el.querySelectorAll('[solarite-placeholder]'))
1119
+ this.parentNg.instantiateComponent(child);
1120
+ }
1121
+ }
1374
1122
  }
1375
1123
 
1376
1124
 
@@ -1547,50 +1295,10 @@ class ExprPath {
1547
1295
  // Arrays and functions.
1548
1296
  // I tried iterating over the result of a generator function to avoid this recursion and simplify the code,
1549
1297
  // but that consistently made the js-framework-benchmarks a few percentage points slower.
1550
- else {
1298
+ else
1551
1299
  this.exprToTemplates(expr, template => {
1552
1300
  this.applyExactNodes(template, newNodes, secondPass);
1553
1301
  });
1554
-
1555
- }
1556
-
1557
- // Old version
1558
- /*else if (Array.isArray(expr))
1559
- for (let subExpr of expr)
1560
- this.applyExactNodes(subExpr, newNodes, secondPass);
1561
-
1562
- else if (typeof expr === 'function') {
1563
- // TODO: One ExprPath can have multiple expr functions.
1564
- // But if using it as a watch, it should only have one at the top level.
1565
- // So maybe this is ok.
1566
- Globals.currentExprPath = this; // Used by watch()
1567
-
1568
- this.watchFunction = expr; // TODO: Only do this if it's a top level function.
1569
- let result = expr(); // As expr accesses watched variables, watch() uses Globals.currentExprPath to mark where those watched variables are being used.
1570
- Globals.currentExprPath = null;
1571
-
1572
- this.applyExactNodes(result, newNodes, secondPass);
1573
- }
1574
-
1575
- // String
1576
- else {
1577
- // Convert expression to a string.
1578
- let stringExpr = expr;
1579
- if (expr === undefined || expr === false || expr === null) // Util.isFalsy()
1580
- stringExpr = '';
1581
- else if (typeof expr !== 'string')
1582
- stringExpr = expr + '';
1583
-
1584
- // Get the same Template for the same string each time.
1585
- let template = Globals.stringTemplates[stringExpr];
1586
- if (!template) {
1587
- template = new Template([stringExpr], []);
1588
- Globals.stringTemplates[stringExpr] = template;
1589
- }
1590
-
1591
- // Recurse.
1592
- this.applyExactNodes(template, newNodes, secondPass);
1593
- }*/
1594
1302
  }
1595
1303
 
1596
1304
  applyMultipleAttribs(node, expr) {
@@ -1733,7 +1441,7 @@ class ExprPath {
1733
1441
  // Copies the attribute to the property when the input event fires.
1734
1442
  // value=${[this, 'value]'}
1735
1443
  // checked=${[this, 'isAgree']}
1736
- // This same logic is in NodeGroup.createNewComponent() for components.
1444
+ // This same logic is in NodeGroup.instantiateComponent() for components.
1737
1445
  if (Util.isPath(expr)) {
1738
1446
  let [obj, path] = [expr[0], expr.slice(1)];
1739
1447
 
@@ -2338,7 +2046,7 @@ class Shell {
2338
2046
  /** @type {int[][]} Array of paths. Used by activateEmbeds() to quickly find components. */
2339
2047
  staticComponents = [];
2340
2048
 
2341
- /** @type {{path:int[], attribs:Object<string, string>}[]} */
2049
+ /** @type {{path:int[], attribs:Record<string, string>}[]} */
2342
2050
  //componentAttribs = [];
2343
2051
 
2344
2052
 
@@ -2399,7 +2107,7 @@ class Shell {
2399
2107
  let parts = attr.value.split(/[\ue000-\uf8ff]/g);
2400
2108
  if (parts.length > 1) {
2401
2109
  let nonEmptyParts = (parts.length === 2 && !parts[0].length && !parts[1].length) ? null : parts;
2402
- let type = isEvent(attr.name) ? ExprPathType.Event : ExprPathType.AttribValue;
2110
+ let type = Util.isEvent(attr.name) ? ExprPathType.Event : ExprPathType.AttribValue;
2403
2111
 
2404
2112
  this.paths.push(new ExprPath(null, node, type, attr.name, nonEmptyParts));
2405
2113
  placeholdersUsed += parts.length - 1;
@@ -2527,11 +2235,12 @@ class Shell {
2527
2235
  function addToken(token, context) {
2528
2236
 
2529
2237
  if (context === HtmlParser.Tag) {
2530
- // Find Solarite Components tags and append -solarite-placeholder to their tag names.
2238
+ // Find Solarite Components tags and append -solarite-placeholder to their tag names
2239
+ // and give them a solarite-placeholder attribute so we can easily find them later.
2531
2240
  // This way we can gather their constructor arguments and their children before we call their constructor.
2532
- // Later, NodeGroup.createNewComponent() will replace them with the real components.
2241
+ // Later, NodeGroup.instantiateComponent() will replace them with the real components.
2533
2242
  // Ctrl+F "solarite-placeholder" in project to find all code that manages subcomponents.
2534
- token = token.replace(/^<\/?[a-z][a-z0-9]*-[a-z0-9-]+/i, match => match + '-solarite-placeholder');
2243
+ token = token.replace(/^<\/?[a-z][a-z0-9]*-[a-z0-9-]+/i, match => match + '-solarite-placeholder solarite-placeholder');
2535
2244
  }
2536
2245
  tokens.push(token);
2537
2246
  }
@@ -2702,7 +2411,7 @@ class NodeGroup {
2702
2411
  // Apply exprs
2703
2412
  this.applyExprs(template.exprs);
2704
2413
 
2705
- this.activateStaticComponents(staticComponents);
2414
+ this.instantiateStaticComponents(staticComponents);
2706
2415
  }
2707
2416
  else if (shell)
2708
2417
  this.activateEmbeds(fragment, shell);
@@ -2796,7 +2505,7 @@ class NodeGroup {
2796
2505
  // Think of having two adjacent components.
2797
2506
  // But the dynamicAttribsAdjacet test already passes.
2798
2507
 
2799
- // If a component:
2508
+ // If expr is an attribute in a component:
2800
2509
  // 1. Instantiate it if it hasn't already been, sending all expr's to its constructor.
2801
2510
  // 2. Otherwise send them to its render function.
2802
2511
  // Components with no expressions as attributes are instead activated in activateEmbeds().
@@ -2833,6 +2542,8 @@ class NodeGroup {
2833
2542
  // TODO: Only do this if we have ExprPaths within styles?
2834
2543
  this.updateStyles();
2835
2544
 
2545
+
2546
+
2836
2547
  // Invalidate the nodes cache because we just changed it.
2837
2548
  this.nodesCache = null;
2838
2549
 
@@ -2857,23 +2568,25 @@ class NodeGroup {
2857
2568
  // then we could re-use the hash and logic from NodeManager?
2858
2569
  let newHash = getObjectHash(props);
2859
2570
 
2860
- let isPreHtmlElement = el.tagName.endsWith('-SOLARITE-PLACEHOLDER');
2571
+ let isPreHtmlElement = el.hasAttribute('solarite-placeholder');
2861
2572
  let isPreIsElement = el.hasAttribute('_is');
2862
2573
 
2863
2574
 
2864
2575
  // Instantiate a placeholder.
2865
2576
  if (isPreHtmlElement || isPreIsElement)
2866
- el = this.createNewComponent(el, isPreHtmlElement, props);
2577
+ el = this.instantiateComponent(el, isPreHtmlElement, props);
2867
2578
 
2868
2579
  // Call render() with the same params that would've been passed to the constructor.
2580
+ // We do this even if the arguments haven't changed, so we can let the child component
2581
+ // compare the arguments and then decide for itself whether it wants to re-render.
2869
2582
  else if (el.render) {
2870
- let oldHash = Globals$1.componentArgsHash.get(el);
2871
- if (oldHash !== newHash) {
2583
+ //let oldHash = Globals.componentArgsHash.get(el);
2584
+ //if (oldHash !== newHash) { // Only if not changed.
2872
2585
  let args = {};
2873
2586
  for (let name in props || {})
2874
2587
  args[Util.dashesToCamel(name)] = props[name];
2875
2588
  el.render(args); // Pass new values of props to render so it can decide how it wants to respond.
2876
- }
2589
+ //}
2877
2590
  }
2878
2591
 
2879
2592
  Globals$1.componentArgsHash.set(el, newHash);
@@ -2886,10 +2599,10 @@ class NodeGroup {
2886
2599
  * The logic of this function is complex and could use cleaning up.
2887
2600
  *
2888
2601
  * @param el
2889
- * @param isPreHtmlElement
2602
+ * @param isPreHtmlElement {?boolean} True if the element's tag name ends with -solarite-placeholder
2890
2603
  * @param props {Object} Attributes with dynamic values.
2891
2604
  * @return {HTMLElement} */
2892
- createNewComponent(el, isPreHtmlElement=undefined, props=undefined) {
2605
+ instantiateComponent(el, isPreHtmlElement=undefined, props=undefined) {
2893
2606
  if (isPreHtmlElement === undefined)
2894
2607
  isPreHtmlElement = !el.hasAttribute('_is');
2895
2608
 
@@ -2912,7 +2625,7 @@ class NodeGroup {
2912
2625
  if (el.attributes.length) {
2913
2626
  for (let attrib of el.attributes) {
2914
2627
  let attribName = Util.dashesToCamel(attrib.name);
2915
- if (!args.hasOwnProperty(attribName))
2628
+ if (!args.hasOwnProperty(attribName) && attribName !== 'solarite-placeholder')
2916
2629
  args[attribName] = attrib.value;
2917
2630
  }
2918
2631
  }
@@ -2954,7 +2667,7 @@ class NodeGroup {
2954
2667
 
2955
2668
  // Copy attributes over.
2956
2669
  for (let attrib of el.attributes)
2957
- if (attrib.name !== '_is')
2670
+ if (attrib.name !== '_is' && attrib.name !== 'solarite-placeholder')
2958
2671
  newEl.setAttribute(attrib.name, attrib.value);
2959
2672
 
2960
2673
  // Set dynamic attributes if they are primitive types.
@@ -3114,9 +2827,9 @@ class NodeGroup {
3114
2827
  let result = [];
3115
2828
 
3116
2829
  // static components. These are WebComponents that do not have any constructor arguments that are expressions.
3117
- // Those are instead created by applyExpr() which calls applyComponentExprs() which calls createNewcomponent().
2830
+ // Those are instead created by applyExpr() which calls applyComponentExprs() which calls instantiateComponent().
3118
2831
  // Maybe someday these two paths will be merged?
3119
- // Must happen before ids because createNewComponent will replace the element.
2832
+ // Must happen before ids because instantiateComponent will replace the element.
3120
2833
  for (let path of shell.staticComponents) {
3121
2834
  if (pathOffset)
3122
2835
  path = path.slice(0, -pathOffset);
@@ -3130,13 +2843,13 @@ class NodeGroup {
3130
2843
  return result;
3131
2844
  }
3132
2845
 
3133
- activateStaticComponents(staticComponents) {
2846
+ instantiateStaticComponents(staticComponents) {
3134
2847
  for (let el of staticComponents)
3135
- this.createNewComponent(el);
2848
+ this.instantiateComponent(el);
3136
2849
  }
3137
2850
 
3138
2851
  /**
3139
- * @param root {HTMLElement}
2852
+ * @param root {HTMLElement|DocumentFragment}
3140
2853
  * @param shell {Shell}
3141
2854
  * @param pathOffset {int} */
3142
2855
  activateEmbeds(root, shell, pathOffset=0) {
@@ -3246,7 +2959,7 @@ class RootNodeGroup extends NodeGroup {
3246
2959
 
3247
2960
  // Copy attributes
3248
2961
  for (let attrib of fragment.children[0].attributes)
3249
- if (!el.hasAttribute(attrib.name))
2962
+ if (!el.hasAttribute(attrib.name) && attrib.name !== 'solarite-placeholder')
3250
2963
  el.setAttribute(attrib.name, attrib.value);
3251
2964
 
3252
2965
  // Go one level deeper into all of shell's paths.
@@ -3306,7 +3019,7 @@ class RootNodeGroup extends NodeGroup {
3306
3019
  // Apply exprs
3307
3020
  this.applyExprs(template.exprs);
3308
3021
 
3309
- this.activateStaticComponents(staticComponents);
3022
+ this.instantiateStaticComponents(staticComponents);
3310
3023
  }
3311
3024
  }
3312
3025
  }
@@ -3330,7 +3043,7 @@ function getSingleEl(fragment) {
3330
3043
  * @returns {boolean} */
3331
3044
  function isReplaceEl(fragment, el) {
3332
3045
  return fragment.children.length===1
3333
- && el.tagName.includes('-')
3046
+ && el.tagName.includes('-') // TODO: Check for solarite-placeholder attribute instead?
3334
3047
  && fragment.children[0].tagName.replace('-SOLARITE-PLACEHOLDER', '') === el.tagName;
3335
3048
  }
3336
3049
 
@@ -3502,6 +3215,8 @@ class Template {
3502
3215
  * @return {Node|HTMLElement|Template} */
3503
3216
  function h(htmlStrings=undefined, ...exprs) {
3504
3217
 
3218
+ if (htmlStrings === undefined && !exprs.length && arguments.length)
3219
+ throw new Error('h() cannot be called with undefined.');
3505
3220
 
3506
3221
  // TODO: Make this a more flat if/else and call other functions for the logic.
3507
3222
  if (htmlStrings instanceof Node) {
@@ -3524,7 +3239,7 @@ function h(htmlStrings=undefined, ...exprs) {
3524
3239
  }
3525
3240
 
3526
3241
  // 2. Render template created by #4 to element.
3527
- else if (exprs[0] instanceof Template) {
3242
+ else { // instanceof Template
3528
3243
  let options = exprs[1];
3529
3244
  template.render(parent, options);
3530
3245
 
@@ -3535,16 +3250,6 @@ function h(htmlStrings=undefined, ...exprs) {
3535
3250
  parent.append(this.rootNg.getParentNode());
3536
3251
  }
3537
3252
  }
3538
-
3539
-
3540
-
3541
- // null for expr[0], remove whole element.
3542
- // This path never happens?
3543
- else {
3544
- throw new Error('unsupported');
3545
- //let ngm = NodeGroupManager.get(parent);
3546
- //ngm.render(null, exprs[1])
3547
- }
3548
3253
  }
3549
3254
 
3550
3255
  // 3. Path if used as a template tag.
@@ -3681,7 +3386,7 @@ let renderF = 'render';
3681
3386
  * @param el {HTMLElement}
3682
3387
  * @param attributeName {string} Attribute name. Not case-sensitive.
3683
3388
  * @param defaultValue {*} Default value to use if attribute doesn't exist.
3684
- * @param type {ArgType|function|*[]}
3389
+ * @param type {ArgType|function|Class|*[]}
3685
3390
  * If an array, use the value if it's in the array, otherwise return undefined.
3686
3391
  * If it's a function, pass the value to the function and return the result.
3687
3392
  * @param fallback {*} If the defaultValue is undefiend and type can't be parsed as the given type, use this value.
@@ -3696,8 +3401,11 @@ function getArg(el, attributeName, defaultValue=undefined, type=ArgType.String,
3696
3401
  if (Array.isArray(type))
3697
3402
  return type.includes(val) ? val : fallback;
3698
3403
 
3699
- if (typeof type === 'function')
3700
- return type(val);
3404
+ if (typeof type === 'function') {
3405
+ return type.constructor
3406
+ ? new type(val) // arg type is custom Class
3407
+ : type(val); // arg type is custom function
3408
+ }
3701
3409
 
3702
3410
  // If bool, it's true as long as it exists and its value isn't falsey.
3703
3411
  if (type===ArgType.Bool) {
@@ -3739,6 +3447,24 @@ function getArg(el, attributeName, defaultValue=undefined, type=ArgType.String,
3739
3447
  }
3740
3448
  }
3741
3449
 
3450
+
3451
+ /**
3452
+ * Experimental. Set multiple arguments/attributes all at once.
3453
+ * @param el {HTMLElement}
3454
+ * @param args {Record<string, any>}
3455
+ * @param types {Record<string, ArgType|function|Class>}
3456
+ *
3457
+ * @example
3458
+ * constructor({user, path}={}) {
3459
+ * setArgs(this, arguments[0], {user: User, path: ArgType.String});
3460
+ * }
3461
+ */
3462
+ function setArgs(el, args, types) {
3463
+ for (let name in args)
3464
+ this[name] = getArg(el, name, args[name], types[name] || ArgType.String);
3465
+ }
3466
+
3467
+
3742
3468
  /**
3743
3469
  * @enum */
3744
3470
  var ArgType = {
@@ -3767,6 +3493,158 @@ var ArgType = {
3767
3493
  Eval: 'Eval'
3768
3494
  };
3769
3495
 
3496
+ function defineClass(Class, tagName, extendsTag) {
3497
+ if (!customElements[getName](Class)) { // If not previously defined.
3498
+ tagName = tagName || Util.camelToDashes(Class.name);
3499
+ if (!tagName.includes('-'))
3500
+ tagName += '-element';
3501
+
3502
+ let options = null;
3503
+ if (extendsTag)
3504
+ options = {extends: extendsTag};
3505
+
3506
+ customElements[define](tagName, Class, options);
3507
+ }
3508
+ }
3509
+
3510
+ /**
3511
+ * Create a version of the Solarite class that extends from the given tag name.
3512
+ * Reasons to inherit from this instead of HTMLElement. None of these are all that useful.
3513
+ * 1. customElements.define() is called automatically when you create the first instance.
3514
+ * 2. Calls render() when added to the DOM, if it hasn't been called already.
3515
+ * 3. Child elements are added before constructor is called. But they're also passed to the constructor. (deprecated?)
3516
+ * 4. We can use this.html = r`...` to set html. (deprecated)
3517
+ * 5. We have the onConnect, onFirstConnect, and onDisconnect methods.
3518
+ * Can't figure out how to have these work standalone though, and still be synchronous.
3519
+ * 6. Can we extend from other element types like TR?
3520
+ * 7. Shows default text if render() function isn't defined.
3521
+ *
3522
+ * Advantages to inheriting from HTMLElement
3523
+ * 1. Minimization won't break when it renames the Class and we call customElements.define() on the wrong name.
3524
+ * 2. We can inherit from things like HTMLTableRowElement directly.
3525
+ * 3. There's less magic, since everyone is familiar with defining custom elements.
3526
+ *
3527
+ * @param extendsTag {?string}
3528
+ * @return {Class} */
3529
+ function createSolarite(extendsTag=null) {
3530
+
3531
+ let BaseClass = HTMLElement;
3532
+ if (extendsTag && !extendsTag.includes('-')) {
3533
+ extendsTag = extendsTag.toLowerCase();
3534
+
3535
+ BaseClass = Globals$1.elementClasses[extendsTag];
3536
+ if (!BaseClass) { // TODO: Use Cache
3537
+ BaseClass = document.createElement(extendsTag).constructor;
3538
+ Globals$1.elementClasses[extendsTag] = BaseClass;
3539
+ }
3540
+ }
3541
+
3542
+ /**
3543
+ * Intercept the construct call to auto-define the class before the constructor is called.
3544
+ * @type {HTMLElement} */
3545
+ let HTMLElementAutoDefine = new Proxy(BaseClass, {
3546
+ construct(Parent, args, Class) {
3547
+ defineClass(Class, null, extendsTag);
3548
+
3549
+ // This is a good place to manipulate any args before they're sent to the constructor.
3550
+ // Such as loading them from attributes, if I could find a way to do so.
3551
+
3552
+ // This line is equivalent the to super() call.
3553
+ return Reflect.construct(Parent, args, Class);
3554
+ }
3555
+ });
3556
+
3557
+ return class Solarite extends HTMLElementAutoDefine {
3558
+
3559
+
3560
+ /**
3561
+ * TODO: Make these standalone functions.
3562
+ * Callbacks.
3563
+ * Use onConnect.push(() => ...); to add new callbacks. */
3564
+ onConnect;
3565
+
3566
+ onFirstConnect;
3567
+ onDisconnect;
3568
+
3569
+ /**
3570
+ * @param options {RenderOptions} */
3571
+ constructor(options={}) {
3572
+ super();
3573
+
3574
+ // TODO: Is options.render ever used?
3575
+ if (options.render===true)
3576
+ this.render();
3577
+
3578
+ else if (options.render===false)
3579
+ Globals$1.rendered.add(this); // Don't render on connectedCallback()
3580
+
3581
+ // Add slot children before constructor code executes.
3582
+ // This breaks the styleStaticNested test.
3583
+ // PendingChildren is setup in NodeGroup.instantiateComponent()
3584
+ // TODO: Match named slots.
3585
+ //let ch = Globals.pendingChildren.pop();
3586
+ //if (ch) // TODO: how could there be a slot before render is called?
3587
+ // (this.querySelector('slot') || this).append(...ch);
3588
+
3589
+ /** @deprecated
3590
+ Object.defineProperty(this, 'html', {
3591
+ set(html) {
3592
+ Globals.rendered.add(this);
3593
+ if (typeof html === 'string') {
3594
+ console.warn("Assigning to this.html without the r template prefix.")
3595
+ this.innerHTML = html;
3596
+ }
3597
+ else
3598
+ this.modifications = r(this, html, options);
3599
+ }
3600
+ })*/
3601
+
3602
+ /*
3603
+ let pthis = new Proxy(this, {
3604
+ get(obj, prop) {
3605
+ return Reflect.get(obj, prop)
3606
+ }
3607
+ });
3608
+ this.render = this.render.bind(pthis);
3609
+ */
3610
+ }
3611
+
3612
+ /**
3613
+ * Call render() only if it hasn't already been called. */
3614
+ renderFirstTime() {
3615
+ if (!Globals$1.rendered.has(this) && this.render)
3616
+ this.render();
3617
+ }
3618
+
3619
+ /**
3620
+ * Called automatically by the browser. */
3621
+ connectedCallback() {
3622
+ this.renderFirstTime();
3623
+ if (!Globals$1.connected.has(this)) {
3624
+ Globals$1.connected.add(this);
3625
+ if (this.onFirstConnect)
3626
+ this.onFirstConnect();
3627
+ }
3628
+ if (this.onConnect)
3629
+ this.onConnect();
3630
+ }
3631
+
3632
+ disconnectedCallback() {
3633
+ if (this.onDisconnect)
3634
+ this.onDisconnect();
3635
+ }
3636
+
3637
+
3638
+ static define(tagName=null) {
3639
+ defineClass(this, tagName, extendsTag);
3640
+ }
3641
+ }
3642
+ }
3643
+
3644
+ // Trick to prevent minifier from renaming this method.
3645
+ let define = 'define';
3646
+ let getName = 'getName';
3647
+
3770
3648
  /**
3771
3649
  * Solarite JavasCript UI library.
3772
3650
  * MIT License
@@ -3776,15 +3654,13 @@ var ArgType = {
3776
3654
  /**
3777
3655
  * TODO: The Proxy and the multiple base classes mess up 'instanceof Solarite'
3778
3656
  * @type {Node|Class<HTMLElement>|function(tagName:string):Node|Class<HTMLElement>} */
3779
- let Solarite = new Proxy(createSolarite(), {
3657
+ const Solarite = new Proxy(createSolarite(), {
3780
3658
  apply(self, _, args) {
3781
3659
  return createSolarite(...args)
3782
3660
  }
3783
3661
  });
3784
- let getInputValue = Util.getInputValue;
3785
3662
 
3786
- //Experimental:
3787
3663
  //export {default as watch, renderWatched} from './watch.js'; // unfinished
3788
3664
 
3789
3665
  export default h;
3790
- export { ArgType, Globals$1 as Globals, Solarite, Util as SolariteUtil, Template, delve, getArg, getInputValue, h, h as r };
3666
+ export { ArgType, Globals$1 as Globals, Solarite, Util as SolariteUtil, Template, delve, getArg, h, h as r, setArgs };