@viewfly/core 0.0.6 → 0.0.7

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.
@@ -107,16 +107,6 @@ function styleToObject(style) {
107
107
  return obj;
108
108
  }
109
109
 
110
- class Memo {
111
- constructor(shouldUpdate, render) {
112
- this.shouldUpdate = shouldUpdate;
113
- this.render = render;
114
- }
115
- }
116
- function withMemo(shouldUpdate, render) {
117
- return new Memo(shouldUpdate, render);
118
- }
119
-
120
110
  const componentSetupStack = [];
121
111
  const signalDepsStack = [];
122
112
  const componentErrorFn = makeError('component');
@@ -193,11 +183,23 @@ class Component extends ReflectiveInjector {
193
183
  componentSetupStack.push(this);
194
184
  let isSetup = true;
195
185
  const render = this.type(props);
186
+ const isRenderFn = typeof render === 'function';
187
+ const componentInstance = isRenderFn ? { $render: render } : render;
188
+ let refs = toRefs(this.props.ref);
189
+ onMounted(() => {
190
+ for (const ref of refs) {
191
+ ref.bind(componentInstance);
192
+ }
193
+ });
194
+ onDestroy(() => {
195
+ for (const ref of refs) {
196
+ ref.unBind(componentInstance);
197
+ }
198
+ });
196
199
  isSetup = false;
197
200
  componentSetupStack.pop();
198
201
  signalDepsStack.push([]);
199
- const templateRender = render instanceof Memo ? render.render : render;
200
- let template = templateRender();
202
+ let template = componentInstance.$render();
201
203
  const deps = signalDepsStack.pop();
202
204
  this.unWatch = useEffect(deps, () => {
203
205
  this.markAsDirtied();
@@ -210,15 +212,27 @@ class Component extends ReflectiveInjector {
210
212
  if (add.length || remove.length || replace.length) {
211
213
  this.invokePropsChangedHooks(newProps);
212
214
  }
215
+ const newRefs = toRefs(newProps.ref);
216
+ for (const oldRef of refs) {
217
+ if (!newRefs.includes(oldRef)) {
218
+ oldRef.unBind(componentInstance);
219
+ }
220
+ }
221
+ for (const newRef of newRefs) {
222
+ if (!refs.includes(newRef)) {
223
+ newRef.bind(componentInstance);
224
+ }
225
+ }
226
+ refs = newRefs;
213
227
  }
214
- if (render instanceof Memo) {
215
- if (!render.shouldUpdate(newProps, oldProps)) {
228
+ if (typeof componentInstance.$shouldUpdate === 'function') {
229
+ if (!componentInstance.$shouldUpdate(newProps, oldProps)) {
216
230
  return template;
217
231
  }
218
232
  }
219
233
  this.unWatch();
220
234
  signalDepsStack.push([]);
221
- template = templateRender();
235
+ template = componentInstance.$render();
222
236
  const deps = signalDepsStack.pop();
223
237
  this.unWatch = useEffect(deps, () => {
224
238
  this.markAsDirtied();
@@ -302,6 +316,11 @@ class Component extends ReflectiveInjector {
302
316
  }
303
317
  }
304
318
  }
319
+ function toRefs(ref) {
320
+ return (Array.isArray(ref) ? ref : [ref]).filter(i => {
321
+ return i instanceof Ref;
322
+ });
323
+ }
305
324
  /**
306
325
  * 当组件第一次渲染完成时触发
307
326
  * @param callback
@@ -383,7 +402,7 @@ function onDestroy(callback) {
383
402
  class Ref {
384
403
  constructor(callback) {
385
404
  this.callback = callback;
386
- this.unBindMap = new WeakMap();
405
+ this.unBindMap = new Map();
387
406
  this.targetCaches = new Set();
388
407
  }
389
408
  bind(value) {
@@ -626,6 +645,13 @@ class JSXElement {
626
645
  }
627
646
  }
628
647
 
648
+ function withMemo(shouldUpdate, render) {
649
+ return {
650
+ $shouldUpdate: shouldUpdate,
651
+ $render: render
652
+ };
653
+ }
654
+
629
655
  /**
630
656
  * Viewfly 根组件,用于实现组件状态更新事件通知
631
657
  */
@@ -1293,4 +1319,4 @@ class Viewfly extends ReflectiveInjector {
1293
1319
  }
1294
1320
  }
1295
1321
 
1296
- export { Component, Fragment, JSXComponent, JSXElement, JSXText, Memo, NativeRenderer, Ref, Renderer, RootComponent, RootComponentRef, Viewfly, inject, jsx, jsxs, makeError, onDestroy, onMounted, onPropsChanged, onUpdated, provide, useDerived, useEffect, useRef, useSignal, withMemo };
1322
+ export { Component, Fragment, JSXComponent, JSXElement, JSXText, NativeRenderer, Ref, Renderer, RootComponent, RootComponentRef, Viewfly, inject, jsx, jsxs, makeError, onDestroy, onMounted, onPropsChanged, onUpdated, provide, useDerived, useEffect, useRef, useSignal, withMemo };
package/bundles/index.js CHANGED
@@ -108,16 +108,6 @@ function styleToObject(style) {
108
108
  return obj;
109
109
  }
110
110
 
111
- class Memo {
112
- constructor(shouldUpdate, render) {
113
- this.shouldUpdate = shouldUpdate;
114
- this.render = render;
115
- }
116
- }
117
- function withMemo(shouldUpdate, render) {
118
- return new Memo(shouldUpdate, render);
119
- }
120
-
121
111
  const componentSetupStack = [];
122
112
  const signalDepsStack = [];
123
113
  const componentErrorFn = makeError('component');
@@ -194,11 +184,23 @@ class Component extends di.ReflectiveInjector {
194
184
  componentSetupStack.push(this);
195
185
  let isSetup = true;
196
186
  const render = this.type(props);
187
+ const isRenderFn = typeof render === 'function';
188
+ const componentInstance = isRenderFn ? { $render: render } : render;
189
+ let refs = toRefs(this.props.ref);
190
+ onMounted(() => {
191
+ for (const ref of refs) {
192
+ ref.bind(componentInstance);
193
+ }
194
+ });
195
+ onDestroy(() => {
196
+ for (const ref of refs) {
197
+ ref.unBind(componentInstance);
198
+ }
199
+ });
197
200
  isSetup = false;
198
201
  componentSetupStack.pop();
199
202
  signalDepsStack.push([]);
200
- const templateRender = render instanceof Memo ? render.render : render;
201
- let template = templateRender();
203
+ let template = componentInstance.$render();
202
204
  const deps = signalDepsStack.pop();
203
205
  this.unWatch = useEffect(deps, () => {
204
206
  this.markAsDirtied();
@@ -211,15 +213,27 @@ class Component extends di.ReflectiveInjector {
211
213
  if (add.length || remove.length || replace.length) {
212
214
  this.invokePropsChangedHooks(newProps);
213
215
  }
216
+ const newRefs = toRefs(newProps.ref);
217
+ for (const oldRef of refs) {
218
+ if (!newRefs.includes(oldRef)) {
219
+ oldRef.unBind(componentInstance);
220
+ }
221
+ }
222
+ for (const newRef of newRefs) {
223
+ if (!refs.includes(newRef)) {
224
+ newRef.bind(componentInstance);
225
+ }
226
+ }
227
+ refs = newRefs;
214
228
  }
215
- if (render instanceof Memo) {
216
- if (!render.shouldUpdate(newProps, oldProps)) {
229
+ if (typeof componentInstance.$shouldUpdate === 'function') {
230
+ if (!componentInstance.$shouldUpdate(newProps, oldProps)) {
217
231
  return template;
218
232
  }
219
233
  }
220
234
  this.unWatch();
221
235
  signalDepsStack.push([]);
222
- template = templateRender();
236
+ template = componentInstance.$render();
223
237
  const deps = signalDepsStack.pop();
224
238
  this.unWatch = useEffect(deps, () => {
225
239
  this.markAsDirtied();
@@ -303,6 +317,11 @@ class Component extends di.ReflectiveInjector {
303
317
  }
304
318
  }
305
319
  }
320
+ function toRefs(ref) {
321
+ return (Array.isArray(ref) ? ref : [ref]).filter(i => {
322
+ return i instanceof Ref;
323
+ });
324
+ }
306
325
  /**
307
326
  * 当组件第一次渲染完成时触发
308
327
  * @param callback
@@ -384,7 +403,7 @@ function onDestroy(callback) {
384
403
  class Ref {
385
404
  constructor(callback) {
386
405
  this.callback = callback;
387
- this.unBindMap = new WeakMap();
406
+ this.unBindMap = new Map();
388
407
  this.targetCaches = new Set();
389
408
  }
390
409
  bind(value) {
@@ -627,6 +646,13 @@ class JSXElement {
627
646
  }
628
647
  }
629
648
 
649
+ function withMemo(shouldUpdate, render) {
650
+ return {
651
+ $shouldUpdate: shouldUpdate,
652
+ $render: render
653
+ };
654
+ }
655
+
630
656
  /**
631
657
  * Viewfly 根组件,用于实现组件状态更新事件通知
632
658
  */
@@ -1299,7 +1325,6 @@ exports.Fragment = Fragment;
1299
1325
  exports.JSXComponent = JSXComponent;
1300
1326
  exports.JSXElement = JSXElement;
1301
1327
  exports.JSXText = JSXText;
1302
- exports.Memo = Memo;
1303
1328
  exports.NativeRenderer = NativeRenderer;
1304
1329
  exports.Ref = Ref;
1305
1330
  exports.RootComponent = RootComponent;
@@ -1,14 +1,20 @@
1
1
  import { Provider, ReflectiveInjector, AbstractType, Type, InjectionToken, InjectFlags, Injector } from '@tanbo/di';
2
2
  import { Props, Key, JSXTypeof, JSXChildNode } from './jsx-element';
3
- import { Memo } from './memo';
4
3
  export declare class JSXComponent {
5
4
  props: Props;
6
5
  private factory;
7
6
  constructor(props: Props, factory: (injector: Component, props: Props) => Component);
8
7
  createInstance(injector: Component): Component;
9
8
  }
9
+ export interface ComponentInstance<T> {
10
+ $render(): JSXChildNode;
11
+ $shouldUpdate?(currentProps: T, prevProps: T): unknown;
12
+ }
13
+ export interface Renderable {
14
+ $render(): any;
15
+ }
10
16
  export interface ComponentSetup<T extends Props<any> = Props<any>> {
11
- (props?: T): (() => JSXChildNode) | Memo<T>;
17
+ (props?: T): (() => JSXChildNode) | ComponentInstance<T>;
12
18
  }
13
19
  /**
14
20
  * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
@@ -109,13 +115,14 @@ export declare function onDestroy(callback: () => void): void;
109
115
  export interface RefListener<T> {
110
116
  (current: T): void | (() => void);
111
117
  }
112
- export declare class Ref<T extends object> {
118
+ export type ExtractInstanceType<T, U = T extends (...args: any) => any ? ReturnType<T> : T> = U extends Renderable ? Omit<U, keyof ComponentInstance<any>> : U extends Function ? never : T;
119
+ export declare class Ref<T, U> {
113
120
  private callback;
114
121
  private unBindMap;
115
122
  private targetCaches;
116
- constructor(callback: RefListener<T>);
117
- bind(value: T): void;
118
- unBind(value: T): void;
123
+ constructor(callback: RefListener<U>);
124
+ bind(value: U): void;
125
+ unBind(value: U): void;
119
126
  }
120
127
  /**
121
128
  * 用于节点渲染完成时获取 DOM 节点
@@ -138,7 +145,7 @@ export declare class Ref<T extends object> {
138
145
  * }
139
146
  * ```
140
147
  */
141
- export declare function useRef<T extends object>(callback: RefListener<T>): Ref<T>;
148
+ export declare function useRef<T, U = ExtractInstanceType<T>>(callback: RefListener<U>): Ref<T, U>;
142
149
  declare const depsKey: unique symbol;
143
150
  /**
144
151
  * 组件状态实例,直接调用可以获取最新的状态,通过 set 方法可以更新状态
@@ -1,10 +1,6 @@
1
1
  import { JSXChildNode, Props } from './jsx-element';
2
+ import { ComponentInstance } from './component';
2
3
  export interface ShouldUpdate<T extends Props> {
3
4
  (currentProps: T, prevProps: T): unknown;
4
5
  }
5
- export declare class Memo<T extends Props> {
6
- shouldUpdate: ShouldUpdate<T>;
7
- render: () => JSXChildNode;
8
- constructor(shouldUpdate: ShouldUpdate<T>, render: () => JSXChildNode);
9
- }
10
- export declare function withMemo<T extends Props = Props>(shouldUpdate: ShouldUpdate<T>, render: () => JSXChildNode): Memo<T>;
6
+ export declare function withMemo<T extends Props = Props>(shouldUpdate: ShouldUpdate<T>, render: () => JSXChildNode): ComponentInstance<T>;
@@ -1,11 +1,12 @@
1
- import { Key, Ref, JSXComponent } from '@viewfly/core';
1
+ import { Key, Ref, JSXComponent, ExtractInstanceType } from '@viewfly/core';
2
2
  export declare namespace ViewTypes {
3
3
  type ClassNames = string | Record<string, unknown> | Array<string | Record<string, unknown>>;
4
4
  interface IntrinsicAttributes {
5
5
  key?: Key;
6
+ ref?: any;
6
7
  }
7
- interface RefAttributes<T extends object> extends IntrinsicAttributes {
8
- ref?: Ref<T> | Ref<T>[];
8
+ interface RefAttributes<T> extends IntrinsicAttributes {
9
+ ref?: Ref<T, ExtractInstanceType<T>> | Ref<T, ExtractInstanceType<T>>[];
9
10
  }
10
11
  interface ElementClass extends JSXComponent {
11
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viewfly/core",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
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",
@@ -34,5 +34,5 @@
34
34
  "bugs": {
35
35
  "url": "https://github.com/viewfly/viewfly.git/issues"
36
36
  },
37
- "gitHead": "75d56812c92bfd5d099e0d7eb8d964251d88df28"
37
+ "gitHead": "78757f2aad67c1a6969b2ca76ada75c58364bc43"
38
38
  }