@viewfly/core 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/foundation/renderer.d.ts +1 -0
- package/bundles/index.esm.js +65 -29
- package/bundles/index.js +65 -29
- package/bundles/model/jsx-element.d.ts +5 -0
- package/package.json +2 -2
package/bundles/index.esm.js
CHANGED
|
@@ -383,13 +383,25 @@ function useSignal(state) {
|
|
|
383
383
|
return;
|
|
384
384
|
}
|
|
385
385
|
state = newState;
|
|
386
|
-
|
|
386
|
+
const depCallbacks = Array.from(signal[depsKey]);
|
|
387
|
+
for (const fn of depCallbacks) {
|
|
388
|
+
// 回调中可能会对依赖做出修改,故需先缓存起来
|
|
387
389
|
fn();
|
|
388
390
|
}
|
|
389
391
|
};
|
|
390
392
|
signal[depsKey] = new Set();
|
|
391
393
|
return signal;
|
|
392
394
|
}
|
|
395
|
+
function invokeDepFn(fn) {
|
|
396
|
+
const deps = [];
|
|
397
|
+
signalDepsStack.push(deps);
|
|
398
|
+
const data = fn();
|
|
399
|
+
signalDepsStack.pop();
|
|
400
|
+
return {
|
|
401
|
+
deps,
|
|
402
|
+
data
|
|
403
|
+
};
|
|
404
|
+
}
|
|
393
405
|
/**
|
|
394
406
|
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
395
407
|
* 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
@@ -398,18 +410,32 @@ function useSignal(state) {
|
|
|
398
410
|
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
399
411
|
*/
|
|
400
412
|
function useDerived(callback, isContinue) {
|
|
401
|
-
|
|
402
|
-
signalDepsStack.push(deps);
|
|
403
|
-
const data = callback();
|
|
404
|
-
signalDepsStack.pop();
|
|
413
|
+
let { data, deps } = invokeDepFn(callback);
|
|
405
414
|
const signal = useSignal(data);
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
415
|
+
const component = getSetupContext(false);
|
|
416
|
+
const unListenRef = {};
|
|
417
|
+
function listen(model, deps, callback, unListenRef, isContinue) {
|
|
418
|
+
const nextListen = () => {
|
|
419
|
+
unListenRef.unListen();
|
|
420
|
+
const { data: nextData, deps: nextDeps } = invokeDepFn(callback);
|
|
421
|
+
model.set(nextData);
|
|
422
|
+
if (typeof isContinue !== 'function' || isContinue(nextData) !== false) {
|
|
423
|
+
listen(model, nextDeps, callback, unListenRef, isContinue);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
unListenRef.unListen = () => {
|
|
427
|
+
for (const s of deps) {
|
|
428
|
+
s[depsKey].delete(nextListen);
|
|
412
429
|
}
|
|
430
|
+
};
|
|
431
|
+
for (const s of deps) {
|
|
432
|
+
s[depsKey].add(nextListen);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
listen(signal, deps, callback, unListenRef, isContinue);
|
|
436
|
+
if (component) {
|
|
437
|
+
component.destroyCallbacks.push(() => {
|
|
438
|
+
unListenRef.unListen();
|
|
413
439
|
});
|
|
414
440
|
}
|
|
415
441
|
return signal;
|
|
@@ -917,14 +943,6 @@ let Renderer = class Renderer {
|
|
|
917
943
|
}
|
|
918
944
|
createChainByComponentFactory(context, factory, parent) {
|
|
919
945
|
const component = factory.createInstance(context);
|
|
920
|
-
// if (component.setup === Fragment) {
|
|
921
|
-
// const children = component.props.children
|
|
922
|
-
// return this.createChainByChildren(
|
|
923
|
-
// component,
|
|
924
|
-
// Array.isArray(children) ? children : [children],
|
|
925
|
-
// parent
|
|
926
|
-
// )
|
|
927
|
-
// }
|
|
928
946
|
return new Atom(component, parent);
|
|
929
947
|
}
|
|
930
948
|
createChainByJSXElement(context, element, parent) {
|
|
@@ -986,7 +1004,10 @@ let Renderer = class Renderer {
|
|
|
986
1004
|
continue;
|
|
987
1005
|
}
|
|
988
1006
|
if (key === 'class') {
|
|
989
|
-
|
|
1007
|
+
const className = classToString(props[key]);
|
|
1008
|
+
if (className) {
|
|
1009
|
+
this.nativeRenderer.setClass(nativeNode, className);
|
|
1010
|
+
}
|
|
990
1011
|
continue;
|
|
991
1012
|
}
|
|
992
1013
|
if (key === 'style') {
|
|
@@ -999,7 +1020,7 @@ let Renderer = class Renderer {
|
|
|
999
1020
|
if (/^on[A-Z]/.test(key)) {
|
|
1000
1021
|
const listener = props[key];
|
|
1001
1022
|
if (typeof listener === 'function') {
|
|
1002
|
-
this.
|
|
1023
|
+
this.bindEvent(vNode, key, nativeNode, listener);
|
|
1003
1024
|
}
|
|
1004
1025
|
continue;
|
|
1005
1026
|
}
|
|
@@ -1039,7 +1060,10 @@ let Renderer = class Renderer {
|
|
|
1039
1060
|
}
|
|
1040
1061
|
if (/^on[A-Z]/.test(key)) {
|
|
1041
1062
|
if (typeof value === 'function') {
|
|
1042
|
-
|
|
1063
|
+
const type = key.replace(/^on/, '').toLowerCase();
|
|
1064
|
+
const oldOn = oldVNode.on;
|
|
1065
|
+
this.nativeRenderer.unListen(nativeNode, type, oldOn[type].delegate);
|
|
1066
|
+
Reflect.deleteProperty(oldOn, type);
|
|
1043
1067
|
}
|
|
1044
1068
|
continue;
|
|
1045
1069
|
}
|
|
@@ -1073,12 +1097,8 @@ let Renderer = class Renderer {
|
|
|
1073
1097
|
}
|
|
1074
1098
|
if (/^on[A-Z]/.test(key)) {
|
|
1075
1099
|
const listenType = key.replace(/^on/, '').toLowerCase();
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
}
|
|
1079
|
-
if (typeof newValue === 'function') {
|
|
1080
|
-
this.nativeRenderer.listen(nativeNode, listenType, newValue);
|
|
1081
|
-
}
|
|
1100
|
+
newVNode.on = oldVNode.on;
|
|
1101
|
+
newVNode.on[listenType].listenFn = newValue;
|
|
1082
1102
|
continue;
|
|
1083
1103
|
}
|
|
1084
1104
|
if (key === refKey) {
|
|
@@ -1105,7 +1125,7 @@ let Renderer = class Renderer {
|
|
|
1105
1125
|
}
|
|
1106
1126
|
if (/^on[A-Z]/.test(key)) {
|
|
1107
1127
|
if (typeof value === 'function') {
|
|
1108
|
-
this.
|
|
1128
|
+
this.bindEvent(newVNode, key, nativeNode, value);
|
|
1109
1129
|
}
|
|
1110
1130
|
continue;
|
|
1111
1131
|
}
|
|
@@ -1128,6 +1148,22 @@ let Renderer = class Renderer {
|
|
|
1128
1148
|
}
|
|
1129
1149
|
}
|
|
1130
1150
|
}
|
|
1151
|
+
bindEvent(vNode, key, nativeNode, listenFn) {
|
|
1152
|
+
let on = vNode.on;
|
|
1153
|
+
if (!on) {
|
|
1154
|
+
vNode.on = on = {};
|
|
1155
|
+
}
|
|
1156
|
+
const type = key.replace(/^on/, '').toLowerCase();
|
|
1157
|
+
const delegate = function (...args) {
|
|
1158
|
+
return delegateObj.listenFn.apply(this, args);
|
|
1159
|
+
};
|
|
1160
|
+
const delegateObj = {
|
|
1161
|
+
delegate,
|
|
1162
|
+
listenFn
|
|
1163
|
+
};
|
|
1164
|
+
on[type] = delegateObj;
|
|
1165
|
+
this.nativeRenderer.listen(nativeNode, type, delegate);
|
|
1166
|
+
}
|
|
1131
1167
|
};
|
|
1132
1168
|
Renderer = __decorate([
|
|
1133
1169
|
Injectable(),
|
package/bundles/index.js
CHANGED
|
@@ -384,13 +384,25 @@ function useSignal(state) {
|
|
|
384
384
|
return;
|
|
385
385
|
}
|
|
386
386
|
state = newState;
|
|
387
|
-
|
|
387
|
+
const depCallbacks = Array.from(signal[depsKey]);
|
|
388
|
+
for (const fn of depCallbacks) {
|
|
389
|
+
// 回调中可能会对依赖做出修改,故需先缓存起来
|
|
388
390
|
fn();
|
|
389
391
|
}
|
|
390
392
|
};
|
|
391
393
|
signal[depsKey] = new Set();
|
|
392
394
|
return signal;
|
|
393
395
|
}
|
|
396
|
+
function invokeDepFn(fn) {
|
|
397
|
+
const deps = [];
|
|
398
|
+
signalDepsStack.push(deps);
|
|
399
|
+
const data = fn();
|
|
400
|
+
signalDepsStack.pop();
|
|
401
|
+
return {
|
|
402
|
+
deps,
|
|
403
|
+
data
|
|
404
|
+
};
|
|
405
|
+
}
|
|
394
406
|
/**
|
|
395
407
|
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
396
408
|
* 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
@@ -399,18 +411,32 @@ function useSignal(state) {
|
|
|
399
411
|
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
400
412
|
*/
|
|
401
413
|
function useDerived(callback, isContinue) {
|
|
402
|
-
|
|
403
|
-
signalDepsStack.push(deps);
|
|
404
|
-
const data = callback();
|
|
405
|
-
signalDepsStack.pop();
|
|
414
|
+
let { data, deps } = invokeDepFn(callback);
|
|
406
415
|
const signal = useSignal(data);
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
416
|
+
const component = getSetupContext(false);
|
|
417
|
+
const unListenRef = {};
|
|
418
|
+
function listen(model, deps, callback, unListenRef, isContinue) {
|
|
419
|
+
const nextListen = () => {
|
|
420
|
+
unListenRef.unListen();
|
|
421
|
+
const { data: nextData, deps: nextDeps } = invokeDepFn(callback);
|
|
422
|
+
model.set(nextData);
|
|
423
|
+
if (typeof isContinue !== 'function' || isContinue(nextData) !== false) {
|
|
424
|
+
listen(model, nextDeps, callback, unListenRef, isContinue);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
unListenRef.unListen = () => {
|
|
428
|
+
for (const s of deps) {
|
|
429
|
+
s[depsKey].delete(nextListen);
|
|
413
430
|
}
|
|
431
|
+
};
|
|
432
|
+
for (const s of deps) {
|
|
433
|
+
s[depsKey].add(nextListen);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
listen(signal, deps, callback, unListenRef, isContinue);
|
|
437
|
+
if (component) {
|
|
438
|
+
component.destroyCallbacks.push(() => {
|
|
439
|
+
unListenRef.unListen();
|
|
414
440
|
});
|
|
415
441
|
}
|
|
416
442
|
return signal;
|
|
@@ -918,14 +944,6 @@ exports.Renderer = class Renderer {
|
|
|
918
944
|
}
|
|
919
945
|
createChainByComponentFactory(context, factory, parent) {
|
|
920
946
|
const component = factory.createInstance(context);
|
|
921
|
-
// if (component.setup === Fragment) {
|
|
922
|
-
// const children = component.props.children
|
|
923
|
-
// return this.createChainByChildren(
|
|
924
|
-
// component,
|
|
925
|
-
// Array.isArray(children) ? children : [children],
|
|
926
|
-
// parent
|
|
927
|
-
// )
|
|
928
|
-
// }
|
|
929
947
|
return new Atom(component, parent);
|
|
930
948
|
}
|
|
931
949
|
createChainByJSXElement(context, element, parent) {
|
|
@@ -987,7 +1005,10 @@ exports.Renderer = class Renderer {
|
|
|
987
1005
|
continue;
|
|
988
1006
|
}
|
|
989
1007
|
if (key === 'class') {
|
|
990
|
-
|
|
1008
|
+
const className = classToString(props[key]);
|
|
1009
|
+
if (className) {
|
|
1010
|
+
this.nativeRenderer.setClass(nativeNode, className);
|
|
1011
|
+
}
|
|
991
1012
|
continue;
|
|
992
1013
|
}
|
|
993
1014
|
if (key === 'style') {
|
|
@@ -1000,7 +1021,7 @@ exports.Renderer = class Renderer {
|
|
|
1000
1021
|
if (/^on[A-Z]/.test(key)) {
|
|
1001
1022
|
const listener = props[key];
|
|
1002
1023
|
if (typeof listener === 'function') {
|
|
1003
|
-
this.
|
|
1024
|
+
this.bindEvent(vNode, key, nativeNode, listener);
|
|
1004
1025
|
}
|
|
1005
1026
|
continue;
|
|
1006
1027
|
}
|
|
@@ -1040,7 +1061,10 @@ exports.Renderer = class Renderer {
|
|
|
1040
1061
|
}
|
|
1041
1062
|
if (/^on[A-Z]/.test(key)) {
|
|
1042
1063
|
if (typeof value === 'function') {
|
|
1043
|
-
|
|
1064
|
+
const type = key.replace(/^on/, '').toLowerCase();
|
|
1065
|
+
const oldOn = oldVNode.on;
|
|
1066
|
+
this.nativeRenderer.unListen(nativeNode, type, oldOn[type].delegate);
|
|
1067
|
+
Reflect.deleteProperty(oldOn, type);
|
|
1044
1068
|
}
|
|
1045
1069
|
continue;
|
|
1046
1070
|
}
|
|
@@ -1074,12 +1098,8 @@ exports.Renderer = class Renderer {
|
|
|
1074
1098
|
}
|
|
1075
1099
|
if (/^on[A-Z]/.test(key)) {
|
|
1076
1100
|
const listenType = key.replace(/^on/, '').toLowerCase();
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
}
|
|
1080
|
-
if (typeof newValue === 'function') {
|
|
1081
|
-
this.nativeRenderer.listen(nativeNode, listenType, newValue);
|
|
1082
|
-
}
|
|
1101
|
+
newVNode.on = oldVNode.on;
|
|
1102
|
+
newVNode.on[listenType].listenFn = newValue;
|
|
1083
1103
|
continue;
|
|
1084
1104
|
}
|
|
1085
1105
|
if (key === refKey) {
|
|
@@ -1106,7 +1126,7 @@ exports.Renderer = class Renderer {
|
|
|
1106
1126
|
}
|
|
1107
1127
|
if (/^on[A-Z]/.test(key)) {
|
|
1108
1128
|
if (typeof value === 'function') {
|
|
1109
|
-
this.
|
|
1129
|
+
this.bindEvent(newVNode, key, nativeNode, value);
|
|
1110
1130
|
}
|
|
1111
1131
|
continue;
|
|
1112
1132
|
}
|
|
@@ -1129,6 +1149,22 @@ exports.Renderer = class Renderer {
|
|
|
1129
1149
|
}
|
|
1130
1150
|
}
|
|
1131
1151
|
}
|
|
1152
|
+
bindEvent(vNode, key, nativeNode, listenFn) {
|
|
1153
|
+
let on = vNode.on;
|
|
1154
|
+
if (!on) {
|
|
1155
|
+
vNode.on = on = {};
|
|
1156
|
+
}
|
|
1157
|
+
const type = key.replace(/^on/, '').toLowerCase();
|
|
1158
|
+
const delegate = function (...args) {
|
|
1159
|
+
return delegateObj.listenFn.apply(this, args);
|
|
1160
|
+
};
|
|
1161
|
+
const delegateObj = {
|
|
1162
|
+
delegate,
|
|
1163
|
+
listenFn
|
|
1164
|
+
};
|
|
1165
|
+
on[type] = delegateObj;
|
|
1166
|
+
this.nativeRenderer.listen(nativeNode, type, delegate);
|
|
1167
|
+
}
|
|
1132
1168
|
};
|
|
1133
1169
|
exports.Renderer = __decorate([
|
|
1134
1170
|
di.Injectable(),
|
|
@@ -21,11 +21,16 @@ export declare class JSXText implements JSXTypeof {
|
|
|
21
21
|
constructor(text: string);
|
|
22
22
|
is(target: JSXTypeof): boolean;
|
|
23
23
|
}
|
|
24
|
+
export interface ListenDelegate {
|
|
25
|
+
delegate: () => any;
|
|
26
|
+
listenFn: ((...args: any[]) => any) | void;
|
|
27
|
+
}
|
|
24
28
|
export declare class JSXElement implements JSXTypeof {
|
|
25
29
|
type: string;
|
|
26
30
|
props: Props<any>;
|
|
27
31
|
key?: Key | undefined;
|
|
28
32
|
$$typeOf: string;
|
|
33
|
+
on?: Record<string, ListenDelegate>;
|
|
29
34
|
constructor(type: string, props: Props<any>, key?: Key | undefined);
|
|
30
35
|
is(target: JSXTypeof): boolean;
|
|
31
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viewfly/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Viewfly is a simple and easy-to-use JavaScript framework with an intuitive development experience.",
|
|
5
5
|
"main": "./bundles/index.js",
|
|
6
6
|
"module": "./bundles/index.esm.js",
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"bugs": {
|
|
35
35
|
"url": "https://github.com/viewfly/viewfly.git/issues"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "fed5b3e328a9f70873bb1c33ea3789c099ad3ebe"
|
|
38
38
|
}
|