@viewfly/core 0.0.1-alpha.2 → 0.0.1-alpha.4
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.esm.js +50 -14
- package/bundles/index.js +50 -13
- package/bundles/model/component.d.ts +24 -3
- package/package.json +3 -2
package/bundles/index.esm.js
CHANGED
|
@@ -230,7 +230,7 @@ class Component extends ReflectiveInjector {
|
|
|
230
230
|
}
|
|
231
231
|
init() {
|
|
232
232
|
const self = this;
|
|
233
|
-
const props = new Proxy({}, {
|
|
233
|
+
const props = new Proxy(this.config || {}, {
|
|
234
234
|
get(_, key) {
|
|
235
235
|
if (self.config) {
|
|
236
236
|
return self.config[key];
|
|
@@ -482,8 +482,12 @@ const depsKey = Symbol('deps');
|
|
|
482
482
|
*/
|
|
483
483
|
function useSignal(state) {
|
|
484
484
|
const usedComponents = new Set();
|
|
485
|
-
function
|
|
485
|
+
function signal() {
|
|
486
486
|
const component = getRendingContext();
|
|
487
|
+
const derivedContext = getDerivedContext();
|
|
488
|
+
if (derivedContext) {
|
|
489
|
+
derivedContext.push(signal);
|
|
490
|
+
}
|
|
487
491
|
if (component && !usedComponents.has(component)) {
|
|
488
492
|
usedComponents.add(component);
|
|
489
493
|
component.destroyCallbacks.push(() => {
|
|
@@ -492,7 +496,7 @@ function useSignal(state) {
|
|
|
492
496
|
}
|
|
493
497
|
return state;
|
|
494
498
|
}
|
|
495
|
-
|
|
499
|
+
signal.set = function (newState) {
|
|
496
500
|
if (newState === state) {
|
|
497
501
|
return;
|
|
498
502
|
}
|
|
@@ -500,28 +504,58 @@ function useSignal(state) {
|
|
|
500
504
|
for (const component of usedComponents) {
|
|
501
505
|
component.markAsDirtied();
|
|
502
506
|
}
|
|
503
|
-
for (const fn of
|
|
507
|
+
for (const fn of signal[depsKey]) {
|
|
504
508
|
fn();
|
|
505
509
|
}
|
|
506
510
|
};
|
|
507
|
-
|
|
508
|
-
return
|
|
511
|
+
signal[depsKey] = new Set();
|
|
512
|
+
return signal;
|
|
513
|
+
}
|
|
514
|
+
const derivedStack = [];
|
|
515
|
+
function getDerivedContext() {
|
|
516
|
+
return derivedStack[derivedStack.length - 1];
|
|
509
517
|
}
|
|
510
518
|
/**
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
* @param
|
|
515
|
-
* @param
|
|
519
|
+
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
520
|
+
* 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
521
|
+
*
|
|
522
|
+
* @param callback
|
|
523
|
+
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
516
524
|
*/
|
|
525
|
+
function useDerived(callback, isContinue) {
|
|
526
|
+
const deps = [];
|
|
527
|
+
derivedStack.push(deps);
|
|
528
|
+
const data = callback();
|
|
529
|
+
derivedStack.pop();
|
|
530
|
+
const signal = useSignal(data);
|
|
531
|
+
if (deps.length) {
|
|
532
|
+
const unListen = useEffect(deps, () => {
|
|
533
|
+
const data = callback();
|
|
534
|
+
signal.set(data);
|
|
535
|
+
if (typeof isContinue === 'function' && !isContinue(data)) {
|
|
536
|
+
unListen();
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
return signal;
|
|
541
|
+
}
|
|
542
|
+
/* eslint-enable max-len*/
|
|
517
543
|
function useEffect(deps, effect) {
|
|
544
|
+
if (typeof deps === 'function' &&
|
|
545
|
+
typeof deps.set === 'undefined' &&
|
|
546
|
+
typeof deps[depsKey] === 'undefined') {
|
|
547
|
+
deps = useDerived(deps);
|
|
548
|
+
}
|
|
518
549
|
const signals = Array.isArray(deps) ? deps : [deps];
|
|
550
|
+
let oldValues = signals.map(s => s());
|
|
519
551
|
let prevCleanup;
|
|
520
552
|
function effectCallback() {
|
|
521
553
|
if (typeof prevCleanup === 'function') {
|
|
522
554
|
prevCleanup();
|
|
523
555
|
}
|
|
524
|
-
|
|
556
|
+
const newValues = signals.map(s => s());
|
|
557
|
+
prevCleanup = Array.isArray(deps) ? effect(newValues, oldValues) : effect(newValues[0], oldValues[0]);
|
|
558
|
+
oldValues = newValues;
|
|
525
559
|
}
|
|
526
560
|
for (const dep of signals) {
|
|
527
561
|
dep[depsKey].add(effectCallback);
|
|
@@ -568,7 +602,7 @@ function inject(token, notFoundValue, flags) {
|
|
|
568
602
|
*/
|
|
569
603
|
class RootComponent extends Component {
|
|
570
604
|
constructor(factory) {
|
|
571
|
-
super(new NullInjector(), factory,
|
|
605
|
+
super(new NullInjector(), factory, null);
|
|
572
606
|
this.changeEmitter = new Subject();
|
|
573
607
|
}
|
|
574
608
|
markAsChanged() {
|
|
@@ -905,7 +939,9 @@ let Renderer = class Renderer {
|
|
|
905
939
|
if (isChanged) {
|
|
906
940
|
diffAtom.jsxNode.invokePropsChangedHooks(start.jsxNode.config);
|
|
907
941
|
}
|
|
942
|
+
const newProps = start.jsxNode.props;
|
|
908
943
|
start.jsxNode = diffAtom.jsxNode;
|
|
944
|
+
start.jsxNode.props = newProps;
|
|
909
945
|
const { render } = this.componentAtomCaches.get(start.jsxNode);
|
|
910
946
|
const template = render();
|
|
911
947
|
if (template) {
|
|
@@ -1205,4 +1241,4 @@ class Viewfly extends ReflectiveInjector {
|
|
|
1205
1241
|
}
|
|
1206
1242
|
}
|
|
1207
1243
|
|
|
1208
|
-
export { Component, Fragment, JSXComponent, JSXElement, JSXText, NativeRenderer, Props, Ref, Renderer, RootComponent, RootComponentRef, Viewfly, inject, jsx, jsxs, onDestroy, onMount, onPropsChanged, onUpdated, provide, useEffect, useRef, useSignal };
|
|
1244
|
+
export { Component, Fragment, JSXComponent, JSXElement, JSXText, NativeRenderer, Props, Ref, Renderer, RootComponent, RootComponentRef, Viewfly, inject, jsx, jsxs, onDestroy, onMount, onPropsChanged, onUpdated, provide, useDerived, useEffect, useRef, useSignal };
|
package/bundles/index.js
CHANGED
|
@@ -231,7 +231,7 @@ class Component extends di.ReflectiveInjector {
|
|
|
231
231
|
}
|
|
232
232
|
init() {
|
|
233
233
|
const self = this;
|
|
234
|
-
const props = new Proxy({}, {
|
|
234
|
+
const props = new Proxy(this.config || {}, {
|
|
235
235
|
get(_, key) {
|
|
236
236
|
if (self.config) {
|
|
237
237
|
return self.config[key];
|
|
@@ -483,8 +483,12 @@ const depsKey = Symbol('deps');
|
|
|
483
483
|
*/
|
|
484
484
|
function useSignal(state) {
|
|
485
485
|
const usedComponents = new Set();
|
|
486
|
-
function
|
|
486
|
+
function signal() {
|
|
487
487
|
const component = getRendingContext();
|
|
488
|
+
const derivedContext = getDerivedContext();
|
|
489
|
+
if (derivedContext) {
|
|
490
|
+
derivedContext.push(signal);
|
|
491
|
+
}
|
|
488
492
|
if (component && !usedComponents.has(component)) {
|
|
489
493
|
usedComponents.add(component);
|
|
490
494
|
component.destroyCallbacks.push(() => {
|
|
@@ -493,7 +497,7 @@ function useSignal(state) {
|
|
|
493
497
|
}
|
|
494
498
|
return state;
|
|
495
499
|
}
|
|
496
|
-
|
|
500
|
+
signal.set = function (newState) {
|
|
497
501
|
if (newState === state) {
|
|
498
502
|
return;
|
|
499
503
|
}
|
|
@@ -501,28 +505,58 @@ function useSignal(state) {
|
|
|
501
505
|
for (const component of usedComponents) {
|
|
502
506
|
component.markAsDirtied();
|
|
503
507
|
}
|
|
504
|
-
for (const fn of
|
|
508
|
+
for (const fn of signal[depsKey]) {
|
|
505
509
|
fn();
|
|
506
510
|
}
|
|
507
511
|
};
|
|
508
|
-
|
|
509
|
-
return
|
|
512
|
+
signal[depsKey] = new Set();
|
|
513
|
+
return signal;
|
|
514
|
+
}
|
|
515
|
+
const derivedStack = [];
|
|
516
|
+
function getDerivedContext() {
|
|
517
|
+
return derivedStack[derivedStack.length - 1];
|
|
510
518
|
}
|
|
511
519
|
/**
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
* @param
|
|
516
|
-
* @param
|
|
520
|
+
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
521
|
+
* 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
522
|
+
*
|
|
523
|
+
* @param callback
|
|
524
|
+
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
517
525
|
*/
|
|
526
|
+
function useDerived(callback, isContinue) {
|
|
527
|
+
const deps = [];
|
|
528
|
+
derivedStack.push(deps);
|
|
529
|
+
const data = callback();
|
|
530
|
+
derivedStack.pop();
|
|
531
|
+
const signal = useSignal(data);
|
|
532
|
+
if (deps.length) {
|
|
533
|
+
const unListen = useEffect(deps, () => {
|
|
534
|
+
const data = callback();
|
|
535
|
+
signal.set(data);
|
|
536
|
+
if (typeof isContinue === 'function' && !isContinue(data)) {
|
|
537
|
+
unListen();
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
return signal;
|
|
542
|
+
}
|
|
543
|
+
/* eslint-enable max-len*/
|
|
518
544
|
function useEffect(deps, effect) {
|
|
545
|
+
if (typeof deps === 'function' &&
|
|
546
|
+
typeof deps.set === 'undefined' &&
|
|
547
|
+
typeof deps[depsKey] === 'undefined') {
|
|
548
|
+
deps = useDerived(deps);
|
|
549
|
+
}
|
|
519
550
|
const signals = Array.isArray(deps) ? deps : [deps];
|
|
551
|
+
let oldValues = signals.map(s => s());
|
|
520
552
|
let prevCleanup;
|
|
521
553
|
function effectCallback() {
|
|
522
554
|
if (typeof prevCleanup === 'function') {
|
|
523
555
|
prevCleanup();
|
|
524
556
|
}
|
|
525
|
-
|
|
557
|
+
const newValues = signals.map(s => s());
|
|
558
|
+
prevCleanup = Array.isArray(deps) ? effect(newValues, oldValues) : effect(newValues[0], oldValues[0]);
|
|
559
|
+
oldValues = newValues;
|
|
526
560
|
}
|
|
527
561
|
for (const dep of signals) {
|
|
528
562
|
dep[depsKey].add(effectCallback);
|
|
@@ -569,7 +603,7 @@ function inject(token, notFoundValue, flags) {
|
|
|
569
603
|
*/
|
|
570
604
|
class RootComponent extends Component {
|
|
571
605
|
constructor(factory) {
|
|
572
|
-
super(new di.NullInjector(), factory,
|
|
606
|
+
super(new di.NullInjector(), factory, null);
|
|
573
607
|
this.changeEmitter = new stream.Subject();
|
|
574
608
|
}
|
|
575
609
|
markAsChanged() {
|
|
@@ -906,7 +940,9 @@ exports.Renderer = class Renderer {
|
|
|
906
940
|
if (isChanged) {
|
|
907
941
|
diffAtom.jsxNode.invokePropsChangedHooks(start.jsxNode.config);
|
|
908
942
|
}
|
|
943
|
+
const newProps = start.jsxNode.props;
|
|
909
944
|
start.jsxNode = diffAtom.jsxNode;
|
|
945
|
+
start.jsxNode.props = newProps;
|
|
910
946
|
const { render } = this.componentAtomCaches.get(start.jsxNode);
|
|
911
947
|
const template = render();
|
|
912
948
|
if (template) {
|
|
@@ -1225,6 +1261,7 @@ exports.onMount = onMount;
|
|
|
1225
1261
|
exports.onPropsChanged = onPropsChanged;
|
|
1226
1262
|
exports.onUpdated = onUpdated;
|
|
1227
1263
|
exports.provide = provide;
|
|
1264
|
+
exports.useDerived = useDerived;
|
|
1228
1265
|
exports.useEffect = useEffect;
|
|
1229
1266
|
exports.useRef = useRef;
|
|
1230
1267
|
exports.useSignal = useSignal;
|
|
@@ -6,7 +6,7 @@ export declare class JSXComponent {
|
|
|
6
6
|
}
|
|
7
7
|
export type JSXTemplate = JSXElement | JSXComponent | null | void;
|
|
8
8
|
export interface ComponentSetup {
|
|
9
|
-
(props
|
|
9
|
+
(props?: JSXProps<any>): () => JSXTemplate;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Viewfly 组件管理类,用于管理组件的生命周期,上下文等
|
|
@@ -175,14 +175,35 @@ export interface Signal<T> {
|
|
|
175
175
|
* }
|
|
176
176
|
*/
|
|
177
177
|
export declare function useSignal<T>(state: T): Signal<T>;
|
|
178
|
+
/**
|
|
179
|
+
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
180
|
+
* 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
181
|
+
*
|
|
182
|
+
* @param callback
|
|
183
|
+
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
184
|
+
*/
|
|
185
|
+
export declare function useDerived<T>(callback: () => T, isContinue?: (data: T) => unknown): Signal<T>;
|
|
186
|
+
export interface EffectCallback<T, U> {
|
|
187
|
+
(newValue: T, oldValue: U): void | (() => void);
|
|
188
|
+
}
|
|
178
189
|
/**
|
|
179
190
|
* 监听状态变化,当任意一个状态发生变更时,触发回调。
|
|
180
191
|
* useEffect 会返回一个取消监听的函数,调用此函数,可以取消监听。
|
|
181
192
|
* 当在组件中调用时,组件销毁时会自动取消监听。
|
|
182
|
-
* @param deps 依赖的状态 Signal,可以是一个 Signal,只可以一个数包含 Signal
|
|
193
|
+
* @param deps 依赖的状态 Signal,可以是一个 Signal,只可以一个数包含 Signal 的数组,或者是一个求值函数
|
|
183
194
|
* @param effect 状态变更后的回调函数
|
|
184
195
|
*/
|
|
185
|
-
export declare function useEffect(deps: Signal<
|
|
196
|
+
export declare function useEffect<T>(deps: Signal<T>, effect: EffectCallback<T, T>): () => void;
|
|
197
|
+
export declare function useEffect<T>(deps: [Signal<T>], effect: EffectCallback<[T], [T]>): () => void;
|
|
198
|
+
export declare function useEffect<T, T1>(deps: [Signal<T>, Signal<T1>], effect: EffectCallback<[T, T1], [T, T1]>): () => void;
|
|
199
|
+
export declare function useEffect<T, T1, T2>(deps: [Signal<T>, Signal<T1>, Signal<T2>], effect: EffectCallback<[T, T1, T2], [T, T1, T2]>): () => void;
|
|
200
|
+
export declare function useEffect<T, T1, T2, T3>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>], effect: EffectCallback<[T, T1, T2, T3], [T, T1, T2, T3]>): () => void;
|
|
201
|
+
export declare function useEffect<T, T1, T2, T3, T4>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>], effect: EffectCallback<[T, T1, T2, T3, T4], [T, T1, T2, T3, T4]>): () => void;
|
|
202
|
+
export declare function useEffect<T, T1, T2, T3, T4, T5>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>, Signal<T5>], effect: EffectCallback<[T, T1, T2, T3, T4, T5], [T, T1, T2, T3, T4, T5]>): () => void;
|
|
203
|
+
export declare function useEffect<T, T1, T2, T3, T4, T5, T6>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>, Signal<T5>, Signal<T6>], effect: EffectCallback<[T, T1, T2, T3, T4, T5, T6], [T, T1, T2, T3, T4, T5, T6]>): () => void;
|
|
204
|
+
export declare function useEffect<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>], effect: EffectCallback<[T, T1, T2, T3, T4, T5, T6, T7], [T, T1, T2, T3, T4, T5, T6, T7]>): () => void;
|
|
205
|
+
export declare function useEffect<T>(deps: () => T, effect: EffectCallback<T, T>): () => void;
|
|
206
|
+
export declare function useEffect<T = any>(deps: Signal<any>[], effect: EffectCallback<T[], T[]>): () => void;
|
|
186
207
|
/**
|
|
187
208
|
* 通过 IoC 容器当前组件提供上下文共享数据的方法
|
|
188
209
|
* @param provider
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viewfly/core",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.4",
|
|
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",
|
|
@@ -36,5 +36,6 @@
|
|
|
36
36
|
},
|
|
37
37
|
"bugs": {
|
|
38
38
|
"url": "https://github.com/viewfly/viewfly.git/issues"
|
|
39
|
-
}
|
|
39
|
+
},
|
|
40
|
+
"gitHead": "68a7c531c0040fc0b1b7addb87a8df3c5981600e"
|
|
40
41
|
}
|