Skip to content

Commit a917c6b

Browse files
authored
Merge branch 'staging' into map
2 parents f576848 + eebc62f commit a917c6b

File tree

12 files changed

+63
-27
lines changed

12 files changed

+63
-27
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ src/extension/build.crx
1010
src/extension/build.pem
1111
bower_components
1212
sandboxes/manual-tests/NextJS/.next
13-
.vscode
13+
.vscode
14+
src/app/components/Map.tsx

AppStructureDiagram.png

440 KB
Loading

package-lock.json

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

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
"react-html-parser": "^2.0.2",
119119
"react-json-tree": "^0.11.2",
120120
"react-router-dom": "^5.2.0",
121-
"react-select": "^3.1.0"
121+
"react-select": "^3.1.0",
122+
"recoil": "0.0.10"
122123
}
123124
}

readme_2.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
This documentation explains the architecture of Reactime v4.
2+
3+
4+
![demo](./AppStructureDiagram.png)
5+
6+
In the src folder, there are three directories: app, backend, and extension.
7+
8+
9+
The app folder is responsible a SPA that you see when you open the chrome dev tools under the Reactime tab.
10+
11+
The backend folder is responsible for generating data and handle time-jump request from the background.js scripts in extension.
12+
13+
The extension folder is where the contentscript.js and background.js located. These two files belongs to Chrome internal to help us handle requests both from the web browser and from the chrome dev tools. Unsure what contentscripts and backgroundscripts are? The details implementation are documented in the files themselves.
14+
15+
> Content scripts are files that run in the context of web pages. By using the standard Document Object Model (DOM), they are able to read details of the web pages the browser visits, make changes to them and pass information to their parent extension. Source: https://developer.chrome.com/extensions/content_scripts
16+
17+
>A background page is loaded when it is needed, and unloaded when it goes idle. Some examples of events include:
18+
>The extension is first installed or updated to a new version.
19+
>The background page was listening for an event, and the event is dispatched.
20+
>A content script or other extension sends a message.
21+
>Another view in the extension, such as a popup, calls runtime.getBackgroundPage.
22+
>Once it has been loaded, a background page will stay running as long as it is performing an action, such as calling a Chrome API or issuing a network request. Additionally, the background page will not unload until all visible views and all message ports are closed. Note that opening a view does not cause the event page to load, but only prevents it from closing once loaded. Source: https://developer.chrome.com/extensions/background_pages
23+
24+
Just to reiterate, contentscript is use to read and modify information that is rendered on the webpage, and a host of other objects. Background is very similar to client/server concept in which background is behaving like a server, listening to request from the contentscipt and **the request from the "front-end" of the chrome dev tools in the reactime tab (not the interface of the browser, this is an important distinction.)** In other words, background script works directly with the React Dev Tools, whereas contentscript works with the interface of the browser.
25+
26+
The general flow of data is described in the following steps:
27+
28+
1. When the background bundle is loaded from the browser, it injects a script into the dom. This script uses a technique called [throttle](https://medium.com/@bitupon.211/debounce-and-throttle-160affa5457b) to get the data of the state of the app to send to the contentscript every specified miliseconds (in our case, it's 70ms).
29+
30+
31+
2. This contentscript always listens to the messages being sent from the interface of the browser. The recieved data will immediately be sent to the background script which then update an object that persist in background script called **tabsObj**. Each time tabsObj is updated, the most recent version will be sent to the interface of reactime dev tools written the app folder.
32+
33+
3. Likewise, when there is an action from Reactime dev tools - a jump request for example, a request will be made to the background script which is proxied to the content script. This content script will talk to the browser interface to request the *state* that the user wants to jump to. One important thing to note here is that the jump action will be excecuted in the backend script because it has direct access to the DOM.

src/backend/astParser.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,19 @@ module.exports = elementType => {
4545
tsCount += 1;
4646
});
4747
} else statements.push(hook.id.name);
48+
49+
// if (hook.id.name !== undefined){
50+
// statements.push(hook.id.name);
51+
// }
52+
4853
});
4954
}
5055
});
56+
console.log(statements);
5157

5258
// Iterate array and determine getter/setters based on pattern
5359
statements.forEach((el, i) => {
54-
if (el.match(/_use/)) hookState[el] = statements[i + 2];
60+
if (el !== undefined && el.match(/_use/)) hookState[el] = statements[i + 2];
5561
});
5662
});
5763
}

src/backend/helpers.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ export const getHooksNames = (elementType) => {
100100
});
101101
}
102102
});
103-
104-
// Iterate array and determine getter/setters based on pattern
103+
105104
statements.forEach((el, i) => {
106105
if (el.match(/_use/)) hookState[el] = statements[i + 2];
107106
});

src/backend/linkFiber.ts

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import 'core-js';
3636

