Skip to content

Commit 7121a48

Browse files
Move root filtering to client adapter
1 parent 7fd5489 commit 7121a48

File tree

13 files changed

+217
-130
lines changed

13 files changed

+217
-130
lines changed

src/adapter/debug.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ describe("debug", () => {
1212
0,
1313
MsgTypes.ADD_ROOT,
1414
root,
15+
root,
1516
]);
1617
});
1718

@@ -24,6 +25,7 @@ describe("debug", () => {
2425
...toStringTable("div"),
2526
MsgTypes.ADD_ROOT,
2627
root,
28+
root,
2729
MsgTypes.ADD_VNODE,
2830
2,
2931
DevNodeType.Element,
@@ -45,6 +47,7 @@ describe("debug", () => {
4547
0,
4648
MsgTypes.ADD_ROOT,
4749
root,
50+
root,
4851
MsgTypes.UPDATE_VNODE_TIMINGS,
4952
2,
5053
12,
@@ -61,6 +64,7 @@ describe("debug", () => {
6164
2,
6265
MsgTypes.ADD_ROOT,
6366
root,
67+
root,
6468
]);
6569
});
6670

@@ -77,6 +81,7 @@ describe("debug", () => {
7781
3,
7882
MsgTypes.ADD_ROOT,
7983
root,
84+
root,
8085
]);
8186
});
8287

