1
+ /* eslint-disable indent */
2
+ /* eslint-disable brace-style */
3
+ /* eslint-disable comma-dangle */
1
4
/**
2
5
* This file contains core module functionality.
3
6
*
@@ -46,15 +49,13 @@ const componentActionsRecord = require('./masterState');
46
49
47
50
module . exports = ( snap , mode ) => {
48
51
let fiberRoot = null ;
49
- let astHooks ;
50
- let concurrent = false ; // flag to check if we are in concurrent mode
51
52
52
53
async function sendSnapshot ( ) {
53
54
// Don't send messages while jumping or while paused
54
55
if ( mode . jumping || mode . paused ) return ;
55
- // console.log('PAYLOAD: before cleaning', snap.tree);
56
+ console . log ( 'PAYLOAD: before cleaning' , snap . tree ) ;
56
57
const payload = snap . tree . cleanTreeCopy ( ) ; // snap.tree.getCopy();
57
- // console.log('PAYLOAD: after cleaning', payload);
58
+ console . log ( 'PAYLOAD: after cleaning' , payload ) ;
58
59
try {
59
60
await window . postMessage ( {
60
61
action : 'recordSnap' ,
@@ -68,14 +69,14 @@ module.exports = (snap, mode) => {
68
69
// Carlos: Injects instrumentation to update our state tree every time
69
70
// a hooks component changes state
70
71
function traverseHooks ( memoizedState ) {
71
- const hooksComponents = [ ] ;
72
+ const hooksStates = [ ] ;
72
73
while ( memoizedState && memoizedState . queue ) {
73
74
// Carlos: these two are legacy comments, we should look into them later
74
75
// prevents useEffect from crashing on load
75
76
// if (memoizedState.next.queue === null) { // prevents double pushing snapshot updates
76
77
if ( memoizedState . memoizedState ) {
77
78
console . log ( 'memoizedState in traverseHooks is:' , memoizedState ) ;
78
- hooksComponents . push ( {
79
+ hooksStates . push ( {
79
80
component : memoizedState . queue ,
80
81
state : memoizedState . memoizedState ,
81
82
} ) ;
@@ -84,14 +85,15 @@ module.exports = (snap, mode) => {
84
85
memoizedState = memoizedState . next !== memoizedState
85
86
? memoizedState . next : null ;
86
87
}
87
- return hooksComponents ;
88
+ return hooksStates ;
88
89
}
89
90
90
91
// Carlos: This runs after EVERY Fiber commit. It creates a new snapshot,
91
92
//
92
93
function createTree ( currentFiber , tree = new Tree ( 'root' ) ) {
93
94
// Base case: child or sibling pointed to null
94
- if ( ! currentFiber ) return tree ;
95
+ if ( ! currentFiber ) return null ;
96
+ if ( ! tree ) return tree ;
95
97
96
98
// These have the newest state. We update state and then
97
99
// called updateSnapshotTree()
@@ -102,46 +104,136 @@ module.exports = (snap, mode) => {
102
104
memoizedState,
103
105
elementType,
104
106
tag,
107
+ actualDuration,
108
+ actualStartTime,
109
+ selfBaseDuration,
110
+ treeBaseDuration,
105
111
} = currentFiber ;
106
112
107
- let index ;
108
- // Check if node is a stateful component
113
+ let newState = null ;
114
+ let componentData = { } ;
115
+ let componentFound = false ;
116
+
117
+ // Check if node is a stateful setState component
109
118
if ( stateNode && stateNode . state && ( tag === 0 || tag === 1 ) ) {
119
+ console . log ( 'in create tree if' )
120
+ console . log ( 'this is currentFiber from createTree' , currentFiber )
110
121
// Save component's state and setState() function to our record for future
111
122
// time-travel state changing. Add record index to snapshot so we can retrieve.
112
- index = componentActionsRecord . saveNew ( stateNode . state , stateNode ) ;
113
- tree . appendChild ( stateNode . state , elementType . name , index ) ; // Add component to tree
114
- } else {
115
- // grab stateless components here
123
+ componentData . index = componentActionsRecord . saveNew ( stateNode . state , stateNode ) ;
124
+ newState . state = stateNode . state ;
125
+ componentFound = true ;
116
126
}
117
127
118
- // Check if node is a hooks function
128
+ // Check if node is a hooks useState function
129
+ let hooksIndex ;
119
130
if ( memoizedState && ( tag === 0 || tag === 1 || tag === 10 ) ) {
131
+ console . log ( 'in create tree if' )
132
+ console . log ( 'this is currentFiber from createTree' , currentFiber )
120
133
if ( memoizedState . queue ) {
121
- const hooksComponents = traverseHooks ( memoizedState ) ;
122
- hooksComponents . forEach ( c => {
123
- if ( elementType . name ) {
124
- index = componentActionsRecord . saveNew ( c . state , c . component ) ;
125
- tree . appendChild ( c . state , elementType . name ? elementType . name : 'nameless' , index ) ;
134
+ // Hooks states are stored as a linked list using memoizedState.next,
135
+ // so we must traverse through the list and get the states.
136
+ // We then store them along with the corresponding memoizedState.queue,
137
+ // which includes the dispatch() function we use to change their state.
138
+ const hooksStates = traverseHooks ( memoizedState ) ;
139
+ hooksStates . forEach ( state => {
140
+ hooksIndex = componentActionsRecord . saveNew ( state . state , state . component ) ;
141
+ if ( newState && newState . hooksState ) {
142
+ newState . hooksState . push ( [ state . state , hooksIndex ] ) ;
143
+ } else if ( newState ) {
144
+ newState . hooksState = [ [ state . state , hooksIndex ] ] ;
145
+ } else {
146
+ newState = { hooksState : [ [ state . state , hooksIndex ] ] } ;
126
147
}
148
+ componentFound = true ;
127
149
} ) ;
128
150
}
151
+ } else {
152
+ console . log ( 'in create tree else' )
153
+ console . log ( 'this is currentFiber from createTree' , currentFiber )
154
+ console . log ( 'this is memoizedState from createTree' , memoizedState )
155
+ // grab stateless components here
156
+ if ( elementType ) {
157
+ if ( elementType . name ) {
158
+ tree . appendChild ( 'stateless' , elementType . name , index ) ;
159
+ } else {
160
+ tree . appendChild ( 'stateless' , elementType , index ) ;
161
+ }
162
+ }
163
+ }
164
+
165
+ // This grabs stateless components
166
+ if ( ! componentFound && ( tag === 0 || tag === 1 ) ) {
167
+ newState = 'stateless' ;
168
+ }
169
+
170
+ // Adds performance metrics to the component data
171
+ componentData = {
172
+ ...componentData ,
173
+ actualDuration,
174
+ actualStartTime,
175
+ selfBaseDuration,
176
+ treeBaseDuration,
177
+ } ;
178
+
179
+ if ( componentFound ) {
180
+ tree . addChild ( newState , elementType . name ? elementType . name : elementType , componentData ) ;
181
+ } else if ( newState === 'stateless' ) {
182
+ tree . addChild ( newState , elementType . name ? elementType . name : elementType , componentData ) ;
129
183
}
130
184
131
- // Recurse on siblings
132
- createTree ( sibling , tree ) ;
133
185
// Recurse on children
134
- if ( tree . children . length > 0 ) {
135
- createTree ( child , tree . children [ 0 ] ) ;
136
- } else {
137
- createTree ( child , tree ) ;
186
+ if ( child ) {
187
+ // If this node had state we appended to the children array,
188
+ // so attach children to the newly appended child.
189
+ // Otherwise, attach children to this same node.
190
+ if ( tree . children . length > 0 ) {
191
+ createTree ( child , tree . children [ tree . children . length - 1 ] ) ;
192
+ } else {
193
+ createTree ( child , tree ) ;
194
+ }
138
195
}
196
+ // Recurse on siblings
197
+ if ( sibling ) createTree ( sibling , tree ) ;
139
198
140
199
return tree ;
141
200
}
142
201
202
+
203
+ // function createUnfilteredTree(curFiber, parentNode) {
204
+ // // on call from updateSnapShot, no parentNode provided, so create a root node
205
+ // if(! parentNode) parentNode = new Tree('root');
206
+
207
+ // // Base case: parentNode's child or sibling pointed to null
208
+ // if (!curFiber) return parentNode;
209
+
210
+ // let newChildNode = null;
211
+
212
+ // // If stateful, add to parentNode's children array, then inject new setState into fiber node
213
+ // if (curFiber.stateNode && curFiber.stateNode.state) {
214
+ // newChildNode = parentNode.appendChild(curFiber.stateNode);
215
+ // // changeSetState(curFiber.stateNode);
216
+ // newChildNode.isStateful = true;
217
+ // }
218
+ // else {
219
+
220
+ // }
221
+
222
+ // // Recurse to sibling; siblings that have state should be added to our parentNode
223
+ // createTree(curFiber.sibling, parentNode);
224
+
225
+ // // Recurse to child; If this fiber was stateful, then we added a newChildNode here, and we want
226
+ // // to attach further children to that. If this fiber wasn't stateful, we want to attach any
227
+ // // children to our existing parentNode.
228
+ // createTree(curFiber.child, newChildNode || parentNode);
229
+
230
+ // return parentNode;
231
+ // }
232
+
233
+
143
234
// ! BUG: skips 1st hook click
144
235
function updateSnapShotTree ( ) {
236
+ < << << << HEAD
145
237
/* let current;
146
238
// If concurrent mode, grab current.child
147
239
if (concurrent) {
@@ -165,27 +257,23 @@ module.exports = (snap, mode) => {
165
257
// Point fiberRoot to FiberRootNode
166
258
if ( container . _internalRoot ) {
167
259
fiberRoot = container . _internalRoot ;
168
- concurrent = true ;
169
260
} else {
170
261
const {
171
262
_reactRootContainer : { _internalRoot } ,
172
263
_reactRootContainer,
173
264
} = container ;
174
265
// Only assign internal root if it actually exists
175
266
fiberRoot = _internalRoot || _reactRootContainer ;
176
- // console.log('_reactRootContainer is:', _reactRootContainer);
177
- // console.log('linkFiber.js, fiberRoot:', fiberRoot);
178
267
}
179
268
const devTools = window . __REACT_DEVTOOLS_GLOBAL_HOOK__ ;
269
+ console . log ( 'this is devTools' , devTools )
180
270
const reactInstance = devTools ? devTools . renderers . get ( 1 ) : null ;
181
- const overrideHookState = reactInstance ? reactInstance . overrideHookState : null ;
182
- console . log ( 'DEVTOOLS:' , devTools ) ;
183
- console . log ( 'roots:' , reactInstance . getCurrentFiber ( ) )
184
271
185
272
if ( reactInstance && reactInstance . version ) {
186
273
devTools . onCommitFiberRoot = ( function ( original ) {
187
274
return function ( ...args ) {
188
275
fiberRoot = args [ 1 ] ;
276
+ console . log ( 'this is fiberRoot' , fiberRoot )
189
277
updateSnapShotTree ( ) ;
190
278
sendSnapshot ( ) ;
191
279
return original ( ...args ) ;
@@ -202,3 +290,82 @@ module.exports = (snap, mode) => {
202
290
} ) ;
203
291
} ;
204
292
} ;
293
+
294
+
295
+
296
+
297
+ // function createUnfilteredTree(currentFiber, tree = new Tree('root')) {
298
+ // // Base case: child or sibling pointed to null
299
+ // if (!currentFiber) return tree;
300
+
301
+ // const { sibling, stateNode, child, memoizedState, elementType,
302
+ // tag, actualDuration, actualStartTime, selfBaseDuration, treeBaseDuration,
303
+ // } = currentFiber;
304
+
305
+ // const extraProps = {
306
+ // tag, actualDuration, actualStartTime, selfBaseDuration, treeBaseDuration,
307
+ // };
308
+
309
+ // let nextTree = tree;
310
+ // let nextTreeUnfiltered = unfilteredTreeNode = new UnfilteredTreeNode('root');
311
+
312
+ // // Check if stateful component
313
+ // if (stateNode && stateNode.state) {
314
+ // nextTree = tree.appendChild(stateNode); // Add component to tree
315
+ // changeSetState(stateNode); // Change setState functionality
316
+ // }
317
+ // nextTreeUnfiltered = unfilteredTreeNode.appendChild(stateNode);
318
+
319
+ // // TODO: handle Hooks cases...
320
+
321
+ // // Recurse on siblings
322
+ // createTree(sibling, tree);
323
+ // // Recurse on children
324
+ // createTree(child, nextTree);
325
+
326
+ // return tree;
327
+ // }
328
+
329
+
330
+
331
+ // Check if the component uses hooks
332
+ // if (memoizedState && Object.hasOwnProperty.call(memoizedState, 'baseState')) {
333
+ // // 'catch-all' for suspense elements (experimental)
334
+ // if (typeof elementType.$$typeof === 'symbol') return;
335
+ // // Traverse through the currentFiber and extract the getters/setters
336
+ // astHooks = astParser(elementType);
337
+ // saveState(astHooks);
338
+ // // Create a traversed property and assign to the evaluated result of
339
+ // // invoking traverseHooks with memoizedState
340
+ // memoizedState.traversed = traverseHooks(memoizedState);
341
+ // nextTree = tree.appendChild(memoizedState);
342
+ // }
343
+
344
+
345
+
346
+
347
+
348
+
349
+
350
+
351
+ // function createTree(currentFiber, tree = new Tree('root')) {
352
+ // // Base case: child or sibling pointed to null
353
+ // if (!currentFiber) return tree;
354
+
355
+ // const { sibling, stateNode, child, memoizedState, elementType } = currentFiber;
356
+
357
+ // let nextTree = tree;
358
+
359
+ // // Check if stateful component
360
+ // if (stateNode && stateNode.state) {
361
+ // nextTree = tree.appendChild(stateNode); // Add component to tree
362
+ // changeSetState(stateNode); // Change setState functionality
363
+ // }
364
+
365
+ // // Recurse on siblings
366
+ // createTree(sibling, tree);
367
+ // // Recurse on children
368
+ // createTree(child, nextTree);
369
+
370
+ // return tree;
371
+ // }
0 commit comments