Skip to content

Commit ca83448

Browse files
committed
linkFiber comments
1 parent 5cddefb commit ca83448

File tree

1 file changed

+70
-30
lines changed

1 file changed

+70
-30
lines changed

package/linkFiber.js

Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,46 @@
1+
/**
2+
* This file contains core module functionality.
3+
*
4+
* It exports an anonymous
5+
* @function
6+
* that is invoked on
7+
* @param snap --> Current snapshot
8+
* @param mode --> Current mode (jumping i.e. time-traveling, locked, or paused)
9+
* and @returns a function to be invoked on the rootContainer HTMLElement
10+
*
11+
* @function updateSnapShotTree
12+
* --> Middleware #1: Updates snap object with latest snapshot
13+
*
14+
* @function sendSnapshot
15+
* --> Middleware #2: Gets a copy of the current snapshot state tree and posts it to the window
16+
*
17+
* @function changeSetState
18+
* @param component : stateNode property on a stateful class component's FiberNode object
19+
* --> Binds class component setState method to the component
20+
* --> Injects middleware into class component's setState method
21+
*
22+
* @function changeUseState
23+
* @param component : memoizedState property on a stateful functional component's FiberNode object
24+
* --> Binds functional component dispatch method to the component
25+
* --> Injects middleware into component's dispatch method
26+
* Note: dispatch is hook equivalent to setState()
27+
*
28+
* @function traverseHooks
29+
* @param memoizedState : memoizedState property on a stateful functional component's FiberNode object
30+
* --> Helper function to traverse through memoizedState
31+
* --> Invokes @changeUseState on each stateful functional component
32+
*
33+
* @function createTree
34+
* @param currentFiber : a FiberNode object
35+
* --> Recursive function to traverse from FiberRootNode and create
36+
* an instance of custom Tree class and build up state snapshot
37+
*/
38+
139
/* eslint-disable no-underscore-dangle */
240
/* eslint-disable func-names */
341
/* eslint-disable no-use-before-define */
442
/* eslint-disable no-param-reassign */
5-
// links component state tree to library
6-
// changes the setState method to also update our snapshot
43+
744
const Tree = require('./tree');
845
const astParser = require('./astParser');
946
const { saveState } = require('./masterState');
@@ -27,67 +64,69 @@ module.exports = (snap, mode) => {
2764
}
2865

2966
function changeSetState(component) {
30-
// check that setState hasn't been changed yet
3167
if (component.setState.linkFiberChanged) return;
32-
// make a copy of setState
68+
69+
// Persist the old setState and bind to component so we can continue to setState({})
3370
const oldSetState = component.setState.bind(component);
34-
// replace component's setState so developer doesn't change syntax
35-
// component.setState = newSetState.bind(component);
71+
3672
component.setState = (state, callback = () => {}) => {
37-
// don't do anything if state is locked
38-
// UNLESS we are currently jumping through time
73+
// Don't do anything if state is locked UNLESS we are currently jumping through time
3974
if (mode.locked && !mode.jumping) return;
40-
// continue normal setState functionality, except add sending message middleware
75+
// Continue normal setState functionality, with middleware in callback
4176
oldSetState(state, () => {
4277
updateSnapShotTree();
4378
sendSnapshot();
4479
callback.bind(component)();
4580
});
4681
};
82+
// Set a custom property to ensure we don't change this method again
4783
component.setState.linkFiberChanged = true;
4884
}
4985

5086
function changeUseState(component) {
5187
if (component.queue.dispatch.linkFiberChanged) return;
52-
// store the original dispatch function definition
88+
89+
// Persist the old dispatch and bind to component so we can continue to dispatch()
5390
const oldDispatch = component.queue.dispatch.bind(component.queue);
54-
// redefine the dispatch function so we can inject our code
91+
5592
component.queue.dispatch = (fiber, queue, action) => {
56-
// don't do anything if state is locked
5793
if (mode.locked && !mode.jumping) return;
5894
oldDispatch(fiber, queue, action);
95+
// * Uncomment setTimeout to prevent snapshot lag-effect
96+
// * (i.e. getting the prior snapshot on each state change)
5997
// setTimeout(() => {
6098
updateSnapShotTree();
6199
sendSnapshot();
62100
// }, 100);
63101
};
102+
// Set a custom property to ensure we don't change this method again
64103
component.queue.dispatch.linkFiberChanged = true;
65104
}
66105

