vasille 2.2.0 → 2.3.0

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 (43) hide show
  1. package/README.md +34 -28
  2. package/cdn/es2015.js +548 -548
  3. package/cdn/es5.js +616 -608
  4. package/flow-typed/vasille.js +55 -50
  5. package/lib/binding/attribute.js +1 -1
  6. package/lib/binding/binding.js +5 -5
  7. package/lib/binding/class.js +2 -2
  8. package/lib/binding/style.js +1 -1
  9. package/lib/core/core.js +21 -15
  10. package/lib/core/destroyable.js +2 -2
  11. package/lib/core/ivalue.js +4 -4
  12. package/lib/functional/reactivity.js +1 -1
  13. package/lib/index.js +2 -3
  14. package/lib/models/array-model.js +6 -9
  15. package/lib/models/object-model.js +3 -17
  16. package/lib/node/app.js +3 -3
  17. package/lib/node/node.js +53 -42
  18. package/lib/node/watch.js +1 -1
  19. package/lib/v/index.js +1 -1
  20. package/lib/value/expression.js +13 -13
  21. package/lib/value/mirror.js +15 -15
  22. package/lib/value/pointer.js +5 -5
  23. package/lib/value/reference.js +18 -18
  24. package/lib/views/base-view.js +1 -1
  25. package/lib/views/object-view.js +1 -1
  26. package/lib/views/repeat-node.js +4 -4
  27. package/package.json +1 -1
  28. package/types/binding/binding.d.ts +1 -1
  29. package/types/core/core.d.ts +8 -6
  30. package/types/core/destroyable.d.ts +2 -2
  31. package/types/core/ivalue.d.ts +4 -4
  32. package/types/functional/options.d.ts +2 -2
  33. package/types/index.d.ts +3 -4
  34. package/types/models/array-model.d.ts +1 -1
  35. package/types/models/object-model.d.ts +1 -1
  36. package/types/node/node.d.ts +18 -15
  37. package/types/node/watch.d.ts +2 -2
  38. package/types/v/index.d.ts +4 -0
  39. package/types/value/expression.d.ts +5 -5
  40. package/types/value/mirror.d.ts +6 -6
  41. package/types/value/pointer.d.ts +1 -1
  42. package/types/value/reference.d.ts +7 -7
  43. package/types/views/repeat-node.d.ts +3 -3
