@viewfly/core 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,6 @@ export declare abstract class NativeRenderer<ElementNode = NativeNode, TextNode
3
3
  abstract createElement(name: string, isSvg: boolean): ElementNode;
4
4
  abstract createTextNode(textContent: string, isSvg: boolean): TextNode;
5
5
  abstract setProperty(node: ElementNode, key: string, value: any, isSvg: boolean): void;
6
- abstract appendChild(parent: ElementNode, newChild: ElementNode | TextNode, isSvg: boolean): void;
7
6
  abstract prependChild(parent: ElementNode, newChild: ElementNode | TextNode, isSvg: boolean): void;
8
7
  abstract removeProperty(node: ElementNode, key: string, isSvg: boolean): void;
9
8
  abstract setStyle(target: ElementNode, key: string, value: any, isSvg: boolean): void;
@@ -1,3 +1,3 @@
1
1
  import { NativeNode, NativeRenderer } from './injection-tokens';
2
2
  import { Component } from './component';
3
- export declare function createRenderer(component: Component, nativeRenderer: NativeRenderer, version: string): (host: NativeNode) => void;
3
+ export declare function createRenderer(component: Component, nativeRenderer: NativeRenderer): (host: NativeNode) => void;
@@ -5,7 +5,7 @@ import { Injector } from '../di/_api';
5
5
  * Viewfly 根组件,用于实现组件状态更新事件通知
6
6
  */
7
7
  export declare class RootComponent extends Component {
8
- onChange: (() => void) | null;
9
- constructor(parentInjector: Injector | null, factory: JSXInternal.ComponentSetup);
8
+ private refresh;
9
+ constructor(parentInjector: Injector | null, factory: JSXInternal.ComponentSetup, refresh: () => void);
10
10
  markAsChanged(changedComponent?: Component): void;
11
11
  }
@@ -551,22 +551,22 @@ function getObjectChanges(newProps, oldProps) {
551
551
  add: [],
552
552
  replace: []
553
553
  };
554
- Object.keys(newProps).forEach(key => {
554
+ for (const key in newProps) {
555
555
  const leftValue = newProps[key];
556
556
  const rightValue = oldProps[key];
557
557
  if (Reflect.has(oldProps, key)) {
558
558
  if (leftValue !== rightValue) {
559
559
  changes.replace.push([key, leftValue, rightValue]);
560
560
  }
561
- return;
561
+ continue;
562
562
  }
563
563
  changes.add.push([key, leftValue]);
564
- });
565
- Object.keys(oldProps).forEach(key => {
564
+ }
565
+ for (const key in oldProps) {
566
566
  if (!Reflect.has(newProps, key)) {
567
567
  changes.remove.push([key, oldProps[key]]);
568
568
  }
569
- });
569
+ }
570
570
  return changes;
571
571
  }
572
572
  function getArrayChanges(left, right) {
@@ -1215,11 +1215,10 @@ function withMemo(canUseMemo, render) {
1215
1215
  };
1216
1216
  }
1217
1217
 
1218
- function createRenderer(component, nativeRenderer, version) {
1218
+ function createRenderer(component, nativeRenderer) {
1219
1219
  let isInit = true;
1220
1220
  return function render(host) {
1221
1221
  if (isInit) {
1222
- nativeRenderer.setProperty(host, 'viewfly-version', version, false);
1223
1222
  isInit = false;
1224
1223
  const atom = {
1225
1224
  jsxNode: component,
@@ -1339,87 +1338,11 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1339
1338
  }
1340
1339
  }
1341
1340
  const commits = [];
1342
- const changeCommits = {
1343
- updateComponent: (newAtom, reusedAtom, expectIndex, oldIndex) => {
1344
- commits.push((offset) => {
1345
- const instance = reusedAtom.jsxNode;
1346
- const newProps = newAtom.jsxNode.props;
1347
- const oldTemplate = instance.template;
1348
- const newTemplate = instance.update(newProps);
1349
- instance.$$view = Object.assign({ atom: newAtom }, context);
1350
- newAtom.jsxNode = instance;
1351
- if (newTemplate === oldTemplate) {
1352
- reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex - offset !== oldIndex);
1353
- updateView(nativeRenderer, instance);
1354
- return;
1355
- }
1356
- if (newTemplate) {
1357
- linkTemplate(newTemplate, newAtom.jsxNode, newAtom);
1358
- }
1359
- if (newAtom.child) {
1360
- diff(nativeRenderer, instance, newAtom.child, reusedAtom.child, context, expectIndex, oldIndex);
1361
- }
1362
- else if (reusedAtom.child) {
1363
- let atom = reusedAtom.child;
1364
- while (atom) {
1365
- cleanView(nativeRenderer, atom, false);
1366
- atom = atom.sibling;
1367
- }
1368
- }
1369
- instance.rendered();
1370
- });
1371
- },
1372
- updateElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
1373
- commits.push((offset) => {
1374
- newAtom.nativeNode = oldAtom.nativeNode;
1375
- const host = context.host;
1376
- if (expectIndex - offset !== oldIndex) {
1377
- if (context.isParent) {
1378
- nativeRenderer.prependChild(host, newAtom.nativeNode, newAtom.isSvg);
1379
- }
1380
- else {
1381
- nativeRenderer.insertAfter(newAtom.nativeNode, host, newAtom.isSvg);
1382
- }
1383
- }
1384
- context.host = newAtom.nativeNode;
1385
- context.isParent = false;
1386
- const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode, newAtom.isSvg);
1387
- if (newAtom.child) {
1388
- diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1389
- host: newAtom.nativeNode,
1390
- isParent: true
1391
- }, 0, 0);
1392
- }
1393
- else if (oldAtom.child) {
1394
- let atom = oldAtom.child;
1395
- while (atom) {
1396
- cleanView(nativeRenderer, atom, false);
1397
- atom = atom.sibling;
1398
- }
1399
- }
1400
- applyRefs();
1401
- });
1402
- },
1403
- updateText: (newAtom, oldAtom) => {
1404
- commits.push(() => {
1405
- const nativeNode = oldAtom.nativeNode;
1406
- if (newAtom.jsxNode.text !== oldAtom.jsxNode.text) {
1407
- nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode.text, newAtom.isSvg);
1408
- }
1409
- newAtom.nativeNode = nativeNode;
1410
- context.host = nativeNode;
1411
- context.isParent = false;
1412
- });
1413
- },
1414
- create: (start) => {
1415
- commits.push(() => {
1416
- buildView(nativeRenderer, parentComponent, start, context);
1417
- offset++;
1418
- });
1419
- }
1420
- };
1341
+ function changeOffset() {
1342
+ offset++;
1343
+ }
1421
1344
  while (newAtom) {
1422
- firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, changeCommits);
1345
+ firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, nativeRenderer, commits, context, parentComponent, changeOffset);
1423
1346
  newAtom = newAtom.sibling;