67-
// Helper function to traverse through the memoized state
68106
// TODO: WE NEED TO CLEAN IT UP A BIT
69107
function traverseHooks(memoizedState) {
70108
// Declare variables and assigned to 0th index and an empty object, respectively
71109
const memoized = {};
72110
let index = 0;
73111
astHooks = Object.values(astHooks);
74-
// while memoizedState is truthy, save the value to the object
112+
// While memoizedState is truthy, save the value to the object
75113
while (memoizedState && memoizedState.queue) {
76-
// prevents useEffect from crashing on load
114+
// // prevents useEffect from crashing on load
77115
// if (memoizedState.next.queue === null) { // prevents double pushing snapshot updates
78116
changeUseState(memoizedState);
79117
// }
80118
// memoized[astHooks[index]] = memoizedState.memoizedState;
81119
memoized[astHooks[index]] = memoizedState.memoizedState;
82120
// Reassign memoizedState to its next value
83121
memoizedState = memoizedState.next;
84-
// Increment the index by 2
122+
// See astParser.js for explanation of this increment
85123
index += 2;
86124
}
87125
return memoized;
88126
}
89127

90128
function createTree(currentFiber, tree = new Tree('root')) {
129+
// Base case: child or sibling pointed to null
91130
if (!currentFiber) return tree;
92131

93132
const {
@@ -99,16 +138,14 @@ module.exports = (snap, mode) => {
99138
} = currentFiber;
100139

101140
let nextTree = tree;
102-
// check if stateful component
141+
142+
// Check if stateful component
103143
if (stateNode && stateNode.state) {
104-
// add component to tree
105-
nextTree = tree.appendChild(stateNode);
106-
// change setState functionality
107-
changeSetState(stateNode);
144+
nextTree = tree.appendChild(stateNode); // Add component to tree
145+
changeSetState(stateNode); // Change setState functionality
108146
}
109-
// Check if the component uses hooks
110-
// console.log("memoizedState", memoizedState);
111147

148+
// Check if the component uses hooks
112149
if (
113150
memoizedState &&
114151
Object.hasOwnProperty.call(memoizedState, 'baseState')
@@ -123,18 +160,19 @@ module.exports = (snap, mode) => {
123160
memoizedState.traversed = traverseHooks(memoizedState);
124161
nextTree = tree.appendChild(memoizedState);
125162
}
126-
// iterate through siblings
163+
164+
// Recurse on siblings
127165
createTree(sibling, tree);
128-
// iterate through children
166+
// Recurse on children
129167
createTree(child, nextTree);
130168

131169
return tree;
132170
}
133-
// runs when page initially loads
134-
// but skips 1st hook click
171+
172+
// ! BUG: skips 1st hook click
135173
async function updateSnapShotTree() {
136174
let current;
137-
// if concurrent mode, grab current.child'
175+
// If concurrent mode, grab current.child
138176
if (concurrent) {
139177
// we need a way to wait for current child to populate
140178
const promise = new Promise((resolve, reject) => {
@@ -152,6 +190,7 @@ module.exports = (snap, mode) => {
152190
}
153191

154192
return async container => {
193+
// Point fiberRoot to FiberRootNode
155194
if (container._internalRoot) {
156195
fiberRoot = container._internalRoot;
157196
concurrent = true;
@@ -160,12 +199,13 @@ module.exports = (snap, mode) => {
160199
_reactRootContainer: { _internalRoot },
161200
_reactRootContainer,
162201
} = container;
163-
// only assign internal root if it actually exists
202+
// Only assign internal root if it actually exists
164203
fiberRoot = _internalRoot || _reactRootContainer;
165204
}
166205

167206
await updateSnapShotTree();
168-
// send the initial snapshot once the content script has started up
207+
// Send the initial snapshot once the content script has started up
208+
// This message is sent from contentScript.js in chrome extension bundles
169209
window.addEventListener('message', ({ data: { action } }) => {
170210
if (action === 'contentScriptStarted') sendSnapshot();
171211
});

0 commit comments

Comments
 (0)