@viewfly/core 0.0.1-alpha.0 → 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.
- package/bundles/foundation/renderer.d.ts +1 -0
- package/bundles/index.esm.js +91 -71
- package/bundles/index.js +91 -71
- package/bundles/model/component.d.ts +13 -12
- package/bundles/model/jsx-element.d.ts +6 -10
- package/bundles/viewfly.d.ts +2 -2
- package/package.json +3 -2
package/bundles/index.esm.js
CHANGED
|
@@ -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
|
|
38
|
-
return ()
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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,12 +71,15 @@ class JSXText {
|
|
|
66
71
|
function flatChildren(jsxNodes) {
|
|
67
72
|
const children = [];
|
|
68
73
|
for (const node of jsxNodes) {
|
|
69
|
-
if (node instanceof JSXElement ||
|
|
74
|
+
if (node instanceof JSXElement || node instanceof JSXComponent) {
|
|
70
75
|
children.push(node);
|
|
71
76
|
}
|
|
72
77
|
else if (typeof node === 'string' && node.length) {
|
|
73
78
|
children.push(new JSXText(node));
|
|
74
79
|
}
|
|
80
|
+
else if (Array.isArray(node)) {
|
|
81
|
+
children.push(...flatChildren(node));
|
|
82
|
+
}
|
|
75
83
|
else if (node !== null && typeof node !== 'undefined') {
|
|
76
84
|
children.push(new JSXText(String(node)));
|
|
77
85
|
}
|
|
@@ -170,24 +178,24 @@ class JSXElement {
|
|
|
170
178
|
}
|
|
171
179
|
}
|
|
172
180
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const error = new Error(message);
|
|
176
|
-
error.name = `[ViewflyError: ${name}]`;
|
|
177
|
-
error.stack = error.stack.replace(/\n.*?(?=\n)/, '');
|
|
178
|
-
return error;
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const componentStack = [];
|
|
181
|
+
const componentSetupStack = [];
|
|
182
|
+
const componentRendingStack = [];
|
|
183
183
|
const componentErrorFn = makeError('component');
|
|
184
|
-
function
|
|
185
|
-
const current =
|
|
184
|
+
function getSetupContext(need = true) {
|
|
185
|
+
const current = componentSetupStack[componentSetupStack.length - 1];
|
|
186
186
|
if (!current && need) {
|
|
187
187
|
throw componentErrorFn('cannot be called outside the component!');
|
|
188
188
|
}
|
|
189
189
|
return current;
|
|
190
190
|
}
|
|
191
|
+
function getRendingContext() {
|
|
192
|
+
return componentRendingStack[componentRendingStack.length - 1];
|
|
193
|
+
}
|
|
194
|
+
class JSXComponent {
|
|
195
|
+
constructor(createInstance) {
|
|
196
|
+
this.createInstance = createInstance;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
191
199
|
/**
|
|
192
200
|
* Viewfly 组件管理类,用于管理组件的生命周期,上下文等
|
|
193
201
|
*/
|
|
@@ -221,7 +229,6 @@ class Component extends ReflectiveInjector {
|
|
|
221
229
|
});
|
|
222
230
|
}
|
|
223
231
|
init() {
|
|
224
|
-
componentStack.push(this);
|
|
225
232
|
const self = this;
|
|
226
233
|
const props = new Proxy({}, {
|
|
227
234
|
get(_, key) {
|
|
@@ -233,15 +240,18 @@ class Component extends ReflectiveInjector {
|
|
|
233
240
|
throw componentErrorFn('component props is readonly!');
|
|
234
241
|
}
|
|
235
242
|
});
|
|
243
|
+
componentSetupStack.push(this);
|
|
236
244
|
const render = this.setup(props);
|
|
245
|
+
componentSetupStack.pop();
|
|
246
|
+
componentRendingStack.push(this);
|
|
237
247
|
const template = render();
|
|
238
|
-
|
|
248
|
+
componentRendingStack.pop();
|
|
239
249
|
return {
|
|
240
250
|
template,
|
|
241
251
|
render: () => {
|
|
242
|
-
|
|
252
|
+
componentRendingStack.push(this);
|
|
243
253
|
const template = render();
|
|
244
|
-
|
|
254
|
+
componentRendingStack.pop();
|
|
245
255
|
return template;
|
|
246
256
|
}
|
|
247
257
|
};
|
|
@@ -330,7 +340,7 @@ class Component extends ReflectiveInjector {
|
|
|
330
340
|
* ```
|
|
331
341
|
*/
|
|
332
342
|
function onMount(callback) {
|
|
333
|
-
const component =
|
|
343
|
+
const component = getSetupContext();
|
|
334
344
|
component.mountCallbacks.push(callback);
|
|
335
345
|
}
|
|
336
346
|
/**
|
|
@@ -349,7 +359,7 @@ function onMount(callback) {
|
|
|
349
359
|
* ```
|
|
350
360
|
*/
|
|
351
361
|
function onUpdated(callback) {
|
|
352
|
-
const component =
|
|
362
|
+
const component = getSetupContext();
|
|
353
363
|
component.updatedCallbacks.push(callback);
|
|
354
364
|
return () => {
|
|
355
365
|
const index = component.updatedCallbacks.indexOf(callback);
|
|
@@ -378,7 +388,7 @@ function onUpdated(callback) {
|
|
|
378
388
|
* ```
|
|
379
389
|
*/
|
|
380
390
|
function onPropsChanged(callback) {
|
|
381
|
-
const component =
|
|
391
|
+
const component = getSetupContext();
|
|
382
392
|
component.propsChangedCallbacks.push(callback);
|
|
383
393
|
return () => {
|
|
384
394
|
const index = component.propsChangedCallbacks.indexOf(callback);
|
|
@@ -392,31 +402,33 @@ function onPropsChanged(callback) {
|
|
|
392
402
|
* @param callback
|
|
393
403
|
*/
|
|
394
404
|
function onDestroy(callback) {
|
|
395
|
-
const component =
|
|
405
|
+
const component = getSetupContext();
|
|
396
406
|
component.destroyCallbacks.push(callback);
|
|
397
407
|
}
|
|
398
408
|
class Ref {
|
|
399
|
-
|
|
400
|
-
constructor(callback, component) {
|
|
409
|
+
constructor(callback) {
|
|
401
410
|
this.callback = callback;
|
|
402
|
-
this.
|
|
403
|
-
this.
|
|
404
|
-
component.destroyCallbacks.push(() => {
|
|
405
|
-
this.unListen();
|
|
406
|
-
});
|
|
411
|
+
this.unBindMap = new WeakMap;
|
|
412
|
+
this.targetCaches = new Set();
|
|
407
413
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
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
|
+
}
|
|
415
426
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
427
|
+
unBind(value) {
|
|
428
|
+
this.targetCaches.delete(value);
|
|
429
|
+
const unBindFn = this.unBindMap.get(value);
|
|
430
|
+
if (typeof unBindFn === 'function') {
|
|
431
|
+
unBindFn();
|
|
420
432
|
}
|
|
421
433
|
}
|
|
422
434
|
}
|
|
@@ -442,8 +454,7 @@ class Ref {
|
|
|
442
454
|
* ```
|
|
443
455
|
*/
|
|
444
456
|
function useRef(callback) {
|
|
445
|
-
|
|
446
|
-
return new Ref(callback, component);
|
|
457
|
+
return new Ref(callback);
|
|
447
458
|
}
|
|
448
459
|
const depsKey = Symbol('deps');
|
|
449
460
|
/**
|
|
@@ -472,7 +483,7 @@ const depsKey = Symbol('deps');
|
|
|
472
483
|
function useSignal(state) {
|
|
473
484
|
const usedComponents = new Set();
|
|
474
485
|
function stateManager() {
|
|
475
|
-
const component =
|
|
486
|
+
const component = getRendingContext();
|
|
476
487
|
if (component && !usedComponents.has(component)) {
|
|
477
488
|
usedComponents.add(component);
|
|
478
489
|
component.destroyCallbacks.push(() => {
|
|
@@ -482,10 +493,7 @@ function useSignal(state) {
|
|
|
482
493
|
return state;
|
|
483
494
|
}
|
|
484
495
|
stateManager.set = function (newState) {
|
|
485
|
-
if (
|
|
486
|
-
newState = newState(state);
|
|
487
|
-
}
|
|
488
|
-
else if (newState === state) {
|
|
496
|
+
if (newState === state) {
|
|
489
497
|
return;
|
|
490
498
|
}
|
|
491
499
|
state = newState;
|
|
@@ -518,7 +526,7 @@ function useEffect(deps, effect) {
|
|
|
518
526
|
for (const dep of signals) {
|
|
519
527
|
dep[depsKey].add(effectCallback);
|
|
520
528
|
}
|
|
521
|
-
const component =
|
|
529
|
+
const component = getSetupContext(false);
|
|
522
530
|
let isClean = false;
|
|
523
531
|
const destroyFn = () => {
|
|
524
532
|
if (isClean) {
|
|
@@ -543,7 +551,7 @@ function useEffect(deps, effect) {
|
|
|
543
551
|
* @param provider
|
|
544
552
|
*/
|
|
545
553
|
function provide(provider) {
|
|
546
|
-
const component =
|
|
554
|
+
const component = getSetupContext();
|
|
547
555
|
component.addProvide(provider);
|
|
548
556
|
return component;
|
|
549
557
|
}
|
|
@@ -551,7 +559,7 @@ function provide(provider) {
|
|
|
551
559
|
* 通过组件上下文获取 IoC 容器内数据的勾子方法
|
|
552
560
|
*/
|
|
553
561
|
function inject(token, notFoundValue, flags) {
|
|
554
|
-
const component =
|
|
562
|
+
const component = getSetupContext();
|
|
555
563
|
return component.parentInjector.get(token, notFoundValue, flags);
|
|
556
564
|
}
|
|
557
565
|
|
|
@@ -856,9 +864,7 @@ let Renderer = class Renderer {
|
|
|
856
864
|
}
|
|
857
865
|
if (atom.jsxNode instanceof JSXElement) {
|
|
858
866
|
const ref = atom.jsxNode.props.attrs.get(refKey);
|
|
859
|
-
|
|
860
|
-
ref.unListen();
|
|
861
|
-
}
|
|
867
|
+
this.applyRefs(ref, atom.nativeNode, false);
|
|
862
868
|
}
|
|
863
869
|
}
|
|
864
870
|
let child = atom.child;
|
|
@@ -1012,7 +1018,7 @@ let Renderer = class Renderer {
|
|
|
1012
1018
|
return parent;
|
|
1013
1019
|
}
|
|
1014
1020
|
createChainByComponentFactory(context, factory, parent) {
|
|
1015
|
-
const component = factory(context);
|
|
1021
|
+
const component = factory.createInstance(context);
|
|
1016
1022
|
if (component.setup === Fragment) {
|
|
1017
1023
|
return this.createChainByChildren(component, component.props.children, parent);
|
|
1018
1024
|
}
|
|
@@ -1066,9 +1072,10 @@ let Renderer = class Renderer {
|
|
|
1066
1072
|
const nativeNode = this.nativeRenderer.createElement(vNode.name);
|
|
1067
1073
|
const props = vNode.props;
|
|
1068
1074
|
if (props) {
|
|
1075
|
+
let bindingRefs;
|
|
1069
1076
|
props.attrs.forEach((value, key) => {
|
|
1070
|
-
if (key === refKey
|
|
1071
|
-
value
|
|
1077
|
+
if (key === refKey) {
|
|
1078
|
+
bindingRefs = value;
|
|
1072
1079
|
return;
|
|
1073
1080
|
}
|
|
1074
1081
|
this.nativeRenderer.setProperty(nativeNode, key, value);
|
|
@@ -1080,6 +1087,7 @@ let Renderer = class Renderer {
|
|
|
1080
1087
|
Object.keys(props.listeners).forEach(type => {
|
|
1081
1088
|
this.nativeRenderer.listen(nativeNode, type, props.listeners[type]);
|
|
1082
1089
|
});
|
|
1090
|
+
this.applyRefs(bindingRefs, nativeNode, true);
|
|
1083
1091
|
}
|
|
1084
1092
|
return nativeNode;
|
|
1085
1093
|
}
|
|
@@ -1093,16 +1101,18 @@ let Renderer = class Renderer {
|
|
|
1093
1101
|
}
|
|
1094
1102
|
styleChanges.remove.forEach(i => this.nativeRenderer.removeStyle(nativeNode, i[0]));
|
|
1095
1103
|
styleChanges.set.forEach(i => this.nativeRenderer.setStyle(nativeNode, i[0], i[1]));
|
|
1104
|
+
let unBindRefs;
|
|
1096
1105
|
attrChanges.remove.forEach(([key, value]) => {
|
|
1097
|
-
if (key === refKey
|
|
1098
|
-
value
|
|
1106
|
+
if (key === refKey) {
|
|
1107
|
+
unBindRefs = value;
|
|
1099
1108
|
return;
|
|
1100
1109
|
}
|
|
1101
1110
|
this.nativeRenderer.removeProperty(nativeNode, key);
|
|
1102
1111
|
});
|
|
1112
|
+
let bindRefs;
|
|
1103
1113
|
attrChanges.set.forEach(([key, value]) => {
|
|
1104
|
-
if (key === refKey
|
|
1105
|
-
value
|
|
1114
|
+
if (key === refKey) {
|
|
1115
|
+
bindRefs = value;
|
|
1106
1116
|
return;
|
|
1107
1117
|
}
|
|
1108
1118
|
this.nativeRenderer.setProperty(nativeNode, key, value);
|
|
@@ -1115,6 +1125,16 @@ let Renderer = class Renderer {
|
|
|
1115
1125
|
listenerChanges.add.forEach(i => {
|
|
1116
1126
|
this.nativeRenderer.listen(nativeNode, i[0], i[1]);
|
|
1117
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
|
+
}
|
|
1118
1138
|
}
|
|
1119
1139
|
};
|
|
1120
1140
|
Renderer = __decorate([
|
|
@@ -1185,4 +1205,4 @@ class Viewfly extends ReflectiveInjector {
|
|
|
1185
1205
|
}
|
|
1186
1206
|
}
|
|
1187
1207
|
|
|
1188
|
-
export { Component, Fragment,
|
|
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
|
|
39
|
-
return ()
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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,12 +72,15 @@ class JSXText {
|
|
|
67
72
|
function flatChildren(jsxNodes) {
|
|
68
73
|
const children = [];
|
|
69
74
|
for (const node of jsxNodes) {
|
|
70
|
-
if (node instanceof JSXElement ||
|
|
75
|
+
if (node instanceof JSXElement || node instanceof JSXComponent) {
|
|
71
76
|
children.push(node);
|
|
72
77
|
}
|
|
73
78
|
else if (typeof node === 'string' && node.length) {
|
|
74
79
|
children.push(new JSXText(node));
|
|
75
80
|
}
|
|
81
|
+
else if (Array.isArray(node)) {
|
|
82
|
+
children.push(...flatChildren(node));
|
|
83
|
+
}
|
|
76
84
|
else if (node !== null && typeof node !== 'undefined') {
|
|
77
85
|
children.push(new JSXText(String(node)));
|
|
78
86
|
}
|
|
@@ -171,24 +179,24 @@ class JSXElement {
|
|
|
171
179
|
}
|
|
172
180
|
}
|
|
173
181
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const error = new Error(message);
|
|
177
|
-
error.name = `[ViewflyError: ${name}]`;
|
|
178
|
-
error.stack = error.stack.replace(/\n.*?(?=\n)/, '');
|
|
179
|
-
return error;
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const componentStack = [];
|
|
182
|
+
const componentSetupStack = [];
|
|
183
|
+
const componentRendingStack = [];
|
|
184
184
|
const componentErrorFn = makeError('component');
|
|
185
|
-
function
|
|
186
|
-
const current =
|
|
185
|
+
function getSetupContext(need = true) {
|
|
186
|
+
const current = componentSetupStack[componentSetupStack.length - 1];
|
|
187
187
|
if (!current && need) {
|
|
188
188
|
throw componentErrorFn('cannot be called outside the component!');
|
|
189
189
|
}
|
|
190
190
|
return current;
|
|
191
191
|
}
|
|
192
|
+
function getRendingContext() {
|
|
193
|
+
return componentRendingStack[componentRendingStack.length - 1];
|
|
194
|
+
}
|
|
195
|
+
class JSXComponent {
|
|
196
|
+
constructor(createInstance) {
|
|
197
|
+
this.createInstance = createInstance;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
192
200
|
/**
|
|
193
201
|
* Viewfly 组件管理类,用于管理组件的生命周期,上下文等
|
|
194
202
|
*/
|
|
@@ -222,7 +230,6 @@ class Component extends di.ReflectiveInjector {
|
|
|
222
230
|
});
|
|
223
231
|
}
|
|
224
232
|
init() {
|
|
225
|
-
componentStack.push(this);
|
|
226
233
|
const self = this;
|
|
227
234
|
const props = new Proxy({}, {
|
|
228
235
|
get(_, key) {
|
|
@@ -234,15 +241,18 @@ class Component extends di.ReflectiveInjector {
|
|
|
234
241
|
throw componentErrorFn('component props is readonly!');
|
|
235
242
|
}
|
|
236
243
|
});
|
|
244
|
+
componentSetupStack.push(this);
|
|
237
245
|
const render = this.setup(props);
|
|
246
|
+
componentSetupStack.pop();
|
|
247
|
+
componentRendingStack.push(this);
|
|
238
248
|
const template = render();
|
|
239
|
-
|
|
249
|
+
componentRendingStack.pop();
|
|
240
250
|
return {
|
|
241
251
|
template,
|
|
242
252
|
render: () => {
|
|
243
|
-
|
|
253
|
+
componentRendingStack.push(this);
|
|
244
254
|
const template = render();
|
|
245
|
-
|
|
255
|
+
componentRendingStack.pop();
|
|
246
256
|
return template;
|
|
247
257
|
}
|
|
248
258
|
};
|
|
@@ -331,7 +341,7 @@ class Component extends di.ReflectiveInjector {
|
|
|
331
341
|
* ```
|
|
332
342
|
*/
|
|
333
343
|
function onMount(callback) {
|
|
334
|
-
const component =
|
|
344
|
+
const component = getSetupContext();
|
|
335
345
|
component.mountCallbacks.push(callback);
|
|
336
346
|
}
|
|
337
347
|
/**
|
|
@@ -350,7 +360,7 @@ function onMount(callback) {
|
|
|
350
360
|
* ```
|
|
351
361
|
*/
|
|
352
362
|
function onUpdated(callback) {
|
|
353
|
-
const component =
|
|
363
|
+
const component = getSetupContext();
|
|
354
364
|
component.updatedCallbacks.push(callback);
|
|
355
365
|
return () => {
|
|
356
366
|
const index = component.updatedCallbacks.indexOf(callback);
|
|
@@ -379,7 +389,7 @@ function onUpdated(callback) {
|
|
|
379
389
|
* ```
|
|
380
390
|
*/
|
|
381
391
|
function onPropsChanged(callback) {
|
|
382
|
-
const component =
|
|
392
|
+
const component = getSetupContext();
|
|
383
393
|
component.propsChangedCallbacks.push(callback);
|
|
384
394
|
return () => {
|
|
385
395
|
const index = component.propsChangedCallbacks.indexOf(callback);
|
|
@@ -393,31 +403,33 @@ function onPropsChanged(callback) {
|
|
|
393
403
|
* @param callback
|
|
394
404
|
*/
|
|
395
405
|
function onDestroy(callback) {
|
|
396
|
-
const component =
|
|
406
|
+
const component = getSetupContext();
|
|
397
407
|
component.destroyCallbacks.push(callback);
|
|
398
408
|
}
|
|
399
409
|
class Ref {
|
|
400
|
-
|
|
401
|
-
constructor(callback, component) {
|
|
410
|
+
constructor(callback) {
|
|
402
411
|
this.callback = callback;
|
|
403
|
-
this.
|
|
404
|
-
this.
|
|
405
|
-
component.destroyCallbacks.push(() => {
|
|
406
|
-
this.unListen();
|
|
407
|
-
});
|
|
412
|
+
this.unBindMap = new WeakMap;
|
|
413
|
+
this.targetCaches = new Set();
|
|
408
414
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
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
|
+
}
|
|
416
427
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
428
|
+
unBind(value) {
|
|
429
|
+
this.targetCaches.delete(value);
|
|
430
|
+
const unBindFn = this.unBindMap.get(value);
|
|
431
|
+
if (typeof unBindFn === 'function') {
|
|
432
|
+
unBindFn();
|
|
421
433
|
}
|
|
422
434
|
}
|
|
423
435
|
}
|
|
@@ -443,8 +455,7 @@ class Ref {
|
|
|
443
455
|
* ```
|
|
444
456
|
*/
|
|
445
457
|
function useRef(callback) {
|
|
446
|
-
|
|
447
|
-
return new Ref(callback, component);
|
|
458
|
+
return new Ref(callback);
|
|
448
459
|
}
|
|
449
460
|
const depsKey = Symbol('deps');
|
|
450
461
|
/**
|
|
@@ -473,7 +484,7 @@ const depsKey = Symbol('deps');
|
|
|
473
484
|
function useSignal(state) {
|
|
474
485
|
const usedComponents = new Set();
|
|
475
486
|
function stateManager() {
|
|
476
|
-
const component =
|
|
487
|
+
const component = getRendingContext();
|
|
477
488
|
if (component && !usedComponents.has(component)) {
|
|
478
489
|
usedComponents.add(component);
|
|
479
490
|
component.destroyCallbacks.push(() => {
|
|
@@ -483,10 +494,7 @@ function useSignal(state) {
|
|
|
483
494
|
return state;
|
|
484
495
|
}
|
|
485
496
|
stateManager.set = function (newState) {
|
|
486
|
-
if (
|
|
487
|
-
newState = newState(state);
|
|
488
|
-
}
|
|
489
|
-
else if (newState === state) {
|
|
497
|
+
if (newState === state) {
|
|
490
498
|
return;
|
|
491
499
|
}
|
|
492
500
|
state = newState;
|
|
@@ -519,7 +527,7 @@ function useEffect(deps, effect) {
|
|
|
519
527
|
for (const dep of signals) {
|
|
520
528
|
dep[depsKey].add(effectCallback);
|
|
521
529
|
}
|
|
522
|
-
const component =
|
|
530
|
+
const component = getSetupContext(false);
|
|
523
531
|
let isClean = false;
|
|
524
532
|
const destroyFn = () => {
|
|
525
533
|
if (isClean) {
|
|
@@ -544,7 +552,7 @@ function useEffect(deps, effect) {
|
|
|
544
552
|
* @param provider
|
|
545
553
|
*/
|
|
546
554
|
function provide(provider) {
|
|
547
|
-
const component =
|
|
555
|
+
const component = getSetupContext();
|
|
548
556
|
component.addProvide(provider);
|
|
549
557
|
return component;
|
|
550
558
|
}
|
|
@@ -552,7 +560,7 @@ function provide(provider) {
|
|
|
552
560
|
* 通过组件上下文获取 IoC 容器内数据的勾子方法
|
|
553
561
|
*/
|
|
554
562
|
function inject(token, notFoundValue, flags) {
|
|
555
|
-
const component =
|
|
563
|
+
const component = getSetupContext();
|
|
556
564
|
return component.parentInjector.get(token, notFoundValue, flags);
|
|
557
565
|
}
|
|
558
566
|
|
|
@@ -857,9 +865,7 @@ exports.Renderer = class Renderer {
|
|
|
857
865
|
}
|
|
858
866
|
if (atom.jsxNode instanceof JSXElement) {
|
|
859
867
|
const ref = atom.jsxNode.props.attrs.get(refKey);
|
|
860
|
-
|
|
861
|
-
ref.unListen();
|
|
862
|
-
}
|
|
868
|
+
this.applyRefs(ref, atom.nativeNode, false);
|
|
863
869
|
}
|
|
864
870
|
}
|
|
865
871
|
let child = atom.child;
|
|
@@ -1013,7 +1019,7 @@ exports.Renderer = class Renderer {
|
|
|
1013
1019
|
return parent;
|
|
1014
1020
|
}
|
|
1015
1021
|
createChainByComponentFactory(context, factory, parent) {
|
|
1016
|
-
const component = factory(context);
|
|
1022
|
+
const component = factory.createInstance(context);
|
|
1017
1023
|
if (component.setup === Fragment) {
|
|
1018
1024
|
return this.createChainByChildren(component, component.props.children, parent);
|
|
1019
1025
|
}
|
|
@@ -1067,9 +1073,10 @@ exports.Renderer = class Renderer {
|
|
|
1067
1073
|
const nativeNode = this.nativeRenderer.createElement(vNode.name);
|
|
1068
1074
|
const props = vNode.props;
|
|
1069
1075
|
if (props) {
|
|
1076
|
+
let bindingRefs;
|
|
1070
1077
|
props.attrs.forEach((value, key) => {
|
|
1071
|
-
if (key === refKey
|
|
1072
|
-
value
|
|
1078
|
+
if (key === refKey) {
|
|
1079
|
+
bindingRefs = value;
|
|
1073
1080
|
return;
|
|
1074
1081
|
}
|
|
1075
1082
|
this.nativeRenderer.setProperty(nativeNode, key, value);
|
|
@@ -1081,6 +1088,7 @@ exports.Renderer = class Renderer {
|
|
|
1081
1088
|
Object.keys(props.listeners).forEach(type => {
|
|
1082
1089
|
this.nativeRenderer.listen(nativeNode, type, props.listeners[type]);
|
|
1083
1090
|
});
|
|
1091
|
+
this.applyRefs(bindingRefs, nativeNode, true);
|
|
1084
1092
|
}
|
|
1085
1093
|
return nativeNode;
|
|
1086
1094
|
}
|
|
@@ -1094,16 +1102,18 @@ exports.Renderer = class Renderer {
|
|
|
1094
1102
|
}
|
|
1095
1103
|
styleChanges.remove.forEach(i => this.nativeRenderer.removeStyle(nativeNode, i[0]));
|
|
1096
1104
|
styleChanges.set.forEach(i => this.nativeRenderer.setStyle(nativeNode, i[0], i[1]));
|
|
1105
|
+
let unBindRefs;
|
|
1097
1106
|
attrChanges.remove.forEach(([key, value]) => {
|
|
1098
|
-
if (key === refKey
|
|
1099
|
-
value
|
|
1107
|
+
if (key === refKey) {
|
|
1108
|
+
unBindRefs = value;
|
|
1100
1109
|
return;
|
|
1101
1110
|
}
|
|
1102
1111
|
this.nativeRenderer.removeProperty(nativeNode, key);
|
|
1103
1112
|
});
|
|
1113
|
+
let bindRefs;
|
|
1104
1114
|
attrChanges.set.forEach(([key, value]) => {
|
|
1105
|
-
if (key === refKey
|
|
1106
|
-
value
|
|
1115
|
+
if (key === refKey) {
|
|
1116
|
+
bindRefs = value;
|
|
1107
1117
|
return;
|
|
1108
1118
|
}
|
|
1109
1119
|
this.nativeRenderer.setProperty(nativeNode, key, value);
|
|
@@ -1116,6 +1126,16 @@ exports.Renderer = class Renderer {
|
|
|
1116
1126
|
listenerChanges.add.forEach(i => {
|
|
1117
1127
|
this.nativeRenderer.listen(nativeNode, i[0], i[1]);
|
|
1118
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
|
+
}
|
|
1119
1139
|
}
|
|
1120
1140
|
};
|
|
1121
1141
|
exports.Renderer = __decorate([
|
|
@@ -1188,8 +1208,8 @@ class Viewfly extends di.ReflectiveInjector {
|
|
|
1188
1208
|
|
|
1189
1209
|
exports.Component = Component;
|
|
1190
1210
|
exports.Fragment = Fragment;
|
|
1211
|
+
exports.JSXComponent = JSXComponent;
|
|
1191
1212
|
exports.JSXElement = JSXElement;
|
|
1192
|
-
exports.JSXFragment = JSXFragment;
|
|
1193
1213
|
exports.JSXText = JSXText;
|
|
1194
1214
|
exports.NativeRenderer = NativeRenderer;
|
|
1195
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
|
|
4
|
-
(
|
|
3
|
+
export declare class JSXComponent {
|
|
4
|
+
createInstance: (injector: Component) => Component;
|
|
5
|
+
constructor(createInstance: (injector: Component) => Component);
|
|
5
6
|
}
|
|
6
|
-
export type JSXTemplate = JSXElement |
|
|
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
|
|
109
|
-
private
|
|
110
|
-
constructor(callback: RefListener<T
|
|
111
|
-
|
|
112
|
-
|
|
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
|
|
151
|
+
set(newState: T): void;
|
|
151
152
|
[depsKey]: Set<LifeCycleCallback>;
|
|
152
153
|
}
|
|
153
154
|
/**
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type JSXChildNode = JSXElement |
|
|
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
|
|
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):
|
|
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):
|
|
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 |
|
|
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>;
|
package/bundles/viewfly.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Provider, ReflectiveInjector } from '@tanbo/di';
|
|
2
2
|
import { NativeNode } from './foundation/_api';
|
|
3
|
-
import {
|
|
4
|
-
export type RootNode = JSXElement |
|
|
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.
|
|
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",
|