@viewfly/core 0.0.28 → 0.0.30

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.
@@ -567,6 +567,23 @@ function getObjectChanges(newProps, oldProps) {
567
567
  });
568
568
  return changes;
569
569
  }
570
+ function getArrayChanges(left, right) {
571
+ const changes = {
572
+ add: [],
573
+ remove: []
574
+ };
575
+ for (const i of left) {
576
+ if (!right.includes(i)) {
577
+ changes.remove.push(i);
578
+ }
579
+ }
580
+ for (const i of right) {
581
+ if (!left.includes(i)) {
582
+ changes.add.push(i);
583
+ }
584
+ }
585
+ return changes;
586
+ }
570
587
  function classToString(config) {
571
588
  if (!config) {
572
589
  return '';
@@ -626,15 +643,6 @@ function getSetupContext(need = true) {
626
643
  function getSignalDepsContext() {
627
644
  return signalDepsStack[signalDepsStack.length - 1];
628
645
  }
629
- class JSXComponent {
630
- constructor(props, factory) {
631
- this.props = props;
632
- this.factory = factory;
633
- }
634
- createInstance(injector) {
635
- return this.factory(injector, this.props);
636
- }
637
- }
638
646
  /**
639
647
  * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
640
648
  */
@@ -645,11 +653,12 @@ class Component extends ReflectiveInjector {
645
653
  get changed() {
646
654
  return this._changed;
647
655
  }
648
- constructor(context, type, props, key) {
649
- super(context, [{
656
+ constructor(parentComponent, type, props, key) {
657
+ super(parentComponent, [{
650
658
  provide: Injector,
651
659
  useFactory: () => this
652
660
  }]);
661
+ this.parentComponent = parentComponent;
653
662
  this.type = type;
654
663
  this.props = props;
655
664
  this.key = key;
@@ -664,22 +673,29 @@ class Component extends ReflectiveInjector {
664
673
  this.updatedDestroyCallbacks = [];
665
674
  this.propsChangedDestroyCallbacks = [];
666
675
  this.isFirstRending = true;
667
- this.parentComponent = this.parentInjector;
668
676
  }
669
- is(target) {
670
- return target.$$typeOf === this.$$typeOf;
677
+ markAsDirtied() {
678
+ this._dirty = true;
679
+ this.markAsChanged();
671
680
  }
672
- provide(providers) {
673
- providers = Array.isArray(providers) ? providers : [providers];
674
- this.normalizedProviders.unshift(...providers.map(i => normalizeProvider(i)));
681
+ markAsChanged(changedComponent) {
682
+ if (changedComponent) {
683
+ this.changedSubComponents.add(changedComponent);
684
+ }
685
+ if (this._changed) {
686
+ return;
687
+ }
688
+ this._changed = true;
689
+ if (this.parentComponent instanceof Component) {
690
+ this.parentComponent.markAsChanged(this);
691
+ }
675
692
  }
676
- setup() {
693
+ render() {
677
694
  const self = this;
678
- const props = new Proxy(this.props, {
695
+ const proxiesProps = new Proxy(this.props, {
679
696
  get(_, key) {
680
- if (self.props) {
681
- return self.props[key];
682
- }
697
+ // 必须用 self,因为 props 会随着页面更新变更,使用 self 才能更新引用
698
+ return self.props[key];
683
699
  },
684
700
  set() {
685
701
  // 防止因外部捕获异常引引起的缓存未清理的问题
@@ -691,78 +707,66 @@ class Component extends ReflectiveInjector {
691
707
  });
692
708
  componentSetupStack.push(this);
693
709
  let isSetup = true;
694
- const render = this.type(props);
710
+ const render = this.type(proxiesProps);
695
711
  const isRenderFn = typeof render === 'function';
696
- const componentInstance = isRenderFn ? { $render: render } : render;
697
- let refs = toRefs(this.props.ref);
698
- onMounted(() => {
699
- for (const ref of refs) {
700
- ref.bind(componentInstance);
712
+ this.instance = isRenderFn ? { $render: render } : render;
713
+ this.refs = toRefs(this.props.ref);
714
+ this.mountCallbacks.push(() => {
715
+ for (const ref of this.refs) {
716
+ ref.bind(this.instance);
701
717
  }
702
718
  });
703
- onDestroy(() => {
704
- for (const ref of refs) {
705
- ref.unBind(componentInstance);
719
+ this.destroyCallbacks.push(() => {
720
+ for (const ref of this.refs) {
721
+ ref.unBind(this.instance);
706
722
  }
707
723
  });
708
724
  isSetup = false;
709
725
  componentSetupStack.pop();
710
726
  signalDepsStack.push([]);
711
- let template = componentInstance.$render();
727
+ let template = this.instance.$render();
712
728
  const deps = signalDepsStack.pop();
713
- this.unWatch = useEffect(deps, () => {
729
+ this.unWatch = useEffect(Array.from(new Set(deps)), () => {
714
730
  this.markAsDirtied();
715
731
  });
716
- return {
717
- template,
718
- render: (newProps, oldProps) => {
719
- if (newProps !== oldProps) {
720
- const { add, remove, replace } = getObjectChanges(newProps, oldProps);
721
- if (add.length || remove.length || replace.length) {
722
- this.invokePropsChangedHooks(newProps);
723
- }
724
- const newRefs = toRefs(newProps.ref);
725
- for (const oldRef of refs) {
726
- if (!newRefs.includes(oldRef)) {
727
- oldRef.unBind(componentInstance);
728
- }
729
- }
730
- for (const newRef of newRefs) {
731
- if (!refs.includes(newRef)) {
732
- newRef.bind(componentInstance);
733
- }
734
- }
735
- refs = newRefs;
736
- }
737
- if (typeof componentInstance.$shouldUpdate === 'function') {
738
- if (!componentInstance.$shouldUpdate(newProps, oldProps)) {
739
- return template;
740
- }
741
- }
742
- this.unWatch();
743
- signalDepsStack.push([]);
744
- template = componentInstance.$render();
745
- const deps = signalDepsStack.pop();
746
- this.unWatch = useEffect(deps, () => {
747
- this.markAsDirtied();
748
- });
749
- return template;
750
- }
751
- };
732
+ this.template = template;
733
+ return template;
752
734
  }
753
- markAsDirtied() {
754
- this._dirty = true;
755
- this.markAsChanged();
756
- }
757
- markAsChanged(changedComponent) {
758
- if (changedComponent) {
759
- this.changedSubComponents.add(changedComponent);
735
+ update(newProps, forceUpdate = false) {
736
+ const oldProps = this.props;
737
+ const { add, remove, replace } = getObjectChanges(newProps, this.props);
738
+ if (add.length || remove.length || replace.length) {
739
+ this.invokePropsChangedHooks(newProps);
740
+ }
741
+ const newRefs = toRefs(newProps.ref);
742
+ for (const oldRef of this.refs) {
743
+ if (!newRefs.includes(oldRef)) {
744
+ oldRef.unBind(this.instance);
745
+ }
760
746
  }
761
- if (this._changed) {
762
- return;
747
+ for (const newRef of newRefs) {
748
+ if (!this.refs.includes(newRef)) {
749
+ newRef.bind(this.instance);
750
+ }
763
751
  }
764
- this._changed = true;
765
- this.parentComponent.markAsChanged(this);
752
+ this.refs = newRefs;
753
+ if (!forceUpdate && typeof this.instance.$useMemo === 'function') {
754
+ if (this.instance.$useMemo(newProps, oldProps)) {
755
+ return this.template;
756
+ }
757
+ }
758
+ this.unWatch();
759
+ signalDepsStack.push([]);
760
+ this.template = this.instance.$render();
761
+ const deps = signalDepsStack.pop();
762
+ this.unWatch = useEffect(Array.from(new Set(deps)), () => {
763
+ this.markAsDirtied();
764
+ });
765
+ return this.template;
766
+ }
767
+ provide(providers) {
768
+ providers = Array.isArray(providers) ? providers : [providers];
769
+ this.normalizedProviders.unshift(...providers.map(i => normalizeProvider(i)));
766
770
  }
767
771
  rendered() {
768
772
  this.changedSubComponents.clear();
@@ -1016,10 +1020,48 @@ function invokeDepFn(fn) {
1016
1020
  const data = fn();
1017
1021
  signalDepsStack.pop();
1018
1022
  return {
1019
- deps,
1023
+ deps: Array.from(new Set(deps)),
1020
1024
  data
1021
1025
  };
1022
1026
  }
1027
+ function listen(model, deps, callback, isContinue) {
1028
+ let isStop = false;
1029
+ const nextListen = () => {
1030
+ if (isStop) {
1031
+ return;
1032
+ }
1033
+ isStop = true;
1034
+ const { data: nextData, deps: nextDeps } = invokeDepFn(callback);
1035
+ model.set(nextData);
1036
+ if (typeof isContinue === 'function' && isContinue(nextData) === false) {
1037
+ unListen();
1038
+ return;
1039
+ }
1040
+ const changes = getArrayChanges(deps, nextDeps);
1041
+ deps = deps.filter(i => {
1042
+ const has = changes.remove.includes(i);
1043
+ if (has) {
1044
+ i[depsKey].delete(nextListen);
1045
+ return false;
1046
+ }
1047
+ return true;
1048
+ });
1049
+ for (const s of changes.add) {
1050
+ s[depsKey].add(nextListen);
1051
+ }
1052
+ deps.push(...changes.add);
1053
+ isStop = false;
1054
+ };
1055
+ const unListen = () => {
1056
+ for (const s of deps) {
1057
+ s[depsKey].delete(nextListen);
1058
+ }
1059
+ };
1060
+ for (const s of deps) {
1061
+ s[depsKey].add(nextListen);
1062
+ }
1063
+ return unListen;
1064
+ }
1023
1065
  /**
1024
1066
  * 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
1025
1067
  * 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
@@ -1031,29 +1073,10 @@ function useDerived(callback, isContinue) {
1031
1073
  let { data, deps } = invokeDepFn(callback);
1032
1074
  const signal = useSignal(data);
1033
1075
  const component = getSetupContext(false);
1034
- const unListenRef = {};
1035
- function listen(model, deps, callback, unListenRef, isContinue) {
1036
- const nextListen = () => {
1037
- unListenRef.unListen();
1038
- const { data: nextData, deps: nextDeps } = invokeDepFn(callback);
1039
- model.set(nextData);
1040
- if (typeof isContinue !== 'function' || isContinue(nextData) !== false) {
1041
- listen(model, nextDeps, callback, unListenRef, isContinue);
1042
- }
1043
- };
1044
- unListenRef.unListen = () => {
1045
- for (const s of deps) {
1046
- s[depsKey].delete(nextListen);
1047
- }
1048
- };
1049
- for (const s of deps) {
1050
- s[depsKey].add(nextListen);
1051
- }
1052
- }
1053
- listen(signal, deps, callback, unListenRef, isContinue);
1076
+ const unListen = listen(signal, deps, callback, isContinue);
1054
1077
  if (component) {
1055
1078
  component.destroyCallbacks.push(() => {
1056
- unListenRef.unListen();
1079
+ unListen();
1057
1080
  });
1058
1081
  }
1059
1082
  return signal;
@@ -1116,6 +1139,9 @@ function inject(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.S
1116
1139
  return component.get(token, notFoundValue, flags);
1117
1140
  }
1118
1141
 
1142
+ class NativeRenderer {
1143
+ }
1144
+
1119
1145
  function Fragment(props) {
1120
1146
  return () => {
1121
1147
  return props.children;
@@ -1123,25 +1149,23 @@ function Fragment(props) {
1123
1149
  }
1124
1150
  function jsx(setup, props, key) {
1125
1151
  if (typeof setup === 'string') {
1126
- return JSXElement.create(setup, props, key);
1152
+ return JSXElement.createInstance(setup, props, key);
1127
1153
  }
1128
- return new JSXComponent(props, function (context, props) {
1154
+ return new JSXComponent(setup, props, function (context) {
1129
1155
  return new Component(context, setup, props, key);
1130
- });
1156
+ }, key);
1131
1157
  }
1132
1158
  const jsxs = jsx;
1159
+ const JSXTextTypeOf = Symbol('JSXText');
1133
1160
  class JSXText {
1134
1161
  constructor(text) {
1135
1162
  this.text = text;
1136
- this.$$typeOf = '#text';
1137
- }
1138
- is(target) {
1139
- return target.$$typeOf === this.$$typeOf;
1163
+ this.$$typeOf = JSXTextTypeOf;
1140
1164
  }
1141
1165
  }
1142
1166
  class JSXElement {
1143
- static create(name, props, key) {
1144
- return new JSXElement(name, props, key);
1167
+ static createInstance(type, props, key) {
1168
+ return new JSXElement(type, props, key);
1145
1169
  }
1146
1170
  constructor(type, props, key) {
1147
1171
  this.type = type;
@@ -1149,39 +1173,27 @@ class JSXElement {
1149
1173
  this.key = key;
1150
1174
  this.$$typeOf = this.type;
1151
1175
  }
1152
- is(target) {
1153
- return target.$$typeOf === this.$$typeOf;
1176
+ }
1177
+ class JSXComponent {
1178
+ constructor(type, props, factory, key) {
1179
+ this.type = type;
1180
+ this.props = props;
1181
+ this.factory = factory;
1182
+ this.key = key;
1183
+ this.$$typeOf = this.type;
1184
+ }
1185
+ createInstance(parentComponent) {
1186
+ return this.factory(parentComponent);
1154
1187
  }
1155
1188
  }
1156
1189
 
1157
- function withMemo(shouldUpdate, render) {
1190
+ function withMemo(canUseMemo, render) {
1158
1191
  return {
1159
- $shouldUpdate: shouldUpdate,
1192
+ $useMemo: canUseMemo,
1160
1193
  $render: render
1161
1194
  };
1162
1195
  }
1163
1196
 
1164
- /**
1165
- * Viewfly 根组件,用于实现组件状态更新事件通知
1166
- */
1167
- class RootComponent extends Component {
1168
- constructor(parentInjector, factory) {
1169
- super(parentInjector, factory, {});
1170
- this.onChange = null;
1171
- }
1172
- markAsChanged(changedComponent) {
1173
- var _a;
1174
- this._changed = true;
1175
- if (changedComponent) {
1176
- this.changedSubComponents.add(changedComponent);
1177
- }
1178
- (_a = this.onChange) === null || _a === void 0 ? void 0 : _a.call(this);
1179
- }
1180
- }
1181
-
1182
- class NativeRenderer {
1183
- }
1184
-
1185
1197
  function createRenderer(component, nativeRenderer) {
1186
1198
  let isInit = true;
1187
1199
  return function render(host) {
@@ -1194,7 +1206,7 @@ function createRenderer(component, nativeRenderer) {
1194
1206
  child: null,
1195
1207
  nativeNode: null
1196
1208
  };
1197
- buildView(nativeRenderer, atom, {
1209
+ componentRender(nativeRenderer, component, atom, {
1198
1210
  isParent: true,
1199
1211
  host
1200
1212
  });
@@ -1204,15 +1216,11 @@ function createRenderer(component, nativeRenderer) {
1204
1216
  }
1205
1217
  };
1206
1218
  }
1207
- function buildView(nativeRenderer, atom, context) {
1208
- if (atom.jsxNode instanceof Component) {
1209
- componentRender(atom.jsxNode, atom, context);
1210
- let child = atom.child;
1211
- while (child) {
1212
- buildView(nativeRenderer, child, context);
1213
- child = child.sibling;
1214
- }
1215
- atom.jsxNode.rendered();
1219
+ function buildView(nativeRenderer, parentComponent, atom, context) {
1220
+ if (atom.jsxNode instanceof JSXComponent) {
1221
+ const component = atom.jsxNode.createInstance(parentComponent);
1222
+ atom.jsxNode = component;
1223
+ componentRender(nativeRenderer, component, atom, context);
1216
1224
  }
1217
1225
  else {
1218
1226
  let nativeNode;
@@ -1239,7 +1247,7 @@ function buildView(nativeRenderer, atom, context) {
1239
1247
  };
1240
1248
  let child = atom.child;
1241
1249
  while (child) {
1242
- buildView(nativeRenderer, child, childContext);
1250
+ buildView(nativeRenderer, parentComponent, child, childContext);
1243
1251
  child = child.sibling;
1244
1252
  }
1245
1253
  }
@@ -1263,9 +1271,9 @@ function updateView(nativeRenderer, component) {
1263
1271
  }
1264
1272
  }
1265
1273
  function applyChanges(nativeRenderer, component) {
1266
- const { atom, render, host, isParent } = component.$$view;
1274
+ const { atom, host, isParent } = component.$$view;
1267
1275
  const diffAtom = atom.child;
1268
- const template = render(component.props, component.props);
1276
+ const template = component.update(component.props, true);
1269
1277
  if (template) {
1270
1278
  linkTemplate(template, component, atom);
1271
1279
  }
@@ -1276,34 +1284,48 @@ function applyChanges(nativeRenderer, component) {
1276
1284
  host,
1277
1285
  isParent
1278
1286
  };
1279
- diff(nativeRenderer, atom.child, diffAtom, context, 0, 0);
1287
+ diff(nativeRenderer, component, atom.child, diffAtom, context, 0, 0);
1280
1288
  const next = atom.sibling;
1281
1289
  if (next && next.jsxNode instanceof Component) {
1282
1290
  next.jsxNode.$$view.host = context.host;
1283
1291
  next.jsxNode.$$view.isParent = context.isParent;
1284
1292
  }
1285
1293
  }
1286
- function diff(nativeRenderer, newAtom, oldAtom, context, expectIndex, index) {
1287
- const oldChildren = [];
1288
- while (oldAtom) {
1289
- oldChildren.push({
1294
+ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expectIndex, index) {
1295
+ let prevDiffAtom = null;
1296
+ let firstDiffAtomIndexed = null;
1297
+ if (oldAtom) {
1298
+ prevDiffAtom = {
1290
1299
  index,
1291
- atom: oldAtom
1292
- });
1293
- oldAtom = oldAtom.sibling;
1300
+ atom: oldAtom,
1301
+ prev: null
1302
+ };
1294
1303
  index++;
1304
+ firstDiffAtomIndexed = prevDiffAtom;
1305
+ oldAtom = oldAtom.sibling;
1306
+ while (oldAtom) {
1307
+ const diffAtom = {
1308
+ index,
1309
+ atom: oldAtom,
1310
+ prev: prevDiffAtom
1311
+ };
1312
+ prevDiffAtom.next = diffAtom;
1313
+ prevDiffAtom = diffAtom;
1314
+ oldAtom = oldAtom.sibling;
1315
+ index++;
1316
+ }
1295
1317
  }
1296
1318
  const commits = [];
1297
1319
  const changeCommits = {
1298
1320
  updateComponent: (newAtom, reusedAtom, expectIndex, diffIndex) => {
1299
1321
  commits.push((offset) => {
1300
- const { render, template } = reusedAtom.jsxNode.$$view;
1322
+ const instance = reusedAtom.jsxNode;
1301
1323
  const newProps = newAtom.jsxNode.props;
1302
- const oldProps = reusedAtom.jsxNode.props;
1303
- newAtom.jsxNode = reusedAtom.jsxNode;
1304
- const newTemplate = render(newProps, oldProps);
1305
- newAtom.jsxNode.$$view = Object.assign({ render, template: newTemplate, atom: newAtom }, context);
1306
- if (newTemplate === template) {
1324
+ const oldTemplate = instance.template;
1325
+ const newTemplate = instance.update(newProps);
1326
+ instance.$$view = Object.assign({ atom: newAtom }, context);
1327
+ newAtom.jsxNode = instance;
1328
+ if (newTemplate === oldTemplate) {
1307
1329
  reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex !== diffIndex - offset);
1308
1330
  return;
1309
1331
  }
@@ -1311,7 +1333,7 @@ function diff(nativeRenderer, newAtom, oldAtom, context, expectIndex, index) {
1311
1333
  linkTemplate(newTemplate, newAtom.jsxNode, newAtom);
1312
1334
  }
1313
1335
  if (newAtom.child) {
1314
- diff(nativeRenderer, newAtom.child, reusedAtom.child, context, expectIndex, diffIndex);
1336
+ diff(nativeRenderer, instance, newAtom.child, reusedAtom.child, context, expectIndex, diffIndex);
1315
1337
  }
1316
1338
  else if (reusedAtom.child) {
1317
1339
  let atom = reusedAtom.child;
@@ -1320,7 +1342,7 @@ function diff(nativeRenderer, newAtom, oldAtom, context, expectIndex, index) {
1320
1342
  atom = atom.sibling;
1321
1343
  }
1322
1344
  }
1323
- newAtom.jsxNode.rendered();
1345
+ instance.rendered();
1324
1346
  });
1325
1347
  },
1326
1348
  updateElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
@@ -1339,7 +1361,7 @@ function diff(nativeRenderer, newAtom, oldAtom, context, expectIndex, index) {
1339
1361
  context.isParent = false;
1340
1362
  const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode);
1341
1363
  if (newAtom.child) {
1342
- diff(nativeRenderer, newAtom.child, oldAtom.child, {
1364
+ diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1343
1365
  host: newAtom.nativeNode,
1344
1366
  isParent: true
1345
1367
  }, 0, 0);
@@ -1367,28 +1389,27 @@ function diff(nativeRenderer, newAtom, oldAtom, context, expectIndex, index) {
1367
1389
  },
1368
1390
  create: (start) => {
1369
1391
  commits.push(() => {
1370
- buildView(nativeRenderer, start, context);
1392
+ buildView(nativeRenderer, parentComponent, start, context);
1371
1393
  });
1372
1394
  }
1373
1395
  };
1374
1396
  while (newAtom) {
1375
- createChanges(newAtom, expectIndex, oldChildren, changeCommits);
1397
+ firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, changeCommits);
1376
1398
  newAtom = newAtom.sibling;
1377
1399
  expectIndex++;
1378
1400
  }
1379
- for (const item of oldChildren) {
1380
- cleanView(nativeRenderer, item.atom, false);
1401
+ let dirtyDiffAtom = firstDiffAtomIndexed;
1402
+ while (dirtyDiffAtom) {
1403
+ cleanView(nativeRenderer, dirtyDiffAtom.atom, false);
1404
+ dirtyDiffAtom = dirtyDiffAtom.next;
1381
1405
  }
1382
- let j = 0;
1383
1406
  let offset = 0;
1384
- const len = oldChildren.length;
1385
1407
  for (let i = 0; i < commits.length; i++) {
1386
1408
  const commit = commits[i];
1387
- while (j < len) {
1388
- const current = oldChildren[j];
1389
- if (current.index <= i) {
1409
+ while (firstDiffAtomIndexed) {
1410
+ if (firstDiffAtomIndexed.index <= i) {
1390
1411
  offset++;
1391
- j++;
1412
+ firstDiffAtomIndexed = firstDiffAtomIndexed.next;
1392
1413
  continue;
1393
1414
  }
1394
1415
  break;
@@ -1430,17 +1451,19 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
1430
1451
  updateContext(atom);
1431
1452
  }
1432
1453
  }
1433
- function createChanges(newAtom, expectIndex, oldChildren, changeCommits) {
1434
- for (let i = 0; i < oldChildren.length; i++) {
1435
- const { atom: diffAtom, index: diffIndex } = oldChildren[i];
1454
+ function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1455
+ const startDiffAtom = diffAtomIndexed;
1456
+ while (diffAtomIndexed) {
1457
+ const { atom: diffAtom, index: diffIndex } = diffAtomIndexed;
1436
1458
  const key = newAtom.jsxNode.key;
1437
1459
  const diffKey = diffAtom.jsxNode.key;
1438
1460
  if (key !== undefined && diffKey !== undefined) {
1439
1461
  if (diffKey !== key) {
1462
+ diffAtomIndexed = diffAtomIndexed.next;
1440
1463
  continue;
1441
1464
  }
1442
1465
  }
1443
- if (newAtom.jsxNode.is(diffAtom.jsxNode)) {
1466
+ if (newAtom.jsxNode.$$typeOf === diffAtom.jsxNode.$$typeOf) {
1444
1467
  if (newAtom.jsxNode instanceof JSXElement) {
1445
1468
  changeCommits.updateElement(newAtom, diffAtom, expectIndex, diffIndex);
1446
1469
  }
@@ -1450,11 +1473,25 @@ function createChanges(newAtom, expectIndex, oldChildren, changeCommits) {
1450
1473
  else {
1451
1474
  changeCommits.updateComponent(newAtom, diffAtom, expectIndex, diffIndex);
1452
1475
  }
1453
- oldChildren.splice(i, 1);
1454
- return;
1476
+ const next = diffAtomIndexed.next;
1477
+ const prev = diffAtomIndexed.prev;
1478
+ if (!prev) {
1479
+ diffAtomIndexed = next;
1480
+ if (diffAtomIndexed) {
1481
+ diffAtomIndexed.prev = null;
1482
+ }
1483
+ return diffAtomIndexed;
1484
+ }
1485
+ prev.next = next;
1486
+ if (next) {
1487
+ next.prev = prev;
1488
+ }
1489
+ return startDiffAtom;
1455
1490
  }
1491
+ diffAtomIndexed = diffAtomIndexed.next;
1456
1492
  }
1457
1493
  changeCommits.create(newAtom);
1494
+ return startDiffAtom;
1458
1495
  }
1459
1496
  function cleanView(nativeRenderer, atom, isClean) {
1460
1497
  if (atom.nativeNode) {
@@ -1476,26 +1513,29 @@ function cleanView(nativeRenderer, atom, isClean) {
1476
1513
  atom.jsxNode.destroy();
1477
1514
  }
1478
1515
  }
1479
- function componentRender(component, from, context) {
1480
- const { template, render } = component.setup();
1516
+ function componentRender(nativeRenderer, component, from, context) {
1517
+ const template = component.render();
1481
1518
  if (template) {
1482
1519
  linkTemplate(template, component, from);
1483
1520
  }
1484
- component.$$view = Object.assign({ render,
1485
- template, atom: from }, context);
1486
- return from;
1521
+ component.$$view = Object.assign({ atom: from }, context);
1522
+ let child = from.child;
1523
+ while (child) {
1524
+ buildView(nativeRenderer, component, child, context);
1525
+ child = child.sibling;
1526
+ }
1527
+ component.rendered();
1487
1528
  }
1488
- function createChainByComponentFactory(context, factory, parent) {
1489
- const component = factory.createInstance(context);
1529
+ function createChainByComponentFactory(jsxComponent, parent) {
1490
1530
  return {
1491
- jsxNode: component,
1531
+ jsxNode: jsxComponent,
1492
1532
  parent,
1493
1533
  sibling: null,
1494
1534
  child: null,
1495
1535
  nativeNode: null
1496
1536
  };
1497
1537
  }
1498
- function createChainByJSXElement(context, element, parent) {
1538
+ function createChainByJSXElement(component, element, parent) {
1499
1539
  const atom = {
1500
1540
  jsxNode: element,
1501
1541
  parent,
@@ -1505,7 +1545,7 @@ function createChainByJSXElement(context, element, parent) {
1505
1545
  };
1506
1546
  if (Reflect.has(element.props, 'children')) {
1507
1547
  const jsxChildren = element.props.children;
1508
- const children = createChainByChildren(context, Array.isArray(jsxChildren) ? jsxChildren : [jsxChildren], atom, []);
1548
+ const children = createChainByChildren(component, Array.isArray(jsxChildren) ? jsxChildren : [jsxChildren], atom, []);
1509
1549
  link(atom, children);
1510
1550
  }
1511
1551
  return atom;
@@ -1519,26 +1559,26 @@ function createChainByJSXText(node, parent) {
1519
1559
  nativeNode: null
1520
1560
  };
1521
1561
  }
1522
- function createChainByChildren(context, children, parent, atoms) {
1562
+ function createChainByChildren(component, children, parent, atoms) {
1523
1563
  for (const item of children) {
1524
- if (item instanceof JSXElement) {
1525
- atoms.push(createChainByJSXElement(context, item, parent));
1526
- continue;
1527
- }
1528
- if (item instanceof JSXComponent) {
1529
- const childAtom = createChainByComponentFactory(context, item, parent);
1530
- atoms.push(childAtom);
1531
- continue;
1532
- }
1533
- if (typeof item === 'string' && item.length) {
1534
- atoms.push(createChainByJSXText(new JSXText(item), parent));
1535
- continue;
1536
- }
1537
- if (Array.isArray(item)) {
1538
- createChainByChildren(context, item, parent, atoms);
1539
- continue;
1540
- }
1541
1564
  if (item !== null && typeof item !== 'undefined') {
1565
+ if (item instanceof JSXElement) {
1566
+ atoms.push(createChainByJSXElement(component, item, parent));
1567
+ continue;
1568
+ }
1569
+ if (item instanceof JSXComponent) {
1570
+ const childAtom = createChainByComponentFactory(item, parent);
1571
+ atoms.push(childAtom);
1572
+ continue;
1573
+ }
1574
+ if (typeof item === 'string' && item.length) {
1575
+ atoms.push(createChainByJSXText(new JSXText(item), parent));
1576
+ continue;
1577
+ }
1578
+ if (Array.isArray(item)) {
1579
+ createChainByChildren(component, item, parent, atoms);
1580
+ continue;
1581
+ }
1542
1582
  atoms.push(createChainByJSXText(new JSXText(String(item)), parent));
1543
1583
  }
1544
1584
  }
@@ -1546,7 +1586,8 @@ function createChainByChildren(context, children, parent, atoms) {
1546
1586
  }
1547
1587
  function linkTemplate(template, component, parent) {
1548
1588
  const children = Array.isArray(template) ? template : [template];
1549
- link(parent, createChainByChildren(component, children, parent, []));
1589
+ const newChildren = createChainByChildren(component, children, parent, []);
1590
+ link(parent, newChildren);
1550
1591
  }
1551
1592
  function link(parent, children) {
1552
1593
  for (let i = 1; i < children.length; i++) {
@@ -1726,6 +1767,24 @@ function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn) {
1726
1767
  nativeRenderer.listen(nativeNode, type, delegate);
1727
1768
  }
1728
1769
 
1770
+ /**
1771
+ * Viewfly 根组件,用于实现组件状态更新事件通知
1772
+ */
1773
+ class RootComponent extends Component {
1774
+ constructor(parentInjector, factory) {
1775
+ super(parentInjector, factory, {});
1776
+ this.onChange = null;
1777
+ }
1778
+ markAsChanged(changedComponent) {
1779
+ var _a;
1780
+ this._changed = true;
1781
+ if (changedComponent) {
1782
+ this.changedSubComponents.add(changedComponent);
1783
+ }
1784
+ (_a = this.onChange) === null || _a === void 0 ? void 0 : _a.call(this);
1785
+ }
1786
+ }
1787
+
1729
1788
  const viewflyErrorFn = makeError('Viewfly');
1730
1789
  function viewfly({ context, nativeRenderer, autoUpdate, root }) {
1731
1790
  const appProviders = [];