@viewfly/core 0.3.0 → 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
  }
@@ -1,3 +1,5 @@
1
+ import 'reflect-metadata';
2
+
1
3
  class ForwardRef {
2
4
  constructor(forwardRefFn) {
3
5
  this.forwardRefFn = forwardRefFn;
@@ -549,22 +551,22 @@ function getObjectChanges(newProps, oldProps) {
549
551
  add: [],
550
552
  replace: []
551
553
  };
552
- Object.keys(newProps).forEach(key => {
554
+ for (const key in newProps) {
553
555
  const leftValue = newProps[key];
554
556
  const rightValue = oldProps[key];
555
557
  if (Reflect.has(oldProps, key)) {
556
558
  if (leftValue !== rightValue) {
557
559
  changes.replace.push([key, leftValue, rightValue]);
558
560
  }
559
- return;
561
+ continue;
560
562
  }
561
563
  changes.add.push([key, leftValue]);
562
- });
563
- Object.keys(oldProps).forEach(key => {
564
+ }
565
+ for (const key in oldProps) {
564
566
  if (!Reflect.has(newProps, key)) {
565
567
  changes.remove.push([key, oldProps[key]]);
566
568
  }
567
- });
569
+ }
568
570
  return changes;
569
571
  }
570
572
  function getArrayChanges(left, right) {
@@ -1213,11 +1215,10 @@ function withMemo(canUseMemo, render) {
1213
1215
  };
1214
1216
  }
1215
1217
 
1216
- function createRenderer(component, nativeRenderer, version) {
1218
+ function createRenderer(component, nativeRenderer) {
1217
1219
  let isInit = true;
1218
1220
  return function render(host) {
1219
1221
  if (isInit) {
1220
- nativeRenderer.setProperty(host, 'viewfly-version', version, false);
1221
1222
  isInit = false;
1222
1223
  const atom = {
1223
1224
  jsxNode: component,
@@ -1337,87 +1338,11 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1337
1338
  }
1338
1339
  }
1339
1340
  const commits = [];
1340
- const changeCommits = {
1341
- updateComponent: (newAtom, reusedAtom, expectIndex, oldIndex) => {
1342
- commits.push((offset) => {
1343
- const instance = reusedAtom.jsxNode;
1344
- const newProps = newAtom.jsxNode.props;
1345
- const oldTemplate = instance.template;
1346
- const newTemplate = instance.update(newProps);
1347
- instance.$$view = Object.assign({ atom: newAtom }, context);
1348
- newAtom.jsxNode = instance;
1349
- if (newTemplate === oldTemplate) {
1350
- reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex - offset !== oldIndex);
1351
- updateView(nativeRenderer, instance);
1352
- return;
1353
- }
1354
- if (newTemplate) {
1355
- linkTemplate(newTemplate, newAtom.jsxNode, newAtom);
1356
- }
1357
- if (newAtom.child) {
1358
- diff(nativeRenderer, instance, newAtom.child, reusedAtom.child, context, expectIndex, oldIndex);
1359
- }
1360
- else if (reusedAtom.child) {
1361
- let atom = reusedAtom.child;
1362
- while (atom) {
1363
- cleanView(nativeRenderer, atom, false);
1364
- atom = atom.sibling;
1365
- }
1366
- }
1367
- instance.rendered();
1368
- });
1369
- },
1370
- updateElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
1371
- commits.push((offset) => {
1372
- newAtom.nativeNode = oldAtom.nativeNode;
1373
- const host = context.host;
1374
- if (expectIndex - offset !== oldIndex) {
1375
- if (context.isParent) {
1376
- nativeRenderer.prependChild(host, newAtom.nativeNode, newAtom.isSvg);
1377
- }
1378
- else {
1379
- nativeRenderer.insertAfter(newAtom.nativeNode, host, newAtom.isSvg);
1380
- }
1381
- }
1382
- context.host = newAtom.nativeNode;
1383
- context.isParent = false;
1384
- const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode, newAtom.isSvg);
1385
- if (newAtom.child) {
1386
- diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1387
- host: newAtom.nativeNode,
1388
- isParent: true
1389
- }, 0, 0);
1390
- }
1391
- else if (oldAtom.child) {
1392
- let atom = oldAtom.child;
1393
- while (atom) {
1394
- cleanView(nativeRenderer, atom, false);
1395
- atom = atom.sibling;
1396
- }
1397
- }
1398
- applyRefs();
1399
- });
1400
- },
1401
- updateText: (newAtom, oldAtom) => {
1402
- commits.push(() => {
1403
- const nativeNode = oldAtom.nativeNode;
1404
- if (newAtom.jsxNode.text !== oldAtom.jsxNode.text) {
1405
- nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode.text, newAtom.isSvg);
1406
- }
1407
- newAtom.nativeNode = nativeNode;
1408
- context.host = nativeNode;
1409
- context.isParent = false;
1410
- });
1411
- },
1412
- create: (start) => {
1413
- commits.push(() => {
1414
- buildView(nativeRenderer, parentComponent, start, context);
1415
- offset++;
1416
- });
1417
- }
1418
- };
1341
+ function changeOffset() {
1342
+ offset++;
1343
+ }
1419
1344
  while (newAtom) {
1420
- firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, changeCommits);
1345
+ firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, nativeRenderer, commits, context, parentComponent, changeOffset);
1421
1346
  newAtom = newAtom.sibling;
