@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.
- package/bundles/foundation/renderer.d.ts +1 -0
- package/bundles/index.esm.js +88 -71
- package/bundles/index.js +88 -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 +4 -4
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,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 ||
|
|
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
|
-
|
|
177
|
-
|
|
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
|
|
188
|
-
const current =
|
|
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
|
-
|
|
248
|
+
componentRendingStack.pop();
|
|
242
249
|
return {
|
|
243
250
|
template,
|
|
244
251
|
render: () => {
|
|
245
|
-
|
|
252
|
+
componentRendingStack.push(this);
|
|
246
253
|
const template = render();
|
|
247
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
405
|
+
const component = getSetupContext();
|
|
399
406
|
component.destroyCallbacks.push(callback);
|
|
400
407
|
}
|
|
401
408
|
class Ref {
|
|
402
|
-
|
|
403
|
-
constructor(callback, component) {
|
|
409
|
+
constructor(callback) {
|
|
404
410
|
this.callback = callback;
|
|
405
|
-
this.
|
|
406
|
-
this.
|
|
407
|
-
component.destroyCallbacks.push(() => {
|
|
408
|
-
this.unListen();
|
|
409
|
-
});
|
|
411
|
+
this.unBindMap = new WeakMap;
|
|
412
|
+
this.targetCaches = new Set();
|
|
410
413
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
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
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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
|
-
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
|
1074
|
-
value
|
|
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
|
|
1101
|
-
value
|
|
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
|
|
1108
|
-
value
|
|
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,
|
|
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,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 ||
|
|
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
|
-
|
|
178
|
-
|
|
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
|
|
189
|
-
const current =
|
|
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
|
-
|
|
249
|
+
componentRendingStack.pop();
|
|
243
250
|
return {
|
|
244
251
|
template,
|
|
245
252
|
render: () => {
|
|
246
|
-
|
|
253
|
+
componentRendingStack.push(this);
|
|
247
254
|
const template = render();
|
|
248
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
406
|
+
const component = getSetupContext();
|
|
400
407
|
component.destroyCallbacks.push(callback);
|
|
401
408
|
}
|
|
402
409
|
class Ref {
|
|
403
|
-
|
|
404
|
-
constructor(callback, component) {
|
|
410
|
+
constructor(callback) {
|
|
405
411
|
this.callback = callback;
|
|
406
|
-
this.
|
|
407
|
-
this.
|
|
408
|
-
component.destroyCallbacks.push(() => {
|
|
409
|
-
this.unListen();
|
|
410
|
-
});
|
|
412
|
+
this.unBindMap = new WeakMap;
|
|
413
|
+
this.targetCaches = new Set();
|
|
411
414
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
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
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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
|
-
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
|
1075
|
-
value
|
|
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
|
|
1102
|
-
value
|
|
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
|
|
1109
|
-
value
|
|
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
|
|
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",
|
|
@@ -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
|
}
|