@viewfly/core 1.1.10 → 1.2.1

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.
@@ -413,19 +413,14 @@ interface ComponentInstance<P> {
413
413
  $useMemo?(currentProps: P, prevProps: P): boolean;
414
414
  }
415
415
  type JSXNode = JSX.Element | JSX.ElementClass | string | number | boolean | null | undefined | Iterable<JSXNode>;
416
- interface ComponentAnnotation {
417
- scope?: Scope;
418
- providers?: Provider[];
419
- }
420
416
  interface ComponentSetup<P = any> {
421
417
  (props: P): (() => JSXNode) | ComponentInstance<P>;
422
- annotation?: ComponentAnnotation;
423
418
  }
424
419
  /**
425
420
  * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
426
421
  */
427
- declare class Component extends ReflectiveInjector {
428
- private readonly parentComponent;
422
+ declare class Component {
423
+ readonly parentComponent: Component | null;
429
424
  readonly type: ComponentSetup;
430
425
  props: Props;
431
426
  readonly key?: Key | undefined;
@@ -444,18 +439,31 @@ declare class Component extends ReflectiveInjector {
444
439
  private isFirstRendering;
445
440
  private refs;
446
441
  private listener;
447
- constructor(parentComponent: Injector | null, type: ComponentSetup, props: Props, key?: Key | undefined);
442
+ constructor(parentComponent: Component | null, type: ComponentSetup, props: Props, key?: Key | undefined);
448
443
  markAsDirtied(): void;
449
444
  markAsChanged(changedComponent?: Component): void;
450
445
  render(update: (template: JSXNode, portalHost?: NativeNode) => void): void;
451
446
  update(newProps: Record<string, any>, updateChildren: (jsxNode: JSXNode) => void, reuseChildren: (skipSubComponentDiff: boolean) => void): void;
452
- provide<T>(providers: Provider<T> | Provider<T>[]): void;
453
447
  destroy(): void;
454
448
  rendered(): void;
455
449
  private invokePropsChangedHooks;
456
450
  private invokeMountHooks;
457
451
  private invokeUpdatedHooks;
458
452
  }
453
+ /**
454
+ * 获取当前组件实例
455
+ */
456
+ declare function getCurrentInstance(): Component;
457
+
458
+ declare function createContext(providers: Provider[], scope?: Scope, parentInjector?: Injector): (props: Props) => () => JSXNode | JSXNode[];
459
+ /**
460
+ * 通过组件上下文获取 IoC 容器内数据的勾子方法
461
+ */
462
+ declare function inject<T extends Type<any> | AbstractType<any> | InjectionToken<any>, U = never>(token: T, notFoundValue?: U, flags?: InjectFlags): ExtractValueType<T> | U;
463
+ interface ComponentAnnotation {
464
+ scope?: Scope;
465
+ providers?: Provider[];
466
+ }
459
467
  /**
460
468
  * 给组件添加注解
461
469
  * @param annotation
@@ -476,15 +484,6 @@ declare class Component extends ReflectiveInjector {
476
484
  * ```
477
485
  */
478
486
  declare function withAnnotation<T extends ComponentSetup>(annotation: ComponentAnnotation, componentSetup: T): T;
479
- /**
480
- * 通过组件上下文获取 IoC 容器内数据的勾子方法
481
- */
482
- declare function inject<T extends Type<any> | AbstractType<any> | InjectionToken<any>, U = never>(token: T, notFoundValue?: U, flags?: InjectFlags): ExtractValueType<T> | U;
483
- /**
484
- * 获取当前组件实例
485
- */
486
- declare function getCurrentInstance(): Component;
487
-
488
487
  interface ContextProps extends Props {
489
488
  providers: Provider[];
490
489
  }
@@ -492,7 +491,10 @@ declare function Context(props: ContextProps): () => ViewFlyNode<string | Compon
492
491
 
493
492
  declare function withMemo<T extends Props = Props>(canUseMemo: ComponentInstance<T>['$useMemo'], render: () => JSXNode): ComponentInstance<T>;
494
493
 
495
- declare const ElementNamespaceMap: Record<string, string>;
494
+ declare const ElementNamespaceMap: {
495
+ readonly svg: "svg";
496
+ readonly math: "mathml";
497
+ };
496
498
  declare function createRenderer(component: Component, nativeRenderer: NativeRenderer, namespace: ElementNamespace): (host: NativeNode) => void;
497
499
 
498
500
  /**
@@ -500,7 +502,7 @@ declare function createRenderer(component: Component, nativeRenderer: NativeRend
500
502
  */
501
503
  declare class RootComponent extends Component {
502
504
  private refresh;
503
- constructor(parentInjector: Injector | null, factory: ComponentSetup, refresh: () => void);
505
+ constructor(factory: ComponentSetup, refresh: () => void);
504
506
  markAsChanged(changedComponent?: Component): void;
505
507
  }
506
508
 
@@ -602,4 +604,4 @@ interface Module {
602
604
  }
603
605
  declare function viewfly<T extends NativeNode>(config: Config): Application<T>;
604
606
 
605
- export { type AbstractInstanceType, type AbstractProvider, type AbstractType, type Application, type Atom, type ClassNames, type ClassProvider, Component, type ComponentAnnotation, type ComponentInstance, type ComponentSetup, type ComponentView, type Config, type ConstructorProvider, Context, type ContextProps, DynamicRef, type ElementNamespace, ElementNamespaceMap, type ExistingProvider, type ExtractInstanceType, type ExtractValueType, type FactoryProvider, ForwardRef, Fragment, Inject, type InjectDecorator, InjectFlags, Injectable, type InjectableDecorator, type InjectableOptions, InjectionToken, Injector, JSX, type JSXNode, JSXNodeFactory, type Key, type LifeCycleCallback, type Module, type NativeNode, NativeRenderer, type NormalizedProvider, NullInjector, Optional, type OptionalDecorator, Prop, type PropDecorator, type Props, type PropsChangedCallback, type ProvideScope, type Provider, type RefListener, type ReflectiveDependency, ReflectiveInjector, RootComponent, Scope, Self, type SelfDecorator, type Signal, SkipSelf, type SkipSelfDecorator, type StaticProvider, StaticRef, THROW_IF_NOT_FOUND, Type, type TypeProvider, type ValueProvider, type ViewFlyNode, type WatchCallback, computed, createDerived, createDynamicRef, createRef, createRenderer, createSignal, forwardRef, getCurrentInstance, getSetupContext, inject, jsx, jsxs, makeError, normalizeProvider, onMounted, onPropsChanged, onUnmounted, onUpdated, viewfly, watch, withAnnotation, withMemo };
607
+ export { type AbstractInstanceType, type AbstractProvider, type AbstractType, type Application, type Atom, type ClassNames, type ClassProvider, Component, type ComponentAnnotation, type ComponentInstance, type ComponentSetup, type ComponentView, type Config, type ConstructorProvider, Context, type ContextProps, DynamicRef, type ElementNamespace, ElementNamespaceMap, type ExistingProvider, type ExtractInstanceType, type ExtractValueType, type FactoryProvider, ForwardRef, Fragment, Inject, type InjectDecorator, InjectFlags, Injectable, type InjectableDecorator, type InjectableOptions, InjectionToken, Injector, JSX, type JSXNode, JSXNodeFactory, type Key, type LifeCycleCallback, type Module, type NativeNode, NativeRenderer, type NormalizedProvider, NullInjector, Optional, type OptionalDecorator, Prop, type PropDecorator, type Props, type PropsChangedCallback, type ProvideScope, type Provider, type RefListener, type ReflectiveDependency, ReflectiveInjector, RootComponent, Scope, Self, type SelfDecorator, type Signal, SkipSelf, type SkipSelfDecorator, type StaticProvider, StaticRef, THROW_IF_NOT_FOUND, Type, type TypeProvider, type ValueProvider, type ViewFlyNode, type WatchCallback, computed, createContext, createDerived, createDynamicRef, createRef, createRenderer, createSignal, forwardRef, getCurrentInstance, getSetupContext, inject, jsx, jsxs, makeError, normalizeProvider, onMounted, onPropsChanged, onUnmounted, onUpdated, viewfly, watch, withAnnotation, withMemo };
@@ -912,7 +912,7 @@ function toRefs(ref) {
912
912
  /**
913
913
  * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
914
914
  */
915
- class Component extends ReflectiveInjector {
915
+ class Component {
916
916
  get dirty() {
917
917
  return this._dirty;
918
918
  }
@@ -920,12 +920,6 @@ class Component extends ReflectiveInjector {
920
920
  return this._changed;
921
921
  }
922
922
  constructor(parentComponent, type, props, key) {
923
- const annotation = type.annotation || {};
924
- const providers = annotation.providers || [];
925
- super(parentComponent, [...providers, {
926
- provide: Injector,
927
- useFactory: () => this
928
- }], annotation.scope);
929
923
  Object.defineProperty(this, "parentComponent", {
930
924
  enumerable: true,
931
925
  configurable: true,
@@ -962,7 +956,6 @@ class Component extends ReflectiveInjector {
962
956
  writable: true,
963
957
  value: new Set()
964
958
  });
965
- // $$view!: ComponentView
966
959
  Object.defineProperty(this, "unmountedCallbacks", {
967
960
  enumerable: true,
968
961
  configurable: true,
@@ -1132,10 +1125,6 @@ class Component extends ReflectiveInjector {
1132
1125
  updateChildren(template);
1133
1126
  this.rendered();
1134
1127
  }
1135
- provide(providers) {
1136
- providers = Array.isArray(providers) ? providers : [providers];
1137
- this.normalizedProviders.unshift(...providers.map(i => normalizeProvider(i)));
1138
- }
1139
1128
  destroy() {
1140
1129
  var _a, _b, _c;
1141
1130
  this.listener.destroy();
@@ -1152,13 +1141,12 @@ class Component extends ReflectiveInjector {
1152
1141
  this.parentComponent.changedSubComponents.delete(this);
1153
1142
  }
1154
1143
  this.parentComponent =
1155
- this.parentInjector =
1156
- this.propsChangedDestroyCallbacks =
1157
- this.updatedDestroyCallbacks =
1158
- this.mountCallbacks =
1159
- this.updatedCallbacks =
1160
- this.propsChangedCallbacks =
1161
- this.unmountedCallbacks = null;
1144
+ this.propsChangedDestroyCallbacks =
1145
+ this.updatedDestroyCallbacks =
1146
+ this.mountCallbacks =
1147
+ this.updatedCallbacks =
1148
+ this.propsChangedCallbacks =
1149
+ this.unmountedCallbacks = null;
1162
1150
  this.changedSubComponents.clear();
1163
1151
  }
1164
1152
  rendered() {
@@ -1235,39 +1223,6 @@ class Component extends ReflectiveInjector {
1235
1223
  }
1236
1224
  }
1237
1225
  }
1238
- /**
1239
- * 给组件添加注解
1240
- * @param annotation
1241
- * @param componentSetup
1242
- * @example
1243
- * ```ts
1244
- * export customScope = new Scope('scopeName')
1245
- * export const App = withAnnotation({
1246
- * scope: customScope,
1247
- * providers: [
1248
- * ExampleService
1249
- * ]
1250
- * }, function(props: Props) {
1251
- * return () => {
1252
- * return <div>...</div>
1253
- * }
1254
- * })
1255
- * ```
1256
- */
1257
- function withAnnotation(annotation, componentSetup) {
1258
- const setup = function setup(props) {
1259
- return componentSetup(props);
1260
- };
1261
- setup.annotation = annotation;
1262
- return setup;
1263
- }
1264
- /**
1265
- * 通过组件上下文获取 IoC 容器内数据的勾子方法
1266
- */
1267
- function inject(token, notFoundValue = THROW_IF_NOT_FOUND, flags) {
1268
- const component = getSetupContext();
1269
- return component.get(token, notFoundValue, flags);
1270
- }
1271
1226
  /**
1272
1227
  * 获取当前组件实例
1273
1228
  */
@@ -1294,6 +1249,63 @@ const JSXNodeFactory = {
1294
1249
  }
1295
1250
  };
1296
1251
 
1252
+ const injectMap = new WeakMap();
1253
+ function getInjector(start) {
1254
+ while (start) {
1255
+ const injector = injectMap.get(start);
1256
+ if (injector) {
1257
+ return injector;
1258
+ }
1259
+ start = start.parentComponent;
1260
+ }
1261
+ return new NullInjector();
1262
+ }
1263
+ function createContext(providers, scope, parentInjector) {
1264
+ return function context(props) {
1265
+ const instance = getCurrentInstance();
1266
+ const injector = new ReflectiveInjector(parentInjector || getInjector(instance), providers, scope);
1267
+ injectMap.set(instance, injector);
1268
+ return () => {
1269
+ return props.children;
1270
+ };
1271
+ };
1272
+ }
1273
+ /**
1274
+ * 通过组件上下文获取 IoC 容器内数据的勾子方法
1275
+ */
1276
+ function inject(token, notFoundValue = THROW_IF_NOT_FOUND, flags) {
1277
+ const component = getCurrentInstance();
1278
+ const injector = getInjector(component);
1279
+ return injector.get(token, notFoundValue, flags);
1280
+ }
1281
+ /**
1282
+ * 给组件添加注解
1283
+ * @param annotation
1284
+ * @param componentSetup
1285
+ * @example
1286
+ * ```ts
1287
+ * export customScope = new Scope('scopeName')
1288
+ * export const App = withAnnotation({
1289
+ * scope: customScope,
1290
+ * providers: [
1291
+ * ExampleService
1292
+ * ]
1293
+ * }, function(props: Props) {
1294
+ * return () => {
1295
+ * return <div>...</div>
1296
+ * }
1297
+ * })
1298
+ * ```
1299
+ */
1300
+ function withAnnotation(annotation, componentSetup) {
1301
+ return function (props) {
1302
+ const instance = getCurrentInstance();
1303
+ const parentInjector = injectMap.get(instance) || getInjector(instance.parentComponent);
1304
+ const injector = new ReflectiveInjector(parentInjector, annotation.providers || [], annotation.scope);
1305
+ injectMap.set(instance, injector);
1306
+ return componentSetup(props);
1307
+ };
1308
+ }
1297
1309
  function Context(props) {
1298
1310
  function createContextComponent(providers) {
1299
1311
  return withAnnotation({
@@ -1408,9 +1420,8 @@ function applyChanges(nativeRenderer, component, atom, context, needMove) {
1408
1420
  view.host = context.host;
1409
1421
  view.isParent = context.isParent;
1410
1422
  }
1411
- }, () => {
1412
- // console.log(skipSubComponentDiff, '----')
1413
- //
1423
+ }, (skipSubComponentDiff) => {
1424
+ reuseComponentView(nativeRenderer, atom, context, needMove, skipSubComponentDiff);
1414
1425
  });
1415
1426
  }
1416
1427
  function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
@@ -1580,27 +1591,31 @@ function cleanElementChildren(atom, nativeRenderer) {
1580
1591
  }
1581
1592
  }
1582
1593
  function cleanView(nativeRenderer, atom, needClean) {
1583
- if (atom.nativeNode) {
1584
- if (needClean) {
1585
- nativeRenderer.remove(atom.nativeNode, atom.namespace);
1586
- needClean = false;
1587
- }
1588
- if (atom.type === ElementAtomType) {
1589
- const ref = atom.jsxNode.props[refKey];
1590
- applyRefs(ref, atom.nativeNode, false);
1594
+ if (atom.type === ComponentAtomType) {
1595
+ const jsxNode = atom.jsxNode;
1596
+ if (jsxNode.instance.$portalHost) {
1597
+ needClean = true;
1591
1598
  }
1599
+ cleanChildren(atom, nativeRenderer, needClean);
1600
+ jsxNode.destroy();
1601
+ return;
1592
1602
  }
1603
+ if (needClean) {
1604
+ nativeRenderer.remove(atom.nativeNode, atom.namespace);
1605
+ needClean = false;
1606
+ }
1607
+ if (atom.type === ElementAtomType) {
1608
+ const ref = atom.jsxNode.props[refKey];
1609
+ applyRefs(ref, atom.nativeNode, false);
1610
+ }
1611
+ cleanChildren(atom, nativeRenderer, needClean);
1612
+ }
1613
+ function cleanChildren(atom, nativeRenderer, needClean) {
1593
1614
  let child = atom.child;
1594
1615
  while (child) {
1595
- if (child.jsxNode instanceof Component && child.jsxNode.instance.$portalHost) {
1596
- needClean = true;
1597
- }
1598
1616
  cleanView(nativeRenderer, child, needClean);
1599
1617
  child = child.sibling;
1600
1618
  }
1601
- if (atom.jsxNode instanceof Component) {
1602
- atom.jsxNode.destroy();
1603
- }
1604
1619
  }
1605
1620
  function componentRender(nativeRenderer, component, from, context) {
1606
1621
  component.render((template, portalHost) => {
@@ -1653,7 +1668,9 @@ function createChainByNode(jsxNode, prevAtom, elementNamespace) {
1653
1668
  return prevAtom;
1654
1669
  }
1655
1670
  function createChainByChildren(children, prevAtom, elementNamespace) {
1656
- for (const item of children) {
1671
+ const len = children.length;
1672
+ for (let i = 0; i < len; i++) {
1673
+ const item = children[i];
1657
1674
  prevAtom = createChainByNode(item, prevAtom, elementNamespace);
1658
1675
  }
1659
1676
  return prevAtom;
@@ -1676,6 +1693,12 @@ function insertNode(nativeRenderer, atom, context) {
1676
1693
  nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.namespace);
1677
1694
  }
1678
1695
  }
1696
+ function createElementChildren(type, children, namespace) {
1697
+ if (type === 'foreignObject' && namespace === ElementNamespaceMap.svg) {
1698
+ return createChildChain(children, void 0);
1699
+ }
1700
+ return createChildChain(children, namespace);
1701
+ }
1679
1702
  function createElement(nativeRenderer, atom, parentComponent, context) {
1680
1703
  const { namespace, jsxNode } = atom;
1681
1704
  const nativeNode = nativeRenderer.createElement(jsxNode.type, namespace);
@@ -1683,7 +1706,7 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
1683
1706
  let bindingRefs;
1684
1707
  for (const key in props) {
1685
1708
  if (key === 'children') {
1686
- atom.child = createChildChain(jsxNode.props.children, namespace);
1709
+ atom.child = createElementChildren(jsxNode.type, props.children, namespace);
1687
1710
  continue;
1688
1711
  }
1689
1712
  if (key === 'class') {
@@ -1745,7 +1768,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1745
1768
  let unBindRefs;
1746
1769
  let bindRefs;
1747
1770
  let updatedChildren = false;
1748
- for (const [key, value] of changes.remove) {
1771
+ let len = changes.remove.length;
1772
+ for (let i = 0; i < len; i++) {
1773
+ const [key, value] = changes.remove[i];
1749
1774
  if (key === 'children') {
1750
1775
  updatedChildren = true;
1751
1776
  cleanElementChildren(oldAtom, nativeRenderer);
@@ -1773,10 +1798,12 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1773
1798
  }
1774
1799
  nativeRenderer.removeProperty(nativeNode, key, isSvg);
1775
1800
  }
1776
- for (const [key, newValue, oldValue] of changes.replace) {
1801
+ len = changes.replace.length;
1802
+ for (let i = 0; i < len; i++) {
1803
+ const [key, newValue, oldValue] = changes.replace[i];
1777
1804
  if (key === 'children') {
1778
1805
  updatedChildren = true;
1779
- newAtom.child = createChildChain(newValue, isSvg);
1806
+ newAtom.child = createElementChildren(newVNode.type, newValue, isSvg);
1780
1807
  if (!newAtom.child) {
1781
1808
  cleanElementChildren(oldAtom, nativeRenderer);
1782
1809
  }
@@ -1818,10 +1845,12 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1818
1845
  }
1819
1846
  nativeRenderer.setProperty(nativeNode, key, newValue, isSvg);
1820
1847
  }
1821
- for (const [key, value] of changes.add) {
1848
+ len = changes.add.length;
1849
+ for (let i = 0; i < len; i++) {
1850
+ const [key, value] = changes.add[i];
1822
1851
  if (key === 'children') {
1823
1852
  updatedChildren = true;
1824
- newAtom.child = createChildChain(value, isSvg);
1853
+ newAtom.child = createElementChildren(newVNode.type, value, isSvg);
1825
1854
  buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
1826
1855
  continue;
1827
1856
  }
@@ -1858,7 +1887,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1858
1887
  function applyRefs(refs, nativeNode, binding) {
1859
1888
  if (refs) {
1860
1889
  const refList = Array.isArray(refs) ? refs : [refs];
1861
- for (const item of refList) {
1890
+ const len = refList.length;
1891
+ for (let i = 0; i < len; i++) {
1892
+ const item = refList[i];
1862
1893
  if (item instanceof DynamicRef) {
1863
1894
  binding ? item.bind(nativeNode) : item.unBind(nativeNode);
1864
1895
  }
@@ -1870,8 +1901,8 @@ function applyRefs(refs, nativeNode, binding) {
1870
1901
  * Viewfly 根组件,用于实现组件状态更新事件通知
1871
1902
  */
1872
1903
  class RootComponent extends Component {
1873
- constructor(parentInjector, factory, refresh) {
1874
- super(parentInjector, factory, {});
1904
+ constructor(factory, refresh) {
1905
+ super(null, factory, {});
1875
1906
  Object.defineProperty(this, "refresh", {
1876
1907
  enumerable: true,
1877
1908
  configurable: true,
@@ -2021,16 +2052,15 @@ function viewfly(config) {
2021
2052
  const modules = [];
2022
2053
  let destroyed = false;
2023
2054
  let appHost = null;
2024
- const rootComponent = new RootComponent(context || null, withAnnotation({
2025
- providers: [{
2026
- provide: NativeRenderer,
2027
- useValue: nativeRenderer
2028
- }]
2029
- }, () => {
2055
+ const rootProviders = [];
2056
+ const rootComponent = new RootComponent(() => {
2057
+ const rootContext = createContext(rootProviders, void 0, context);
2030
2058
  return () => {
2031
- return destroyed ? null : root;
2059
+ return jsx(rootContext, {
2060
+ children: destroyed ? null : root
2061
+ });
2032
2062
  };
2033
- }), function () {
2063
+ }, function () {
2034
2064
  if (destroyed || !autoUpdate) {
2035
2065
  return;
2036
2066
  }
@@ -2052,7 +2082,8 @@ function viewfly(config) {
2052
2082
  }
2053
2083
  const app = {
2054
2084
  provide(providers) {
2055
- rootComponent.provide(providers);
2085
+ providers = Array.isArray(providers) ? providers : [providers];
2086
+ rootProviders.push(...providers);
2056
2087
  return app;
2057
2088
  },
2058
2089
  use(module) {
@@ -2102,4 +2133,4 @@ function viewfly(config) {
2102
2133
  return app;
2103
2134
  }
2104
2135
 
2105
- export { Component, Context, DynamicRef, ElementNamespaceMap, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXNodeFactory, NativeRenderer, NullInjector, Optional, Prop, ReflectiveInjector, RootComponent, Scope, Self, SkipSelf, StaticRef, THROW_IF_NOT_FOUND, Type, computed, createDerived, createDynamicRef, createRef, createRenderer, createSignal, forwardRef, getCurrentInstance, getSetupContext, inject, jsx, jsxs, makeError, normalizeProvider, onMounted, onPropsChanged, onUnmounted, onUpdated, viewfly, watch, withAnnotation, withMemo };
2136
+ export { Component, Context, DynamicRef, ElementNamespaceMap, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXNodeFactory, NativeRenderer, NullInjector, Optional, Prop, ReflectiveInjector, RootComponent, Scope, Self, SkipSelf, StaticRef, THROW_IF_NOT_FOUND, Type, computed, createContext, createDerived, createDynamicRef, createRef, createRenderer, createSignal, forwardRef, getCurrentInstance, getSetupContext, inject, jsx, jsxs, makeError, normalizeProvider, onMounted, onPropsChanged, onUnmounted, onUpdated, viewfly, watch, withAnnotation, withMemo };
package/bundles/index.js CHANGED
@@ -914,7 +914,7 @@ function toRefs(ref) {
914
914
  /**
915
915
  * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
916
916
  */
917
- class Component extends ReflectiveInjector {
917
+ class Component {
918
918
  get dirty() {
919
919
  return this._dirty;
920
920
  }
@@ -922,12 +922,6 @@ class Component extends ReflectiveInjector {
922
922
  return this._changed;
923
923
  }
924
924
  constructor(parentComponent, type, props, key) {
925
- const annotation = type.annotation || {};
926
- const providers = annotation.providers || [];
927
- super(parentComponent, [...providers, {
928
- provide: Injector,
929
- useFactory: () => this
930
- }], annotation.scope);
931
925
  Object.defineProperty(this, "parentComponent", {
932
926
  enumerable: true,
933
927
  configurable: true,
@@ -964,7 +958,6 @@ class Component extends ReflectiveInjector {
964
958
  writable: true,
965
959
  value: new Set()
966
960
  });
967
- // $$view!: ComponentView
968
961
  Object.defineProperty(this, "unmountedCallbacks", {
969
962
  enumerable: true,
970
963
  configurable: true,
@@ -1134,10 +1127,6 @@ class Component extends ReflectiveInjector {
1134
1127
  updateChildren(template);
1135
1128
  this.rendered();
1136
1129
  }
1137
- provide(providers) {
1138
- providers = Array.isArray(providers) ? providers : [providers];
1139
- this.normalizedProviders.unshift(...providers.map(i => normalizeProvider(i)));
1140
- }
1141
1130
  destroy() {
1142
1131
  var _a, _b, _c;
1143
1132
  this.listener.destroy();
@@ -1154,13 +1143,12 @@ class Component extends ReflectiveInjector {
1154
1143
  this.parentComponent.changedSubComponents.delete(this);
1155
1144
  }
1156
1145
  this.parentComponent =
1157
- this.parentInjector =
1158
- this.propsChangedDestroyCallbacks =
1159
- this.updatedDestroyCallbacks =
1160
- this.mountCallbacks =
1161
- this.updatedCallbacks =
1162
- this.propsChangedCallbacks =
1163
- this.unmountedCallbacks = null;
1146
+ this.propsChangedDestroyCallbacks =
1147
+ this.updatedDestroyCallbacks =
1148
+ this.mountCallbacks =
1149
+ this.updatedCallbacks =
1150
+ this.propsChangedCallbacks =
1151
+ this.unmountedCallbacks = null;
1164
1152
  this.changedSubComponents.clear();
1165
1153
  }
1166
1154
  rendered() {
@@ -1237,39 +1225,6 @@ class Component extends ReflectiveInjector {
1237
1225
  }
1238
1226
  }
1239
1227
  }
1240
- /**
1241
- * 给组件添加注解
1242
- * @param annotation
1243
- * @param componentSetup
1244
- * @example
1245
- * ```ts
1246
- * export customScope = new Scope('scopeName')
1247
- * export const App = withAnnotation({
1248
- * scope: customScope,
1249
- * providers: [
1250
- * ExampleService
1251
- * ]
1252
- * }, function(props: Props) {
1253
- * return () => {
1254
- * return <div>...</div>
1255
- * }
1256
- * })
1257
- * ```
1258
- */
1259
- function withAnnotation(annotation, componentSetup) {
1260
- const setup = function setup(props) {
1261
- return componentSetup(props);
1262
- };
1263
- setup.annotation = annotation;
1264
- return setup;
1265
- }
1266
- /**
1267
- * 通过组件上下文获取 IoC 容器内数据的勾子方法
1268
- */
1269
- function inject(token, notFoundValue = THROW_IF_NOT_FOUND, flags) {
1270
- const component = getSetupContext();
1271
- return component.get(token, notFoundValue, flags);
1272
- }
1273
1228
  /**
1274
1229
  * 获取当前组件实例
1275
1230
  */
@@ -1296,6 +1251,63 @@ const JSXNodeFactory = {
1296
1251
  }
1297
1252
  };
1298
1253
 
1254
+ const injectMap = new WeakMap();
1255
+ function getInjector(start) {
1256
+ while (start) {
1257
+ const injector = injectMap.get(start);
1258
+ if (injector) {
1259
+ return injector;
1260
+ }
1261
+ start = start.parentComponent;
1262
+ }
1263
+ return new NullInjector();
1264
+ }
1265
+ function createContext(providers, scope, parentInjector) {
1266
+ return function context(props) {
1267
+ const instance = getCurrentInstance();
1268
+ const injector = new ReflectiveInjector(parentInjector || getInjector(instance), providers, scope);
1269
+ injectMap.set(instance, injector);
1270
+ return () => {
1271
+ return props.children;
1272
+ };
1273
+ };
1274
+ }
1275
+ /**
1276
+ * 通过组件上下文获取 IoC 容器内数据的勾子方法
1277
+ */
1278
+ function inject(token, notFoundValue = THROW_IF_NOT_FOUND, flags) {
1279
+ const component = getCurrentInstance();
1280
+ const injector = getInjector(component);
1281
+ return injector.get(token, notFoundValue, flags);
1282
+ }
1283
+ /**
1284
+ * 给组件添加注解
1285
+ * @param annotation
1286
+ * @param componentSetup
1287
+ * @example
1288
+ * ```ts
1289
+ * export customScope = new Scope('scopeName')
1290
+ * export const App = withAnnotation({
1291
+ * scope: customScope,
1292
+ * providers: [
1293
+ * ExampleService
1294
+ * ]
1295
+ * }, function(props: Props) {
1296
+ * return () => {
1297
+ * return <div>...</div>
1298
+ * }
1299
+ * })
1300
+ * ```
1301
+ */
1302
+ function withAnnotation(annotation, componentSetup) {
1303
+ return function (props) {
1304
+ const instance = getCurrentInstance();
1305
+ const parentInjector = injectMap.get(instance) || getInjector(instance.parentComponent);
1306
+ const injector = new ReflectiveInjector(parentInjector, annotation.providers || [], annotation.scope);
1307
+ injectMap.set(instance, injector);
1308
+ return componentSetup(props);
1309
+ };
1310
+ }
1299
1311
  function Context(props) {
1300
1312
  function createContextComponent(providers) {
1301
1313
  return withAnnotation({
@@ -1410,9 +1422,8 @@ function applyChanges(nativeRenderer, component, atom, context, needMove) {
1410
1422
  view.host = context.host;
1411
1423
  view.isParent = context.isParent;
1412
1424
  }
1413
- }, () => {
1414
- // console.log(skipSubComponentDiff, '----')
1415
- //
1425
+ }, (skipSubComponentDiff) => {
1426
+ reuseComponentView(nativeRenderer, atom, context, needMove, skipSubComponentDiff);
1416
1427
  });
1417
1428
  }
1418
1429
  function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
@@ -1582,27 +1593,31 @@ function cleanElementChildren(atom, nativeRenderer) {
1582
1593
  }
1583
1594
  }
1584
1595
  function cleanView(nativeRenderer, atom, needClean) {
1585
- if (atom.nativeNode) {
1586
- if (needClean) {
1587
- nativeRenderer.remove(atom.nativeNode, atom.namespace);
1588
- needClean = false;
1589
- }
1590
- if (atom.type === ElementAtomType) {
1591
- const ref = atom.jsxNode.props[refKey];
1592
- applyRefs(ref, atom.nativeNode, false);
1596
+ if (atom.type === ComponentAtomType) {
1597
+ const jsxNode = atom.jsxNode;
1598
+ if (jsxNode.instance.$portalHost) {
1599
+ needClean = true;
1593
1600
  }
1601
+ cleanChildren(atom, nativeRenderer, needClean);
1602
+ jsxNode.destroy();
1603
+ return;
1594
1604
  }
1605
+ if (needClean) {
1606
+ nativeRenderer.remove(atom.nativeNode, atom.namespace);
1607
+ needClean = false;
1608
+ }
1609
+ if (atom.type === ElementAtomType) {
1610
+ const ref = atom.jsxNode.props[refKey];
1611
+ applyRefs(ref, atom.nativeNode, false);
1612
+ }
1613
+ cleanChildren(atom, nativeRenderer, needClean);
1614
+ }
1615
+ function cleanChildren(atom, nativeRenderer, needClean) {
1595
1616
  let child = atom.child;
1596
1617
  while (child) {
1597
- if (child.jsxNode instanceof Component && child.jsxNode.instance.$portalHost) {
1598
- needClean = true;
1599
- }
1600
1618
  cleanView(nativeRenderer, child, needClean);
1601
1619
  child = child.sibling;
1602
1620
  }
1603
- if (atom.jsxNode instanceof Component) {
1604
- atom.jsxNode.destroy();
1605
- }
1606
1621
  }
1607
1622
  function componentRender(nativeRenderer, component, from, context) {
1608
1623
  component.render((template, portalHost) => {
@@ -1655,7 +1670,9 @@ function createChainByNode(jsxNode, prevAtom, elementNamespace) {
1655
1670
  return prevAtom;
1656
1671
  }
1657
1672
  function createChainByChildren(children, prevAtom, elementNamespace) {
1658
- for (const item of children) {
1673
+ const len = children.length;
1674
+ for (let i = 0; i < len; i++) {
1675
+ const item = children[i];
1659
1676
  prevAtom = createChainByNode(item, prevAtom, elementNamespace);
1660
1677
  }
1661
1678
  return prevAtom;
@@ -1678,6 +1695,12 @@ function insertNode(nativeRenderer, atom, context) {
1678
1695
  nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.namespace);
1679
1696
  }
1680
1697
  }
1698
+ function createElementChildren(type, children, namespace) {
1699
+ if (type === 'foreignObject' && namespace === ElementNamespaceMap.svg) {
1700
+ return createChildChain(children, void 0);
1701
+ }
1702
+ return createChildChain(children, namespace);
1703
+ }
1681
1704
  function createElement(nativeRenderer, atom, parentComponent, context) {
1682
1705
  const { namespace, jsxNode } = atom;
1683
1706
  const nativeNode = nativeRenderer.createElement(jsxNode.type, namespace);
@@ -1685,7 +1708,7 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
1685
1708
  let bindingRefs;
1686
1709
  for (const key in props) {
1687
1710
  if (key === 'children') {
1688
- atom.child = createChildChain(jsxNode.props.children, namespace);
1711
+ atom.child = createElementChildren(jsxNode.type, props.children, namespace);
1689
1712
  continue;
1690
1713
  }
1691
1714
  if (key === 'class') {
@@ -1747,7 +1770,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1747
1770
  let unBindRefs;
1748
1771
  let bindRefs;
1749
1772
  let updatedChildren = false;
1750
- for (const [key, value] of changes.remove) {
1773
+ let len = changes.remove.length;
1774
+ for (let i = 0; i < len; i++) {
1775
+ const [key, value] = changes.remove[i];
1751
1776
  if (key === 'children') {
1752
1777
  updatedChildren = true;
1753
1778
  cleanElementChildren(oldAtom, nativeRenderer);
@@ -1775,10 +1800,12 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1775
1800
  }
1776
1801
  nativeRenderer.removeProperty(nativeNode, key, isSvg);
1777
1802
  }
1778
- for (const [key, newValue, oldValue] of changes.replace) {
1803
+ len = changes.replace.length;
1804
+ for (let i = 0; i < len; i++) {
1805
+ const [key, newValue, oldValue] = changes.replace[i];
1779
1806
  if (key === 'children') {
1780
1807
  updatedChildren = true;
1781
- newAtom.child = createChildChain(newValue, isSvg);
1808
+ newAtom.child = createElementChildren(newVNode.type, newValue, isSvg);
1782
1809
  if (!newAtom.child) {
1783
1810
  cleanElementChildren(oldAtom, nativeRenderer);
1784
1811
  }
@@ -1820,10 +1847,12 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1820
1847
  }
1821
1848
  nativeRenderer.setProperty(nativeNode, key, newValue, isSvg);
1822
1849
  }
1823
- for (const [key, value] of changes.add) {
1850
+ len = changes.add.length;
1851
+ for (let i = 0; i < len; i++) {
1852
+ const [key, value] = changes.add[i];
1824
1853
  if (key === 'children') {
1825
1854
  updatedChildren = true;
1826
- newAtom.child = createChildChain(value, isSvg);
1855
+ newAtom.child = createElementChildren(newVNode.type, value, isSvg);
1827
1856
  buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
1828
1857
  continue;
1829
1858
  }
@@ -1860,7 +1889,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1860
1889
  function applyRefs(refs, nativeNode, binding) {
1861
1890
  if (refs) {
1862
1891
  const refList = Array.isArray(refs) ? refs : [refs];
1863
- for (const item of refList) {
1892
+ const len = refList.length;
1893
+ for (let i = 0; i < len; i++) {
1894
+ const item = refList[i];
1864
1895
  if (item instanceof DynamicRef) {
1865
1896
  binding ? item.bind(nativeNode) : item.unBind(nativeNode);
1866
1897
  }
@@ -1872,8 +1903,8 @@ function applyRefs(refs, nativeNode, binding) {
1872
1903
  * Viewfly 根组件,用于实现组件状态更新事件通知
1873
1904
  */
1874
1905
  class RootComponent extends Component {
1875
- constructor(parentInjector, factory, refresh) {
1876
- super(parentInjector, factory, {});
1906
+ constructor(factory, refresh) {
1907
+ super(null, factory, {});
1877
1908
  Object.defineProperty(this, "refresh", {
1878
1909
  enumerable: true,
1879
1910
  configurable: true,
@@ -2023,16 +2054,15 @@ function viewfly(config) {
2023
2054
  const modules = [];
2024
2055
  let destroyed = false;
2025
2056
  let appHost = null;
2026
- const rootComponent = new RootComponent(context || null, withAnnotation({
2027
- providers: [{
2028
- provide: NativeRenderer,
2029
- useValue: nativeRenderer
2030
- }]
2031
- }, () => {
2057
+ const rootProviders = [];
2058
+ const rootComponent = new RootComponent(() => {
2059
+ const rootContext = createContext(rootProviders, void 0, context);
2032
2060
  return () => {
2033
- return destroyed ? null : root;
2061
+ return jsx(rootContext, {
2062
+ children: destroyed ? null : root
2063
+ });
2034
2064
  };
2035
- }), function () {
2065
+ }, function () {
2036
2066
  if (destroyed || !autoUpdate) {
2037
2067
  return;
2038
2068
  }
@@ -2054,7 +2084,8 @@ function viewfly(config) {
2054
2084
  }
2055
2085
  const app = {
2056
2086
  provide(providers) {
2057
- rootComponent.provide(providers);
2087
+ providers = Array.isArray(providers) ? providers : [providers];
2088
+ rootProviders.push(...providers);
2058
2089
  return app;
2059
2090
  },
2060
2091
  use(module) {
@@ -2128,6 +2159,7 @@ exports.StaticRef = StaticRef;
2128
2159
  exports.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
2129
2160
  exports.Type = Type;
2130
2161
  exports.computed = computed;
2162
+ exports.createContext = createContext;
2131
2163
  exports.createDerived = createDerived;
2132
2164
  exports.createDynamicRef = createDynamicRef;
2133
2165
  exports.createRef = createRef;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viewfly/core",
3
- "version": "1.1.10",
3
+ "version": "1.2.1",
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",
@@ -50,7 +50,7 @@
50
50
  "bugs": {
51
51
  "url": "https://github.com/viewfly/viewfly.git/issues"
52
52
  },
53
- "gitHead": "08cdabe11ffa8fb6c9c4bc53898881af2396f735",
53
+ "gitHead": "8b79b4e067238c81c61d62581b9f6d2c64f60677",
54
54
  "dependencies": {
55
55
  "reflect-metadata": "^0.2.2"
56
56
  }