@viewfly/core 0.0.1-alpha.1 → 0.0.1-alpha.2

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.
@@ -30,4 +30,5 @@ export declare class Renderer {
30
30
  private createElement;
31
31
  private createTextNode;
32
32
  private updateNativeNodeProperties;
33
+ private applyRefs;
33
34
  }
@@ -34,29 +34,34 @@ function __metadata(metadataKey, metadataValue) {
34
34
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
35
35
  }
36
36
 
37
- function Fragment(props) {
38
- return () => new JSXFragment(props);
39
- }
40
- class JSXFragment {
41
- constructor(props) {
42
- this.props = props;
43
- }
37
+ function makeError(name) {
38
+ return function viewflyError(message) {
39
+ const error = new Error(message);
40
+ error.name = `[ViewflyError: ${name}]`;
41
+ error.stack = error.stack.replace(/\n.*?(?=\n)/, '');
42
+ return error;
43
+ };
44
44
  }
45
+
46
+ const jsxErrorFn = makeError('JSX');
47
+ const Fragment = function Fragment() {
48
+ throw jsxErrorFn('Fragment does not support calling.');
49
+ };
45
50
  function jsx(setup, config) {
46
51
  if (typeof setup === 'string') {
47
52
  return new JSXElement(setup, config);
48
53
  }
49
- return function (context) {
54
+ return new JSXComponent(function (context) {
50
55
  return new Component(context, setup, config);
51
- };
56
+ });
52
57
  }
53
58
  function jsxs(setup, config) {
54
59
  if (typeof setup === 'string') {
55
60
  return new JSXElement(setup, config);
56
61
  }
57
- return function (context) {
62
+ return new JSXComponent(function (context) {
58
63
  return new Component(context, setup, config);
59
- };
64
+ });
60
65
  }
61
66
  class JSXText {
62
67
  constructor(text) {
@@ -66,7 +71,7 @@ class JSXText {
66
71
  function flatChildren(jsxNodes) {
67
72
  const children = [];
68
73
  for (const node of jsxNodes) {
69
- if (node instanceof JSXElement || typeof node === 'function') {
74
+ if (node instanceof JSXElement || node instanceof JSXComponent) {
70
75
  children.push(node);
71
76
  }
72
77
  else if (typeof node === 'string' && node.length) {
@@ -173,24 +178,24 @@ class JSXElement {
173
178
  }
174
179
  }
175
180
 
176
- function makeError(name) {
177
- return function viewflyError(message) {
178
- const error = new Error(message);
179
- error.name = `[ViewflyError: ${name}]`;
180
- error.stack = error.stack.replace(/\n.*?(?=\n)/, '');
181
- return error;
182
- };
183
- }
184
-
185
- const componentStack = [];
181
+ const componentSetupStack = [];
182
+ const componentRendingStack = [];
186
183
  const componentErrorFn = makeError('component');
187
- function getComponentContext(need = true) {
188
- const current = componentStack[componentStack.length - 1];
184
+ function getSetupContext(need = true) {
185
+ const current = componentSetupStack[componentSetupStack.length - 1];
189
186
  if (!current && need) {
190
187
  throw componentErrorFn('cannot be called outside the component!');
191
188
  }
192
189
  return current;
193
190
  }
191
+ function getRendingContext() {
192
+ return componentRendingStack[componentRendingStack.length - 1];
193
+ }
194
+ class JSXComponent {
195
+ constructor(createInstance) {
196
+ this.createInstance = createInstance;
197
+ }
198
+ }
194
199
  /**
195
200
  * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
196
201
  */
@@ -224,7 +229,6 @@ class Component extends ReflectiveInjector {
224
229
  });
225
230
  }
226
231
  init() {
227
- componentStack.push(this);
228
232
  const self = this;
229
233
  const props = new Proxy({}, {
230
234
  get(_, key) {
@@ -236,15 +240,18 @@ class Component extends ReflectiveInjector {
236
240
  throw componentErrorFn('component props is readonly!');
237
241
  }
238
242
  });
243
+ componentSetupStack.push(this);
239
244
  const render = this.setup(props);
245
+ componentSetupStack.pop();
246
+ componentRendingStack.push(this);
240
247
  const template = render();
241
- componentStack.pop();
248
+ componentRendingStack.pop();
242
249
  return {
243
250
  template,
244
251
  render: () => {
245
- componentStack.push(this);
252
+ componentRendingStack.push(this);
246
253
  const template = render();
247
- componentStack.pop();
254
+ componentRendingStack.pop();
248
255
  return template;
249
256
  }
250
257
  };
@@ -333,7 +340,7 @@ class Component extends ReflectiveInjector {
333
340
  * ```
334
341
  */
335
342
  function onMount(callback) {
336
- const component = getComponentContext();
343
+ const component = getSetupContext();
337
344
  component.mountCallbacks.push(callback);
338
345
  }
339
346
  /**
@@ -352,7 +359,7 @@ function onMount(callback) {
352
359
  * ```
353
360
  */
354
361
  function onUpdated(callback) {
355
- const component = getComponentContext();
362
+ const component = getSetupContext();
356
363
  component.updatedCallbacks.push(callback);
357
364
  return () => {
358
365
  const index = component.updatedCallbacks.indexOf(callback);
@@ -381,7 +388,7 @@ function onUpdated(callback) {
381
388
  * ```
382
389
  */
383
390
  function onPropsChanged(callback) {
384
- const component = getComponentContext();
391
+ const component = getSetupContext();
385
392
  component.propsChangedCallbacks.push(callback);
386
393
  return () => {
387
394
  const index = component.propsChangedCallbacks.indexOf(callback);
@@ -395,31 +402,33 @@ function onPropsChanged(callback) {
395
402
  * @param callback
396
403
  */
397
404
  function onDestroy(callback) {
398
- const component = getComponentContext();
405
+ const component = getSetupContext();
399
406
  component.destroyCallbacks.push(callback);
400
407
  }
401
408
  class Ref {
402
- // private prevValue: T | null = null
403
- constructor(callback, component) {
409
+ constructor(callback) {
404
410
  this.callback = callback;
405
- this.component = component;
406
- this.unListenFn = null;
407
- component.destroyCallbacks.push(() => {
408
- this.unListen();
409
- });
411
+ this.unBindMap = new WeakMap;
412
+ this.targetCaches = new Set();
410
413
  }
411
- update(value) {
412
- // if (value === this.prevValue) {
413
- // return
414
- // }
415
- // this.prevValue = value
416
- this.unListen();
417
- this.unListenFn = this.callback(value) || null;
414
+ bind(value) {
415
+ if (typeof value !== 'object' || value === null) {
416
+ return;
417
+ }
418
+ if (this.targetCaches.has(value)) {
419
+ return;
420
+ }
421
+ this.targetCaches.add(value);
422
+ const unBindFn = this.callback(value);
423
+ if (typeof unBindFn === 'function') {
424
+ this.unBindMap.set(value, unBindFn);
425
+ }
418
426
  }
419
- unListen() {
420
- if (typeof this.unListenFn === 'function') {
421
- this.unListenFn();
422
- this.unListenFn = null;
427
+ unBind(value) {
428
+ this.targetCaches.delete(value);
429
+ const unBindFn = this.unBindMap.get(value);
430
+ if (typeof unBindFn === 'function') {
431
+ unBindFn();
423
432
  }
424
433
  }
425
434
  }
@@ -445,8 +454,7 @@ class Ref {
445
454
  * ```
446
455
  */
447
456
  function useRef(callback) {
448
- const component = getComponentContext();
449
- return new Ref(callback, component);
457
+ return new Ref(callback);
450
458
  }
451
459
  const depsKey = Symbol('deps');
452
460
  /**
@@ -475,7 +483,7 @@ const depsKey = Symbol('deps');
475
483
  function useSignal(state) {
476
484
  const usedComponents = new Set();
477
485
  function stateManager() {
478
- const component = getComponentContext(false);
486
+ const component = getRendingContext();
479
487
  if (component && !usedComponents.has(component)) {
480
488
  usedComponents.add(component);
481
489
  component.destroyCallbacks.push(() => {
@@ -485,10 +493,7 @@ function useSignal(state) {
485
493
  return state;
486
494
  }
487
495
  stateManager.set = function (newState) {
488
- if (typeof newState === 'function') {
489
- newState = newState(state);
490
- }
491
- else if (newState === state) {
496
+ if (newState === state) {
492
497
  return;
493
498
  }
494
499
  state = newState;
@@ -521,7 +526,7 @@ function useEffect(deps, effect) {
521
526
  for (const dep of signals) {
522
527
  dep[depsKey].add(effectCallback);
523
528
  }
524
- const component = getComponentContext(false);
529
+ const component = getSetupContext(false);
525
530
  let isClean = false;
526
531
  const destroyFn = () => {
527
532
  if (isClean) {
@@ -546,7 +551,7 @@ function useEffect(deps, effect) {
546
551
  * @param provider
547
552
  */
548
553
  function provide(provider) {
549
- const component = getComponentContext();
554
+ const component = getSetupContext();
550
555
  component.addProvide(provider);
551
556
  return component;
552
557
  }
@@ -554,7 +559,7 @@ function provide(provider) {
554
559
  * 通过组件上下文获取 IoC 容器内数据的勾子方法
555
560
  */
556
561
  function inject(token, notFoundValue, flags) {
557
- const component = getComponentContext();
562
+ const component = getSetupContext();
558
563
  return component.parentInjector.get(token, notFoundValue, flags);
559
564
  }
560
565
 
@@ -859,9 +864,7 @@ let Renderer = class Renderer {
859
864
  }
860
865
  if (atom.jsxNode instanceof JSXElement) {
861
866
  const ref = atom.jsxNode.props.attrs.get(refKey);
862
- if (ref instanceof Ref) {
863
- ref.unListen();
864
- }
867
+ this.applyRefs(ref, atom.nativeNode, false);
865
868
  }
866
869
  }
867
870
  let child = atom.child;
@@ -1015,7 +1018,7 @@ let Renderer = class Renderer {
1015
1018
  return parent;
1016
1019
  }
1017
1020
  createChainByComponentFactory(context, factory, parent) {
1018
- const component = factory(context);
1021
+ const component = factory.createInstance(context);
1019
1022
  if (component.setup === Fragment) {
1020
1023
  return this.createChainByChildren(component, component.props.children, parent);
1021
1024
  }
@@ -1069,9 +1072,10 @@ let Renderer = class Renderer {
1069
1072
  const nativeNode = this.nativeRenderer.createElement(vNode.name);
1070
1073
  const props = vNode.props;
1071
1074
  if (props) {
1075
+ let bindingRefs;
1072
1076
  props.attrs.forEach((value, key) => {
1073
- if (key === refKey && value instanceof Ref) {
1074
- value.update(nativeNode);
1077
+ if (key === refKey) {
1078
+ bindingRefs = value;
1075
1079
  return;
1076
1080
  }
1077
1081
  this.nativeRenderer.setProperty(nativeNode, key, value);
@@ -1083,6 +1087,7 @@ let Renderer = class Renderer {
1083
1087
  Object.keys(props.listeners).forEach(type => {
1084
1088
  this.nativeRenderer.listen(nativeNode, type, props.listeners[type]);
1085
1089
  });
1090
+ this.applyRefs(bindingRefs, nativeNode, true);
1086
1091
  }
1087
1092
  return nativeNode;
1088
1093
  }
@@ -1096,16 +1101,18 @@ let Renderer = class Renderer {
1096
1101
  }
1097
1102
  styleChanges.remove.forEach(i => this.nativeRenderer.removeStyle(nativeNode, i[0]));
1098
1103
  styleChanges.set.forEach(i => this.nativeRenderer.setStyle(nativeNode, i[0], i[1]));
1104
+ let unBindRefs;
1099
1105
  attrChanges.remove.forEach(([key, value]) => {
1100
- if (key === refKey && value instanceof Ref) {
1101
- value.unListen();
1106
+ if (key === refKey) {
1107
+ unBindRefs = value;
1102
1108
  return;
1103
1109
  }
1104
1110
  this.nativeRenderer.removeProperty(nativeNode, key);
1105
1111
  });
1112
+ let bindRefs;
1106
1113
  attrChanges.set.forEach(([key, value]) => {
1107
- if (key === refKey && value instanceof Ref) {
1108
- value.update(nativeNode);
1114
+ if (key === refKey) {
1115
+ bindRefs = value;
1109
1116
  return;
1110
1117
  }
1111
1118
  this.nativeRenderer.setProperty(nativeNode, key, value);
@@ -1118,6 +1125,16 @@ let Renderer = class Renderer {
1118
1125
  listenerChanges.add.forEach(i => {
1119
1126
  this.nativeRenderer.listen(nativeNode, i[0], i[1]);
1120
1127
  });
1128
+ this.applyRefs(unBindRefs, nativeNode, false);
1129
+ this.applyRefs(bindRefs, nativeNode, true);
1130
+ }
1131
+ applyRefs(refs, nativeNode, binding) {
1132
+ refs = Array.isArray(refs) ? refs : [refs];
1133
+ for (const item of refs) {
1134
+ if (item instanceof Ref) {
1135
+ binding ? item.bind(nativeNode) : item.unBind(nativeNode);
1136
+ }
1137
+ }
1121
1138
  }
1122
1139
  };
1123
1140
  Renderer = __decorate([
@@ -1188,4 +1205,4 @@ class Viewfly extends ReflectiveInjector {
1188
1205
  }
1189
1206
  }
1190
1207
 
1191
- export { Component, Fragment, JSXElement, JSXFragment, JSXText, NativeRenderer, Props, Ref, Renderer, RootComponent, RootComponentRef, Viewfly, inject, jsx, jsxs, onDestroy, onMount, onPropsChanged, onUpdated, provide, useEffect, useRef, useSignal };
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 };
package/bundles/index.js CHANGED
@@ -35,29 +35,34 @@ function __metadata(metadataKey, metadataValue) {
35
35
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
36
36
  }
37
37
 
38
- function Fragment(props) {
39
- return () => new JSXFragment(props);
40
- }
41
- class JSXFragment {
42
- constructor(props) {
43
- this.props = props;
44
- }
38
+ function makeError(name) {
39
+ return function viewflyError(message) {
40
+ const error = new Error(message);
41
+ error.name = `[ViewflyError: ${name}]`;
42
+ error.stack = error.stack.replace(/\n.*?(?=\n)/, '');
43
+ return error;
44
+ };
45
45
  }
46
+
47
+ const jsxErrorFn = makeError('JSX');
48
+ const Fragment = function Fragment() {
49
+ throw jsxErrorFn('Fragment does not support calling.');
50
+ };
46
51
  function jsx(setup, config) {
47
52
  if (typeof setup === 'string') {
48
53
  return new JSXElement(setup, config);
49
54
  }
50
- return function (context) {
55
+ return new JSXComponent(function (context) {
51
56
  return new Component(context, setup, config);
52
- };
57
+ });
53
58
  }
54
59
  function jsxs(setup, config) {
55
60
  if (typeof setup === 'string') {
56
61
  return new JSXElement(setup, config);
57
62
  }
58
- return function (context) {
63
+ return new JSXComponent(function (context) {
59
64
  return new Component(context, setup, config);
60
- };
65
+ });
61
66
  }
62
67
  class JSXText {
63
68
  constructor(text) {
@@ -67,7 +72,7 @@ class JSXText {
67
72
  function flatChildren(jsxNodes) {
68
73
  const children = [];
69
74
  for (const node of jsxNodes) {
70
- if (node instanceof JSXElement || typeof node === 'function') {
75
+ if (node instanceof JSXElement || node instanceof JSXComponent) {
71
76
  children.push(node);
72
77
  }
73
78
  else if (typeof node === 'string' && node.length) {
@@ -174,24 +179,24 @@ class JSXElement {
174
179
  }
175
180
  }
176
181
 
177
- function makeError(name) {
178
- return function viewflyError(message) {
179
- const error = new Error(message);
180
- error.name = `[ViewflyError: ${name}]`;
181
- error.stack = error.stack.replace(/\n.*?(?=\n)/, '');
182
- return error;
183
- };
184
- }
185
-
186
- const componentStack = [];
182
+ const componentSetupStack = [];
183
+ const componentRendingStack = [];
187
184
  const componentErrorFn = makeError('component');
188
- function getComponentContext(need = true) {
189
- const current = componentStack[componentStack.length - 1];
185
+ function getSetupContext(need = true) {
186
+ const current = componentSetupStack[componentSetupStack.length - 1];
190
187
  if (!current && need) {
191
188
  throw componentErrorFn('cannot be called outside the component!');
192
189
  }
193
190
  return current;
194
191
  }
192
+ function getRendingContext() {
193
+ return componentRendingStack[componentRendingStack.length - 1];
194
+ }
195
+ class JSXComponent {
196
+ constructor(createInstance) {
197
+ this.createInstance = createInstance;
198
+ }
199
+ }
195
200
  /**
196
201
  * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
197
202
  */
@@ -225,7 +230,6 @@ class Component extends di.ReflectiveInjector {
225
230
  });
226
231
  }
227
232
  init() {
228
- componentStack.push(this);
229
233
  const self = this;
230
234
  const props = new Proxy({}, {
231
235
  get(_, key) {
@@ -237,15 +241,18 @@ class Component extends di.ReflectiveInjector {
237
241
  throw componentErrorFn('component props is readonly!');
238
242
  }
239
243
  });
244
+ componentSetupStack.push(this);
240
245
  const render = this.setup(props);
246
+ componentSetupStack.pop();
247
+ componentRendingStack.push(this);
241
248
  const template = render();
242
- componentStack.pop();
249
+ componentRendingStack.pop();
243
250
  return {
244
251
  template,
245
252
  render: () => {
246
- componentStack.push(this);
253
+ componentRendingStack.push(this);
247
254
  const template = render();
248
- componentStack.pop();
255
+ componentRendingStack.pop();
249
256
  return template;
250
257
  }
251
258
  };
@@ -334,7 +341,7 @@ class Component extends di.ReflectiveInjector {
334
341
  * ```
335
342
  */
336
343
  function onMount(callback) {
337
- const component = getComponentContext();
344
+ const component = getSetupContext();
338
345
  component.mountCallbacks.push(callback);
339
346
  }
340
347
  /**
@@ -353,7 +360,7 @@ function onMount(callback) {
353
360
  * ```
354
361
  */
355
362
  function onUpdated(callback) {
356
- const component = getComponentContext();
363
+ const component = getSetupContext();
357
364
  component.updatedCallbacks.push(callback);
358
365
  return () => {
359
366
  const index = component.updatedCallbacks.indexOf(callback);
@@ -382,7 +389,7 @@ function onUpdated(callback) {
382
389
  * ```
383
390
  */
384
391
  function onPropsChanged(callback) {
385
- const component = getComponentContext();
392
+ const component = getSetupContext();
386
393
  component.propsChangedCallbacks.push(callback);
387
394
  return () => {
388
395
  const index = component.propsChangedCallbacks.indexOf(callback);
@@ -396,31 +403,33 @@ function onPropsChanged(callback) {
396
403
  * @param callback
397
404
  */
398
405
  function onDestroy(callback) {
399
- const component = getComponentContext();
406
+ const component = getSetupContext();
400
407
  component.destroyCallbacks.push(callback);
401
408
  }
402
409
  class Ref {
403
- // private prevValue: T | null = null
404
- constructor(callback, component) {
410
+ constructor(callback) {
405
411
  this.callback = callback;
406
- this.component = component;
407
- this.unListenFn = null;
408
- component.destroyCallbacks.push(() => {
409
- this.unListen();
410
- });
412
+ this.unBindMap = new WeakMap;
413
+ this.targetCaches = new Set();
411
414
  }
412
- update(value) {
413
- // if (value === this.prevValue) {
414
- // return
415
- // }
416
- // this.prevValue = value
417
- this.unListen();
418
- this.unListenFn = this.callback(value) || null;
415
+ bind(value) {
416
+ if (typeof value !== 'object' || value === null) {
417
+ return;
418
+ }
419
+ if (this.targetCaches.has(value)) {
420
+ return;
421
+ }
422
+ this.targetCaches.add(value);
423
+ const unBindFn = this.callback(value);
424
+ if (typeof unBindFn === 'function') {
425
+ this.unBindMap.set(value, unBindFn);
426
+ }
419
427
  }
420
- unListen() {
421
- if (typeof this.unListenFn === 'function') {
422
- this.unListenFn();
423
- this.unListenFn = null;
428
+ unBind(value) {
429
+ this.targetCaches.delete(value);
430
+ const unBindFn = this.unBindMap.get(value);
431
+ if (typeof unBindFn === 'function') {
432
+ unBindFn();
424
433
  }
425
434
  }
426
435
  }
@@ -446,8 +455,7 @@ class Ref {
446
455
  * ```
447
456
  */
448
457
  function useRef(callback) {
449
- const component = getComponentContext();
450
- return new Ref(callback, component);
458
+ return new Ref(callback);
451
459
  }
452
460
  const depsKey = Symbol('deps');
453
461
  /**
@@ -476,7 +484,7 @@ const depsKey = Symbol('deps');
476
484
  function useSignal(state) {
477
485
  const usedComponents = new Set();
478
486
  function stateManager() {
479
- const component = getComponentContext(false);
487
+ const component = getRendingContext();
480
488
  if (component && !usedComponents.has(component)) {
481
489
  usedComponents.add(component);
482
490
  component.destroyCallbacks.push(() => {
@@ -486,10 +494,7 @@ function useSignal(state) {
486
494
  return state;
487
495
  }
488
496
  stateManager.set = function (newState) {
489
- if (typeof newState === 'function') {
490
- newState = newState(state);
491
- }
492
- else if (newState === state) {
497
+ if (newState === state) {
493
498
  return;
494
499
  }
495
500
  state = newState;
@@ -522,7 +527,7 @@ function useEffect(deps, effect) {
522
527
  for (const dep of signals) {
523
528
  dep[depsKey].add(effectCallback);
524
529
  }
525
- const component = getComponentContext(false);
530
+ const component = getSetupContext(false);
526
531
  let isClean = false;
527
532
  const destroyFn = () => {
528
533
  if (isClean) {
@@ -547,7 +552,7 @@ function useEffect(deps, effect) {
547
552
  * @param provider
548
553
  */
549
554
  function provide(provider) {
550
- const component = getComponentContext();
555
+ const component = getSetupContext();
551
556
  component.addProvide(provider);
552
557
  return component;
553
558
  }
@@ -555,7 +560,7 @@ function provide(provider) {
555
560
  * 通过组件上下文获取 IoC 容器内数据的勾子方法
556
561
  */
557
562
  function inject(token, notFoundValue, flags) {
558
- const component = getComponentContext();
563
+ const component = getSetupContext();
559
564
  return component.parentInjector.get(token, notFoundValue, flags);
560
565
  }
561
566
 
@@ -860,9 +865,7 @@ exports.Renderer = class Renderer {
860
865
  }
861
866
  if (atom.jsxNode instanceof JSXElement) {
862
867
  const ref = atom.jsxNode.props.attrs.get(refKey);
863
- if (ref instanceof Ref) {
864
- ref.unListen();
865
- }
868
+ this.applyRefs(ref, atom.nativeNode, false);
866
869
  }
867
870
  }
868
871
  let child = atom.child;
@@ -1016,7 +1019,7 @@ exports.Renderer = class Renderer {
1016
1019
  return parent;
1017
1020
  }
1018
1021
  createChainByComponentFactory(context, factory, parent) {
1019
- const component = factory(context);
1022
+ const component = factory.createInstance(context);
1020
1023
  if (component.setup === Fragment) {
1021
1024
  return this.createChainByChildren(component, component.props.children, parent);
1022
1025
  }
@@ -1070,9 +1073,10 @@ exports.Renderer = class Renderer {
1070
1073
  const nativeNode = this.nativeRenderer.createElement(vNode.name);
1071
1074
  const props = vNode.props;
1072
1075
  if (props) {
1076
+ let bindingRefs;
1073
1077
  props.attrs.forEach((value, key) => {
1074
- if (key === refKey && value instanceof Ref) {
1075
- value.update(nativeNode);
1078
+ if (key === refKey) {
1079
+ bindingRefs = value;
1076
1080
  return;
1077
1081
  }
1078
1082
  this.nativeRenderer.setProperty(nativeNode, key, value);
@@ -1084,6 +1088,7 @@ exports.Renderer = class Renderer {
1084
1088
  Object.keys(props.listeners).forEach(type => {
1085
1089
  this.nativeRenderer.listen(nativeNode, type, props.listeners[type]);
1086
1090
  });
1091
+ this.applyRefs(bindingRefs, nativeNode, true);
1087
1092
  }
1088
1093
  return nativeNode;
1089
1094
  }
@@ -1097,16 +1102,18 @@ exports.Renderer = class Renderer {
1097
1102
  }
1098
1103
  styleChanges.remove.forEach(i => this.nativeRenderer.removeStyle(nativeNode, i[0]));
1099
1104
  styleChanges.set.forEach(i => this.nativeRenderer.setStyle(nativeNode, i[0], i[1]));
1105
+ let unBindRefs;
1100
1106
  attrChanges.remove.forEach(([key, value]) => {
1101
- if (key === refKey && value instanceof Ref) {
1102
- value.unListen();
1107
+ if (key === refKey) {
1108
+ unBindRefs = value;
1103
1109
  return;
1104
1110
  }
1105
1111
  this.nativeRenderer.removeProperty(nativeNode, key);
1106
1112
  });
1113
+ let bindRefs;
1107
1114
  attrChanges.set.forEach(([key, value]) => {
1108
- if (key === refKey && value instanceof Ref) {
1109
- value.update(nativeNode);
1115
+ if (key === refKey) {
1116
+ bindRefs = value;
1110
1117
  return;
1111
1118
  }
1112
1119
  this.nativeRenderer.setProperty(nativeNode, key, value);
@@ -1119,6 +1126,16 @@ exports.Renderer = class Renderer {
1119
1126
  listenerChanges.add.forEach(i => {
1120
1127
  this.nativeRenderer.listen(nativeNode, i[0], i[1]);
1121
1128
  });
1129
+ this.applyRefs(unBindRefs, nativeNode, false);
1130
+ this.applyRefs(bindRefs, nativeNode, true);
1131
+ }
1132
+ applyRefs(refs, nativeNode, binding) {
1133
+ refs = Array.isArray(refs) ? refs : [refs];
1134
+ for (const item of refs) {
1135
+ if (item instanceof Ref) {
1136
+ binding ? item.bind(nativeNode) : item.unBind(nativeNode);
1137
+ }
1138
+ }
1122
1139
  }
1123
1140
  };
1124
1141
  exports.Renderer = __decorate([
@@ -1191,8 +1208,8 @@ class Viewfly extends di.ReflectiveInjector {
1191
1208
 
1192
1209
  exports.Component = Component;
1193
1210
  exports.Fragment = Fragment;
1211
+ exports.JSXComponent = JSXComponent;
1194
1212
  exports.JSXElement = JSXElement;
1195
- exports.JSXFragment = JSXFragment;
1196
1213
  exports.JSXText = JSXText;
1197
1214
  exports.NativeRenderer = NativeRenderer;
1198
1215
  exports.Props = Props;
@@ -1,9 +1,10 @@
1
1
  import { Provider, ReflectiveInjector, AbstractType, Type, InjectionToken, InjectFlags, Injector } from '@tanbo/di';
2
2
  import { JSXProps, JSXElement, Props } from './jsx-element';
3
- export interface ComponentFactory {
4
- (context: Injector): Component;
3
+ export declare class JSXComponent {
4
+ createInstance: (injector: Component) => Component;
5
+ constructor(createInstance: (injector: Component) => Component);
5
6
  }
6
- export type JSXTemplate = JSXElement | ComponentFactory | null | void;
7
+ export type JSXTemplate = JSXElement | JSXComponent | null | void;
7
8
  export interface ComponentSetup {
8
9
  (props: JSXProps<any>): () => JSXTemplate;
9
10
  }
@@ -103,13 +104,13 @@ export declare function onDestroy(callback: () => void): void;
103
104
  export interface RefListener<T> {
104
105
  (current: T): void | (() => void);
105
106
  }
106
- export declare class Ref<T> {
107
+ export declare class Ref<T extends object> {
107
108
  private callback;
108
- private component;
109
- private unListenFn;
110
- constructor(callback: RefListener<T>, component: Component);
111
- update(value: T): void;
112
- unListen(): void;
109
+ private unBindMap;
110
+ private targetCaches;
111
+ constructor(callback: RefListener<T>);
112
+ bind(value: T): void;
113
+ unBind(value: T): void;
113
114
  }
114
115
  /**
115
116
  * 用于节点渲染完成时获取 DOM 节点
@@ -132,7 +133,7 @@ export declare class Ref<T> {
132
133
  * }
133
134
  * ```
134
135
  */
135
- export declare function useRef<T>(callback: RefListener<T>): Ref<T>;
136
+ export declare function useRef<T extends object>(callback: RefListener<T>): Ref<T>;
136
137
  declare const depsKey: unique symbol;
137
138
  /**
138
139
  * 组件状态实例,直接调用可以获取最新的状态,通过 set 方法可以更新状态
@@ -144,10 +145,10 @@ export interface Signal<T> {
144
145
  */
145
146
  (): T;
146
147
  /**
147
- * 更新组件状态的方法,可以传入最新的值,或者传入一个函数,并返回最新的值
148
+ * 更新组件状态的方法,可以传入最新的值
148
149
  * @param newState
149
150
  */
150
- set(newState: T | ((oldState: T) => T)): void;
151
+ set(newState: T): void;
151
152
  [depsKey]: Set<LifeCycleCallback>;
152
153
  }
153
154
  /**
@@ -1,19 +1,15 @@
1
- import { ComponentFactory, ComponentSetup } from './component';
2
- export type JSXChildNode = JSXElement | ComponentFactory | string | number | boolean | null | undefined;
1
+ import { JSXComponent, ComponentSetup } from './component';
2
+ export type JSXChildNode = JSXElement | JSXComponent | string | number | boolean | null | undefined;
3
3
  export interface JSXProps<T = JSXChildNode | JSXChildNode[]> {
4
4
  children?: T;
5
5
  [key: string]: any;
6
6
  [key: symbol]: any;
7
7
  }
8
- export declare function Fragment(props: Props | null): () => JSXFragment;
9
- export declare class JSXFragment {
10
- props: Props | null;
11
- constructor(props: Props | null);
12
- }
8
+ export declare const Fragment: () => never;
13
9
  export declare function jsx<T extends JSXChildNode>(name: string, config: JSXProps<T> | null): JSXElement;
14
- export declare function jsx<T extends JSXChildNode>(setup: ComponentSetup, config: JSXProps<T> | null): ComponentFactory;
10
+ export declare function jsx<T extends JSXChildNode>(setup: ComponentSetup, config: JSXProps<T> | null): JSXComponent;
15
11
  export declare function jsxs<T extends JSXChildNode[]>(name: string, config: JSXProps<T> | null): JSXElement;
16
- export declare function jsxs<T extends JSXChildNode[]>(setup: ComponentSetup, config: JSXProps<T> | null): ComponentFactory;
12
+ export declare function jsxs<T extends JSXChildNode[]>(setup: ComponentSetup, config: JSXProps<T> | null): JSXComponent;
17
13
  export interface VElementListeners {
18
14
  [listenKey: string]: <T extends Event>(ev: T) => any;
19
15
  }
@@ -21,7 +17,7 @@ export declare class JSXText {
21
17
  text: string;
22
18
  constructor(text: string);
23
19
  }
24
- export type VNode = JSXElement | ComponentFactory | JSXText;
20
+ export type VNode = JSXElement | JSXComponent | JSXText;
25
21
  export declare class Props {
26
22
  attrs: Map<string, any>;
27
23
  styles: Map<string, string | number>;
@@ -1,7 +1,7 @@
1
1
  import { Provider, ReflectiveInjector } from '@tanbo/di';
2
2
  import { NativeNode } from './foundation/_api';
3
- import { ComponentFactory, JSXElement } from './model/_api';
4
- export type RootNode = JSXElement | ComponentFactory;
3
+ import { JSXComponent, JSXElement } from './model/_api';
4
+ export type RootNode = JSXElement | JSXComponent;
5
5
  /**
6
6
  * Viewfly 配置项
7
7
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viewfly/core",
3
- "version": "0.0.1-alpha.1",
3
+ "version": "0.0.1-alpha.2",
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",
@@ -16,7 +16,8 @@
16
16
  "keywords": [],
17
17
  "dependencies": {
18
18
  "@tanbo/di": "^1.1.4",
19
- "@tanbo/stream": "^1.1.9"
19
+ "@tanbo/stream": "^1.1.9",
20
+ "reflect-metadata": "^0.1.13"
20
21
  },
21
22
  "devDependencies": {
22
23
  "@rollup/plugin-commonjs": "^23.0.2",
@@ -35,6 +36,5 @@
35
36
  },
36
37
  "bugs": {
37
38
  "url": "https://github.com/viewfly/viewfly.git/issues"
38
- },
39
- "gitHead": "abca65615d81e3a6617d5fe588cdf38142a3523a"
39
+ }
40
40
  }