@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.
@@ -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 stateManager() {
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
- stateManager.set = function (newState) {
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 stateManager[depsKey]) {
507
+ for (const fn of signal[depsKey]) {
504
508
  fn();
505
509
  }
506
510
  };
507
- stateManager[depsKey] = new Set();
508
- return stateManager;
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
- * useEffect 会返回一个取消监听的函数,调用此函数,可以取消监听。
513
- * 当在组件中调用时,组件销毁时会自动取消监听。
514
- * @param deps 依赖的状态 Signal,可以是一个 Signal,只可以一个数包含 Signal 的数组
515
- * @param effect 状态变更后的回调函数
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
- prevCleanup = effect();
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, new Props(null));
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 stateManager() {
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
- stateManager.set = function (newState) {
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 stateManager[depsKey]) {
508
+ for (const fn of signal[depsKey]) {
505
509
  fn();
506
510
  }
507
511
  };
508
- stateManager[depsKey] = new Set();
509
- return stateManager;
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
- * useEffect 会返回一个取消监听的函数,调用此函数,可以取消监听。
514
- * 当在组件中调用时,组件销毁时会自动取消监听。
515
- * @param deps 依赖的状态 Signal,可以是一个 Signal,只可以一个数包含 Signal 的数组
516
- * @param effect 状态变更后的回调函数
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
- prevCleanup = effect();
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, new Props(null));
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: JSXProps<any>): () => JSXTemplate;
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<any> | Signal<any>[], effect: LifeCycleCallback): () => void;
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.2",
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
  }