1424
1347
  expectIndex++;
1425
1348
  }
@@ -1442,28 +1365,34 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1442
1365
  commit(offset);
1443
1366
  }
1444
1367
  }
1445
- function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1368
+ function createChanges(newAtom, expectIndex, diffAtomIndexed, nativeRenderer, commits, context, parentComponent, effect) {
1446
1369
  const startDiffAtom = diffAtomIndexed;
1370
+ const key = newAtom.jsxNode.key;
1447
1371
  while (diffAtomIndexed) {
1448
1372
  const { atom: diffAtom, index: diffIndex } = diffAtomIndexed;
1449
- const key = newAtom.jsxNode.key;
1450
1373
  const diffKey = diffAtom.jsxNode.key;
1451
- if (key !== undefined && diffKey !== undefined) {
1374
+ if (key !== undefined) {
1452
1375
  if (diffKey !== key) {
1453
1376
  diffAtomIndexed = diffAtomIndexed.next;
1454
1377
  continue;
1455
1378
  }
1456
1379
  }
1380
+ else if (diffKey !== undefined) {
1381
+ diffAtomIndexed = diffAtomIndexed.next;
1382
+ continue;
1383
+ }
1457
1384
  if (newAtom.jsxNode.$$typeOf === diffAtom.jsxNode.$$typeOf) {
1385
+ let commit;
1458
1386
  if (newAtom.jsxNode instanceof JSXElement) {
1459
- changeCommits.updateElement(newAtom, diffAtom, expectIndex, diffIndex);
1387
+ commit = updateElement(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context, parentComponent);
1460
1388
  }
1461
1389
  else if (newAtom.jsxNode instanceof JSXText) {
1462
- changeCommits.updateText(newAtom, diffAtom);
1390
+ commit = updateText(newAtom, diffAtom, nativeRenderer, context);
1463
1391
  }
1464
1392
  else {
1465
- changeCommits.updateComponent(newAtom, diffAtom, expectIndex, diffIndex);
1393
+ commit = updateComponent(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context);
1466
1394
  }
1395
+ commits.push(commit);
1467
1396
  const next = diffAtomIndexed.next;
1468
1397
  const prev = diffAtomIndexed.prev;
1469
1398
  if (!prev) {
@@ -1481,9 +1410,86 @@ function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1481
1410
  }
1482
1411
  diffAtomIndexed = diffAtomIndexed.next;
1483
1412
  }
1484
- changeCommits.create(newAtom);
1413
+ commits.push(createNewView(newAtom, nativeRenderer, context, parentComponent, effect));
1485
1414
  return startDiffAtom;
1486
1415
  }
1416
+ function createNewView(start, nativeRenderer, context, parentComponent, effect) {
1417
+ return function () {
1418
+ buildView(nativeRenderer, parentComponent, start, context);
1419
+ effect();
1420
+ };
1421
+ }
1422
+ function updateText(newAtom, oldAtom, nativeRenderer, context) {
1423
+ return function () {
1424
+ const nativeNode = oldAtom.nativeNode;
1425
+ if (newAtom.jsxNode.text !== oldAtom.jsxNode.text) {
1426
+ nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode.text, newAtom.isSvg);
1427
+ }
1428
+ newAtom.nativeNode = nativeNode;
1429
+ context.host = nativeNode;
1430
+ context.isParent = false;
1431
+ };
1432
+ }
1433
+ function updateElement(newAtom, oldAtom, expectIndex, oldIndex, nativeRenderer, context, parentComponent) {
1434
+ return function (offset) {
1435
+ newAtom.nativeNode = oldAtom.nativeNode;
1436
+ const host = context.host;
1437
+ if (expectIndex - offset !== oldIndex) {
1438
+ if (context.isParent) {
1439
+ nativeRenderer.prependChild(host, newAtom.nativeNode, newAtom.isSvg);
1440
+ }
1441
+ else {
1442
+ nativeRenderer.insertAfter(newAtom.nativeNode, host, newAtom.isSvg);
1443
+ }
1444
+ }
1445
+ context.host = newAtom.nativeNode;
1446
+ context.isParent = false;
1447
+ const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode, newAtom.isSvg);
1448
+ if (newAtom.child) {
1449
+ diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1450
+ host: newAtom.nativeNode,
1451
+ isParent: true
1452
+ }, 0, 0);
1453
+ }
1454
+ else if (oldAtom.child) {
1455
+ let atom = oldAtom.child;
1456
+ while (atom) {
1457
+ cleanView(nativeRenderer, atom, false);
1458
+ atom = atom.sibling;
1459
+ }
1460
+ }
1461
+ applyRefs();
1462
+ };
1463
+ }
1464
+ function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRenderer, context) {
1465
+ return function (offset) {
1466
+ const instance = reusedAtom.jsxNode;
1467
+ const newProps = newAtom.jsxNode.props;
1468
+ const oldTemplate = instance.template;
1469
+ const newTemplate = instance.update(newProps);
1470
+ instance.$$view = Object.assign({ atom: newAtom }, context);
1471
+ newAtom.jsxNode = instance;
1472
+ if (newTemplate === oldTemplate) {
1473
+ reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex - offset !== oldIndex);
1474
+ updateView(nativeRenderer, instance);
1475
+ return;
1476
+ }
1477
+ if (newTemplate) {
1478
+ linkTemplate(newTemplate, newAtom.jsxNode, newAtom);
1479
+ }
1480
+ if (newAtom.child) {
1481
+ diff(nativeRenderer, instance, newAtom.child, reusedAtom.child, context, expectIndex, oldIndex);
1482
+ }
1483
+ else if (reusedAtom.child) {
1484
+ let atom = reusedAtom.child;
1485
+ while (atom) {
1486
+ cleanView(nativeRenderer, atom, false);
1487
+ atom = atom.sibling;
1488
+ }
1489
+ }
1490
+ instance.rendered();
1491
+ };
1492
+ }
1487
1493
  function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveView) {
1488
1494
  let child = reusedAtom.child;
1489
1495
  newAtom.child = child;
@@ -1551,9 +1557,9 @@ function componentRender(nativeRenderer, component, from, context) {
1551
1557
  }
1552
1558
  component.rendered();
1553
1559
  }
