@viewfly/core 3.0.0-alpha.2 → 3.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/dist/index.esm.js CHANGED
@@ -209,7 +209,7 @@ var NullInjector = class {
209
209
  * @param provider
210
210
  */
211
211
  function normalizeProvider(provider) {
212
- if (provider.useValue) return normalizeValueProviderFactory(provider);
212
+ if (Object.prototype.hasOwnProperty.call(provider, "useValue")) return normalizeValueProviderFactory(provider);
213
213
  if (provider.useClass) return normalizeClassProviderFactory(provider);
214
214
  if (provider.useExisting) return normalizeExistingProviderFactory(provider);
215
215
  if (provider.useFactory) return normalizeFactoryProviderFactory(provider);
@@ -345,13 +345,14 @@ var provideScopeError = (token) => {
345
345
  * 反射注入器
346
346
  */
347
347
  var ReflectiveInjector = class {
348
- normalizedProviders;
348
+ normalizedProviders = /* @__PURE__ */ new Map();
349
349
  recordValues = /* @__PURE__ */ new Map();
350
350
  constructor(parentInjector, staticProviders, scope) {
351
351
  this.parentInjector = parentInjector;
352
352
  this.scope = scope;
353
- this.normalizedProviders = staticProviders.map((provide) => {
354
- return normalizeProvider(provide);
353
+ staticProviders.forEach((provide) => {
354
+ const normalizedProvider = normalizeProvider(provide);
355
+ this.normalizedProviders.set(normalizedProvider.provide, normalizedProvider);
355
356
  });
356
357
  }
357
358
  /**
@@ -368,22 +369,20 @@ var ReflectiveInjector = class {
368
369
  throw reflectiveInjectorErrorFn(token);
369
370
  }
370
371
  if (this.recordValues.has(token)) return this.recordValues.get(token);
371
- for (let i = 0; i < this.normalizedProviders.length; i++) {
372
- const normalizedProvider = this.normalizedProviders[i];
373
- if (normalizedProvider.provide === token) return this.getValue(token, normalizedProvider);
374
- }
372
+ const normalizedProvider = this.normalizedProviders.get(token);
373
+ if (normalizedProvider) return this.getValue(token, normalizedProvider);
375
374
  if (!(token instanceof InjectionToken)) {
376
375
  const scope = getAnnotations(token).getClassMetadata(Injectable)?.metadata.provideIn;
377
376
  if (scope) {
378
377
  const normalizedProvider = normalizeProvider(token);
379
378
  if (this.scope === scope) {
380
- this.normalizedProviders.push(normalizedProvider);
379
+ this.normalizedProviders.set(normalizedProvider.provide, normalizedProvider);
381
380
  return this.getValue(token, normalizedProvider);
382
381
  }
383
382
  const parentInjector = this.parentInjector;
384
383
  if (!parentInjector || parentInjector instanceof NullInjector) {
385
384
  if (normalizedProvider.scope === "root") {
386
- this.normalizedProviders.push(normalizedProvider);
385
+ this.normalizedProviders.set(normalizedProvider.provide, normalizedProvider);
387
386
  return this.getValue(token, normalizedProvider);
388
387
  }
389
388
  if (notFoundValue !== THROW_IF_NOT_FOUND) return notFoundValue;
@@ -402,9 +401,8 @@ var ReflectiveInjector = class {
402
401
  getValue(token, normalizedProvider) {
403
402
  const { generateFactory, deps } = normalizedProvider;
404
403
  const params = this.resolveDeps(deps);
405
- let value = this.recordValues.get(token);
406
- if (value) return value;
407
- value = generateFactory(this, (token, value) => {
404
+ if (this.recordValues.has(token)) return this.recordValues.get(token);
405
+ const value = generateFactory(this, (token, value) => {
408
406
  this.recordValues.set(token, value);
409
407
  })(...params);
410
408
  this.recordValues.set(token, value);
@@ -524,8 +522,9 @@ function hasOwn(target, key) {
524
522
  //#region src/base/dep.ts
525
523
  var Dep = class {
526
524
  destroyCallbacks = [];
527
- constructor(effect) {
525
+ constructor(effect, flushMode = "sync") {
528
526
  this.effect = effect;
527
+ this.flushMode = flushMode;
529
528
  }
530
529
  destroy() {
531
530
  this.destroyCallbacks.forEach((callback) => callback());
@@ -534,7 +533,7 @@ var Dep = class {
534
533
  };
535
534
  var deps = [];
536
535
  function getDepContext() {
537
- return deps.at(-1);
536
+ return deps[deps.length - 1];
538
537
  }
539
538
  function pushDepContext(dep) {
540
539
  deps.push(dep);
@@ -545,6 +544,47 @@ function popDepContext() {
545
544
  //#endregion
546
545
  //#region src/reactive/effect.ts
547
546
  var subscribers = /* @__PURE__ */ new WeakMap();
547
+ var pendingDeps = /* @__PURE__ */ new Set();
548
+ var isFlushScheduled = false;
549
+ var effectErrorFn = makeError("Effect");
550
+ function scheduleDep(dep) {
551
+ if (dep.flushMode === "sync") {
552
+ dep.effect();
553
+ return;
554
+ }
555
+ pendingDeps.add(dep);
556
+ if (!isFlushScheduled) {
557
+ isFlushScheduled = true;
558
+ queueMicrotask(flushPendingDeps);
559
+ }
560
+ }
561
+ function flushPendingDeps() {
562
+ try {
563
+ while (pendingDeps.size > 0) {
564
+ const deps = Array.from(pendingDeps);
565
+ pendingDeps.clear();
566
+ deps.forEach((dep) => {
567
+ dep.effect();
568
+ });
569
+ }
570
+ } finally {
571
+ isFlushScheduled = false;
572
+ if (pendingDeps.size > 0) {
573
+ isFlushScheduled = true;
574
+ queueMicrotask(flushPendingDeps);
575
+ }
576
+ }
577
+ }
578
+ function nextTick() {
579
+ return Promise.resolve();
580
+ }
581
+ /**
582
+ * 同步清空响应式调度队列。
583
+ * @internal 仅用于框架内部桥接与测试控制,不建议业务代码使用。
584
+ */
585
+ function flushReactiveEffectsSync() {
586
+ flushPendingDeps();
587
+ }
548
588
  function getSubscriber(target) {
549
589
  let subscriber = subscribers.get(target);
550
590
  if (!subscriber) {
@@ -564,9 +604,17 @@ var TriggerOpTypes = /* @__PURE__ */ function(TriggerOpTypes) {
564
604
  TriggerOpTypes["Add"] = "Add";
565
605
  TriggerOpTypes["Delete"] = "Delete";
566
606
  TriggerOpTypes["Clear"] = "Clear";
607
+ TriggerOpTypes["Iterate"] = "Iterate";
567
608
  return TriggerOpTypes;
568
609
  }({});
569
610
  var unKnownKey = Symbol("unKnownKey");
611
+ function cleanupEmptyEffects(target, type, key, effects, record, subscriber) {
612
+ if (effects.size > 0) return;
613
+ record.delete(key);
614
+ if (record.size > 0) return;
615
+ subscriber.delete(type);
616
+ if (subscriber.size === 0) subscribers.delete(target);
617
+ }
570
618
  function track(target, type, key = unKnownKey) {
571
619
  const dep = getDepContext();
572
620
  if (dep) {
@@ -582,10 +630,12 @@ function track(target, type, key = unKnownKey) {
582
630
  record.set(key, effects);
583
631
  dep.destroyCallbacks.push(() => {
584
632
  effects.delete(dep);
633
+ cleanupEmptyEffects(target, type, key, effects, record, subscriber);
585
634
  });
586
635
  } else if (!effects.has(dep)) {
587
636
  dep.destroyCallbacks.push(() => {
588
637
  effects.delete(dep);
638
+ cleanupEmptyEffects(target, type, key, effects, record, subscriber);
589
639
  });
590
640
  effects.add(dep);
591
641
  }
@@ -594,23 +644,105 @@ function track(target, type, key = unKnownKey) {
594
644
  function runEffect(key, record) {
595
645
  if (!record) return;
596
646
  const effects = record.get(key);
597
- if (effects) [...effects].forEach((i) => i.effect());
647
+ if (effects) [...effects].forEach((dep) => scheduleDep(dep));
648
+ }
649
+ function collectAllEffects(record, effectSet) {
650
+ if (!record) return;
651
+ record.forEach((effects) => {
652
+ effects.forEach((effect) => {
653
+ effectSet.add(effect);
654
+ });
655
+ });
598
656
  }
599
657
  function trigger(target, type, key = unKnownKey) {
600
- const subscriber = getSubscriber(target);
601
- if (subscriber) switch (type) {
602
- case TriggerOpTypes.Set:
603
- if (isArray(target)) runEffect(unKnownKey, subscriber.get(TrackOpTypes.Iterate));
658
+ const subscriber = subscribers.get(target);
659
+ if (!subscriber) return;
660
+ if (isArray(target)) {
661
+ switch (type) {
662
+ case TriggerOpTypes.Set:
663
+ runEffect(key, subscriber.get(TrackOpTypes.Get));
664
+ runEffect(key, subscriber.get(TrackOpTypes.Has));
665
+ break;
666
+ case TriggerOpTypes.Iterate:
667
+ runEffect(key, subscriber.get(TrackOpTypes.Iterate));
668
+ break;
669
+ case TriggerOpTypes.Delete:
670
+ runEffect(key, subscriber.get(TrackOpTypes.Get));
671
+ runEffect(key, subscriber.get(TrackOpTypes.Has));
672
+ break;
673
+ default: throw effectErrorFn(`trigger: type '${type}' is not supported`);
674
+ }
675
+ return;
676
+ }
677
+ if (target instanceof Map || target instanceof WeakMap) {
678
+ switch (type) {
679
+ case TriggerOpTypes.Set:
680
+ case TriggerOpTypes.Add:
681
+ runEffect(key, subscriber.get(TrackOpTypes.Get));
682
+ runEffect(key, subscriber.get(TrackOpTypes.Has));
683
+ break;
684
+ case TriggerOpTypes.Iterate:
685
+ runEffect(key, subscriber.get(TrackOpTypes.Iterate));
686
+ break;
687
+ case TriggerOpTypes.Delete:
688
+ runEffect(key, subscriber.get(TrackOpTypes.Get));
689
+ runEffect(key, subscriber.get(TrackOpTypes.Has));
690
+ runEffect(key, subscriber.get(TrackOpTypes.Iterate));
691
+ break;
692
+ case TriggerOpTypes.Clear: {
693
+ const effects = /* @__PURE__ */ new Set();
694
+ collectAllEffects(subscriber.get(TrackOpTypes.Get), effects);
695
+ collectAllEffects(subscriber.get(TrackOpTypes.Has), effects);
696
+ collectAllEffects(subscriber.get(TrackOpTypes.Iterate), effects);
697
+ effects.forEach((effect) => scheduleDep(effect));
698
+ break;
699
+ }
700
+ default: throw effectErrorFn(`trigger: type '${type}' is not supported`);
701
+ }
702
+ return;
703
+ }
704
+ if (target instanceof Set || target instanceof WeakSet) {
705
+ switch (type) {
706
+ case TriggerOpTypes.Add:
707
+ runEffect(key, subscriber.get(TrackOpTypes.Get));
708
+ runEffect(key, subscriber.get(TrackOpTypes.Has));
709
+ break;
710
+ case TriggerOpTypes.Iterate:
711
+ runEffect(key, subscriber.get(TrackOpTypes.Iterate));
712
+ break;
713
+ case TriggerOpTypes.Delete:
714
+ runEffect(key, subscriber.get(TrackOpTypes.Get));
715
+ runEffect(key, subscriber.get(TrackOpTypes.Has));
716
+ runEffect(key, subscriber.get(TrackOpTypes.Iterate));
717
+ break;
718
+ case TriggerOpTypes.Clear: {
719
+ const effects = /* @__PURE__ */ new Set();
720
+ collectAllEffects(subscriber.get(TrackOpTypes.Get), effects);
721
+ collectAllEffects(subscriber.get(TrackOpTypes.Has), effects);
722
+ collectAllEffects(subscriber.get(TrackOpTypes.Iterate), effects);
723
+ effects.forEach((effect) => scheduleDep(effect));
724
+ break;
725
+ }
726
+ default: throw effectErrorFn(`trigger: type '${type}' is not supported`);
727
+ }
728
+ return;
729
+ }
730
+ switch (type) {
731
+ case TriggerOpTypes.Add:
604
732
  runEffect(key, subscriber.get(TrackOpTypes.Get));
605
733
  runEffect(key, subscriber.get(TrackOpTypes.Has));
606
734
  break;
607
- case TriggerOpTypes.Add:
608
- case TriggerOpTypes.Clear:
735
+ case TriggerOpTypes.Set:
736
+ runEffect(key, subscriber.get(TrackOpTypes.Get));
737
+ break;
609
738
  case TriggerOpTypes.Delete:
610
- runEffect(unKnownKey, subscriber.get(TrackOpTypes.Iterate));
611
- runEffect(key, subscriber.get(TrackOpTypes.Has));
612
739
  runEffect(key, subscriber.get(TrackOpTypes.Get));
740
+ runEffect(key, subscriber.get(TrackOpTypes.Has));
613
741
  break;
742
+ case TriggerOpTypes.Iterate:
743
+ runEffect(key, subscriber.get(TrackOpTypes.Iterate));
744
+ break;
745
+ default: throw effectErrorFn(`trigger: type '${type}' is not supported`);
614
746
  }
615
747
  }
616
748
  //#endregion
@@ -639,8 +771,8 @@ function createIterableIterator(wrapper) {
639
771
  function applyPredicateMethod(self, methodName, predicate, wrapper, thisArg) {
640
772
  const target = toRaw(self);
641
773
  track(target, TrackOpTypes.Iterate);
642
- return target[methodName]((value, index, array) => {
643
- return predicate.call(target, wrapper(value), index, array);
774
+ return target[methodName]((value, index) => {
775
+ return predicate.call(thisArg, wrapper(value), index, self);
644
776
  }, thisArg);
645
777
  }
646
778
  function applySearchMethod(self, methodName, args) {
@@ -648,11 +780,14 @@ function applySearchMethod(self, methodName, args) {
648
780
  track(target, TrackOpTypes.Iterate);
649
781
  return target[methodName](...args.map(toRaw));
650
782
  }
783
+ function triggerArrayByRange(target, startIndex, endIndex) {
784
+ for (; startIndex < endIndex; startIndex++) trigger(target, TriggerOpTypes.Set, startIndex + "");
785
+ }
651
786
  function createArrayHandlers(wrapper) {
652
787
  return {
653
788
  concat(...items) {
654
789
  const target = toRaw(this);
655
- trigger(target, TriggerOpTypes.Add);
790
+ track(target, TrackOpTypes.Iterate);
656
791
  return target.concat(...items);
657
792
  },
658
793
  every(predicate, thisArg) {
@@ -695,13 +830,23 @@ function createArrayHandlers(wrapper) {
695
830
  },
696
831
  pop() {
697
832
  const target = toRaw(this);
698
- trigger(target, TriggerOpTypes.Delete);
699
- return target.pop();
833
+ const oldLength = target.length;
834
+ const value = target.pop();
835
+ const newLength = target.length;
836
+ if (newLength < oldLength) {
837
+ trigger(target, TriggerOpTypes.Set, newLength + "");
838
+ trigger(target, TriggerOpTypes.Set, "length");
839
+ trigger(target, TriggerOpTypes.Iterate);
840
+ }
841
+ return value;
700
842
  },
701
843
  push(...items) {
702
844
  const target = toRaw(this);
703
- trigger(target, TriggerOpTypes.Add);
704
- return target.push(...items);
845
+ const oldLength = target.length;
846
+ const length = target.push(...items);
847
+ triggerArrayByRange(target, oldLength, length);
848
+ trigger(target, TriggerOpTypes.Iterate);
849
+ return length;
705
850
  },
706
851
  reduce(callbackFn, ...args) {
707
852
  const target = toRaw(this);
@@ -721,18 +866,27 @@ function createArrayHandlers(wrapper) {
721
866
  },
722
867
  shift() {
723
868
  const target = toRaw(this);
724
- trigger(target, TriggerOpTypes.Delete);
725
- return target.shift();
869
+ const oldLength = target.length;
870
+ const value = target.shift();
871
+ if (target.length < oldLength) {
872
+ triggerArrayByRange(target, 0, oldLength);
873
+ trigger(target, TriggerOpTypes.Set, "length");
874
+ trigger(target, TriggerOpTypes.Iterate);
875
+ }
876
+ return value;
726
877
  },
727
878
  some(predicate, thisArg) {
728
879
  return applyPredicateMethod(this, "some", predicate, wrapper, thisArg);
729
880
  },
730
- splice(start, deleteCount) {
881
+ splice(start, ...items) {
731
882
  const target = toRaw(this);
732
- trigger(target, TriggerOpTypes.Set);
733
- trigger(target, TriggerOpTypes.Add);
734
- trigger(target, TriggerOpTypes.Delete);
735
- return target.splice(start, deleteCount).map((i) => wrapper(i));
883
+ const oldLength = target.length;
884
+ const deleted = target.splice(start, ...items).map((i) => wrapper(i));
885
+ const newLength = target.length;
886
+ triggerArrayByRange(target, start, Math.max(oldLength, newLength));
887
+ if (oldLength !== newLength) trigger(target, TriggerOpTypes.Set, "length");
888
+ trigger(target, TriggerOpTypes.Iterate);
889
+ return deleted;
736
890
  },
737
891
  toReversed() {
738
892
  const target = toRaw(this);
@@ -751,8 +905,11 @@ function createArrayHandlers(wrapper) {
751
905
  },
752
906
  unshift(...items) {
753
907
  const target = toRaw(this);
754
- trigger(target, TriggerOpTypes.Add);
755
- return target.unshift(...items);
908
+ const length = target.unshift(...items);
909
+ triggerArrayByRange(target, 0, length);
910
+ trigger(target, TriggerOpTypes.Set, "length");
911
+ trigger(target, TriggerOpTypes.Iterate);
912
+ return length;
756
913
  },
757
914
  [Symbol.iterator]() {
758
915
  return this.values();
@@ -765,6 +922,7 @@ function createArrayHandlers(wrapper) {
765
922
  function createMapHandlers(wrapper) {
766
923
  return {
767
924
  get(key) {
925
+ key = toRaw(key);
768
926
  const target = toRaw(this);
769
927
  track(target, TrackOpTypes.Get, key);
770
928
  return wrapper(target.get(key));
@@ -774,8 +932,11 @@ function createMapHandlers(wrapper) {
774
932
  key = toRaw(key);
775
933
  value = toRaw(value);
776
934
  const has = target.has(key);
935
+ const oldValue = has ? target.get(key) : void 0;
936
+ if (has && Object.is(oldValue, value)) return this;
777
937
  const r = target.set(key, value);
778
938
  trigger(target, has ? TriggerOpTypes.Set : TriggerOpTypes.Add, key);
939
+ if (!has) trigger(target, TriggerOpTypes.Iterate);
779
940
  return r;
780
941
  },
781
942
  has(key) {
@@ -789,19 +950,21 @@ function createMapHandlers(wrapper) {
789
950
  key = toRaw(key);
790
951
  const r = target.delete(key);
791
952
  trigger(target, TriggerOpTypes.Delete, key);
953
+ if (r) trigger(target, TriggerOpTypes.Iterate);
792
954
  return r;
793
955
  },
794
956
  forEach(callbackFn, thisArg) {
795
957
  const target = toRaw(this);
796
- track(target, TrackOpTypes.Iterate, void 0);
958
+ track(target, TrackOpTypes.Iterate);
797
959
  target.forEach((v, k, m) => {
798
- callbackFn.call(this, wrapper(v), wrapper(k), m);
960
+ callbackFn.call(thisArg, wrapper(v), wrapper(k), m);
799
961
  }, thisArg);
800
962
  },
801
963
  clear() {
802
964
  const target = toRaw(this);
965
+ if (target.size === 0) return;
803
966
  target.clear();
804
- trigger(target, TriggerOpTypes.Clear, void 0);
967
+ trigger(target, TriggerOpTypes.Clear);
805
968
  },
806
969
  [Symbol.iterator]() {
807
970
  return this.entries();
@@ -818,16 +981,19 @@ function createSetHandlers(wrapper) {
818
981
  value = toRaw(value);
819
982
  if (!target.has(value)) {
820
983
  target.add(value);
821
- trigger(target, TriggerOpTypes.Add, void 0);
984
+ trigger(target, TriggerOpTypes.Add, value);
985
+ trigger(target, TriggerOpTypes.Iterate);
822
986
  }
823
987
  return this;
824
988
  },
825
989
  delete(value) {
826
990
  const target = toRaw(this);
827
991
  value = toRaw(value);
828
- const has = target.has(value);
829
992
  const b = target.delete(value);
830
- if (!has) trigger(target, TriggerOpTypes.Delete, void 0);
993
+ if (b) {
994
+ trigger(target, TriggerOpTypes.Delete, value);
995
+ trigger(target, TriggerOpTypes.Iterate);
996
+ }
831
997
  return b;
832
998
  },
833
999
  has(key) {
@@ -838,16 +1004,16 @@ function createSetHandlers(wrapper) {
838
1004
  },
839
1005
  forEach(callbackFn, thisArg) {
840
1006
  const target = toRaw(this);
841
- track(target, TrackOpTypes.Iterate, void 0);
1007
+ track(target, TrackOpTypes.Iterate);
842
1008
  target.forEach((v, k, m) => {
843
- callbackFn.call(this, wrapper(v), wrapper(k), m);
1009
+ callbackFn.call(thisArg, wrapper(v), wrapper(k), m);
844
1010
  }, thisArg);
845
1011
  },
846
1012
  clear() {
847
1013
  const target = toRaw(this);
848
1014
  if (target.size !== 0) {
849
1015
  target.clear();
850
- trigger(target, TriggerOpTypes.Clear, void 0);
1016
+ trigger(target, TriggerOpTypes.Clear);
851
1017
  }
852
1018
  },
853
1019
  [Symbol.iterator]() {
@@ -861,6 +1027,8 @@ function createSetHandlers(wrapper) {
861
1027
  var reactiveErrorFn = makeError("reactive");
862
1028
  var rawToProxyCache = /* @__PURE__ */ new WeakMap();
863
1029
  var proxyToRawCache = /* @__PURE__ */ new WeakMap();
1030
+ var shallowRawToProxyCache = /* @__PURE__ */ new WeakMap();
1031
+ var shallowProxyToRawCache = /* @__PURE__ */ new WeakMap();
864
1032
  /**
865
1033
  * 将响应式对象转换为原始对象
866
1034
  * @param value 响应式对象
@@ -876,6 +1044,7 @@ var proxyToRawCache = /* @__PURE__ */ new WeakMap();
876
1044
  */
877
1045
  function toRaw(value) {
878
1046
  if (proxyToRawCache.has(value)) return proxyToRawCache.get(value);
1047
+ if (shallowProxyToRawCache.has(value)) return shallowProxyToRawCache.get(value);
879
1048
  return value;
880
1049
  }
881
1050
  /**
@@ -892,18 +1061,24 @@ function toRaw(value) {
892
1061
  * ```
893
1062
  */
894
1063
  function isReactive(value) {
895
- return proxyToRawCache.has(value);
1064
+ return proxyToRawCache.has(value) || shallowProxyToRawCache.has(value);
1065
+ }
1066
+ var internalWriteDepth = 0;
1067
+ function isInternalWriting() {
1068
+ return internalWriteDepth > 0;
896
1069
  }
897
- var fromInternalWrite = false;
898
1070
  /**
899
1071
  * 内部写入,用于避免类型为只读的响应式对象写入报错
900
1072
  * @param fn 要执行的函数
901
1073
  * @internal
902
1074
  */
903
1075
  function internalWrite(fn) {
904
- fromInternalWrite = true;
905
- fn();
906
- fromInternalWrite = false;
1076
+ internalWriteDepth++;
1077
+ try {
1078
+ fn();
1079
+ } finally {
1080
+ internalWriteDepth--;
1081
+ }
907
1082
  }
908
1083
  var ObjectReactiveHandler = class {
909
1084
  isShallow;
@@ -913,32 +1088,44 @@ var ObjectReactiveHandler = class {
913
1088
  this.isShallow = config.shallow;
914
1089
  }
915
1090
  set(target, p, newValue, receiver) {
916
- if (this.isReadonly && !fromInternalWrite) throw reactiveErrorFn("Object is readonly!");
1091
+ if (this.isReadonly && !isInternalWriting()) throw reactiveErrorFn("Object is readonly!");
917
1092
  const rawValue = toRaw(newValue);
918
1093
  const oldValue = target[p];
919
1094
  const v = this.isShallow ? newValue : rawValue;
920
- if (oldValue === rawValue) return Reflect.set(target, p, v, receiver);
1095
+ if (Object.is(oldValue, rawValue)) return Reflect.set(target, p, v, receiver);
1096
+ const has = hasOwn(target, p);
921
1097
  const b = Reflect.set(target, p, v, receiver);
922
- fromInternalWrite = false;
923
- if (hasOwn(target, p)) trigger(target, TriggerOpTypes.Set, p);
924
- else trigger(target, TriggerOpTypes.Add, p);
1098
+ if (has) trigger(target, TriggerOpTypes.Set, p);
1099
+ else {
1100
+ trigger(target, TriggerOpTypes.Add, p);
1101
+ trigger(target, TriggerOpTypes.Iterate);
1102
+ }
925
1103
  return b;
926
1104
  }
927
1105
  get(target, p, receiver) {
928
1106
  track(target, TrackOpTypes.Get, p);
929
1107
  const value = Reflect.get(target, p, receiver);
930
- if (this.isShallow) return value;
1108
+ if (this.isShallow || !value || typeof value !== "object") return value;
931
1109
  return reactive(value);
932
1110
  }
933
1111
  deleteProperty(target, p) {
1112
+ if (this.isReadonly && !isInternalWriting()) throw reactiveErrorFn("Object is readonly!");
1113
+ const has = hasOwn(target, p);
934
1114
  const b = Reflect.deleteProperty(target, p);
935
- trigger(target, TriggerOpTypes.Delete, p);
1115
+ if (b && has) {
1116
+ trigger(target, TriggerOpTypes.Delete, p);
1117
+ trigger(target, TriggerOpTypes.Iterate);
1118
+ }
936
1119
  return b;
937
1120
  }
938
1121
  ownKeys(target) {
939
1122
  track(target, TrackOpTypes.Iterate);
940
1123
  return Reflect.ownKeys(target);
941
1124
  }
1125
+ has(target, p) {
1126
+ track(target, TrackOpTypes.Has, p);
1127
+ return Reflect.has(target, p);
1128
+ }
942
1129
  };
943
1130
  function noReactive(v) {
944
1131
  return v;
@@ -950,8 +1137,41 @@ var ArrayReactiveHandler = class extends ObjectReactiveHandler {
950
1137
  }
951
1138
  get(target, p, receiver) {
952
1139
  if (Reflect.has(this.interceptors, p) && p in target) return this.interceptors[p];
1140
+ if (p === "length") {
1141
+ track(target, TrackOpTypes.Iterate);
1142
+ return Reflect.get(target, p, receiver);
1143
+ }
953
1144
  return super.get(target, p, receiver);
954
1145
  }
1146
+ set(target, p, newValue, receiver) {
1147
+ if (this.isReadonly && !isInternalWriting()) throw reactiveErrorFn("Object is readonly!");
1148
+ if (p === "length") {
1149
+ const oldLength = target.length;
1150
+ const b = super.set(target, p, newValue, receiver);
1151
+ const newLength = target.length;
1152
+ if (newLength < oldLength) triggerArrayByRange(target, newLength, oldLength);
1153
+ if (oldLength !== newLength) trigger(target, TriggerOpTypes.Iterate);
1154
+ return b;
1155
+ }
1156
+ const rawValue = toRaw(newValue);
1157
+ const oldValue = target[p];
1158
+ const v = this.isShallow ? newValue : rawValue;
1159
+ if (Object.is(oldValue, rawValue)) return Reflect.set(target, p, v, receiver);
1160
+ const oldLength = target.length;
1161
+ const b = Reflect.set(target, p, v, receiver);
1162
+ const newLength = target.length;
1163
+ trigger(target, TriggerOpTypes.Set, p);
1164
+ trigger(target, TriggerOpTypes.Iterate);
1165
+ if (newLength > oldLength) trigger(target, TriggerOpTypes.Set, "length");
1166
+ return b;
1167
+ }
1168
+ deleteProperty(target, p) {
1169
+ if (this.isReadonly && !isInternalWriting()) throw reactiveErrorFn("Object is readonly!");
1170
+ const has = hasOwn(target, p);
1171
+ const b = Reflect.deleteProperty(target, p);
1172
+ if (b && has) trigger(target, TriggerOpTypes.Delete, p);
1173
+ return b;
1174
+ }
955
1175
  };
956
1176
  var MapReactiveHandler = class extends ObjectReactiveHandler {
957
1177
  interceptors = createMapHandlers(this.isShallow ? noReactive : reactive);
@@ -961,7 +1181,7 @@ var MapReactiveHandler = class extends ObjectReactiveHandler {
961
1181
  get(target, p, receiver) {
962
1182
  if (Reflect.has(this.interceptors, p) && p in target) return this.interceptors[p];
963
1183
  if (p === "size") {
964
- track(target, TrackOpTypes.Iterate, p);
1184
+ track(target, TrackOpTypes.Iterate);
965
1185
  return Reflect.get(target, p);
966
1186
  }
967
1187
  return super.get(target, p, receiver);
@@ -975,7 +1195,7 @@ var SetReactiveHandler = class extends ObjectReactiveHandler {
975
1195
  get(target, p, receiver) {
976
1196
  if (Reflect.has(this.interceptors, p) && p in target) return this.interceptors[p];
977
1197
  if (p === "size") {
978
- track(target, TrackOpTypes.Iterate, p);
1198
+ track(target, TrackOpTypes.Iterate);
979
1199
  return Reflect.get(target, p);
980
1200
  }
981
1201
  return super.get(target, p, receiver);
@@ -1051,29 +1271,10 @@ function reactive(raw) {
1051
1271
  }
1052
1272
  //#endregion
1053
1273
  //#region src/base/_utils.ts
1054
- function hasChange(newProps, oldProps) {
1055
- const newKeys = Object.keys(oldProps);
1056
- const oldKeys = Object.keys(newProps);
1057
- if (oldKeys.length !== newKeys.length) return true;
1058
- const len = oldKeys.length;
1059
- for (let i = 0; i < len; i++) {
1060
- const key = newKeys[i];
1061
- if (newProps[key] !== oldProps[key]) return true;
1062
- }
1063
- return false;
1064
- }
1065
1274
  function comparePropsWithCallbacks(oldProps, newProps, onDeleted, onAdded, onUpdated) {
1066
- const oldKeys = Object.keys(oldProps);
1067
- for (let i = 0; i < oldKeys.length; i++) {
1068
- const key = oldKeys[i];
1069
- if (!(key in newProps)) onDeleted(key, oldProps[key]);
1070
- }
1071
- const newKeys = Object.keys(newProps);
1072
- for (let i = 0; i < newKeys.length; i++) {
1073
- const key = newKeys[i];
1074
- if (!(key in oldProps)) onAdded(key, newProps[key]);
1075
- else if (oldProps[key] !== newProps[key]) onUpdated(key, newProps[key], oldProps[key]);
1076
- }
1275
+ for (const key in oldProps) if (!(key in newProps)) onDeleted(key, oldProps[key]);
1276
+ for (const key in newProps) if (!(key in oldProps)) onAdded(key, newProps[key]);
1277
+ else if (oldProps[key] !== newProps[key]) onUpdated(key, newProps[key], oldProps[key]);
1077
1278
  }
1078
1279
  function classToString(config) {
1079
1280
  if (typeof config === "string") return config;
@@ -1127,6 +1328,30 @@ var refErrorFn = makeError("Ref");
1127
1328
  * }
1128
1329
  * }
1129
1330
  * ```
1331
+ * @example
1332
+ * ```tsx
1333
+ * function Child() {
1334
+ * return {
1335
+ * show() {
1336
+ * console.log('show')
1337
+ * },
1338
+ * render() {
1339
+ * return <div>child</div>
1340
+ * }
1341
+ * }
1342
+ * }
1343
+ * function App() {
1344
+ * const ref = createDynamicRef<typeof Child>((child) => {
1345
+ * child.show()
1346
+ * return () => {
1347
+ * console.log('destroy')
1348
+ * }
1349
+ * })
1350
+ * return () => {
1351
+ * return <Child ref={ref}/>
1352
+ * }
1353
+ * }
1354
+ * ```
1130
1355
  */
1131
1356
  function createDynamicRef(effect) {
1132
1357
  return effect;
@@ -1147,6 +1372,28 @@ function createDynamicRef(effect) {
1147
1372
  * }
1148
1373
  * }
1149
1374
  * ```
1375
+ * @example
1376
+ * ```tsx
1377
+ * function Child() {
1378
+ * return {
1379
+ * show() {
1380
+ * console.log('show')
1381
+ * },
1382
+ * render() {
1383
+ * return <div>child</div>
1384
+ * }
1385
+ * }
1386
+ * }
1387
+ * function App() {
1388
+ * const ref = createRef<typeof Child>()
1389
+ * onMounted(() => {
1390
+ * ref.value?.show()
1391
+ * })
1392
+ * return () => {
1393
+ * return <Child ref={ref}/>
1394
+ * }
1395
+ * }
1396
+ * ```
1150
1397
  */
1151
1398
  function createRef() {
1152
1399
  return createShallowReadonlyProxy({ value: null });
@@ -1236,7 +1483,7 @@ var Component = class {
1236
1483
  this.refEffects = /* @__PURE__ */ new Map();
1237
1484
  this.listener = new Dep(() => {
1238
1485
  this.markAsDirtied();
1239
- });
1486
+ }, "sync");
1240
1487
  }
1241
1488
  markAsDirtied() {
1242
1489
  this._dirty = true;
@@ -1252,7 +1499,7 @@ var Component = class {
1252
1499
  componentSetupStack.push(this);
1253
1500
  const render = this.type(this.props);
1254
1501
  const isRenderFn = typeof render === "function";
1255
- this.instance = isRenderFn ? { $render: render } : render;
1502
+ this.instance = isRenderFn ? { render } : render;
1256
1503
  onMounted(() => {
1257
1504
  applyRefs(this.props.ref, this.instance, this.refEffects);
1258
1505
  return () => {
@@ -1263,15 +1510,16 @@ var Component = class {
1263
1510
  });
1264
1511
  componentSetupStack.pop();
1265
1512
  pushDepContext(this.listener);
1266
- const template = this.instance.$render();
1513
+ const template = this.instance.render();
1267
1514
  popDepContext();
1268
- update(template, this.instance.$portalHost);
1515
+ update(template);
1269
1516
  this.rendered();
1270
1517
  }
1271
1518
  updateProps(newProps) {
1272
1519
  const oldProps = this.rawProps;
1273
1520
  this.rawProps = newProps;
1274
1521
  const newRefs = newProps.ref;
1522
+ updateRefs(newRefs, this.instance, this.refEffects);
1275
1523
  comparePropsWithCallbacks(oldProps, newProps, (key) => {
1276
1524
  internalWrite(() => {
1277
1525
  Reflect.deleteProperty(oldProps, key);
@@ -1285,12 +1533,11 @@ var Component = class {
1285
1533
  this.props[key] = value;
1286
1534
  });
1287
1535
  });
1288
- updateRefs(newRefs, this.instance, this.refEffects);
1289
1536
  }
1290
1537
  rerender() {
1291
1538
  this.listener.destroy();
1292
1539
  pushDepContext(this.listener);
1293
- const template = this.instance.$render();
1540
+ const template = this.instance.render();
1294
1541
  popDepContext();
1295
1542
  return template;
1296
1543
  }
@@ -1373,6 +1620,18 @@ function registryComponentDestroyCallback(fn) {
1373
1620
  }
1374
1621
  }
1375
1622
  //#endregion
1623
+ //#region src/base/_render-context.ts
1624
+ var containerStack = [];
1625
+ function pushContainer(container) {
1626
+ containerStack.push(container);
1627
+ }
1628
+ function popContainer() {
1629
+ containerStack.pop();
1630
+ }
1631
+ function getContainer() {
1632
+ return containerStack[containerStack.length - 1];
1633
+ }
1634
+ //#endregion
1376
1635
  //#region src/base/jsx-element.ts
1377
1636
  function Fragment(props) {
1378
1637
  return () => {
@@ -1410,8 +1669,8 @@ function withMark(marks, setup) {
1410
1669
  if (typeof componentRenderFn === "function") return function() {
1411
1670
  return applyMark(marks, componentRenderFn);
1412
1671
  };
1413
- const oldRender = componentRenderFn.$render;
1414
- componentRenderFn.$render = function() {
1672
+ const oldRender = componentRenderFn.render;
1673
+ componentRenderFn.render = function() {
1415
1674
  return applyMark(marks, () => {
1416
1675
  return oldRender.call(componentRenderFn);
1417
1676
  });
@@ -1450,7 +1709,7 @@ function applyMark(mark, render) {
1450
1709
  * return () => {
1451
1710
  * return (
1452
1711
  * <div>
1453
- * <Portal host={modal}>
1712
+ * <Portal container={modal}>
1454
1713
  * 这里的内容将渲染到 modal 节点
1455
1714
  * </Portal>
1456
1715
  * </div>
@@ -1460,12 +1719,10 @@ function applyMark(mark, render) {
1460
1719
  * ```
1461
1720
  */
1462
1721
  function Portal(props) {
1463
- return {
1464
- $portalHost: props.host,
1465
- $render() {
1466
- return props.children;
1467
- }
1468
- };
1722
+ return { render() {
1723
+ pushContainer(props.container);
1724
+ return props.children;
1725
+ } };
1469
1726
  }
1470
1727
  //#endregion
1471
1728
  //#region src/reactive/watch-effect.ts
@@ -1478,12 +1735,18 @@ function Portal(props) {
1478
1735
  function watchEffect(effect) {
1479
1736
  const dep = new Dep(function() {
1480
1737
  pushDepContext(dep);
1738
+ try {
1739
+ effect();
1740
+ } finally {
1741
+ popDepContext();
1742
+ }
1743
+ }, "async");
1744
+ pushDepContext(dep);
1745
+ try {
1481
1746
  effect();
1747
+ } finally {
1482
1748
  popDepContext();
1483
- });
1484
- pushDepContext(dep);
1485
- effect();
1486
- popDepContext();
1749
+ }
1487
1750
  function unWatch() {
1488
1751
  dep.destroy();
1489
1752
  }
@@ -1508,7 +1771,7 @@ function watch(trigger, callback) {
1508
1771
  return;
1509
1772
  }
1510
1773
  const newValue = trigger();
1511
- if (newValue !== oldValue) {
1774
+ if (!Object.is(newValue, oldValue)) {
1512
1775
  callback(newValue, oldValue);
1513
1776
  oldValue = newValue;
1514
1777
  }
@@ -1673,7 +1936,7 @@ var listenerReg = /^on[A-Z]/;
1673
1936
  var nativeNodeRefRecord = /* @__PURE__ */ new WeakMap();
1674
1937
  function createRenderer(component, nativeRenderer, namespace) {
1675
1938
  let isInit = true;
1676
- return function render(host) {
1939
+ return function render(container) {
1677
1940
  if (isInit) {
1678
1941
  isInit = false;
1679
1942
  componentRender(nativeRenderer, component, {
@@ -1687,8 +1950,8 @@ function createRenderer(component, nativeRenderer, namespace) {
1687
1950
  namespace
1688
1951
  }, {
1689
1952
  isParent: true,
1690
- host,
1691
- rootHost: host
1953
+ anchorNode: container,
1954
+ rootContainer: container
1692
1955
  });
1693
1956
  } else deepUpdateByComponentDirtyTree(nativeRenderer, component, false);
1694
1957
  };
@@ -1710,23 +1973,40 @@ function buildElementChildren(atom, nativeRenderer, parentComponent, context) {
1710
1973
  }
1711
1974
  }
1712
1975
  function patchComponent(nativeRenderer, component, oldChildAtom, newAtom, context, needMove) {
1713
- newAtom.child = createChildChain(component.rerender(), nativeRenderer, newAtom.namespace);
1976
+ const oldContainer = component.viewMetadata.anchorNode;
1977
+ const expectContainer = component.viewMetadata.expectContainer;
1978
+ const newTemplate = component.rerender();
1979
+ const portalContainer = getContainer();
1980
+ popContainer();
1981
+ if (portalContainer && portalContainer !== expectContainer) context = {
1982
+ isParent: true,
1983
+ anchorNode: portalContainer,
1984
+ rootContainer: portalContainer
1985
+ };
1986
+ component.viewMetadata = {
1987
+ atom: newAtom,
1988
+ expectContainer,
1989
+ ...context
1990
+ };
1991
+ if (oldContainer !== context.anchorNode) needMove = true;
1992
+ newAtom.child = createChildChain(newTemplate, nativeRenderer, newAtom.namespace);
1714
1993
  diff(nativeRenderer, component, newAtom.child, oldChildAtom, context, needMove);
1994
+ return context;
1715
1995
  }
1716
1996
  function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
1717
1997
  if (component.dirty) {
1718
- const { atom, host, isParent, rootHost } = component.viewMetadata;
1998
+ const { atom, anchorNode, isParent, rootContainer } = component.viewMetadata;
1719
1999
  const context = {
1720
- host,
2000
+ anchorNode,
1721
2001
  isParent,
1722
- rootHost
2002
+ rootContainer
1723
2003
  };
1724
2004
  const diffAtom = atom.child;
1725
2005
  patchComponent(nativeRenderer, component, diffAtom, atom, context, needMove);
1726
2006
  const next = atom.sibling;
1727
2007
  if (next && next.jsxNode instanceof Component) {
1728
2008
  const view = next.jsxNode.viewMetadata;
1729
- view.host = context.host;
2009
+ view.anchorNode = context.anchorNode;
1730
2010
  view.isParent = context.isParent;
1731
2011
  }
1732
2012
  component.rendered();
@@ -1737,85 +2017,24 @@ function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
1737
2017
  component.rendered();
1738
2018
  }
1739
2019
  }
1740
- function createOldAtomMatcher(oldAtoms) {
1741
- const typeMap = /* @__PURE__ */ new Map();
1742
- const cursorMap = /* @__PURE__ */ new WeakMap();
1743
- for (let i = 0; i < oldAtoms.length; i++) {
1744
- const atom = oldAtoms[i];
1745
- let nodeTypeMap = typeMap.get(atom.type);
1746
- if (!nodeTypeMap) {
1747
- nodeTypeMap = /* @__PURE__ */ new Map();
1748
- typeMap.set(atom.type, nodeTypeMap);
1749
- }
1750
- let keyMap = nodeTypeMap.get(atom.nodeType);
1751
- if (!keyMap) {
1752
- keyMap = /* @__PURE__ */ new Map();
1753
- nodeTypeMap.set(atom.nodeType, keyMap);
1754
- }
1755
- const key = atom.key;
1756
- const indices = keyMap.get(key);
1757
- if (indices) indices.push(i);
1758
- else keyMap.set(key, [i]);
1759
- }
1760
- const take = (atom, matched) => {
1761
- const nodeTypeMap = typeMap.get(atom.type);
1762
- if (!nodeTypeMap) return -1;
1763
- const keyMap = nodeTypeMap.get(atom.nodeType);
1764
- if (!keyMap) return -1;
1765
- const indices = keyMap.get(atom.key);
1766
- if (!indices || !indices.length) return -1;
1767
- let cursor = cursorMap.get(indices) ?? 0;
1768
- while (cursor < indices.length) {
1769
- const index = indices[cursor];
1770
- cursor++;
1771
- if (!matched[index]) {
1772
- cursorMap.set(indices, cursor);
1773
- return index;
1774
- }
1775
- }
1776
- cursorMap.set(indices, cursor);
1777
- return -1;
1778
- };
1779
- return { take };
1780
- }
1781
2020
  function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
1782
2021
  const commits = [];
1783
- const oldAtoms = [];
2022
+ while (newAtom) {
2023
+ oldAtom = createChanges(newAtom, oldAtom, commits);
2024
+ newAtom = newAtom.sibling;
2025
+ }
1784
2026
  let dirtyDiffAtom = oldAtom;
1785
2027
  while (dirtyDiffAtom) {
1786
- oldAtoms.push(dirtyDiffAtom);
2028
+ cleanView(nativeRenderer, dirtyDiffAtom, true);
1787
2029
  dirtyDiffAtom = dirtyDiffAtom.sibling;
1788
2030
  }
1789
- const matched = new Array(oldAtoms.length).fill(false);
1790
- const matcher = createOldAtomMatcher(oldAtoms);
1791
- const pendingDeleteIndices = [];
1792
- let cursor = newAtom;
1793
- while (cursor) {
1794
- const matchedIndex = matcher.take(cursor, matched);
1795
- if (matchedIndex >= 0) {
1796
- matched[matchedIndex] = true;
1797
- commits.push({
1798
- dirtyAtom: oldAtoms[matchedIndex],
1799
- newAtom: cursor
1800
- });
1801
- } else commits.push({
1802
- dirtyAtom: null,
1803
- newAtom: cursor
1804
- });
1805
- cursor = cursor.sibling;
1806
- }
1807
- for (let i = 0; i < oldAtoms.length; i++) if (!matched[i]) {
1808
- pendingDeleteIndices.push(i);
1809
- cleanView(nativeRenderer, oldAtoms[i], true);
1810
- }
1811
2031
  let offset = 0;
1812
- let pendingDeleteCursor = 0;
1813
2032
  const len = commits.length;
1814
2033
  for (let i = 0; i < len; i++) {
1815
- while (pendingDeleteCursor < pendingDeleteIndices.length) {
1816
- if (oldAtoms[pendingDeleteIndices[pendingDeleteCursor]].index <= i) {
2034
+ while (oldAtom) {
2035
+ if (oldAtom.index <= i) {
1817
2036
  offset--;
1818
- pendingDeleteCursor++;
2037
+ oldAtom = oldAtom.sibling;
1819
2038
  continue;
1820
2039
  }
1821
2040
  break;
@@ -1838,51 +2057,68 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMo
1838
2057
  }
1839
2058
  }
1840
2059
  }
2060
+ function createChanges(newAtom, oldAtom, commits) {
2061
+ const startDiffAtom = oldAtom;
2062
+ let prev = null;
2063
+ while (oldAtom) {
2064
+ if (oldAtom.type === newAtom.type && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
2065
+ commits.push({
2066
+ dirtyAtom: oldAtom,
2067
+ newAtom
2068
+ });
2069
+ const next = oldAtom.sibling;
2070
+ if (!prev) return next;
2071
+ prev.sibling = next;
2072
+ return startDiffAtom;
2073
+ }
2074
+ prev = oldAtom;
2075
+ oldAtom = oldAtom.sibling;
2076
+ }
2077
+ commits.push({
2078
+ dirtyAtom: null,
2079
+ newAtom
2080
+ });
2081
+ return startDiffAtom;
2082
+ }
1841
2083
  function updateText(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
1842
2084
  const nativeNode = oldAtom.nativeNode;
1843
2085
  newAtom.nativeNode = nativeNode;
1844
2086
  if (needMove || newAtom.index - offset !== oldAtom.index) insertNode(nativeRenderer, newAtom, context);
1845
- context.host = nativeNode;
2087
+ context.anchorNode = nativeNode;
1846
2088
  context.isParent = false;
1847
2089
  }
1848
2090
  function updateElement(nativeRenderer, context, parentComponent, offset, needMove, newAtom, oldAtom) {
1849
2091
  const nativeNode = oldAtom.nativeNode;
1850
2092
  newAtom.nativeNode = nativeNode;
1851
2093
  if (needMove || newAtom.index - offset !== oldAtom.index) insertNode(nativeRenderer, newAtom, context);
1852
- context.host = nativeNode;
2094
+ context.anchorNode = nativeNode;
1853
2095
  context.isParent = false;
1854
2096
  updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, {
1855
- host: nativeNode,
2097
+ anchorNode: nativeNode,
1856
2098
  isParent: true,
1857
- rootHost: context.rootHost
2099
+ rootContainer: context.rootContainer
1858
2100
  });
1859
2101
  }
1860
2102
  function updateComponent(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
1861
2103
  const component = oldAtom.jsxNode;
1862
- const portalHost = component.instance.$portalHost;
1863
- context = portalHost ? {
1864
- isParent: true,
1865
- host: portalHost,
1866
- rootHost: portalHost
1867
- } : context;
1868
- component.viewMetadata = {
1869
- atom: newAtom,
1870
- ...context
1871
- };
1872
2104
  const newProps = newAtom.jsxNode.props;
1873
2105
  newAtom.jsxNode = component;
1874
2106
  needMove = needMove || newAtom.index - offset !== oldAtom.index;
1875
- const propsIsChanged = hasChange(newProps, component.props);
1876
- if (propsIsChanged) component.updateProps(newProps);
1877
- if (propsIsChanged || component.dirty) {
1878
- patchComponent(nativeRenderer, component, oldAtom.child, newAtom, context, needMove);
2107
+ component.updateProps(newProps);
2108
+ if (component.dirty) {
2109
+ const updatedContext = patchComponent(nativeRenderer, component, oldAtom.child, newAtom, context, needMove);
1879
2110
  const next = oldAtom.sibling;
1880
2111
  if (next && next.jsxNode instanceof Component) {
1881
2112
  const view = next.jsxNode.viewMetadata;
1882
- view.host = context.host;
1883
- view.isParent = context.isParent;
2113
+ view.anchorNode = updatedContext.anchorNode;
2114
+ view.isParent = updatedContext.isParent;
1884
2115
  }
1885
2116
  } else {
2117
+ component.viewMetadata = {
2118
+ atom: newAtom,
2119
+ expectContainer: component.viewMetadata.expectContainer,
2120
+ ...context
2121
+ };
1886
2122
  newAtom.child = oldAtom.child;
1887
2123
  reuseComponentView(nativeRenderer, newAtom.child, context, needMove, !component.changedSubComponents.size);
1888
2124
  }
@@ -1898,7 +2134,7 @@ function reuseComponentView(nativeRenderer, child, context, moveView, skipSubCom
1898
2134
  if (moveView) insertNode(nativeRenderer, atom, context);
1899
2135
  if (!skipSubComponentDiff) reuseElementChildrenView(nativeRenderer, atom, context);
1900
2136
  context.isParent = false;
1901
- context.host = atom.nativeNode;
2137
+ context.anchorNode = atom.nativeNode;
1902
2138
  }
1903
2139
  };
1904
2140
  while (child) {
@@ -1925,7 +2161,7 @@ function cleanElementChildren(atom, nativeRenderer) {
1925
2161
  function cleanView(nativeRenderer, atom, needClean) {
1926
2162
  if (atom.type === ComponentAtomType) {
1927
2163
  const jsxNode = atom.jsxNode;
1928
- if (jsxNode.instance.$portalHost) needClean = true;
2164
+ if (jsxNode.viewMetadata.anchorNode !== jsxNode.viewMetadata.expectContainer) needClean = true;
1929
2165
  cleanChildren(atom, nativeRenderer, needClean);
1930
2166
  jsxNode.destroy();
1931
2167
  return;
@@ -1953,15 +2189,19 @@ function cleanChildren(atom, nativeRenderer, needClean) {
1953
2189
  }
1954
2190
  }
1955
2191
  function componentRender(nativeRenderer, component, from, context) {
1956
- component.render((template, portalHost) => {
2192
+ component.render((template) => {
2193
+ const portalContainer = getContainer();
2194
+ popContainer();
1957
2195
  from.child = createChildChain(template, nativeRenderer, from.namespace);
1958
- context = portalHost ? {
2196
+ const expectContainer = context.anchorNode;
2197
+ context = portalContainer && portalContainer !== context.anchorNode ? {
1959
2198
  isParent: true,
1960
- host: portalHost,
1961
- rootHost: portalHost
2199
+ anchorNode: portalContainer,
2200
+ rootContainer: portalContainer
1962
2201
  } : context;
1963
2202
  component.viewMetadata = {
1964
2203
  atom: from,
2204
+ expectContainer,
1965
2205
  ...context
1966
2206
  };
1967
2207
  let child = from.child;
@@ -2018,9 +2258,9 @@ function createChildChain(template, nativeRenderer, namespace) {
2018
2258
  return beforeAtom.sibling;
2019
2259
  }
2020
2260
  function insertNode(nativeRenderer, atom, context) {
2021
- if (context.isParent) if (context.host === context.rootHost) nativeRenderer.appendChild(context.host, atom.nativeNode, atom.namespace);
2022
- else nativeRenderer.prependChild(context.host, atom.nativeNode, atom.namespace);
2023
- else nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.namespace);
2261
+ if (context.isParent) if (context.anchorNode === context.rootContainer) nativeRenderer.appendChild(context.anchorNode, atom.nativeNode, atom.namespace);
2262
+ else nativeRenderer.prependChild(context.anchorNode, atom.nativeNode, atom.namespace);
2263
+ else nativeRenderer.insertAfter(atom.nativeNode, context.anchorNode, atom.namespace);
2024
2264
  }
2025
2265
  function createElementChildren(type, children, nativeRenderer, namespace) {
2026
2266
  return createChildChain(children, nativeRenderer, nativeRenderer.getNameSpace(type, namespace));
@@ -2030,10 +2270,7 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
2030
2270
  const nativeNode = nativeRenderer.createElement(jsxNode.type, namespace);
2031
2271
  const props = jsxNode.props;
2032
2272
  let bindingRefs;
2033
- const propKeys = Object.keys(props);
2034
- const propKeyLen = propKeys.length;
2035
- for (let i = 0; i < propKeyLen; i++) {
2036
- const key = propKeys[i];
2273
+ for (const key in props) {
2037
2274
  if (key === "children") {
2038
2275
  atom.child = createElementChildren(jsxNode.type, props.children, nativeRenderer, namespace);
2039
2276
  continue;
@@ -2063,10 +2300,10 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
2063
2300
  insertNode(nativeRenderer, atom, context);
2064
2301
  buildElementChildren(atom, nativeRenderer, parentComponent, {
2065
2302
  isParent: true,
2066
- host: nativeNode,
2067
- rootHost: context.rootHost
2303
+ anchorNode: nativeNode,
2304
+ rootContainer: context.rootContainer
2068
2305
  });
2069
- context.host = nativeNode;
2306
+ context.anchorNode = nativeNode;
2070
2307
  context.isParent = false;
2071
2308
  if (bindingRefs) {
2072
2309
  const refEffects = /* @__PURE__ */ new Map();
@@ -2078,7 +2315,7 @@ function createTextNode(nativeRenderer, atom, context) {
2078
2315
  const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.namespace);
2079
2316
  atom.nativeNode = nativeNode;
2080
2317
  insertNode(nativeRenderer, atom, context);
2081
- context.host = nativeNode;
2318
+ context.anchorNode = nativeNode;
2082
2319
  context.isParent = false;
2083
2320
  }
2084
2321
  function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context) {
@@ -2087,6 +2324,11 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
2087
2324
  const nativeNode = newAtom.nativeNode;
2088
2325
  const oldVNode = oldAtom.jsxNode;
2089
2326
  if (newVNode === oldVNode) {
2327
+ const refEffects = nativeNodeRefRecord.get(oldAtom);
2328
+ if (refEffects) {
2329
+ nativeNodeRefRecord.delete(oldAtom);
2330
+ nativeNodeRefRecord.set(newAtom, refEffects);
2331
+ }
2090
2332
  newAtom.child = oldAtom.child;
2091
2333
  reuseElementChildrenView(nativeRenderer, newAtom, context);
2092
2334
  return;
@@ -2094,17 +2336,6 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
2094
2336
  let unBindRefs;
2095
2337
  let bindRefs;
2096
2338
  let updatedChildren = false;
2097
- const styleCache = /* @__PURE__ */ new WeakMap();
2098
- const toStyleObject = (style) => {
2099
- if (style && typeof style === "object") {
2100
- const cached = styleCache.get(style);
2101
- if (cached) return cached;
2102
- const normalized = styleToObject(style);
2103
- styleCache.set(style, normalized);
2104
- return normalized;
2105
- }
2106
- return styleToObject(style);
2107
- };
2108
2339
  comparePropsWithCallbacks(oldVNode.props, newVNode.props, (key, oldValue) => {
2109
2340
  if (key === "children") {
2110
2341
  updatedChildren = true;
@@ -2116,12 +2347,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
2116
2347
  return;
2117
2348
  }
2118
2349
  if (key === "style") {
2119
- const oldStyle = toStyleObject(oldValue);
2120
- const styleNames = Object.keys(oldStyle);
2121
- for (let i = 0; i < styleNames.length; i++) {
2122
- const styleName = styleNames[i];
2123
- nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
2124
- }
2350
+ for (const styleName in styleToObject(oldValue)) nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
2125
2351
  return;
2126
2352
  }
2127
2353
  if (listenerReg.test(key)) {
@@ -2145,12 +2371,8 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
2145
2371
  return;
2146
2372
  }
2147
2373
  if (key === "style") {
2148
- const styleObj = toStyleObject(value);
2149
- const styleNames = Object.keys(styleObj);
2150
- for (let i = 0; i < styleNames.length; i++) {
2151
- const styleName = styleNames[i];
2152
- nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
2153
- }
2374
+ const styleObj = styleToObject(value);
2375
+ for (const styleName in styleObj) nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
2154
2376
  return;
2155
2377
  }
2156
2378
  if (listenerReg.test(key)) {
@@ -2178,7 +2400,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
2178
2400
  return;
2179
2401
  }
2180
2402
  if (key === "style") {
2181
- comparePropsWithCallbacks(toStyleObject(oldValue), toStyleObject(newValue), (styleName) => {
2403
+ comparePropsWithCallbacks(styleToObject(oldValue), styleToObject(newValue), (styleName) => {
2182
2404
  nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
2183
2405
  }, (styleName, styleValue) => {
2184
2406
  nativeRenderer.setStyle(nativeNode, styleName, styleValue, isSvg);
@@ -2237,7 +2459,7 @@ function viewfly(config) {
2237
2459
  const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
2238
2460
  const modules = [];
2239
2461
  let destroyed = false;
2240
- let appHost = null;
2462
+ let appContainer = null;
2241
2463
  const rootProviders = [];
2242
2464
  const rootComponent = new RootComponent(() => {
2243
2465
  const rootContext = createContext(rootProviders, null, context);
@@ -2247,7 +2469,7 @@ function viewfly(config) {
2247
2469
  }, function() {
2248
2470
  if (destroyed || !autoUpdate) return;
2249
2471
  nextTick(() => {
2250
- render(appHost);
2472
+ render(appContainer);
2251
2473
  });
2252
2474
  });
2253
2475
  const render = createRenderer(rootComponent, nativeRenderer, config.elementNamespace);
@@ -2271,18 +2493,22 @@ function viewfly(config) {
2271
2493
  else modules.push(module);
2272
2494
  return app;
2273
2495
  },
2274
- mount(host) {
2496
+ mount(container) {
2275
2497
  if (isStarted) throw viewflyErrorFn("application has already started.");
2276
2498
  for (const module of modules) module.setup?.(app);
2277
2499
  isStarted = true;
2278
- appHost = host;
2279
- render(host);
2500
+ appContainer = container;
2501
+ render(container);
2280
2502
  for (const module of modules) module.onAfterStartup?.(app);
2281
2503
  if (!autoUpdate) return app;
2282
2504
  return app;
2283
2505
  },
2284
2506
  render() {
2285
- if (appHost) render(appHost);
2507
+ if (appContainer) {
2508
+ flushReactiveEffectsSync();
2509
+ render(appContainer);
2510
+ flushReactiveEffectsSync();
2511
+ }
2286
2512
  return app;
2287
2513
  },
2288
2514
  destroy() {
@@ -2303,13 +2529,31 @@ function viewfly(config) {
2303
2529
  * @returns 一个对象,对象的 value 属性是计算的值
2304
2530
  */
2305
2531
  function computed(getter) {
2306
- const proxy = new Proxy({ value: null }, readonlyProxyHandler);
2307
- watchEffect(() => {
2308
- internalWrite(() => {
2309
- proxy.value = getter();
2310
- });
2532
+ let cacheValue;
2533
+ let dirty = true;
2534
+ const target = { get value() {
2535
+ if (dirty) {
2536
+ dep.destroy();
2537
+ pushDepContext(dep);
2538
+ try {
2539
+ cacheValue = getter();
2540
+ dirty = false;
2541
+ } finally {
2542
+ popDepContext();
2543
+ }
2544
+ }
2545
+ return cacheValue;
2546
+ } };
2547
+ const dep = new Dep(() => {
2548
+ if (!dirty) {
2549
+ dirty = true;
2550
+ trigger(target, TriggerOpTypes.Set, "value");
2551
+ }
2552
+ }, "sync");
2553
+ registryComponentDestroyCallback(() => {
2554
+ dep.destroy();
2311
2555
  });
2312
- return proxy;
2556
+ return new Proxy(target, readonlyProxyHandler);
2313
2557
  }
2314
2558
  //#endregion
2315
2559
  //#region src/reactive/shallow-reactive.ts
@@ -2331,7 +2575,7 @@ var defaultShallowSetReactiveHandler = new SetReactiveHandler({
2331
2575
  });
2332
2576
  function shallowReactive(raw) {
2333
2577
  if (isReactive(raw)) return raw;
2334
- let proxy = rawToProxyCache.get(raw);
2578
+ let proxy = shallowRawToProxyCache.get(raw);
2335
2579
  if (proxy) return proxy;
2336
2580
  switch (getStringType(raw)) {
2337
2581
  case "[object Object]":
@@ -2350,8 +2594,8 @@ function shallowReactive(raw) {
2350
2594
  break;
2351
2595
  default: return raw;
2352
2596
  }
2353
- rawToProxyCache.set(raw, proxy);
2354
- proxyToRawCache.set(proxy, raw);
2597
+ shallowRawToProxyCache.set(raw, proxy);
2598
+ shallowProxyToRawCache.set(proxy, raw);
2355
2599
  return proxy;
2356
2600
  }
2357
2601
  //#endregion
@@ -2390,4 +2634,4 @@ function createSignal(state) {
2390
2634
  return signal;
2391
2635
  }
2392
2636
  //#endregion
2393
- export { ArrayReactiveHandler, Component, Dep, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXNodeFactory, MapReactiveHandler, NativeRenderer, NullInjector, ObjectReactiveHandler, Optional, Portal, Prop, ReflectiveInjector, RootComponent, Scope, Self, SetReactiveHandler, SkipSelf, THROW_IF_NOT_FOUND, TrackOpTypes, TriggerOpTypes, Type, applyMark, applyRefs, comparePropsWithCallbacks, computed, createContext, createContextProvider, createDynamicRef, createRef, createRenderer, createShallowReadonlyProxy, createSignal, defaultArrayReactiveHandler, defaultMapReactiveHandler, defaultObjectReactiveHandler, defaultSetReactiveHandler, defaultShallowArrayReactiveHandler, defaultShallowMapReactiveHandler, defaultShallowObjectReactiveHandler, defaultShallowSetReactiveHandler, forwardRef, getCurrentInstance, getDepContext, getSetupContext, inject, internalWrite, isReactive, jsx, jsxs, makeError, normalizeProvider, onMounted, onUnmounted, onUpdated, popDepContext, proxyToRawCache, pushDepContext, rawToProxyCache, reactive, readonlyProxyHandler, registryComponentDestroyCallback, shallowReactive, toRaw, track, trigger, updateRefs, viewfly, watch, watchEffect, withAnnotation, withMark };
2637
+ export { ArrayReactiveHandler, Component, Dep, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXNodeFactory, MapReactiveHandler, NativeRenderer, NullInjector, ObjectReactiveHandler, Optional, Portal, Prop, ReflectiveInjector, RootComponent, Scope, Self, SetReactiveHandler, SkipSelf, THROW_IF_NOT_FOUND, TrackOpTypes, TriggerOpTypes, Type, applyMark, applyRefs, comparePropsWithCallbacks, computed, createContext, createContextProvider, createDynamicRef, createRef, createRenderer, createShallowReadonlyProxy, createSignal, defaultArrayReactiveHandler, defaultMapReactiveHandler, defaultObjectReactiveHandler, defaultSetReactiveHandler, defaultShallowArrayReactiveHandler, defaultShallowMapReactiveHandler, defaultShallowObjectReactiveHandler, defaultShallowSetReactiveHandler, flushReactiveEffectsSync, forwardRef, getCurrentInstance, getDepContext, getSetupContext, inject, internalWrite, isReactive, jsx, jsxs, makeError, nextTick, normalizeProvider, onMounted, onUnmounted, onUpdated, popDepContext, proxyToRawCache, pushDepContext, rawToProxyCache, reactive, readonlyProxyHandler, registryComponentDestroyCallback, shallowProxyToRawCache, shallowRawToProxyCache, shallowReactive, toRaw, track, trigger, updateRefs, viewfly, watch, watchEffect, withAnnotation, withMark };