Skip to content

Commit a095f3e

Browse files
authored
Merge pull request #32 from oslabs-beta/dev
Dev to master merge
2 parents 24947dd + c5abe63 commit a095f3e

File tree

8 files changed

+153
-76
lines changed

8 files changed

+153
-76
lines changed

package-lock.json

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

package/.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__tests__

package/astParser.js

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,53 @@
11
const acorn = require('acorn');
22
const jsx = require('acorn-jsx');
3-
const JSXParser = acorn.Parser.extend(jsx());
43

5-
// Helper function to recursively traverse through the user's codebase
6-
// INSERT HERE
4+
const JSXParser = acorn.Parser.extend(jsx());
75

8-
module.exports = file => {
6+
// Helper function to recursively traverse AST of a specified component for all hook declarations
7+
function getHookNames(ast) {
98
// Initialize empty object to store the setters and getter
109
const hookState = {};
11-
const ast = JSXParser.parse(file).body;
12-
// Iterate through AST of every function declaration
13-
// Check within each function declaration if there are hook declarations
14-
ast.forEach(func => {
15-
const { body } = func.body;
16-
const statements = [];
17-
// Traverse through the function's funcDecs and Expression Statements
18-
body.forEach(program => {
19-
if (program.type === 'VariableDeclaration') {
20-
program.declarations.forEach(dec => {
21-
statements.push(dec.id.name);
22-
});
10+
// All module exports will always start off as a single 'FunctionDeclaration' type
11+
while (Object.hasOwnProperty.call(ast, 'body')) {
12+
// Traverse down .body once before invoking parsing logic and will loop through any .body after
13+
ast = ast.body;
14+
// Iterate through AST of every function declaration
15+
// Check within each function declaration if there are hook declarations
16+
ast.forEach(functionDec => {
17+
const { body } = functionDec.body;
18+
const statements = [];
19+
// Traverse through the function's funcDecs and Expression Statements
20+
body.forEach(program => {
21+
// Hook Declarations will only be under 'VariableDeclaration' type
22+
if (program.type === 'VariableDeclaration') {
23+
program.declarations.forEach(dec => {
24+
statements.push(dec.id.name);
25+
});
26+
}
27+
});
28+
// Iterate through the array and determine getter/setters based on pattern
29+
for (let i = 0; i < statements.length; i += 1) {
30+
if (statements[i].match(/_use/)) {
31+
hookState[statements[i]] = statements[i + 2];
32+
}
2333
}
2434
});
25-
// Iterate through the array and determine getter/setters based on pattern
26-
for (let i = 0; i < statements.length; i += 1) {
27-
if (statements[i].match(/_use/)) {
28-
hookState[statements[i]] = statements[i + 2];
29-
}
30-
}
31-
});
32-
// Return the object with setters and getters
35+
}
3336
return hookState;
37+
}
38+
39+
module.exports = file => {
40+
// Create an empty object to allow all invocations of getHookNames to consolidate
41+
let allHookNames = {};
42+
const ast = JSXParser.parse(file);
43+
// console.log('Original File', file.toString());
44+
// console.log('Original AST', ast);
45+
// Upsert any new/updated {_hookType#: hookName} pairs
46+
allHookNames = {
47+
...allHookNames,
48+
...getHookNames(ast),
49+
};
50+
51+
// Return the object with setters and getters
52+
return allHookNames;
3453
};

package/linkFiber.js

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
/* eslint-disable no-param-reassign */
44
// links component state tree to library
55
// changes the setState method to also update our snapshot
6+
7+
// import loadable from '@loadable/component';
8+
69
const Tree = require('./tree');
7-
const astParser = require('./astParser');
8-
const { saveState } = require('./masterState');
10+
const astParser = require('./astParser');
11+
const { saveState } = require('./masterState');
912

1013
module.exports = (snap, mode) => {
1114
let fiberRoot = null;
@@ -46,13 +49,13 @@ module.exports = (snap, mode) => {
4649

4750
function changeUseState(component) {
4851
if (component.queue.dispatch.linkFiberChanged) return;
49-
// store the original dispatch function definition
52+
// store the original dispatch function definition
5053
const oldDispatch = component.queue.dispatch.bind(component.queue);
5154
// redefine the dispatch function so we can inject our code
5255
component.queue.dispatch = (fiber, queue, action) => {
5356
// don't do anything if state is locked
54-
if (mode.locked && !mode.jumping) return;
55-
//oldDispatch(fiber, queue, action);
57+
if (mode.locked && !mode.jumping) return;
58+
// oldDispatch(fiber, queue, action);
5659
setTimeout(() => {
5760
oldDispatch(fiber, queue, action);
5861
updateSnapShotTree();
@@ -67,17 +70,17 @@ module.exports = (snap, mode) => {
6770
function traverseHooks(memoizedState) {
6871
// Declare variables and assigned to 0th index and an empty object, respectively
6972
const memoized = {};
70-
let index = 0;
71-
astHooks = Object.values(astHooks);
73+
let index = 0;
74+
astHooks = Object.values(astHooks);
7275
// while memoizedState is truthy, save the value to the object
7376
while (memoizedState) {
7477
changeUseState(memoizedState);
75-
//memoized[astHooks[index]] = memoizedState.memoizedState;
76-
memoized[astHooks[index]] = memoizedState.memoizedState;
78+
// memoized[astHooks[index]] = memoizedState.memoizedState;
79+
memoized[astHooks[index]] = memoizedState.memoizedState;
7780
// Reassign memoizedState to its next value
7881
memoizedState = memoizedState.next;
7982
// Increment the index by 2
80-
index += 2;
83+
index += 2;
8184
}
8285
return memoized;
8386
}
@@ -101,8 +104,8 @@ module.exports = (snap, mode) => {
101104
changeSetState(stateNode);
102105
}
103106
// Check if the component uses hooks
104-
if (memoizedState && memoizedState.hasOwnProperty('baseState')) {
105-
// Add a traversed property and initialize to the evaluated result
107+
if (memoizedState && Object.hasOwnProperty.call(memoizedState, 'baseState')) {
108+
// Add a traversed property and initialize to the evaluated result
106109
// of invoking traverseHooks, and reassign nextTree
107110
memoizedState.traversed = traverseHooks(memoizedState);
108111
nextTree = tree.appendChild(memoizedState);
@@ -114,8 +117,8 @@ module.exports = (snap, mode) => {
114117

115118
return tree;
116119
}
117-
// runs when page initially loads
118-
// but skips 1st hook click
120+
// runs when page initially loads
121+
// but skips 1st hook click
119122
function updateSnapShotTree() {
120123
const { current } = fiberRoot;
121124
snap.tree = createTree(current);
@@ -128,16 +131,25 @@ module.exports = (snap, mode) => {
128131
} = container;
129132
// only assign internal rootp if it actually exists
130133
fiberRoot = _internalRoot || _reactRootContainer;
131-
// If hooks are implemented, traverse through the source code
134+
// If hooks are implemented, traverse through the source code
132135
// Save the getter/setter combo for timeJump
133136
if (entryFile) {
134137
astHooks = astParser(entryFile);
135-
saveState(astHooks);
138+
// console.log('Ast Hooks', astHooks);
139+
saveState(astHooks);
136140
}
137-
updateSnapShotTree();
141+
updateSnapShotTree();
138142
// send the initial snapshot once the content script has started up
139143
window.addEventListener('message', ({ data: { action } }) => {
140144
if (action === 'contentScriptStarted') sendSnapshot();
141145
});
146+
// Testing sending back a function def to client
147+
// function getNextImport(filePath) {
148+
// return loadable(() => import(`${filePath}`))
149+
// Got relative file path to return back to client code
150+
// return (`myTestString${filePath}`);
151+
// return getNextImport('./UseStateHook');
152+
// return 'Testing outside';
153+
// const OtherComponent = loadable(() => import('./OtherComponent'))
142154
}
143-
};
155+
};

package/masterState.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable guard-for-in */
2+
/* eslint-disable no-restricted-syntax */
13
// Export two functions that either saves the AST state object into an array
24
// or returns the array for use
35
const masterState = [];
@@ -7,7 +9,7 @@ module.exports = {
79
for (const key in state) {
810
masterState.push(state[key]);
911
}
10-
return masterState;
12+
return masterState;
1113
},
12-
returnState: () => masterState
14+
returnState: () => masterState,
1315
};

package/package-lock.json

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

package/timeJump.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable no-param-reassign */
22
// traverses given tree by accessing children through coords array
3-
const { returnState } = require('./masterState');
3+
const { returnState } = require('./masterState');
44

55
function traverseTree(tree, coords) {
66
let curr = tree;
@@ -26,8 +26,8 @@ module.exports = (origin, mode) => {
2626
// if component uses hooks, traverse through the memoize tree
2727
let current = originNode.component;
2828
let index = 0;
29-
const hooks = returnState();
30-
// Iterate through the memoize tree
29+
const hooks = returnState();
30+
// while loop through the memoize tree
3131
while (current) {
3232
current.queue.dispatch(target.state[hooks[index]]);
3333
// Reassign the current value

0 commit comments

Comments
 (0)