Skip to content

Commit 8738fc8

Browse files
committed
merged changes into local master
2 parents 6685ef2 + 69d0d8f commit 8738fc8

19 files changed

+1052
-532
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ src/extension/build.crx
1010
src/extension/build.pem
1111
bower_components
1212
sandboxes/manual-tests/NextJS/.next
13+
.vscode

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"eslint.enable": true
3+
}

dev-reactime/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import 'regenerator-runtime/runtime';
77
import { exist } from 'acorn-jsx/xhtml';
88

99
// * State snapshot object initialized here
10-
const snapShot = { tree: null };
10+
const snapShot = {
11+
tree: null,
12+
unfilteredTree: null
13+
};
1114

1215

1316
const mode = {

dev-reactime/linkFiber.js

Lines changed: 199 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/* eslint-disable indent */
2+
/* eslint-disable brace-style */
3+
/* eslint-disable comma-dangle */
14
/**
25
* This file contains core module functionality.
36
*
@@ -46,15 +49,13 @@ const componentActionsRecord = require('./masterState');
4649

4750
module.exports = (snap, mode) => {
4851
let fiberRoot = null;
49-
let astHooks;
50-
let concurrent = false; // flag to check if we are in concurrent mode
5152

5253
async function sendSnapshot() {
5354
// Don't send messages while jumping or while paused
5455
if (mode.jumping || mode.paused) return;
55-
// console.log('PAYLOAD: before cleaning', snap.tree);
56+
console.log('PAYLOAD: before cleaning', snap.tree);
5657
const payload = snap.tree.cleanTreeCopy();// snap.tree.getCopy();
57-
// console.log('PAYLOAD: after cleaning', payload);
58+
console.log('PAYLOAD: after cleaning', payload);
5859
try {
5960
await window.postMessage({
6061
action: 'recordSnap',
@@ -68,14 +69,14 @@ module.exports = (snap, mode) => {
6869
// Carlos: Injects instrumentation to update our state tree every time
6970
// a hooks component changes state
7071
function traverseHooks(memoizedState) {
71-
const hooksComponents = [];
72+
const hooksStates = [];
7273
while (memoizedState && memoizedState.queue) {
7374
// Carlos: these two are legacy comments, we should look into them later
7475
// prevents useEffect from crashing on load
7576
// if (memoizedState.next.queue === null) { // prevents double pushing snapshot updates
7677
if (memoizedState.memoizedState) {
7778
console.log('memoizedState in traverseHooks is:', memoizedState);
78-
hooksComponents.push({
79+
hooksStates.push({
7980
component: memoizedState.queue,
8081
state: memoizedState.memoizedState,
8182
});
@@ -84,14 +85,15 @@ module.exports = (snap, mode) => {
8485
memoizedState = memoizedState.next !== memoizedState
8586
? memoizedState.next : null;
8687
}
87-
return hooksComponents;
88+
return hooksStates;
8889
}
8990

9091
// Carlos: This runs after EVERY Fiber commit. It creates a new snapshot,
9192
//
9293
function createTree(currentFiber, tree = new Tree('root')) {
9394
// Base case: child or sibling pointed to null
94-
if (!currentFiber) return tree;
95+
if (!currentFiber) return null;
96+
if (!tree) return tree;
9597

9698
// These have the newest state. We update state and then
9799
// called updateSnapshotTree()
@@ -102,46 +104,136 @@ module.exports = (snap, mode) => {
102104
memoizedState,
103105
elementType,
104106
tag,
107+
actualDuration,
108+
actualStartTime,
109+
selfBaseDuration,
110+
treeBaseDuration,
105111
} = currentFiber;
106112

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
109118
if (stateNode && stateNode.state && (tag === 0 || tag === 1)) {
119+
console.log('in create tree if')
120+
console.log('this is currentFiber from createTree', currentFiber)
110121
// Save component's state and setState() function to our record for future
111122
// 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;
116126
}
117127

118-
// Check if node is a hooks function
128+
// Check if node is a hooks useState function
129+
let hooksIndex;
119130
if (memoizedState && (tag === 0 || tag === 1 || tag === 10)) {
131+
console.log('in create tree if')
132+
console.log('this is currentFiber from createTree', currentFiber)
120133
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]] };
126147
}
148+
componentFound = true;
127149
});
128150
}
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);
129183
}
130184

131-
// Recurse on siblings
132-
createTree(sibling, tree);
133185
// 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+
}
138195
}
196+
// Recurse on siblings
197+
if (sibling) createTree(sibling, tree);
139198

140199
return tree;
141200
}
142201

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+
143234
// ! BUG: skips 1st hook click
144235
function updateSnapShotTree() {
236+
<<<<<<< HEAD
145237
/* let current;
146238
// If concurrent mode, grab current.child
147239
if (concurrent) {
@@ -165,27 +257,23 @@ module.exports = (snap, mode) => {
165257
// Point fiberRoot to FiberRootNode
166258
if (container._internalRoot) {
167259
fiberRoot = container._internalRoot;
168-
concurrent = true;
169260
} else {
170261
const {
171262
_reactRootContainer: { _internalRoot },
172263
_reactRootContainer,
173264
} = container;
174265
// Only assign internal root if it actually exists
175266
fiberRoot = _internalRoot || _reactRootContainer;
176-
// console.log('_reactRootContainer is:', _reactRootContainer);
177-
// console.log('linkFiber.js, fiberRoot:', fiberRoot);
178267
}
179268
const devTools = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
269+
console.log('this is devTools', devTools)
180270
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())
184271

185272
if (reactInstance && reactInstance.version) {
186273
devTools.onCommitFiberRoot = (function (original) {
187274
return function (...args) {
188275
fiberRoot = args[1];
276+
console.log('this is fiberRoot', fiberRoot)
189277
updateSnapShotTree();
190278
sendSnapshot();
191279
return original(...args);
@@ -202,3 +290,82 @@ module.exports = (snap, mode) => {
202290
});
203291
};
204292
};
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+
// }

dev-reactime/reactWorkTags.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// eslint-disable-next-line import/prefer-default-export
2+
export const reactWorkTags = [
3+
{ 0: 'FunctionComponent' },
4+
{ 1: 'ClassComponent' },
5+
{ 2: 'IndeterminateComponent' },
6+
{ 3: 'HostRoot' }, // Root of a host tree. Could be nested inside another node.
7+
{ 4: 'HostPortal' }, // A subtree. Could be an entry point to a different renderer.
8+
{ 5: 'HostComponent' },
9+
{ 6: 'HostText' },
10+
];

0 commit comments

Comments
 (0)