@viewfly/core 2.0.0-alpha.1 → 2.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundles/index.js CHANGED
@@ -603,110 +603,6 @@ class ReflectiveInjector {
603
603
 
604
604
  const Type = Function;
605
605
 
606
- const refKey = 'ref';
607
- function getObjectChanges(newProps, oldProps) {
608
- const changes = {
609
- remove: [],
610
- add: [],
611
- replace: []
612
- };
613
- for (const key in newProps) {
614
- const leftValue = newProps[key];
615
- const rightValue = oldProps[key];
616
- if (Reflect.has(oldProps, key)) {
617
- if (leftValue !== rightValue) {
618
- changes.replace.push([key, leftValue, rightValue]);
619
- }
620
- continue;
621
- }
622
- changes.add.push([key, leftValue]);
623
- }
624
- for (const key in oldProps) {
625
- if (!Reflect.has(newProps, key)) {
626
- changes.remove.push([key, oldProps[key]]);
627
- }
628
- }
629
- return changes;
630
- }
631
- function classToString(config) {
632
- if (typeof config === 'string') {
633
- return config;
634
- }
635
- if (!config) {
636
- return '';
637
- }
638
- if (Array.isArray(config)) {
639
- const classes = [];
640
- for (const i of config) {
641
- const v = classToString(i);
642
- if (v) {
643
- classes.push(v);
644
- }
645
- }
646
- return classes.join(' ');
647
- }
648
- if (typeof config === 'object') {
649
- if (config.toString !== Object.prototype.toString && !config.toString.toString().includes('[native code]')) {
650
- return config.toString();
651
- }
652
- const classes = [];
653
- for (const key in config) {
654
- if ({}.hasOwnProperty.call(config, key) && config[key]) {
655
- classes.push(key);
656
- }
657
- }
658
- return classes.join(' ');
659
- }
660
- return '';
661
- }
662
- function styleToObject(style) {
663
- if (typeof style !== 'string') {
664
- return style;
665
- }
666
- const obj = {};
667
- style.split(';').map(s => s.split(':')).forEach(v => {
668
- if (!v[0] || !v[1]) {
669
- return;
670
- }
671
- obj[v[0].trim()] = v[1].trim();
672
- });
673
- return obj;
674
- }
675
- const TextAtomType = Symbol('Text');
676
- const ElementAtomType = Symbol('Element');
677
- const ComponentAtomType = Symbol('Component');
678
-
679
- class Listener {
680
- constructor(effect) {
681
- Object.defineProperty(this, "effect", {
682
- enumerable: true,
683
- configurable: true,
684
- writable: true,
685
- value: effect
686
- });
687
- Object.defineProperty(this, "destroyCallbacks", {
688
- enumerable: true,
689
- configurable: true,
690
- writable: true,
691
- value: []
692
- });
693
- }
694
- destroy() {
695
- this.destroyCallbacks.forEach(fn => fn());
696
- this.destroyCallbacks = [];
697
- }
698
- }
699
- const listeners = [];
700
- function getCurrentListener() {
701
- return listeners.at(-1);
702
- }
703
- function pushListener(listener) {
704
- listeners.push(listener);
705
- }
706
- function popListener() {
707
- listeners.pop();
708
- }
709
-
710
606
  /**
711
607
  * 当组件第一次渲染完成时触发
712
608
  * @param callback
@@ -754,38 +650,6 @@ function onUpdated(callback) {
754
650
  }
755
651
  };
756
652
  }
757
- /**
758
- * 当组件 props 更新地调用
759
- * @param callback
760
- * @example
761
- * ```tsx
762
- * function YourComponent(props) {
763
- * onPropsChanged((currentProps, prevProps) => {
764
- * console.log(currentProps, prevProps)
765
- *
766
- * return () => {
767
- * console.log('destroy prev changed!')
768
- * }
769
- * })
770
- * return () => {
771
- * return <div>xxx</div>
772
- * }
773
- * }
774
- * ```
775
- */
776
- function onPropsChanged(callback) {
777
- const component = getSetupContext();
778
- if (!component.propsChangedCallbacks) {
779
- component.propsChangedCallbacks = [];
780
- }
781
- component.propsChangedCallbacks.push(callback);
782
- return () => {
783
- const index = component.propsChangedCallbacks.indexOf(callback);
784
- if (index > -1) {
785
- component.propsChangedCallbacks.splice(index, 1);
786
- }
787
- };
788
- }
789
653
  /**
790
654
  * 当组件销毁时调用回调函数
791
655
  * @param callback
@@ -896,135 +760,697 @@ function createRef() {
896
760
  return new StaticRef();
897
761
  }
898
762
 
899
- const componentSetupStack = [];
900
- const componentErrorFn = makeError('component');
901
- function getSetupContext(need = true) {
902
- const current = componentSetupStack[componentSetupStack.length - 1];
903
- if (!current && need) {
904
- // 防止因外部捕获异常引引起的缓存未清理的问题
905
- throw componentErrorFn('cannot be called outside the component!');
906
- }
907
- return current;
763
+ const toStr = Object.prototype.toString;
764
+ function getStringType(v) {
765
+ return toStr.call(v);
908
766
  }
909
- function toRefs(ref) {
910
- return (Array.isArray(ref) ? ref : [ref]).filter(i => {
911
- return i instanceof DynamicRef;
912
- });
767
+ function isArray(v) {
768
+ return Array.isArray(v);
913
769
  }
914
- /**
915
- * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
916
- */
917
- class Component {
918
- get dirty() {
919
- return this._dirty;
920
- }
921
- get changed() {
922
- return this._changed;
923
- }
924
- constructor(parentComponent, type, props, key) {
925
- Object.defineProperty(this, "parentComponent", {
926
- enumerable: true,
927
- configurable: true,
928
- writable: true,
929
- value: parentComponent
930
- });
931
- Object.defineProperty(this, "type", {
932
- enumerable: true,
933
- configurable: true,
934
- writable: true,
935
- value: type
936
- });
937
- Object.defineProperty(this, "props", {
938
- enumerable: true,
939
- configurable: true,
940
- writable: true,
941
- value: props
942
- });
943
- Object.defineProperty(this, "key", {
944
- enumerable: true,
945
- configurable: true,
946
- writable: true,
947
- value: key
948
- });
949
- Object.defineProperty(this, "instance", {
950
- enumerable: true,
951
- configurable: true,
952
- writable: true,
953
- value: void 0
954
- });
955
- Object.defineProperty(this, "changedSubComponents", {
956
- enumerable: true,
957
- configurable: true,
958
- writable: true,
959
- value: new Set()
960
- });
961
- Object.defineProperty(this, "unmountedCallbacks", {
962
- enumerable: true,
963
- configurable: true,
964
- writable: true,
965
- value: void 0
966
- });
967
- Object.defineProperty(this, "mountCallbacks", {
968
- enumerable: true,
969
- configurable: true,
970
- writable: true,
971
- value: void 0
972
- });
973
- Object.defineProperty(this, "propsChangedCallbacks", {
770
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
771
+ function hasOwn(target, key) {
772
+ return hasOwnProperty.call(target, key);
773
+ }
774
+
775
+ class Dep {
776
+ constructor(effect) {
777
+ Object.defineProperty(this, "effect", {
974
778
  enumerable: true,
975
779
  configurable: true,
976
780
  writable: true,
977
- value: void 0
781
+ value: effect
978
782
  });
979
- Object.defineProperty(this, "updatedCallbacks", {
783
+ Object.defineProperty(this, "destroyCallbacks", {
980
784
  enumerable: true,
981
785
  configurable: true,
982
786
  writable: true,
983
- value: void 0
787
+ value: []
984
788
  });
985
- Object.defineProperty(this, "updatedDestroyCallbacks", {
789
+ }
790
+ destroy() {
791
+ this.destroyCallbacks.forEach(callback => callback());
792
+ this.destroyCallbacks = [];
793
+ }
794
+ }
795
+ const deps = [];
796
+ function getDepContext() {
797
+ return deps.at(-1);
798
+ }
799
+ function pushDepContext(dep) {
800
+ deps.push(dep);
801
+ }
802
+ function popDepContext() {
803
+ deps.pop();
804
+ }
805
+ const subscribers = new WeakMap();
806
+ function getSubscriber(target) {
807
+ let subscriber = subscribers.get(target);
808
+ if (!subscriber) {
809
+ subscriber = new Map();
810
+ subscribers.set(target, subscriber);
811
+ }
812
+ return subscriber;
813
+ }
814
+ exports.TrackOpTypes = void 0;
815
+ (function (TrackOpTypes) {
816
+ TrackOpTypes["Get"] = "Get";
817
+ TrackOpTypes["Has"] = "Has";
818
+ TrackOpTypes["Iterate"] = "Iterate";
819
+ })(exports.TrackOpTypes || (exports.TrackOpTypes = {}));
820
+ exports.TriggerOpTypes = void 0;
821
+ (function (TriggerOpTypes) {
822
+ TriggerOpTypes["Set"] = "Set";
823
+ TriggerOpTypes["Add"] = "Add";
824
+ TriggerOpTypes["Delete"] = "Delete";
825
+ TriggerOpTypes["Clear"] = "Clear";
826
+ })(exports.TriggerOpTypes || (exports.TriggerOpTypes = {}));
827
+ const unKnownKey = Symbol('unKnownKey');
828
+ function track(target, type, key = unKnownKey) {
829
+ const dep = getDepContext();
830
+ if (dep) {
831
+ const subscriber = getSubscriber(target);
832
+ let record = subscriber.get(type);
833
+ if (!record) {
834
+ record = new Map();
835
+ subscriber.set(type, record);
836
+ }
837
+ let effects = record.get(key);
838
+ if (!effects) {
839
+ effects = new Set([dep]);
840
+ record.set(key, effects);
841
+ dep.destroyCallbacks.push(() => {
842
+ effects.delete(dep);
843
+ });
844
+ }
845
+ else if (!effects.has(dep)) {
846
+ dep.destroyCallbacks.push(() => {
847
+ effects.delete(dep);
848
+ });
849
+ effects.add(dep);
850
+ }
851
+ }
852
+ }
853
+ function runEffect(key, record) {
854
+ if (!record) {
855
+ return;
856
+ }
857
+ const effects = record.get(key);
858
+ if (effects) {
859
+ const fns = [...effects];
860
+ fns.forEach(i => i.effect());
861
+ }
862
+ }
863
+ function trigger(target, type, key = unKnownKey) {
864
+ const subscriber = getSubscriber(target);
865
+ if (subscriber) {
866
+ switch (type) {
867
+ case exports.TriggerOpTypes.Set:
868
+ if (isArray(target)) {
869
+ const iterateRecord = subscriber.get(exports.TrackOpTypes.Iterate);
870
+ runEffect(unKnownKey, iterateRecord);
871
+ }
872
+ runEffect(key, subscriber.get(exports.TrackOpTypes.Get));
873
+ runEffect(key, subscriber.get(exports.TrackOpTypes.Has));
874
+ break;
875
+ case exports.TriggerOpTypes.Add:
876
+ case exports.TriggerOpTypes.Clear:
877
+ case exports.TriggerOpTypes.Delete:
878
+ {
879
+ const iterateRecord = subscriber.get(exports.TrackOpTypes.Iterate);
880
+ runEffect(unKnownKey, iterateRecord);
881
+ runEffect(key, subscriber.get(exports.TrackOpTypes.Has));
882
+ runEffect(key, subscriber.get(exports.TrackOpTypes.Get));
883
+ }
884
+ break;
885
+ }
886
+ }
887
+ }
888
+ function registryComponentDestroyCallback(fn) {
889
+ const component = getSetupContext(false);
890
+ if (component) {
891
+ if (!component.unmountedCallbacks) {
892
+ component.unmountedCallbacks = [];
893
+ }
894
+ component.unmountedCallbacks.push(fn);
895
+ }
896
+ }
897
+
898
+ function createIterableIterator(wrapper) {
899
+ return {
900
+ *entries() {
901
+ const target = toRaw(this);
902
+ track(target, exports.TrackOpTypes.Iterate);
903
+ for (const [key, value] of target.entries()) {
904
+ yield [wrapper(key), wrapper(value)];
905
+ }
906
+ },
907
+ *keys() {
908
+ const target = toRaw(this);
909
+ track(target, exports.TrackOpTypes.Iterate);
910
+ for (const item of target.keys()) {
911
+ yield wrapper(item);
912
+ }
913
+ },
914
+ *values() {
915
+ const target = toRaw(this);
916
+ track(target, exports.TrackOpTypes.Iterate);
917
+ for (const item of target.values()) {
918
+ yield wrapper(item);
919
+ }
920
+ }
921
+ };
922
+ }
923
+
924
+ function applyPredicateMethod(self, methodName, predicate, wrapper, thisArg) {
925
+ const target = toRaw(self);
926
+ track(target, exports.TrackOpTypes.Iterate);
927
+ return target[methodName]((value, index, array) => {
928
+ return predicate.call(target, wrapper(value), index, array);
929
+ }, thisArg);
930
+ }
931
+ function applySearchMethod(self, methodName, args) {
932
+ const target = toRaw(self);
933
+ track(target, exports.TrackOpTypes.Iterate);
934
+ return target[methodName](...args.map(toRaw));
935
+ }
936
+ function createArrayHandlers(wrapper) {
937
+ return Object.assign({ concat(...items) {
938
+ const target = toRaw(this);
939
+ trigger(target, exports.TriggerOpTypes.Add);
940
+ return target.concat(...items);
941
+ },
942
+ every(predicate, thisArg) {
943
+ return applyPredicateMethod(this, 'every', predicate, wrapper, thisArg);
944
+ },
945
+ filter(predicate, thisArg) {
946
+ return applyPredicateMethod(this, 'filter', predicate, wrapper, thisArg);
947
+ },
948
+ find(predicate, thisArg) {
949
+ return applyPredicateMethod(this, 'find', predicate, wrapper, thisArg);
950
+ },
951
+ findIndex(predicate, thisArg) {
952
+ return applyPredicateMethod(this, 'findIndex', predicate, wrapper, thisArg);
953
+ },
954
+ findLast(predicate, thisArg) {
955
+ return applyPredicateMethod(this, 'findLast', predicate, wrapper, thisArg);
956
+ },
957
+ findLastIndex(predicate, thisArg) {
958
+ return applyPredicateMethod(this, 'findLastIndex', predicate, wrapper, thisArg);
959
+ },
960
+ forEach(callbackfn, thisArg) {
961
+ return applyPredicateMethod(this, 'forEach', callbackfn, wrapper, thisArg);
962
+ },
963
+ includes(...args) {
964
+ return applySearchMethod(this, 'includes', args);
965
+ },
966
+ indexOf(...args) {
967
+ return applySearchMethod(this, 'indexOf', args);
968
+ },
969
+ join(separator) {
970
+ const target = toRaw(this);
971
+ track(target, exports.TrackOpTypes.Iterate);
972
+ return target.join(separator);
973
+ },
974
+ lastIndexOf(...args) {
975
+ return applySearchMethod(this, 'lastIndexOf', args);
976
+ },
977
+ map(callbackFn, thisArg) {
978
+ return applyPredicateMethod(this, 'map', callbackFn, wrapper, thisArg);
979
+ },
980
+ pop() {
981
+ const target = toRaw(this);
982
+ trigger(target, exports.TriggerOpTypes.Delete);
983
+ return target.pop();
984
+ },
985
+ push(...items) {
986
+ const target = toRaw(this);
987
+ trigger(target, exports.TriggerOpTypes.Add);
988
+ return target.push(...items);
989
+ },
990
+ reduce(callbackFn, ...args) {
991
+ const target = toRaw(this);
992
+ track(target, exports.TrackOpTypes.Iterate);
993
+ return target.reduce((p, c, i, a) => {
994
+ if (args.length > 0) {
995
+ return callbackFn(p, wrapper(c), i, a);
996
+ }
997
+ return callbackFn(wrapper(p), wrapper(c), i, a);
998
+ }, ...args);
999
+ },
1000
+ reduceRight(callbackFn, ...args) {
1001
+ const target = toRaw(this);
1002
+ track(target, exports.TrackOpTypes.Iterate);
1003
+ return target.reduceRight((p, c, i, a) => {
1004
+ if (args.length > 0) {
1005
+ return callbackFn(p, wrapper(c), i, a);
1006
+ }
1007
+ return callbackFn(wrapper(p), wrapper(c), i, a);
1008
+ }, ...args);
1009
+ },
1010
+ shift() {
1011
+ const target = toRaw(this);
1012
+ trigger(target, exports.TriggerOpTypes.Delete);
1013
+ return target.shift();
1014
+ },
1015
+ some(predicate, thisArg) {
1016
+ return applyPredicateMethod(this, 'some', predicate, thisArg);
1017
+ },
1018
+ splice(start, deleteCount) {
1019
+ const target = toRaw(this);
1020
+ trigger(target, exports.TriggerOpTypes.Set);
1021
+ trigger(target, exports.TriggerOpTypes.Add);
1022
+ trigger(target, exports.TriggerOpTypes.Delete);
1023
+ return target.splice(start, deleteCount).map(i => wrapper(i));
1024
+ },
1025
+ toReversed() {
1026
+ const target = toRaw(this);
1027
+ track(target, exports.TrackOpTypes.Iterate);
1028
+ return target.toReversed();
1029
+ },
1030
+ toSorted(compareFn) {
1031
+ const target = toRaw(this);
1032
+ track(target, exports.TrackOpTypes.Iterate);
1033
+ return target.toSorted(compareFn);
1034
+ },
1035
+ toSpliced(start, deleteCount, ...items) {
1036
+ const target = toRaw(this);
1037
+ track(target, exports.TrackOpTypes.Iterate);
1038
+ return target.toSpliced(start, deleteCount, ...items);
1039
+ },
1040
+ unshift(...items) {
1041
+ const target = toRaw(this);
1042
+ trigger(target, exports.TriggerOpTypes.Add);
1043
+ return target.unshift(...items);
1044
+ },
1045
+ [Symbol.iterator]() {
1046
+ return this.values();
1047
+ } }, createIterableIterator(wrapper));
1048
+ }
1049
+
1050
+ function createMapHandlers(wrapper) {
1051
+ return Object.assign({ get(key) {
1052
+ const target = toRaw(this);
1053
+ track(target, exports.TrackOpTypes.Get, key);
1054
+ return wrapper(target.get(key));
1055
+ },
1056
+ set(key, value) {
1057
+ const target = toRaw(this);
1058
+ key = toRaw(key);
1059
+ value = toRaw(value);
1060
+ const has = target.has(key);
1061
+ const r = target.set(key, value);
1062
+ trigger(target, has ? exports.TriggerOpTypes.Set : exports.TriggerOpTypes.Add, key);
1063
+ return r;
1064
+ },
1065
+ has(key) {
1066
+ const target = toRaw(this);
1067
+ key = toRaw(key);
1068
+ track(target, exports.TrackOpTypes.Has, key);
1069
+ return target.has(key);
1070
+ },
1071
+ delete(key) {
1072
+ const target = toRaw(this);
1073
+ key = toRaw(key);
1074
+ const r = target.delete(key);
1075
+ trigger(target, exports.TriggerOpTypes.Delete, key);
1076
+ return r;
1077
+ },
1078
+ forEach(callbackFn, thisArg) {
1079
+ const target = toRaw(this);
1080
+ track(target, exports.TrackOpTypes.Iterate, undefined);
1081
+ target.forEach((v, k, m) => {
1082
+ callbackFn.call(this, wrapper(v), wrapper(k), m);
1083
+ }, thisArg);
1084
+ },
1085
+ clear() {
1086
+ const target = toRaw(this);
1087
+ target.clear();
1088
+ trigger(target, exports.TriggerOpTypes.Clear, undefined);
1089
+ },
1090
+ [Symbol.iterator]() {
1091
+ return this.entries();
1092
+ } }, createIterableIterator(wrapper));
1093
+ }
1094
+
1095
+ function createSetHandlers(wrapper) {
1096
+ return Object.assign({ add(value) {
1097
+ const target = toRaw(this);
1098
+ value = toRaw(value);
1099
+ if (!target.has(value)) {
1100
+ target.add(value);
1101
+ trigger(target, exports.TriggerOpTypes.Add, undefined);
1102
+ }
1103
+ return this;
1104
+ },
1105
+ delete(value) {
1106
+ const target = toRaw(this);
1107
+ value = toRaw(value);
1108
+ const has = target.has(value);
1109
+ const b = target.delete(value);
1110
+ if (!has) {
1111
+ trigger(target, exports.TriggerOpTypes.Delete, undefined);
1112
+ }
1113
+ return b;
1114
+ },
1115
+ has(key) {
1116
+ const target = toRaw(this);
1117
+ key = toRaw(key);
1118
+ track(target, exports.TrackOpTypes.Has, key);
1119
+ return target.has(key);
1120
+ },
1121
+ forEach(callbackFn, thisArg) {
1122
+ const target = toRaw(this);
1123
+ track(target, exports.TrackOpTypes.Iterate, undefined);
1124
+ target.forEach((v, k, m) => {
1125
+ callbackFn.call(this, wrapper(v), wrapper(k), m);
1126
+ }, thisArg);
1127
+ },
1128
+ clear() {
1129
+ const target = toRaw(this);
1130
+ const size = target.size;
1131
+ if (size !== 0) {
1132
+ target.clear();
1133
+ trigger(target, exports.TriggerOpTypes.Clear, undefined);
1134
+ }
1135
+ },
1136
+ [Symbol.iterator]() {
1137
+ return this.values();
1138
+ } }, createIterableIterator(wrapper));
1139
+ }
1140
+
1141
+ const reactiveErrorFn = makeError('reactive');
1142
+ const rawToProxyCache = new WeakMap();
1143
+ const proxyToRawCache = new WeakMap();
1144
+ function toRaw(value) {
1145
+ if (proxyToRawCache.has(value)) {
1146
+ return proxyToRawCache.get(value);
1147
+ }
1148
+ return value;
1149
+ }
1150
+ function isReactive(value) {
1151
+ return proxyToRawCache.has(value);
1152
+ }
1153
+ let fromInternalWrite = false;
1154
+ function internalWrite(fn) {
1155
+ fromInternalWrite = true;
1156
+ fn();
1157
+ fromInternalWrite = false;
1158
+ }
1159
+ class ObjectReactiveHandler {
1160
+ constructor(config) {
1161
+ Object.defineProperty(this, "isShallow", {
986
1162
  enumerable: true,
987
1163
  configurable: true,
988
1164
  writable: true,
989
1165
  value: void 0
990
1166
  });
991
- Object.defineProperty(this, "propsChangedDestroyCallbacks", {
1167
+ Object.defineProperty(this, "isReadonly", {
992
1168
  enumerable: true,
993
1169
  configurable: true,
994
1170
  writable: true,
995
1171
  value: void 0
996
1172
  });
997
- Object.defineProperty(this, "_dirty", {
998
- enumerable: true,
999
- configurable: true,
1000
- writable: true,
1001
- value: true
1002
- });
1003
- Object.defineProperty(this, "_changed", {
1173
+ this.isReadonly = config.readonly;
1174
+ this.isShallow = config.shallow;
1175
+ }
1176
+ set(target, p, newValue, receiver) {
1177
+ if (this.isReadonly && !fromInternalWrite) {
1178
+ throw reactiveErrorFn('Object is readonly!');
1179
+ }
1180
+ newValue = toRaw(newValue);
1181
+ const oldValue = target[p];
1182
+ if (oldValue === newValue) {
1183
+ return Reflect.set(target, p, newValue, receiver);
1184
+ }
1185
+ const b = Reflect.set(target, p, newValue, receiver);
1186
+ fromInternalWrite = false;
1187
+ if (hasOwn(target, p)) {
1188
+ trigger(target, exports.TriggerOpTypes.Set, p);
1189
+ }
1190
+ else {
1191
+ trigger(target, exports.TriggerOpTypes.Add, p);
1192
+ }
1193
+ return b;
1194
+ }
1195
+ get(target, p, receiver) {
1196
+ track(target, exports.TrackOpTypes.Get, p);
1197
+ const value = Reflect.get(target, p, receiver);
1198
+ if (this.isShallow) {
1199
+ return value;
1200
+ }
1201
+ return reactive(value);
1202
+ }
1203
+ deleteProperty(target, p) {
1204
+ const b = Reflect.deleteProperty(target, p);
1205
+ trigger(target, exports.TriggerOpTypes.Delete, p);
1206
+ return b;
1207
+ }
1208
+ ownKeys(target) {
1209
+ track(target, exports.TrackOpTypes.Iterate);
1210
+ return Reflect.ownKeys(target);
1211
+ }
1212
+ }
1213
+ function noReactive(v) {
1214
+ return v;
1215
+ }
1216
+ class ArrayReactiveHandler extends ObjectReactiveHandler {
1217
+ constructor(config) {
1218
+ super(config);
1219
+ Object.defineProperty(this, "interceptors", {
1004
1220
  enumerable: true,
1005
1221
  configurable: true,
1006
1222
  writable: true,
1007
- value: true
1223
+ value: createArrayHandlers(this.isShallow ? noReactive : reactive)
1008
1224
  });
1009
- Object.defineProperty(this, "isFirstRendering", {
1225
+ }
1226
+ get(target, p, receiver) {
1227
+ if (Reflect.has(this.interceptors, p) && p in target) {
1228
+ return this.interceptors[p];
1229
+ }
1230
+ return super.get(target, p, receiver);
1231
+ }
1232
+ }
1233
+ class MapReactiveHandler extends ObjectReactiveHandler {
1234
+ constructor(config) {
1235
+ super(config);
1236
+ Object.defineProperty(this, "interceptors", {
1010
1237
  enumerable: true,
1011
1238
  configurable: true,
1012
1239
  writable: true,
1013
- value: true
1240
+ value: createMapHandlers(this.isShallow ? noReactive : reactive)
1014
1241
  });
1015
- Object.defineProperty(this, "refs", {
1242
+ }
1243
+ get(target, p, receiver) {
1244
+ if (Reflect.has(this.interceptors, p) && p in target) {
1245
+ return this.interceptors[p];
1246
+ }
1247
+ if (p === 'size') {
1248
+ track(target, exports.TrackOpTypes.Iterate, p);
1249
+ return Reflect.get(target, p);
1250
+ }
1251
+ return super.get(target, p, receiver);
1252
+ }
1253
+ }
1254
+ class SetReactiveHandler extends ObjectReactiveHandler {
1255
+ constructor(config) {
1256
+ super(config);
1257
+ Object.defineProperty(this, "interceptors", {
1016
1258
  enumerable: true,
1017
1259
  configurable: true,
1018
1260
  writable: true,
1019
- value: null
1261
+ value: createSetHandlers(this.isShallow ? noReactive : reactive)
1020
1262
  });
1021
- Object.defineProperty(this, "listener", {
1022
- enumerable: true,
1023
- configurable: true,
1024
- writable: true,
1025
- value: new Listener(() => {
1026
- this.markAsDirtied();
1027
- })
1263
+ }
1264
+ get(target, p, receiver) {
1265
+ if (Reflect.has(this.interceptors, p) && p in target) {
1266
+ return this.interceptors[p];
1267
+ }
1268
+ if (p === 'size') {
1269
+ track(target, exports.TrackOpTypes.Iterate, p);
1270
+ return Reflect.get(target, p);
1271
+ }
1272
+ return super.get(target, p, receiver);
1273
+ }
1274
+ }
1275
+ const defaultObjectReactiveHandler = new ObjectReactiveHandler({
1276
+ readonly: false,
1277
+ shallow: false
1278
+ });
1279
+ const defaultArrayReactiveHandler = new ArrayReactiveHandler({
1280
+ readonly: false,
1281
+ shallow: false
1282
+ });
1283
+ const defaultMapReactiveHandler = new MapReactiveHandler({
1284
+ readonly: false,
1285
+ shallow: false
1286
+ });
1287
+ const defaultSetReactiveHandler = new SetReactiveHandler({
1288
+ readonly: false,
1289
+ shallow: false
1290
+ });
1291
+ const readonlyProxyHandler = new ObjectReactiveHandler({
1292
+ shallow: true,
1293
+ readonly: true
1294
+ });
1295
+ function reactive(raw) {
1296
+ if (isReactive(raw)) {
1297
+ return raw;
1298
+ }
1299
+ let proxy = rawToProxyCache.get(raw);
1300
+ if (proxy) {
1301
+ return proxy;
1302
+ }
1303
+ const type = getStringType(raw);
1304
+ switch (type) {
1305
+ case '[object Object]':
1306
+ proxy = new Proxy(raw, defaultObjectReactiveHandler);
1307
+ break;
1308
+ case '[object Array]':
1309
+ proxy = new Proxy(raw, defaultArrayReactiveHandler);
1310
+ break;
1311
+ case '[object Set]':
1312
+ case '[object WeakSet]':
1313
+ proxy = new Proxy(raw, defaultSetReactiveHandler);
1314
+ break;
1315
+ case '[object Map]':
1316
+ case '[object WeakMap]':
1317
+ proxy = new Proxy(raw, defaultMapReactiveHandler);
1318
+ break;
1319
+ default:
1320
+ return raw;
1321
+ }
1322
+ rawToProxyCache.set(raw, proxy);
1323
+ proxyToRawCache.set(proxy, raw);
1324
+ return proxy;
1325
+ }
1326
+
1327
+ function hasChange(newProps, oldProps) {
1328
+ const newKeys = Object.keys(oldProps);
1329
+ const oldKeys = Object.keys(newProps);
1330
+ if (oldKeys.length !== newKeys.length) {
1331
+ return true;
1332
+ }
1333
+ const len = oldKeys.length;
1334
+ for (let i = 0; i < len; i++) {
1335
+ const key = newKeys[i];
1336
+ if (newProps[key] !== oldProps[key]) {
1337
+ return true;
1338
+ }
1339
+ }
1340
+ return false;
1341
+ }
1342
+ const refKey = 'ref';
1343
+ function comparePropsWithCallbacks(oldProps, newProps, onDeleted, onAdded, onUpdated) {
1344
+ for (const key in oldProps) {
1345
+ if (!(key in newProps)) {
1346
+ onDeleted(key, oldProps[key]);
1347
+ }
1348
+ }
1349
+ for (const key in newProps) {
1350
+ if (!(key in oldProps)) {
1351
+ onAdded(key, newProps[key]);
1352
+ }
1353
+ else if (oldProps[key] !== newProps[key]) {
1354
+ onUpdated(key, newProps[key], oldProps[key]);
1355
+ }
1356
+ }
1357
+ }
1358
+ function classToString(config) {
1359
+ if (typeof config === 'string') {
1360
+ return config;
1361
+ }
1362
+ if (!config) {
1363
+ return '';
1364
+ }
1365
+ if (Array.isArray(config)) {
1366
+ const classes = [];
1367
+ for (const i of config) {
1368
+ const v = classToString(i);
1369
+ if (v) {
1370
+ classes.push(v);
1371
+ }
1372
+ }
1373
+ return classes.join(' ');
1374
+ }
1375
+ if (typeof config === 'object') {
1376
+ if (config.toString !== Object.prototype.toString && !config.toString.toString().includes('[native code]')) {
1377
+ return config.toString();
1378
+ }
1379
+ const classes = [];
1380
+ for (const key in config) {
1381
+ if ({}.hasOwnProperty.call(config, key) && config[key]) {
1382
+ classes.push(key);
1383
+ }
1384
+ }
1385
+ return classes.join(' ');
1386
+ }
1387
+ return '';
1388
+ }
1389
+ function styleToObject(style) {
1390
+ if (typeof style !== 'string') {
1391
+ return style || {};
1392
+ }
1393
+ const obj = {};
1394
+ style.split(';').map(s => s.split(':')).forEach(v => {
1395
+ if (!v[0] || !v[1]) {
1396
+ return;
1397
+ }
1398
+ obj[v[0].trim()] = v[1].trim();
1399
+ });
1400
+ return obj;
1401
+ }
1402
+ const TextAtomType = Symbol('Text');
1403
+ const ElementAtomType = Symbol('Element');
1404
+ const ComponentAtomType = Symbol('Component');
1405
+
1406
+ const componentSetupStack = [];
1407
+ const componentErrorFn = makeError('component');
1408
+ function getSetupContext(need = true) {
1409
+ const current = componentSetupStack[componentSetupStack.length - 1];
1410
+ if (!current && need) {
1411
+ // 防止因外部捕获异常引引起的缓存未清理的问题
1412
+ throw componentErrorFn('cannot be called outside the component!');
1413
+ }
1414
+ return current;
1415
+ }
1416
+ function toRefs(ref) {
1417
+ return (Array.isArray(ref) ? ref : [ref]).filter(i => {
1418
+ return i instanceof DynamicRef;
1419
+ });
1420
+ }
1421
+ function createReadonlyProxy(value) {
1422
+ return new Proxy(value, readonlyProxyHandler);
1423
+ }
1424
+ /**
1425
+ * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
1426
+ */
1427
+ class Component {
1428
+ get dirty() {
1429
+ return this._dirty;
1430
+ }
1431
+ get changed() {
1432
+ return this._changed;
1433
+ }
1434
+ constructor(parentComponent, type, props, key) {
1435
+ this.parentComponent = parentComponent;
1436
+ this.type = type;
1437
+ this.props = props;
1438
+ this.key = key;
1439
+ this.instance = null;
1440
+ this.changedSubComponents = new Set();
1441
+ this.viewMetadata = null;
1442
+ this.unmountedCallbacks = null;
1443
+ this.mountCallbacks = null;
1444
+ this.updatedCallbacks = null;
1445
+ this.updatedDestroyCallbacks = null;
1446
+ this._dirty = true;
1447
+ this._changed = false;
1448
+ this.isFirstRendering = true;
1449
+ this.refs = null;
1450
+ this.rawProps = props;
1451
+ this.props = createReadonlyProxy(Object.assign({}, props));
1452
+ this.listener = new Dep(() => {
1453
+ this.markAsDirtied();
1028
1454
  });
1029
1455
  }
1030
1456
  markAsDirtied() {
@@ -1039,117 +1465,109 @@ class Component {
1039
1465
  return;
1040
1466
  }
1041
1467
  this._changed = true;
1042
- if (this.parentComponent instanceof Component) {
1468
+ if (this.parentComponent) {
1043
1469
  this.parentComponent.markAsChanged(this);
1044
1470
  }
1045
1471
  }
1046
1472
  render(update) {
1047
- const self = this;
1048
- const proxiesProps = new Proxy(this.props, {
1049
- get(_, key) {
1050
- // 必须用 self,因为 props 会随着页面更新变更,使用 self 才能更新引用
1051
- return self.props[key];
1052
- },
1053
- set() {
1054
- // 防止因外部捕获异常引引起的缓存未清理的问题
1055
- if (isSetup) {
1056
- componentSetupStack.pop();
1057
- }
1058
- throw componentErrorFn('component props is readonly!');
1059
- }
1060
- });
1061
1473
  componentSetupStack.push(this);
1062
- let isSetup = true;
1063
- const render = this.type(proxiesProps);
1474
+ const render = this.type(this.props);
1064
1475
  const isRenderFn = typeof render === 'function';
1065
1476
  this.instance = isRenderFn ? { $render: render } : render;
1066
1477
  const refs = toRefs(this.props.ref);
1067
1478
  if (refs.length) {
1068
1479
  this.refs = refs;
1069
1480
  onMounted(() => {
1070
- for (const ref of refs) {
1481
+ const refs = this.refs;
1482
+ const length = refs.length;
1483
+ for (let i = 0; i < length; i++) {
1484
+ const ref = refs[i];
1071
1485
  ref.bind(this.instance);
1072
1486
  }
1073
1487
  return () => {
1074
- for (const ref of refs) {
1488
+ const refs = this.refs;
1489
+ const length = refs.length;
1490
+ for (let i = 0; i < length; i++) {
1491
+ const ref = refs[i];
1075
1492
  ref.unBind(this.instance);
1076
1493
  }
1077
1494
  };
1078
1495
  });
1079
1496
  }
1080
- isSetup = false;
1081
1497
  componentSetupStack.pop();
1082
- pushListener(this.listener);
1498
+ pushDepContext(this.listener);
1083
1499
  const template = this.instance.$render();
1084
- popListener();
1500
+ popDepContext();
1085
1501
  update(template, this.instance.$portalHost);
1086
1502
  this.rendered();
1087
1503
  }
1088
- update(newProps, updateChildren, reuseChildren) {
1089
- const oldProps = this.props;
1090
- if (newProps !== oldProps) {
1091
- const { add, remove, replace } = getObjectChanges(newProps, oldProps);
1092
- if (add.length || remove.length || replace.length) {
1093
- this.invokePropsChangedHooks(newProps);
1094
- }
1095
- else if (!this.dirty) {
1096
- this.props = newProps;
1097
- reuseChildren(false);
1098
- this.rendered();
1099
- return;
1100
- }
1101
- const newRefs = toRefs(newProps.ref);
1102
- if (this.refs) {
1103
- for (const oldRef of this.refs) {
1104
- if (!newRefs.includes(oldRef)) {
1105
- oldRef.unBind(this.instance);
1106
- }
1504
+ updateProps(newProps) {
1505
+ const oldProps = this.rawProps;
1506
+ this.rawProps = newProps;
1507
+ const newRefs = toRefs(newProps.ref);
1508
+ comparePropsWithCallbacks(oldProps, newProps, key => {
1509
+ internalWrite(() => {
1510
+ Reflect.deleteProperty(oldProps, key);
1511
+ });
1512
+ }, (key, value) => {
1513
+ internalWrite(() => {
1514
+ this.props[key] = value;
1515
+ });
1516
+ }, (key, value) => {
1517
+ internalWrite(() => {
1518
+ this.props[key] = value;
1519
+ });
1520
+ });
1521
+ if (this.refs) {
1522
+ const len = this.refs.length;
1523
+ for (let i = 0; i < len; i++) {
1524
+ const oldRef = this.refs[i];
1525
+ if (!newRefs.includes(oldRef)) {
1526
+ oldRef.unBind(this.instance);
1107
1527
  }
1108
1528
  }
1109
- for (const newRef of newRefs) {
1110
- newRef.bind(this.instance);
1111
- }
1112
- if (newRefs.length) {
1113
- this.refs = newRefs;
1114
- }
1115
1529
  }
1530
+ const len = newRefs.length;
1531
+ for (let i = 0; i < len; i++) {
1532
+ const newRef = newRefs[i];
1533
+ newRef.bind(this.instance);
1534
+ }
1535
+ if (len) {
1536
+ this.refs = newRefs;
1537
+ }
1538
+ }
1539
+ canUpdate(oldProps, newProps) {
1116
1540
  if (typeof this.instance.$useMemo === 'function') {
1117
1541
  if (this.instance.$useMemo(newProps, oldProps)) {
1118
- reuseChildren(true);
1119
- this.rendered();
1120
- return;
1542
+ return false;
1121
1543
  }
1122
1544
  }
1545
+ return true;
1546
+ }
1547
+ rerender() {
1123
1548
  this.listener.destroy();
1124
- pushListener(this.listener);
1549
+ pushDepContext(this.listener);
1125
1550
  const template = this.instance.$render();
1126
- popListener();
1127
- updateChildren(template);
1128
- this.rendered();
1551
+ popDepContext();
1552
+ return template;
1129
1553
  }
1130
1554
  destroy() {
1131
- var _a, _b, _c;
1132
1555
  this.listener.destroy();
1133
- (_a = this.updatedDestroyCallbacks) === null || _a === void 0 ? void 0 : _a.forEach(fn => {
1134
- fn();
1135
- });
1136
- (_b = this.propsChangedDestroyCallbacks) === null || _b === void 0 ? void 0 : _b.forEach(fn => {
1137
- fn();
1138
- });
1139
- (_c = this.unmountedCallbacks) === null || _c === void 0 ? void 0 : _c.forEach(fn => {
1140
- fn();
1141
- });
1142
- if (this.parentComponent instanceof Component) {
1143
- this.parentComponent.changedSubComponents.delete(this);
1556
+ if (this.updatedDestroyCallbacks) {
1557
+ this.updatedDestroyCallbacks.forEach(fn => {
1558
+ fn();
1559
+ });
1560
+ }
1561
+ if (this.unmountedCallbacks) {
1562
+ this.unmountedCallbacks.forEach(fn => {
1563
+ fn();
1564
+ });
1144
1565
  }
1145
1566
  this.parentComponent =
1146
- this.propsChangedDestroyCallbacks =
1147
- this.updatedDestroyCallbacks =
1148
- this.mountCallbacks =
1149
- this.updatedCallbacks =
1150
- this.propsChangedCallbacks =
1151
- this.unmountedCallbacks = null;
1152
- this.changedSubComponents.clear();
1567
+ this.updatedDestroyCallbacks =
1568
+ this.mountCallbacks =
1569
+ this.updatedCallbacks =
1570
+ this.unmountedCallbacks = null;
1153
1571
  }
1154
1572
  rendered() {
1155
1573
  this.changedSubComponents.clear();
@@ -1162,35 +1580,18 @@ class Component {
1162
1580
  }
1163
1581
  if (this.changed) {
1164
1582
  Promise.resolve().then(() => {
1165
- if (this.parentComponent instanceof Component) {
1583
+ if (this.parentComponent) {
1166
1584
  this.parentComponent.markAsChanged(this);
1167
1585
  }
1168
1586
  });
1169
1587
  }
1170
1588
  }
1171
- invokePropsChangedHooks(newProps) {
1172
- const oldProps = this.props;
1173
- this.props = newProps;
1174
- if (this.propsChangedCallbacks) {
1175
- if (this.propsChangedDestroyCallbacks) {
1176
- this.propsChangedDestroyCallbacks.forEach(fn => {
1177
- fn();
1178
- });
1179
- }
1180
- const propsChangedDestroyCallbacks = [];
1181
- for (const fn of this.propsChangedCallbacks) {
1182
- const destroyFn = fn(newProps, oldProps);
1183
- if (typeof destroyFn === 'function') {
1184
- propsChangedDestroyCallbacks.push(destroyFn);
1185
- }
1186
- }
1187
- this.propsChangedDestroyCallbacks = propsChangedDestroyCallbacks.length ? propsChangedDestroyCallbacks : null;
1188
- }
1189
- }
1190
1589
  invokeMountHooks() {
1191
1590
  const unmountedCallbacks = [];
1192
1591
  if (this.mountCallbacks) {
1193
- for (const fn of this.mountCallbacks) {
1592
+ const len = this.mountCallbacks.length;
1593
+ for (let i = 0; i < len; ++i) {
1594
+ const fn = this.mountCallbacks[i];
1194
1595
  const destroyFn = fn();
1195
1596
  if (typeof destroyFn === 'function') {
1196
1597
  unmountedCallbacks.push(destroyFn);
@@ -1215,7 +1616,9 @@ class Component {
1215
1616
  });
1216
1617
  }
1217
1618
  const updatedDestroyCallbacks = [];
1218
- for (const fn of this.updatedCallbacks) {
1619
+ const len = this.updatedCallbacks.length;
1620
+ for (let i = 0; i < len; ++i) {
1621
+ const fn = this.updatedCallbacks[i];
1219
1622
  const destroyFn = fn();
1220
1623
  if (typeof destroyFn === 'function') {
1221
1624
  updatedDestroyCallbacks.push(destroyFn);
@@ -1261,13 +1664,37 @@ function inject(token, notFoundValue = THROW_IF_NOT_FOUND, flags) {
1261
1664
  const injector = getInjector(component);
1262
1665
  return injector.get(token, notFoundValue, flags);
1263
1666
  }
1264
- function withAnnotation(annotation, component) {
1667
+ /**
1668
+ * 给组件添加注解
1669
+ * @param annotation
1670
+ * @param componentSetup
1671
+ * @example
1672
+ * ```ts
1673
+ * export customScope = new Scope('scopeName')
1674
+ * export const App = withAnnotation({
1675
+ * scope: customScope,
1676
+ * providers: [
1677
+ * ExampleService
1678
+ * ]
1679
+ * }, function(props: Props) {
1680
+ * return () => {
1681
+ * return <div>...</div>
1682
+ * }
1683
+ * })
1684
+ * ```
1685
+ */
1686
+ function withAnnotation(annotation, componentSetup) {
1265
1687
  return function (props) {
1266
1688
  const instance = getCurrentInstance();
1267
1689
  const parentInjector = injectMap.get(instance) || getInjector(instance.parentComponent);
1268
- const injector = new ReflectiveInjector(parentInjector, annotation.providers || [], annotation.scope);
1690
+ const injector = new ReflectiveInjector(parentInjector, [{
1691
+ provide: Injector,
1692
+ useFactory() {
1693
+ return injector;
1694
+ }
1695
+ }, ...(annotation.providers || [])], annotation.scope);
1269
1696
  injectMap.set(instance, injector);
1270
- return component(props);
1697
+ return componentSetup(props);
1271
1698
  };
1272
1699
  }
1273
1700
 
@@ -1304,7 +1731,6 @@ const ElementNamespaceMap = {
1304
1731
  svg: 'svg',
1305
1732
  math: 'mathml',
1306
1733
  };
1307
- const componentViewCache = new WeakMap();
1308
1734
  const listenerReg = /^on[A-Z]/;
1309
1735
  function createRenderer(component, nativeRenderer, namespace) {
1310
1736
  let isInit = true;
@@ -1328,7 +1754,7 @@ function createRenderer(component, nativeRenderer, namespace) {
1328
1754
  });
1329
1755
  }
1330
1756
  else {
1331
- updateView(nativeRenderer, component, false);
1757
+ deepUpdateByComponentDirtyTree(nativeRenderer, component, false);
1332
1758
  }
1333
1759
  };
1334
1760
  }
@@ -1353,37 +1779,39 @@ function buildElementChildren(atom, nativeRenderer, parentComponent, context) {
1353
1779
  child = child.sibling;
1354
1780
  }
1355
1781
  }
1356
- function updateView(nativeRenderer, component, needMove) {
1782
+ function patchComponent(nativeRenderer, component, oldChildAtom, newAtom, context, needMove) {
1783
+ const newTemplate = component.rerender();
1784
+ newAtom.child = createChildChain(newTemplate, newAtom.namespace);
1785
+ diff(nativeRenderer, component, newAtom.child, oldChildAtom, context, needMove);
1786
+ }
1787
+ function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
1357
1788
  if (component.dirty) {
1358
- const { atom, host, isParent, rootHost } = componentViewCache.get(component);
1359
- applyChanges(nativeRenderer, component, atom, {
1360
- host,
1361
- isParent,
1362
- rootHost
1363
- }, needMove);
1789
+ const canUpdate = component.canUpdate(component.props, component.props);
1790
+ if (canUpdate) {
1791
+ const { atom, host, isParent, rootHost } = component.viewMetadata;
1792
+ const context = {
1793
+ host,
1794
+ isParent,
1795
+ rootHost
1796
+ };
1797
+ const diffAtom = atom.child;
1798
+ patchComponent(nativeRenderer, component, diffAtom, atom, context, needMove);
1799
+ const next = atom.sibling;
1800
+ if (next && next.jsxNode instanceof Component) {
1801
+ const view = next.jsxNode.viewMetadata;
1802
+ view.host = context.host;
1803
+ view.isParent = context.isParent;
1804
+ }
1805
+ }
1806
+ component.rendered();
1364
1807
  }
1365
1808
  else if (component.changed) {
1366
1809
  component.changedSubComponents.forEach(child => {
1367
- updateView(nativeRenderer, child, needMove);
1810
+ deepUpdateByComponentDirtyTree(nativeRenderer, child, needMove);
1368
1811
  });
1369
1812
  component.rendered();
1370
1813
  }
1371
1814
  }
1372
- function applyChanges(nativeRenderer, component, atom, context, needMove) {
1373
- const diffAtom = atom.child;
1374
- component.update(component.props, newTemplate => {
1375
- atom.child = createChildChain(newTemplate, atom.namespace);
1376
- diff(nativeRenderer, component, atom.child, diffAtom, context, needMove);
1377
- const next = atom.sibling;
1378
- if (next && next.jsxNode instanceof Component) {
1379
- const view = componentViewCache.get(next.jsxNode);
1380
- view.host = context.host;
1381
- view.isParent = context.isParent;
1382
- }
1383
- }, (skipSubComponentDiff) => {
1384
- reuseComponentView(nativeRenderer, atom, context, needMove, skipSubComponentDiff);
1385
- });
1386
- }
1387
1815
  function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
1388
1816
  const commits = [];
1389
1817
  function changeOffset() {
@@ -1399,7 +1827,8 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMo
1399
1827
  dirtyDiffAtom = dirtyDiffAtom.sibling;
1400
1828
  }
1401
1829
  let offset = 0;
1402
- for (let i = 0; i < commits.length; i++) {
1830
+ const len = commits.length;
1831
+ for (let i = 0; i < len; i++) {
1403
1832
  const commit = commits[i];
1404
1833
  while (oldAtom) {
1405
1834
  if (oldAtom.index <= i) {
@@ -1409,7 +1838,7 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMo
1409
1838
  }
1410
1839
  break;
1411
1840
  }
1412
- commit(offset, needMove);
1841
+ commit.callback(commit.params, offset, needMove);
1413
1842
  }
1414
1843
  }
1415
1844
  function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, parentComponent, effect) {
@@ -1418,17 +1847,19 @@ function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, paren
1418
1847
  while (oldAtom) {
1419
1848
  const newAtomType = newAtom.type;
1420
1849
  if (oldAtom.type === newAtomType && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
1421
- let commit;
1422
- if (newAtomType === TextAtomType) {
1423
- commit = updateText(newAtom, oldAtom, nativeRenderer, context);
1424
- }
1425
- else if (newAtomType === ComponentAtomType) {
1426
- commit = updateComponent(newAtom, oldAtom, nativeRenderer, context);
1427
- }
1428
- else {
1429
- commit = updateElement(newAtom, oldAtom, nativeRenderer, context, parentComponent);
1430
- }
1431
- commits.push(commit);
1850
+ commits.push({
1851
+ callback: newAtomType === TextAtomType ? updateText :
1852
+ newAtomType === ComponentAtomType ? updateComponent :
1853
+ updateElement,
1854
+ params: {
1855
+ oldAtom,
1856
+ newAtom,
1857
+ nativeRenderer,
1858
+ context,
1859
+ effect,
1860
+ parentComponent
1861
+ }
1862
+ });
1432
1863
  const next = oldAtom.sibling;
1433
1864
  if (!prev) {
1434
1865
  return next;
@@ -1439,81 +1870,85 @@ function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, paren
1439
1870
  prev = oldAtom;
1440
1871
  oldAtom = oldAtom.sibling;
1441
1872
  }
1442
- commits.push(createNewView(newAtom, nativeRenderer, context, parentComponent, effect));
1873
+ commits.push({
1874
+ callback: patchUpdate,
1875
+ params: {
1876
+ oldAtom: oldAtom,
1877
+ newAtom,
1878
+ nativeRenderer,
1879
+ context,
1880
+ effect,
1881
+ parentComponent
1882
+ }
1883
+ });
1443
1884
  return startDiffAtom;
1444
1885
  }
1445
- function createNewView(start, nativeRenderer, context, parentComponent, effect) {
1446
- return function () {
1447
- buildView(nativeRenderer, parentComponent, start, context);
1448
- effect();
1449
- };
1886
+ function patchUpdate(params) {
1887
+ const { nativeRenderer, parentComponent, newAtom, context, effect } = params;
1888
+ buildView(nativeRenderer, parentComponent, newAtom, context);
1889
+ effect();
1450
1890
  }
1451
- function updateText(newAtom, oldAtom, nativeRenderer, context) {
1452
- return function (offset, needMove) {
1453
- const nativeNode = oldAtom.nativeNode;
1454
- newAtom.nativeNode = nativeNode;
1455
- if (needMove || newAtom.index - offset !== oldAtom.index) {
1456
- insertNode(nativeRenderer, newAtom, context);
1457
- }
1458
- context.host = nativeNode;
1459
- context.isParent = false;
1460
- };
1891
+ function updateText(params, offset, needMove) {
1892
+ const { oldAtom, newAtom, nativeRenderer, context } = params;
1893
+ const nativeNode = oldAtom.nativeNode;
1894
+ newAtom.nativeNode = nativeNode;
1895
+ if (needMove || newAtom.index - offset !== oldAtom.index) {
1896
+ insertNode(nativeRenderer, newAtom, context);
1897
+ }
1898
+ context.host = nativeNode;
1899
+ context.isParent = false;
1461
1900
  }
1462
- function updateElement(newAtom, oldAtom, nativeRenderer, context, parentComponent) {
1463
- return function (offset, needMove) {
1464
- newAtom.nativeNode = oldAtom.nativeNode;
1465
- if (needMove || newAtom.index - offset !== oldAtom.index) {
1466
- insertNode(nativeRenderer, newAtom, context);
1467
- }
1468
- context.host = newAtom.nativeNode;
1469
- context.isParent = false;
1470
- updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, {
1471
- host: newAtom.nativeNode,
1472
- isParent: true,
1473
- rootHost: context.rootHost
1474
- });
1475
- };
1901
+ function updateElement(params, offset, needMove) {
1902
+ const { nativeRenderer, newAtom, oldAtom, context, parentComponent } = params;
1903
+ newAtom.nativeNode = oldAtom.nativeNode;
1904
+ if (needMove || newAtom.index - offset !== oldAtom.index) {
1905
+ insertNode(nativeRenderer, newAtom, context);
1906
+ }
1907
+ context.host = newAtom.nativeNode;
1908
+ context.isParent = false;
1909
+ updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, {
1910
+ host: newAtom.nativeNode,
1911
+ isParent: true,
1912
+ rootHost: context.rootHost
1913
+ });
1476
1914
  }
1477
- function updateComponent(newAtom, reusedAtom, nativeRenderer, context) {
1478
- return function (offset, needMove) {
1479
- const component = reusedAtom.jsxNode;
1480
- const newProps = newAtom.jsxNode.props;
1481
- const portalHost = component.instance.$portalHost;
1482
- context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
1483
- componentViewCache.set(component, Object.assign({ atom: newAtom }, context));
1484
- newAtom.jsxNode = component;
1485
- component.update(newProps, newTemplate => {
1486
- if (newTemplate) {
1487
- newAtom.child = createChildChain(newTemplate, newAtom.namespace);
1488
- }
1489
- if (newAtom.child) {
1490
- diff(nativeRenderer, component, newAtom.child, reusedAtom.child, context, needMove || newAtom.index - offset !== reusedAtom.index);
1491
- }
1492
- else if (reusedAtom.child) {
1493
- let atom = reusedAtom.child;
1494
- while (atom) {
1495
- cleanView(nativeRenderer, atom, true);
1496
- atom = atom.sibling;
1497
- }
1498
- }
1499
- }, (skipSubComponentDiff) => {
1500
- newAtom.child = reusedAtom.child;
1501
- reuseComponentView(nativeRenderer, newAtom.child, context, needMove || newAtom.index - offset !== reusedAtom.index, skipSubComponentDiff);
1502
- });
1503
- };
1915
+ function updateComponent(params, offset, needMove) {
1916
+ const { oldAtom, newAtom, nativeRenderer } = params;
1917
+ let context = params.context;
1918
+ const component = oldAtom.jsxNode;
1919
+ const portalHost = component.instance.$portalHost;
1920
+ context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
1921
+ component.viewMetadata = Object.assign({ atom: newAtom }, context);
1922
+ const newProps = newAtom.jsxNode.props;
1923
+ newAtom.jsxNode = component;
1924
+ needMove = needMove || newAtom.index - offset !== oldAtom.index;
1925
+ const canUpdate = component.canUpdate(component.props, newProps);
1926
+ const propsIsChanged = hasChange(newProps, component.props);
1927
+ if (propsIsChanged) {
1928
+ component.updateProps(newProps);
1929
+ }
1930
+ if (canUpdate && (propsIsChanged || component.dirty)) {
1931
+ patchComponent(nativeRenderer, component, oldAtom.child, newAtom, context, needMove);
1932
+ const next = oldAtom.sibling;
1933
+ if (next && next.jsxNode instanceof Component) {
1934
+ const view = next.jsxNode.viewMetadata;
1935
+ view.host = context.host;
1936
+ view.isParent = context.isParent;
1937
+ }
1938
+ }
1939
+ else {
1940
+ newAtom.child = oldAtom.child;
1941
+ reuseComponentView(nativeRenderer, newAtom.child, context, needMove, !canUpdate);
1942
+ }
1943
+ component.rendered();
1504
1944
  }
1505
1945
  function reuseComponentView(nativeRenderer, child, context, moveView, skipSubComponentDiff) {
1506
1946
  const updateContext = (atom) => {
1507
- if (atom.jsxNode instanceof Component) {
1508
- if (skipSubComponentDiff || !moveView) {
1509
- let child = atom.child;
1510
- while (child) {
1511
- updateContext(child);
1512
- child = child.sibling;
1513
- }
1514
- }
1515
- else {
1516
- applyChanges(nativeRenderer, atom.jsxNode, atom, context, true);
1947
+ const jsxNode = atom.jsxNode;
1948
+ if (jsxNode instanceof Component) {
1949
+ reuseComponentView(nativeRenderer, atom.child, context, moveView, skipSubComponentDiff);
1950
+ if (!skipSubComponentDiff) {
1951
+ deepUpdateByComponentDirtyTree(nativeRenderer, jsxNode, moveView);
1517
1952
  }
1518
1953
  }
1519
1954
  else {
@@ -1534,7 +1969,7 @@ function reuseElementChildrenView(nativeRenderer, atom, context, skipSubComponen
1534
1969
  let child = atom.child;
1535
1970
  while (child) {
1536
1971
  if (child.jsxNode instanceof Component) {
1537
- updateView(nativeRenderer, child.jsxNode, false);
1972
+ deepUpdateByComponentDirtyTree(nativeRenderer, child.jsxNode, false);
1538
1973
  }
1539
1974
  else {
1540
1975
  reuseElementChildrenView(nativeRenderer, child);
@@ -1581,7 +2016,7 @@ function componentRender(nativeRenderer, component, from, context) {
1581
2016
  component.render((template, portalHost) => {
1582
2017
  from.child = createChildChain(template, from.namespace);
1583
2018
  context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
1584
- componentViewCache.set(component, Object.assign({ atom: from }, context));
2019
+ component.viewMetadata = Object.assign({ atom: from }, context);
1585
2020
  let child = from.child;
1586
2021
  while (child) {
1587
2022
  buildView(nativeRenderer, component, child, context);
@@ -1606,14 +2041,14 @@ function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, namespace, key)
1606
2041
  }
1607
2042
  function createChainByNode(jsxNode, prevAtom, elementNamespace) {
1608
2043
  const type = typeof jsxNode;
1609
- if (jsxNode !== null && type !== 'undefined' && type !== 'boolean') {
1610
- if (typeof jsxNode === 'string') {
2044
+ if (jsxNode != null && type !== 'boolean') {
2045
+ if (type === 'string') {
1611
2046
  return createChainByJSXNode(TextAtomType, jsxNode, jsxNode, prevAtom, elementNamespace);
1612
2047
  }
1613
- if (Array.isArray(jsxNode)) {
1614
- return createChainByChildren(jsxNode, prevAtom, elementNamespace);
1615
- }
1616
2048
  if (type === 'object') {
2049
+ if (Array.isArray(jsxNode)) {
2050
+ return createChainByChildren(jsxNode, prevAtom, elementNamespace);
2051
+ }
1617
2052
  const nodeType = typeof jsxNode.type;
1618
2053
  if (nodeType === 'string') {
1619
2054
  return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom, elementNamespace || ElementNamespaceMap[jsxNode.type], jsxNode.key);
@@ -1653,6 +2088,12 @@ function insertNode(nativeRenderer, atom, context) {
1653
2088
  nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.namespace);
1654
2089
  }
1655
2090
  }
2091
+ function createElementChildren(type, children, namespace) {
2092
+ if (type === 'foreignObject' && namespace === ElementNamespaceMap.svg) {
2093
+ return createChildChain(children, void 0);
2094
+ }
2095
+ return createChildChain(children, namespace);
2096
+ }
1656
2097
  function createElement(nativeRenderer, atom, parentComponent, context) {
1657
2098
  const { namespace, jsxNode } = atom;
1658
2099
  const nativeNode = nativeRenderer.createElement(jsxNode.type, namespace);
@@ -1660,7 +2101,7 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
1660
2101
  let bindingRefs;
1661
2102
  for (const key in props) {
1662
2103
  if (key === 'children') {
1663
- atom.child = createChildChain(jsxNode.props.children, namespace);
2104
+ atom.child = createElementChildren(jsxNode.type, props.children, namespace);
1664
2105
  continue;
1665
2106
  }
1666
2107
  if (key === 'class') {
@@ -1718,46 +2159,69 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1718
2159
  reuseElementChildrenView(nativeRenderer, newAtom);
1719
2160
  return;
1720
2161
  }
1721
- const changes = getObjectChanges(newVNode.props, oldVNode.props);
1722
2162
  let unBindRefs;
1723
2163
  let bindRefs;
1724
2164
  let updatedChildren = false;
1725
- let len = changes.remove.length;
1726
- for (let i = 0; i < len; i++) {
1727
- const [key, value] = changes.remove[i];
2165
+ comparePropsWithCallbacks(oldVNode.props, newVNode.props, (key, oldValue) => {
1728
2166
  if (key === 'children') {
1729
2167
  updatedChildren = true;
1730
2168
  cleanElementChildren(oldAtom, nativeRenderer);
1731
- continue;
2169
+ return;
1732
2170
  }
1733
2171
  if (key === 'class') {
1734
2172
  nativeRenderer.setClass(nativeNode, '', isSvg);
1735
- continue;
2173
+ return;
1736
2174
  }
1737
2175
  if (key === 'style') {
1738
- for (const styleName in styleToObject(value)) {
2176
+ for (const styleName in styleToObject(oldValue)) {
1739
2177
  nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
1740
2178
  }
1741
- continue;
2179
+ return;
1742
2180
  }
1743
2181
  if (listenerReg.test(key)) {
1744
- if (typeof value === 'function') {
1745
- nativeRenderer.unListen(nativeNode, key, value, isSvg);
2182
+ if (typeof oldValue === 'function') {
2183
+ nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
1746
2184
  }
1747
- continue;
2185
+ return;
1748
2186
  }
1749
2187
  if (key === refKey) {
1750
- unBindRefs = value;
1751
- continue;
2188
+ unBindRefs = oldValue;
2189
+ return;
1752
2190
  }
1753
2191
  nativeRenderer.removeProperty(nativeNode, key, isSvg);
1754
- }
1755
- len = changes.replace.length;
1756
- for (let i = 0; i < len; i++) {
1757
- const [key, newValue, oldValue] = changes.replace[i];
2192
+ }, (key, value) => {
2193
+ if (key === 'children') {
2194
+ updatedChildren = true;
2195
+ newAtom.child = createElementChildren(newVNode.type, value, isSvg);
2196
+ buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
2197
+ return;
2198
+ }
2199
+ if (key === 'class') {
2200
+ nativeRenderer.setClass(nativeNode, classToString(value), isSvg);
2201
+ return;
2202
+ }
2203
+ if (key === 'style') {
2204
+ const styleObj = styleToObject(value);
2205
+ for (const styleName in styleObj) {
2206
+ nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
2207
+ }
2208
+ return;
2209
+ }
2210
+ if (listenerReg.test(key)) {
2211
+ if (typeof value === 'function') {
2212
+ nativeRenderer.listen(nativeNode, key, value, isSvg);
2213
+ }
2214
+ return;
2215
+ }
2216
+ if (key === refKey) {
2217
+ bindRefs = value;
2218
+ return;
2219
+ }
2220
+ nativeRenderer.setProperty(nativeNode, key, value, isSvg);
2221
+ }, (key, newValue, oldValue) => {
1758
2222
  if (key === 'children') {
1759
2223
  updatedChildren = true;
1760
- newAtom.child = createChildChain(newValue, isSvg);
2224
+ newAtom.child = createElementChildren(newVNode.type, newValue, isSvg);
1761
2225
  if (!newAtom.child) {
1762
2226
  cleanElementChildren(oldAtom, nativeRenderer);
1763
2227
  }
@@ -1767,7 +2231,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1767
2231
  else {
1768
2232
  diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, context, false);
1769
2233
  }
1770
- continue;
2234
+ return;
1771
2235
  }
1772
2236
  if (key === 'class') {
1773
2237
  const oldClassName = classToString(oldValue);
@@ -1775,62 +2239,30 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1775
2239
  if (oldClassName !== newClassName) {
1776
2240
  nativeRenderer.setClass(nativeNode, newClassName, isSvg);
1777
2241
  }
1778
- continue;
2242
+ return;
1779
2243
  }
1780
2244
  if (key === 'style') {
1781
- const styleChanges = getObjectChanges(styleToObject(newValue) || {}, styleToObject(oldValue) || {});
1782
- for (const [styleName] of styleChanges.remove) {
2245
+ comparePropsWithCallbacks(styleToObject(oldValue), styleToObject(newValue), styleName => {
1783
2246
  nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
1784
- }
1785
- for (const [styleName, styleValue] of [...styleChanges.add, ...styleChanges.replace]) {
2247
+ }, (styleName, styleValue) => {
1786
2248
  nativeRenderer.setStyle(nativeNode, styleName, styleValue, isSvg);
1787
- }
1788
- continue;
2249
+ }, (styleName, styleValue) => {
2250
+ nativeRenderer.setStyle(nativeNode, styleName, styleValue, isSvg);
2251
+ });
2252
+ return;
1789
2253
  }
1790
2254
  if (listenerReg.test(key)) {
1791
2255
  nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
1792
2256
  nativeRenderer.listen(nativeNode, key, newValue, isSvg);
1793
- continue;
2257
+ return;
1794
2258
  }
1795
2259
  if (key === refKey) {
1796
2260
  unBindRefs = oldValue;
1797
2261
  bindRefs = newValue;
1798
- continue;
2262
+ return;
1799
2263
  }
1800
2264
  nativeRenderer.setProperty(nativeNode, key, newValue, isSvg);
1801
- }
1802
- len = changes.add.length;
1803
- for (let i = 0; i < len; i++) {
1804
- const [key, value] = changes.add[i];
1805
- if (key === 'children') {
1806
- updatedChildren = true;
1807
- newAtom.child = createChildChain(value, isSvg);
1808
- buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
1809
- continue;
1810
- }
1811
- if (key === 'class') {
1812
- nativeRenderer.setClass(nativeNode, classToString(value), isSvg);
1813
- continue;
1814
- }
1815
- if (key === 'style') {
1816
- const styleObj = styleToObject(value);
1817
- for (const styleName in styleObj) {
1818
- nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
1819
- }
1820
- continue;
1821
- }
1822
- if (listenerReg.test(key)) {
1823
- if (typeof value === 'function') {
1824
- nativeRenderer.listen(nativeNode, key, value, isSvg);
1825
- }
1826
- continue;
1827
- }
1828
- if (key === refKey) {
1829
- bindRefs = value;
1830
- continue;
1831
- }
1832
- nativeRenderer.setProperty(nativeNode, key, value, isSvg);
1833
- }
2265
+ });
1834
2266
  if (!updatedChildren) {
1835
2267
  newAtom.child = oldAtom.child;
1836
2268
  reuseElementChildrenView(nativeRenderer, newAtom);
@@ -1873,133 +2305,6 @@ class RootComponent extends Component {
1873
2305
  }
1874
2306
  }
1875
2307
 
1876
- /**
1877
- * 组件状态管理器
1878
- * @param state 初始状态
1879
- * @example
1880
- * ```tsx
1881
- * function App() {
1882
- * // 初始化状态
1883
- * const state = createSignal(1)
1884
- *
1885
- * return () => {
1886
- * <div>
1887
- * <div>当前值为:{state()}</div>
1888
- * <div>
1889
- * <button type="button" onClick={() => {
1890
- * // 当点击时更新状态
1891
- * state.set(state() + 1)
1892
- * }
1893
- * }>updateState</button>
1894
- * </div>
1895
- * </div>
1896
- * }
1897
- * }
1898
- */
1899
- function createSignal(state) {
1900
- const subscribers = new Set();
1901
- function signal() {
1902
- const listener = getCurrentListener();
1903
- if (listener && !subscribers.has(listener)) {
1904
- listener.destroyCallbacks.push(() => {
1905
- subscribers.delete(listener);
1906
- });
1907
- subscribers.add(listener);
1908
- }
1909
- return state;
1910
- }
1911
- signal.set = function (newValue) {
1912
- if (newValue === state) {
1913
- return;
1914
- }
1915
- state = newValue;
1916
- const listeners = Array.from(subscribers);
1917
- listeners.forEach(listener => listener.effect());
1918
- };
1919
- return signal;
1920
- }
1921
- /**
1922
- * 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
1923
- * 并在你获取 createDerived 函数返回的 Signal 的值时,自动计算最新的值。
1924
- *
1925
- * @param fn
1926
- * @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
1927
- */
1928
- function computed(fn, isContinue) {
1929
- let isStop = false;
1930
- function canListen(value) {
1931
- if (isContinue) {
1932
- const b = isContinue(value);
1933
- if (b === false) {
1934
- listener.destroy();
1935
- return false;
1936
- }
1937
- }
1938
- return true;
1939
- }
1940
- const listener = new Listener(() => {
1941
- if (isStop) {
1942
- return;
1943
- }
1944
- isStop = true;
1945
- listener.destroy();
1946
- pushListener(listener);
1947
- const value = fn();
1948
- popListener();
1949
- signal.set(value);
1950
- canListen(value);
1951
- isStop = false;
1952
- });
1953
- pushListener(listener);
1954
- const value = fn();
1955
- const signal = createSignal(value);
1956
- popListener();
1957
- isStop = false;
1958
- if (canListen(value)) {
1959
- registryComponentDestroyCallback(() => listener.destroy());
1960
- }
1961
- return signal;
1962
- }
1963
- const createDerived = computed;
1964
- /* eslint-enable max-len*/
1965
- function watch(deps, callback) {
1966
- let prevFn;
1967
- const isArray = Array.isArray(deps);
1968
- const effect = new Listener(function () {
1969
- if (prevFn) {
1970
- prevFn();
1971
- }
1972
- const newValue = isArray ? deps.map(fn => fn()) : deps();
1973
- prevFn = callback(newValue, oldValue);
1974
- oldValue = newValue;
1975
- });
1976
- pushListener(effect);
1977
- let oldValue = isArray ? deps.map(fn => fn()) : deps();
1978
- popListener();
1979
- let isUnWatch = false;
1980
- function unWatch() {
1981
- if (isUnWatch) {
1982
- return;
1983
- }
1984
- isUnWatch = true;
1985
- if (prevFn) {
1986
- prevFn();
1987
- }
1988
- effect.destroy();
1989
- }
1990
- registryComponentDestroyCallback(unWatch);
1991
- return unWatch;
1992
- }
1993
- function registryComponentDestroyCallback(fn) {
1994
- const component = getSetupContext(false);
1995
- if (component) {
1996
- if (!component.unmountedCallbacks) {
1997
- component.unmountedCallbacks = [];
1998
- }
1999
- component.unmountedCallbacks.push(fn);
2000
- }
2001
- }
2002
-
2003
2308
  const viewflyErrorFn = makeError('Viewfly');
2004
2309
  function viewfly(config) {
2005
2310
  const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
@@ -2008,7 +2313,7 @@ function viewfly(config) {
2008
2313
  let appHost = null;
2009
2314
  const rootProviders = [];
2010
2315
  const rootComponent = new RootComponent(() => {
2011
- const rootContext = createContext(rootProviders, void 0, context);
2316
+ const rootContext = createContext(rootProviders, null, context);
2012
2317
  return () => {
2013
2318
  return jsx(rootContext, {
2014
2319
  children: destroyed ? null : root
@@ -2087,7 +2392,127 @@ function viewfly(config) {
2087
2392
  return app;
2088
2393
  }
2089
2394
 
2395
+ function computed(callback, isContinue) {
2396
+ let isStop = false;
2397
+ const dep = new Dep(() => {
2398
+ if (isStop) {
2399
+ return;
2400
+ }
2401
+ isStop = true;
2402
+ dep.destroy();
2403
+ pushDepContext(dep);
2404
+ const value = callback();
2405
+ popDepContext();
2406
+ internalWrite(() => {
2407
+ proxy.value = value;
2408
+ });
2409
+ canListen(value);
2410
+ isStop = false;
2411
+ });
2412
+ pushDepContext(dep);
2413
+ const value = callback();
2414
+ popDepContext();
2415
+ const proxy = new Proxy({
2416
+ value
2417
+ }, readonlyProxyHandler);
2418
+ function canListen(value) {
2419
+ if (isContinue) {
2420
+ const b = isContinue(value);
2421
+ if (b === false) {
2422
+ dep.destroy();
2423
+ return false;
2424
+ }
2425
+ }
2426
+ return true;
2427
+ }
2428
+ if (!canListen(value)) {
2429
+ return proxy;
2430
+ }
2431
+ registryComponentDestroyCallback(() => {
2432
+ dep.destroy();
2433
+ });
2434
+ return proxy;
2435
+ }
2436
+
2437
+ const defaultShallowObjectReactiveHandler = new ObjectReactiveHandler({
2438
+ readonly: false,
2439
+ shallow: true
2440
+ });
2441
+ const defaultShallowArrayReactiveHandler = new ArrayReactiveHandler({
2442
+ readonly: false,
2443
+ shallow: true
2444
+ });
2445
+ const defaultShallowMapReactiveHandler = new MapReactiveHandler({
2446
+ readonly: false,
2447
+ shallow: true
2448
+ });
2449
+ const defaultShallowSetReactiveHandler = new SetReactiveHandler({
2450
+ readonly: false,
2451
+ shallow: true
2452
+ });
2453
+ function shallowReactive(raw) {
2454
+ if (isReactive(raw)) {
2455
+ return raw;
2456
+ }
2457
+ let proxy = rawToProxyCache.get(raw);
2458
+ if (proxy) {
2459
+ return proxy;
2460
+ }
2461
+ const type = getStringType(raw);
2462
+ switch (type) {
2463
+ case '[object Object]':
2464
+ proxy = new Proxy(raw, defaultShallowObjectReactiveHandler);
2465
+ break;
2466
+ case '[object Array]':
2467
+ proxy = new Proxy(raw, defaultShallowArrayReactiveHandler);
2468
+ break;
2469
+ case '[object Set]':
2470
+ case '[object WeakSet]':
2471
+ proxy = new Proxy(raw, defaultShallowSetReactiveHandler);
2472
+ break;
2473
+ case '[object Map]':
2474
+ case '[object WeakMap]':
2475
+ proxy = new Proxy(raw, defaultShallowMapReactiveHandler);
2476
+ break;
2477
+ default:
2478
+ return raw;
2479
+ }
2480
+ rawToProxyCache.set(raw, proxy);
2481
+ proxyToRawCache.set(proxy, raw);
2482
+ return proxy;
2483
+ }
2484
+
2485
+ function watch(trigger, callback) {
2486
+ let prevFn;
2487
+ const dep = new Dep(() => {
2488
+ pushDepContext(dep);
2489
+ const newValue = trigger();
2490
+ popDepContext();
2491
+ if (newValue === oldValue) {
2492
+ return;
2493
+ }
2494
+ if (prevFn) {
2495
+ prevFn();
2496
+ }
2497
+ prevFn = callback(newValue, oldValue);
2498
+ oldValue = newValue;
2499
+ });
2500
+ pushDepContext(dep);
2501
+ let oldValue = trigger();
2502
+ popDepContext();
2503
+ dep.destroyCallbacks.push(() => {
2504
+ prevFn === null || prevFn === void 0 ? void 0 : prevFn();
2505
+ });
2506
+ function unWatch() {
2507
+ dep.destroy();
2508
+ }
2509
+ registryComponentDestroyCallback(unWatch);
2510
+ return unWatch;
2511
+ }
2512
+
2513
+ exports.ArrayReactiveHandler = ArrayReactiveHandler;
2090
2514
  exports.Component = Component;
2515
+ exports.Dep = Dep;
2091
2516
  exports.DynamicRef = DynamicRef;
2092
2517
  exports.ElementNamespaceMap = ElementNamespaceMap;
2093
2518
  exports.ForwardRef = ForwardRef;
@@ -2097,37 +2522,60 @@ exports.Injectable = Injectable;
2097
2522
  exports.InjectionToken = InjectionToken;
2098
2523
  exports.Injector = Injector;
2099
2524
  exports.JSXNodeFactory = JSXNodeFactory;
2525
+ exports.MapReactiveHandler = MapReactiveHandler;
2100
2526
  exports.NativeRenderer = NativeRenderer;
2101
2527
  exports.NullInjector = NullInjector;
2528
+ exports.ObjectReactiveHandler = ObjectReactiveHandler;
2102
2529
  exports.Optional = Optional;
2103
2530
  exports.Prop = Prop;
2104
2531
  exports.ReflectiveInjector = ReflectiveInjector;
2105
2532
  exports.RootComponent = RootComponent;
2106
2533
  exports.Scope = Scope;
2107
2534
  exports.Self = Self;
2535
+ exports.SetReactiveHandler = SetReactiveHandler;
2108
2536
  exports.SkipSelf = SkipSelf;
2109
2537
  exports.StaticRef = StaticRef;
2110
2538
  exports.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
2111
2539
  exports.Type = Type;
2540
+ exports.comparePropsWithCallbacks = comparePropsWithCallbacks;
2112
2541
  exports.computed = computed;
2113
2542
  exports.createContext = createContext;
2114
- exports.createDerived = createDerived;
2115
2543
  exports.createDynamicRef = createDynamicRef;
2116
2544
  exports.createRef = createRef;
2117
2545
  exports.createRenderer = createRenderer;
2118
- exports.createSignal = createSignal;
2546
+ exports.defaultArrayReactiveHandler = defaultArrayReactiveHandler;
2547
+ exports.defaultMapReactiveHandler = defaultMapReactiveHandler;
2548
+ exports.defaultObjectReactiveHandler = defaultObjectReactiveHandler;
2549
+ exports.defaultSetReactiveHandler = defaultSetReactiveHandler;
2550
+ exports.defaultShallowArrayReactiveHandler = defaultShallowArrayReactiveHandler;
2551
+ exports.defaultShallowMapReactiveHandler = defaultShallowMapReactiveHandler;
2552
+ exports.defaultShallowObjectReactiveHandler = defaultShallowObjectReactiveHandler;
2553
+ exports.defaultShallowSetReactiveHandler = defaultShallowSetReactiveHandler;
2119
2554
  exports.forwardRef = forwardRef;
2120
2555
  exports.getCurrentInstance = getCurrentInstance;
2556
+ exports.getDepContext = getDepContext;
2121
2557
  exports.getSetupContext = getSetupContext;
2122
2558
  exports.inject = inject;
2559
+ exports.internalWrite = internalWrite;
2560
+ exports.isReactive = isReactive;
2123
2561
  exports.jsx = jsx;
2124
2562
  exports.jsxs = jsxs;
2125
2563
  exports.makeError = makeError;
2126
2564
  exports.normalizeProvider = normalizeProvider;
2127
2565
  exports.onMounted = onMounted;
2128
- exports.onPropsChanged = onPropsChanged;
2129
2566
  exports.onUnmounted = onUnmounted;
2130
2567
  exports.onUpdated = onUpdated;
2568
+ exports.popDepContext = popDepContext;
2569
+ exports.proxyToRawCache = proxyToRawCache;
2570
+ exports.pushDepContext = pushDepContext;
2571
+ exports.rawToProxyCache = rawToProxyCache;
2572
+ exports.reactive = reactive;
2573
+ exports.readonlyProxyHandler = readonlyProxyHandler;
2574
+ exports.registryComponentDestroyCallback = registryComponentDestroyCallback;
2575
+ exports.shallowReactive = shallowReactive;
2576
+ exports.toRaw = toRaw;
2577
+ exports.track = track;
2578
+ exports.trigger = trigger;
2131
2579
  exports.viewfly = viewfly;
2132
2580
  exports.watch = watch;
2133
2581
  exports.withAnnotation = withAnnotation;