Skip to content

Commit 0842afd

Browse files
committed
pull carlos
2 parents 0581708 + 8e77467 commit 0842afd

File tree

20 files changed

+424
-214
lines changed

20 files changed

+424
-214
lines changed

dev-reactime/astParser.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ const JSXParser = acorn.Parser.extend(jsx());
88
// Helper function to grab the getters/setters from `elementType`
99
module.exports = elementType => {
1010
// Initialize empty object to store the setters and getter
11+
console.log('entered ast parser');
12+
//console.log('elementType: ', elementType);
1113
let ast = JSXParser.parse(elementType);
14+
//console.log('ast:', ast);
1215
const hookState = {};
1316

1417
while (Object.hasOwnProperty.call(ast, 'body')) {

dev-reactime/index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,34 @@
44
*/
55
import 'core-js';
66
import 'regenerator-runtime/runtime';
7+
import { exist } from 'acorn-jsx/xhtml';
78

89
// * State snapshot object initialized here
910
const snapShot = {
1011
tree: null,
1112
unfilteredTree: null
1213
};
1314

15+
1416
const mode = {
1517
jumping: false,
1618
paused: false,
1719
locked: false,
1820
};
1921

2022
const linkFiber = require('./linkFiber')(snapShot, mode);
23+
console.log('import timeJump in index.js:', JSON.parse(JSON.stringify(snapShot)));
2124
const timeJump = require('./timeJump')(snapShot, mode);
2225

26+
2327
function getRouteURL(node) {
2428
if (node.name === 'Router') {
2529
return node.state.location.pathname;
2630
}
2731
if (node.children && node.children.length >= 1) {
2832
const tempNode = node.children;
2933
for (let index = 0; index < tempNode.length; index += 1) {
30-
return getRouteURL(tempNode[index]);
34+
return getRouteURL(tempNode[index]); // Carlos: ???
3135
}
3236
}
3337
}
@@ -36,9 +40,12 @@ function getRouteURL(node) {
3640
window.addEventListener('message', ({ data: { action, payload } }) => {
3741
switch (action) {
3842
case 'jumpToSnap':
43+
console.log('payload in jumpToSnap', payload);
3944
timeJump(payload); // * This sets state with given payload
4045
// Get the pathname from payload and add new entry to browser history
4146
// MORE: https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
47+
48+
// try to modify workInProgress tree from here
4249
window.history.pushState('', '', getRouteURL(payload));
4350
break;
4451
case 'setLock':
@@ -52,5 +59,5 @@ window.addEventListener('message', ({ data: { action, payload } }) => {
5259
}
5360
});
5461

55-
//module.exports = linkFiber;
62+
// module.exports = linkFiber;
5663
export default linkFiber;

dev-reactime/linkFiber.js

Lines changed: 107 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,15 @@
4444
/* eslint-disable no-use-before-define */
4545
/* eslint-disable no-param-reassign */
4646

47+
<<<<<<< HEAD
4748
const { Tree, UnfilteredTreeNode } = require('./tree');
4849
const astParser = require('./astParser');
4950
const { saveState } = require('./masterState');
5051
// import * as reactWorkTags from './reactWorkTags';
52+
=======
53+
const Tree = require('./tree');
54+
const componentActionsRecord = require('./masterState');
55+
>>>>>>> 8e774670f36699322d70300c6382bcdcc7b349e0
5156

5257
module.exports = (snap, mode) => {
5358
let fiberRoot = null;
@@ -64,109 +69,93 @@ module.exports = (snap, mode) => {
6469
];
6570

6671

67-
function sendSnapshot() {
72+
async function sendSnapshot() {
6873
// Don't send messages while jumping or while paused
69-
// DEV: So that when we are jumping to an old snapshot it
7074
if (mode.jumping || mode.paused) return;
71-
const payload = snap.tree.getCopy();
72-
window.postMessage({
73-
action: 'recordSnap',
74-
payload,
75-
});
76-
}
77-
78-
function changeSetState(component) {
79-
if (component.setState.linkFiberChanged) return;
80-
81-
// Persist the old setState and bind to component so we can continue to setState({})
82-
const oldSetState = component.setState.bind(component);
83-
84-
component.setState = (state, callback = () => {}) => {
85-
// Don't do anything if state is locked UNLESS we are currently jumping through time
86-
if (mode.locked && !mode.jumping) return;
87-
// Continue normal setState functionality, with middleware in callback
88-
oldSetState(state, () => {
89-
updateSnapShotTree();
90-
sendSnapshot();
91-
callback.bind(component)();
75+
// console.log('PAYLOAD: before cleaning', snap.tree);
76+
const payload = snap.tree.cleanTreeCopy();// snap.tree.getCopy();
77+
// console.log('PAYLOAD: after cleaning', payload);
78+
try {
79+
await window.postMessage({
80+
action: 'recordSnap',
81+
payload,
9282
});
93-
};
94-
// Set a custom property to ensure we don't change this method again
95-
component.setState.linkFiberChanged = true;
96-
}
97-
98-
function changeUseState(component) {
99-
if (component.queue.dispatch.linkFiberChanged) return;
100-
101-
// Persist the old dispatch and bind to component so we can continue to dispatch()
102-
const oldDispatch = component.queue.dispatch.bind(component.queue);
103-
104-
component.queue.dispatch = (fiber, queue, action) => {
105-
if (mode.locked && !mode.jumping) return;
106-
oldDispatch(fiber, queue, action);
107-
// * Uncomment setTimeout to prevent snapshot lag-effect
108-
// * (i.e. getting the prior snapshot on each state change)
109-
// setTimeout(() => {
110-
updateSnapShotTree();
111-
sendSnapshot();
112-
// }, 100);
113-
};
114-
// Set a custom property to ensure we don't change this method again
115-
component.queue.dispatch.linkFiberChanged = true;
83+
} catch (e) {
84+
console.log('failed to send postMessage:', e);
85+
}
11686
}
11787

118-
// TODO: WE NEED TO CLEAN IT UP A BIT
88+
// Carlos: Injects instrumentation to update our state tree every time
89+
// a hooks component changes state
11990
function traverseHooks(memoizedState) {
120-
// Declare variables and assigned to 0th index and an empty object, respectively
121-
const memoized = {};
122-
let index = 0;
123-
astHooks = Object.values(astHooks);
124-
// While memoizedState is truthy, save the value to the object
91+
const hooksComponents = [];
12592
while (memoizedState && memoizedState.queue) {
126-
// // prevents useEffect from crashing on load
93+
// Carlos: these two are legacy comments, we should look into them later
94+
// prevents useEffect from crashing on load
12795
// if (memoizedState.next.queue === null) { // prevents double pushing snapshot updates
128-
changeUseState(memoizedState);
129-
// }
130-
// memoized[astHooks[index]] = memoizedState.memoizedState;
131-
memoized[astHooks[index]] = memoizedState.memoizedState;
132-
// Reassign memoizedState to its next value
133-
memoizedState = memoizedState.next;
134-
// See astParser.js for explanation of this increment
135-
index += 2;
96+
if (memoizedState.memoizedState) {
97+
console.log('memoizedState in traverseHooks is:', memoizedState);
98+
hooksComponents.push({
99+
component: memoizedState.queue,
100+
state: memoizedState.memoizedState,
101+
});
102+
}
103+
// console.log('GOT STATE', memoizedState.memoizedState);
104+
memoizedState = memoizedState.next !== memoizedState
105+
? memoizedState.next : null;
136106
}
137-
return memoized;
107+
return hooksComponents;
138108
}
139109

140-
141-
function createTree(curFiber, parentNode) {
142-
// on call from updateSnapShot, no parentNode provided, so create a root node
143-
if(! parentNode) parentNode = new Tree('root');
144-
145-
// Base case: parentNode's child or sibling pointed to null
146-
if (!curFiber) return parentNode;
147-
148-
let newChildNode = null;
149-
150-
// If stateful, add to parentNode's children array, then inject new setState into fiber node
151-
if (curFiber.stateNode && curFiber.stateNode.state) {
152-
newChildNode = parentNode.appendChild(curFiber.stateNode);
153-
changeSetState(curFiber.stateNode);
154-
155-
// newChildNode.isStateful = true;
156-
newChildNode.tagLabel = reactWorkTags[curFiber.tag];
157-
newChildNode.actualDuration = curFiber.actualDuration;
158-
// newChildNode.actualStartTime = curFiber.actualStartTime;
159-
// newChildNode.selfBaseDuration = curFiber.selfBaseDuration;
160-
// newChildNode.treeBaseDuration = curFiber.treeBaseDuration;
110+
// Carlos: This runs after EVERY Fiber commit. It creates a new snapshot,
111+
//
112+
function createTree(currentFiber, tree = new Tree('root')) {
113+
// Base case: child or sibling pointed to null
114+
if (!currentFiber) return tree;
115+
116+
// These have the newest state. We update state and then
117+
// called updateSnapshotTree()
118+
const {
119+
sibling,
120+
stateNode,
121+
child,
122+
memoizedState,
123+
elementType,
124+
tag,
125+
} = currentFiber;
126+
127+
let index;
128+
// Check if node is a stateful component
129+
if (stateNode && stateNode.state && (tag === 0 || tag === 1)) {
130+
// Save component's state and setState() function to our record for future
131+
// time-travel state changing. Add record index to snapshot so we can retrieve.
132+
index = componentActionsRecord.saveNew(stateNode.state, stateNode);
133+
tree.appendChild(stateNode.state, elementType.name, index); // Add component to tree
134+
} else {
135+
// grab stateless components here
161136
}
162137

163-
// Recurse to sibling; siblings that have state should be added to our parentNode
164-
createTree(curFiber.sibling, parentNode);
138+
// Check if node is a hooks function
139+
if (memoizedState && (tag === 0 || tag === 1 || tag === 10)) {
140+
if (memoizedState.queue) {
141+
const hooksComponents = traverseHooks(memoizedState);
142+
hooksComponents.forEach(c => {
143+
if (elementType.name) {
144+
index = componentActionsRecord.saveNew(c.state, c.component);
145+
tree.appendChild(c.state, elementType.name ? elementType.name : 'nameless', index);
146+
}
147+
});
148+
}
149+
}
165150

166-
// Recurse to child; If this fiber was stateful, then we added a newChildNode here, and we want
167-
// to attach further children to that. If this fiber wasn't stateful, we want to attach any
168-
// children to our existing parentNode.
169-
createTree(curFiber.child, newChildNode || parentNode);
151+
// Recurse on siblings
152+
createTree(sibling, tree);
153+
// Recurse on children
154+
if (tree.children.length > 0) {
155+
createTree(child, tree.children[0]);
156+
} else {
157+
createTree(child, tree);
158+
}
170159

171160
return parentNode;
172161
}
@@ -204,26 +193,31 @@ module.exports = (snap, mode) => {
204193

205194

206195
// ! BUG: skips 1st hook click
207-
async function updateSnapShotTree() {
208-
let current;
196+
function updateSnapShotTree() {
197+
/* let current;
209198
// If concurrent mode, grab current.child
210199
if (concurrent) {
211200
// we need a way to wait for current child to populate
212201
const promise = new Promise((resolve, reject) => {
213202
setTimeout(() => resolve(fiberRoot.current.child), 400);
214203
});
215-
216204
current = await promise;
217-
218205
current = fiberRoot.current.child;
219206
} else {
220207
current = fiberRoot.current;
221-
}
208+
} */
209+
const { current } = fiberRoot; // Carlos: get rid of concurrent mode for now
222210

211+
<<<<<<< HEAD
223212
snap.tree = createTree(current);
224213
console.log("updateSnapShotTree -> snap.tree", snap.tree)
225214
// snap.unfilteredTree = createUnfilteredTree(current);
226215
// console.log("updateSnapShotTree -> snap.unfilteredTree", snap.unfilteredTree)
216+
=======
217+
// console.log('FIBER COMMITTED, new fiber is:', util.inspect(current, false, 4));
218+
// fs.appendFile('fiberlog.txt', util.inspect(current, false, 10));
219+
snap.tree = createTree(current); // Carlos: pass new hooks state here?
220+
>>>>>>> 8e774670f36699322d70300c6382bcdcc7b349e0
227221
}
228222

229223
return async container => {
@@ -238,15 +232,30 @@ module.exports = (snap, mode) => {
238232
} = container;
239233
// Only assign internal root if it actually exists
240234
fiberRoot = _internalRoot || _reactRootContainer;
241-
console.log('linkFiber.js, fiberRoot:', fiberRoot);
235+
// console.log('_reactRootContainer is:', _reactRootContainer);
236+
// console.log('linkFiber.js, fiberRoot:', fiberRoot);
242237
}
243-
244-
await updateSnapShotTree();
238+
const devTools = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
239+
const reactInstance = devTools ? devTools.renderers.get(1) : null;
240+
const overrideHookState = reactInstance ? reactInstance.overrideHookState : null;
241+
console.log('DEVTOOLS:', devTools);
242+
console.log('roots:', reactInstance.getCurrentFiber())
243+
244+
if (reactInstance && reactInstance.version) {
245+
devTools.onCommitFiberRoot = (function (original) {
246+
return function (...args) {
247+
fiberRoot = args[1];
248+
updateSnapShotTree();
249+
sendSnapshot();
250+
return original(...args);
251+
};
252+
}(devTools.onCommitFiberRoot));
253+
}
254+
updateSnapShotTree();
245255
// Send the initial snapshot once the content script has started up
246256
// This message is sent from contentScript.js in chrome extension bundles
247257
window.addEventListener('message', ({ data: { action } }) => {
248258
if (action === 'contentScriptStarted') {
249-
console.log('linkFiber.js received contentScriptStarted message, sending snapshot');
250259
sendSnapshot();
251260
}
252261
});

dev-reactime/masterState.js

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
1+
/* eslint-disable no-plusplus */
12
/* eslint-disable guard-for-in */
23
/* eslint-disable no-restricted-syntax */
3-
// Export two functions that either saves the AST state object into an array
4-
// or returns the array for use
5-
const masterState = [];
4+
5+
const componentActionsRecord = {};
6+
let index = 0;
7+
8+
module.exports = {
9+
saveNew: (state, component) => {
10+
componentActionsRecord[index] = { state, component };
11+
index++;
12+
return index - 1;
13+
},
14+
getRecordByIndex: inputIndex => componentActionsRecord[inputIndex],
15+
getComponentByIndex: inputIndex => (componentActionsRecord[inputIndex]
16+
? componentActionsRecord[inputIndex].component
17+
: undefined),
18+
};
19+
20+
21+
/* const masterState = [];
22+
const hooksComponentsActions = {};
623
724
module.exports = {
825
saveState: state => {
@@ -12,4 +29,10 @@ module.exports = {
1229
return masterState;
1330
},
1431
returnState: () => masterState,
32+
saveHooksComponent: stateAndAction => {
33+
for (const elementName in stateAndAction) {
34+
hooksComponentsActions[elementName] = stateAndAction[elementName];
35+
}
36+
},
1537
};
38+
*/

dev-reactime/node_modules/fs/README.md

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)