@viewfly/core 0.0.29 → 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.
package/bundles/index.js CHANGED
@@ -569,6 +569,23 @@ function getObjectChanges(newProps, oldProps) {
569
569
  });
570
570
  return changes;
571
571
  }
572
+ function getArrayChanges(left, right) {
573
+ const changes = {
574
+ add: [],
575
+ remove: []
576
+ };
577
+ for (const i of left) {
578
+ if (!right.includes(i)) {
579
+ changes.remove.push(i);
580
+ }
581
+ }
582
+ for (const i of right) {
583
+ if (!left.includes(i)) {
584
+ changes.add.push(i);
585
+ }
586
+ }
587
+ return changes;
588
+ }
572
589
  function classToString(config) {
573
590
  if (!config) {
574
591
  return '';
@@ -632,23 +649,52 @@ function getSignalDepsContext() {
632
649
  * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
633
650
  */
634
651
  class Component extends ReflectiveInjector {
635
- constructor(context, jsxNode, props, key) {
636
- super(context, [{
652
+ get dirty() {
653
+ return this._dirty;
654
+ }
655
+ get changed() {
656
+ return this._changed;
657
+ }
658
+ constructor(parentComponent, type, props, key) {
659
+ super(parentComponent, [{
637
660
  provide: Injector,
638
661
  useFactory: () => this
639
662
  }]);
640
- this.jsxNode = jsxNode;
663
+ this.parentComponent = parentComponent;
664
+ this.type = type;
641
665
  this.props = props;
642
666
  this.key = key;
667
+ this.$$typeOf = this.type;
643
668
  this.destroyCallbacks = [];
644
669
  this.mountCallbacks = [];
645
670
  this.propsChangedCallbacks = [];
646
671
  this.updatedCallbacks = [];
672
+ this.changedSubComponents = new Set();
673
+ this._dirty = true;
674
+ this._changed = true;
647
675
  this.updatedDestroyCallbacks = [];
648
676
  this.propsChangedDestroyCallbacks = [];
649
677
  this.isFirstRending = true;
678
+ }
679
+ markAsDirtied() {
680
+ this._dirty = true;
681
+ this.markAsChanged();
682
+ }
683
+ markAsChanged(changedComponent) {
684
+ if (changedComponent) {
685
+ this.changedSubComponents.add(changedComponent);
686
+ }
687
+ if (this._changed) {
688
+ return;
689
+ }
690
+ this._changed = true;
691
+ if (this.parentComponent instanceof Component) {
692
+ this.parentComponent.markAsChanged(this);
693
+ }
694
+ }
695
+ render() {
650
696
  const self = this;
651
- const proxiesProps = new Proxy(props, {
697
+ const proxiesProps = new Proxy(this.props, {
652
698
  get(_, key) {
653
699
  // 必须用 self,因为 props 会随着页面更新变更,使用 self 才能更新引用
654
700
  return self.props[key];
@@ -663,10 +709,10 @@ class Component extends ReflectiveInjector {
663
709
  });
664
710
  componentSetupStack.push(this);
665
711
  let isSetup = true;
666
- const render = this.jsxNode.type(proxiesProps);
712
+ const render = this.type(proxiesProps);
667
713
  const isRenderFn = typeof render === 'function';
668
714
  this.instance = isRenderFn ? { $render: render } : render;
669
- this.refs = toRefs(props.ref);
715
+ this.refs = toRefs(this.props.ref);
670
716
  this.mountCallbacks.push(() => {
671
717
  for (const ref of this.refs) {
672
718
  ref.bind(this.instance);
@@ -679,13 +725,11 @@ class Component extends ReflectiveInjector {
679
725
  });
680
726
  isSetup = false;
681
727
  componentSetupStack.pop();
682
- }
683
- render() {
684
728
  signalDepsStack.push([]);
685
729
  let template = this.instance.$render();
686
730
  const deps = signalDepsStack.pop();
687
- this.unWatch = useEffect(deps, () => {
688
- this.jsxNode.markAsDirtied();
731
+ this.unWatch = useEffect(Array.from(new Set(deps)), () => {
732
+ this.markAsDirtied();
689
733
  });
690
734
  this.template = template;
691
735
  return template;
@@ -717,8 +761,8 @@ class Component extends ReflectiveInjector {
717
761
  signalDepsStack.push([]);
718
762
  this.template = this.instance.$render();
719
763
  const deps = signalDepsStack.pop();
720
- this.unWatch = useEffect(deps, () => {
721
- this.jsxNode.markAsDirtied();
764
+ this.unWatch = useEffect(Array.from(new Set(deps)), () => {
765
+ this.markAsDirtied();
722
766
  });
723
767
  return this.template;
724
768
  }
@@ -727,8 +771,10 @@ class Component extends ReflectiveInjector {
727
771
  this.normalizedProviders.unshift(...providers.map(i => normalizeProvider(i)));
728
772
  }
729
773
  rendered() {
774
+ this.changedSubComponents.clear();
730
775
  const is = this.isFirstRending;
731
776
  this.isFirstRending = false;
777
+ this._dirty = this._changed = false;
732
778
  if (is) {
733
779
  this.invokeUpdatedHooks();
734
780
  this.invokeMountHooks();
@@ -976,10 +1022,48 @@ function invokeDepFn(fn) {
976
1022
  const data = fn();
977
1023
  signalDepsStack.pop();
978
1024
  return {
979
- deps,
1025
+ deps: Array.from(new Set(deps)),
980
1026
  data
981
1027
  };
982
1028
  }
1029
+ function listen(model, deps, callback, isContinue) {
1030
+ let isStop = false;
1031
+ const nextListen = () => {
1032
+ if (isStop) {
1033
+ return;
1034
+ }
1035
+ isStop = true;
1036
+ const { data: nextData, deps: nextDeps } = invokeDepFn(callback);
1037
+ model.set(nextData);
1038
+ if (typeof isContinue === 'function' && isContinue(nextData) === false) {
1039
+ unListen();
1040
+ return;
1041
+ }
1042
+ const changes = getArrayChanges(deps, nextDeps);
1043
+ deps = deps.filter(i => {
1044
+ const has = changes.remove.includes(i);
1045
+ if (has) {
1046
+ i[depsKey].delete(nextListen);
1047
+ return false;
1048
+ }
1049
+ return true;
1050
+ });
1051
+ for (const s of changes.add) {
1052
+ s[depsKey].add(nextListen);
1053
+ }
1054
+ deps.push(...changes.add);
1055
+ isStop = false;
1056
+ };
1057
+ const unListen = () => {
1058
+ for (const s of deps) {
1059
+ s[depsKey].delete(nextListen);
1060
+ }
1061
+ };
1062
+ for (const s of deps) {
1063
+ s[depsKey].add(nextListen);
1064
+ }
1065
+ return unListen;
1066
+ }
983
1067
  /**
984
1068
  * 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
985
1069
  * 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
@@ -991,29 +1075,10 @@ function useDerived(callback, isContinue) {
991
1075
  let { data, deps } = invokeDepFn(callback);
992
1076
  const signal = useSignal(data);
993
1077
  const component = getSetupContext(false);
994
- const unListenRef = {};
995
- function listen(model, deps, callback, unListenRef, isContinue) {
996
- const nextListen = () => {
997
- unListenRef.unListen();
998
- const { data: nextData, deps: nextDeps } = invokeDepFn(callback);
999
- model.set(nextData);
1000
- if (typeof isContinue !== 'function' || isContinue(nextData) !== false) {
1001
- listen(model, nextDeps, callback, unListenRef, isContinue);
1002
- }
1003
- };
1004
- unListenRef.unListen = () => {
1005
- for (const s of deps) {
1006
- s[depsKey].delete(nextListen);
1007
- }
1008
- };
1009
- for (const s of deps) {
1010
- s[depsKey].add(nextListen);
1011
- }
1012
- }
1013
- listen(signal, deps, callback, unListenRef, isContinue);
1078
+ const unListen = listen(signal, deps, callback, isContinue);
1014
1079
  if (component) {
1015
1080
  component.destroyCallbacks.push(() => {
1016
- unListenRef.unListen();
1081
+ unListen();
1017
1082
  });
1018
1083
  }
1019
1084
  return signal;
@@ -1086,25 +1151,23 @@ function Fragment(props) {
1086
1151
  }
1087
1152
  function jsx(setup, props, key) {
1088
1153
  if (typeof setup === 'string') {
1089
- return JSXElement.create(setup, props, key);
1154
+ return JSXElement.createInstance(setup, props, key);
1090
1155
  }
1091
- return new JSXComponent(setup, props, function (context, jsxNode) {
1092
- return new Component(context, jsxNode, props, key);
1156
+ return new JSXComponent(setup, props, function (context) {
1157
+ return new Component(context, setup, props, key);
1093
1158
  }, key);
1094
1159
  }
1095
1160
  const jsxs = jsx;
1161
+ const JSXTextTypeOf = Symbol('JSXText');
1096
1162
  class JSXText {
1097
1163
  constructor(text) {
1098
1164
  this.text = text;
1099
- this.$$typeOf = '#text';
1100
- }
1101
- is(target) {
1102
- return target.$$typeOf === this.$$typeOf;
1165
+ this.$$typeOf = JSXTextTypeOf;
1103
1166
  }
1104
1167
  }
1105
1168
  class JSXElement {
1106
- static create(name, props, key) {
1107
- return new JSXElement(name, props, key);
1169
+ static createInstance(type, props, key) {
1170
+ return new JSXElement(type, props, key);
1108
1171
  }
1109
1172
  constructor(type, props, key) {
1110
1173
  this.type = type;
@@ -1112,54 +1175,17 @@ class JSXElement {
1112
1175
  this.key = key;
1113
1176
  this.$$typeOf = this.type;
1114
1177
  }
1115
- is(target) {
1116
- return target.$$typeOf === this.$$typeOf;
1117
- }
1118
1178
  }
1119
1179
  class JSXComponent {
1120
- get dirty() {
1121
- return this._dirty;
1122
- }
1123
- get changed() {
1124
- return this._changed;
1125
- }
1126
1180
  constructor(type, props, factory, key) {
1127
1181
  this.type = type;
1128
1182
  this.props = props;
1129
1183
  this.factory = factory;
1130
1184
  this.key = key;
1131
1185
  this.$$typeOf = this.type;
1132
- this.parentComponent = null;
1133
- this.changedSubComponents = new Set();
1134
- this._dirty = true;
1135
- this._changed = true;
1136
1186
  }
1137
- markAsDirtied() {
1138
- this._dirty = true;
1139
- this.markAsChanged();
1140
- }
1141
- markAsChanged(changedComponent) {
1142
- if (changedComponent) {
1143
- this.changedSubComponents.add(changedComponent);
1144
- }
1145
- if (this._changed) {
1146
- return;
1147
- }
1148
- this._changed = true;
1149
- this.parentComponent.markAsChanged(this);
1150
- }
1151
- reset() {
1152
- this.changedSubComponents.clear();
1153
- this.instance.rendered();
1154
- this._dirty = this._changed = false;
1155
- }
1156
- is(target) {
1157
- return target.$$typeOf === this.$$typeOf;
1158
- }
1159
- createInstance(injector) {
1160
- this.parentComponent = injector.jsxNode;
1161
- this.instance = this.factory(injector, this);
1162
- return this.instance;
1187
+ createInstance(parentComponent) {
1188
+ return this.factory(parentComponent);
1163
1189
  }
1164
1190
  }
1165
1191
 
@@ -1170,37 +1196,33 @@ function withMemo(canUseMemo, render) {
1170
1196
  };
1171
1197
  }
1172
1198
 
1173
- function createRenderer(jsxComponent, nativeRenderer, parentComponent) {
1199
+ function createRenderer(component, nativeRenderer) {
1174
1200
  let isInit = true;
1175
1201
  return function render(host) {
1176
1202
  if (isInit) {
1177
1203
  isInit = false;
1178
1204
  const atom = {
1179
- jsxNode: jsxComponent,
1205
+ jsxNode: component,
1180
1206
  parent: null,
1181
1207
  sibling: null,
1182
1208
  child: null,
1183
1209
  nativeNode: null
1184
1210
  };
1185
- buildView(nativeRenderer, parentComponent, atom, {
1211
+ componentRender(nativeRenderer, component, atom, {
1186
1212
  isParent: true,
1187
1213
  host
1188
1214
  });
1189
1215
  }
1190
1216
  else {
1191
- updateView(nativeRenderer, jsxComponent);
1217
+ updateView(nativeRenderer, component);
1192
1218
  }
1193
1219
  };
1194
1220
  }
1195
1221
  function buildView(nativeRenderer, parentComponent, atom, context) {
1196
1222
  if (atom.jsxNode instanceof JSXComponent) {
1197
- const component = componentRender(atom.jsxNode, parentComponent, atom, context);
1198
- let child = atom.child;
1199
- while (child) {
1200
- buildView(nativeRenderer, component, child, context);
1201
- child = child.sibling;
1202
- }
1203
- atom.jsxNode.reset();
1223
+ const component = atom.jsxNode.createInstance(parentComponent);
1224
+ atom.jsxNode = component;
1225
+ componentRender(nativeRenderer, component, atom, context);
1204
1226
  }
1205
1227
  else {
1206
1228
  let nativeNode;
@@ -1238,24 +1260,24 @@ function buildView(nativeRenderer, parentComponent, atom, context) {
1238
1260
  }
1239
1261
  }
1240
1262
  }
1241
- function updateView(nativeRenderer, jsxComponent) {
1242
- if (jsxComponent.dirty) {
1243
- applyChanges(nativeRenderer, jsxComponent);
1244
- jsxComponent.reset();
1263
+ function updateView(nativeRenderer, component) {
1264
+ if (component.dirty) {
1265
+ applyChanges(nativeRenderer, component);
1266
+ component.rendered();
1245
1267
  }
1246
- else if (jsxComponent.changed) {
1247
- jsxComponent.changedSubComponents.forEach(child => {
1268
+ else if (component.changed) {
1269
+ component.changedSubComponents.forEach(child => {
1248
1270
  updateView(nativeRenderer, child);
1249
1271
  });
1250
- jsxComponent.reset();
1272
+ component.rendered();
1251
1273
  }
1252
1274
  }
1253
- function applyChanges(nativeRenderer, jsxComponent) {
1254
- const { atom, host, isParent } = jsxComponent.$$view;
1275
+ function applyChanges(nativeRenderer, component) {
1276
+ const { atom, host, isParent } = component.$$view;
1255
1277
  const diffAtom = atom.child;
1256
- const template = jsxComponent.instance.update(jsxComponent.instance.props, true);
1278
+ const template = component.update(component.props, true);
1257
1279
  if (template) {
1258
- linkTemplate(template, jsxComponent, atom);
1280
+ linkTemplate(template, component, atom);
1259
1281
  }
1260
1282
  else {
1261
1283
  atom.child = null;
@@ -1264,34 +1286,47 @@ function applyChanges(nativeRenderer, jsxComponent) {
1264
1286
  host,
1265
1287
  isParent
1266
1288
  };
1267
- diff(nativeRenderer, jsxComponent.instance, atom.child, diffAtom, context, 0, 0);
1289
+ diff(nativeRenderer, component, atom.child, diffAtom, context, 0, 0);
1268
1290
  const next = atom.sibling;
1269
- if (next && next.jsxNode instanceof JSXComponent) {
1291
+ if (next && next.jsxNode instanceof Component) {
1270
1292
  next.jsxNode.$$view.host = context.host;
1271
1293
  next.jsxNode.$$view.isParent = context.isParent;
1272
1294
  }
1273
1295
  }
1274
1296
  function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expectIndex, index) {
1275
- const oldChildren = [];
1276
- while (oldAtom) {
1277
- oldChildren.push({
1297
+ let prevDiffAtom = null;
1298
+ let firstDiffAtomIndexed = null;
1299
+ if (oldAtom) {
1300
+ prevDiffAtom = {
1278
1301
  index,
1279
- atom: oldAtom
1280
- });
1281
- oldAtom = oldAtom.sibling;
1302
+ atom: oldAtom,
1303
+ prev: null
1304
+ };
1282
1305
  index++;
1306
+ firstDiffAtomIndexed = prevDiffAtom;
1307
+ oldAtom = oldAtom.sibling;
1308
+ while (oldAtom) {
1309
+ const diffAtom = {
1310
+ index,
1311
+ atom: oldAtom,
1312
+ prev: prevDiffAtom
1313
+ };
1314
+ prevDiffAtom.next = diffAtom;
1315
+ prevDiffAtom = diffAtom;
1316
+ oldAtom = oldAtom.sibling;
1317
+ index++;
1318
+ }
1283
1319
  }
1284
1320
  const commits = [];
1285
1321
  const changeCommits = {
1286
1322
  updateComponent: (newAtom, reusedAtom, expectIndex, diffIndex) => {
1287
1323
  commits.push((offset) => {
1288
- const oldJSXComponent = reusedAtom.jsxNode;
1289
- const instance = oldJSXComponent.instance;
1324
+ const instance = reusedAtom.jsxNode;
1290
1325
  const newProps = newAtom.jsxNode.props;
1291
1326
  const oldTemplate = instance.template;
1292
1327
  const newTemplate = instance.update(newProps);
1293
- oldJSXComponent.$$view = Object.assign({ atom: newAtom }, context);
1294
- newAtom.jsxNode = oldJSXComponent;
1328
+ instance.$$view = Object.assign({ atom: newAtom }, context);
1329
+ newAtom.jsxNode = instance;
1295
1330
  if (newTemplate === oldTemplate) {
1296
1331
  reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex !== diffIndex - offset);
1297
1332
  return;
@@ -1309,7 +1344,7 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1309
1344
  atom = atom.sibling;
1310
1345
  }
1311
1346
  }
1312
- oldJSXComponent.reset();
1347
+ instance.rendered();
1313
1348
  });
1314
1349
  },
1315
1350
  updateElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
@@ -1361,23 +1396,22 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1361
1396
  }
1362
1397
  };
1363
1398
  while (newAtom) {
1364
- createChanges(newAtom, expectIndex, oldChildren, changeCommits);
1399
+ firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, changeCommits);
1365
1400
  newAtom = newAtom.sibling;
1366
1401
  expectIndex++;
1367
1402
  }
1368
- for (const item of oldChildren) {
1369
- cleanView(nativeRenderer, item.atom, false);
1403
+ let dirtyDiffAtom = firstDiffAtomIndexed;
1404
+ while (dirtyDiffAtom) {
1405
+ cleanView(nativeRenderer, dirtyDiffAtom.atom, false);
1406
+ dirtyDiffAtom = dirtyDiffAtom.next;
1370
1407
  }
1371
- let j = 0;
1372
1408
  let offset = 0;
1373
- const len = oldChildren.length;
1374
1409
  for (let i = 0; i < commits.length; i++) {
1375
1410
  const commit = commits[i];
1376
- while (j < len) {
1377
- const current = oldChildren[j];
1378
- if (current.index <= i) {
1411
+ while (firstDiffAtomIndexed) {
1412
+ if (firstDiffAtomIndexed.index <= i) {
1379
1413
  offset++;
1380
- j++;
1414
+ firstDiffAtomIndexed = firstDiffAtomIndexed.next;
1381
1415
  continue;
1382
1416
  }
1383
1417
  break;
@@ -1395,7 +1429,7 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
1395
1429
  child = child.sibling;
1396
1430
  }
1397
1431
  const updateContext = (atom) => {
1398
- if (atom.jsxNode instanceof JSXComponent) {
1432
+ if (atom.jsxNode instanceof Component) {
1399
1433
  let child = atom.child;
1400
1434
  while (child) {
1401
1435
  updateContext(child);
@@ -1419,17 +1453,19 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
1419
1453
  updateContext(atom);
1420
1454
  }
1421
1455
  }
1422
- function createChanges(newAtom, expectIndex, oldChildren, changeCommits) {
1423
- for (let i = 0; i < oldChildren.length; i++) {
1424
- const { atom: diffAtom, index: diffIndex } = oldChildren[i];
1456
+ function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1457
+ const startDiffAtom = diffAtomIndexed;
1458
+ while (diffAtomIndexed) {
1459
+ const { atom: diffAtom, index: diffIndex } = diffAtomIndexed;
1425
1460
  const key = newAtom.jsxNode.key;
1426
1461
  const diffKey = diffAtom.jsxNode.key;
1427
1462
  if (key !== undefined && diffKey !== undefined) {
1428
1463
  if (diffKey !== key) {
1464
+ diffAtomIndexed = diffAtomIndexed.next;
1429
1465
  continue;
1430
1466
  }
1431
1467
  }
1432
- if (newAtom.jsxNode.is(diffAtom.jsxNode)) {
1468
+ if (newAtom.jsxNode.$$typeOf === diffAtom.jsxNode.$$typeOf) {
1433
1469
  if (newAtom.jsxNode instanceof JSXElement) {
1434
1470
  changeCommits.updateElement(newAtom, diffAtom, expectIndex, diffIndex);
1435
1471
  }
@@ -1439,11 +1475,25 @@ function createChanges(newAtom, expectIndex, oldChildren, changeCommits) {
1439
1475
  else {
1440
1476
  changeCommits.updateComponent(newAtom, diffAtom, expectIndex, diffIndex);
1441
1477
  }
1442
- oldChildren.splice(i, 1);
1443
- return;
1478
+ const next = diffAtomIndexed.next;
1479
+ const prev = diffAtomIndexed.prev;
1480
+ if (!prev) {
1481
+ diffAtomIndexed = next;
1482
+ if (diffAtomIndexed) {
1483
+ diffAtomIndexed.prev = null;
1484
+ }
1485
+ return diffAtomIndexed;
1486
+ }
1487
+ prev.next = next;
1488
+ if (next) {
1489
+ next.prev = prev;
1490
+ }
1491
+ return startDiffAtom;
1444
1492
  }
1493
+ diffAtomIndexed = diffAtomIndexed.next;
1445
1494
  }
1446
1495
  changeCommits.create(newAtom);
1496
+ return startDiffAtom;
1447
1497
  }
1448
1498
  function cleanView(nativeRenderer, atom, isClean) {
1449
1499
  if (atom.nativeNode) {
@@ -1461,18 +1511,22 @@ function cleanView(nativeRenderer, atom, isClean) {
1461
1511
  cleanView(nativeRenderer, child, isClean);
1462
1512
  child = child.sibling;
1463
1513
  }
1464
- if (atom.jsxNode instanceof JSXComponent) {
1465
- atom.jsxNode.instance.destroy();
1514
+ if (atom.jsxNode instanceof Component) {
1515
+ atom.jsxNode.destroy();
1466
1516
  }
1467
1517
  }
1468
- function componentRender(jsxComponent, parentComponent, from, context) {
1469
- const component = jsxComponent.createInstance(parentComponent);
1518
+ function componentRender(nativeRenderer, component, from, context) {
1470
1519
  const template = component.render();
1471
1520
  if (template) {
1472
- linkTemplate(template, jsxComponent, from);
1521
+ linkTemplate(template, component, from);
1473
1522
  }
1474
- jsxComponent.$$view = Object.assign({ atom: from }, context);
1475
- return component;
1523
+ component.$$view = Object.assign({ atom: from }, context);
1524
+ let child = from.child;
1525
+ while (child) {
1526
+ buildView(nativeRenderer, component, child, context);
1527
+ child = child.sibling;
1528
+ }
1529
+ component.rendered();
1476
1530
  }
1477
1531
  function createChainByComponentFactory(jsxComponent, parent) {
1478
1532
  return {
@@ -1483,7 +1537,7 @@ function createChainByComponentFactory(jsxComponent, parent) {
1483
1537
  nativeNode: null
1484
1538
  };
1485
1539
  }
1486
- function createChainByJSXElement(jsxComponent, element, parent) {
1540
+ function createChainByJSXElement(component, element, parent) {
1487
1541
  const atom = {
1488
1542
  jsxNode: element,
1489
1543
  parent,
@@ -1493,7 +1547,7 @@ function createChainByJSXElement(jsxComponent, element, parent) {
1493
1547
  };
1494
1548
  if (Reflect.has(element.props, 'children')) {
1495
1549
  const jsxChildren = element.props.children;
1496
- const children = createChainByChildren(jsxComponent, Array.isArray(jsxChildren) ? jsxChildren : [jsxChildren], atom, []);
1550
+ const children = createChainByChildren(component, Array.isArray(jsxChildren) ? jsxChildren : [jsxChildren], atom, []);
1497
1551
  link(atom, children);
1498
1552
  }
1499
1553
  return atom;
@@ -1507,34 +1561,34 @@ function createChainByJSXText(node, parent) {
1507
1561
  nativeNode: null
1508
1562
  };
1509
1563
  }
1510
- function createChainByChildren(jsxComponent, children, parent, atoms) {
1564
+ function createChainByChildren(component, children, parent, atoms) {
1511
1565
  for (const item of children) {
1512
- if (item instanceof JSXElement) {
1513
- atoms.push(createChainByJSXElement(jsxComponent, item, parent));
1514
- continue;
1515
- }
1516
- if (item instanceof JSXComponent) {
1517
- const childAtom = createChainByComponentFactory(item, parent);
1518
- atoms.push(childAtom);
1519
- continue;
1520
- }
1521
- if (typeof item === 'string' && item.length) {
1522
- atoms.push(createChainByJSXText(new JSXText(item), parent));
1523
- continue;
1524
- }
1525
- if (Array.isArray(item)) {
1526
- createChainByChildren(jsxComponent, item, parent, atoms);
1527
- continue;
1528
- }
1529
1566
  if (item !== null && typeof item !== 'undefined') {
1567
+ if (item instanceof JSXElement) {
1568
+ atoms.push(createChainByJSXElement(component, item, parent));
1569
+ continue;
1570
+ }
1571
+ if (item instanceof JSXComponent) {
1572
+ const childAtom = createChainByComponentFactory(item, parent);
1573
+ atoms.push(childAtom);
1574
+ continue;
1575
+ }
1576
+ if (typeof item === 'string' && item.length) {
1577
+ atoms.push(createChainByJSXText(new JSXText(item), parent));
1578
+ continue;
1579
+ }
1580
+ if (Array.isArray(item)) {
1581
+ createChainByChildren(component, item, parent, atoms);
1582
+ continue;
1583
+ }
1530
1584
  atoms.push(createChainByJSXText(new JSXText(String(item)), parent));
1531
1585
  }
1532
1586
  }
1533
1587
  return atoms;
1534
1588
  }
1535
- function linkTemplate(template, jsxComponent, parent) {
1589
+ function linkTemplate(template, component, parent) {
1536
1590
  const children = Array.isArray(template) ? template : [template];
1537
- const newChildren = createChainByChildren(jsxComponent, children, parent, []);
1591
+ const newChildren = createChainByChildren(component, children, parent, []);
1538
1592
  link(parent, newChildren);
1539
1593
  }
1540
1594
  function link(parent, children) {
@@ -1718,11 +1772,9 @@ function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn) {
1718
1772
  /**
1719
1773
  * Viewfly 根组件,用于实现组件状态更新事件通知
1720
1774
  */
1721
- class RootComponent extends JSXComponent {
1722
- constructor(factory, {}) {
1723
- super(factory, {}, (parentComponent, jsxNode) => {
1724
- return new Component(parentComponent, jsxNode, {});
1725
- });
1775
+ class RootComponent extends Component {
1776
+ constructor(parentInjector, factory) {
1777
+ super(parentInjector, factory, {});
1726
1778
  this.onChange = null;
1727
1779
  }
1728
1780
  markAsChanged(changedComponent) {
@@ -1739,13 +1791,13 @@ const viewflyErrorFn = makeError('Viewfly');
1739
1791
  function viewfly({ context, nativeRenderer, autoUpdate, root }) {
1740
1792
  const appProviders = [];
1741
1793
  let destroyed = false;
1742
- const rootComponent = new RootComponent(() => {
1794
+ const rootComponent = new RootComponent(context || null, () => {
1743
1795
  provide(appProviders);
1744
1796
  return () => {
1745
1797
  return destroyed ? null : root;
1746
1798
  };
1747
- }, {});
1748
- const render = createRenderer(rootComponent, nativeRenderer, context || new NullInjector());
1799
+ });
1800
+ const render = createRenderer(rootComponent, nativeRenderer);
1749
1801
  let isStarted = false;
1750
1802
  let task = null;
1751
1803
  function microTask(callback) {
@@ -1,5 +1,6 @@
1
- import type { Injector, Provider } from './di/_api';
1
+ import type { Provider } from './di/_api';
2
2
  import { JSXInternal, NativeNode, NativeRenderer } from './foundation/_api';
3
+ import { Injector } from './di/_api';
3
4
  /**
4
5
  * Viewfly 配置项
5
6
  */