1554
- function createChainByComponentFactory(jsxComponent, parent, isSvg) {
1560
+ function createChainByJSXComponentOrJSXText(jsxNode, parent, isSvg) {
1555
1561
  return {
1556
- jsxNode: jsxComponent,
1562
+ jsxNode,
1557
1563
  parent,
1558
1564
  sibling: null,
1559
1565
  child: null,
@@ -1578,16 +1584,6 @@ function createChainByJSXElement(component, element, parent, isSvg) {
1578
1584
  }
1579
1585
  return atom;
1580
1586
  }
1581
- function createChainByJSXText(node, parent, isSvg) {
1582
- return {
1583
- jsxNode: node,
1584
- parent,
1585
- sibling: null,
1586
- child: null,
1587
- nativeNode: null,
1588
- isSvg
1589
- };
1590
- }
1591
1587
  function createChainByChildren(component, children, parent, atoms, isSvg) {
1592
1588
  for (const item of children) {
1593
1589
  if (item !== null && typeof item !== 'undefined' && typeof item !== 'boolean') {
@@ -1595,20 +1591,20 @@ function createChainByChildren(component, children, parent, atoms, isSvg) {
1595
1591
  atoms.push(createChainByJSXElement(component, item, parent, isSvg));
1596
1592
  continue;
1597
1593
  }
1598
- if (item instanceof JSXComponent) {
1599
- const childAtom = createChainByComponentFactory(item, parent, isSvg);
1600
- atoms.push(childAtom);
1601
- continue;
1602
- }
1603
1594
  if (typeof item === 'string' && item.length) {
1604
- atoms.push(createChainByJSXText(new JSXText(item), parent, isSvg));
1595
+ atoms.push(createChainByJSXComponentOrJSXText(new JSXText(item), parent, isSvg));
1605
1596
  continue;
1606
1597
  }
1607
1598
  if (Array.isArray(item)) {
1608
1599
  createChainByChildren(component, item, parent, atoms, isSvg);
1609
1600
  continue;
1610
1601
  }
1611
- atoms.push(createChainByJSXText(new JSXText(String(item)), parent, isSvg));
1602
+ if (item instanceof JSXComponent) {
1603
+ const childAtom = createChainByJSXComponentOrJSXText(item, parent, isSvg);
1604
+ atoms.push(childAtom);
1605
+ continue;
1606
+ }
1607
+ atoms.push(createChainByJSXComponentOrJSXText(new JSXText(String(item)), parent, isSvg));
1612
1608
  }
1613
1609
  }
1614
1610
  return atoms;
@@ -1629,8 +1625,7 @@ function createElement(nativeRenderer, vNode, isSvg) {
1629
1625
  const nativeNode = nativeRenderer.createElement(vNode.type, isSvg);
1630
1626
  const props = vNode.props;
1631
1627
  let bindingRefs;
1632
- const keys = Object.keys(props);
1633
- for (const key of keys) {
1628
+ for (const key in props) {
1634
1629
  if (key === 'children') {
1635
1630
  continue;
1636
1631
  }
@@ -1643,9 +1638,9 @@ function createElement(nativeRenderer, vNode, isSvg) {
1643
1638
  }
1644
1639
  if (key === 'style') {
1645
1640
  const style = styleToObject(props.style);
1646
- Object.keys(style).forEach(key => {
1641
+ for (const key in style) {
1647
1642
  nativeRenderer.setStyle(nativeNode, key, style[key], isSvg);
1648
- });
1643
+ }
1649
1644
  continue;
1650
1645
  }
1651
1646
  if (/^on[A-Z]/.test(key)) {
@@ -1685,9 +1680,9 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1685
1680
  continue;
1686
1681
  }
1687
1682
  if (key === 'style') {
1688
- Object.keys(styleToObject(value)).forEach(styleName => {
1683
+ for (const styleName in styleToObject(value)) {
1689
1684
  nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
1690
- });
1685
+ }
1691
1686
  continue;
1692
1687
  }
1693
1688
  if (/^on[A-Z]/.test(key)) {
@@ -1749,9 +1744,9 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1749
1744
  }
1750
1745
  if (key === 'style') {
1751
1746
  const styleObj = styleToObject(value);
1752
- Object.keys(styleObj).forEach(styleName => {
1747
+ for (const styleName in styleObj) {
1753
1748
  nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
1754
- });
1749
+ }
1755
1750
  continue;
1756
1751
  }
1757
1752
  if (/^on[A-Z]/.test(key)) {
@@ -1785,61 +1780,65 @@ function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn, isSvg) {
1785
1780
  vNode.on = on = {};
1786
1781
  }
1787
1782
  const type = key.replace(/^on/, '').toLowerCase();
1788
- const delegate = function (...args) {
1789
- return delegateObj.listenFn.apply(this, args);
1790
- };
1791
1783
  const delegateObj = {
1792
- delegate,
1784
+ delegate(...args) {
1785
+ return delegateObj.listenFn.apply(this, args);
1786
+ },
1793
1787
  listenFn
1794
1788
  };
1795
1789
  on[type] = delegateObj;
1796
- nativeRenderer.listen(nativeNode, type, delegate, isSvg);
1790
+ nativeRenderer.listen(nativeNode, type, delegateObj.delegate, isSvg);
1797
1791
  }
1798
1792
 
1799
1793
  /**
1800
1794
  * Viewfly 根组件,用于实现组件状态更新事件通知
1801
1795
  */
1802
1796
  class RootComponent extends Component {
1803
- constructor(parentInjector, factory) {
1797
+ constructor(parentInjector, factory, refresh) {
1804
1798
  super(parentInjector, factory, {});
1805
- this.onChange = null;
1799
+ this.refresh = refresh;
1806
1800
  }
1807
1801
  markAsChanged(changedComponent) {
1808
- var _a;
1809
1802
  this._changed = true;
1810
1803
  if (changedComponent) {
1811
1804
  this.changedSubComponents.add(changedComponent);
1812
1805
  }
1813
- (_a = this.onChange) === null || _a === void 0 ? void 0 : _a.call(this);
1806
+ this.refresh();
1814
1807
  }
1815
1808
  }
1816
1809
 
1817
1810
  const viewflyErrorFn = makeError('Viewfly');
1818
- const VERSION = "0.3.1";
1819
1811
  function viewfly(config) {
1820
1812
  const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
1821
1813
  const appProviders = [];
1822
1814
  const modules = [];
1823
1815
  let destroyed = false;
1816
+ let appHost = null;
1824
1817
  const rootComponent = new RootComponent(context || null, () => {
1825
1818
  provide(appProviders);
1826
1819
  return () => {
1827
1820
  return destroyed ? null : root;
1828
1821
  };
1822
+ }, function () {
1823
+ if (destroyed) {
1824
+ return;
1825
+ }
1826
+ nextTick(() => {
1827
+ render(appHost);
1828
+ });
1829
1829
  });
1830
- const render = createRenderer(rootComponent, nativeRenderer, VERSION);
1830
+ const render = createRenderer(rootComponent, nativeRenderer);
1831
1831
  let isStarted = false;
1832
1832
  let task = null;
1833
1833
  function nextTick(callback) {
1834
1834
  if (task !== null) {
1835
1835
  return;
1836
1836
  }
1837
- task = setTimeout(() => {
1837
+ task = Promise.resolve().then(() => {
1838
1838
  task = null;
1839
1839
  callback();
1840
1840
  });
1841
1841
  }
1842
- let appHost = null;
1843
1842
  const app = {
1844
1843
  provide(providers) {
1845
1844
  if (Array.isArray(providers)) {
@@ -1876,15 +1875,6 @@ function viewfly(config) {
1876
1875
  if (!autoUpdate) {
1877
1876
  return app;
1878
1877
  }
1879
- const refresh = () => {
1880
- if (destroyed) {
1881
- return;
1882
- }
1883
- render(host);
1884
- };
1885
- rootComponent.onChange = function () {
1886
- nextTick(refresh);
1887
- };
1888
1878
  return app;
1889
1879
  },
1890
1880
  render() {
@@ -1906,4 +1896,4 @@ function viewfly(config) {
1906
1896
  return app;
1907
1897
  }
1908
1898
 
1909
- export { Component, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXComponent, JSXElement, JSXText, NativeRenderer, NullInjector, Optional, Prop, Ref, ReflectiveInjector, RootComponent, Scope, Self, SkipSelf, THROW_IF_NOT_FOUND, Type, VERSION, createRenderer, forwardRef, getCurrentInstance, inject, jsx, jsxs, makeError, normalizeProvider, onMounted, onPropsChanged, onUnmounted, onUpdated, provide, useDerived, useEffect, useRef, useSignal, viewfly, withMemo };
1899
+ export { Component, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXComponent, JSXElement, JSXText, NativeRenderer, NullInjector, Optional, Prop, Ref, ReflectiveInjector, RootComponent, Scope, Self, SkipSelf, THROW_IF_NOT_FOUND, Type, createRenderer, forwardRef, getCurrentInstance, inject, jsx, jsxs, makeError, normalizeProvider, onMounted, onPropsChanged, onUnmounted, onUpdated, provide, useDerived, useEffect, useRef, useSignal, viewfly, withMemo };
package/bundles/index.js CHANGED
@@ -553,22 +553,22 @@ function getObjectChanges(newProps, oldProps) {
553
553
  add: [],
554
554
  replace: []
555
555
  };
556
- Object.keys(newProps).forEach(key => {
556
+ for (const key in newProps) {
557
557
  const leftValue = newProps[key];
558
558
  const rightValue = oldProps[key];
559
559
  if (Reflect.has(oldProps, key)) {
560
560
  if (leftValue !== rightValue) {
561
561
  changes.replace.push([key, leftValue, rightValue]);
562
562
  }
563
- return;
563
+ continue;
564
564
  }
565
565
  changes.add.push([key, leftValue]);
566
- });
567
- Object.keys(oldProps).forEach(key => {
566
+ }
567
+ for (const key in oldProps) {
568
568
  if (!Reflect.has(newProps, key)) {
569
569
  changes.remove.push([key, oldProps[key]]);
570
570
  }
571
- });
571
+ }
572
572
  return changes;
573
573
  }
574
574
  function getArrayChanges(left, right) {
@@ -1217,11 +1217,10 @@ function withMemo(canUseMemo, render) {
1217
1217
  };
1218
1218
  }
1219
1219
 
1220
- function createRenderer(component, nativeRenderer, version) {
1220
+ function createRenderer(component, nativeRenderer) {
1221
1221
  let isInit = true;
1222
1222
  return function render(host) {
1223
1223
  if (isInit) {
1224
- nativeRenderer.setProperty(host, 'viewfly-version', version, false);
1225
1224
  isInit = false;
1226
1225
  const atom = {
1227
1226
  jsxNode: component,
@@ -1341,87 +1340,11 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1341
1340
  }
1342
1341
  }
1343
1342
  const commits = [];
1344
- const changeCommits = {
1345
- updateComponent: (newAtom, reusedAtom, expectIndex, oldIndex) => {
1346
- commits.push((offset) => {
1347
- const instance = reusedAtom.jsxNode;
1348
- const newProps = newAtom.jsxNode.props;
1349
- const oldTemplate = instance.template;
1350
- const newTemplate = instance.update(newProps);
1351
- instance.$$view = Object.assign({ atom: newAtom }, context);
1352
- newAtom.jsxNode = instance;
1353
- if (newTemplate === oldTemplate) {
1354
- reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex - offset !== oldIndex);
1355
- updateView(nativeRenderer, instance);
1356
- return;
1357
- }
1358
- if (newTemplate) {
1359
- linkTemplate(newTemplate, newAtom.jsxNode, newAtom);
1360
- }
1361
- if (newAtom.child) {
1362
- diff(nativeRenderer, instance, newAtom.child, reusedAtom.child, context, expectIndex, oldIndex);
1363
- }
1364
- else if (reusedAtom.child) {
1365
- let atom = reusedAtom.child;
1366
- while (atom) {
1367
- cleanView(nativeRenderer, atom, false);
1368
- atom = atom.sibling;
1369
- }
1370
- }
1371
- instance.rendered();
1372
- });
1373
- },
1374
- updateElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
1375
- commits.push((offset) => {
1376
- newAtom.nativeNode = oldAtom.nativeNode;
1377
- const host = context.host;
1378
- if (expectIndex - offset !== oldIndex) {
1379
- if (context.isParent) {
1380
- nativeRenderer.prependChild(host, newAtom.nativeNode, newAtom.isSvg);
1381
- }
1382
- else {
1383
- nativeRenderer.insertAfter(newAtom.nativeNode, host, newAtom.isSvg);
1384
- }
1385
- }
1386
- context.host = newAtom.nativeNode;
1387
- context.isParent = false;
1388
- const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode, newAtom.isSvg);
1389
- if (newAtom.child) {
1390
- diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1391
- host: newAtom.nativeNode,
1392
- isParent: true
1393
- }, 0, 0);
1394
- }
1395
- else if (oldAtom.child) {
1396
- let atom = oldAtom.child;
1397
- while (atom) {
1398
- cleanView(nativeRenderer, atom, false);
1399
- atom = atom.sibling;
1400
- }
1401
- }
1402
- applyRefs();
1403
- });
1404
- },
1405
- updateText: (newAtom, oldAtom) => {
1406
- commits.push(() => {
1407
- const nativeNode = oldAtom.nativeNode;
1408
- if (newAtom.jsxNode.text !== oldAtom.jsxNode.text) {
1409
- nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode.text, newAtom.isSvg);
1410
- }
1411
- newAtom.nativeNode = nativeNode;
1412
- context.host = nativeNode;
1413
- context.isParent = false;
1414
- });
1415
- },
1416
- create: (start) => {
1417
- commits.push(() => {
1418
- buildView(nativeRenderer, parentComponent, start, context);
1419
- offset++;
1420
- });
1421
- }
1422
- };
1343
+ function changeOffset() {
1344
+ offset++;
1345
+ }
1423
1346
  while (newAtom) {
1424
- firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, changeCommits);
1347
+ firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, nativeRenderer, commits, context, parentComponent, changeOffset);
1425
1348
  newAtom = newAtom.sibling;
1426
1349
  expectIndex++;
1427
1350
  }
@@ -1444,28 +1367,34 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1444
1367
  commit(offset);
1445
1368
  }
1446
1369
  }
1447
- function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1370
+ function createChanges(newAtom, expectIndex, diffAtomIndexed, nativeRenderer, commits, context, parentComponent, effect) {
1448
1371
  const startDiffAtom = diffAtomIndexed;
1372
+ const key = newAtom.jsxNode.key;
1449
1373
  while (diffAtomIndexed) {
1450
1374
  const { atom: diffAtom, index: diffIndex } = diffAtomIndexed;
1451
- const key = newAtom.jsxNode.key;
1452
1375
  const diffKey = diffAtom.jsxNode.key;
1453
- if (key !== undefined && diffKey !== undefined) {
1376
+ if (key !== undefined) {
1454
1377
  if (diffKey !== key) {
1455
1378
  diffAtomIndexed = diffAtomIndexed.next;
1456
1379
  continue;
1457
1380
  }
1458
1381
  }
1382
+ else if (diffKey !== undefined) {
1383
+ diffAtomIndexed = diffAtomIndexed.next;
1384
+ continue;
1385
+ }
1459
1386
  if (newAtom.jsxNode.$$typeOf === diffAtom.jsxNode.$$typeOf) {
1387
+ let commit;
1460
1388
  if (newAtom.jsxNode instanceof JSXElement) {
1461
- changeCommits.updateElement(newAtom, diffAtom, expectIndex, diffIndex);
1389
+ commit = updateElement(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context, parentComponent);
1462
1390
  }
1463
1391
  else if (newAtom.jsxNode instanceof JSXText) {
1464
- changeCommits.updateText(newAtom, diffAtom);
1392
+ commit = updateText(newAtom, diffAtom, nativeRenderer, context);
1465
1393
  }
1466
1394
  else {
1467
- changeCommits.updateComponent(newAtom, diffAtom, expectIndex, diffIndex);
1395
+ commit = updateComponent(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context);
1468
1396
  }
1397
+ commits.push(commit);
1469
1398
  const next = diffAtomIndexed.next;
1470
1399
  const prev = diffAtomIndexed.prev;
1471
1400
  if (!prev) {
@@ -1483,9 +1412,86 @@ function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1483
1412
  }
1484
1413
  diffAtomIndexed = diffAtomIndexed.next;
1485
1414
  }
1486
- changeCommits.create(newAtom);
1415
+ commits.push(createNewView(newAtom, nativeRenderer, context, parentComponent, effect));
1487
1416
  return startDiffAtom;
1488
1417
  }
1418
+ function createNewView(start, nativeRenderer, context, parentComponent, effect) {
1419
+ return function () {
1420
+ buildView(nativeRenderer, parentComponent, start, context);
1421
+ effect();
1422
+ };
1423
+ }
1424
+ function updateText(newAtom, oldAtom, nativeRenderer, context) {
1425
+ return function () {
1426
+ const nativeNode = oldAtom.nativeNode;
1427
+ if (newAtom.jsxNode.text !== oldAtom.jsxNode.text) {
1428
+ nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode.text, newAtom.isSvg);
1429
+ }
1430
+ newAtom.nativeNode = nativeNode;
1431
+ context.host = nativeNode;
1432
+ context.isParent = false;
1433
+ };
1434
+ }
1435
+ function updateElement(newAtom, oldAtom, expectIndex, oldIndex, nativeRenderer, context, parentComponent) {
1436
+ return function (offset) {
1437
+ newAtom.nativeNode = oldAtom.nativeNode;
1438
+ const host = context.host;
1439
+ if (expectIndex - offset !== oldIndex) {
1440
+ if (context.isParent) {
1441
+ nativeRenderer.prependChild(host, newAtom.nativeNode, newAtom.isSvg);
1442
+ }
1443
+ else {
1444
+ nativeRenderer.insertAfter(newAtom.nativeNode, host, newAtom.isSvg);
1445
+ }
1446
+ }
1447
+ context.host = newAtom.nativeNode;
1448
+ context.isParent = false;
1449
+ const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode, newAtom.isSvg);
1450
+ if (newAtom.child) {
1451
+ diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1452
+ host: newAtom.nativeNode,
1453
+ isParent: true
1454
+ }, 0, 0);
1455
+ }
1456
+ else if (oldAtom.child) {
1457
+ let atom = oldAtom.child;
1458
+ while (atom) {
1459
+ cleanView(nativeRenderer, atom, false);
1460
+ atom = atom.sibling;
1461
+ }
1462
+ }
1463
+ applyRefs();
1464
+ };
1465
+ }
1466
+ function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRenderer, context) {
1467
+ return function (offset) {
1468
+ const instance = reusedAtom.jsxNode;
1469
+ const newProps = newAtom.jsxNode.props;
1470
+ const oldTemplate = instance.template;
1471
+ const newTemplate = instance.update(newProps);
1472
+ instance.$$view = Object.assign({ atom: newAtom }, context);
1473
+ newAtom.jsxNode = instance;
1474
+ if (newTemplate === oldTemplate) {
1475
+ reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex - offset !== oldIndex);
1476
+ updateView(nativeRenderer, instance);
1477
+ return;
1478
+ }
1479
+ if (newTemplate) {
1480
+ linkTemplate(newTemplate, newAtom.jsxNode, newAtom);
1481
+ }
1482
+ if (newAtom.child) {
1483
+ diff(nativeRenderer, instance, newAtom.child, reusedAtom.child, context, expectIndex, oldIndex);
1484
+ }
1485
+ else if (reusedAtom.child) {
1486
+ let atom = reusedAtom.child;
1487
+ while (atom) {
1488
+ cleanView(nativeRenderer, atom, false);
1489
+ atom = atom.sibling;
1490
+ }
1491
+ }
1492
+ instance.rendered();
1493
+ };
1494
+ }
1489
1495
  function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveView) {
1490
1496
  let child = reusedAtom.child;
1491
1497
  newAtom.child = child;
@@ -1553,9 +1559,9 @@ function componentRender(nativeRenderer, component, from, context) {
1553
1559
  }
1554
1560
  component.rendered();
1555
1561
  }
