@viewfly/core 2.0.0-alpha.4 → 2.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/index.d.ts +94 -16
- package/bundles/index.esm.js +228 -111
- package/bundles/index.js +231 -111
- package/package.json +2 -2
package/bundles/index.d.ts
CHANGED
|
@@ -211,7 +211,7 @@ declare function comparePropsWithCallbacks(oldProps: Record<string, any>, newPro
|
|
|
211
211
|
declare const TextAtomType: unique symbol;
|
|
212
212
|
declare const ElementAtomType: unique symbol;
|
|
213
213
|
declare const ComponentAtomType: unique symbol;
|
|
214
|
-
type ElementNamespace = string |
|
|
214
|
+
type ElementNamespace = string | void;
|
|
215
215
|
interface TextAtom {
|
|
216
216
|
type: typeof TextAtomType;
|
|
217
217
|
index: number;
|
|
@@ -264,6 +264,7 @@ declare abstract class NativeRenderer<ElementNode = NativeNode, TextNode = Nativ
|
|
|
264
264
|
abstract cleanChildren(node: ElementNode, namespace: ElementNamespace): void;
|
|
265
265
|
abstract syncTextContent(target: TextNode, content: string, namespace: ElementNamespace): void;
|
|
266
266
|
abstract insertAfter(newNode: ElementNode | TextNode, ref: ElementNode | TextNode, namespace: ElementNamespace): void;
|
|
267
|
+
abstract getNameSpace(type: string, namespace: ElementNamespace): string | void;
|
|
267
268
|
}
|
|
268
269
|
|
|
269
270
|
interface RefListener<T> {
|
|
@@ -436,8 +437,19 @@ declare class Component {
|
|
|
436
437
|
* 获取当前组件实例
|
|
437
438
|
*/
|
|
438
439
|
declare function getCurrentInstance(): Component;
|
|
440
|
+
declare function registryComponentDestroyCallback(fn: () => void): void;
|
|
439
441
|
|
|
440
442
|
declare function createContext(providers: Provider[], scope?: Scope | null, parentInjector?: Injector): (props: Props) => () => JSXNode | JSXNode[];
|
|
443
|
+
interface ContextProviderParams<T> {
|
|
444
|
+
provide: Type<T> | AbstractType<T> | InjectionToken<T>;
|
|
445
|
+
}
|
|
446
|
+
interface ContextProvider<T> extends Props {
|
|
447
|
+
useClass?: ClassProvider<T>['useClass'];
|
|
448
|
+
useFactory?: FactoryProvider<T>['useFactory'];
|
|
449
|
+
useValue?: ValueProvider<T>['useValue'];
|
|
450
|
+
useExisting?: ExistingProvider<T>['useExisting'];
|
|
451
|
+
}
|
|
452
|
+
declare function createContextProvider<T>(params: ContextProviderParams<T>): (props: ContextProvider<T>) => () => ViewFlyNode<string | ComponentSetup<any>>;
|
|
441
453
|
/**
|
|
442
454
|
* 通过组件上下文获取 IoC 容器内数据的勾子方法
|
|
443
455
|
*/
|
|
@@ -467,12 +479,18 @@ interface ComponentAnnotation {
|
|
|
467
479
|
*/
|
|
468
480
|
declare function withAnnotation<T extends ComponentSetup>(annotation: ComponentAnnotation, componentSetup: T): T;
|
|
469
481
|
|
|
482
|
+
declare class Dep {
|
|
483
|
+
effect: () => void;
|
|
484
|
+
destroyCallbacks: Array<() => void>;
|
|
485
|
+
constructor(effect: () => void);
|
|
486
|
+
destroy(): void;
|
|
487
|
+
}
|
|
488
|
+
declare function getDepContext(): Dep | undefined;
|
|
489
|
+
declare function pushDepContext(dep: Dep): void;
|
|
490
|
+
declare function popDepContext(): void;
|
|
491
|
+
|
|
470
492
|
declare function withMemo<T extends Props = Props>(canUseMemo: ComponentInstance<T>['$useMemo'], render: () => JSXNode): ComponentInstance<T>;
|
|
471
493
|
|
|
472
|
-
declare const ElementNamespaceMap: {
|
|
473
|
-
readonly svg: "svg";
|
|
474
|
-
readonly math: "mathml";
|
|
475
|
-
};
|
|
476
494
|
declare function createRenderer(component: Component, nativeRenderer: NativeRenderer, namespace: ElementNamespace): (host: NativeNode) => void;
|
|
477
495
|
|
|
478
496
|
/**
|
|
@@ -518,15 +536,6 @@ interface Computed<T> {
|
|
|
518
536
|
}
|
|
519
537
|
declare function computed<T>(callback: () => T, isContinue?: (data: T) => unknown): Computed<T>;
|
|
520
538
|
|
|
521
|
-
declare class Dep {
|
|
522
|
-
effect: () => void;
|
|
523
|
-
destroyCallbacks: Array<() => void>;
|
|
524
|
-
constructor(effect: () => void);
|
|
525
|
-
destroy(): void;
|
|
526
|
-
}
|
|
527
|
-
declare function getDepContext(): Dep | undefined;
|
|
528
|
-
declare function pushDepContext(dep: Dep): void;
|
|
529
|
-
declare function popDepContext(): void;
|
|
530
539
|
declare enum TrackOpTypes {
|
|
531
540
|
Get = "Get",
|
|
532
541
|
Has = "Has",
|
|
@@ -540,7 +549,6 @@ declare enum TriggerOpTypes {
|
|
|
540
549
|
}
|
|
541
550
|
declare function track(target: object, type: TrackOpTypes, key?: unknown): void;
|
|
542
551
|
declare function trigger(target: object, type: TriggerOpTypes, key?: unknown): void;
|
|
543
|
-
declare function registryComponentDestroyCallback(fn: () => void): void;
|
|
544
552
|
|
|
545
553
|
declare const rawToProxyCache: WeakMap<object, any>;
|
|
546
554
|
declare const proxyToRawCache: WeakMap<object, any>;
|
|
@@ -640,4 +648,74 @@ declare function shallowReactive<T>(raw: T): T;
|
|
|
640
648
|
|
|
641
649
|
declare function watch<T>(trigger: () => T, callback: (newValue: T, oldValue: T) => (() => any) | void): () => void;
|
|
642
650
|
|
|
643
|
-
|
|
651
|
+
/**
|
|
652
|
+
* 组件状态实例,直接调用可以获取最新的状态,通过 set 方法可以更新状态
|
|
653
|
+
*/
|
|
654
|
+
interface Signal<T> {
|
|
655
|
+
/**
|
|
656
|
+
* 直接调用一个 Signal 实例,可以获取最新状态
|
|
657
|
+
*/
|
|
658
|
+
(): T;
|
|
659
|
+
/**
|
|
660
|
+
* 更新组件状态的方法,可以传入最新的值
|
|
661
|
+
* @param newState
|
|
662
|
+
*/
|
|
663
|
+
set(newState: T): void;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* 组件状态管理器
|
|
667
|
+
* @param state 初始状态
|
|
668
|
+
* @example
|
|
669
|
+
* ```tsx
|
|
670
|
+
* function App() {
|
|
671
|
+
* // 初始化状态
|
|
672
|
+
* const state = createSignal(1)
|
|
673
|
+
*
|
|
674
|
+
* return () => {
|
|
675
|
+
* <div>
|
|
676
|
+
* <div>当前值为:{state()}</div>
|
|
677
|
+
* <div>
|
|
678
|
+
* <button type="button" onClick={() => {
|
|
679
|
+
* // 当点击时更新状态
|
|
680
|
+
* state.set(state() + 1)
|
|
681
|
+
* }
|
|
682
|
+
* }>updateState</button>
|
|
683
|
+
* </div>
|
|
684
|
+
* </div>
|
|
685
|
+
* }
|
|
686
|
+
* }
|
|
687
|
+
*/
|
|
688
|
+
declare function createSignal<T>(state: T): Signal<T>;
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
692
|
+
* 并在你获取 createDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
693
|
+
*
|
|
694
|
+
* @param fn
|
|
695
|
+
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
696
|
+
*/
|
|
697
|
+
declare function createDerived<T>(fn: () => T, isContinue?: (data: T) => unknown): Signal<T>;
|
|
698
|
+
|
|
699
|
+
interface EffectCallback<T> {
|
|
700
|
+
(newValue: T, oldValue: T): void | (() => void);
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* 监听状态变化,当任意一个状态发生变更时,触发回调。
|
|
704
|
+
* createEffect 会返回一个取消监听的函数,调用此函数,可以取消监听。
|
|
705
|
+
* 当在组件中调用时,组件销毁时会自动取消监听。
|
|
706
|
+
* @param deps 依赖的状态 Signal,可以是一个 Signal,只可以一个数包含 Signal 的数组,或者是一个求值函数
|
|
707
|
+
* @param callback 状态变更后的回调函数
|
|
708
|
+
*/
|
|
709
|
+
declare function createEffect<T>(deps: Signal<T>, callback: EffectCallback<T>): () => void;
|
|
710
|
+
declare function createEffect<T>(deps: [Signal<T>], callback: EffectCallback<[T]>): () => void;
|
|
711
|
+
declare function createEffect<T, T1>(deps: [Signal<T>, Signal<T1>], callback: EffectCallback<[T, T1]>): () => void;
|
|
712
|
+
declare function createEffect<T, T1, T2>(deps: [Signal<T>, Signal<T1>, Signal<T2>], callback: EffectCallback<[T, T1, T2]>): () => void;
|
|
713
|
+
declare function createEffect<T, T1, T2, T3>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>], callback: EffectCallback<[T, T1, T2, T3]>): () => void;
|
|
714
|
+
declare function createEffect<T, T1, T2, T3, T4>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>], callback: EffectCallback<[T, T1, T2, T3, T4]>): () => void;
|
|
715
|
+
declare function createEffect<T, T1, T2, T3, T4, T5>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>, Signal<T5>], callback: EffectCallback<[T, T1, T2, T3, T4, T5]>): () => void;
|
|
716
|
+
declare function createEffect<T, T1, T2, T3, T4, T5, T6>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>, Signal<T5>, Signal<T6>], callback: EffectCallback<[T, T1, T2, T3, T4, T5, T6]>): () => void;
|
|
717
|
+
declare function createEffect<T, T1, T2, T3, T4, T5, T6, T7>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>, Signal<T5>, Signal<T6>, Signal<T7>], callback: EffectCallback<[T, T1, T2, T3, T4, T5, T6, T7]>): () => void;
|
|
718
|
+
declare function createEffect<T>(deps: () => T, callback: EffectCallback<T>): () => void;
|
|
719
|
+
declare function createEffect<T = any>(deps: Signal<any>[], callback: EffectCallback<T[]>): () => void;
|
|
720
|
+
|
|
721
|
+
export { type AbstractInstanceType, type AbstractProvider, type AbstractType, type Application, ArrayReactiveHandler, type Atom, type ClassNames, type ClassProvider, Component, type ComponentAnnotation, type ComponentInstance, type ComponentSetup, type ComponentViewMetadata, type Computed, type Config, type ConstructorProvider, type ContextProvider, type ContextProviderParams, Dep, DynamicRef, type EffectCallback, type ElementNamespace, 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, MapReactiveHandler, type Module, type NativeNode, NativeRenderer, type NormalizedProvider, NullInjector, ObjectReactiveHandler, Optional, type OptionalDecorator, Prop, type PropDecorator, type Props, type ProvideScope, type Provider, type ReactiveConfig, type RefListener, type ReflectiveDependency, ReflectiveInjector, RootComponent, Scope, Self, type SelfDecorator, SetReactiveHandler, type Signal, SkipSelf, type SkipSelfDecorator, type StaticProvider, StaticRef, THROW_IF_NOT_FOUND, TrackOpTypes, TriggerOpTypes, Type, type TypeProvider, type ValueProvider, type ViewFlyNode, comparePropsWithCallbacks, computed, createContext, createContextProvider, createDerived, createDynamicRef, createEffect, createRef, createRenderer, createSignal, defaultArrayReactiveHandler, defaultMapReactiveHandler, defaultObjectReactiveHandler, defaultSetReactiveHandler, defaultShallowArrayReactiveHandler, defaultShallowMapReactiveHandler, defaultShallowObjectReactiveHandler, defaultShallowSetReactiveHandler, forwardRef, getCurrentInstance, getDepContext, getSetupContext, inject, internalWrite, isReactive, jsx, jsxs, makeError, normalizeProvider, onMounted, onUnmounted, onUpdated, popDepContext, proxyToRawCache, pushDepContext, rawToProxyCache, reactive, readonlyProxyHandler, registryComponentDestroyCallback, shallowReactive, toRaw, track, trigger, viewfly, watch, withAnnotation, withMemo };
|
package/bundles/index.esm.js
CHANGED
|
@@ -800,6 +800,7 @@ function pushDepContext(dep) {
|
|
|
800
800
|
function popDepContext() {
|
|
801
801
|
deps.pop();
|
|
802
802
|
}
|
|
803
|
+
|
|
803
804
|
const subscribers = new WeakMap();
|
|
804
805
|
function getSubscriber(target) {
|
|
805
806
|
let subscriber = subscribers.get(target);
|
|
@@ -883,15 +884,6 @@ function trigger(target, type, key = unKnownKey) {
|
|
|
883
884
|
}
|
|
884
885
|
}
|
|
885
886
|
}
|
|
886
|
-
function registryComponentDestroyCallback(fn) {
|
|
887
|
-
const component = getSetupContext(false);
|
|
888
|
-
if (component) {
|
|
889
|
-
if (!component.unmountedCallbacks) {
|
|
890
|
-
component.unmountedCallbacks = [];
|
|
891
|
-
}
|
|
892
|
-
component.unmountedCallbacks.push(fn);
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
887
|
|
|
896
888
|
function createIterableIterator(wrapper) {
|
|
897
889
|
return {
|
|
@@ -1632,6 +1624,62 @@ class Component {
|
|
|
1632
1624
|
function getCurrentInstance() {
|
|
1633
1625
|
return getSetupContext();
|
|
1634
1626
|
}
|
|
1627
|
+
function registryComponentDestroyCallback(fn) {
|
|
1628
|
+
const component = getSetupContext(false);
|
|
1629
|
+
if (component) {
|
|
1630
|
+
if (!component.unmountedCallbacks) {
|
|
1631
|
+
component.unmountedCallbacks = [];
|
|
1632
|
+
}
|
|
1633
|
+
component.unmountedCallbacks.push(fn);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
function Fragment(props) {
|
|
1638
|
+
return () => {
|
|
1639
|
+
return props.children;
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
function jsx(type, props, key) {
|
|
1643
|
+
return JSXNodeFactory.createNode(type, props, key);
|
|
1644
|
+
}
|
|
1645
|
+
const jsxs = jsx;
|
|
1646
|
+
const JSXNodeFactory = {
|
|
1647
|
+
createNode(type, props, key) {
|
|
1648
|
+
return {
|
|
1649
|
+
type,
|
|
1650
|
+
props,
|
|
1651
|
+
key
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
};
|
|
1655
|
+
|
|
1656
|
+
function watch(trigger, callback) {
|
|
1657
|
+
let prevFn;
|
|
1658
|
+
const dep = new Dep(() => {
|
|
1659
|
+
pushDepContext(dep);
|
|
1660
|
+
const newValue = trigger();
|
|
1661
|
+
popDepContext();
|
|
1662
|
+
if (newValue === oldValue) {
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
1665
|
+
if (prevFn) {
|
|
1666
|
+
prevFn();
|
|
1667
|
+
}
|
|
1668
|
+
prevFn = callback(newValue, oldValue);
|
|
1669
|
+
oldValue = newValue;
|
|
1670
|
+
});
|
|
1671
|
+
pushDepContext(dep);
|
|
1672
|
+
let oldValue = trigger();
|
|
1673
|
+
popDepContext();
|
|
1674
|
+
dep.destroyCallbacks.push(() => {
|
|
1675
|
+
prevFn === null || prevFn === void 0 ? void 0 : prevFn();
|
|
1676
|
+
});
|
|
1677
|
+
function unWatch() {
|
|
1678
|
+
dep.destroy();
|
|
1679
|
+
}
|
|
1680
|
+
registryComponentDestroyCallback(unWatch);
|
|
1681
|
+
return unWatch;
|
|
1682
|
+
}
|
|
1635
1683
|
|
|
1636
1684
|
const injectMap = new WeakMap();
|
|
1637
1685
|
function getInjector(start) {
|
|
@@ -1654,6 +1702,19 @@ function createContext(providers, scope, parentInjector) {
|
|
|
1654
1702
|
};
|
|
1655
1703
|
};
|
|
1656
1704
|
}
|
|
1705
|
+
function createContextProvider(params) {
|
|
1706
|
+
return function contextProvider(props) {
|
|
1707
|
+
let Context = createContext([Object.assign({ provide: params.provide }, props)]);
|
|
1708
|
+
watch(() => {
|
|
1709
|
+
return props.useClass || props.useFactory || props.useValue || props.useExisting;
|
|
1710
|
+
}, () => {
|
|
1711
|
+
Context = createContext([Object.assign({ provide: params.provide }, props)]);
|
|
1712
|
+
});
|
|
1713
|
+
return () => {
|
|
1714
|
+
return jsx(Context, { children: props.children });
|
|
1715
|
+
};
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1657
1718
|
/**
|
|
1658
1719
|
* 通过组件上下文获取 IoC 容器内数据的勾子方法
|
|
1659
1720
|
*/
|
|
@@ -1699,25 +1760,6 @@ function withAnnotation(annotation, componentSetup) {
|
|
|
1699
1760
|
class NativeRenderer {
|
|
1700
1761
|
}
|
|
1701
1762
|
|
|
1702
|
-
function Fragment(props) {
|
|
1703
|
-
return () => {
|
|
1704
|
-
return props.children;
|
|
1705
|
-
};
|
|
1706
|
-
}
|
|
1707
|
-
function jsx(type, props, key) {
|
|
1708
|
-
return JSXNodeFactory.createNode(type, props, key);
|
|
1709
|
-
}
|
|
1710
|
-
const jsxs = jsx;
|
|
1711
|
-
const JSXNodeFactory = {
|
|
1712
|
-
createNode(type, props, key) {
|
|
1713
|
-
return {
|
|
1714
|
-
type,
|
|
1715
|
-
props,
|
|
1716
|
-
key
|
|
1717
|
-
};
|
|
1718
|
-
}
|
|
1719
|
-
};
|
|
1720
|
-
|
|
1721
1763
|
function withMemo(canUseMemo, render) {
|
|
1722
1764
|
return {
|
|
1723
1765
|
$useMemo: canUseMemo,
|
|
@@ -1725,10 +1767,6 @@ function withMemo(canUseMemo, render) {
|
|
|
1725
1767
|
};
|
|
1726
1768
|
}
|
|
1727
1769
|
|
|
1728
|
-
const ElementNamespaceMap = {
|
|
1729
|
-
svg: 'svg',
|
|
1730
|
-
math: 'mathml',
|
|
1731
|
-
};
|
|
1732
1770
|
const listenerReg = /^on[A-Z]/;
|
|
1733
1771
|
function createRenderer(component, nativeRenderer, namespace) {
|
|
1734
1772
|
let isInit = true;
|
|
@@ -1779,7 +1817,7 @@ function buildElementChildren(atom, nativeRenderer, parentComponent, context) {
|
|
|
1779
1817
|
}
|
|
1780
1818
|
function patchComponent(nativeRenderer, component, oldChildAtom, newAtom, context, needMove) {
|
|
1781
1819
|
const newTemplate = component.rerender();
|
|
1782
|
-
newAtom.child = createChildChain(newTemplate, newAtom.namespace);
|
|
1820
|
+
newAtom.child = createChildChain(newTemplate, nativeRenderer, newAtom.namespace);
|
|
1783
1821
|
diff(nativeRenderer, component, newAtom.child, oldChildAtom, context, needMove);
|
|
1784
1822
|
}
|
|
1785
1823
|
function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
|
|
@@ -1812,11 +1850,8 @@ function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
|
|
|
1812
1850
|
}
|
|
1813
1851
|
function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
|
|
1814
1852
|
const commits = [];
|
|
1815
|
-
function changeOffset() {
|
|
1816
|
-
offset++;
|
|
1817
|
-
}
|
|
1818
1853
|
while (newAtom) {
|
|
1819
|
-
oldAtom = createChanges(newAtom, oldAtom,
|
|
1854
|
+
oldAtom = createChanges(newAtom, oldAtom, commits);
|
|
1820
1855
|
newAtom = newAtom.sibling;
|
|
1821
1856
|
}
|
|
1822
1857
|
let dirtyDiffAtom = oldAtom;
|
|
@@ -1827,7 +1862,6 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMo
|
|
|
1827
1862
|
let offset = 0;
|
|
1828
1863
|
const len = commits.length;
|
|
1829
1864
|
for (let i = 0; i < len; i++) {
|
|
1830
|
-
const commit = commits[i];
|
|
1831
1865
|
while (oldAtom) {
|
|
1832
1866
|
if (oldAtom.index <= i) {
|
|
1833
1867
|
offset--;
|
|
@@ -1836,27 +1870,34 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMo
|
|
|
1836
1870
|
}
|
|
1837
1871
|
break;
|
|
1838
1872
|
}
|
|
1839
|
-
|
|
1873
|
+
const { dirtyAtom, newAtom } = commits[i];
|
|
1874
|
+
if (dirtyAtom) {
|
|
1875
|
+
switch (dirtyAtom.type) {
|
|
1876
|
+
case ElementAtomType:
|
|
1877
|
+
updateElement(nativeRenderer, context, parentComponent, offset, needMove, newAtom, dirtyAtom);
|
|
1878
|
+
break;
|
|
1879
|
+
case TextAtomType:
|
|
1880
|
+
updateText(nativeRenderer, context, offset, needMove, newAtom, dirtyAtom);
|
|
1881
|
+
break;
|
|
1882
|
+
case ComponentAtomType:
|
|
1883
|
+
updateComponent(nativeRenderer, context, offset, needMove, newAtom, dirtyAtom);
|
|
1884
|
+
break;
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
else {
|
|
1888
|
+
buildView(nativeRenderer, parentComponent, newAtom, context);
|
|
1889
|
+
offset++;
|
|
1890
|
+
}
|
|
1840
1891
|
}
|
|
1841
1892
|
}
|
|
1842
|
-
function createChanges(newAtom, oldAtom,
|
|
1893
|
+
function createChanges(newAtom, oldAtom, commits) {
|
|
1843
1894
|
const startDiffAtom = oldAtom;
|
|
1844
1895
|
let prev = null;
|
|
1845
1896
|
while (oldAtom) {
|
|
1846
|
-
|
|
1847
|
-
if (oldAtom.type === newAtomType && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
|
|
1897
|
+
if (oldAtom.type === newAtom.type && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
|
|
1848
1898
|
commits.push({
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
updateElement,
|
|
1852
|
-
params: {
|
|
1853
|
-
oldAtom,
|
|
1854
|
-
newAtom,
|
|
1855
|
-
nativeRenderer,
|
|
1856
|
-
context,
|
|
1857
|
-
effect,
|
|
1858
|
-
parentComponent
|
|
1859
|
-
}
|
|
1899
|
+
dirtyAtom: oldAtom,
|
|
1900
|
+
newAtom
|
|
1860
1901
|
});
|
|
1861
1902
|
const next = oldAtom.sibling;
|
|
1862
1903
|
if (!prev) {
|
|
@@ -1869,25 +1910,12 @@ function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, paren
|
|
|
1869
1910
|
oldAtom = oldAtom.sibling;
|
|
1870
1911
|
}
|
|
1871
1912
|
commits.push({
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
oldAtom: oldAtom,
|
|
1875
|
-
newAtom,
|
|
1876
|
-
nativeRenderer,
|
|
1877
|
-
context,
|
|
1878
|
-
effect,
|
|
1879
|
-
parentComponent
|
|
1880
|
-
}
|
|
1913
|
+
dirtyAtom: null,
|
|
1914
|
+
newAtom
|
|
1881
1915
|
});
|
|
1882
1916
|
return startDiffAtom;
|
|
1883
1917
|
}
|
|
1884
|
-
function
|
|
1885
|
-
const { nativeRenderer, parentComponent, newAtom, context, effect } = params;
|
|
1886
|
-
buildView(nativeRenderer, parentComponent, newAtom, context);
|
|
1887
|
-
effect();
|
|
1888
|
-
}
|
|
1889
|
-
function updateText(params, offset, needMove) {
|
|
1890
|
-
const { oldAtom, newAtom, nativeRenderer, context } = params;
|
|
1918
|
+
function updateText(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
|
|
1891
1919
|
const nativeNode = oldAtom.nativeNode;
|
|
1892
1920
|
newAtom.nativeNode = nativeNode;
|
|
1893
1921
|
if (needMove || newAtom.index - offset !== oldAtom.index) {
|
|
@@ -1896,23 +1924,21 @@ function updateText(params, offset, needMove) {
|
|
|
1896
1924
|
context.host = nativeNode;
|
|
1897
1925
|
context.isParent = false;
|
|
1898
1926
|
}
|
|
1899
|
-
function updateElement(
|
|
1900
|
-
const
|
|
1901
|
-
newAtom.nativeNode =
|
|
1927
|
+
function updateElement(nativeRenderer, context, parentComponent, offset, needMove, newAtom, oldAtom) {
|
|
1928
|
+
const nativeNode = oldAtom.nativeNode;
|
|
1929
|
+
newAtom.nativeNode = nativeNode;
|
|
1902
1930
|
if (needMove || newAtom.index - offset !== oldAtom.index) {
|
|
1903
1931
|
insertNode(nativeRenderer, newAtom, context);
|
|
1904
1932
|
}
|
|
1905
|
-
context.host =
|
|
1933
|
+
context.host = nativeNode;
|
|
1906
1934
|
context.isParent = false;
|
|
1907
1935
|
updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, {
|
|
1908
|
-
host:
|
|
1936
|
+
host: nativeNode,
|
|
1909
1937
|
isParent: true,
|
|
1910
1938
|
rootHost: context.rootHost
|
|
1911
1939
|
});
|
|
1912
1940
|
}
|
|
1913
|
-
function updateComponent(
|
|
1914
|
-
const { oldAtom, newAtom, nativeRenderer } = params;
|
|
1915
|
-
let context = params.context;
|
|
1941
|
+
function updateComponent(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
|
|
1916
1942
|
const component = oldAtom.jsxNode;
|
|
1917
1943
|
const portalHost = component.instance.$portalHost;
|
|
1918
1944
|
context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
|
|
@@ -1936,7 +1962,7 @@ function updateComponent(params, offset, needMove) {
|
|
|
1936
1962
|
}
|
|
1937
1963
|
else {
|
|
1938
1964
|
newAtom.child = oldAtom.child;
|
|
1939
|
-
reuseComponentView(nativeRenderer, newAtom.child, context, needMove, !canUpdate);
|
|
1965
|
+
reuseComponentView(nativeRenderer, newAtom.child, context, needMove, !canUpdate || !component.changedSubComponents.size);
|
|
1940
1966
|
}
|
|
1941
1967
|
component.rendered();
|
|
1942
1968
|
}
|
|
@@ -1953,7 +1979,9 @@ function reuseComponentView(nativeRenderer, child, context, moveView, skipSubCom
|
|
|
1953
1979
|
if (moveView) {
|
|
1954
1980
|
insertNode(nativeRenderer, atom, context);
|
|
1955
1981
|
}
|
|
1956
|
-
|
|
1982
|
+
if (!skipSubComponentDiff) {
|
|
1983
|
+
reuseElementChildrenView(nativeRenderer, atom);
|
|
1984
|
+
}
|
|
1957
1985
|
context.isParent = false;
|
|
1958
1986
|
context.host = atom.nativeNode;
|
|
1959
1987
|
}
|
|
@@ -1963,7 +1991,7 @@ function reuseComponentView(nativeRenderer, child, context, moveView, skipSubCom
|
|
|
1963
1991
|
child = child.sibling;
|
|
1964
1992
|
}
|
|
1965
1993
|
}
|
|
1966
|
-
function reuseElementChildrenView(nativeRenderer, atom, context
|
|
1994
|
+
function reuseElementChildrenView(nativeRenderer, atom, context) {
|
|
1967
1995
|
let child = atom.child;
|
|
1968
1996
|
while (child) {
|
|
1969
1997
|
if (child.jsxNode instanceof Component) {
|
|
@@ -2012,7 +2040,7 @@ function cleanChildren(atom, nativeRenderer, needClean) {
|
|
|
2012
2040
|
}
|
|
2013
2041
|
function componentRender(nativeRenderer, component, from, context) {
|
|
2014
2042
|
component.render((template, portalHost) => {
|
|
2015
|
-
from.child = createChildChain(template, from.namespace);
|
|
2043
|
+
from.child = createChildChain(template, nativeRenderer, from.namespace);
|
|
2016
2044
|
context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
|
|
2017
2045
|
component.viewMetadata = Object.assign({ atom: from }, context);
|
|
2018
2046
|
let child = from.child;
|
|
@@ -2037,7 +2065,7 @@ function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, namespace, key)
|
|
|
2037
2065
|
prevAtom.sibling = atom;
|
|
2038
2066
|
return atom;
|
|
2039
2067
|
}
|
|
2040
|
-
function createChainByNode(jsxNode, prevAtom, elementNamespace) {
|
|
2068
|
+
function createChainByNode(jsxNode, prevAtom, nativeRenderer, elementNamespace) {
|
|
2041
2069
|
const type = typeof jsxNode;
|
|
2042
2070
|
if (jsxNode != null && type !== 'boolean') {
|
|
2043
2071
|
if (type === 'string') {
|
|
@@ -2045,11 +2073,11 @@ function createChainByNode(jsxNode, prevAtom, elementNamespace) {
|
|
|
2045
2073
|
}
|
|
2046
2074
|
if (type === 'object') {
|
|
2047
2075
|
if (Array.isArray(jsxNode)) {
|
|
2048
|
-
return createChainByChildren(jsxNode, prevAtom, elementNamespace);
|
|
2076
|
+
return createChainByChildren(jsxNode, prevAtom, nativeRenderer, elementNamespace);
|
|
2049
2077
|
}
|
|
2050
2078
|
const nodeType = typeof jsxNode.type;
|
|
2051
2079
|
if (nodeType === 'string') {
|
|
2052
|
-
return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom,
|
|
2080
|
+
return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom, nativeRenderer.getNameSpace(jsxNode.type, elementNamespace), jsxNode.key);
|
|
2053
2081
|
}
|
|
2054
2082
|
else if (nodeType === 'function') {
|
|
2055
2083
|
return createChainByJSXNode(ComponentAtomType, jsxNode, jsxNode.type, prevAtom, elementNamespace, jsxNode.key);
|
|
@@ -2060,17 +2088,17 @@ function createChainByNode(jsxNode, prevAtom, elementNamespace) {
|
|
|
2060
2088
|
}
|
|
2061
2089
|
return prevAtom;
|
|
2062
2090
|
}
|
|
2063
|
-
function createChainByChildren(children, prevAtom, elementNamespace) {
|
|
2091
|
+
function createChainByChildren(children, prevAtom, nativeRenderer, elementNamespace) {
|
|
2064
2092
|
const len = children.length;
|
|
2065
2093
|
for (let i = 0; i < len; i++) {
|
|
2066
2094
|
const item = children[i];
|
|
2067
|
-
prevAtom = createChainByNode(item, prevAtom, elementNamespace);
|
|
2095
|
+
prevAtom = createChainByNode(item, prevAtom, nativeRenderer, elementNamespace);
|
|
2068
2096
|
}
|
|
2069
2097
|
return prevAtom;
|
|
2070
2098
|
}
|
|
2071
|
-
function createChildChain(template, namespace) {
|
|
2099
|
+
function createChildChain(template, nativeRenderer, namespace) {
|
|
2072
2100
|
const beforeAtom = { sibling: null, index: -1 };
|
|
2073
|
-
createChainByNode(template, beforeAtom, namespace);
|
|
2101
|
+
createChainByNode(template, beforeAtom, nativeRenderer, namespace);
|
|
2074
2102
|
return beforeAtom.sibling;
|
|
2075
2103
|
}
|
|
2076
2104
|
function insertNode(nativeRenderer, atom, context) {
|
|
@@ -2086,11 +2114,9 @@ function insertNode(nativeRenderer, atom, context) {
|
|
|
2086
2114
|
nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.namespace);
|
|
2087
2115
|
}
|
|
2088
2116
|
}
|
|
2089
|
-
function createElementChildren(type, children, namespace) {
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
}
|
|
2093
|
-
return createChildChain(children, namespace);
|
|
2117
|
+
function createElementChildren(type, children, nativeRenderer, namespace) {
|
|
2118
|
+
const ns = nativeRenderer.getNameSpace(type, namespace);
|
|
2119
|
+
return createChildChain(children, nativeRenderer, ns);
|
|
2094
2120
|
}
|
|
2095
2121
|
function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
2096
2122
|
const { namespace, jsxNode } = atom;
|
|
@@ -2099,7 +2125,7 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
|
2099
2125
|
let bindingRefs;
|
|
2100
2126
|
for (const key in props) {
|
|
2101
2127
|
if (key === 'children') {
|
|
2102
|
-
atom.child = createElementChildren(jsxNode.type, props.children, namespace);
|
|
2128
|
+
atom.child = createElementChildren(jsxNode.type, props.children, nativeRenderer, namespace);
|
|
2103
2129
|
continue;
|
|
2104
2130
|
}
|
|
2105
2131
|
if (key === 'class') {
|
|
@@ -2190,7 +2216,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2190
2216
|
}, (key, value) => {
|
|
2191
2217
|
if (key === 'children') {
|
|
2192
2218
|
updatedChildren = true;
|
|
2193
|
-
newAtom.child = createElementChildren(newVNode.type, value, isSvg);
|
|
2219
|
+
newAtom.child = createElementChildren(newVNode.type, value, nativeRenderer, isSvg);
|
|
2194
2220
|
buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
|
|
2195
2221
|
return;
|
|
2196
2222
|
}
|
|
@@ -2219,7 +2245,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2219
2245
|
}, (key, newValue, oldValue) => {
|
|
2220
2246
|
if (key === 'children') {
|
|
2221
2247
|
updatedChildren = true;
|
|
2222
|
-
newAtom.child = createElementChildren(newVNode.type, newValue, isSvg);
|
|
2248
|
+
newAtom.child = createElementChildren(newVNode.type, newValue, nativeRenderer, isSvg);
|
|
2223
2249
|
if (!newAtom.child) {
|
|
2224
2250
|
cleanElementChildren(oldAtom, nativeRenderer);
|
|
2225
2251
|
}
|
|
@@ -2263,7 +2289,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2263
2289
|
});
|
|
2264
2290
|
if (!updatedChildren) {
|
|
2265
2291
|
newAtom.child = oldAtom.child;
|
|
2266
|
-
reuseElementChildrenView(nativeRenderer, newAtom)
|
|
2292
|
+
// reuseElementChildrenView(nativeRenderer, newAtom, context)
|
|
2267
2293
|
}
|
|
2268
2294
|
applyRefs(unBindRefs, nativeNode, false);
|
|
2269
2295
|
applyRefs(bindRefs, nativeNode, true);
|
|
@@ -2480,32 +2506,123 @@ function shallowReactive(raw) {
|
|
|
2480
2506
|
return proxy;
|
|
2481
2507
|
}
|
|
2482
2508
|
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2509
|
+
/**
|
|
2510
|
+
* 组件状态管理器
|
|
2511
|
+
* @param state 初始状态
|
|
2512
|
+
* @example
|
|
2513
|
+
* ```tsx
|
|
2514
|
+
* function App() {
|
|
2515
|
+
* // 初始化状态
|
|
2516
|
+
* const state = createSignal(1)
|
|
2517
|
+
*
|
|
2518
|
+
* return () => {
|
|
2519
|
+
* <div>
|
|
2520
|
+
* <div>当前值为:{state()}</div>
|
|
2521
|
+
* <div>
|
|
2522
|
+
* <button type="button" onClick={() => {
|
|
2523
|
+
* // 当点击时更新状态
|
|
2524
|
+
* state.set(state() + 1)
|
|
2525
|
+
* }
|
|
2526
|
+
* }>updateState</button>
|
|
2527
|
+
* </div>
|
|
2528
|
+
* </div>
|
|
2529
|
+
* }
|
|
2530
|
+
* }
|
|
2531
|
+
*/
|
|
2532
|
+
function createSignal(state) {
|
|
2533
|
+
const subscribers = new Set();
|
|
2534
|
+
function signal() {
|
|
2535
|
+
const listener = getDepContext();
|
|
2536
|
+
if (listener && !subscribers.has(listener)) {
|
|
2537
|
+
listener.destroyCallbacks.push(() => {
|
|
2538
|
+
subscribers.delete(listener);
|
|
2539
|
+
});
|
|
2540
|
+
subscribers.add(listener);
|
|
2541
|
+
}
|
|
2542
|
+
return state;
|
|
2543
|
+
}
|
|
2544
|
+
signal.set = function (newValue) {
|
|
2545
|
+
if (newValue === state) {
|
|
2490
2546
|
return;
|
|
2491
2547
|
}
|
|
2548
|
+
state = newValue;
|
|
2549
|
+
const listeners = Array.from(subscribers);
|
|
2550
|
+
listeners.forEach(listener => listener.effect());
|
|
2551
|
+
};
|
|
2552
|
+
return signal;
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
/**
|
|
2556
|
+
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
2557
|
+
* 并在你获取 createDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
2558
|
+
*
|
|
2559
|
+
* @param fn
|
|
2560
|
+
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
2561
|
+
*/
|
|
2562
|
+
function createDerived(fn, isContinue) {
|
|
2563
|
+
let isStop = false;
|
|
2564
|
+
function canListen(value) {
|
|
2565
|
+
if (isContinue) {
|
|
2566
|
+
const b = isContinue(value);
|
|
2567
|
+
if (b === false) {
|
|
2568
|
+
listener.destroy();
|
|
2569
|
+
return false;
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
return true;
|
|
2573
|
+
}
|
|
2574
|
+
const listener = new Dep(() => {
|
|
2575
|
+
if (isStop) {
|
|
2576
|
+
return;
|
|
2577
|
+
}
|
|
2578
|
+
isStop = true;
|
|
2579
|
+
listener.destroy();
|
|
2580
|
+
pushDepContext(listener);
|
|
2581
|
+
const value = fn();
|
|
2582
|
+
popDepContext();
|
|
2583
|
+
signal.set(value);
|
|
2584
|
+
canListen(value);
|
|
2585
|
+
isStop = false;
|
|
2586
|
+
});
|
|
2587
|
+
pushDepContext(listener);
|
|
2588
|
+
const value = fn();
|
|
2589
|
+
const signal = createSignal(value);
|
|
2590
|
+
popDepContext();
|
|
2591
|
+
isStop = false;
|
|
2592
|
+
if (canListen(value)) {
|
|
2593
|
+
registryComponentDestroyCallback(() => listener.destroy());
|
|
2594
|
+
}
|
|
2595
|
+
return signal;
|
|
2596
|
+
}
|
|
2597
|
+
|
|
2598
|
+
/* eslint-enable max-len*/
|
|
2599
|
+
function createEffect(deps, callback) {
|
|
2600
|
+
let prevFn;
|
|
2601
|
+
const isArray = Array.isArray(deps);
|
|
2602
|
+
const effect = new Dep(function () {
|
|
2492
2603
|
if (prevFn) {
|
|
2493
2604
|
prevFn();
|
|
2494
2605
|
}
|
|
2606
|
+
const newValue = isArray ? deps.map(fn => fn()) : deps();
|
|
2495
2607
|
prevFn = callback(newValue, oldValue);
|
|
2496
2608
|
oldValue = newValue;
|
|
2497
2609
|
});
|
|
2498
|
-
pushDepContext(
|
|
2499
|
-
let oldValue =
|
|
2610
|
+
pushDepContext(effect);
|
|
2611
|
+
let oldValue = isArray ? deps.map(fn => fn()) : deps();
|
|
2500
2612
|
popDepContext();
|
|
2501
|
-
|
|
2502
|
-
prevFn === null || prevFn === void 0 ? void 0 : prevFn();
|
|
2503
|
-
});
|
|
2613
|
+
let isUnWatch = false;
|
|
2504
2614
|
function unWatch() {
|
|
2505
|
-
|
|
2615
|
+
if (isUnWatch) {
|
|
2616
|
+
return;
|
|
2617
|
+
}
|
|
2618
|
+
isUnWatch = true;
|
|
2619
|
+
if (prevFn) {
|
|
2620
|
+
prevFn();
|
|
2621
|
+
}
|
|
2622
|
+
effect.destroy();
|
|
2506
2623
|
}
|
|
2507
2624
|
registryComponentDestroyCallback(unWatch);
|
|
2508
2625
|
return unWatch;
|
|
2509
2626
|
}
|
|
2510
2627
|
|
|
2511
|
-
export { ArrayReactiveHandler, Component, Dep, DynamicRef,
|
|
2628
|
+
export { ArrayReactiveHandler, Component, Dep, DynamicRef, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXNodeFactory, MapReactiveHandler, NativeRenderer, NullInjector, ObjectReactiveHandler, Optional, Prop, ReflectiveInjector, RootComponent, Scope, Self, SetReactiveHandler, SkipSelf, StaticRef, THROW_IF_NOT_FOUND, TrackOpTypes, TriggerOpTypes, Type, comparePropsWithCallbacks, computed, createContext, createContextProvider, createDerived, createDynamicRef, createEffect, createRef, createRenderer, createSignal, defaultArrayReactiveHandler, defaultMapReactiveHandler, defaultObjectReactiveHandler, defaultSetReactiveHandler, defaultShallowArrayReactiveHandler, defaultShallowMapReactiveHandler, defaultShallowObjectReactiveHandler, defaultShallowSetReactiveHandler, forwardRef, getCurrentInstance, getDepContext, getSetupContext, inject, internalWrite, isReactive, jsx, jsxs, makeError, normalizeProvider, onMounted, onUnmounted, onUpdated, popDepContext, proxyToRawCache, pushDepContext, rawToProxyCache, reactive, readonlyProxyHandler, registryComponentDestroyCallback, shallowReactive, toRaw, track, trigger, viewfly, watch, withAnnotation, withMemo };
|
package/bundles/index.js
CHANGED
|
@@ -802,6 +802,7 @@ function pushDepContext(dep) {
|
|
|
802
802
|
function popDepContext() {
|
|
803
803
|
deps.pop();
|
|
804
804
|
}
|
|
805
|
+
|
|
805
806
|
const subscribers = new WeakMap();
|
|
806
807
|
function getSubscriber(target) {
|
|
807
808
|
let subscriber = subscribers.get(target);
|
|
@@ -885,15 +886,6 @@ function trigger(target, type, key = unKnownKey) {
|
|
|
885
886
|
}
|
|
886
887
|
}
|
|
887
888
|
}
|
|
888
|
-
function registryComponentDestroyCallback(fn) {
|
|
889
|
-
const component = getSetupContext(false);
|
|
890
|
-
if (component) {
|
|
891
|
-
if (!component.unmountedCallbacks) {
|
|
892
|
-
component.unmountedCallbacks = [];
|
|
893
|
-
}
|
|
894
|
-
component.unmountedCallbacks.push(fn);
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
889
|
|
|
898
890
|
function createIterableIterator(wrapper) {
|
|
899
891
|
return {
|
|
@@ -1634,6 +1626,62 @@ class Component {
|
|
|
1634
1626
|
function getCurrentInstance() {
|
|
1635
1627
|
return getSetupContext();
|
|
1636
1628
|
}
|
|
1629
|
+
function registryComponentDestroyCallback(fn) {
|
|
1630
|
+
const component = getSetupContext(false);
|
|
1631
|
+
if (component) {
|
|
1632
|
+
if (!component.unmountedCallbacks) {
|
|
1633
|
+
component.unmountedCallbacks = [];
|
|
1634
|
+
}
|
|
1635
|
+
component.unmountedCallbacks.push(fn);
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
function Fragment(props) {
|
|
1640
|
+
return () => {
|
|
1641
|
+
return props.children;
|
|
1642
|
+
};
|
|
1643
|
+
}
|
|
1644
|
+
function jsx(type, props, key) {
|
|
1645
|
+
return JSXNodeFactory.createNode(type, props, key);
|
|
1646
|
+
}
|
|
1647
|
+
const jsxs = jsx;
|
|
1648
|
+
const JSXNodeFactory = {
|
|
1649
|
+
createNode(type, props, key) {
|
|
1650
|
+
return {
|
|
1651
|
+
type,
|
|
1652
|
+
props,
|
|
1653
|
+
key
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
};
|
|
1657
|
+
|
|
1658
|
+
function watch(trigger, callback) {
|
|
1659
|
+
let prevFn;
|
|
1660
|
+
const dep = new Dep(() => {
|
|
1661
|
+
pushDepContext(dep);
|
|
1662
|
+
const newValue = trigger();
|
|
1663
|
+
popDepContext();
|
|
1664
|
+
if (newValue === oldValue) {
|
|
1665
|
+
return;
|
|
1666
|
+
}
|
|
1667
|
+
if (prevFn) {
|
|
1668
|
+
prevFn();
|
|
1669
|
+
}
|
|
1670
|
+
prevFn = callback(newValue, oldValue);
|
|
1671
|
+
oldValue = newValue;
|
|
1672
|
+
});
|
|
1673
|
+
pushDepContext(dep);
|
|
1674
|
+
let oldValue = trigger();
|
|
1675
|
+
popDepContext();
|
|
1676
|
+
dep.destroyCallbacks.push(() => {
|
|
1677
|
+
prevFn === null || prevFn === void 0 ? void 0 : prevFn();
|
|
1678
|
+
});
|
|
1679
|
+
function unWatch() {
|
|
1680
|
+
dep.destroy();
|
|
1681
|
+
}
|
|
1682
|
+
registryComponentDestroyCallback(unWatch);
|
|
1683
|
+
return unWatch;
|
|
1684
|
+
}
|
|
1637
1685
|
|
|
1638
1686
|
const injectMap = new WeakMap();
|
|
1639
1687
|
function getInjector(start) {
|
|
@@ -1656,6 +1704,19 @@ function createContext(providers, scope, parentInjector) {
|
|
|
1656
1704
|
};
|
|
1657
1705
|
};
|
|
1658
1706
|
}
|
|
1707
|
+
function createContextProvider(params) {
|
|
1708
|
+
return function contextProvider(props) {
|
|
1709
|
+
let Context = createContext([Object.assign({ provide: params.provide }, props)]);
|
|
1710
|
+
watch(() => {
|
|
1711
|
+
return props.useClass || props.useFactory || props.useValue || props.useExisting;
|
|
1712
|
+
}, () => {
|
|
1713
|
+
Context = createContext([Object.assign({ provide: params.provide }, props)]);
|
|
1714
|
+
});
|
|
1715
|
+
return () => {
|
|
1716
|
+
return jsx(Context, { children: props.children });
|
|
1717
|
+
};
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1659
1720
|
/**
|
|
1660
1721
|
* 通过组件上下文获取 IoC 容器内数据的勾子方法
|
|
1661
1722
|
*/
|
|
@@ -1701,25 +1762,6 @@ function withAnnotation(annotation, componentSetup) {
|
|
|
1701
1762
|
class NativeRenderer {
|
|
1702
1763
|
}
|
|
1703
1764
|
|
|
1704
|
-
function Fragment(props) {
|
|
1705
|
-
return () => {
|
|
1706
|
-
return props.children;
|
|
1707
|
-
};
|
|
1708
|
-
}
|
|
1709
|
-
function jsx(type, props, key) {
|
|
1710
|
-
return JSXNodeFactory.createNode(type, props, key);
|
|
1711
|
-
}
|
|
1712
|
-
const jsxs = jsx;
|
|
1713
|
-
const JSXNodeFactory = {
|
|
1714
|
-
createNode(type, props, key) {
|
|
1715
|
-
return {
|
|
1716
|
-
type,
|
|
1717
|
-
props,
|
|
1718
|
-
key
|
|
1719
|
-
};
|
|
1720
|
-
}
|
|
1721
|
-
};
|
|
1722
|
-
|
|
1723
1765
|
function withMemo(canUseMemo, render) {
|
|
1724
1766
|
return {
|
|
1725
1767
|
$useMemo: canUseMemo,
|
|
@@ -1727,10 +1769,6 @@ function withMemo(canUseMemo, render) {
|
|
|
1727
1769
|
};
|
|
1728
1770
|
}
|
|
1729
1771
|
|
|
1730
|
-
const ElementNamespaceMap = {
|
|
1731
|
-
svg: 'svg',
|
|
1732
|
-
math: 'mathml',
|
|
1733
|
-
};
|
|
1734
1772
|
const listenerReg = /^on[A-Z]/;
|
|
1735
1773
|
function createRenderer(component, nativeRenderer, namespace) {
|
|
1736
1774
|
let isInit = true;
|
|
@@ -1781,7 +1819,7 @@ function buildElementChildren(atom, nativeRenderer, parentComponent, context) {
|
|
|
1781
1819
|
}
|
|
1782
1820
|
function patchComponent(nativeRenderer, component, oldChildAtom, newAtom, context, needMove) {
|
|
1783
1821
|
const newTemplate = component.rerender();
|
|
1784
|
-
newAtom.child = createChildChain(newTemplate, newAtom.namespace);
|
|
1822
|
+
newAtom.child = createChildChain(newTemplate, nativeRenderer, newAtom.namespace);
|
|
1785
1823
|
diff(nativeRenderer, component, newAtom.child, oldChildAtom, context, needMove);
|
|
1786
1824
|
}
|
|
1787
1825
|
function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
|
|
@@ -1814,11 +1852,8 @@ function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
|
|
|
1814
1852
|
}
|
|
1815
1853
|
function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
|
|
1816
1854
|
const commits = [];
|
|
1817
|
-
function changeOffset() {
|
|
1818
|
-
offset++;
|
|
1819
|
-
}
|
|
1820
1855
|
while (newAtom) {
|
|
1821
|
-
oldAtom = createChanges(newAtom, oldAtom,
|
|
1856
|
+
oldAtom = createChanges(newAtom, oldAtom, commits);
|
|
1822
1857
|
newAtom = newAtom.sibling;
|
|
1823
1858
|
}
|
|
1824
1859
|
let dirtyDiffAtom = oldAtom;
|
|
@@ -1829,7 +1864,6 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMo
|
|
|
1829
1864
|
let offset = 0;
|
|
1830
1865
|
const len = commits.length;
|
|
1831
1866
|
for (let i = 0; i < len; i++) {
|
|
1832
|
-
const commit = commits[i];
|
|
1833
1867
|
while (oldAtom) {
|
|
1834
1868
|
if (oldAtom.index <= i) {
|
|
1835
1869
|
offset--;
|
|
@@ -1838,27 +1872,34 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMo
|
|
|
1838
1872
|
}
|
|
1839
1873
|
break;
|
|
1840
1874
|
}
|
|
1841
|
-
|
|
1875
|
+
const { dirtyAtom, newAtom } = commits[i];
|
|
1876
|
+
if (dirtyAtom) {
|
|
1877
|
+
switch (dirtyAtom.type) {
|
|
1878
|
+
case ElementAtomType:
|
|
1879
|
+
updateElement(nativeRenderer, context, parentComponent, offset, needMove, newAtom, dirtyAtom);
|
|
1880
|
+
break;
|
|
1881
|
+
case TextAtomType:
|
|
1882
|
+
updateText(nativeRenderer, context, offset, needMove, newAtom, dirtyAtom);
|
|
1883
|
+
break;
|
|
1884
|
+
case ComponentAtomType:
|
|
1885
|
+
updateComponent(nativeRenderer, context, offset, needMove, newAtom, dirtyAtom);
|
|
1886
|
+
break;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
else {
|
|
1890
|
+
buildView(nativeRenderer, parentComponent, newAtom, context);
|
|
1891
|
+
offset++;
|
|
1892
|
+
}
|
|
1842
1893
|
}
|
|
1843
1894
|
}
|
|
1844
|
-
function createChanges(newAtom, oldAtom,
|
|
1895
|
+
function createChanges(newAtom, oldAtom, commits) {
|
|
1845
1896
|
const startDiffAtom = oldAtom;
|
|
1846
1897
|
let prev = null;
|
|
1847
1898
|
while (oldAtom) {
|
|
1848
|
-
|
|
1849
|
-
if (oldAtom.type === newAtomType && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
|
|
1899
|
+
if (oldAtom.type === newAtom.type && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
|
|
1850
1900
|
commits.push({
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
updateElement,
|
|
1854
|
-
params: {
|
|
1855
|
-
oldAtom,
|
|
1856
|
-
newAtom,
|
|
1857
|
-
nativeRenderer,
|
|
1858
|
-
context,
|
|
1859
|
-
effect,
|
|
1860
|
-
parentComponent
|
|
1861
|
-
}
|
|
1901
|
+
dirtyAtom: oldAtom,
|
|
1902
|
+
newAtom
|
|
1862
1903
|
});
|
|
1863
1904
|
const next = oldAtom.sibling;
|
|
1864
1905
|
if (!prev) {
|
|
@@ -1871,25 +1912,12 @@ function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, paren
|
|
|
1871
1912
|
oldAtom = oldAtom.sibling;
|
|
1872
1913
|
}
|
|
1873
1914
|
commits.push({
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
oldAtom: oldAtom,
|
|
1877
|
-
newAtom,
|
|
1878
|
-
nativeRenderer,
|
|
1879
|
-
context,
|
|
1880
|
-
effect,
|
|
1881
|
-
parentComponent
|
|
1882
|
-
}
|
|
1915
|
+
dirtyAtom: null,
|
|
1916
|
+
newAtom
|
|
1883
1917
|
});
|
|
1884
1918
|
return startDiffAtom;
|
|
1885
1919
|
}
|
|
1886
|
-
function
|
|
1887
|
-
const { nativeRenderer, parentComponent, newAtom, context, effect } = params;
|
|
1888
|
-
buildView(nativeRenderer, parentComponent, newAtom, context);
|
|
1889
|
-
effect();
|
|
1890
|
-
}
|
|
1891
|
-
function updateText(params, offset, needMove) {
|
|
1892
|
-
const { oldAtom, newAtom, nativeRenderer, context } = params;
|
|
1920
|
+
function updateText(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
|
|
1893
1921
|
const nativeNode = oldAtom.nativeNode;
|
|
1894
1922
|
newAtom.nativeNode = nativeNode;
|
|
1895
1923
|
if (needMove || newAtom.index - offset !== oldAtom.index) {
|
|
@@ -1898,23 +1926,21 @@ function updateText(params, offset, needMove) {
|
|
|
1898
1926
|
context.host = nativeNode;
|
|
1899
1927
|
context.isParent = false;
|
|
1900
1928
|
}
|
|
1901
|
-
function updateElement(
|
|
1902
|
-
const
|
|
1903
|
-
newAtom.nativeNode =
|
|
1929
|
+
function updateElement(nativeRenderer, context, parentComponent, offset, needMove, newAtom, oldAtom) {
|
|
1930
|
+
const nativeNode = oldAtom.nativeNode;
|
|
1931
|
+
newAtom.nativeNode = nativeNode;
|
|
1904
1932
|
if (needMove || newAtom.index - offset !== oldAtom.index) {
|
|
1905
1933
|
insertNode(nativeRenderer, newAtom, context);
|
|
1906
1934
|
}
|
|
1907
|
-
context.host =
|
|
1935
|
+
context.host = nativeNode;
|
|
1908
1936
|
context.isParent = false;
|
|
1909
1937
|
updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, {
|
|
1910
|
-
host:
|
|
1938
|
+
host: nativeNode,
|
|
1911
1939
|
isParent: true,
|
|
1912
1940
|
rootHost: context.rootHost
|
|
1913
1941
|
});
|
|
1914
1942
|
}
|
|
1915
|
-
function updateComponent(
|
|
1916
|
-
const { oldAtom, newAtom, nativeRenderer } = params;
|
|
1917
|
-
let context = params.context;
|
|
1943
|
+
function updateComponent(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
|
|
1918
1944
|
const component = oldAtom.jsxNode;
|
|
1919
1945
|
const portalHost = component.instance.$portalHost;
|
|
1920
1946
|
context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
|
|
@@ -1938,7 +1964,7 @@ function updateComponent(params, offset, needMove) {
|
|
|
1938
1964
|
}
|
|
1939
1965
|
else {
|
|
1940
1966
|
newAtom.child = oldAtom.child;
|
|
1941
|
-
reuseComponentView(nativeRenderer, newAtom.child, context, needMove, !canUpdate);
|
|
1967
|
+
reuseComponentView(nativeRenderer, newAtom.child, context, needMove, !canUpdate || !component.changedSubComponents.size);
|
|
1942
1968
|
}
|
|
1943
1969
|
component.rendered();
|
|
1944
1970
|
}
|
|
@@ -1955,7 +1981,9 @@ function reuseComponentView(nativeRenderer, child, context, moveView, skipSubCom
|
|
|
1955
1981
|
if (moveView) {
|
|
1956
1982
|
insertNode(nativeRenderer, atom, context);
|
|
1957
1983
|
}
|
|
1958
|
-
|
|
1984
|
+
if (!skipSubComponentDiff) {
|
|
1985
|
+
reuseElementChildrenView(nativeRenderer, atom);
|
|
1986
|
+
}
|
|
1959
1987
|
context.isParent = false;
|
|
1960
1988
|
context.host = atom.nativeNode;
|
|
1961
1989
|
}
|
|
@@ -1965,7 +1993,7 @@ function reuseComponentView(nativeRenderer, child, context, moveView, skipSubCom
|
|
|
1965
1993
|
child = child.sibling;
|
|
1966
1994
|
}
|
|
1967
1995
|
}
|
|
1968
|
-
function reuseElementChildrenView(nativeRenderer, atom, context
|
|
1996
|
+
function reuseElementChildrenView(nativeRenderer, atom, context) {
|
|
1969
1997
|
let child = atom.child;
|
|
1970
1998
|
while (child) {
|
|
1971
1999
|
if (child.jsxNode instanceof Component) {
|
|
@@ -2014,7 +2042,7 @@ function cleanChildren(atom, nativeRenderer, needClean) {
|
|
|
2014
2042
|
}
|
|
2015
2043
|
function componentRender(nativeRenderer, component, from, context) {
|
|
2016
2044
|
component.render((template, portalHost) => {
|
|
2017
|
-
from.child = createChildChain(template, from.namespace);
|
|
2045
|
+
from.child = createChildChain(template, nativeRenderer, from.namespace);
|
|
2018
2046
|
context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
|
|
2019
2047
|
component.viewMetadata = Object.assign({ atom: from }, context);
|
|
2020
2048
|
let child = from.child;
|
|
@@ -2039,7 +2067,7 @@ function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, namespace, key)
|
|
|
2039
2067
|
prevAtom.sibling = atom;
|
|
2040
2068
|
return atom;
|
|
2041
2069
|
}
|
|
2042
|
-
function createChainByNode(jsxNode, prevAtom, elementNamespace) {
|
|
2070
|
+
function createChainByNode(jsxNode, prevAtom, nativeRenderer, elementNamespace) {
|
|
2043
2071
|
const type = typeof jsxNode;
|
|
2044
2072
|
if (jsxNode != null && type !== 'boolean') {
|
|
2045
2073
|
if (type === 'string') {
|
|
@@ -2047,11 +2075,11 @@ function createChainByNode(jsxNode, prevAtom, elementNamespace) {
|
|
|
2047
2075
|
}
|
|
2048
2076
|
if (type === 'object') {
|
|
2049
2077
|
if (Array.isArray(jsxNode)) {
|
|
2050
|
-
return createChainByChildren(jsxNode, prevAtom, elementNamespace);
|
|
2078
|
+
return createChainByChildren(jsxNode, prevAtom, nativeRenderer, elementNamespace);
|
|
2051
2079
|
}
|
|
2052
2080
|
const nodeType = typeof jsxNode.type;
|
|
2053
2081
|
if (nodeType === 'string') {
|
|
2054
|
-
return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom,
|
|
2082
|
+
return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom, nativeRenderer.getNameSpace(jsxNode.type, elementNamespace), jsxNode.key);
|
|
2055
2083
|
}
|
|
2056
2084
|
else if (nodeType === 'function') {
|
|
2057
2085
|
return createChainByJSXNode(ComponentAtomType, jsxNode, jsxNode.type, prevAtom, elementNamespace, jsxNode.key);
|
|
@@ -2062,17 +2090,17 @@ function createChainByNode(jsxNode, prevAtom, elementNamespace) {
|
|
|
2062
2090
|
}
|
|
2063
2091
|
return prevAtom;
|
|
2064
2092
|
}
|
|
2065
|
-
function createChainByChildren(children, prevAtom, elementNamespace) {
|
|
2093
|
+
function createChainByChildren(children, prevAtom, nativeRenderer, elementNamespace) {
|
|
2066
2094
|
const len = children.length;
|
|
2067
2095
|
for (let i = 0; i < len; i++) {
|
|
2068
2096
|
const item = children[i];
|
|
2069
|
-
prevAtom = createChainByNode(item, prevAtom, elementNamespace);
|
|
2097
|
+
prevAtom = createChainByNode(item, prevAtom, nativeRenderer, elementNamespace);
|
|
2070
2098
|
}
|
|
2071
2099
|
return prevAtom;
|
|
2072
2100
|
}
|
|
2073
|
-
function createChildChain(template, namespace) {
|
|
2101
|
+
function createChildChain(template, nativeRenderer, namespace) {
|
|
2074
2102
|
const beforeAtom = { sibling: null, index: -1 };
|
|
2075
|
-
createChainByNode(template, beforeAtom, namespace);
|
|
2103
|
+
createChainByNode(template, beforeAtom, nativeRenderer, namespace);
|
|
2076
2104
|
return beforeAtom.sibling;
|
|
2077
2105
|
}
|
|
2078
2106
|
function insertNode(nativeRenderer, atom, context) {
|
|
@@ -2088,11 +2116,9 @@ function insertNode(nativeRenderer, atom, context) {
|
|
|
2088
2116
|
nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.namespace);
|
|
2089
2117
|
}
|
|
2090
2118
|
}
|
|
2091
|
-
function createElementChildren(type, children, namespace) {
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
}
|
|
2095
|
-
return createChildChain(children, namespace);
|
|
2119
|
+
function createElementChildren(type, children, nativeRenderer, namespace) {
|
|
2120
|
+
const ns = nativeRenderer.getNameSpace(type, namespace);
|
|
2121
|
+
return createChildChain(children, nativeRenderer, ns);
|
|
2096
2122
|
}
|
|
2097
2123
|
function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
2098
2124
|
const { namespace, jsxNode } = atom;
|
|
@@ -2101,7 +2127,7 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
|
2101
2127
|
let bindingRefs;
|
|
2102
2128
|
for (const key in props) {
|
|
2103
2129
|
if (key === 'children') {
|
|
2104
|
-
atom.child = createElementChildren(jsxNode.type, props.children, namespace);
|
|
2130
|
+
atom.child = createElementChildren(jsxNode.type, props.children, nativeRenderer, namespace);
|
|
2105
2131
|
continue;
|
|
2106
2132
|
}
|
|
2107
2133
|
if (key === 'class') {
|
|
@@ -2192,7 +2218,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2192
2218
|
}, (key, value) => {
|
|
2193
2219
|
if (key === 'children') {
|
|
2194
2220
|
updatedChildren = true;
|
|
2195
|
-
newAtom.child = createElementChildren(newVNode.type, value, isSvg);
|
|
2221
|
+
newAtom.child = createElementChildren(newVNode.type, value, nativeRenderer, isSvg);
|
|
2196
2222
|
buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
|
|
2197
2223
|
return;
|
|
2198
2224
|
}
|
|
@@ -2221,7 +2247,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2221
2247
|
}, (key, newValue, oldValue) => {
|
|
2222
2248
|
if (key === 'children') {
|
|
2223
2249
|
updatedChildren = true;
|
|
2224
|
-
newAtom.child = createElementChildren(newVNode.type, newValue, isSvg);
|
|
2250
|
+
newAtom.child = createElementChildren(newVNode.type, newValue, nativeRenderer, isSvg);
|
|
2225
2251
|
if (!newAtom.child) {
|
|
2226
2252
|
cleanElementChildren(oldAtom, nativeRenderer);
|
|
2227
2253
|
}
|
|
@@ -2265,7 +2291,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2265
2291
|
});
|
|
2266
2292
|
if (!updatedChildren) {
|
|
2267
2293
|
newAtom.child = oldAtom.child;
|
|
2268
|
-
reuseElementChildrenView(nativeRenderer, newAtom)
|
|
2294
|
+
// reuseElementChildrenView(nativeRenderer, newAtom, context)
|
|
2269
2295
|
}
|
|
2270
2296
|
applyRefs(unBindRefs, nativeNode, false);
|
|
2271
2297
|
applyRefs(bindRefs, nativeNode, true);
|
|
@@ -2482,29 +2508,120 @@ function shallowReactive(raw) {
|
|
|
2482
2508
|
return proxy;
|
|
2483
2509
|
}
|
|
2484
2510
|
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2511
|
+
/**
|
|
2512
|
+
* 组件状态管理器
|
|
2513
|
+
* @param state 初始状态
|
|
2514
|
+
* @example
|
|
2515
|
+
* ```tsx
|
|
2516
|
+
* function App() {
|
|
2517
|
+
* // 初始化状态
|
|
2518
|
+
* const state = createSignal(1)
|
|
2519
|
+
*
|
|
2520
|
+
* return () => {
|
|
2521
|
+
* <div>
|
|
2522
|
+
* <div>当前值为:{state()}</div>
|
|
2523
|
+
* <div>
|
|
2524
|
+
* <button type="button" onClick={() => {
|
|
2525
|
+
* // 当点击时更新状态
|
|
2526
|
+
* state.set(state() + 1)
|
|
2527
|
+
* }
|
|
2528
|
+
* }>updateState</button>
|
|
2529
|
+
* </div>
|
|
2530
|
+
* </div>
|
|
2531
|
+
* }
|
|
2532
|
+
* }
|
|
2533
|
+
*/
|
|
2534
|
+
function createSignal(state) {
|
|
2535
|
+
const subscribers = new Set();
|
|
2536
|
+
function signal() {
|
|
2537
|
+
const listener = getDepContext();
|
|
2538
|
+
if (listener && !subscribers.has(listener)) {
|
|
2539
|
+
listener.destroyCallbacks.push(() => {
|
|
2540
|
+
subscribers.delete(listener);
|
|
2541
|
+
});
|
|
2542
|
+
subscribers.add(listener);
|
|
2543
|
+
}
|
|
2544
|
+
return state;
|
|
2545
|
+
}
|
|
2546
|
+
signal.set = function (newValue) {
|
|
2547
|
+
if (newValue === state) {
|
|
2492
2548
|
return;
|
|
2493
2549
|
}
|
|
2550
|
+
state = newValue;
|
|
2551
|
+
const listeners = Array.from(subscribers);
|
|
2552
|
+
listeners.forEach(listener => listener.effect());
|
|
2553
|
+
};
|
|
2554
|
+
return signal;
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
/**
|
|
2558
|
+
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
2559
|
+
* 并在你获取 createDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
2560
|
+
*
|
|
2561
|
+
* @param fn
|
|
2562
|
+
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
2563
|
+
*/
|
|
2564
|
+
function createDerived(fn, isContinue) {
|
|
2565
|
+
let isStop = false;
|
|
2566
|
+
function canListen(value) {
|
|
2567
|
+
if (isContinue) {
|
|
2568
|
+
const b = isContinue(value);
|
|
2569
|
+
if (b === false) {
|
|
2570
|
+
listener.destroy();
|
|
2571
|
+
return false;
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
return true;
|
|
2575
|
+
}
|
|
2576
|
+
const listener = new Dep(() => {
|
|
2577
|
+
if (isStop) {
|
|
2578
|
+
return;
|
|
2579
|
+
}
|
|
2580
|
+
isStop = true;
|
|
2581
|
+
listener.destroy();
|
|
2582
|
+
pushDepContext(listener);
|
|
2583
|
+
const value = fn();
|
|
2584
|
+
popDepContext();
|
|
2585
|
+
signal.set(value);
|
|
2586
|
+
canListen(value);
|
|
2587
|
+
isStop = false;
|
|
2588
|
+
});
|
|
2589
|
+
pushDepContext(listener);
|
|
2590
|
+
const value = fn();
|
|
2591
|
+
const signal = createSignal(value);
|
|
2592
|
+
popDepContext();
|
|
2593
|
+
isStop = false;
|
|
2594
|
+
if (canListen(value)) {
|
|
2595
|
+
registryComponentDestroyCallback(() => listener.destroy());
|
|
2596
|
+
}
|
|
2597
|
+
return signal;
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
/* eslint-enable max-len*/
|
|
2601
|
+
function createEffect(deps, callback) {
|
|
2602
|
+
let prevFn;
|
|
2603
|
+
const isArray = Array.isArray(deps);
|
|
2604
|
+
const effect = new Dep(function () {
|
|
2494
2605
|
if (prevFn) {
|
|
2495
2606
|
prevFn();
|
|
2496
2607
|
}
|
|
2608
|
+
const newValue = isArray ? deps.map(fn => fn()) : deps();
|
|
2497
2609
|
prevFn = callback(newValue, oldValue);
|
|
2498
2610
|
oldValue = newValue;
|
|
2499
2611
|
});
|
|
2500
|
-
pushDepContext(
|
|
2501
|
-
let oldValue =
|
|
2612
|
+
pushDepContext(effect);
|
|
2613
|
+
let oldValue = isArray ? deps.map(fn => fn()) : deps();
|
|
2502
2614
|
popDepContext();
|
|
2503
|
-
|
|
2504
|
-
prevFn === null || prevFn === void 0 ? void 0 : prevFn();
|
|
2505
|
-
});
|
|
2615
|
+
let isUnWatch = false;
|
|
2506
2616
|
function unWatch() {
|
|
2507
|
-
|
|
2617
|
+
if (isUnWatch) {
|
|
2618
|
+
return;
|
|
2619
|
+
}
|
|
2620
|
+
isUnWatch = true;
|
|
2621
|
+
if (prevFn) {
|
|
2622
|
+
prevFn();
|
|
2623
|
+
}
|
|
2624
|
+
effect.destroy();
|
|
2508
2625
|
}
|
|
2509
2626
|
registryComponentDestroyCallback(unWatch);
|
|
2510
2627
|
return unWatch;
|
|
@@ -2514,7 +2631,6 @@ exports.ArrayReactiveHandler = ArrayReactiveHandler;
|
|
|
2514
2631
|
exports.Component = Component;
|
|
2515
2632
|
exports.Dep = Dep;
|
|
2516
2633
|
exports.DynamicRef = DynamicRef;
|
|
2517
|
-
exports.ElementNamespaceMap = ElementNamespaceMap;
|
|
2518
2634
|
exports.ForwardRef = ForwardRef;
|
|
2519
2635
|
exports.Fragment = Fragment;
|
|
2520
2636
|
exports.Inject = Inject;
|
|
@@ -2540,9 +2656,13 @@ exports.Type = Type;
|
|
|
2540
2656
|
exports.comparePropsWithCallbacks = comparePropsWithCallbacks;
|
|
2541
2657
|
exports.computed = computed;
|
|
2542
2658
|
exports.createContext = createContext;
|
|
2659
|
+
exports.createContextProvider = createContextProvider;
|
|
2660
|
+
exports.createDerived = createDerived;
|
|
2543
2661
|
exports.createDynamicRef = createDynamicRef;
|
|
2662
|
+
exports.createEffect = createEffect;
|
|
2544
2663
|
exports.createRef = createRef;
|
|
2545
2664
|
exports.createRenderer = createRenderer;
|
|
2665
|
+
exports.createSignal = createSignal;
|
|
2546
2666
|
exports.defaultArrayReactiveHandler = defaultArrayReactiveHandler;
|
|
2547
2667
|
exports.defaultMapReactiveHandler = defaultMapReactiveHandler;
|
|
2548
2668
|
exports.defaultObjectReactiveHandler = defaultObjectReactiveHandler;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viewfly/core",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.6",
|
|
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": "
|
|
53
|
+
"gitHead": "287516a11d9fddbe9f38c341e06d1b7256cfe7ac",
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"reflect-metadata": "^0.2.2"
|
|
56
56
|
}
|