1422
1347
  expectIndex++;
1423
1348
  }
@@ -1440,28 +1365,34 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1440
1365
  commit(offset);
1441
1366
  }
1442
1367
  }
1443
- function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1368
+ function createChanges(newAtom, expectIndex, diffAtomIndexed, nativeRenderer, commits, context, parentComponent, effect) {
1444
1369
  const startDiffAtom = diffAtomIndexed;
1370
+ const key = newAtom.jsxNode.key;
1445
1371
  while (diffAtomIndexed) {
1446
1372
  const { atom: diffAtom, index: diffIndex } = diffAtomIndexed;
1447
- const key = newAtom.jsxNode.key;
1448
1373
  const diffKey = diffAtom.jsxNode.key;
1449
- if (key !== undefined && diffKey !== undefined) {
1374
+ if (key !== undefined) {
1450
1375
  if (diffKey !== key) {
1451
1376
  diffAtomIndexed = diffAtomIndexed.next;
1452
1377
  continue;
1453
1378
  }
1454
1379
  }
1380
+ else if (diffKey !== undefined) {
1381
+ diffAtomIndexed = diffAtomIndexed.next;
1382
+ continue;
1383
+ }
1455
1384
  if (newAtom.jsxNode.$$typeOf === diffAtom.jsxNode.$$typeOf) {
1385
+ let commit;
1456
1386
  if (newAtom.jsxNode instanceof JSXElement) {
1457
- changeCommits.updateElement(newAtom, diffAtom, expectIndex, diffIndex);
1387
+ commit = updateElement(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context, parentComponent);
1458
1388
  }
1459
1389
  else if (newAtom.jsxNode instanceof JSXText) {
1460
- changeCommits.updateText(newAtom, diffAtom);
1390
+ commit = updateText(newAtom, diffAtom, nativeRenderer, context);
1461
1391
  }
1462
1392
  else {
1463
- changeCommits.updateComponent(newAtom, diffAtom, expectIndex, diffIndex);
1393
+ commit = updateComponent(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context);
1464
1394
  }
1395
+ commits.push(commit);
1465
1396
  const next = diffAtomIndexed.next;
1466
1397
  const prev = diffAtomIndexed.prev;
1467
1398
  if (!prev) {
@@ -1479,9 +1410,86 @@ function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1479
1410
  }
1480
1411
  diffAtomIndexed = diffAtomIndexed.next;
1481
1412
  }
1482
- changeCommits.create(newAtom);
1413
+ commits.push(createNewView(newAtom, nativeRenderer, context, parentComponent, effect));
1483
1414
  return startDiffAtom;
1484
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
+ }
1485
1493
  function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveView) {
1486
1494
  let child = reusedAtom.child;
1487
1495
  newAtom.child = child;
@@ -1549,9 +1557,9 @@ function componentRender(nativeRenderer, component, from, context) {
1549
1557
  }
1550
1558
  component.rendered();
1551
1559
  }
1552
- function createChainByComponentFactory(jsxComponent, parent, isSvg) {
1560
+ function createChainByJSXComponentOrJSXText(jsxNode, parent, isSvg) {
1553
1561
  return {
1554
- jsxNode: jsxComponent,
1562
+ jsxNode,
1555
1563
  parent,
1556
1564
  sibling: null,
1557
1565
  child: null,
@@ -1576,16 +1584,6 @@ function createChainByJSXElement(component, element, parent, isSvg) {
1576
1584
  }
1577
1585
  return atom;
1578
1586
  }
1579
- function createChainByJSXText(node, parent, isSvg) {
1580
- return {
1581
- jsxNode: node,
1582
- parent,
1583
- sibling: null,
1584
- child: null,
1585
- nativeNode: null,
1586
- isSvg
1587
- };
1588
- }
1589
1587
  function createChainByChildren(component, children, parent, atoms, isSvg) {
1590
1588
  for (const item of children) {
1591
1589
  if (item !== null && typeof item !== 'undefined' && typeof item !== 'boolean') {
@@ -1593,20 +1591,20 @@ function createChainByChildren(component, children, parent, atoms, isSvg) {
1593
1591
  atoms.push(createChainByJSXElement(component, item, parent, isSvg));
1594
1592
  continue;
1595
1593
  }
1596
- if (item instanceof JSXComponent) {
1597
- const childAtom = createChainByComponentFactory(item, parent, isSvg);
1598
- atoms.push(childAtom);
1599
- continue;
1600
- }
1601
1594
  if (typeof item === 'string' && item.length) {
1602
- atoms.push(createChainByJSXText(new JSXText(item), parent, isSvg));
1595
+ atoms.push(createChainByJSXComponentOrJSXText(new JSXText(item), parent, isSvg));
1603
1596
  continue;
1604
1597
  }
1605
1598
  if (Array.isArray(item)) {
1606
1599
  createChainByChildren(component, item, parent, atoms, isSvg);
1607
1600
  continue;
1608
1601
  }
1609
- 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));
1610
1608
  }
1611
1609
  }
1612
1610
  return atoms;
@@ -1627,8 +1625,7 @@ function createElement(nativeRenderer, vNode, isSvg) {
1627
1625
  const nativeNode = nativeRenderer.createElement(vNode.type, isSvg);
1628
1626
  const props = vNode.props;
1629
1627
  let bindingRefs;
1630
- const keys = Object.keys(props);
1631
- for (const key of keys) {
1628
+ for (const key in props) {
1632
1629
  if (key === 'children') {
1633
1630
  continue;
1634
1631
  }
@@ -1641,9 +1638,9 @@ function createElement(nativeRenderer, vNode, isSvg) {
1641
1638
  }
1642
1639
  if (key === 'style') {
1643
1640
  const style = styleToObject(props.style);
1644
- Object.keys(style).forEach(key => {
1641
+ for (const key in style) {
1645
1642
  nativeRenderer.setStyle(nativeNode, key, style[key], isSvg);
1646
- });
1643
+ }
1647
1644
  continue;
1648
1645
  }
1649
1646
  if (/^on[A-Z]/.test(key)) {
@@ -1683,9 +1680,9 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1683
1680
  continue;
1684
1681
  }
1685
1682
  if (key === 'style') {
1686
- Object.keys(styleToObject(value)).forEach(styleName => {
1683
+ for (const styleName in styleToObject(value)) {
1687
1684
  nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
1688
- });
1685
+ }
1689
1686
  continue;
1690
1687
  }
1691
1688
  if (/^on[A-Z]/.test(key)) {
@@ -1747,9 +1744,9 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1747
1744
  }
1748
1745
  if (key === 'style') {
1749
1746
  const styleObj = styleToObject(value);
1750
- Object.keys(styleObj).forEach(styleName => {
1747
+ for (const styleName in styleObj) {
1751
1748
  nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
1752
- });
1749
+ }
1753
1750
  continue;
1754
1751
  }
1755
1752
  if (/^on[A-Z]/.test(key)) {
@@ -1783,61 +1780,65 @@ function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn, isSvg) {
1783
1780
  vNode.on = on = {};
1784
1781
  }
1785
1782
  const type = key.replace(/^on/, '').toLowerCase();
1786
- const delegate = function (...args) {
1787
- return delegateObj.listenFn.apply(this, args);
1788
- };
1789
1783
  const delegateObj = {
1790
- delegate,
1784
+ delegate(...args) {
1785
+ return delegateObj.listenFn.apply(this, args);
1786
+ },
1791
1787
  listenFn
1792
1788
  };
1793
1789
  on[type] = delegateObj;
1794
- nativeRenderer.listen(nativeNode, type, delegate, isSvg);
1790
+ nativeRenderer.listen(nativeNode, type, delegateObj.delegate, isSvg);
1795
1791
  }
1796
1792
 
1797
1793
  /**
1798
1794
  * Viewfly 根组件,用于实现组件状态更新事件通知
1799
1795
  */
1800
1796
  class RootComponent extends Component {
1801
- constructor(parentInjector, factory) {
1797
+ constructor(parentInjector, factory, refresh) {
1802
1798
  super(parentInjector, factory, {});
1803
- this.onChange = null;
1799
+ this.refresh = refresh;
1804
1800
  }
1805
1801
  markAsChanged(changedComponent) {
1806
- var _a;
1807
1802
  this._changed = true;
1808
1803
  if (changedComponent) {
1809
1804
  this.changedSubComponents.add(changedComponent);
1810
1805
  }
1811
- (_a = this.onChange) === null || _a === void 0 ? void 0 : _a.call(this);
1806
+ this.refresh();
1812
1807
  }
1813
1808
  }
1814
1809
 
1815
1810
  const viewflyErrorFn = makeError('Viewfly');
1816
- const VERSION = "0.3.0";
1817
1811
  function viewfly(config) {
1818
1812
  const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
1819
1813
  const appProviders = [];
1820
1814
  const modules = [];
1821
1815
  let destroyed = false;
1816
+ let appHost = null;
1822
1817
  const rootComponent = new RootComponent(context || null, () => {
1823
1818
  provide(appProviders);
1824
1819
  return () => {
1825
1820
  return destroyed ? null : root;
1826
1821
  };
1822
+ }, function () {
1823
+ if (destroyed) {
1824
+ return;
1825
+ }
1826
+ nextTick(() => {
1827
+ render(appHost);
1828
+ });
1827
1829
  });
1828
- const render = createRenderer(rootComponent, nativeRenderer, VERSION);
1830
+ const render = createRenderer(rootComponent, nativeRenderer);
1829
1831
  let isStarted = false;
1830
1832
  let task = null;
1831
1833
  function nextTick(callback) {
1832
1834
  if (task !== null) {
1833
1835
  return;
1834
1836
  }
1835
- task = setTimeout(() => {
1837
+ task = Promise.resolve().then(() => {
1836
1838
  task = null;
1837
1839
  callback();
1838
1840
  });
1839
1841
  }
1840
- let appHost = null;
1841
1842
  const app = {
1842
1843
  provide(providers) {
1843
1844
  if (Array.isArray(providers)) {
@@ -1874,15 +1875,6 @@ function viewfly(config) {
1874
1875
  if (!autoUpdate) {
1875
1876
  return app;
1876
1877
  }
1877
- const refresh = () => {
1878
- if (destroyed) {
1879
- return;
1880
- }
1881
- render(host);
1882
- };
1883
- rootComponent.onChange = function () {
1884
- nextTick(refresh);
1885
- };
1886
1878
  return app;
1887
1879
  },
1888
1880
  render() {
@@ -1904,4 +1896,4 @@ function viewfly(config) {
1904
1896
  return app;
1905
1897
  }
1906
1898
 
1907
- 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
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ require('reflect-metadata');
4
+
3
5
  class ForwardRef {
4
6
  constructor(forwardRefFn) {
5
7
  this.forwardRefFn = forwardRefFn;
@@ -551,22 +553,22 @@ function getObjectChanges(newProps, oldProps) {
551
553
  add: [],
552
554
  replace: []
553
555
  };
554
- Object.keys(newProps).forEach(key => {
556
+ for (const key in newProps) {
555
557
  const leftValue = newProps[key];
556
558
  const rightValue = oldProps[key];
557
559
  if (Reflect.has(oldProps, key)) {
558
560
  if (leftValue !== rightValue) {
559
561
  changes.replace.push([key, leftValue, rightValue]);
560
562
  }
561
- return;
563
+ continue;
562
564
  }
563
565
  changes.add.push([key, leftValue]);
564
- });
565
- Object.keys(oldProps).forEach(key => {
566
+ }
567
+ for (const key in oldProps) {
566
568
  if (!Reflect.has(newProps, key)) {
567
569
  changes.remove.push([key, oldProps[key]]);
568
570
  }
569
- });
571
+ }
570
572
  return changes;
571
573
  }
572
574
  function getArrayChanges(left, right) {
@@ -1215,11 +1217,10 @@ function withMemo(canUseMemo, render) {
1215
1217
  };
1216
1218
  }
1217
1219
 
1218
- function createRenderer(component, nativeRenderer, version) {
1220
+ function createRenderer(component, nativeRenderer) {
1219
1221
  let isInit = true;
1220
1222
  return function render(host) {
1221
1223
  if (isInit) {
1222
- nativeRenderer.setProperty(host, 'viewfly-version', version, false);
1223
1224
  isInit = false;
1224
1225
  const atom = {
1225
1226
  jsxNode: component,
@@ -1339,87 +1340,11 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1339
1340
  }
1340
1341
  }
1341
1342
  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
- };
1343
+ function changeOffset() {
1344
+ offset++;
1345
+ }
1421
1346
  while (newAtom) {
1422
- firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, changeCommits);
1347
+ firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, nativeRenderer, commits, context, parentComponent, changeOffset);
1423
1348
  newAtom = newAtom.sibling;
1424
1349
  expectIndex++;
1425
1350
  }
@@ -1442,28 +1367,34 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
1442
1367
  commit(offset);
1443
1368
  }
1444
1369
  }
1445
- function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1370
+ function createChanges(newAtom, expectIndex, diffAtomIndexed, nativeRenderer, commits, context, parentComponent, effect) {
1446
1371
  const startDiffAtom = diffAtomIndexed;
1372
+ const key = newAtom.jsxNode.key;
1447
1373
  while (diffAtomIndexed) {
1448
1374
  const { atom: diffAtom, index: diffIndex } = diffAtomIndexed;
1449
- const key = newAtom.jsxNode.key;
1450
1375
  const diffKey = diffAtom.jsxNode.key;
1451
- if (key !== undefined && diffKey !== undefined) {
1376
+ if (key !== undefined) {
1452
1377
  if (diffKey !== key) {
1453
1378
  diffAtomIndexed = diffAtomIndexed.next;
1454
1379
  continue;
1455
1380
  }
1456
1381
  }
1382
+ else if (diffKey !== undefined) {
1383
+ diffAtomIndexed = diffAtomIndexed.next;
1384
+ continue;
1385
+ }
1457
1386
  if (newAtom.jsxNode.$$typeOf === diffAtom.jsxNode.$$typeOf) {
1387
+ let commit;
1458
1388
  if (newAtom.jsxNode instanceof JSXElement) {
1459
- changeCommits.updateElement(newAtom, diffAtom, expectIndex, diffIndex);
1389
+ commit = updateElement(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context, parentComponent);
1460
1390
  }
1461
1391
  else if (newAtom.jsxNode instanceof JSXText) {
1462
- changeCommits.updateText(newAtom, diffAtom);
1392
+ commit = updateText(newAtom, diffAtom, nativeRenderer, context);
1463
1393
  }
1464
1394
  else {
1465
- changeCommits.updateComponent(newAtom, diffAtom, expectIndex, diffIndex);
1395
+ commit = updateComponent(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context);
1466
1396
  }
1397
+ commits.push(commit);
1467
1398
  const next = diffAtomIndexed.next;
1468
1399
  const prev = diffAtomIndexed.prev;
1469
1400
  if (!prev) {
@@ -1481,9 +1412,86 @@ function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
1481
1412
  }
1482
1413
  diffAtomIndexed = diffAtomIndexed.next;
1483
1414
  }
1484
- changeCommits.create(newAtom);
1415
+ commits.push(createNewView(newAtom, nativeRenderer, context, parentComponent, effect));
1485
1416
  return startDiffAtom;
1486
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
+ }
1487
1495
  function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveView) {
1488
1496
  let child = reusedAtom.child;
1489
1497
  newAtom.child = child;
@@ -1551,9 +1559,9 @@ function componentRender(nativeRenderer, component, from, context) {
1551
1559
  }
1552
1560
  component.rendered();
1553
1561
  }
1554
- function createChainByComponentFactory(jsxComponent, parent, isSvg) {
1562
+ function createChainByJSXComponentOrJSXText(jsxNode, parent, isSvg) {
1555
1563
  return {
1556
- jsxNode: jsxComponent,
1564
+ jsxNode,
1557
1565
  parent,
1558
1566
  sibling: null,
1559
1567
  child: null,
@@ -1578,16 +1586,6 @@ function createChainByJSXElement(component, element, parent, isSvg) {
1578
1586
  }
1579
1587
  return atom;
1580
1588
  }
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
1589
  function createChainByChildren(component, children, parent, atoms, isSvg) {
1592
1590
  for (const item of children) {
1593
1591
  if (item !== null && typeof item !== 'undefined' && typeof item !== 'boolean') {
@@ -1595,20 +1593,20 @@ function createChainByChildren(component, children, parent, atoms, isSvg) {
1595
1593
  atoms.push(createChainByJSXElement(component, item, parent, isSvg));
1596
1594
  continue;
1597
1595
  }
1598
- if (item instanceof JSXComponent) {
1599
- const childAtom = createChainByComponentFactory(item, parent, isSvg);
1600
- atoms.push(childAtom);
1601
- continue;
1602
- }
1603
1596
  if (typeof item === 'string' && item.length) {
1604
- atoms.push(createChainByJSXText(new JSXText(item), parent, isSvg));
1597
+ atoms.push(createChainByJSXComponentOrJSXText(new JSXText(item), parent, isSvg));
1605
1598
  continue;
1606
1599
  }
1607
1600
  if (Array.isArray(item)) {
1608
1601
  createChainByChildren(component, item, parent, atoms, isSvg);
1609
1602
  continue;
1610
1603
  }
1611
- 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));
1612
1610
  }
1613
1611
  }
1614
1612
  return atoms;
@@ -1629,8 +1627,7 @@ function createElement(nativeRenderer, vNode, isSvg) {
1629
1627
  const nativeNode = nativeRenderer.createElement(vNode.type, isSvg);
1630
1628
  const props = vNode.props;
1631
1629
  let bindingRefs;
1632
- const keys = Object.keys(props);
1633
- for (const key of keys) {
1630
+ for (const key in props) {
1634
1631
  if (key === 'children') {
1635
1632
  continue;
1636
1633
  }
@@ -1643,9 +1640,9 @@ function createElement(nativeRenderer, vNode, isSvg) {
1643
1640
  }
1644
1641
  if (key === 'style') {
1645
1642
  const style = styleToObject(props.style);
1646
- Object.keys(style).forEach(key => {
1643
+ for (const key in style) {
1647
1644
  nativeRenderer.setStyle(nativeNode, key, style[key], isSvg);
1648
- });
1645
+ }
1649
1646
  continue;
1650
1647
  }
1651
1648
  if (/^on[A-Z]/.test(key)) {
@@ -1685,9 +1682,9 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1685
1682
  continue;
1686
1683
  }
1687
1684
  if (key === 'style') {
1688
- Object.keys(styleToObject(value)).forEach(styleName => {
1685
+ for (const styleName in styleToObject(value)) {
1689
1686
  nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
1690
- });
1687
+ }
1691
1688
  continue;
1692
1689
  }
1693
1690
  if (/^on[A-Z]/.test(key)) {
@@ -1749,9 +1746,9 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1749
1746
  }
1750
1747
  if (key === 'style') {
1751
1748
  const styleObj = styleToObject(value);
1752
- Object.keys(styleObj).forEach(styleName => {
1749
+ for (const styleName in styleObj) {
1753
1750
  nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
1754
- });
1751
+ }
1755
1752
  continue;
1756
1753
  }
1757
1754
  if (/^on[A-Z]/.test(key)) {
@@ -1785,61 +1782,65 @@ function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn, isSvg) {
1785
1782
  vNode.on = on = {};
1786
1783
  }
1787
1784
  const type = key.replace(/^on/, '').toLowerCase();
1788
- const delegate = function (...args) {
1789
- return delegateObj.listenFn.apply(this, args);
1790
- };
1791
1785
  const delegateObj = {
1792
- delegate,
1786
+ delegate(...args) {
1787
+ return delegateObj.listenFn.apply(this, args);
1788
+ },
1793
1789
  listenFn
1794
1790
  };
1795
1791
  on[type] = delegateObj;
1796
- nativeRenderer.listen(nativeNode, type, delegate, isSvg);
1792
+ nativeRenderer.listen(nativeNode, type, delegateObj.delegate, isSvg);
1797
1793
  }
1798
1794
 
1799
1795
  /**
1800
1796
  * Viewfly 根组件,用于实现组件状态更新事件通知
1801
1797
  */
1802
1798
  class RootComponent extends Component {
1803
- constructor(parentInjector, factory) {
1799
+ constructor(parentInjector, factory, refresh) {
1804
1800
  super(parentInjector, factory, {});
1805
- this.onChange = null;
1801
+ this.refresh = refresh;
1806
1802
  }
1807
1803
  markAsChanged(changedComponent) {
1808
- var _a;
1809
1804
  this._changed = true;
1810
1805
  if (changedComponent) {
1811
1806
  this.changedSubComponents.add(changedComponent);
1812
1807
  }
1813
- (_a = this.onChange) === null || _a === void 0 ? void 0 : _a.call(this);
1808
+ this.refresh();
1814
1809
  }
1815
1810
  }
1816
1811
 
1817
1812
  const viewflyErrorFn = makeError('Viewfly');
1818
- const VERSION = "0.3.0";
1819
1813
  function viewfly(config) {
1820
1814
  const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
1821
1815
  const appProviders = [];
1822
1816
  const modules = [];
1823
1817
  let destroyed = false;
1818
+ let appHost = null;
1824
1819
  const rootComponent = new RootComponent(context || null, () => {
1825
1820
  provide(appProviders);
1826
1821
  return () => {
1827
1822
  return destroyed ? null : root;
1828
1823
  };
1824
+ }, function () {
1825
+ if (destroyed) {
1826
+ return;
1827
+ }
1828
+ nextTick(() => {
1829
+ render(appHost);
1830
+ });
1829
1831
  });
1830
- const render = createRenderer(rootComponent, nativeRenderer, VERSION);
1832
+ const render = createRenderer(rootComponent, nativeRenderer);
1831
1833
  let isStarted = false;
1832
1834
  let task = null;
1833
1835
  function nextTick(callback) {
1834
1836
  if (task !== null) {
1835
1837
  return;
1836
1838
  }
1837
- task = setTimeout(() => {
1839
+ task = Promise.resolve().then(() => {
1838
1840
  task = null;
1839
1841
  callback();
1840
1842
  });
1841
1843
  }
1842
- let appHost = null;
1843
1844
  const app = {
1844
1845
  provide(providers) {
1845
1846
  if (Array.isArray(providers)) {
@@ -1876,15 +1877,6 @@ function viewfly(config) {
1876
1877
  if (!autoUpdate) {
1877
1878
  return app;
1878
1879
  }
1879
- const refresh = () => {
1880
- if (destroyed) {
1881
- return;
1882
- }
1883
- render(host);
1884
- };
1885
- rootComponent.onChange = function () {
1886
- nextTick(refresh);
1887
- };
1888
1880
  return app;
1889
1881
  },
1890
1882
  render() {
@@ -1928,7 +1920,6 @@ exports.Self = Self;
1928
1920
  exports.SkipSelf = SkipSelf;
1929
1921
  exports.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
1930
1922
  exports.Type = Type;
1931
- exports.VERSION = VERSION;
1932
1923
  exports.createRenderer = createRenderer;
1933
1924
  exports.forwardRef = forwardRef;
1934
1925
  exports.getCurrentInstance = getCurrentInstance;
@@ -1,3 +1,4 @@
1
+ import 'reflect-metadata';
1
2
  export * from './di/_api';
2
3
  export * from './_utils/make-error';
3
4
  export * from './foundation/_api';
@@ -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.0",
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,5 +47,8 @@
47
47
  "bugs": {
48
48
  "url": "https://github.com/viewfly/viewfly.git/issues"
49
49
  },
50
- "gitHead": "b66ca589f7662cd518fc2e5955b3e3ff9de83f94"
50
+ "gitHead": "d14b3cd0247a07f72519745933c3070f12adbfa1",
51
+ "dependencies": {
52
+ "reflect-metadata": "^0.1.13"
53
+ }
51
54
  }