1- let timeTravelTracker = [ ] ;
2- let timeTravelTrackerIndex = null ;
1+ class DoublyLinkedListNode {
2+ constructor ( value , next = null , prev = null ) {
3+ this . value = value ;
4+ this . next = next ;
5+ this . prev = prev ;
6+ }
7+ }
8+
9+ class DoublyLinkedList {
10+ constructor ( ) {
11+ this . head = null ;
12+ this . tail = null ;
13+ this . current = null ;
14+ }
15+
16+ append ( fiberNode ) {
17+ const newDLLNode = new DoublyLinkedListNode ( fiberNode ) ;
18+
19+ if ( ! this . head ) {
20+ this . head = newDLLNode ;
21+ this . tail = newDLLNode ;
22+ this . current = newDLLNode ;
23+ } else {
24+ this . tail . next = newDLLNode ;
25+ newDLLNode . prev = this . tail ;
26+ this . tail = newDLLNode ;
27+ }
28+
29+ return this ;
30+ }
31+ }
32+
33+
334const funcStorage = { } ;
4- let root ;
35+ let root = null ;
36+ const timeTravelLList = new DoublyLinkedList ( ) ;
537
638function timeTravel ( direction ) {
7- if ( timeTravelTrackerIndex === null ) {
8- // First time we call this function. We need to remove the PLACEMENT entry
9- // from position [0]. This is originated from the initial mount of the App.
10- timeTravelTracker = timeTravelTracker . slice ( 1 ) ;
11- timeTravelTrackerIndex = timeTravelTracker . length - 1 ;
12- root = getRootContainerInstance ( timeTravelTracker [ 0 ] . effect ) ;
39+ if ( ! root ) {
40+ root = getRootContainerInstance ( timeTravelLList . current . value . effect ) ;
41+ timeTravelLList . current = timeTravelLList . tail ;
1342 }
1443
1544 const diff = direction === 'forward' ? 1 : - 1 ;
1645
17- if ( ( diff === 1 && timeTravelTrackerIndex === timeTravelTracker . length - 1 )
18- || ( diff === - 1 && timeTravelTrackerIndex === 0 ) ) {
46+ if ( ( diff === 1 && timeTravelLList . current . next === null )
47+ || ( diff === - 1 && timeTravelLList . current . prev === null ) ) {
1948 return ;
2049 }
2150
22- if ( diff === 1 && timeTravelTrackerIndex !== 0 ) timeTravelTrackerIndex += 1 ;
51+ if ( diff === 1 && timeTravelLList . current !== timeTravelLList . tail ) {
52+ timeTravelLList . current = timeTravelLList . current . next ;
53+ }
54+
55+ const {
56+ commitDeletion,
57+ commitPlacement,
58+ commitWork,
59+ prepareUpdate,
60+ } = funcStorage ;
2361
2462 while ( true ) {
25- const {
26- commitDeletion,
27- commitPlacement,
28- commitWork,
29- prepareUpdate,
30- } = funcStorage ;
31- console . log ( 'doing work for ' , timeTravelTrackerIndex ) ;
32- const { primaryEffectTag, effect } = timeTravelTracker [ timeTravelTrackerIndex ] ;
63+ // console.log('doing work for ', timeTravelTrackerIndex);
64+ const { primaryEffectTag, effect } = timeTravelLList . current . value ;
3365
3466 switch ( primaryEffectTag ) {
3567 case 'UPDATE' : {
36- const { current } = timeTravelTracker [ timeTravelTrackerIndex ] ;
68+ const { current } = timeTravelLList . current . value ;
3769
3870 // if we are moving forwards, we need to commitWork() the same
3971 // way the function was originally called.
4072 if ( diff === 1 ) {
41- commitWork ( current , effect ) ;
73+ commitWork ( _ . cloneDeep ( current ) , _ . cloneDeep ( effect ) ) ;
4274 break ;
4375 }
4476
@@ -60,24 +92,23 @@ function timeTravel(direction) {
6092
6193 const currentCopy = _ . cloneDeep ( current ) ;
6294 currentCopy . updateQueue = payload ;
63- commitWork ( effect , currentCopy ) ;
95+ commitWork ( _ . cloneDeep ( effect ) , currentCopy ) ;
6496 break ;
6597 }
6698
67- commitWork ( effect , current ) ;
99+ commitWork ( _ . cloneDeep ( effect ) , _ . cloneDeep ( current ) ) ;
68100 break ;
69101 }
70102 case 'PLACEMENT' : {
71103 if ( diff === 1 ) {
72- commitPlacement ( effect ) ;
104+ commitPlacement ( _ . cloneDeep ( effect ) ) ;
73105 } else {
74106 // commitDeletion() will call unmountHostComponents(), which recursively
75107 // deletes all host nodes from the parent. This means that
76108 // effect.return = null. BUT we need that reference for later calls
77109 // on commitPlacement() on this same node. This is why we need to clone
78110 // the effect fiberNode and call commitDeletion() on that instead.
79111 const effectCopy = _ . cloneDeep ( effect ) ;
80- console . log ( effectCopy ) ;
81112 commitDeletion ( effectCopy ) ;
82113 }
83114 break ;
@@ -88,7 +119,7 @@ function timeTravel(direction) {
88119 const effectCopy = _ . cloneDeep ( effect ) ;
89120 commitDeletion ( effectCopy ) ;
90121 } else {
91- commitPlacement ( effect ) ;
122+ commitPlacement ( _ . cloneDeep ( effect ) ) ;
92123 }
93124 break ;
94125 }
@@ -97,15 +128,17 @@ function timeTravel(direction) {
97128 }
98129
99130 // break points for the while loop
100- if ( timeTravelTrackerIndex + diff === timeTravelTracker . length
101- || ( diff === - 1 && timeTravelTrackerIndex === 0 )
102- || ( diff === 1 && timeTravelTracker [ timeTravelTrackerIndex ] . actionDispatched ) ) {
131+ if ( ( diff === - 1 && timeTravelLList . current . prev === null )
132+ || ( diff === 1 && timeTravelLList . current . next === null )
133+ || ( diff === 1 && timeTravelLList . current . value . actionDispatched ) ) {
103134 return ;
104135 }
105136
106- timeTravelTrackerIndex += diff ;
137+ timeTravelLList . current = diff === 1
138+ ? timeTravelLList . current . next
139+ : timeTravelLList . current . prev ;
107140
108- if ( diff === - 1 && timeTravelTracker [ timeTravelTrackerIndex ] . actionDispatched ) {
141+ if ( diff === - 1 && timeTravelLList . current . value . actionDispatched ) {
109142 return ;
110143 }
111144 }
0 commit comments