package/cdn/es2015.js CHANGED
@@ -1,24 +1,4 @@
1
1
  (function(){
2
- // ./lib/v/index.js
3
-
4
- const v = Object.assign(Object.assign({ ref(value) {
5
- return current.ref(value);
6
- }, expr: expr, of: valueOf, sv: setValue, alwaysFalse: new Reference(false), app,
7
- component,
8
- fragment,
9
- extension,
10
- text,
11
- tag,
12
- create }, vx), { merge,
13
- destructor() {
14
- return current.destroy.bind(current);
15
- },
16
- runOnDestroy(callback) {
17
- current.runOnDestroy(callback);
18
- } });
19
-
20
- window.v = v;
21
-
22
2
  // ./lib/models/model.js
23
3
 
24
4
 
@@ -215,6 +195,9 @@ class ObjectModel extends Object {
215
195
  this.listener.emitAdded(key, this.container[key]);
216
196
  return this;
217
197
  }
198
+ get values() {
199
+ return this.container;
200
+ }
218
201
  /**
219
202
  * Deletes an object property
220
203
  * @param key {string} property name
@@ -225,23 +208,6 @@ class ObjectModel extends Object {
225
208
  delete this.container[key];
226
209
  }
227
210
  }
228
- proxy() {
229
- // eslint-disable-next-line @typescript-eslint/no-this-alias
230
- const ts = this;
231
- return new Proxy(this.container, {
232
- get(target, p) {
233
- return ts.get(p);
234
- },
235
- set(target, p, value) {
236
- ts.set(p, value);
237
- return true;
238
- },
239
- deleteProperty(target, p) {
240
- ts.delete(p);
241
- return true;
242
- }
243
- });
244
- }
245
211
  enableReactivity() {
246
212
  this.listener.enableReactivity();
247
213
  }
@@ -407,15 +373,6 @@ class ArrayModel extends Array {
407
373
  super.push(data[i]);
408
374
  }
409
375
  }
410
- // proxy
411
- proxy() {
412
- return new Proxy(this, {
413
- set(target, p, value) {
414
- target.splice(parseInt(p), 1, value);
415
- return true;
416
- }
417
- });
418
- }
419
376
  /* Array members */
420
377
  /**
421
378
  * Gets the last item of array
@@ -596,6 +553,12 @@ class ArrayModel extends Array {
596
553
  this.removeAt(this.indexOf(v));
597
554
  return this;
598
555
  }
556
+ replace(at, with_) {
557
+ this.listener.emitAdded(this[at], with_);
558
+ this.listener.emitRemoved(this[at], this[at]);
559
+ this[at] = with_;
560
+ return this;
561
+ }
599
562
  enableReactivity() {
600
563
  this.listener.enableReactivity();
601
564
  }
@@ -606,387 +569,127 @@ class ArrayModel extends Array {
606
569
 
607
570
  window.ArrayModel = ArrayModel;
608
571
 
609
- // ./lib/functional/merge.js
610
- function merge(main, ...targets) {
611
- function refactorClass(obj) {
612
- if (Array.isArray(obj.class)) {
613
- const out = {
614
- $: []
615
- };
616
- obj.class.forEach(item => {
617
- if (item instanceof IValue) {
618
- out.$.push(item);
619
- }
620
- else if (typeof item === 'string') {
621
- out[item] = true;
622
- }
623
- else if (typeof item === 'object') {
624
- Object.assign(out, item);
625
- }
626
- });
627
- obj.class = out;
628
- }
572
+ // ./lib/core/signal.js
573
+ /**
574
+ * Signal is an event generator
575
+ * @class Signal
576
+ */
577
+ class Signal {
578
+ constructor() {
579
+ /**
580
+ * Handler of event
581
+ * @type {Set}
582
+ * @private
583
+ */
584
+ this.handlers = new Set;
629
585
  }
630
- refactorClass(main);
631
- targets.forEach(target => {
632
- Reflect.ownKeys(target).forEach((prop) => {
633
- if (!Reflect.has(main, prop)) {
634
- main[prop] = target[prop];
586
+ /**
587
+ * Emit event
588
+ * @param a1 {*} argument
589
+ * @param a2 {*} argument
590
+ * @param a3 {*} argument
591
+ * @param a4 {*} argument
592
+ * @param a5 {*} argument
593
+ * @param a6 {*} argument
594
+ * @param a7 {*} argument
595
+ * @param a8 {*} argument
596
+ * @param a9 {*} argument
597
+ */
598
+ emit(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
599
+ this.handlers.forEach(handler => {
600
+ try {
601
+ handler(a1, a2, a3, a4, a5, a6, a7, a8, a9);
635
602
  }
636
- else if (typeof main[prop] === 'object' && typeof target[prop] === 'object') {
637
- if (prop === 'class') {
638
- refactorClass(target);
639
- }
640
- if (prop === '$' && Array.isArray(main[prop]) && Array.isArray(target[prop])) {
641
- main.$.push(...target.$);
642
- }
643
- else {
644
- merge(main[prop], target[prop]);
645
- }
603
+ catch (e) {
604
+ console.error(`Vasille.js: Handler throw exception: `, e);
646
605
  }
647
606
  });
648
- });
607
+ }
608
+ /**
609
+ * Subscribe to event
610
+ * @param func {function} handler
611
+ */
612
+ subscribe(func) {
613
+ this.handlers.add(func);
614
+ }
615
+ /**
616
+ * Unsubscribe from event
617
+ * @param func {function} handler
618
+ */
619
+ unsubscribe(func) {
620
+ this.handlers.delete(func);
621
+ }
649
622
  }
650
623
 
651
- window.merge = merge;
624
+ window.Signal = Signal;
652
625
 
653
- // ./lib/functional/stack.js
654
- function app(renderer) {
655
- return (node, opts) => {
656
- return new App(node, opts).runFunctional(renderer, opts);
657
- };
658
- }
659
- function component(renderer) {
660
- return (opts, callback) => {
661
- const component = new Component(opts);
662
- if (!(current instanceof Fragment))
663
- throw userError('missing parent node', 'out-of-context');
664
- let ret;
665
- if (callback)
666
- opts.slot = callback;
667
- current.create(component, node => {
668
- ret = node.runFunctional(renderer, opts);
669
- });
670
- return ret;
671
- };
626
+ // ./lib/core/slot.js
627
+ /**
628
+ * Component slot
629
+ * @class Slot
630
+ */
631
+ class Slot {
632
+ /**
633
+ * Sets the runner
634
+ * @param func {function} the function to run
635
+ */
636
+ insert(func) {
637
+ this.runner = func;
638
+ }
639
+ /**
640
+ * @param a0 {Fragment} node to paste content
641
+ * @param a1 {*} 1st argument
642
+ * @param a2 {*} 2nd argument
643
+ * @param a3 {*} 3rd argument
644
+ * @param a4 {*} 4th argument
645
+ * @param a5 {*} 5th argument
646
+ * @param a6 {*} 6th argument
647
+ * @param a7 {*} 7th argument
648
+ * @param a8 {*} 8th argument
649
+ * @param a9 {*} 9th argument
650
+ */
651
+ release(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
652
+ if (this.runner) {
653
+ this.runner(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
654
+ }
655
+ }
656
+ /**
657
+ * Predefine a handler for a slot
658
+ * @param func {function(node : Fragment)} Function to run if no handler specified
659
+ * @param a0 {Fragment} node to paste content
660
+ * @param a1 {*} 1st argument
661
+ * @param a2 {*} 2nd argument
662
+ * @param a3 {*} 3rd argument
663
+ * @param a4 {*} 4th argument
664
+ * @param a5 {*} 5th argument
665
+ * @param a6 {*} 6th argument
666
+ * @param a7 {*} 7th argument
667
+ * @param a8 {*} 8th argument
668
+ * @param a9 {*} 9th argument
669
+ */
670
+ predefine(func, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
671
+ (this.runner || func)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
672
+ }
672
673
  }
673
- function fragment(renderer) {
674
- return (opts, callback) => {
675
- const frag = new Fragment(opts);
676
- if (!(current instanceof Fragment))
677
- throw userError('missing parent node', 'out-of-context');
678
- if (callback)
679
- opts.slot = callback;
680
- current.create(frag);
681
- return frag.runFunctional(renderer, opts);
682
- };
674
+
675
+ window.Slot = Slot;
676
+
677
+ // ./lib/core/errors.js
678
+ const reportIt = "Report it here: https://gitlab.com/vasille-js/vasille-js/-/issues";
679
+ function notOverwritten() {
680
+ console.error("Vasille-SFP: Internal error", "Must be overwritten", reportIt);
681
+ return "not-overwritten";
683
682
  }
684
- function extension(renderer) {
685
- return (opts, callback) => {
686
- const ext = new Extension(opts);
687
- if (!(current instanceof Fragment))
688
- throw userError('missing parent node', 'out-of-context');
689
- if (callback)
690
- opts.slot = callback;
691
- current.create(ext);
692
- return ext.runFunctional(renderer, opts);
693
- };
683
+ function internalError(msg) {
684
+ console.error("Vasille-SFP: Internal error", msg, reportIt);
685
+ return "internal-error";
694
686
  }
695
- function tag(name, opts, callback) {
696
- if (!(current instanceof Fragment))
697
- throw userError('missing parent node', 'out-of-context');
698
- return {
699
- node: current.tag(name, opts, (node) => {
700
- callback && node.runFunctional(callback);
701
- })
702
- };
687
+ function userError(msg, err) {
688
+ console.error("Vasille-SFP: User error", msg);
689
+ return err;
703
690
  }
704
- function create(node, callback) {
705
- if (!(current instanceof Fragment))
706
- throw userError('missing current node', 'out-of-context');
707
- current.create(node, (node, ...args) => {
708
- callback && node.runFunctional(callback, ...args);
709
- });
710
- return node;
711
- }
712
- const vx = {
713
- if(condition, callback) {
714
- if (current instanceof Fragment) {
715
- current.if(condition, node => node.runFunctional(callback));
716
- }
717
- else {
718
- throw userError("wrong use of `v.if` function", "logic-error");
719
- }
720
- },
721
- else(callback) {
722
- if (current instanceof Fragment) {
723
- current.else(node => node.runFunctional(callback));
724
- }
725
- else {
726
- throw userError("wrong use of `v.else` function", "logic-error");
727
- }
728
- },
729
- elif(condition, callback) {
730
- if (current instanceof Fragment) {
731
- current.elif(condition, node => node.runFunctional(callback));
732
- }
733
- else {
734
- throw userError("wrong use of `v.elif` function", "logic-error");
735
- }
736
- },
737
- for(model, callback) {
738
- if (model instanceof ArrayModel) {
739
- // for arrays T & K are the same type
740
- create(new ArrayView({ model }), callback);
741
- }
742
- else if (model instanceof MapModel) {
743
- create(new MapView({ model }), callback);
744
- }
745
- else if (model instanceof SetModel) {
746
- // for sets T & K are the same type
747
- create(new SetView({ model }), callback);
748
- }
749
- else if (model instanceof ObjectModel) {
750
- // for objects K is always string
751
- create(new ObjectView({ model }), callback);
752
- }
753
- else {
754
- throw userError("wrong use of `v.for` function", 'wrong-model');
755
- }
756
- },
757
- watch(model, callback) {
758
- const opts = { model };
759
- create(new Watch(opts), callback);
760
- },
761
- nextTick(callback) {
762
- const node = current;
763
- window.setTimeout(() => {
764
- node.runFunctional(callback);
765
- }, 0);
766
- }
767
- };
768
-
769
- window.app = app;
770
- window.component = component;
771
- window.fragment = fragment;
772
- window.extension = extension;
773
- window.tag = tag;
774
- window.create = create;
775
- window.vx = vx;
776
-
777
- // ./lib/functional/models.js
778
- function arrayModel(arr = []) {
779
- if (!current)
780
- throw userError('missing parent node', 'out-of-context');
781
- return current.register(new ArrayModel(arr)).proxy();
782
- }
783
- function mapModel(map = []) {
784
- if (!current)
785
- throw userError('missing parent node', 'out-of-context');
786
- return current.register(new MapModel(map));
787
- }
788
- function setModel(arr = []) {
789
- if (!current)
790
- throw userError('missing parent node', 'out-of-context');
791
- return current.register(new SetModel(arr));
792
- }
793
- function objectModel(obj = {}) {
794
- if (!current)
795
- throw userError('missing parent node', 'out-of-context');
796
- return current.register(new ObjectModel(obj));
797
- }
798
-
799
- window.arrayModel = arrayModel;
800
- window.mapModel = mapModel;
801
- window.setModel = setModel;
802
- window.objectModel = objectModel;
803
-
804
- // ./lib/functional/options.js
805
-
806
-
807
-
808
- // ./lib/functional/reactivity.js
809
- function ref(value) {
810
- const ref = current.ref(value);
811
- return [ref, (value) => ref.$ = value];
812
- }
813
- function mirror(value) {
814
- return current.mirror(value);
815
- }
816
- function forward(value) {
817
- return current.forward(value);
818
- }
819
- function point(value) {
820
- return current.point(value);
821
- }
822
- function expr(func, ...values) {
823
- return current.expr(func, ...values);
824
- }
825
- function watch(func, ...values) {
826
- current.watch(func, ...values);
827
- }
828
- function valueOf(value) {
829
- return value.$;
830
- }
831
- function setValue(ref, value) {
832
- if (ref instanceof Pointer && value instanceof IValue) {
833
- ref.point(value);
834
- }
835
- else {
836
- ref.$ = value instanceof IValue ? value.$ : value;
837
- }
838
- }
839
-
840
- window.ref = ref;
841
- window.mirror = mirror;
842
- window.forward = forward;
843
- window.point = point;
844
- window.expr = expr;
845
- window.watch = watch;
846
- window.valueOf = valueOf;
847
- window.setValue = setValue;
848
-
849
- // ./lib/functional/components.js
850
- function text(text) {
851
- if (!(current instanceof Fragment))
852
- throw userError('missing parent node', 'out-of-context');
853
- ;
854
- current.text(text);
855
- }
856
- function debug(text) {
857
- if (!(current instanceof Fragment))
858
- throw userError('missing parent node', 'out-of-context');
859
- current.debug(text);
860
- }
861
- function predefine(slot, predefined) {
862
- return slot || predefined;
863
- }
864
-
865
- window.text = text;
866
- window.debug = debug;
867
- window.predefine = predefine;
868
-
869
- // ./lib/core/signal.js
870
- /**
871
- * Signal is an event generator
872
- * @class Signal
873
- */
874
- class Signal {
875
- constructor() {
876
- /**
877
- * Handler of event
878
- * @type {Set}
879
- * @private
880
- */
881
- this.handlers = new Set;
882
- }
883
- /**
884
- * Emit event
885
- * @param a1 {*} argument
886
- * @param a2 {*} argument
887
- * @param a3 {*} argument
888
- * @param a4 {*} argument
889
- * @param a5 {*} argument
890
- * @param a6 {*} argument
891
- * @param a7 {*} argument
892
- * @param a8 {*} argument
893
- * @param a9 {*} argument
894
- */
895
- emit(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
896
- this.handlers.forEach(handler => {
897
- try {
898
- handler(a1, a2, a3, a4, a5, a6, a7, a8, a9);
899
- }
900
- catch (e) {
901
- console.error(`Vasille.js: Handler throw exception: `, e);
902
- }
903
- });
904
- }
905
- /**
906
- * Subscribe to event
907
- * @param func {function} handler
908
- */
909
- subscribe(func) {
910
- this.handlers.add(func);
911
- }
912
- /**
913
- * Unsubscribe from event
914
- * @param func {function} handler
915
- */
916
- unsubscribe(func) {
917
- this.handlers.delete(func);
918
- }
919
- }
920
-
921
- window.Signal = Signal;
922
-
923
- // ./lib/core/slot.js
924
- /**
925
- * Component slot
926
- * @class Slot
927
- */
928
- class Slot {
929
- /**
930
- * Sets the runner
931
- * @param func {function} the function to run
932
- */
933
- insert(func) {
934
- this.runner = func;
935
- }
936
- /**
937
- * @param a0 {Fragment} node to paste content
938
- * @param a1 {*} 1st argument
939
- * @param a2 {*} 2nd argument
940
- * @param a3 {*} 3rd argument
941
- * @param a4 {*} 4th argument
942
- * @param a5 {*} 5th argument
943
- * @param a6 {*} 6th argument
944
- * @param a7 {*} 7th argument
945
- * @param a8 {*} 8th argument
946
- * @param a9 {*} 9th argument
947
- */
948
- release(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
949
- if (this.runner) {
950
- this.runner(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
951
- }
952
- }
953
- /**
954
- * Predefine a handler for a slot
955
- * @param func {function(node : Fragment)} Function to run if no handler specified
956
- * @param a0 {Fragment} node to paste content
957
- * @param a1 {*} 1st argument
958
- * @param a2 {*} 2nd argument
959
- * @param a3 {*} 3rd argument
960
- * @param a4 {*} 4th argument
961
- * @param a5 {*} 5th argument
962
- * @param a6 {*} 6th argument
963
- * @param a7 {*} 7th argument
964
- * @param a8 {*} 8th argument
965
- * @param a9 {*} 9th argument
966
- */
967
- predefine(func, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
968
- (this.runner || func)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
969
- }
970
- }
971
-
972
- window.Slot = Slot;
973
-
974
- // ./lib/core/errors.js
975
- const reportIt = "Report it here: https://gitlab.com/vasille-js/vasille-js/-/issues";
976
- function notOverwritten() {
977
- console.error("Vasille-SFP: Internal error", "Must be overwritten", reportIt);
978
- return "not-overwritten";
979
- }
980
- function internalError(msg) {
981
- console.error("Vasille-SFP: Internal error", msg, reportIt);
982
- return "internal-error";
983
- }
984
- function userError(msg, err) {
985
- console.error("Vasille-SFP: User error", msg);
986
- return err;
987
- }
988
- function wrongBinding(msg) {
989
- return userError(msg, "wrong-binding");
691
+ function wrongBinding(msg) {
692
+ return userError(msg, "wrong-binding");
990
693
  }
991
694
 
992
695
  window.notOverwritten = notOverwritten;
@@ -1165,7 +868,7 @@ class Destroyable {
1165
868
  * Make object fields non configurable
1166
869
  * @protected
1167
870
  */
1168
- seal() {
871
+ $seal() {
1169
872
  const $ = this;
1170
873
  Object.keys($).forEach(i => {
1171
874
  // eslint-disable-next-line no-prototype-builtins
@@ -1197,7 +900,7 @@ class Destroyable {
1197
900
  /**
1198
901
  * Garbage collector method
1199
902
  */
1200
- destroy() {
903
+ $destroy() {
1201
904
  // nothing here
1202
905
  }
1203
906
  }
@@ -1209,13 +912,13 @@ class Switchable extends Destroyable {
1209
912
  /**
1210
913
  * Enable update handlers triggering
1211
914
  */
1212
- enable() {
915
+ $enable() {
1213
916
  throw notOverwritten();
1214
917
  }
1215
918
  /**
1216
919
  * disable update handlers triggering
1217
920
  */
1218
- disable() {
921
+ $disable() {
1219
922
  throw notOverwritten();
1220
923
  }
1221
924
  }
@@ -1250,14 +953,14 @@ class IValue extends Switchable {
1250
953
  * Add a new handler to value change
1251
954
  * @param handler {function(value : *)} the handler to add
1252
955
  */
1253
- on(handler) {
956
+ $on(handler) {
1254
957
  throw notOverwritten();
1255
958
  }
1256
959
  /**
1257
960
  * Removes a handler of value change
1258
961
  * @param handler {function(value : *)} the handler to remove
1259
962
  */
1260
- off(handler) {
963
+ $off(handler) {
1261
964
  throw notOverwritten();
1262
965
  }
1263
966
  }
@@ -1317,12 +1020,12 @@ class Expression extends IValue {
1317
1020
  this.values = values;
1318
1021
  this.func = handler;
1319
1022
  if (link) {
1320
- this.enable();
1023
+ this.$enable();
1321
1024
  }
1322
1025
  else {
1323
1026
  handler();
1324
1027
  }
1325
- this.seal();
1028
+ this.$seal();
1326
1029
  }
1327
1030
  get $() {
1328
1031
  return this.sync.$;
@@ -1330,18 +1033,18 @@ class Expression extends IValue {
1330
1033
  set $(value) {
1331
1034
  this.sync.$ = value;
1332
1035
  }
1333
- on(handler) {
1334
- this.sync.on(handler);
1036
+ $on(handler) {
1037
+ this.sync.$on(handler);
1335
1038
  return this;
1336
1039
  }
1337
- off(handler) {
1338
- this.sync.off(handler);
1040
+ $off(handler) {
1041
+ this.sync.$off(handler);
1339
1042
  return this;
1340
1043
  }
1341
- enable() {
1044
+ $enable() {
1342
1045
  if (!this.isEnabled) {
1343
1046
  for (let i = 0; i < this.values.length; i++) {
1344
- this.values[i].on(this.linkedFunc[i]);
1047
+ this.values[i].$on(this.linkedFunc[i]);
1345
1048
  this.valuesCache[i] = this.values[i].$;
1346
1049
  }
1347
1050
  this.func();
@@ -1349,21 +1052,21 @@ class Expression extends IValue {
1349
1052
  }
1350
1053
  return this;
1351
1054
  }
1352
- disable() {
1055
+ $disable() {
1353
1056
  if (this.isEnabled) {
1354
1057
  for (let i = 0; i < this.values.length; i++) {
1355
- this.values[i].off(this.linkedFunc[i]);
1058
+ this.values[i].$off(this.linkedFunc[i]);
1356
1059
  }
1357
1060
  this.isEnabled = false;
1358
1061
  }
1359
1062
  return this;
1360
1063
  }
1361
- destroy() {
1362
- this.disable();
1064
+ $destroy() {
1065
+ this.$disable();
1363
1066
  this.values.splice(0);
1364
1067
  this.valuesCache.splice(0);
1365
1068
  this.linkedFunc.splice(0);
1366
- super.destroy();
1069
+ super.$destroy();
1367
1070
  }
1368
1071
  }
1369
1072
 
@@ -1381,43 +1084,43 @@ class Reference extends IValue {
1381
1084
  */
1382
1085
  constructor(value) {
1383
1086
  super(true);
1384
- this.value = value;
1385
- this.onchange = new Set;
1386
- this.seal();
1087
+ this.$value = value;
1088
+ this.$onchange = new Set;
1089
+ this.$seal();
1387
1090
  }
1388
1091
  get $() {
1389
- return this.value;
1092
+ return this.$value;
1390
1093
  }
1391
1094
  set $(value) {
1392
- if (this.value !== value) {
1393
- this.value = value;
1095
+ if (this.$value !== value) {
1096
+ this.$value = value;
1394
1097
  if (this.isEnabled) {
1395
- this.onchange.forEach(handler => {
1098
+ this.$onchange.forEach(handler => {
1396
1099
  handler(value);
1397
1100
  });
1398
1101
  }
1399
1102
  }
1400
1103
  }
1401
- enable() {
1104
+ $enable() {
1402
1105
  if (!this.isEnabled) {
1403
- this.onchange.forEach(handler => {
1404
- handler(this.value);
1106
+ this.$onchange.forEach(handler => {
1107
+ handler(this.$value);
1405
1108
  });
1406
1109
  this.isEnabled = true;
1407
1110
  }
1408
1111
  }
1409
- disable() {
1112
+ $disable() {
1410
1113
  this.isEnabled = false;
1411
1114
  }
1412
- on(handler) {
1413
- this.onchange.add(handler);
1115
+ $on(handler) {
1116
+ this.$onchange.add(handler);
1414
1117
  }
1415
- off(handler) {
1416
- this.onchange.delete(handler);
1118
+ $off(handler) {
1119
+ this.$onchange.delete(handler);
1417
1120
  }
1418
- destroy() {
1419
- super.destroy();
1420
- this.onchange.clear();
1121
+ $destroy() {
1122
+ super.$destroy();
1123
+ this.$onchange.clear();
1421
1124
  }
1422
1125
  }
1423
1126
 
@@ -1438,13 +1141,13 @@ class Mirror extends Reference {
1438
1141
  */
1439
1142
  constructor(value, forwardOnly = false) {
1440
1143
  super(value.$);
1441
- this.handler = (v) => {
1144
+ this.$handler = (v) => {
1442
1145
  this.$ = v;
1443
1146
  };
1444
- this.pointedValue = value;
1445
- this.forwardOnly = forwardOnly;
1446
- value.on(this.handler);
1447
- this.seal();
1147
+ this.$pointedValue = value;
1148
+ this.$forwardOnly = forwardOnly;
1149
+ value.$on(this.$handler);
1150
+ this.$seal();
1448
1151
  }
1449
1152
  get $() {
1450
1153
  // this is a ts bug
@@ -1453,30 +1156,30 @@ class Mirror extends Reference {
1453
1156
  return super.$;
1454
1157
  }
1455
1158
  set $(v) {
1456
- if (!this.forwardOnly) {
1457
- this.pointedValue.$ = v;
1159
+ if (!this.$forwardOnly) {
1160
+ this.$pointedValue.$ = v;
1458
1161
  }
1459
1162
  // this is a ts bug
1460
1163
  // eslint-disable-next-line
1461
1164
  // @ts-ignore
1462
1165
  super.$ = v;
1463
1166
  }
1464
- enable() {
1167
+ $enable() {
1465
1168
  if (!this.isEnabled) {
1466
1169
  this.isEnabled = true;
1467
- this.pointedValue.on(this.handler);
1468
- this.$ = this.pointedValue.$;
1170
+ this.$pointedValue.$on(this.$handler);
1171
+ this.$ = this.$pointedValue.$;
1469
1172
  }
1470
1173
  }
1471
- disable() {
1174
+ $disable() {
1472
1175
  if (this.isEnabled) {
1473
- this.pointedValue.off(this.handler);
1176
+ this.$pointedValue.$off(this.$handler);
1474
1177
  this.isEnabled = false;
1475
1178
  }
1476
1179
  }
1477
- destroy() {
1478
- this.disable();
1479
- super.destroy();
1180
+ $destroy() {
1181
+ this.$disable();
1182
+ super.$destroy();
1480
1183
  }
1481
1184
  }
1482
1185
 
@@ -1500,11 +1203,11 @@ class Pointer extends Mirror {
1500
1203
  * Point a new ivalue
1501
1204
  * @param value {IValue} value to point
1502
1205
  */
1503
- point(value) {
1504
- if (this.pointedValue !== value) {
1505
- this.disable();
1506
- this.pointedValue = value;
1507
- this.enable();
1206
+ set $$(value) {
1207
+ if (this.$pointedValue !== value) {
1208
+ this.$disable();
1209
+ this.$pointedValue = value;
1210
+ this.$enable();
1508
1211
  }
1509
1212
  }
1510
1213
  }
@@ -1525,19 +1228,19 @@ class Binding extends Destroyable {
1525
1228
  constructor(value) {
1526
1229
  super();
1527
1230
  this.binding = value;
1528
- this.seal();
1231
+ this.$seal();
1529
1232
  }
1530
1233
  init(bounded) {
1531
1234
  this.func = bounded;
1532
- this.binding.on(this.func);
1235
+ this.binding.$on(this.func);
1533
1236
  this.func(this.binding.$);
1534
1237
  }
1535
1238
  /**
1536
1239
  * Just clear bindings
1537
1240
  */
1538
- destroy() {
1539
- this.binding.off(this.func);
1540
- super.destroy();
1241
+ $destroy() {
1242
+ this.binding.$off(this.func);
1243
+ super.$destroy();
1541
1244
  }
1542
1245
  }
1543
1246
 
@@ -1585,18 +1288,18 @@ class ReactivePrivate extends Destroyable {
1585
1288
  * @type {boolean}
1586
1289
  */
1587
1290
  this.frozen = false;
1588
- this.seal();
1291
+ this.$seal();
1589
1292
  }
1590
- destroy() {
1591
- this.watch.forEach(value => value.destroy());
1293
+ $destroy() {
1294
+ this.watch.forEach(value => value.$destroy());
1592
1295
  this.watch.clear();
1593
- this.bindings.forEach(binding => binding.destroy());
1296
+ this.bindings.forEach(binding => binding.$destroy());
1594
1297
  this.bindings.clear();
1595
1298
  this.models.forEach(model => model.disableReactivity());
1596
1299
  this.models.clear();
1597
- this.freezeExpr && this.freezeExpr.destroy();
1300
+ this.freezeExpr && this.freezeExpr.$destroy();
1598
1301
  this.onDestroy && this.onDestroy();
1599
- super.destroy();
1302
+ super.$destroy();
1600
1303
  }
1601
1304
  }
1602
1305
  /**
@@ -1609,7 +1312,7 @@ class Reactive extends Destroyable {
1609
1312
  super();
1610
1313
  this.input = input;
1611
1314
  this.$ = $ || new ReactivePrivate;
1612
- this.seal();
1315
+ this.$seal();
1613
1316
  }
1614
1317
  /**
1615
1318
  * Get parent node
@@ -1692,7 +1395,7 @@ class Reactive extends Destroyable {
1692
1395
  const $ = this.$;
1693
1396
  if (!$.enabled) {
1694
1397
  $.watch.forEach(watcher => {
1695
- watcher.enable();
1398
+ watcher.$enable();
1696
1399
  });
1697
1400
  $.models.forEach(model => {
1698
1401
  model.enableReactivity();
@@ -1707,7 +1410,7 @@ class Reactive extends Destroyable {
1707
1410
  const $ = this.$;
1708
1411
  if ($.enabled) {
1709
1412
  $.watch.forEach(watcher => {
1710
- watcher.disable();
1413
+ watcher.$disable();
1711
1414
  });
1712
1415
  $.models.forEach(model => {
1713
1416
  model.disableReactivity();
@@ -1744,13 +1447,19 @@ class Reactive extends Destroyable {
1744
1447
  }
1745
1448
  init() {
1746
1449
  this.applyOptions(this.input);
1747
- this.compose(this.input);
1450
+ return this.compose(this.input);
1748
1451
  }
1749
1452
  applyOptions(input) {
1750
1453
  // empty
1751
1454
  }
1455
+ applyOptionsNow() {
1456
+ this.applyOptions(this.input);
1457
+ }
1752
1458
  compose(input) {
1753
- // empty
1459
+ throw notOverwritten();
1460
+ }
1461
+ composeNow() {
1462
+ this.compose(this.input);
1754
1463
  }
1755
1464
  runFunctional(f, ...args) {
1756
1465
  stack(this);
@@ -1764,9 +1473,9 @@ class Reactive extends Destroyable {
1764
1473
  runOnDestroy(func) {
1765
1474
  this.$.onDestroy = func;
1766
1475
  }
1767
- destroy() {
1768
- super.destroy();
1769
- this.$.destroy();
1476
+ $destroy() {
1477
+ super.$destroy();
1478
+ this.$.$destroy();
1770
1479
  this.$ = null;
1771
1480
  }
1772
1481
  }
@@ -1783,7 +1492,7 @@ window.Reactive = Reactive;
1783
1492
  class FragmentPrivate extends ReactivePrivate {
1784
1493
  constructor() {
1785
1494
  super();
1786
- this.seal();
1495
+ this.$seal();
1787
1496
  }
1788
1497
  /**
1789
1498
  * Pre-initializes the base of a fragment
@@ -1797,10 +1506,10 @@ class FragmentPrivate extends ReactivePrivate {
1797
1506
  /**
1798
1507
  * Unlinks all bindings
1799
1508
  */
1800
- destroy() {
1509
+ $destroy() {
1801
1510
  this.next = null;
1802
1511
  this.prev = null;
1803
- super.destroy();
1512
+ super.$destroy();
1804
1513
  }
1805
1514
  }
1806
1515
  /**
@@ -1838,8 +1547,12 @@ class Fragment extends Reactive {
1838
1547
  const $ = this.$;
1839
1548
  $.preinit(app, parent);
1840
1549
  }
1550
+ init() {
1551
+ const ret = super.init();
1552
+ this.ready();
1553
+ return ret;
1554
+ }
1841
1555
  compose(input) {
1842
- super.compose(input);
1843
1556
  input.slot && input.slot(this);
1844
1557
  }
1845
1558
  /** To be overloaded: ready event handler */
@@ -1947,8 +1660,7 @@ class Fragment extends Reactive {
1947
1660
  node.preinit($.app, this);
1948
1661
  node.input.slot = callback || node.input.slot;
1949
1662
  this.pushNode(node);
1950
- node.init();
1951
- node.ready();
1663
+ return node.init();
1952
1664
  }
1953
1665
  /**
1954
1666
  * Defines an if node
@@ -2020,14 +1732,14 @@ class Fragment extends Reactive {
2020
1732
  $.prev.$.next = $.next;
2021
1733
  }
2022
1734
  }
2023
- destroy() {
2024
- this.children.forEach(child => child.destroy());
1735
+ $destroy() {
1736
+ this.children.forEach(child => child.$destroy());
2025
1737
  this.children.clear();
2026
1738
  this.lastChild = null;
2027
1739
  if (this.$.parent.lastChild === this) {
2028
1740
  this.$.parent.lastChild = this.$.prev;
2029
1741
  }
2030
- super.destroy();
1742
+ super.$destroy();
2031
1743
  }
2032
1744
  }
2033
1745
  const trueIValue = new Reference(true);
@@ -2039,7 +1751,7 @@ const trueIValue = new Reference(true);
2039
1751
  class TextNodePrivate extends FragmentPrivate {
2040
1752
  constructor() {
2041
1753
  super();
2042
- this.seal();
1754
+ this.$seal();
2043
1755
  }
2044
1756
  /**
2045
1757
  * Pre-initializes a text node
@@ -2059,8 +1771,8 @@ class TextNodePrivate extends FragmentPrivate {
2059
1771
  /**
2060
1772
  * Clear node data
2061
1773
  */
2062
- destroy() {
2063
- super.destroy();
1774
+ $destroy() {
1775
+ super.$destroy();
2064
1776
  }
2065
1777
  }
2066
1778
  /**
@@ -2071,7 +1783,7 @@ class TextNodePrivate extends FragmentPrivate {
2071
1783
  class TextNode extends Fragment {
2072
1784
  constructor($ = new TextNodePrivate()) {
2073
1785
  super({}, $);
2074
- this.seal();
1786
+ this.$seal();
2075
1787
  }
2076
1788
  preinit(app, parent, text) {
2077
1789
  const $ = this.$;
@@ -2084,10 +1796,10 @@ class TextNode extends Fragment {
2084
1796
  findFirstChild() {
2085
1797
  return this.$.node;
2086
1798
  }
2087
- destroy() {
1799
+ $destroy() {
2088
1800
  this.$.node.remove();
2089
- this.$.destroy();
2090
- super.destroy();
1801
+ this.$.$destroy();
1802
+ super.$destroy();
2091
1803
  }
2092
1804
  }
2093
1805
  /**
@@ -2103,10 +1815,10 @@ class INodePrivate extends FragmentPrivate {
2103
1815
  * @type {boolean}
2104
1816
  */
2105
1817
  this.unmounted = false;
2106
- this.seal();
1818
+ this.$seal();
2107
1819
  }
2108
- destroy() {
2109
- super.destroy();
1820
+ $destroy() {
1821
+ super.$destroy();
2110
1822
  }
2111
1823
  }
2112
1824
  /**
@@ -2122,7 +1834,7 @@ class INode extends Fragment {
2122
1834
  */
2123
1835
  constructor(input, $) {
2124
1836
  super(input, $ || new INodePrivate);
2125
- this.seal();
1837
+ this.$seal();
2126
1838
  }
2127
1839
  /**
2128
1840
  * Get the bound node
@@ -2365,7 +2077,7 @@ class INode extends Fragment {
2365
2077
  class Tag extends INode {
2366
2078
  constructor(input) {
2367
2079
  super(input);
2368
- this.seal();
2080
+ this.$seal();
2369
2081
  }
2370
2082
  preinit(app, parent, tagName) {
2371
2083
  if (!tagName || typeof tagName !== "string") {
@@ -2418,9 +2130,9 @@ class Tag extends INode {
2418
2130
  /**
2419
2131
  * Runs GC
2420
2132
  */
2421
- destroy() {
2133
+ $destroy() {
2422
2134
  this.node.remove();
2423
- super.destroy();
2135
+ super.$destroy();
2424
2136
  }
2425
2137
  }
2426
2138
  /**
@@ -2443,8 +2155,11 @@ class Extension extends INode {
2443
2155
  throw userError("A extension node can be encapsulated only in a tag/extension/component", "virtual-dom");
2444
2156
  }
2445
2157
  }
2446
- destroy() {
2447
- super.destroy();
2158
+ extend(options) {
2159
+ this.applyOptions(options);
2160
+ }
2161
+ $destroy() {
2162
+ super.$destroy();
2448
2163
  }
2449
2164
  }
2450
2165
  /**
@@ -2453,6 +2168,11 @@ class Extension extends INode {
2453
2168
  * @extends Extension
2454
2169
  */
2455
2170
  class Component extends Extension {
2171
+ init() {
2172
+ super.composeNow();
2173
+ this.ready();
2174
+ super.applyOptionsNow();
2175
+ }
2456
2176
  ready() {
2457
2177
  super.ready();
2458
2178
  if (this.children.size !== 1) {
@@ -2484,18 +2204,18 @@ class SwitchedNodePrivate extends FragmentPrivate {
2484
2204
  * @type {Array<{cond : IValue<boolean>, cb : function(Fragment)}>}
2485
2205
  */
2486
2206
  this.cases = [];
2487
- this.seal();
2207
+ this.$seal();
2488
2208
  }
2489
2209
  /**
2490
2210
  * Runs GC
2491
2211
  */
2492
- destroy() {
2212
+ $destroy() {
2493
2213
  this.cases.forEach(c => {
2494
2214
  delete c.cond;
2495
2215
  delete c.cb;
2496
2216
  });
2497
2217
  this.cases.splice(0);
2498
- super.destroy();
2218
+ super.$destroy();
2499
2219
  }
2500
2220
  }
2501
2221
  /**
@@ -2519,7 +2239,7 @@ class SwitchedNode extends Fragment {
2519
2239
  return;
2520
2240
  }
2521
2241
  if (this.lastChild) {
2522
- this.lastChild.destroy();
2242
+ this.lastChild.$destroy();
2523
2243
  this.children.clear();
2524
2244
  this.lastChild = null;
2525
2245
  }
@@ -2531,11 +2251,11 @@ class SwitchedNode extends Fragment {
2531
2251
  $.index = -1;
2532
2252
  }
2533
2253
  };
2534
- this.seal();
2254
+ this.$seal();
2535
2255
  }
2536
2256
  addCase(case_) {
2537
2257
  this.$.cases.push(case_);
2538
- case_.cond.on(this.$.sync);
2258
+ case_.cond.$on(this.$.sync);
2539
2259
  this.$.sync();
2540
2260
  }
2541
2261
  /**
@@ -2553,16 +2273,16 @@ class SwitchedNode extends Fragment {
2553
2273
  ready() {
2554
2274
  const $ = this.$;
2555
2275
  $.cases.forEach(c => {
2556
- c.cond.on($.sync);
2276
+ c.cond.$on($.sync);
2557
2277
  });
2558
2278
  $.sync();
2559
2279
  }
2560
- destroy() {
2280
+ $destroy() {
2561
2281
  const $ = this.$;
2562
2282
  $.cases.forEach(c => {
2563
- c.cond.off($.sync);
2283
+ c.cond.$off($.sync);
2564
2284
  });
2565
- super.destroy();
2285
+ super.$destroy();
2566
2286
  }
2567
2287
  }
2568
2288
  /**
@@ -2571,7 +2291,7 @@ class SwitchedNode extends Fragment {
2571
2291
  class DebugPrivate extends FragmentPrivate {
2572
2292
  constructor() {
2573
2293
  super();
2574
- this.seal();
2294
+ this.$seal();
2575
2295
  }
2576
2296
  /**
2577
2297
  * Pre-initializes a text node
@@ -2590,9 +2310,9 @@ class DebugPrivate extends FragmentPrivate {
2590
2310
  /**
2591
2311
  * Clear node data
2592
2312
  */
2593
- destroy() {
2313
+ $destroy() {
2594
2314
  this.node.remove();
2595
- super.destroy();
2315
+ super.$destroy();
2596
2316
  }
2597
2317
  }
2598
2318
  /**
@@ -2608,7 +2328,7 @@ class DebugNode extends Fragment {
2608
2328
  * @type {DebugNode}
2609
2329
  */
2610
2330
  this.$ = new DebugPrivate();
2611
- this.seal();
2331
+ this.$seal();
2612
2332
  }
2613
2333
  preinit(app, parent, text) {
2614
2334
  const $ = this.$;
@@ -2620,9 +2340,9 @@ class DebugNode extends Fragment {
2620
2340
  /**
2621
2341
  * Runs garbage collector
2622
2342
  */
2623
- destroy() {
2624
- this.$.destroy();
2625
- super.destroy();
2343
+ $destroy() {
2344
+ this.$.$destroy();
2345
+ super.$destroy();
2626
2346
  }
2627
2347
  }
2628
2348
 
@@ -2653,7 +2373,7 @@ class AppNode extends INode {
2653
2373
  constructor(input) {
2654
2374
  super(input);
2655
2375
  this.debugUi = input.debugUi || false;
2656
- this.seal();
2376
+ this.$seal();
2657
2377
  }
2658
2378
  }
2659
2379
  /**
@@ -2672,7 +2392,7 @@ class App extends AppNode {
2672
2392
  this.$.node = node;
2673
2393
  this.preinit(this, this);
2674
2394
  this.init();
2675
- this.seal();
2395
+ this.$seal();
2676
2396
  }
2677
2397
  appendNode(node) {
2678
2398
  this.$.node.appendChild(node);
@@ -2682,7 +2402,7 @@ class Portal extends AppNode {
2682
2402
  constructor(input) {
2683
2403
  super(input);
2684
2404
  this.$.node = input.node;
2685
- this.seal();
2405
+ this.$seal();
2686
2406
  }
2687
2407
  appendNode(node) {
2688
2408
  this.$.node.appendChild(node);
@@ -2805,7 +2525,7 @@ class AttributeBinding extends Binding {
2805
2525
  node.node.removeAttribute(name);
2806
2526
  }
2807
2527
  });
2808
- this.seal();
2528
+ this.$seal();
2809
2529
  }
2810
2530
  }
2811
2531
 
@@ -2831,7 +2551,7 @@ class StyleBinding extends Binding {
2831
2551
  node.node.style.setProperty(name, value);
2832
2552
  }
2833
2553
  });
2834
- this.seal();
2554
+ this.$seal();
2835
2555
  }
2836
2556
  }
2837
2557
 
@@ -2859,7 +2579,7 @@ class StaticClassBinding extends Binding {
2859
2579
  this.current = value;
2860
2580
  }
2861
2581
  });
2862
- this.seal();
2582
+ this.$seal();
2863
2583
  }
2864
2584
  }
2865
2585
  class DynamicalClassBinding extends Binding {
@@ -2877,7 +2597,7 @@ class DynamicalClassBinding extends Binding {
2877
2597
  this.current = value;
2878
2598
  }
2879
2599
  });
2880
- this.seal();
2600
+ this.$seal();
2881
2601
  }
2882
2602
  }
2883
2603
 
@@ -2898,11 +2618,11 @@ class RepeatNodePrivate extends INodePrivate {
2898
2618
  * @type {Map}
2899
2619
  */
2900
2620
  this.nodes = new Map();
2901
- this.seal();
2621
+ this.$seal();
2902
2622
  }
2903
- destroy() {
2623
+ $destroy() {
2904
2624
  this.nodes.clear();
2905
- super.destroy();
2625
+ super.$destroy();
2906
2626
  }
2907
2627
  }
2908
2628
  /**
@@ -2944,7 +2664,7 @@ class RepeatNode extends Fragment {
2944
2664
  const child = $.nodes.get(id);
2945
2665
  if (child) {
2946
2666
  child.remove();
2947
- child.destroy();
2667
+ child.$destroy();
2948
2668
  this.$.nodes.delete(id);
2949
2669
  this.children.delete(child);
2950
2670
  }
@@ -3029,7 +2749,7 @@ window.Repeater = Repeater;
3029
2749
  class BaseViewPrivate extends RepeatNodePrivate {
3030
2750
  constructor() {
3031
2751
  super();
3032
- this.seal();
2752
+ this.$seal();
3033
2753
  }
3034
2754
  }
3035
2755
  /**
@@ -3092,7 +2812,7 @@ class Watch extends Fragment {
3092
2812
  compose(input) {
3093
2813
  this.watch((value) => {
3094
2814
  this.children.forEach(child => {
3095
- child.destroy();
2815
+ child.$destroy();
3096
2816
  });
3097
2817
  this.children.clear();
3098
2818
  this.lastChild = null;
@@ -3113,7 +2833,7 @@ window.Watch = Watch;
3113
2833
  class ObjectView extends BaseView {
3114
2834
  compose(input) {
3115
2835
  super.compose(input);
3116
- const obj = input.model.proxy();
2836
+ const obj = input.model.values;
3117
2837
  for (const key in obj) {
3118
2838
  this.createChild(input, key, obj[key]);
3119
2839
  }
@@ -3158,4 +2878,284 @@ class SetView extends BaseView {
3158
2878
 
3159
2879
  window.SetView = SetView;
3160
2880
 
2881
+ // ./lib/functional/merge.js
2882
+ function merge(main, ...targets) {
2883
+ function refactorClass(obj) {
2884
+ if (Array.isArray(obj.class)) {
2885
+ const out = {
2886
+ $: []
2887
+ };
2888
+ obj.class.forEach(item => {
2889
+ if (item instanceof IValue) {
2890
+ out.$.push(item);
2891
+ }
2892
+ else if (typeof item === 'string') {
2893
+ out[item] = true;
2894
+ }
2895
+ else if (typeof item === 'object') {
2896
+ Object.assign(out, item);
2897
+ }
2898
+ });
2899
+ obj.class = out;
2900
+ }
2901
+ }
2902
+ refactorClass(main);
2903
+ targets.forEach(target => {
2904
+ Reflect.ownKeys(target).forEach((prop) => {
2905
+ if (!Reflect.has(main, prop)) {
2906
+ main[prop] = target[prop];
2907
+ }
2908
+ else if (typeof main[prop] === 'object' && typeof target[prop] === 'object') {
2909
+ if (prop === 'class') {
2910
+ refactorClass(target);
2911
+ }
2912
+ if (prop === '$' && Array.isArray(main[prop]) && Array.isArray(target[prop])) {
2913
+ main.$.push(...target.$);
2914
+ }
2915
+ else {
2916
+ merge(main[prop], target[prop]);
2917
+ }
2918
+ }
2919
+ });
2920
+ });
2921
+ }
2922
+
2923
+ window.merge = merge;
2924
+
2925
+ // ./lib/functional/stack.js
2926
+ function app(renderer) {
2927
+ return (node, opts) => {
2928
+ return new App(node, opts).runFunctional(renderer, opts);
2929
+ };
2930
+ }
2931
+ function component(renderer) {
2932
+ return (opts, callback) => {
2933
+ const component = new Component(opts);
2934
+ if (!(current instanceof Fragment))
2935
+ throw userError('missing parent node', 'out-of-context');
2936
+ let ret;
2937
+ if (callback)
2938
+ opts.slot = callback;
2939
+ current.create(component, node => {
2940
+ ret = node.runFunctional(renderer, opts);
2941
+ });
2942
+ return ret;
2943
+ };
2944
+ }
2945
+ function fragment(renderer) {
2946
+ return (opts, callback) => {
2947
+ const frag = new Fragment(opts);
2948
+ if (!(current instanceof Fragment))
2949
+ throw userError('missing parent node', 'out-of-context');
2950
+ if (callback)
2951
+ opts.slot = callback;
2952
+ current.create(frag);
2953
+ return frag.runFunctional(renderer, opts);
2954
+ };
2955
+ }
2956
+ function extension(renderer) {
2957
+ return (opts, callback) => {
2958
+ const ext = new Extension(opts);
2959
+ if (!(current instanceof Fragment))
2960
+ throw userError('missing parent node', 'out-of-context');
2961
+ if (callback)
2962
+ opts.slot = callback;
2963
+ current.create(ext);
2964
+ return ext.runFunctional(renderer, opts);
2965
+ };
2966
+ }
2967
+ function tag(name, opts, callback) {
2968
+ if (!(current instanceof Fragment))
2969
+ throw userError('missing parent node', 'out-of-context');
2970
+ return {
2971
+ node: current.tag(name, opts, (node) => {
2972
+ callback && node.runFunctional(callback);
2973
+ })
2974
+ };
2975
+ }
2976
+ function create(node, callback) {
2977
+ if (!(current instanceof Fragment))
2978
+ throw userError('missing current node', 'out-of-context');
2979
+ current.create(node, (node, ...args) => {
2980
+ callback && node.runFunctional(callback, ...args);
2981
+ });
2982
+ return node;
2983
+ }
2984
+ const vx = {
2985
+ if(condition, callback) {
2986
+ if (current instanceof Fragment) {
2987
+ current.if(condition, node => node.runFunctional(callback));
2988
+ }
2989
+ else {
2990
+ throw userError("wrong use of `v.if` function", "logic-error");
2991
+ }
2992
+ },
2993
+ else(callback) {
2994
+ if (current instanceof Fragment) {
2995
+ current.else(node => node.runFunctional(callback));
2996
+ }
2997
+ else {
2998
+ throw userError("wrong use of `v.else` function", "logic-error");
2999
+ }
3000
+ },
3001
+ elif(condition, callback) {
3002
+ if (current instanceof Fragment) {
3003
+ current.elif(condition, node => node.runFunctional(callback));
3004
+ }
3005
+ else {
3006
+ throw userError("wrong use of `v.elif` function", "logic-error");
3007
+ }
3008
+ },
3009
+ for(model, callback) {
3010
+ if (model instanceof ArrayModel) {
3011
+ // for arrays T & K are the same type
3012
+ create(new ArrayView({ model }), callback);
3013
+ }
3014
+ else if (model instanceof MapModel) {
3015
+ create(new MapView({ model }), callback);
3016
+ }
3017
+ else if (model instanceof SetModel) {
3018
+ // for sets T & K are the same type
3019
+ create(new SetView({ model }), callback);
3020
+ }
3021
+ else if (model instanceof ObjectModel) {
3022
+ // for objects K is always string
3023
+ create(new ObjectView({ model }), callback);
3024
+ }
3025
+ else {
3026
+ throw userError("wrong use of `v.for` function", 'wrong-model');
3027
+ }
3028
+ },
3029
+ watch(model, callback) {
3030
+ const opts = { model };
3031
+ create(new Watch(opts), callback);
3032
+ },
3033
+ nextTick(callback) {
3034
+ const node = current;
3035
+ window.setTimeout(() => {
3036
+ node.runFunctional(callback);
3037
+ }, 0);
3038
+ }
3039
+ };
3040
+
3041
+ window.app = app;
3042
+ window.component = component;
3043
+ window.fragment = fragment;
3044
+ window.extension = extension;
3045
+ window.tag = tag;
3046
+ window.create = create;
3047
+ window.vx = vx;
3048
+
3049
+ // ./lib/functional/models.js
3050
+ function arrayModel(arr = []) {
3051
+ if (!current)
3052
+ throw userError('missing parent node', 'out-of-context');
3053
+ return current.register(new ArrayModel(arr)).proxy();
3054
+ }
3055
+ function mapModel(map = []) {
3056
+ if (!current)
3057
+ throw userError('missing parent node', 'out-of-context');
3058
+ return current.register(new MapModel(map));
3059
+ }
3060
+ function setModel(arr = []) {
3061
+ if (!current)
3062
+ throw userError('missing parent node', 'out-of-context');
3063
+ return current.register(new SetModel(arr));
3064
+ }
3065
+ function objectModel(obj = {}) {
3066
+ if (!current)
3067
+ throw userError('missing parent node', 'out-of-context');
3068
+ return current.register(new ObjectModel(obj));
3069
+ }
3070
+
3071
+ window.arrayModel = arrayModel;
3072
+ window.mapModel = mapModel;
3073
+ window.setModel = setModel;
3074
+ window.objectModel = objectModel;
3075
+
3076
+ // ./lib/functional/options.js
3077
+
3078
+
3079
+
3080
+ // ./lib/functional/reactivity.js
3081
+ function ref(value) {
3082
+ const ref = current.ref(value);
3083
+ return [ref, (value) => ref.$ = value];
3084
+ }
3085
+ function mirror(value) {
3086
+ return current.mirror(value);
3087
+ }
3088
+ function forward(value) {
3089
+ return current.forward(value);
3090
+ }
3091
+ function point(value) {
3092
+ return current.point(value);
3093
+ }
3094
+ function expr(func, ...values) {
3095
+ return current.expr(func, ...values);
3096
+ }
3097
+ function watch(func, ...values) {
3098
+ current.watch(func, ...values);
3099
+ }
3100
+ function valueOf(value) {
3101
+ return value.$;
3102
+ }
3103
+ function setValue(ref, value) {
3104
+ if (ref instanceof Pointer && value instanceof IValue) {
3105
+ ref.$$ = value;
3106
+ }
3107
+ else {
3108
+ ref.$ = value instanceof IValue ? value.$ : value;
3109
+ }
3110
+ }
3111
+
3112
+ window.ref = ref;
3113
+ window.mirror = mirror;
3114
+ window.forward = forward;
3115
+ window.point = point;
3116
+ window.expr = expr;
3117
+ window.watch = watch;
3118
+ window.valueOf = valueOf;
3119
+ window.setValue = setValue;
3120
+
3121
+ // ./lib/functional/components.js
3122
+ function text(text) {
3123
+ if (!(current instanceof Fragment))
3124
+ throw userError('missing parent node', 'out-of-context');
3125
+ ;
3126
+ current.text(text);
3127
+ }
3128
+ function debug(text) {
3129
+ if (!(current instanceof Fragment))
3130
+ throw userError('missing parent node', 'out-of-context');
3131
+ current.debug(text);
3132
+ }
3133
+ function predefine(slot, predefined) {
3134
+ return slot || predefined;
3135
+ }
3136
+
3137
+ window.text = text;
3138
+ window.debug = debug;
3139
+ window.predefine = predefine;
3140
+
3141
+ // ./lib/v/index.js
3142
+
3143
+ const v = Object.assign(Object.assign({ ref(value) {
3144
+ return current.ref(value);
3145
+ }, expr: expr, of: valueOf, sv: setValue, alwaysFalse: new Reference(false), app,
3146
+ component,
3147
+ fragment,
3148
+ extension,
3149
+ text,
3150
+ tag,
3151
+ create }, vx), { merge,
3152
+ destructor() {
3153
+ return current.$destroy.bind(current);
3154
+ },
3155
+ runOnDestroy(callback) {
3156
+ current.runOnDestroy(callback);
3157
+ } });
3158
+
3159
+ window.v = v;
3160
+
3161
3161
  })();