Skip to content

Commit 9f391b8

Browse files
Merge pull request #308 from oslabs-beta/main
Merging from OS Labs Beta to Main, ready for chrome webstore
2 parents dc8c119 + 23218d0 commit 9f391b8

18 files changed

+445
-1026
lines changed

src/README.md

+74-56
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Developer README
22

33
## Brief
4+
45
Our mission at Reactime is to maintain and iterate constantly, but never at the expense of future developers.<br />We know how hard it is to quickly get up to speed and onboard in a new codebase.<br />So, here are some helpful pointers to help you hit the ground running. 🏃🏾💨
56

67
## Building from source
@@ -19,131 +20,148 @@ Now you should be able to change Reactime code and see the changes instantly ref
1920
For version Node v16.16.0, please use script 'npm run devlegacy' | 'npm run buildlegacy'</b>
2021

2122
## Quick Tips
23+
2224
- _Before_ beginning development, especially on teams, make sure to configure your linter and code formatting to conform to one unified setting (We recommend [the Airbnb style guide](https://github.com/airbnb/javascript)!) This will make reviewing PRs much more readable and less error-prone.
2325

2426
## File Structure
2527

26-
In the *src* folder, there are three directories we care about: *app*, *backend*, and *extension*.
28+
In the _src_ folder, there are three directories we care about: _app_, _backend_, and _extension_.
29+
2730
```
2831
src/
29-
├── app/ # Frontend code
30-
│   ├── __tests__/ #
31-
│   ├── actions/ # Redux action creators
32-
│   ├── components/ # React components
33-
│   ├── constants/ #
34-
│   ├── containers/ # More React components
35-
│   ├── reducers/ # Redux mechanism for updating state
36-
│   ├── styles/ #
37-
│   ├── index.tsx # Starting point for root App component
38-
│   ├── module.d.ts #
39-
│   └── store.tsx #
32+
├── app/ # Frontend code
33+
│   ├── __tests__/ #
34+
│   ├── actions/ # Redux action creators
35+
│   ├── components/ # React components
36+
│   ├── constants/ #
37+
│   ├── containers/ # More React components
38+
│   ├── reducers/ # Redux mechanism for updating state
39+
│   ├── styles/ #
40+
│   ├── index.tsx # Starting point for root App component
41+
│   ├── module.d.ts #
42+
│   └── store.tsx #
4043
41-
├── backend/ # "Backend" code (injected into target app)
42-
│   │ # Focus especially on linkFiber, timeJump, tree, and helpers
43-
│   ├── __tests__/ #
44-
│   ├── types/ # Typescript interfaces
45-
│   ├── helpers.js #
46-
│   ├── index.ts # Starting point for backend functionality
47-
│   ├── index.d.ts #
48-
│   ├── linkFiber.ts #
49-
│   ├── masterState.js # Component action record interface
50-
│   ├── module.d.ts #
51-
│   ├── package.json #
52-
│   ├── puppeteerServer.js #
53-
│   ├── routes.ts # Interfaces with the browser history stack
54-
│   ├── timeJump.ts # Rerenders DOM based on snapshot from background script
55-
│   └── tree.ts # Custom structure to send to background
44+
├── backend/ # "Backend" code (injected into target app)
45+
│   │ # Focus especially on linkFiber, timeJump, tree, and helpers
46+
│   ├── __tests__/ #
47+
│   ├── controllers/ #
48+
│   ├── createComponentActionsRecord.ts # Update the componentActionsRecord with new bound state-update methods
49+
│   ├── createTree.ts # Construct a tree snapshot from the FiberRoot tree given by ReactFiber.
50+
│   ├── statePropExtractor.ts # Helper functions to extract & format prop, state, and context data
51+
│   ├── throttle.ts #
52+
│   ├── timeJump.ts # Rerenders DOM based on snapshot from background script
53+
│   ├── models/
54+
│   ├── filterConditions.ts #
55+
│   ├── masterState.ts # Component action record interface
56+
│   ├── routes.ts # Interfaces with the browser history stack
57+
│   ├── tree.ts # Custom structure to send to background
58+
│   ├── routers/
59+
│   ├── linkFiber.ts # Check for all requirement to start Reactime and
60+
│   ├── snapShot.ts #
61+
│   ├── types/ # Typescript interfaces
62+
│   ├── index.ts # Starting point for backend functionality
63+
│   ├── index.d.ts # Definitely Type file for Index
64+
│   ├── module.d.ts #
65+
│   ├── package.json #
66+
│   ├── puppeteerServer.js #
5667
57-
├── extension/ # Chrome Extension code
58-
│   ├── build/ # Destination for bundles and manifest.json (Chrome config file)
59-
│ │ #
60-
│   ├── background.js # Chrome Background Script
61-
│   └── contentScript.ts # Chrome Content Script
68+
├── extension/ # Chrome Extension code
69+
│   ├── build/ # Destination for bundles and manifest.json (Chrome config file)
70+
│ │ #
71+
│   ├── background.js # Chrome Background Script
72+
│   └── contentScript.ts # Chrome Content Script
6273
└──
6374
```
6475

65-
1. The *app* folder is responsible for the Single Page Application that you see when you open the chrome dev tools under the Reactime tab.
76+
1. The _app_ folder is responsible for the Single Page Application that you see when you open the chrome dev tools under the Reactime tab.
6677

6778
![FRONTEND DATA FLOW](../assets/frontend-diagram.png)
6879

69-
2. The *backend* folder contains the set of all scripts that we inject into our "target" application via `background.js`
70-
- In Reactime, its main role is to generate data and handle time-jump requests from the background script in our *extension* folder.
80+
2. The _backend_ folder contains the set of all scripts that we inject into our "target" application via `background.js`
81+
- In Reactime, its main role is to generate data and handle time-jump requests from the background script in our _extension_ folder.
7182

7283
![BACKEND DATA FLOW](../assets/backend.png)
7384

74-
3. The *extension* folder is where the `contentScript.js` and `background.js` are located.
75-
- Like regular web apps, Chrome Extensions are event-based. The background script is where one typically monitors for browser triggers (e.g. events like closing a tab, for example). The content script is what allows us to read or write to our target web application, usually as a result of [messages passed](https://developer.chrome.com/extensions/messaging) from the background script.
76-
- These two files help us handle requests both from the web browser and from the Reactime extension itself
77-
85+
3. The _extension_ folder is where the `contentScript.js` and `background.js` are located.
86+
- Like regular web apps, Chrome Extensions are event-based. The background script is where one typically monitors for browser triggers (e.g. events like closing a tab, for example). The content script is what allows us to read or write to our target web application, usually as a result of [messages passed](https://developer.chrome.com/extensions/messaging) from the background script.
87+
- These two files help us handle requests both from the web browser and from the Reactime extension itself
7888

7989
## Diagramming
90+
8091
All the diagrams of data flows are avaliable on [MIRO](https://miro.com/app/board/o9J_lejUqLQ=/)
92+
8193
## Data Flow Architecture
8294

8395
The general flow of data is described in the following steps:
8496

8597
![GENERAL DATA FLOW](../assets/DataFlowDiagram.PNG)
8698

87-
1. When the background bundle is loaded by the browser, it executes a script injection into the dom. (see section on *backend*). This script uses a technique called [throttle](https://medium.com/@bitupon.211/debounce-and-throttle-160affa5457b) to send state data from the app to the content script every specified milliseconds (in our case, this interval is 70ms).
88-
<!-- CHECK LINE 496 IN LINKFIBER.TS -->
99+
1. When the background bundle is loaded by the browser, it executes a script injection into the dom. (see section on _backend_). This script uses a technique called [throttle](https://medium.com/@bitupon.211/debounce-and-throttle-160affa5457b) to send state data from the app to the content script every specified milliseconds (in our case, this interval is 70ms).
89100

101+
2. The content script always listens for messages being passed from the extension's target application. Upon receiving data from the target app, the content script will immediately forward this data to the background script which then updates an object called `tabsObj`. Each time `tabsObj` is updated, its latest version will be passed to Reactime, where it is processed for displaying to the user by the _app_ folder scripts.
90102

91-
2. The content script always listens for messages being passed from the extension's target application. Upon receiving data from the target app, the content script will immediately forward this data to the background script which then updates an object called `tabsObj`. Each time `tabsObj` is updated, its latest version will be passed to Reactime, where it is processed for displaying to the user by the *app* folder scripts.
92-
93-
3. Likewise, when Reactime emits an action due to user interaction -- a "jump" request for example -- a message will be passed from Reactime via the background script to the content script. Then, the content script will pass a message to the target application containing a payload that represents the state the user wants the DOM to reflect or "jump" to.
94-
- One important thing to note here is that this jump action must be dispatched in the target application (i.e. *backend* land), because only there do we have direct access to the DOM.
103+
3. Likewise, when Reactime emits an action due to user interaction -- a "jump" request for example -- a message will be passed from Reactime via the background script to the content script. Then, the content script will pass a message to the target application containing a payload that represents the state the user wants the DOM to reflect or "jump" to.
104+
- One important thing to note here is that this jump action must be dispatched in the target application (i.e. _backend_ land), because only there do we have direct access to the DOM.
95105

96106
## Console.log
97107

98108
Navigation between different console.log panels can be confusing when running Reactime. We created a short instruction where you can find the results for your console.log
99109

100110
### <b> /src/extension </b>
111+
101112
Console.logs from the Extension folder you can find here:
113+
102114
- Chrome Extension (Developer mode)
103115
- Background page
104116

105117
![extension](../assets/extension-console.gif)
106118

107119
### <b> /src/app </b>
120+
108121
Console.logs from the App folder you can find here:
122+
109123
- Chrome Browser
110124
- Inspect
111125

112126
![frontend](../assets/console.gif)
113127

114128
### <b> /src/backend </b>
129+
115130
Console.logs from the App folder you can find here:
131+
116132
- Open the Reactime extension in Chrome
117133
- Click "Inspect" on Reactime
118134

119135
![backend](../assets/reactime-console.gif)
120136

121137
## Chrome Developer Resources
138+
122139
Still unsure about what content scripts and background scripts do for Reactime, or for a chrome extensions in general?
123-
- The implementation details [can be found](./extension/background.js) [in the source files](./extension/contentScript.ts) themselves.
124-
- We also encourage you to dive into [the official Chrome Developer Docs](https://developer.chrome.com/home).
125140

126-
Some relevant sections are reproduced below:
141+
- The implementation details [can be found](./extension/background.js) [in the source files](./extension/contentScript.ts) themselves.
142+
- We also encourage you to dive into [the official Chrome Developer Docs](https://developer.chrome.com/home).
143+
144+
Some relevant sections are reproduced below:
127145

128146
> Content scripts are files that run in the context of web pages.
129147
>
130148
> 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 back** to their parent extension. ([Source](https://developer.chrome.com/extensions/content_scripts))
131149
132-
- One helpful way to remember a content script's role in the Chrome ecosystem is to think: a *content* script is used to read and modify a target web page's rendered *content*.
150+
- One helpful way to remember a content script's role in the Chrome ecosystem is to think: a _content_ script is used to read and modify a target web page's rendered _content_.
133151

134-
>A background page is loaded when it is needed, and unloaded when it goes idle.
152+
> A background page is loaded when it is needed, and unloaded when it goes idle.
135153
>
136154
> Some examples of events include:
137-
>The extension is first installed or updated to a new version.
138-
>The background page was listening for an event, and the event is dispatched.
139-
>A content script or other extension sends a message.
140-
>Another view in the extension, such as a popup, calls `runtime.getBackgroundPage`.
155+
> The extension is first installed or updated to a new version.
156+
> The background page was listening for an event, and the event is dispatched.
157+
> A content script or other extension sends a message.
158+
> Another view in the extension, such as a popup, calls `runtime.getBackgroundPage`.
141159
>
142-
>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.
160+
> 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.
143161
>
144162
> 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))
145163
146164
- You can think of background scripts serving a purpose analogous to that of a **server** in the client/server paradigm. Much like a server, our `background.js` listens constantly for messages (i.e. requests) from two main places:
147165
1. The content script
148-
2. The chrome extension "front-end" **(*NOT* the interface of the browser, this is an important distinction.)**
166+
2. The chrome extension "front-end" **(_NOT_ the interface of the browser, this is an important distinction.)**
149167
- In other words, a background script works as a sort of middleman, directly maintaining connection with its parent extension, and acting as a proxy enabling communication between it and the content script.

src/backend/__tests__/linkFiber.test.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@ import {
1212
mixComponents,
1313
mixPayload,
1414
} from './ignore/stateComponents-testcases';
15-
import { Snapshot, Status, FiberRoot } from '../types/backendTypes';
15+
import { Status, FiberRoot } from '../types/backendTypes';
1616
import Tree from '../models/tree';
1717
import { DevTools } from '../types/linkFiberTypes';
1818
import { JSDOM } from 'jsdom';
1919
import path from 'path';
2020
import fs from 'fs';
2121

2222
describe('linkFiber', () => {
23-
let snapshot: Snapshot;
2423
let mode: Status;
2524
let linkFiber: () => Promise<void>;
2625
let linkFiberDelayed: (resolve: any) => NodeJS.Timeout;
@@ -46,19 +45,14 @@ describe('linkFiber', () => {
4645
});
4746

4847
beforeEach(() => {
49-
// Create snapshot and mode objects
50-
snapshot = {
51-
tree: new Tree('root', 'root'),
52-
};
5348
mode = {
5449
jumping: false,
55-
paused: false,
5650
};
5751
// Initialize Fiber Root:
5852
fiberRoot = { current: root };
5953

6054
// Initialize linkFiber
61-
linkFiber = linkFiberInitialization(snapshot, mode);
55+
linkFiber = linkFiberInitialization(mode);
6256
// Since linkFiber invoke a throttle function that get delay for 70 ms, between each test, linkFiber need to be delayed for 75 ms to ensure no overlapping async calls.
6357
linkFiberDelayed = (resolve) => setTimeout(async () => resolve(await linkFiber()), DELAY);
6458

src/backend/__tests__/masterTree.test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import createTree from '../controllers/createTree/createTree';
1+
import createTree from '../controllers/createTree';
22
import componentActionsRecord from '../models/masterState';
3-
import createComponentActionsRecord from '../controllers/createTree/createComponentActionsRecord';
3+
import createComponentActionsRecord from '../controllers/createComponentActionsRecord';
44
import {
55
Fiber,
66
FunctionComponent,

0 commit comments

Comments
 (0)