Skip to content

Commit f5caebc

Browse files
committed
Merge with backend changes
2 parents 1cbd30c + 44092dd commit f5caebc

File tree

3 files changed

+17
-178
lines changed

3 files changed

+17
-178
lines changed

src/backend/controllers/createComponentActionsRecord.ts

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
// import typescript types
2-
import {
3-
// object with tree structure
4-
Fiber,
5-
} from '../types/backendTypes';
1+
import { Fiber } from '../types/backendTypes';
62
import {
73
FunctionComponent,
84
ClassComponent,
9-
IndeterminateComponent, // Before we know whether it is function or class
5+
IndeterminateComponent,
106
ContextProvider,
117
} from '../types/backendTypes';
12-
// passes the data down to its components
138
import componentActionsRecord from '../models/masterState';
149
import { getHooksStateAndUpdateMethod } from './statePropExtractors';
1510
import {
@@ -20,14 +15,14 @@ import {
2015

2116
// ------------------------CREATE COMPONENT ACTIONS RECORD----------------------
2217
/**
23-
* This is a recursive function that runs after Fiber commit, if user navigating to a new route during jumping. This function performs the following logic:
18+
* This is a recursive function that runs after Fiber commit, if user is navigating to a new route during jumping. This function performs the following logic:
2419
* 1. Traverse from FiberRootNode
2520
* 2. If the component is stateful, extract its update methods & push to the `componentActionRecord` array
2621
* @param currentFiberNode A Fiber object
2722
*/
2823
export default function createComponentActionsRecord(currentFiberNode: Fiber): void {
2924
// ------------------OBTAIN DATA FROM THE CURRENT FIBER NODE----------------
30-
// Destructure the current fiber node:
25+
// Destructure the current fiber node
3126
const {
3227
sibling,
3328
stateNode,
@@ -46,28 +41,13 @@ export default function createComponentActionsRecord(currentFiberNode: Fiber): v
4641
elementType?.name ||
4742
'nameless';
4843

49-
// console.log('createComponentActionsRecord', {
50-
// currentFiberNode,
51-
// // tag,
52-
// // elementType,
53-
// componentName:
54-
// elementType?._context?.displayName || //For ContextProvider
55-
// elementType?._result?.name || //For lazy Component
56-
// elementType?.render?.name ||
57-
// elementType?.name ||
58-
// elementType,
59-
// // memoizedState,
60-
// // stateNode,
61-
// // _debugHookTypes,
62-
// });
63-
6444
// --------------------FILTER COMPONENTS/FIBER NODE-------------------------
6545
/**
6646
* For the snapshot tree,
67-
* 1. We will only interested in components that are one of these types: Function Component, Class Component, Indeterminate Component or Context Provider.
47+
* 1. We are only interested in components that are one of these types: Function Component, Class Component, Indeterminate Component or Context Provider.
6848
* NOTE: this list of components may change depending on future use
69-
* 2. If user use Next JS, filter out default NextJS components
70-
* 3. If user use Remix JS, filter out default Remix components
49+
* 2. If user is using Next JS, filter out default NextJS components
50+
* 3. If user is using Remix JS, filter out default Remix components
7151
*/
7252

7353
if (
@@ -90,20 +70,15 @@ export default function createComponentActionsRecord(currentFiberNode: Fiber): v
9070
// ---------OBTAIN STATE & SET STATE METHODS FROM CLASS COMPONENT-----------
9171
// Check if node is a stateful class component when user use setState.
9272
// If user use setState to define/manage state, the state object will be stored in stateNode.state => grab the state object stored in the stateNode.state
93-
// Example: for tic-tac-toe demo-app: Board is a stateful component that use setState to store state data.
9473
if ((tag === ClassComponent || tag === IndeterminateComponent) && stateNode?.state) {
9574
// Save component setState() method to our componentActionsRecord for use during timeJump
9675
componentActionsRecord.saveNew(stateNode);
9776
}
98-
9977
// --------OBTAIN STATE & DISPATCH METHODS FROM FUNCTIONAL COMPONENT--------
10078
// Check if node is a stateful class component when user use setState.
10179
// If user use useState to define/manage state, the state object will be stored in memoizedState.queue => grab the state object stored in the memoizedState.queue
10280
if (
103-
(tag === FunctionComponent ||
104-
tag === IndeterminateComponent ||
105-
//TODO: Need to figure out why we need context provider
106-
tag === ContextProvider) &&
81+
(tag === FunctionComponent || tag === IndeterminateComponent || tag === ContextProvider) &&
10782
memoizedState
10883
) {
10984
if (memoizedState.queue) {
@@ -114,7 +89,7 @@ export default function createComponentActionsRecord(currentFiberNode: Fiber): v
11489
// which includes the dispatch() function we use to change their state.
11590
const hooksStates = getHooksStateAndUpdateMethod(memoizedState);
11691
hooksStates.forEach(({ component }) => {
117-
// Save component's state and dispatch() function to our record for future time-travel state changing. Add record index to snapshot so we can retrieve.
92+
// Save component's state and dispatch() function to our record for future time-travel state changing. Add record index to snapshot so we can retrieve later
11893
componentActionsRecord.saveNew(component);
11994
});
12095
} catch (err) {
@@ -124,7 +99,6 @@ export default function createComponentActionsRecord(currentFiberNode: Fiber): v
12499
}
125100
}
126101
}
127-
128102
// ---------------------TRAVERSE TO NEXT FIBERNODE--------------------------
129103
// If currentFiberNode has children, recurse on children
130104
if (child) createComponentActionsRecord(child);
Lines changed: 3 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
const acorn = require('acorn');
22
const jsx = require('acorn-jsx');
33
const JSXParser = acorn.Parser.extend(jsx());
4-
import {
5-
// array of state and component
6-
HookStates,
7-
// object with tree structure
8-
Fiber,
9-
} from '../types/backendTypes';
4+
import { HookStates, Fiber } from '../types/backendTypes';
105
import { exclude } from '../models/filterConditions';
11-
// TODO: Determine what Component Data Type we are sending back for state, context, & props
6+
127
type ReactimeData = {
138
[key: string]: any;
149
};
15-
1610
// ------------FILTER DATA FROM REACT DEV TOOL && CONVERT TO STRING-------------
1711
/**
1812
* This function receives raw Data from REACT DEV TOOL and filter the Data based on the exclude list. The filterd data is then converted to string (if applicable) before being sent to reacTime front end.
@@ -27,8 +21,7 @@ export function filterAndFormatData(
2721
): ReactimeData {
2822
for (const key in reactDevData) {
2923
try {
30-
// Skip keys that are in exclude set OR if there is no value at key
31-
// Falsy values such as 0, false, null are still valid value
24+
// If key is in exclude set or if there is no value at key, skip
3225
if (exclude.has(key) || reactDevData[key] === undefined) {
3326
continue;
3427
}
@@ -59,62 +52,6 @@ export function filterAndFormatData(
5952
}
6053
return reactimeData;
6154
}
62-
// COMMENT OUT SINCE EXTRACTING CONTEXT IS STILL IN EXPERIMENT
63-
// // ------------------------FILTER STATE & CONTEXT DATA--------------------------
64-
// /**
65-
// * This function is used to filter the state data of a component.
66-
// * All propperty name that are in the central `exclude` list would be filtered out.
67-
// * If passed in memoizedState is a not an object (a.k.a a primitive type), a default name would be provided.
68-
// * @param memoizedState - The current state of the component associated with the current Fiber node.
69-
// * @param _debugHookTypes - An array of hooks used for debugging purposes.
70-
// * @param componentName - Name of the evaluated component
71-
// * @returns - The updated state data object to send to front end of ReactTime
72-
// */
73-
// export function getStateAndContextData(
74-
// memoizedState: Fiber['memoizedState'],
75-
// componentName: string,
76-
// _debugHookTypes: Fiber['_debugHookTypes'],
77-
// ) {
78-
// // Initialize a list of componentName that would not be evaluated for State Data:
79-
// const ignoreComponent = new Set(['BrowserRouter', 'Router']);
80-
// if (ignoreComponent.has(componentName)) return;
81-
82-
// // Initialize object to store state and context data of the component
83-
// const reactimeData: ReactimeData = {};
84-
// // Initialize counter for the default naming. If user use reactHook, such as useState, react will only pass in the value, and not the variable name of the state.
85-
// let stateCounter = 1;
86-
// let refCounter = 1;
87-
88-
// // Loop through each hook inside the _debugHookTypes array.
89-
// // NOTE: _debugHookTypes.length === height of memoizedState tree.
90-
// for (const hook of _debugHookTypes) {
91-
// // useContext does not create any state => skip
92-
// if (hook === 'useContext') {
93-
// continue;
94-
// }
95-
// // If user use useState reactHook => React will only pass in the value of state & not the name of the state => create a default name:
96-
// else if (hook === 'useState') {
97-
// const defaultName = `State ${stateCounter}`;
98-
// reactimeData[defaultName] = memoizedState.memoizedState;
99-
// stateCounter++;
100-
// }
101-
// // If user use useRef reactHook => React will store memoizedState in current object:
102-
// else if (hook === 'useRef') {
103-
// const defaultName = `Ref ${refCounter}`;
104-
// reactimeData[defaultName] = memoizedState.memoizedState.current;
105-
// refCounter++;
106-
// }
107-
// // If user use Redux to contain their context => the context object will be stored using useMemo Hook, as of for Rect Dev Tool v4.27.2
108-
// // Note: Provider is not a reserved component name for redux. User may name their component as Provider, which will break this logic. However, it is a good assumption that if user have a custom provider component, it would have a more specific naming such as ThemeProvider.
109-
// else if (hook === 'useMemo' && componentName === 'Provider') {
110-
// filterAndFormatData(memoizedState.memoizedState[0], reactimeData);
111-
// }
112-
// //Move on to the next level of memoizedState tree.
113-
// memoizedState = memoizedState?.next;
114-
// }
115-
// // Return the updated state data object to send to front end of ReactTime
116-
// return reactimeData;
117-
// }
11855

11956
// ----------------------GET HOOK STATE AND DISPATCH METHOD---------------------
12057
/**
@@ -202,75 +139,3 @@ export function getHooksNames(elementType: string): { hookName: string; varName:
202139
throw new Error('getHooksNameError' + err.message);
203140
}
204141
}
205-
206-
// DEPERACATED: After React DEV Tool Update. This function no longer works. Keep for history record
207-
// // Helper function to grab the getters/setters from `elementType`
208-
// /**
209-
// * @method getHooksNames
210-
// * @param elementType The fiber `type`, A stringified function of the component, the Fiber whose hooks we want corresponds to
211-
// * @returns An array of strings
212-
// */
213-
// // TODO: this function has return at the end of loop? Is this intentional?
214-
// export const getHooksNames = (elementType: string): Array<string> | undefined => {
215-
// // Initialize empty object to store the setters and getter
216-
// let ast: any;
217-
// try {
218-
// ast = JSXParser.parse(elementType);
219-
// } catch (e) {
220-
// return ['unknown'];
221-
// }
222-
// // hookNames will contain an object with methods (functions)
223-
// const hooksNames: any = {};
224-
225-
// // Begin search for hook names, only if ast has a body property.
226-
// while (Object.hasOwnProperty.call(ast, 'body')) {
227-
// let tsCount = 0; // Counter for the number of TypeScript hooks seen (to distinguish in masterState)
228-
// ast = ast.body;
229-
230-
// // Statements get all the names of the hooks. For example: useCount, useWildcard, ...
231-
// const statements: Array<string> = [];
232-
// /** All module exports always start off as a single 'FunctionDeclaration' type
233-
// * Other types: "BlockStatement" / "ExpressionStatement" / "ReturnStatement"
234-
// * Iterate through AST of every function declaration
235-
// * Check within each function declaration if there are hook declarations */
236-
// ast.forEach((functionDec: any) => {
237-
// let declarationBody: any;
238-
// if (functionDec.expression?.body) declarationBody = functionDec.expression.body.body;
239-
// // check if functionDec.expression.body exists, then set declarationBody to functionDec's body
240-
// else declarationBody = functionDec.body?.body ?? [];
241-
// // Traverse through the function's funcDecs and Expression Statements
242-
// declarationBody.forEach((elem: any) => {
243-
// // Hooks will always be contained in a variable declaration
244-
// if (elem.type === 'VariableDeclaration') {
245-
// elem.declarations.forEach((hook: any) => {
246-
// // Parse destructured statements pair
247-
// if (hook.id.type === 'ArrayPattern') {
248-
// hook.id.elements.forEach((hook: any) => {
249-
// statements.push(`_useWildcard${tsCount}`);
250-
// statements.push(hook.name);
251-
// tsCount += 1;
252-
// });
253-
// // Process hook function invocation ?
254-
// } else {
255-
// // hook.init.object is '_useState2', '_useState4', etc.
256-
// // eslint-disable-next-line no-lonely-if
257-
// if (hook?.init?.object?.name) {
258-
// const varName: any = hook.init.object.name;
259-
// if (!hooksNames[varName] && varName.match(/_use/)) {
260-
// hooksNames[varName] = hook.id.name;
261-
// }
262-
// }
263-
// if (hook.id.name !== undefined) {
264-
// statements.push(hook.id.name);
265-
// }
266-
// }
267-
// });
268-
// }
269-
// });
270-
// statements.forEach((el, i) => {
271-
// if (el.match(/_use/)) hooksNames[el] = statements[i + 1];
272-
// });
273-
// });
274-
// return Object.values(hooksNames);
275-
// }
276-
// };

src/backend/controllers/throttle.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ export default function throttle<T extends (...args: any) => any>(
3535
let timeout: NodeJS.Timeout;
3636
// Wrap the passed-in function callback in a callback function that "throttles" (puts a limit on) the number of calls that can be made to function in a given period of time (ms)
3737
return function throttledFunc(...args: Parameters<T>): ReturnType<T> {
38-
// CASE 1: In cooldown mode and we already have a function waiting to be executed, so do nothing
38+
// CASE 1: In cooldown mode and we have a function waiting to be executed, so do nothing
3939
if (isOnCooldown && isCallQueued) return;
4040

41-
// CASE 2: In cooldown mode, but we have no functions waiting to be executed, so just make note that we now have a call waiting to be executed and return
41+
// CASE 2: In cooldown mode, but we have no functions waiting to be executed, so just make note that we now have a callback waiting to be executed and then return
4242
if (isOnCooldown) {
4343
isCallQueued = true;
4444
return;
@@ -59,9 +59,9 @@ export default function throttle<T extends (...args: any) => any>(
5959
* @returns void
6060
*/
6161
function runAfterTimeout() {
62-
// If there is callback in the queue
62+
// If there is callback in the queue, execute callback immediately
6363
if (isCallQueued) {
64-
// Execute the function callback immediately
64+
// Execute callback
6565
callback(...args);
6666
// Initiate a new cooldown period and reset the "call queue"
6767
isOnCooldown = true;
@@ -70,7 +70,7 @@ export default function throttle<T extends (...args: any) => any>(
7070
clearTimeout(timeout);
7171
setTimeout(runAfterTimeout, MIN_TIME_BETWEEN_UPDATE);
7272
}
73-
// If not callback in queue, end the cooldown period
73+
// If no callback in queue, end the cooldown period
7474
else {
7575
// End cooldown period after MIN_TIME_BETWEEN_UPDATE has passed
7676
isOnCooldown = false;

0 commit comments

Comments
 (0)