@@ -89,6 +94,7 @@ describe("debug", () => {
8994
0,
9095
MsgTypes.ADD_ROOT,
9196
root,
97+
root,
9298
MsgTypes.REORDER_CHILDREN,
9399
2,
94100
3,

src/adapter/debug.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ import { renderReasonToStr } from "./shared/renderReasons";
55

66
export interface ParsedMsg {
77
rootId: number;
8+
mappedRootId: number;
89
mounts: Array<{ id: ID; key: string; name: string; parentId: ID }>;
910
unmounts: ID[];
1011
reorders: Array<{ id: ID; children: ID[] }>;
1112
timings: Array<{ id: ID; duration: number }>;
1213
}
1314

1415
export function parseCommitMessage(data: number[]): ParsedMsg {
15-
const rootId = data[0] || -1;
16+
let rootId = data[0] || -1;
17+
let mappedRootId = rootId;
1618

1719
// String table
1820
let i = 1;
@@ -57,11 +59,17 @@ export function parseCommitMessage(data: number[]): ParsedMsg {
5759
i += 3 + data[i + 2];
5860
break;
5961
}
62+
case MsgTypes.ADD_ROOT:
63+
rootId = data[i + 1];
64+
mappedRootId = data[i + 2];
65+
i += 2;
66+
break;
6067
}
6168
}
6269

6370
return {
6471
rootId,
72+
mappedRootId,
6573
mounts,
6674
unmounts,
6775
timings,
@@ -71,7 +79,7 @@ export function parseCommitMessage(data: number[]): ParsedMsg {
7179

7280
export function formatForTest(msg: ParsedMsg) {
7381
const out = [];
74-
out.push("rootId: " + msg.rootId);
82+
out.push(`rootId: ${msg.rootId} => ${msg.mappedRootId}`);
7583
msg.mounts.forEach(m => {
7684
const key = m.key ? "#" + m.key : "";
7785
out.push(`Add ${m.id} <${m.name}${key}> to parent ${m.parentId}`);
@@ -119,7 +127,7 @@ export function fromSnapshot(events: string[]): number[] {
119127
if (/^rootId:/.test(events[0])) {
120128
const id = +events[0].slice(events[0].indexOf(":") + 1);
121129
out.push(id);
122-
operations.push(MsgTypes.ADD_ROOT, id);
130+
operations.push(MsgTypes.ADD_ROOT, id, id);
123131
} else {
124132
throw new Error("rootId must be first event");
125133
}
@@ -300,8 +308,14 @@ export function printCommit(data: number[]) {
300308
}
301309
case MsgTypes.ADD_ROOT: {
302310
const id = data[i + 1];
303-
console.log(`Add Root: %c${id}`, "color: yellow");
304-
i++;
311+
const mapped = data[i + 2];
312+
console.log(
313+
`Add Root: %c${id}%c => %c${mapped}`,
314+
"color: yellow",
315+
"color: inherit",
316+
"color: yellow",
317+
);
318+
i += 2;
305319
break;
306320
}
307321
case MsgTypes.HOC_NODES: {

src/adapter/protocol/events.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe("applyEvent", () => {
99
const store = createStore();
1010
const data = fromSnapshot(["rootId: 1"]);
1111
applyEvent(store, "operation_v2", data);
12-
expect(store.roots.$.length).to.equal(1);
12+
expect(store.roots.$.size).to.equal(1);
1313
});
1414

1515
it("should update roots correctly", () => {
@@ -20,7 +20,7 @@ describe("applyEvent", () => {
2020
"Add 2 <div> to parent 1",
2121
]);
2222
applyEvent(store, "operation_v2", data);
23-
expect(store.roots.$.length).to.equal(1);
23+
expect(store.roots.$.size).to.equal(1);
2424
});
2525

2626
it("should mount nodes", () => {

src/adapter/protocol/events.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,14 @@ export function flush(commit: Commit) {
107107
* We currently expect all operations to be in order.
108108
*/
109109
export function applyOperationsV2(store: Store, data: number[]) {
110-
const { rootId: commitRootId, roots, tree, reasons, stats } = ops2Tree(
110+
const { rootId, roots, tree, reasons, stats, rendered } = ops2Tree(
111111
store.nodes.$,
112112
store.roots.$,
113113
data,
114114
);
115115

116+
const mappedRootId = roots.has(rootId) ? roots.get(rootId)! : rootId;
117+
116118
// Update store data
117119
store.roots.$ = roots;
118120
store.nodes.$ = tree;
@@ -127,9 +129,14 @@ export function applyOperationsV2(store: Store, data: number[]) {
127129
// If we are profiling, we'll make a frozen copy of the mutable
128130
// elements tree because the profiler can step through time
129131
if (store.profiler.isRecording.$) {
130-
recordProfilerCommit(store.nodes.$, store.profiler, commitRootId);
132+
recordProfilerCommit(
133+
store.nodes.$,
134+
store.profiler,
135+
mappedRootId,
136+
rendered[0],
137+
);
131138
store.profiler.renderReasons.update(m => {
132-
m.set(commitRootId, reasons);
139+
m.set(mappedRootId, reasons);
133140
});
134141
}
135142

src/adapter/protocol/legacy/operationsV1.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ export function applyOperationsV1(store: Store, data: number[]) {
1515
switch (data[i]) {
1616
case MsgTypes.ADD_ROOT: {
1717
const id = data[i + 1];
18-
store.roots.$.push(id);
19-
i += 1;
18+
store.roots.$.set(id, id);
19+
i += 2;
2020
break;
2121
}
2222
case MsgTypes.ADD_VNODE: {

src/adapter/protocol/operations.test.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,19 @@ describe("ops2Tree", () => {
99
Fragment ***
1010
`;
1111

12-
const res = ops2Tree(state.idMap, [], []);
12+
const res = ops2Tree(state.idMap, new Map(), []);
1313
expect(res.tree).not.to.equal(state.idMap);
1414
expect(res.tree.size).to.equal(state.idMap.size);
1515
});
1616

1717
describe("ADD_ROOT", () => {
1818
it("should add new roots", () => {
1919
const ops = fromSnapshot(["rootId: 1"]);
20-
expect(ops2Tree(new Map(), [], ops)).to.deep.equal({
20+
expect(ops2Tree(new Map(), new Map(), ops)).to.deep.equal({
2121
rootId: 1,
22-
roots: [1],
22+
roots: new Map([[1, 1]]),
2323
removals: [],
24+
rendered: [],
2425
tree: new Map(),
2526
reasons: new Map(),
2627
stats: null,
@@ -32,7 +33,7 @@ describe("ops2Tree", () => {
3233
it("should add a vnode", () => {
3334
const ops = fromSnapshot(["rootId: 1", "Add 1 <Fragment> to parent -1"]);
3435
expect(
35-
Array.from(ops2Tree(new Map(), [], ops).tree.values()),
36+
Array.from(ops2Tree(new Map(), new Map(), ops).tree.values()),
3637
).to.deep.equal([
3738
{
3839
children: [],
@@ -56,7 +57,7 @@ describe("ops2Tree", () => {
5657
"Add 2 <span> to parent 1",
5758
]);
5859

59-
const { tree } = ops2Tree(new Map(), [], ops);
60+
const { tree } = ops2Tree(new Map(), new Map(), ops);
6061
expect(Array.from(tree.values())).to.deep.equal([
6162
{
6263
children: [2],
@@ -93,7 +94,7 @@ describe("ops2Tree", () => {
9394
`;
9495

9596
const ops = fromSnapshot(["rootId: 1", "Update timings 1 time 20:40"]);
96-
const next = ops2Tree(state.idMap, [], ops).tree.get(1)!;
97+
const next = ops2Tree(state.idMap, new Map(), ops).tree.get(1)!;
9798

9899
expect(next.startTime).to.equal(20);
99100
expect(next.endTime).to.equal(40);
@@ -120,7 +121,7 @@ describe("ops2Tree", () => {
120121
"Remove 4",
121122
]);
122123

123-
const next = ops2Tree(state.idMap, [], ops).tree;
124+
const next = ops2Tree(state.idMap, new Map(), ops).tree;
124125
const root = next.get(1)!;
125126
const span = next.get(2)!;
126127

@@ -142,7 +143,7 @@ describe("ops2Tree", () => {
142143
"Remove 4",
143144
]);
144145

145-
const next = ops2Tree(state.idMap, [], ops);
146+
const next = ops2Tree(state.idMap, new Map(), ops);
146147
expect(next.removals).to.deep.equal([3, 4]);
147148
});
148149

@@ -158,7 +159,7 @@ describe("ops2Tree", () => {
158159
"Remove 2",
159160
]);
160161

161-
const next = ops2Tree(state.idMap, [], ops);
162+
const next = ops2Tree(state.idMap, new Map(), ops);
162163
expect(Array.from(next.tree.keys())).to.deep.equal([1, 4]);
163164
});
164165
});
@@ -178,7 +179,7 @@ describe("ops2Tree", () => {
178179
"Reorder 1 [3,2]",
179180
]);
180181

181-
const next = ops2Tree(state.idMap, [], ops).tree;
182+
const next = ops2Tree(state.idMap, new Map(), ops).tree;
182183
expect(next.get(1)!.children).to.deep.equal([3, 2]);
183184
});
184185

@@ -192,8 +193,10 @@ describe("ops2Tree", () => {
192193
"Update timings 1 time 20:40",
193194
]);
194195

195-
expect(() => ops2Tree(new Map(), [], ops)).to.not.throw();
196-
expect(ops2Tree(new Map(), [], ops).tree.get(1)!.startTime).to.equal(20);
196+
expect(() => ops2Tree(new Map(), new Map(), ops)).to.not.throw();
197+
expect(
198+
ops2Tree(new Map(), new Map(), ops).tree.get(1)!.startTime,
199+
).to.equal(20);
197200
});
198201
});
199202
});

src/adapter/protocol/operations.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,35 @@ import { ParsedStats, parseStats } from "../shared/stats";
1212
*
1313
* We currently expect all operations to be in order.
1414
*/
15-
export function ops2Tree(oldTree: Tree, existingRoots: ID[], ops: number[]) {
15+
export function ops2Tree(
16+
oldTree: Tree,
17+
existingRoots: Map<ID, ID>,
18+
ops: number[],
19+
) {
1620
const pending: Tree = new Map(oldTree);
1721
const rootId = ops[0];
18-
const roots: ID[] = [...existingRoots];
22+
const roots = new Map(existingRoots);
23+
const mappedRoots = new Map(
24+
Array.from(roots.entries()).map(([key, value]) => [value, key]),
25+
);
1926
const removals: ID[] = [];
2027
const reasons: RenderReasonMap = new Map();
2128
let stats: ParsedStats | null = null;
29+
const rendered: ID[] = [];
2230

2331
let i = ops[1] + 1;
2432
const strings = parseTable(ops.slice(1, i + 1));
2533

2634
for (i += 1; i < ops.length; i++) {
2735
switch (ops[i]) {
28-
case MsgTypes.ADD_ROOT:
29-
roots.push(ops[i + 1]);
30-
i += 1;
36+
case MsgTypes.ADD_ROOT: {
37+
const rootId = ops[i + 1];
38+
const mappedRootId = ops[i + 2];
39+
roots.set(rootId, mappedRootId);
40+
mappedRoots.set(mappedRootId, rootId);
41+
i += 2;
3142
break;
43+
}
3244
case MsgTypes.ADD_VNODE: {
3345
const id = ops[i + 1];
3446
const parentId = ops[i + 3];
@@ -39,6 +51,8 @@ export function ops2Tree(oldTree: Tree, existingRoots: ID[], ops: number[]) {
3951
clone.children.push(id);
4052
}
4153

54+
rendered.push(id);
55+
4256
pending.set(id, {
4357
children: [],
4458
depth: parent ? parent.depth + 1 : 0,
@@ -61,6 +75,8 @@ export function ops2Tree(oldTree: Tree, existingRoots: ID[], ops: number[]) {
6175
x.startTime = ops[i + 2] / 1000;
6276
x.endTime = ops[i + 3] / 1000;
6377

78+
rendered.push(id);
79+
6480
i += 3;
6581
break;
6682
}
@@ -85,9 +101,9 @@ export function ops2Tree(oldTree: Tree, existingRoots: ID[], ops: number[]) {
85101
}
86102

87103
// Check if node was a root
88-
const rootIdx = roots.indexOf(node.id);
89-
if (rootIdx > -1) {
90-
roots.splice(rootIdx, 1);
104+
const mappedId = mappedRoots.get(node.id);
105+
if (mappedId !== undefined) {
106+
roots.delete(mappedId);
91107
}
92108

93109
// Delete children recursively
@@ -159,5 +175,5 @@ export function ops2Tree(oldTree: Tree, existingRoots: ID[], ops: number[]) {
159175
}
160176
}
161177

162-
return { rootId, roots, tree: pending, removals, reasons, stats };
178+
return { rootId, roots, tree: pending, removals, reasons, stats, rendered };
163179
}

0 commit comments

Comments
 (0)