@lvce-editor/virtual-dom-worker 1.6.0 → 1.8.0
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/package.json +1 -1
- package/src/parts/AddPatch/AddPatch.ts +6 -0
- package/src/parts/AttributePatch/AttributePatch.ts +0 -1
- package/src/parts/GetTotalChildCount/GetTotalChildCount.ts +16 -0
- package/src/parts/NavigateChildPatch/NavigateChildPatch.ts +4 -0
- package/src/parts/NavigateParentPatch/NavigateParentPatch.ts +4 -0
- package/src/parts/NavigateSiblingPatch/NavigateSiblingPatch.ts +4 -0
- package/src/parts/Patch/Patch.ts +13 -1
- package/src/parts/PatchType/PatchType.ts +6 -0
- package/src/parts/RemoveAttributePatch/RemoveAttributePatch.ts +0 -1
- package/src/parts/RemoveChildPatch/RemoveChildPatch.ts +4 -0
- package/src/parts/RemovePatch/RemovePatch.ts +4 -0
- package/src/parts/TextPatch/TextPatch.ts +0 -1
- package/src/parts/VirtualDomDiff/VirtualDomDiff.ts +103 -27
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { VirtualDomNode } from '../VirtualDomNode/VirtualDomNode.ts'
|
|
2
|
+
|
|
3
|
+
export const getTotalChildCount = (
|
|
4
|
+
nodes: readonly VirtualDomNode[],
|
|
5
|
+
index: number,
|
|
6
|
+
): number => {
|
|
7
|
+
let i = index
|
|
8
|
+
let pending = 1
|
|
9
|
+
while (pending) {
|
|
10
|
+
const node = nodes[i]
|
|
11
|
+
pending += node.childCount
|
|
12
|
+
pending--
|
|
13
|
+
i++
|
|
14
|
+
}
|
|
15
|
+
return i - index
|
|
16
|
+
}
|
package/src/parts/Patch/Patch.ts
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
|
+
import type { AddPatch } from '../AddPatch/AddPatch.ts'
|
|
1
2
|
import type { AttributePatch } from '../AttributePatch/AttributePatch.ts'
|
|
3
|
+
import type { NavigateChildPatch } from '../NavigateChildPatch/NavigateChildPatch.ts'
|
|
4
|
+
import type { NavigateParentPatch } from '../NavigateParentPatch/NavigateParentPatch.ts'
|
|
5
|
+
import type { NavigateSiblingPatch } from '../NavigateSiblingPatch/NavigateSiblingPatch.ts'
|
|
6
|
+
import type { RemoveAttributePatch } from '../RemoveAttributePatch/RemoveAttributePatch.ts'
|
|
7
|
+
import type { RemoveChildPatch } from '../RemoveChildPatch/RemoveChildPatch.ts'
|
|
8
|
+
import type { RemovePatch } from '../RemovePatch/RemovePatch.ts'
|
|
2
9
|
import type { ReplacePatch } from '../ReplacePatch/ReplacePatch.ts'
|
|
3
10
|
import type { TextPatch } from '../TextPatch/TextPatch.ts'
|
|
4
|
-
import type { RemoveAttributePatch } from '../RemoveAttributePatch/RemoveAttributePatch.ts'
|
|
5
11
|
|
|
6
12
|
export type Patch =
|
|
7
13
|
| TextPatch
|
|
8
14
|
| AttributePatch
|
|
9
15
|
| ReplacePatch
|
|
10
16
|
| RemoveAttributePatch
|
|
17
|
+
| RemovePatch
|
|
18
|
+
| AddPatch
|
|
19
|
+
| NavigateChildPatch
|
|
20
|
+
| NavigateParentPatch
|
|
21
|
+
| RemoveChildPatch
|
|
22
|
+
| NavigateSiblingPatch
|
|
@@ -2,3 +2,9 @@ export const SetText = 1
|
|
|
2
2
|
export const Replace = 2
|
|
3
3
|
export const SetAttribute = 3
|
|
4
4
|
export const RemoveAttribute = 4
|
|
5
|
+
export const Remove = 5
|
|
6
|
+
export const Add = 6
|
|
7
|
+
export const NavigateChild = 7
|
|
8
|
+
export const NavigateParent = 8
|
|
9
|
+
export const RemoveChild = 9
|
|
10
|
+
export const NavigateSibling = 10
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Patch } from '../Patch/Patch.ts'
|
|
2
2
|
import type { VirtualDomNode } from '../VirtualDomNode/VirtualDomNode.ts'
|
|
3
|
+
import * as GetTotalChildCount from '../GetTotalChildCount/GetTotalChildCount.ts'
|
|
3
4
|
import * as PatchType from '../PatchType/PatchType.ts'
|
|
4
5
|
import * as VirtualDomElements from '../VirtualDomElements/VirtualDomElements.ts'
|
|
5
6
|
|
|
@@ -8,44 +9,46 @@ export const diff = (
|
|
|
8
9
|
newNodes: readonly VirtualDomNode[],
|
|
9
10
|
): readonly Patch[] => {
|
|
10
11
|
const patches: Patch[] = []
|
|
12
|
+
let i = 0 // Index for oldNodes
|
|
13
|
+
let j = 0 // Index for newNodes
|
|
14
|
+
let siblingOffset = 0
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const oldNodeCount = oldNodes.length
|
|
17
|
+
const newNodeCount = newNodes.length
|
|
18
|
+
|
|
19
|
+
while (i < oldNodeCount && j < newNodeCount) {
|
|
14
20
|
const oldNode = oldNodes[i]
|
|
15
|
-
const newNode = newNodes[
|
|
21
|
+
const newNode = newNodes[j]
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
if (oldNode.type !== newNode.type) {
|
|
24
|
+
const oldTotal = GetTotalChildCount.getTotalChildCount(oldNodes, i)
|
|
25
|
+
const newTotal = GetTotalChildCount.getTotalChildCount(newNodes, j)
|
|
26
|
+
const last = patches.at(-1)
|
|
27
|
+
if (last && last.type === PatchType.NavigateChild) {
|
|
28
|
+
patches.pop()
|
|
29
|
+
}
|
|
19
30
|
patches.push({
|
|
20
|
-
type: PatchType.
|
|
21
|
-
index:
|
|
22
|
-
// @ts-ignore
|
|
23
|
-
node: undefined,
|
|
31
|
+
type: PatchType.RemoveChild,
|
|
32
|
+
index: 0,
|
|
24
33
|
})
|
|
25
|
-
continue
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Handle node addition
|
|
29
|
-
if (!oldNode) {
|
|
30
34
|
patches.push({
|
|
31
|
-
type: PatchType.
|
|
32
|
-
|
|
33
|
-
node: newNode,
|
|
35
|
+
type: PatchType.Add,
|
|
36
|
+
nodes: newNodes.slice(j, j + newTotal),
|
|
34
37
|
})
|
|
38
|
+
i += oldTotal
|
|
39
|
+
j += newTotal
|
|
35
40
|
continue
|
|
36
41
|
}
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
if (oldNode.type !== newNode.type) {
|
|
43
|
+
if (siblingOffset > 0) {
|
|
40
44
|
patches.push({
|
|
41
|
-
type: PatchType.
|
|
42
|
-
index:
|
|
43
|
-
node: newNode,
|
|
45
|
+
type: PatchType.NavigateSibling,
|
|
46
|
+
index: siblingOffset,
|
|
44
47
|
})
|
|
45
|
-
|
|
48
|
+
siblingOffset = 0
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
//
|
|
51
|
+
// text node
|
|
49
52
|
if (
|
|
50
53
|
oldNode.type === VirtualDomElements.Text &&
|
|
51
54
|
newNode.type === VirtualDomElements.Text
|
|
@@ -53,10 +56,12 @@ export const diff = (
|
|
|
53
56
|
if (oldNode.text !== newNode.text) {
|
|
54
57
|
patches.push({
|
|
55
58
|
type: PatchType.SetText,
|
|
56
|
-
index: i,
|
|
57
59
|
value: newNode.text,
|
|
58
60
|
})
|
|
59
61
|
}
|
|
62
|
+
i++
|
|
63
|
+
j++
|
|
64
|
+
siblingOffset++
|
|
60
65
|
continue
|
|
61
66
|
}
|
|
62
67
|
|
|
@@ -73,7 +78,6 @@ export const diff = (
|
|
|
73
78
|
if (oldNode[key] !== newNode[key]) {
|
|
74
79
|
patches.push({
|
|
75
80
|
type: PatchType.SetAttribute,
|
|
76
|
-
index: i,
|
|
77
81
|
key,
|
|
78
82
|
value: newNode[key],
|
|
79
83
|
})
|
|
@@ -85,11 +89,83 @@ export const diff = (
|
|
|
85
89
|
if (!(key in newNode)) {
|
|
86
90
|
patches.push({
|
|
87
91
|
type: PatchType.RemoveAttribute,
|
|
88
|
-
index: i,
|
|
89
92
|
key,
|
|
90
93
|
})
|
|
91
94
|
}
|
|
92
95
|
}
|
|
96
|
+
|
|
97
|
+
if (oldNode.childCount && newNode.childCount) {
|
|
98
|
+
patches.push({
|
|
99
|
+
type: PatchType.NavigateChild,
|
|
100
|
+
index: 0,
|
|
101
|
+
})
|
|
102
|
+
i++
|
|
103
|
+
j++
|
|
104
|
+
continue
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (oldNode.childCount) {
|
|
108
|
+
const total = GetTotalChildCount.getTotalChildCount(oldNodes, i)
|
|
109
|
+
// const last = patches.at(-1)
|
|
110
|
+
// if (last && last.type === PatchType.NavigateChild) {
|
|
111
|
+
// patches.pop()
|
|
112
|
+
// }
|
|
113
|
+
patches.push({
|
|
114
|
+
type: PatchType.RemoveChild,
|
|
115
|
+
index: 0,
|
|
116
|
+
})
|
|
117
|
+
i += total
|
|
118
|
+
j++
|
|
119
|
+
continue
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (newNode.childCount) {
|
|
123
|
+
const total = GetTotalChildCount.getTotalChildCount(newNodes, j)
|
|
124
|
+
patches.push({
|
|
125
|
+
type: PatchType.Add,
|
|
126
|
+
nodes: newNodes.slice(j + 1, j + total),
|
|
127
|
+
})
|
|
128
|
+
i++
|
|
129
|
+
j += total
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
i++
|
|
134
|
+
j++
|
|
135
|
+
siblingOffset++
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Handle remaining old nodes
|
|
139
|
+
while (i < oldNodes.length) {
|
|
140
|
+
if (siblingOffset > 0) {
|
|
141
|
+
patches.push({
|
|
142
|
+
type: PatchType.NavigateSibling,
|
|
143
|
+
index: siblingOffset,
|
|
144
|
+
})
|
|
145
|
+
siblingOffset = 0
|
|
146
|
+
}
|
|
147
|
+
patches.push({
|
|
148
|
+
type: PatchType.RemoveChild,
|
|
149
|
+
index: 0,
|
|
150
|
+
})
|
|
151
|
+
i += GetTotalChildCount.getTotalChildCount(oldNodes, i)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Handle remaining new nodes
|
|
155
|
+
while (j < newNodes.length) {
|
|
156
|
+
if (siblingOffset > 0) {
|
|
157
|
+
patches.push({
|
|
158
|
+
type: PatchType.NavigateSibling,
|
|
159
|
+
index: siblingOffset,
|
|
160
|
+
})
|
|
161
|
+
siblingOffset = 0
|
|
162
|
+
}
|
|
163
|
+
const count = GetTotalChildCount.getTotalChildCount(newNodes, j)
|
|
164
|
+
patches.push({
|
|
165
|
+
type: PatchType.Add,
|
|
166
|
+
nodes: newNodes.slice(j, j + count),
|
|
167
|
+
})
|
|
168
|
+
j += count
|
|
93
169
|
}
|
|
94
170
|
|
|
95
171
|
return patches
|