Skip to content

Commit b3befcb

Browse files
RobbyTiptonfscgoldenjoeeparkdavidkim7773khobread
committed
Improved robustness of react-router logic. Reactime can now reliably time travel through a react-router application even in situations where the history branches. This is achieved via the rebuildHistory method on the Routes class.
Co-authored-by: Chris LeBrett <[email protected]> Co-authored-by: Robby Tipton <[email protected]> Co-authored-by: Joseph Park <[email protected]> Co-authored-by: David Kim <[email protected]> Co-authored-by: Kevin HoEun Lee <[email protected]>
1 parent 7c66177 commit b3befcb

File tree

4 files changed

+46
-16
lines changed

4 files changed

+46
-16
lines changed

src/backend/linkFiber.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ function sendSnapshot(snap: Snapshot, mode: Mode): void {
9494
snap.tree = new Tree('root', 'root');
9595
}
9696
const payload = snap.tree.cleanTreeCopy();
97-
payload.url = routes.addRoute(window.location.href);
97+
payload.route = routes.addRoute(window.location.href);
9898
// if it's Recoil - run different actions
9999
if (isRecoil) {
100100
// getRecoilState()

src/backend/routes.ts

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,57 @@
1+
/* eslint-disable max-classes-per-file */
2+
3+
class Route {
4+
url: string;
5+
6+
id: number;
7+
8+
constructor(url: string, id: number) {
9+
this.url = url;
10+
this.id = id;
11+
}
12+
}
13+
114
class Routes {
2-
values: string[] = [];
15+
values: Route[] = [new Route(null, null)];
316

417
id = 0;
518

6-
current: number | null = null;
19+
current: number | null = 0;
720

8-
addRoute(url: string): string {
9-
if (this.values[this.values.length - 1] !== url) {
10-
if (this.values.includes(url)) {
11-
this.values.push((url += this.id++));
12-
} else {
13-
this.values.push(url);
21+
addRoute(url: string): Route {
22+
let route: Route = this.values[this.current];
23+
24+
if (this.values[this.current].url !== url) {
25+
if (this.current !== this.values.length - 1) {
26+
this.rebuildHistory(url);
1427
}
28+
29+
route = new Route(url, (this.id += 1));
30+
this.values.push(route);
31+
32+
this.current = this.values.length - 1;
33+
}
34+
35+
return route;
36+
}
37+
38+
rebuildHistory(url: string): void {
39+
window.history.replaceState('', '', this.values[this.current + 1].url);
40+
41+
for (let i = this.current + 2; i < this.values.length; i += 1) {
42+
window.history.pushState('', '', this.values[i].url);
1543
}
1644

17-
this.current = this.values.length - 1;
18-
return url;
45+
window.history.pushState('', '', url);
1946
}
2047

21-
navigate(url: string): boolean {
48+
navigate(route: Route): boolean {
2249
let targetIndex: number | null = null;
23-
for (let i = 0; i < this.values.length; i++) {
24-
if (this.values[i] === url) targetIndex = i;
50+
51+
for (let i = 0; i < this.values.length; i += 1) {
52+
if (this.values[i].url === route.url && this.values[i].id === route.id) {
53+
targetIndex = i;
54+
}
2555
}
2656

2757
const delta: number = targetIndex - this.current;

src/backend/timeJump.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export default (origin, mode) => {
8686
// * Setting mode disables setState from posting messages to window
8787
mode.jumping = true;
8888
if (firstCall) circularComponentTable.clear();
89-
const navigating: boolean = routes.navigate(target.url);
89+
const navigating: boolean = routes.navigate(target.route);
9090
if (navigating) {
9191
addEventListener('popstate', event => {
9292
jump(target);

src/backend/tree.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class Tree {
6161

6262
recoilDomNode: any;
6363

64-
url: string;
64+
route: {};
6565

6666
// Duplicate names: add a unique number ID
6767
// Create an object 'componentNames' to store each component name as a key and it's frequency of use as its value

0 commit comments

Comments
 (0)