3737
// const Tree = require('./tree').default;
3838
// const componentActionsRecord = require('./masterState');
39-
39+
import { useGotoRecoilSnapshot, RecoilRoot, useRecoilSnapshot } from 'recoil';
4040
import {
4141
// eslint-disable-next-line @typescript-eslint/no-unused-vars
4242
Snapshot,
@@ -48,6 +48,7 @@ import {
4848
import Tree from './tree';
4949
import componentActionsRecord from './masterState';
5050
import { throttle, getHooksNames } from './helpers';
51+
import ReactDOM from 'react-dom';
5152

5253
declare global {
5354
interface Window {
@@ -58,7 +59,6 @@ declare global {
5859
let doWork = true;
5960
const circularComponentTable = new Set();
6061

61-
// module.exports = (snap, mode) => {
6262
export default (snap: Snapshot, mode: Mode): (() => void) => {
6363
let fiberRoot = null;
6464

@@ -94,9 +94,7 @@ export default (snap: Snapshot, mode: Mode): (() => void) => {
9494
component: memoizedState.queue,
9595
state: memoizedState.memoizedState,
9696
});
97-
//console.log('MEMOIZED PROPS ------>', memoizedProps);
98-
// console.log('MEMOIZEDSTATE QUEUE------>', memoizedState.queue);
99-
// console.log('HOOK STATE ------->', hooksStates);
97+
10098
}
10199
memoizedState =
102100
memoizedState.next !== memoizedState ? memoizedState.next : null;
@@ -155,7 +153,6 @@ export default (snap: Snapshot, mode: Mode): (() => void) => {
155153
}
156154

157155
let hooksIndex;
158-
// RECOIL
159156
let isRecoil = false;
160157

161158
if (window[`$recoilDebugStates`]) {
@@ -170,7 +167,8 @@ export default (snap: Snapshot, mode: Mode): (() => void) => {
170167
// });
171168
atomArray.push(memoizedProps);
172169

173-
//console.log('1st ATOM ARRAY', atomArray);
170+
171+
// console.log('1st ATOM ARRAY', atomArray);
174172

175173
function traverseRecoilHooks(memoizedState: any): HookStates {
176174
const hooksStates: HookStates = [];
@@ -180,17 +178,13 @@ export default (snap: Snapshot, mode: Mode): (() => void) => {
180178
memoizedState.queue.lastRenderedReducer &&
181179
memoizedState.queue.lastRenderedReducer.name === 'basicStateReducer'
182180
) {
183-
// console.log('MEM STATE', memoizedState);
184181
if (Object.entries(memoizedProps).length !== 0) {
185182
hooksStates.push({
186183
component: memoizedState.queue,
187184
state: memoizedProps,
188185
});
189186
}
190187

191-
// console.log('MEMOIZED PROPS ------>', memoizedProps);
192-
// console.log('MEMOIZEDSTATE QUEUE------>', memoizedState.queue);
193-
// console.log('HOOK STATE ------->', hooksStates);
194188
}
195189
memoizedState =
196190
memoizedState.next !== memoizedState ? memoizedState.next : null;
@@ -211,10 +205,10 @@ export default (snap: Snapshot, mode: Mode): (() => void) => {
211205
// which includes the dispatch() function we use to change their state.
212206

213207
const hooksStates = traverseRecoilHooks(memoizedState);
214-
// console.log('HOOK STATE BEFORE LOOPING', hooksStates);
208+
215209
const hooksNames = getHooksNames(elementType.toString());
216210
hooksStates.forEach((state, i) => {
217-
// console.log('STATE IN SAVE NEW LOOP', state);
211+
218212
hooksIndex = componentActionsRecord.saveNew(
219213
state.state,
220214
state.component
@@ -251,7 +245,7 @@ export default (snap: Snapshot, mode: Mode): (() => void) => {
251245
isRecoil === false
252246
) {
253247
if (memoizedState.queue) {
254-
//console.log('Regular Hooks');
248+
255249
// Hooks states are stored as a linked list using memoizedState.next,
256250
// so we must traverse through the list and get the states.
257251
// We then store them along with the corresponding memoizedState.queue,
@@ -278,7 +272,6 @@ export default (snap: Snapshot, mode: Mode): (() => void) => {
278272
}
279273

280274
// This grabs stateless components
281-
282275
if (!componentFound && (tag === 0 || tag === 1 || tag === 2)) {
283276
newState = 'stateless';
284277
}
@@ -336,9 +329,6 @@ export default (snap: Snapshot, mode: Mode): (() => void) => {
336329
snap.tree = createTree(current);
337330
}
338331

339-
// console.log('Fiber', fiberRoot.current);
340-
341-
// console.log('SNAP.TREE->', snap.tree);
342332

343333
sendSnapshot();
344334
}
@@ -364,11 +354,10 @@ export default (snap: Snapshot, mode: Mode): (() => void) => {
364354
const reactInstance = devTools ? devTools.renderers.get(1) : null;
365355
fiberRoot = devTools.getFiberRoots(1).values().next().value;
366356

367-
console.log('FIBER ROOT', fiberRoot.current);
357+
// console.log('FIBER ROOT', fiberRoot.current);
368358

369359
const throttledUpdateSnapshot = throttle(updateSnapShotTree, 70);
370360
document.addEventListener('visibilitychange', onVisibilityChange);
371-
372361
if (reactInstance && reactInstance.version) {
373362
devTools.onCommitFiberRoot = (function (original) {
374363
return function (...args) {

src/backend/recoilidea.js

Whitespace-only changes.

src/backend/timeJump.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export default (origin, mode) => {
5454
);
5555
}
5656

57+
console.log('TARGET', target);
5758
// Check for hooks state and set it with dispatch()
5859
if (target.state && target.state.hooksState) {
5960
target.state.hooksState.forEach((hook) => {
@@ -63,8 +64,7 @@ export default (origin, mode) => {
6364
const hookState = Object.values(hook);
6465
console.log('target', target);
6566
if (hooksComponent && hooksComponent.dispatch) {
66-
console.log('HOOKS COMPONENT', hooksComponent);
67-
console.log('HOOKS STATE of Zero', hookState[0]);
67+
6868
hooksComponent.dispatch(hookState[0]);
6969
}
7070
});

tests/manual-tests/recoilTest

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

tests/manual-tests/todolist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 55d0fbb5098696e662f8a562ed284dcd77fa9055

0 commit comments

Comments
 (0)