1556
- function createChainByComponentFactory(jsxComponent, parent, isSvg) {
1562
+ function createChainByJSXComponentOrJSXText(jsxNode, parent, isSvg) {
1557
1563
  return {
1558
- jsxNode: jsxComponent,
1564
+ jsxNode,
1559
1565
  parent,
1560
1566
  sibling: null,
1561
1567
  child: null,
@@ -1580,16 +1586,6 @@ function createChainByJSXElement(component, element, parent, isSvg) {
1580
1586
  }
1581
1587
  return atom;
1582
1588
  }
1583
- function createChainByJSXText(node, parent, isSvg) {
1584
- return {
1585
- jsxNode: node,
1586
- parent,
1587
- sibling: null,
1588
- child: null,
1589
- nativeNode: null,
1590
- isSvg
1591
- };
1592
- }
1593
1589
  function createChainByChildren(component, children, parent, atoms, isSvg) {
1594
1590
  for (const item of children) {
1595
1591
  if (item !== null && typeof item !== 'undefined' && typeof item !== 'boolean') {
@@ -1597,20 +1593,20 @@ function createChainByChildren(component, children, parent, atoms, isSvg) {
1597
1593
  atoms.push(createChainByJSXElement(component, item, parent, isSvg));
1598
1594
  continue;
1599
1595
  }
1600
- if (item instanceof JSXComponent) {
1601
- const childAtom = createChainByComponentFactory(item, parent, isSvg);
1602
- atoms.push(childAtom);
1603
- continue;
1604
- }
1605
1596
  if (typeof item === 'string' && item.length) {
1606
- atoms.push(createChainByJSXText(new JSXText(item), parent, isSvg));
1597
+ atoms.push(createChainByJSXComponentOrJSXText(new JSXText(item), parent, isSvg));
1607
1598
  continue;
1608
1599
  }
1609
1600
  if (Array.isArray(item)) {
1610
1601
  createChainByChildren(component, item, parent, atoms, isSvg);
1611
1602
  continue;
1612
1603
  }
1613
- atoms.push(createChainByJSXText(new JSXText(String(item)), parent, isSvg));
1604
+ if (item instanceof JSXComponent) {
1605
+ const childAtom = createChainByJSXComponentOrJSXText(item, parent, isSvg);
1606
+ atoms.push(childAtom);
1607
+ continue;
1608
+ }
1609
+ atoms.push(createChainByJSXComponentOrJSXText(new JSXText(String(item)), parent, isSvg));
1614
1610
  }
1615
1611
  }
1616
1612
  return atoms;
@@ -1631,8 +1627,7 @@ function createElement(nativeRenderer, vNode, isSvg) {
1631
1627
  const nativeNode = nativeRenderer.createElement(vNode.type, isSvg);
1632
1628
  const props = vNode.props;
1633
1629
  let bindingRefs;
1634
- const keys = Object.keys(props);
1635
- for (const key of keys) {
1630
+ for (const key in props) {
1636
1631
  if (key === 'children') {
1637
1632
  continue;
1638
1633
  }
@@ -1645,9 +1640,9 @@ function createElement(nativeRenderer, vNode, isSvg) {
1645
1640
  }
1646
1641
  if (key === 'style') {
1647
1642
  const style = styleToObject(props.style);
1648
- Object.keys(style).forEach(key => {
1643
+ for (const key in style) {
1649
1644
  nativeRenderer.setStyle(nativeNode, key, style[key], isSvg);
1650
- });
1645
+ }
1651
1646
  continue;
1652
1647
  }
1653
1648
  if (/^on[A-Z]/.test(key)) {
@@ -1687,9 +1682,9 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1687
1682
  continue;
1688
1683
  }
1689
1684
  if (key === 'style') {
1690
- Object.keys(styleToObject(value)).forEach(styleName => {
1685
+ for (const styleName in styleToObject(value)) {
1691
1686
  nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
1692
- });
1687
+ }
1693
1688
  continue;
1694
1689
  }
1695
1690
  if (/^on[A-Z]/.test(key)) {
@@ -1751,9 +1746,9 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1751
1746
  }
1752
1747
  if (key === 'style') {
1753
1748
  const styleObj = styleToObject(value);
1754
- Object.keys(styleObj).forEach(styleName => {
1749
+ for (const styleName in styleObj) {
1755
1750
  nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
1756
- });
1751
+ }
1757
1752
  continue;
1758
1753
  }
1759
1754
  if (/^on[A-Z]/.test(key)) {
@@ -1787,61 +1782,65 @@ function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn, isSvg) {
1787
1782
  vNode.on = on = {};
1788
1783
  }
1789
1784
  const type = key.replace(/^on/, '').toLowerCase();
1790
- const delegate = function (...args) {
1791
- return delegateObj.listenFn.apply(this, args);
1792
- };
1793
1785
  const delegateObj = {
1794
- delegate,
1786
+ delegate(...args) {
1787
+ return delegateObj.listenFn.apply(this, args);
1788
+ },
1795
1789
  listenFn
1796
1790
  };
1797
1791
  on[type] = delegateObj;
1798
- nativeRenderer.listen(nativeNode, type, delegate, isSvg);
1792
+ nativeRenderer.listen(nativeNode, type, delegateObj.delegate, isSvg);
1799
1793
  }
1800
1794
 
1801
1795
  /**
1802
1796
  * Viewfly 根组件,用于实现组件状态更新事件通知
1803
1797
  */
1804
1798
  class RootComponent extends Component {
1805
- constructor(parentInjector, factory) {
1799
+ constructor(parentInjector, factory, refresh) {
1806
1800
  super(parentInjector, factory, {});
1807
- this.onChange = null;
1801
+ this.refresh = refresh;
1808
1802
  }
1809
1803
  markAsChanged(changedComponent) {
1810
- var _a;
1811
1804
  this._changed = true;
1812
1805
  if (changedComponent) {
1813
1806
  this.changedSubComponents.add(changedComponent);
1814
1807
  }
1815
- (_a = this.onChange) === null || _a === void 0 ? void 0 : _a.call(this);
1808
+ this.refresh();
1816
1809
  }
1817
1810
  }
1818
1811
 
1819
1812
  const viewflyErrorFn = makeError('Viewfly');
1820
- const VERSION = "0.3.1";
1821
1813
  function viewfly(config) {
1822
1814
  const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
1823
1815
  const appProviders = [];
1824
1816
  const modules = [];
1825
1817
  let destroyed = false;
1818
+ let appHost = null;
1826
1819
  const rootComponent = new RootComponent(context || null, () => {
1827
1820
  provide(appProviders);
1828
1821
  return () => {
1829
1822
  return destroyed ? null : root;
1830
1823
  };
1824
+ }, function () {
1825
+ if (destroyed) {
1826
+ return;
1827
+ }
1828
+ nextTick(() => {
1829
+ render(appHost);
1830
+ });
1831
1831
  });
1832
- const render = createRenderer(rootComponent, nativeRenderer, VERSION);
1832
+ const render = createRenderer(rootComponent, nativeRenderer);
1833
1833
  let isStarted = false;
1834
1834
  let task = null;
1835
1835
  function nextTick(callback) {
1836
1836
  if (task !== null) {
1837
1837
  return;
1838
1838
  }
1839
- task = setTimeout(() => {
1839
+ task = Promise.resolve().then(() => {
1840
1840
  task = null;
1841
1841
  callback();
1842
1842
  });
1843
1843
  }
1844
- let appHost = null;
1845
1844
  const app = {
1846
1845
  provide(providers) {
1847
1846
  if (Array.isArray(providers)) {
@@ -1878,15 +1877,6 @@ function viewfly(config) {
1878
1877
  if (!autoUpdate) {
1879
1878
  return app;
1880
1879
  }
1881
- const refresh = () => {
1882
- if (destroyed) {
1883
- return;
1884
- }
1885
- render(host);
1886
- };
1887
- rootComponent.onChange = function () {
1888
- nextTick(refresh);
1889
- };
1890
1880
  return app;
1891
1881
  },
1892
1882
  render() {
@@ -1930,7 +1920,6 @@ exports.Self = Self;
1930
1920
  exports.SkipSelf = SkipSelf;
1931
1921
  exports.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
1932
1922
  exports.Type = Type;
1933
- exports.VERSION = VERSION;
1934
1923
  exports.createRenderer = createRenderer;
1935
1924
  exports.forwardRef = forwardRef;
1936
1925
  exports.getCurrentInstance = getCurrentInstance;
@@ -1,7 +1,6 @@
1
1
  import type { Provider } from './di/_api';
2
2
  import { JSXInternal, NativeNode, NativeRenderer } from './foundation/_api';
3
3
  import { Injector } from './di/_api';
4
- export declare const VERSION: string;
5
4
  /**
6
5
  * Viewfly 配置项
7
6
  */
@@ -17,7 +16,7 @@ export interface Config {
17
16
  }
18
17
  export interface Application<T extends NativeNode = NativeNode> {
19
18
  provide(providers: Provider | Provider[]): Application<T>;
20
- mount(host: T, autoUpdate?: boolean): Application<T>;
19
+ mount(host: T): Application<T>;
21
20
  use(module: Module | Module[]): Application<T>;
22
21
  render(): Application<T>;
23
22
  destroy(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viewfly/core",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Viewfly is a simple and easy-to-use JavaScript framework with an intuitive development experience.",
5
5
  "main": "./bundles/index.js",
6
6
  "module": "./bundles/index.esm.js",
@@ -47,7 +47,7 @@
47
47
  "bugs": {
48
48
  "url": "https://github.com/viewfly/viewfly.git/issues"
49
49
  },
50
- "gitHead": "b66ca589f7662cd518fc2e5955b3e3ff9de83f94",
50
+ "gitHead": "d14b3cd0247a07f72519745933c3070f12adbfa1",
51
51
  "dependencies": {
52
52
  "reflect-metadata": "^0.1.13"
53
53
  }