@viewfly/core 3.0.0-alpha.0 → 3.0.0-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/README.md +3 -3
- package/dist/index.esm.js +146 -55
- package/dist/index.js +146 -55
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ pnpm add @viewfly/core
|
|
|
19
19
|
import 'reflect-metadata'
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
更稳妥的做法以**当前安装版本**随附的类型定义与 README 为准。
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
@@ -49,7 +49,7 @@ import 'reflect-metadata'
|
|
|
49
49
|
| 组件 | 函数组件:在 JSX 中当标签使用;配合生命周期钩子使用。 |
|
|
50
50
|
| 生命周期 | **`onMounted`**、**`onUpdated`**、**`onUnmounted`** 等(须在组件 setup 阶段调用)。 |
|
|
51
51
|
| 响应式 | **`reactive`**、**`shallowReactive`**、**`watch`** 等(`reactive` 模块)。 |
|
|
52
|
-
| 信号 | **`createSignal`**、**`
|
|
52
|
+
| 信号 / 派生 | **`createSignal`**、**`computed`** 等(见 `reactive` 导出;具体符号以类型为准)。 |
|
|
53
53
|
| 依赖注入 | 在组件内用 **`inject`** 解析 token;用 **`Injectable()`** 声明可注入类;用 **`withAnnotation`** 或 **`createContext`** / **`createContextProvider`** 挂载 **`Provider`**;根应用上通过 **`createApp(...).provide(...)`**(由 **`@viewfly/platform-browser`** 提供)注册全局提供者。 |
|
|
54
54
|
| 自定义 DOM 属性标记 | **`withMark(marks, setup)`**:为组件渲染出的元素附加与 `marks` 同名的属性(常用于 scoped CSS 的 `scopeId` 等场景)。 |
|
|
55
55
|
|
|
@@ -59,7 +59,7 @@ import 'reflect-metadata'
|
|
|
59
59
|
|
|
60
60
|
## 文档与示例
|
|
61
61
|
|
|
62
|
-
-
|
|
62
|
+
- **权威说明**:本文件、源码注释与发布包中的 **`.d.ts`**(第三方文档站点可能滞后)。
|
|
63
63
|
- **本仓库试跑**:仓库根目录执行 `pnpm dev` 打开 playground
|
|
64
64
|
|
|
65
65
|
---
|
package/dist/index.esm.js
CHANGED
|
@@ -1063,9 +1063,17 @@ function hasChange(newProps, oldProps) {
|
|
|
1063
1063
|
return false;
|
|
1064
1064
|
}
|
|
1065
1065
|
function comparePropsWithCallbacks(oldProps, newProps, onDeleted, onAdded, onUpdated) {
|
|
1066
|
-
|
|
1067
|
-
for (
|
|
1068
|
-
|
|
1066
|
+
const oldKeys = Object.keys(oldProps);
|
|
1067
|
+
for (let i = 0; i < oldKeys.length; i++) {
|
|
1068
|
+
const key = oldKeys[i];
|
|
1069
|
+
if (!(key in newProps)) onDeleted(key, oldProps[key]);
|
|
1070
|
+
}
|
|
1071
|
+
const newKeys = Object.keys(newProps);
|
|
1072
|
+
for (let i = 0; i < newKeys.length; i++) {
|
|
1073
|
+
const key = newKeys[i];
|
|
1074
|
+
if (!(key in oldProps)) onAdded(key, newProps[key]);
|
|
1075
|
+
else if (oldProps[key] !== newProps[key]) onUpdated(key, newProps[key], oldProps[key]);
|
|
1076
|
+
}
|
|
1069
1077
|
}
|
|
1070
1078
|
function classToString(config) {
|
|
1071
1079
|
if (typeof config === "string") return config;
|
|
@@ -1662,7 +1670,7 @@ var NativeRenderer = class {};
|
|
|
1662
1670
|
//#endregion
|
|
1663
1671
|
//#region src/base/renderer.ts
|
|
1664
1672
|
var listenerReg = /^on[A-Z]/;
|
|
1665
|
-
var nativeNodeRefRecord = /* @__PURE__ */ new
|
|
1673
|
+
var nativeNodeRefRecord = /* @__PURE__ */ new WeakMap();
|
|
1666
1674
|
function createRenderer(component, nativeRenderer, namespace) {
|
|
1667
1675
|
let isInit = true;
|
|
1668
1676
|
return function render(host) {
|
|
@@ -1729,24 +1737,85 @@ function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
|
|
|
1729
1737
|
component.rendered();
|
|
1730
1738
|
}
|
|
1731
1739
|
}
|
|
1740
|
+
function createOldAtomMatcher(oldAtoms) {
|
|
1741
|
+
const typeMap = /* @__PURE__ */ new Map();
|
|
1742
|
+
const cursorMap = /* @__PURE__ */ new WeakMap();
|
|
1743
|
+
for (let i = 0; i < oldAtoms.length; i++) {
|
|
1744
|
+
const atom = oldAtoms[i];
|
|
1745
|
+
let nodeTypeMap = typeMap.get(atom.type);
|
|
1746
|
+
if (!nodeTypeMap) {
|
|
1747
|
+
nodeTypeMap = /* @__PURE__ */ new Map();
|
|
1748
|
+
typeMap.set(atom.type, nodeTypeMap);
|
|
1749
|
+
}
|
|
1750
|
+
let keyMap = nodeTypeMap.get(atom.nodeType);
|
|
1751
|
+
if (!keyMap) {
|
|
1752
|
+
keyMap = /* @__PURE__ */ new Map();
|
|
1753
|
+
nodeTypeMap.set(atom.nodeType, keyMap);
|
|
1754
|
+
}
|
|
1755
|
+
const key = atom.key;
|
|
1756
|
+
const indices = keyMap.get(key);
|
|
1757
|
+
if (indices) indices.push(i);
|
|
1758
|
+
else keyMap.set(key, [i]);
|
|
1759
|
+
}
|
|
1760
|
+
const take = (atom, matched) => {
|
|
1761
|
+
const nodeTypeMap = typeMap.get(atom.type);
|
|
1762
|
+
if (!nodeTypeMap) return -1;
|
|
1763
|
+
const keyMap = nodeTypeMap.get(atom.nodeType);
|
|
1764
|
+
if (!keyMap) return -1;
|
|
1765
|
+
const indices = keyMap.get(atom.key);
|
|
1766
|
+
if (!indices || !indices.length) return -1;
|
|
1767
|
+
let cursor = cursorMap.get(indices) ?? 0;
|
|
1768
|
+
while (cursor < indices.length) {
|
|
1769
|
+
const index = indices[cursor];
|
|
1770
|
+
cursor++;
|
|
1771
|
+
if (!matched[index]) {
|
|
1772
|
+
cursorMap.set(indices, cursor);
|
|
1773
|
+
return index;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
cursorMap.set(indices, cursor);
|
|
1777
|
+
return -1;
|
|
1778
|
+
};
|
|
1779
|
+
return { take };
|
|
1780
|
+
}
|
|
1732
1781
|
function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
|
|
1733
1782
|
const commits = [];
|
|
1734
|
-
|
|
1735
|
-
oldAtom = createChanges(newAtom, oldAtom, commits);
|
|
1736
|
-
newAtom = newAtom.sibling;
|
|
1737
|
-
}
|
|
1783
|
+
const oldAtoms = [];
|
|
1738
1784
|
let dirtyDiffAtom = oldAtom;
|
|
1739
1785
|
while (dirtyDiffAtom) {
|
|
1740
|
-
|
|
1786
|
+
oldAtoms.push(dirtyDiffAtom);
|
|
1741
1787
|
dirtyDiffAtom = dirtyDiffAtom.sibling;
|
|
1742
1788
|
}
|
|
1789
|
+
const matched = new Array(oldAtoms.length).fill(false);
|
|
1790
|
+
const matcher = createOldAtomMatcher(oldAtoms);
|
|
1791
|
+
const pendingDeleteIndices = [];
|
|
1792
|
+
let cursor = newAtom;
|
|
1793
|
+
while (cursor) {
|
|
1794
|
+
const matchedIndex = matcher.take(cursor, matched);
|
|
1795
|
+
if (matchedIndex >= 0) {
|
|
1796
|
+
matched[matchedIndex] = true;
|
|
1797
|
+
commits.push({
|
|
1798
|
+
dirtyAtom: oldAtoms[matchedIndex],
|
|
1799
|
+
newAtom: cursor
|
|
1800
|
+
});
|
|
1801
|
+
} else commits.push({
|
|
1802
|
+
dirtyAtom: null,
|
|
1803
|
+
newAtom: cursor
|
|
1804
|
+
});
|
|
1805
|
+
cursor = cursor.sibling;
|
|
1806
|
+
}
|
|
1807
|
+
for (let i = 0; i < oldAtoms.length; i++) if (!matched[i]) {
|
|
1808
|
+
pendingDeleteIndices.push(i);
|
|
1809
|
+
cleanView(nativeRenderer, oldAtoms[i], true);
|
|
1810
|
+
}
|
|
1743
1811
|
let offset = 0;
|
|
1812
|
+
let pendingDeleteCursor = 0;
|
|
1744
1813
|
const len = commits.length;
|
|
1745
1814
|
for (let i = 0; i < len; i++) {
|
|
1746
|
-
while (
|
|
1747
|
-
if (
|
|
1815
|
+
while (pendingDeleteCursor < pendingDeleteIndices.length) {
|
|
1816
|
+
if (oldAtoms[pendingDeleteIndices[pendingDeleteCursor]].index <= i) {
|
|
1748
1817
|
offset--;
|
|
1749
|
-
|
|
1818
|
+
pendingDeleteCursor++;
|
|
1750
1819
|
continue;
|
|
1751
1820
|
}
|
|
1752
1821
|
break;
|
|
@@ -1769,29 +1838,6 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMo
|
|
|
1769
1838
|
}
|
|
1770
1839
|
}
|
|
1771
1840
|
}
|
|
1772
|
-
function createChanges(newAtom, oldAtom, commits) {
|
|
1773
|
-
const startDiffAtom = oldAtom;
|
|
1774
|
-
let prev = null;
|
|
1775
|
-
while (oldAtom) {
|
|
1776
|
-
if (oldAtom.type === newAtom.type && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
|
|
1777
|
-
commits.push({
|
|
1778
|
-
dirtyAtom: oldAtom,
|
|
1779
|
-
newAtom
|
|
1780
|
-
});
|
|
1781
|
-
const next = oldAtom.sibling;
|
|
1782
|
-
if (!prev) return next;
|
|
1783
|
-
prev.sibling = next;
|
|
1784
|
-
return startDiffAtom;
|
|
1785
|
-
}
|
|
1786
|
-
prev = oldAtom;
|
|
1787
|
-
oldAtom = oldAtom.sibling;
|
|
1788
|
-
}
|
|
1789
|
-
commits.push({
|
|
1790
|
-
dirtyAtom: null,
|
|
1791
|
-
newAtom
|
|
1792
|
-
});
|
|
1793
|
-
return startDiffAtom;
|
|
1794
|
-
}
|
|
1795
1841
|
function updateText(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
|
|
1796
1842
|
const nativeNode = oldAtom.nativeNode;
|
|
1797
1843
|
newAtom.nativeNode = nativeNode;
|
|
@@ -1890,9 +1936,12 @@ function cleanView(nativeRenderer, atom, needClean) {
|
|
|
1890
1936
|
}
|
|
1891
1937
|
if (atom.type === ElementAtomType) {
|
|
1892
1938
|
const record = nativeNodeRefRecord.get(atom);
|
|
1893
|
-
if (record)
|
|
1894
|
-
|
|
1895
|
-
|
|
1939
|
+
if (record) {
|
|
1940
|
+
nativeNodeRefRecord.delete(atom);
|
|
1941
|
+
record.forEach((fn) => {
|
|
1942
|
+
if (typeof fn === "function") fn();
|
|
1943
|
+
});
|
|
1944
|
+
}
|
|
1896
1945
|
}
|
|
1897
1946
|
cleanChildren(atom, nativeRenderer, needClean);
|
|
1898
1947
|
}
|
|
@@ -1981,7 +2030,10 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
|
1981
2030
|
const nativeNode = nativeRenderer.createElement(jsxNode.type, namespace);
|
|
1982
2031
|
const props = jsxNode.props;
|
|
1983
2032
|
let bindingRefs;
|
|
1984
|
-
|
|
2033
|
+
const propKeys = Object.keys(props);
|
|
2034
|
+
const propKeyLen = propKeys.length;
|
|
2035
|
+
for (let i = 0; i < propKeyLen; i++) {
|
|
2036
|
+
const key = propKeys[i];
|
|
1985
2037
|
if (key === "children") {
|
|
1986
2038
|
atom.child = createElementChildren(jsxNode.type, props.children, nativeRenderer, namespace);
|
|
1987
2039
|
continue;
|
|
@@ -2016,9 +2068,11 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
|
2016
2068
|
});
|
|
2017
2069
|
context.host = nativeNode;
|
|
2018
2070
|
context.isParent = false;
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2071
|
+
if (bindingRefs) {
|
|
2072
|
+
const refEffects = /* @__PURE__ */ new Map();
|
|
2073
|
+
nativeNodeRefRecord.set(atom, refEffects);
|
|
2074
|
+
applyRefs(bindingRefs, nativeNode, refEffects);
|
|
2075
|
+
}
|
|
2022
2076
|
}
|
|
2023
2077
|
function createTextNode(nativeRenderer, atom, context) {
|
|
2024
2078
|
const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.namespace);
|
|
@@ -2037,8 +2091,20 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2037
2091
|
reuseElementChildrenView(nativeRenderer, newAtom, context);
|
|
2038
2092
|
return;
|
|
2039
2093
|
}
|
|
2094
|
+
let unBindRefs;
|
|
2040
2095
|
let bindRefs;
|
|
2041
2096
|
let updatedChildren = false;
|
|
2097
|
+
const styleCache = /* @__PURE__ */ new WeakMap();
|
|
2098
|
+
const toStyleObject = (style) => {
|
|
2099
|
+
if (style && typeof style === "object") {
|
|
2100
|
+
const cached = styleCache.get(style);
|
|
2101
|
+
if (cached) return cached;
|
|
2102
|
+
const normalized = styleToObject(style);
|
|
2103
|
+
styleCache.set(style, normalized);
|
|
2104
|
+
return normalized;
|
|
2105
|
+
}
|
|
2106
|
+
return styleToObject(style);
|
|
2107
|
+
};
|
|
2042
2108
|
comparePropsWithCallbacks(oldVNode.props, newVNode.props, (key, oldValue) => {
|
|
2043
2109
|
if (key === "children") {
|
|
2044
2110
|
updatedChildren = true;
|
|
@@ -2050,14 +2116,22 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2050
2116
|
return;
|
|
2051
2117
|
}
|
|
2052
2118
|
if (key === "style") {
|
|
2053
|
-
|
|
2119
|
+
const oldStyle = toStyleObject(oldValue);
|
|
2120
|
+
const styleNames = Object.keys(oldStyle);
|
|
2121
|
+
for (let i = 0; i < styleNames.length; i++) {
|
|
2122
|
+
const styleName = styleNames[i];
|
|
2123
|
+
nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
|
|
2124
|
+
}
|
|
2054
2125
|
return;
|
|
2055
2126
|
}
|
|
2056
2127
|
if (listenerReg.test(key)) {
|
|
2057
2128
|
if (typeof oldValue === "function") nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
|
|
2058
2129
|
return;
|
|
2059
2130
|
}
|
|
2060
|
-
if (key === "ref")
|
|
2131
|
+
if (key === "ref") {
|
|
2132
|
+
unBindRefs = oldValue;
|
|
2133
|
+
return;
|
|
2134
|
+
}
|
|
2061
2135
|
nativeRenderer.removeProperty(nativeNode, key, isSvg);
|
|
2062
2136
|
}, (key, value) => {
|
|
2063
2137
|
if (key === "children") {
|
|
@@ -2071,8 +2145,12 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2071
2145
|
return;
|
|
2072
2146
|
}
|
|
2073
2147
|
if (key === "style") {
|
|
2074
|
-
const styleObj =
|
|
2075
|
-
|
|
2148
|
+
const styleObj = toStyleObject(value);
|
|
2149
|
+
const styleNames = Object.keys(styleObj);
|
|
2150
|
+
for (let i = 0; i < styleNames.length; i++) {
|
|
2151
|
+
const styleName = styleNames[i];
|
|
2152
|
+
nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
|
|
2153
|
+
}
|
|
2076
2154
|
return;
|
|
2077
2155
|
}
|
|
2078
2156
|
if (listenerReg.test(key)) {
|
|
@@ -2100,7 +2178,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2100
2178
|
return;
|
|
2101
2179
|
}
|
|
2102
2180
|
if (key === "style") {
|
|
2103
|
-
comparePropsWithCallbacks(
|
|
2181
|
+
comparePropsWithCallbacks(toStyleObject(oldValue), toStyleObject(newValue), (styleName) => {
|
|
2104
2182
|
nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
|
|
2105
2183
|
}, (styleName, styleValue) => {
|
|
2106
2184
|
nativeRenderer.setStyle(nativeNode, styleName, styleValue, isSvg);
|
|
@@ -2115,17 +2193,26 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2115
2193
|
return;
|
|
2116
2194
|
}
|
|
2117
2195
|
if (key === "ref") {
|
|
2196
|
+
unBindRefs = oldValue;
|
|
2118
2197
|
bindRefs = newValue;
|
|
2119
2198
|
return;
|
|
2120
2199
|
}
|
|
2121
2200
|
nativeRenderer.setProperty(nativeNode, key, newValue, isSvg);
|
|
2122
2201
|
});
|
|
2123
2202
|
if (!updatedChildren) newAtom.child = oldAtom.child;
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2203
|
+
if (bindRefs === unBindRefs) {
|
|
2204
|
+
const refEffects = nativeNodeRefRecord.get(oldAtom);
|
|
2205
|
+
if (refEffects) {
|
|
2206
|
+
nativeNodeRefRecord.delete(oldAtom);
|
|
2207
|
+
nativeNodeRefRecord.set(newAtom, refEffects);
|
|
2208
|
+
}
|
|
2209
|
+
} else {
|
|
2210
|
+
let refEffects = nativeNodeRefRecord.get(oldAtom);
|
|
2211
|
+
if (!refEffects) refEffects = /* @__PURE__ */ new Map();
|
|
2212
|
+
nativeNodeRefRecord.delete(oldAtom);
|
|
2213
|
+
nativeNodeRefRecord.set(newAtom, refEffects);
|
|
2214
|
+
updateRefs(bindRefs, nativeNode, refEffects);
|
|
2215
|
+
}
|
|
2129
2216
|
}
|
|
2130
2217
|
//#endregion
|
|
2131
2218
|
//#region src/base/root.component.ts
|
|
@@ -2216,9 +2303,13 @@ function viewfly(config) {
|
|
|
2216
2303
|
* @returns 一个对象,对象的 value 属性是计算的值
|
|
2217
2304
|
*/
|
|
2218
2305
|
function computed(getter) {
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2306
|
+
const proxy = new Proxy({ value: null }, readonlyProxyHandler);
|
|
2307
|
+
watchEffect(() => {
|
|
2308
|
+
internalWrite(() => {
|
|
2309
|
+
proxy.value = getter();
|
|
2310
|
+
});
|
|
2311
|
+
});
|
|
2312
|
+
return proxy;
|
|
2222
2313
|
}
|
|
2223
2314
|
//#endregion
|
|
2224
2315
|
//#region src/reactive/shallow-reactive.ts
|
package/dist/index.js
CHANGED
|
@@ -1064,9 +1064,17 @@ function hasChange(newProps, oldProps) {
|
|
|
1064
1064
|
return false;
|
|
1065
1065
|
}
|
|
1066
1066
|
function comparePropsWithCallbacks(oldProps, newProps, onDeleted, onAdded, onUpdated) {
|
|
1067
|
-
|
|
1068
|
-
for (
|
|
1069
|
-
|
|
1067
|
+
const oldKeys = Object.keys(oldProps);
|
|
1068
|
+
for (let i = 0; i < oldKeys.length; i++) {
|
|
1069
|
+
const key = oldKeys[i];
|
|
1070
|
+
if (!(key in newProps)) onDeleted(key, oldProps[key]);
|
|
1071
|
+
}
|
|
1072
|
+
const newKeys = Object.keys(newProps);
|
|
1073
|
+
for (let i = 0; i < newKeys.length; i++) {
|
|
1074
|
+
const key = newKeys[i];
|
|
1075
|
+
if (!(key in oldProps)) onAdded(key, newProps[key]);
|
|
1076
|
+
else if (oldProps[key] !== newProps[key]) onUpdated(key, newProps[key], oldProps[key]);
|
|
1077
|
+
}
|
|
1070
1078
|
}
|
|
1071
1079
|
function classToString(config) {
|
|
1072
1080
|
if (typeof config === "string") return config;
|
|
@@ -2223,7 +2231,7 @@ var NativeRenderer = class {};
|
|
|
2223
2231
|
//#endregion
|
|
2224
2232
|
//#region src/base/renderer.ts
|
|
2225
2233
|
var listenerReg = /^on[A-Z]/;
|
|
2226
|
-
var nativeNodeRefRecord = /* @__PURE__ */ new
|
|
2234
|
+
var nativeNodeRefRecord = /* @__PURE__ */ new WeakMap();
|
|
2227
2235
|
function createRenderer(component, nativeRenderer, namespace) {
|
|
2228
2236
|
let isInit = true;
|
|
2229
2237
|
return function render(host) {
|
|
@@ -2290,24 +2298,85 @@ function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
|
|
|
2290
2298
|
component.rendered();
|
|
2291
2299
|
}
|
|
2292
2300
|
}
|
|
2301
|
+
function createOldAtomMatcher(oldAtoms) {
|
|
2302
|
+
const typeMap = /* @__PURE__ */ new Map();
|
|
2303
|
+
const cursorMap = /* @__PURE__ */ new WeakMap();
|
|
2304
|
+
for (let i = 0; i < oldAtoms.length; i++) {
|
|
2305
|
+
const atom = oldAtoms[i];
|
|
2306
|
+
let nodeTypeMap = typeMap.get(atom.type);
|
|
2307
|
+
if (!nodeTypeMap) {
|
|
2308
|
+
nodeTypeMap = /* @__PURE__ */ new Map();
|
|
2309
|
+
typeMap.set(atom.type, nodeTypeMap);
|
|
2310
|
+
}
|
|
2311
|
+
let keyMap = nodeTypeMap.get(atom.nodeType);
|
|
2312
|
+
if (!keyMap) {
|
|
2313
|
+
keyMap = /* @__PURE__ */ new Map();
|
|
2314
|
+
nodeTypeMap.set(atom.nodeType, keyMap);
|
|
2315
|
+
}
|
|
2316
|
+
const key = atom.key;
|
|
2317
|
+
const indices = keyMap.get(key);
|
|
2318
|
+
if (indices) indices.push(i);
|
|
2319
|
+
else keyMap.set(key, [i]);
|
|
2320
|
+
}
|
|
2321
|
+
const take = (atom, matched) => {
|
|
2322
|
+
const nodeTypeMap = typeMap.get(atom.type);
|
|
2323
|
+
if (!nodeTypeMap) return -1;
|
|
2324
|
+
const keyMap = nodeTypeMap.get(atom.nodeType);
|
|
2325
|
+
if (!keyMap) return -1;
|
|
2326
|
+
const indices = keyMap.get(atom.key);
|
|
2327
|
+
if (!indices || !indices.length) return -1;
|
|
2328
|
+
let cursor = cursorMap.get(indices) ?? 0;
|
|
2329
|
+
while (cursor < indices.length) {
|
|
2330
|
+
const index = indices[cursor];
|
|
2331
|
+
cursor++;
|
|
2332
|
+
if (!matched[index]) {
|
|
2333
|
+
cursorMap.set(indices, cursor);
|
|
2334
|
+
return index;
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
cursorMap.set(indices, cursor);
|
|
2338
|
+
return -1;
|
|
2339
|
+
};
|
|
2340
|
+
return { take };
|
|
2341
|
+
}
|
|
2293
2342
|
function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
|
|
2294
2343
|
const commits = [];
|
|
2295
|
-
|
|
2296
|
-
oldAtom = createChanges(newAtom, oldAtom, commits);
|
|
2297
|
-
newAtom = newAtom.sibling;
|
|
2298
|
-
}
|
|
2344
|
+
const oldAtoms = [];
|
|
2299
2345
|
let dirtyDiffAtom = oldAtom;
|
|
2300
2346
|
while (dirtyDiffAtom) {
|
|
2301
|
-
|
|
2347
|
+
oldAtoms.push(dirtyDiffAtom);
|
|
2302
2348
|
dirtyDiffAtom = dirtyDiffAtom.sibling;
|
|
2303
2349
|
}
|
|
2350
|
+
const matched = new Array(oldAtoms.length).fill(false);
|
|
2351
|
+
const matcher = createOldAtomMatcher(oldAtoms);
|
|
2352
|
+
const pendingDeleteIndices = [];
|
|
2353
|
+
let cursor = newAtom;
|
|
2354
|
+
while (cursor) {
|
|
2355
|
+
const matchedIndex = matcher.take(cursor, matched);
|
|
2356
|
+
if (matchedIndex >= 0) {
|
|
2357
|
+
matched[matchedIndex] = true;
|
|
2358
|
+
commits.push({
|
|
2359
|
+
dirtyAtom: oldAtoms[matchedIndex],
|
|
2360
|
+
newAtom: cursor
|
|
2361
|
+
});
|
|
2362
|
+
} else commits.push({
|
|
2363
|
+
dirtyAtom: null,
|
|
2364
|
+
newAtom: cursor
|
|
2365
|
+
});
|
|
2366
|
+
cursor = cursor.sibling;
|
|
2367
|
+
}
|
|
2368
|
+
for (let i = 0; i < oldAtoms.length; i++) if (!matched[i]) {
|
|
2369
|
+
pendingDeleteIndices.push(i);
|
|
2370
|
+
cleanView(nativeRenderer, oldAtoms[i], true);
|
|
2371
|
+
}
|
|
2304
2372
|
let offset = 0;
|
|
2373
|
+
let pendingDeleteCursor = 0;
|
|
2305
2374
|
const len = commits.length;
|
|
2306
2375
|
for (let i = 0; i < len; i++) {
|
|
2307
|
-
while (
|
|
2308
|
-
if (
|
|
2376
|
+
while (pendingDeleteCursor < pendingDeleteIndices.length) {
|
|
2377
|
+
if (oldAtoms[pendingDeleteIndices[pendingDeleteCursor]].index <= i) {
|
|
2309
2378
|
offset--;
|
|
2310
|
-
|
|
2379
|
+
pendingDeleteCursor++;
|
|
2311
2380
|
continue;
|
|
2312
2381
|
}
|
|
2313
2382
|
break;
|
|
@@ -2330,29 +2399,6 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMo
|
|
|
2330
2399
|
}
|
|
2331
2400
|
}
|
|
2332
2401
|
}
|
|
2333
|
-
function createChanges(newAtom, oldAtom, commits) {
|
|
2334
|
-
const startDiffAtom = oldAtom;
|
|
2335
|
-
let prev = null;
|
|
2336
|
-
while (oldAtom) {
|
|
2337
|
-
if (oldAtom.type === newAtom.type && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
|
|
2338
|
-
commits.push({
|
|
2339
|
-
dirtyAtom: oldAtom,
|
|
2340
|
-
newAtom
|
|
2341
|
-
});
|
|
2342
|
-
const next = oldAtom.sibling;
|
|
2343
|
-
if (!prev) return next;
|
|
2344
|
-
prev.sibling = next;
|
|
2345
|
-
return startDiffAtom;
|
|
2346
|
-
}
|
|
2347
|
-
prev = oldAtom;
|
|
2348
|
-
oldAtom = oldAtom.sibling;
|
|
2349
|
-
}
|
|
2350
|
-
commits.push({
|
|
2351
|
-
dirtyAtom: null,
|
|
2352
|
-
newAtom
|
|
2353
|
-
});
|
|
2354
|
-
return startDiffAtom;
|
|
2355
|
-
}
|
|
2356
2402
|
function updateText(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
|
|
2357
2403
|
const nativeNode = oldAtom.nativeNode;
|
|
2358
2404
|
newAtom.nativeNode = nativeNode;
|
|
@@ -2451,9 +2497,12 @@ function cleanView(nativeRenderer, atom, needClean) {
|
|
|
2451
2497
|
}
|
|
2452
2498
|
if (atom.type === ElementAtomType) {
|
|
2453
2499
|
const record = nativeNodeRefRecord.get(atom);
|
|
2454
|
-
if (record)
|
|
2455
|
-
|
|
2456
|
-
|
|
2500
|
+
if (record) {
|
|
2501
|
+
nativeNodeRefRecord.delete(atom);
|
|
2502
|
+
record.forEach((fn) => {
|
|
2503
|
+
if (typeof fn === "function") fn();
|
|
2504
|
+
});
|
|
2505
|
+
}
|
|
2457
2506
|
}
|
|
2458
2507
|
cleanChildren(atom, nativeRenderer, needClean);
|
|
2459
2508
|
}
|
|
@@ -2542,7 +2591,10 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
|
2542
2591
|
const nativeNode = nativeRenderer.createElement(jsxNode.type, namespace);
|
|
2543
2592
|
const props = jsxNode.props;
|
|
2544
2593
|
let bindingRefs;
|
|
2545
|
-
|
|
2594
|
+
const propKeys = Object.keys(props);
|
|
2595
|
+
const propKeyLen = propKeys.length;
|
|
2596
|
+
for (let i = 0; i < propKeyLen; i++) {
|
|
2597
|
+
const key = propKeys[i];
|
|
2546
2598
|
if (key === "children") {
|
|
2547
2599
|
atom.child = createElementChildren(jsxNode.type, props.children, nativeRenderer, namespace);
|
|
2548
2600
|
continue;
|
|
@@ -2577,9 +2629,11 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
|
2577
2629
|
});
|
|
2578
2630
|
context.host = nativeNode;
|
|
2579
2631
|
context.isParent = false;
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2632
|
+
if (bindingRefs) {
|
|
2633
|
+
const refEffects = /* @__PURE__ */ new Map();
|
|
2634
|
+
nativeNodeRefRecord.set(atom, refEffects);
|
|
2635
|
+
applyRefs(bindingRefs, nativeNode, refEffects);
|
|
2636
|
+
}
|
|
2583
2637
|
}
|
|
2584
2638
|
function createTextNode(nativeRenderer, atom, context) {
|
|
2585
2639
|
const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.namespace);
|
|
@@ -2598,8 +2652,20 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2598
2652
|
reuseElementChildrenView(nativeRenderer, newAtom, context);
|
|
2599
2653
|
return;
|
|
2600
2654
|
}
|
|
2655
|
+
let unBindRefs;
|
|
2601
2656
|
let bindRefs;
|
|
2602
2657
|
let updatedChildren = false;
|
|
2658
|
+
const styleCache = /* @__PURE__ */ new WeakMap();
|
|
2659
|
+
const toStyleObject = (style) => {
|
|
2660
|
+
if (style && typeof style === "object") {
|
|
2661
|
+
const cached = styleCache.get(style);
|
|
2662
|
+
if (cached) return cached;
|
|
2663
|
+
const normalized = styleToObject(style);
|
|
2664
|
+
styleCache.set(style, normalized);
|
|
2665
|
+
return normalized;
|
|
2666
|
+
}
|
|
2667
|
+
return styleToObject(style);
|
|
2668
|
+
};
|
|
2603
2669
|
comparePropsWithCallbacks(oldVNode.props, newVNode.props, (key, oldValue) => {
|
|
2604
2670
|
if (key === "children") {
|
|
2605
2671
|
updatedChildren = true;
|
|
@@ -2611,14 +2677,22 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2611
2677
|
return;
|
|
2612
2678
|
}
|
|
2613
2679
|
if (key === "style") {
|
|
2614
|
-
|
|
2680
|
+
const oldStyle = toStyleObject(oldValue);
|
|
2681
|
+
const styleNames = Object.keys(oldStyle);
|
|
2682
|
+
for (let i = 0; i < styleNames.length; i++) {
|
|
2683
|
+
const styleName = styleNames[i];
|
|
2684
|
+
nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
|
|
2685
|
+
}
|
|
2615
2686
|
return;
|
|
2616
2687
|
}
|
|
2617
2688
|
if (listenerReg.test(key)) {
|
|
2618
2689
|
if (typeof oldValue === "function") nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
|
|
2619
2690
|
return;
|
|
2620
2691
|
}
|
|
2621
|
-
if (key === "ref")
|
|
2692
|
+
if (key === "ref") {
|
|
2693
|
+
unBindRefs = oldValue;
|
|
2694
|
+
return;
|
|
2695
|
+
}
|
|
2622
2696
|
nativeRenderer.removeProperty(nativeNode, key, isSvg);
|
|
2623
2697
|
}, (key, value) => {
|
|
2624
2698
|
if (key === "children") {
|
|
@@ -2632,8 +2706,12 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2632
2706
|
return;
|
|
2633
2707
|
}
|
|
2634
2708
|
if (key === "style") {
|
|
2635
|
-
const styleObj =
|
|
2636
|
-
|
|
2709
|
+
const styleObj = toStyleObject(value);
|
|
2710
|
+
const styleNames = Object.keys(styleObj);
|
|
2711
|
+
for (let i = 0; i < styleNames.length; i++) {
|
|
2712
|
+
const styleName = styleNames[i];
|
|
2713
|
+
nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
|
|
2714
|
+
}
|
|
2637
2715
|
return;
|
|
2638
2716
|
}
|
|
2639
2717
|
if (listenerReg.test(key)) {
|
|
@@ -2661,7 +2739,7 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2661
2739
|
return;
|
|
2662
2740
|
}
|
|
2663
2741
|
if (key === "style") {
|
|
2664
|
-
comparePropsWithCallbacks(
|
|
2742
|
+
comparePropsWithCallbacks(toStyleObject(oldValue), toStyleObject(newValue), (styleName) => {
|
|
2665
2743
|
nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
|
|
2666
2744
|
}, (styleName, styleValue) => {
|
|
2667
2745
|
nativeRenderer.setStyle(nativeNode, styleName, styleValue, isSvg);
|
|
@@ -2676,17 +2754,26 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
|
|
|
2676
2754
|
return;
|
|
2677
2755
|
}
|
|
2678
2756
|
if (key === "ref") {
|
|
2757
|
+
unBindRefs = oldValue;
|
|
2679
2758
|
bindRefs = newValue;
|
|
2680
2759
|
return;
|
|
2681
2760
|
}
|
|
2682
2761
|
nativeRenderer.setProperty(nativeNode, key, newValue, isSvg);
|
|
2683
2762
|
});
|
|
2684
2763
|
if (!updatedChildren) newAtom.child = oldAtom.child;
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2764
|
+
if (bindRefs === unBindRefs) {
|
|
2765
|
+
const refEffects = nativeNodeRefRecord.get(oldAtom);
|
|
2766
|
+
if (refEffects) {
|
|
2767
|
+
nativeNodeRefRecord.delete(oldAtom);
|
|
2768
|
+
nativeNodeRefRecord.set(newAtom, refEffects);
|
|
2769
|
+
}
|
|
2770
|
+
} else {
|
|
2771
|
+
let refEffects = nativeNodeRefRecord.get(oldAtom);
|
|
2772
|
+
if (!refEffects) refEffects = /* @__PURE__ */ new Map();
|
|
2773
|
+
nativeNodeRefRecord.delete(oldAtom);
|
|
2774
|
+
nativeNodeRefRecord.set(newAtom, refEffects);
|
|
2775
|
+
updateRefs(bindRefs, nativeNode, refEffects);
|
|
2776
|
+
}
|
|
2690
2777
|
}
|
|
2691
2778
|
//#endregion
|
|
2692
2779
|
//#region src/base/root.component.ts
|
|
@@ -2777,9 +2864,13 @@ function viewfly(config) {
|
|
|
2777
2864
|
* @returns 一个对象,对象的 value 属性是计算的值
|
|
2778
2865
|
*/
|
|
2779
2866
|
function computed(getter) {
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2867
|
+
const proxy = new Proxy({ value: null }, readonlyProxyHandler);
|
|
2868
|
+
watchEffect(() => {
|
|
2869
|
+
internalWrite(() => {
|
|
2870
|
+
proxy.value = getter();
|
|
2871
|
+
});
|
|
2872
|
+
});
|
|
2873
|
+
return proxy;
|
|
2783
2874
|
}
|
|
2784
2875
|
//#endregion
|
|
2785
2876
|
//#region src/reactive/shallow-reactive.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viewfly/core",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.2",
|
|
4
4
|
"description": "Viewfly is a simple and easy-to-use JavaScript framework with an intuitive development experience.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.esm.js",
|