-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiffChildNodes.ts
More file actions
72 lines (66 loc) · 2.11 KB
/
diffChildNodes.ts
File metadata and controls
72 lines (66 loc) · 2.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import type { HashNode } from "../partition/index.js";
import type { ChangePath, SpecChange } from "./diffChangeSet.js";
/**
* 두 node의 children을 비교하여 added/removed change를 생성하고,
* 공통 자식 중 hash가 다른 경우 재귀 비교가 필요한 쌍을 반환
* @param base 기준 node
* @param head 비교 대상 node
* @param path 현재 경로 (base.key 포함)
*/
export function diffChildNodes<K>(
base: HashNode<K>,
head: HashNode<K>,
path: ChangePath<K>,
): {
changes: SpecChange<K>[];
modifiedPairs: Array<{
base: HashNode<K>;
head: HashNode<K>;
}>;
} {
const changes: SpecChange<K>[] = [];
const modifiedPairs: Array<{
base: HashNode<K>;
head: HashNode<K>;
}> = [];
const baseChildMap = new Map(
base.children?.map((child) => [child.key, child]),
);
const headChildMap = new Map(
head.children?.map((child) => [child.key, child]),
);
// Removed children (base에만 존재)
for (const [key, baseChild] of baseChildMap) {
if (!headChildMap.has(key)) {
const childPath = [...path, key];
changes.push({
type: "removed",
path: childPath,
key: key,
baseHash: baseChild.hash,
baseNodeType: baseChild.type,
});
}
}
// Added children (head에만 존재)
for (const [key, headChild] of headChildMap) {
if (!baseChildMap.has(key)) {
const childPath = [...path, key];
changes.push({
type: "added",
path: childPath,
key: key,
headHash: headChild.hash,
headNodeType: headChild.type,
});
}
}
// Modified pairs (공통 자식 중 hash가 다른 경우)
for (const [key, baseChild] of baseChildMap) {
const headChild = headChildMap.get(key);
if (headChild && baseChild.hash !== headChild.hash) {
modifiedPairs.push({ base: baseChild, head: headChild });
}
}
return { changes, modifiedPairs };
}