@viewfly/core 1.1.10 → 1.2.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.
@@ -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
  }
@@ -500,7 +499,7 @@ declare function createRenderer(component: Component, nativeRenderer: NativeRend
500
499
  */
501
500
  declare class RootComponent extends Component {
502
501
  private refresh;
503
- constructor(parentInjector: Injector | null, factory: ComponentSetup, refresh: () => void);
502
+ constructor(factory: ComponentSetup, refresh: () => void);
504
503
  markAsChanged(changedComponent?: Component): void;
505
504
  }
506
505
 
@@ -602,4 +601,4 @@ interface Module {
602
601
  }
603
602
  declare function viewfly<T extends NativeNode>(config: Config): Application<T>;
604
603
 
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 };
604
+ 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;
1602
+ }
1603
+ if (needClean) {
1604
+ nativeRenderer.remove(atom.nativeNode, atom.namespace);
1605
+ needClean = false;
1592
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;
@@ -1745,7 +1762,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1745
1762
  let unBindRefs;
1746
1763
  let bindRefs;
1747
1764
  let updatedChildren = false;
1748
- for (const [key, value] of changes.remove) {
1765
+ let len = changes.remove.length;
1766
+ for (let i = 0; i < len; i++) {
1767
+ const [key, value] = changes.remove[i];
1749
1768
  if (key === 'children') {
1750
1769
  updatedChildren = true;
1751
1770
  cleanElementChildren(oldAtom, nativeRenderer);
@@ -1773,7 +1792,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1773
1792
  }
1774
1793
  nativeRenderer.removeProperty(nativeNode, key, isSvg);
1775
1794
  }
1776
- for (const [key, newValue, oldValue] of changes.replace) {
1795
+ len = changes.replace.length;
1796
+ for (let i = 0; i < len; i++) {
1797
+ const [key, newValue, oldValue] = changes.replace[i];
1777
1798
  if (key === 'children') {
1778
1799
  updatedChildren = true;
1779
1800
  newAtom.child = createChildChain(newValue, isSvg);
@@ -1818,7 +1839,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1818
1839
  }
1819
1840
  nativeRenderer.setProperty(nativeNode, key, newValue, isSvg);
1820
1841
  }
1821
- for (const [key, value] of changes.add) {
1842
+ len = changes.add.length;
1843
+ for (let i = 0; i < len; i++) {
1844
+ const [key, value] = changes.add[i];
1822
1845
  if (key === 'children') {
1823
1846
  updatedChildren = true;
1824
1847
  newAtom.child = createChildChain(value, isSvg);
@@ -1858,7 +1881,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1858
1881
  function applyRefs(refs, nativeNode, binding) {
1859
1882
  if (refs) {
1860
1883
  const refList = Array.isArray(refs) ? refs : [refs];
1861
- for (const item of refList) {
1884
+ const len = refList.length;
1885
+ for (let i = 0; i < len; i++) {
1886
+ const item = refList[i];
1862
1887
  if (item instanceof DynamicRef) {
1863
1888
  binding ? item.bind(nativeNode) : item.unBind(nativeNode);
1864
1889
  }
@@ -1870,8 +1895,8 @@ function applyRefs(refs, nativeNode, binding) {
1870
1895
  * Viewfly 根组件,用于实现组件状态更新事件通知
1871
1896
  */
1872
1897
  class RootComponent extends Component {
1873
- constructor(parentInjector, factory, refresh) {
1874
- super(parentInjector, factory, {});
1898
+ constructor(factory, refresh) {
1899
+ super(null, factory, {});
1875
1900
  Object.defineProperty(this, "refresh", {
1876
1901
  enumerable: true,
1877
1902
  configurable: true,
@@ -2021,16 +2046,15 @@ function viewfly(config) {
2021
2046
  const modules = [];
2022
2047
  let destroyed = false;
2023
2048
  let appHost = null;
2024
- const rootComponent = new RootComponent(context || null, withAnnotation({
2025
- providers: [{
2026
- provide: NativeRenderer,
2027
- useValue: nativeRenderer
2028
- }]
2029
- }, () => {
2049
+ const rootProviders = [];
2050
+ const rootComponent = new RootComponent(() => {
2051
+ const rootContext = createContext(rootProviders, void 0, context);
2030
2052
  return () => {
2031
- return destroyed ? null : root;
2053
+ return jsx(rootContext, {
2054
+ children: destroyed ? null : root
2055
+ });
2032
2056
  };
2033
- }), function () {
2057
+ }, function () {
2034
2058
  if (destroyed || !autoUpdate) {
2035
2059
  return;
2036
2060
  }
@@ -2052,7 +2076,8 @@ function viewfly(config) {
2052
2076
  }
2053
2077
  const app = {
2054
2078
  provide(providers) {
2055
- rootComponent.provide(providers);
2079
+ providers = Array.isArray(providers) ? providers : [providers];
2080
+ rootProviders.push(...providers);
2056
2081
  return app;
2057
2082
  },
2058
2083
  use(module) {
@@ -2102,4 +2127,4 @@ function viewfly(config) {
2102
2127
  return app;
2103
2128
  }
2104
2129
 
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 };
2130
+ 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;
1604
+ }
1605
+ if (needClean) {
1606
+ nativeRenderer.remove(atom.nativeNode, atom.namespace);
1607
+ needClean = false;
1594
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;
@@ -1747,7 +1764,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1747
1764
  let unBindRefs;
1748
1765
  let bindRefs;
1749
1766
  let updatedChildren = false;
1750
- for (const [key, value] of changes.remove) {
1767
+ let len = changes.remove.length;
1768
+ for (let i = 0; i < len; i++) {
1769
+ const [key, value] = changes.remove[i];
1751
1770
  if (key === 'children') {
1752
1771
  updatedChildren = true;
1753
1772
  cleanElementChildren(oldAtom, nativeRenderer);
@@ -1775,7 +1794,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1775
1794
  }
1776
1795
  nativeRenderer.removeProperty(nativeNode, key, isSvg);
1777
1796
  }
1778
- for (const [key, newValue, oldValue] of changes.replace) {
1797
+ len = changes.replace.length;
1798
+ for (let i = 0; i < len; i++) {
1799
+ const [key, newValue, oldValue] = changes.replace[i];
1779
1800
  if (key === 'children') {
1780
1801
  updatedChildren = true;
1781
1802
  newAtom.child = createChildChain(newValue, isSvg);
@@ -1820,7 +1841,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1820
1841
  }
1821
1842
  nativeRenderer.setProperty(nativeNode, key, newValue, isSvg);
1822
1843
  }
1823
- for (const [key, value] of changes.add) {
1844
+ len = changes.add.length;
1845
+ for (let i = 0; i < len; i++) {
1846
+ const [key, value] = changes.add[i];
1824
1847
  if (key === 'children') {
1825
1848
  updatedChildren = true;
1826
1849
  newAtom.child = createChildChain(value, isSvg);
@@ -1860,7 +1883,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1860
1883
  function applyRefs(refs, nativeNode, binding) {
1861
1884
  if (refs) {
1862
1885
  const refList = Array.isArray(refs) ? refs : [refs];
1863
- for (const item of refList) {
1886
+ const len = refList.length;
1887
+ for (let i = 0; i < len; i++) {
1888
+ const item = refList[i];
1864
1889
  if (item instanceof DynamicRef) {
1865
1890
  binding ? item.bind(nativeNode) : item.unBind(nativeNode);
1866
1891
  }
@@ -1872,8 +1897,8 @@ function applyRefs(refs, nativeNode, binding) {
1872
1897
  * Viewfly 根组件,用于实现组件状态更新事件通知
1873
1898
  */
1874
1899
  class RootComponent extends Component {
1875
- constructor(parentInjector, factory, refresh) {
1876
- super(parentInjector, factory, {});
1900
+ constructor(factory, refresh) {
1901
+ super(null, factory, {});
1877
1902
  Object.defineProperty(this, "refresh", {
1878
1903
  enumerable: true,
1879
1904
  configurable: true,
@@ -2023,16 +2048,15 @@ function viewfly(config) {
2023
2048
  const modules = [];
2024
2049
  let destroyed = false;
2025
2050
  let appHost = null;
2026
- const rootComponent = new RootComponent(context || null, withAnnotation({
2027
- providers: [{
2028
- provide: NativeRenderer,
2029
- useValue: nativeRenderer
2030
- }]
2031
- }, () => {
2051
+ const rootProviders = [];
2052
+ const rootComponent = new RootComponent(() => {
2053
+ const rootContext = createContext(rootProviders, void 0, context);
2032
2054
  return () => {
2033
- return destroyed ? null : root;
2055
+ return jsx(rootContext, {
2056
+ children: destroyed ? null : root
2057
+ });
2034
2058
  };
2035
- }), function () {
2059
+ }, function () {
2036
2060
  if (destroyed || !autoUpdate) {
2037
2061
  return;
2038
2062
  }
@@ -2054,7 +2078,8 @@ function viewfly(config) {
2054
2078
  }
2055
2079
  const app = {
2056
2080
  provide(providers) {
2057
- rootComponent.provide(providers);
2081
+ providers = Array.isArray(providers) ? providers : [providers];
2082
+ rootProviders.push(...providers);
2058
2083
  return app;
2059
2084
  },
2060
2085
  use(module) {
@@ -2128,6 +2153,7 @@ exports.StaticRef = StaticRef;
2128
2153
  exports.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
2129
2154
  exports.Type = Type;
2130
2155
  exports.computed = computed;
2156
+ exports.createContext = createContext;
2131
2157
  exports.createDerived = createDerived;
2132
2158
  exports.createDynamicRef = createDynamicRef;
2133
2159
  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.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",
@@ -50,7 +50,7 @@
50
50
  "bugs": {
51
51
  "url": "https://github.com/viewfly/viewfly.git/issues"
52
52
  },
53
- "gitHead": "08cdabe11ffa8fb6c9c4bc53898881af2396f735",
53
+ "gitHead": "8d13d8667f8875f24bc5218e9e4136d9efd9565a",
54
54
  "dependencies": {
55
55
  "reflect-metadata": "^0.2.2"
56
56
  }