Skip to content

Commit 1fc0413

Browse files
committed
removed need for npm package by injecting backend script into target page; refactored code into ES6 style imports; started refactor of tree to fix hierarchy
1 parent 37a41ca commit 1fc0413

File tree

9 files changed

+167
-110
lines changed

9 files changed

+167
-110
lines changed

dev-reactime/index.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
import 'core-js';
66
import 'regenerator-runtime/runtime';
7+
import linkFiberStart from './linkFiber';
8+
import timeJumpStart from './timeJump';
79

810
// * State snapshot object initialized here
911
const snapShot = {
@@ -17,9 +19,14 @@ const mode = {
1719
locked: false,
1820
};
1921

20-
const linkFiber = require('./linkFiber')(snapShot, mode);
21-
console.log('import timeJump in index.js:', JSON.parse(JSON.stringify(snapShot)));
22-
const timeJump = require('./timeJump')(snapShot, mode);
22+
// const linkFiber = require('./linkFiber')(snapShot, mode);
23+
// console.log('import timeJump in index.js:', JSON.parse(JSON.stringify(snapShot)));
24+
// const timeJump = require('./timeJump')(snapShot, mode);
25+
26+
27+
28+
const linkFiber = linkFiberStart(snapShot, mode);
29+
const timeJump = timeJumpStart(snapShot, mode);
2330

2431

2532
function getRouteURL(node) {
@@ -57,5 +64,8 @@ window.addEventListener('message', ({ data: { action, payload } }) => {
5764
}
5865
});
5966

67+
console.log('index.js: loading reactime');
68+
linkFiber();
69+
6070
// module.exports = linkFiber;
61-
export default linkFiber;
71+
// export default linkFiber;

dev-reactime/linkFiber.js

Lines changed: 74 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,41 @@
4444
/* eslint-disable no-use-before-define */
4545
/* eslint-disable no-param-reassign */
4646

47-
const Tree = require('./tree');
48-
const componentActionsRecord = require('./masterState');
47+
// const Tree = require('./tree').default;
48+
// const componentActionsRecord = require('./masterState');\
4949

50-
module.exports = (snap, mode) => {
50+
import Tree from './tree';
51+
import componentActionsRecord from './masterState';
52+
53+
const circularComponentTable = new Map();
54+
55+
// module.exports = (snap, mode) => {
56+
export default (snap, mode) => {
5157
let fiberRoot = null;
5258

53-
async function sendSnapshot() {
59+
function sendSnapshot() {
5460
// Don't send messages while jumping or while paused
61+
circularComponentTable.clear();
62+
console.log('sending snapshot');
5563
if (mode.jumping || mode.paused) return;
5664
console.log('PAYLOAD: before cleaning', snap.tree);
65+
66+
if (!snap.tree) {
67+
console.log('snapshot empty, sending root');
68+
snap.tree = new Tree('root');
69+
}
5770
const payload = snap.tree.cleanTreeCopy();// snap.tree.getCopy();
71+
5872
console.log('PAYLOAD: after cleaning', payload);
59-
try {
60-
await window.postMessage({
73+
//try {
74+
//await window.postMessage({
75+
window.postMessage({
6176
action: 'recordSnap',
6277
payload,
6378
});
64-
} catch (e) {
65-
console.log('failed to send postMessage:', e);
66-
}
79+
// } catch (e) {
80+
// console.log('failed to send postMessage:', e);
81+
// }
6782
}
6883

6984
// Carlos: Injects instrumentation to update our state tree every time
@@ -75,13 +90,11 @@ module.exports = (snap, mode) => {
7590
// prevents useEffect from crashing on load
7691
// if (memoizedState.next.queue === null) { // prevents double pushing snapshot updates
7792
if (memoizedState.memoizedState) {
78-
console.log('memoizedState in traverseHooks is:', memoizedState);
7993
hooksStates.push({
8094
component: memoizedState.queue,
8195
state: memoizedState.memoizedState,
8296
});
8397
}
84-
// console.log('GOT STATE', memoizedState.memoizedState);
8598
memoizedState = memoizedState.next !== memoizedState
8699
? memoizedState.next : null;
87100
}
@@ -90,8 +103,9 @@ module.exports = (snap, mode) => {
90103

91104
// Carlos: This runs after EVERY Fiber commit. It creates a new snapshot,
92105
//
93-
function createTree(currentFiber, tree = new Tree('root')) {
106+
function createTree(currentFiber, tree = new Tree('root'), fromSibling = false) {
94107
// Base case: child or sibling pointed to null
108+
console.log('linkFiber.js: creating tree');
95109
if (!currentFiber) return null;
96110
if (!tree) return tree;
97111

@@ -115,11 +129,10 @@ module.exports = (snap, mode) => {
115129
let componentFound = false;
116130

117131
// Check if node is a stateful setState component
118-
if (stateNode && stateNode.state && (tag === 0 || tag === 1)) {
119-
console.log('in create tree if')
120-
console.log('this is currentFiber from createTree', currentFiber)
132+
if (stateNode && stateNode.state && (tag === 0 || tag === 1 || tag === 2)) {
121133
// Save component's state and setState() function to our record for future
122134
// time-travel state changing. Add record index to snapshot so we can retrieve.
135+
console.log('linkFiber.js: found stateNode component');
123136
componentData.index = componentActionsRecord.saveNew(stateNode.state, stateNode);
124137
newState = stateNode.state;
125138
componentFound = true;
@@ -128,9 +141,8 @@ module.exports = (snap, mode) => {
128141
// Check if node is a hooks useState function
129142
let hooksIndex;
130143
if (memoizedState && (tag === 0 || tag === 1 || tag === 10)) {
131-
console.log('in create tree if')
132-
console.log('this is currentFiber from createTree', currentFiber)
133144
if (memoizedState.queue) {
145+
console.log('linkFiber.js: found hooks component');
134146
// Hooks states are stored as a linked list using memoizedState.next,
135147
// so we must traverse through the list and get the states.
136148
// We then store them along with the corresponding memoizedState.queue,
@@ -164,103 +176,80 @@ module.exports = (snap, mode) => {
164176
treeBaseDuration,
165177
};
166178

179+
console.log('linkFiber.js: adding new state to tree:', newState);
167180
if (componentFound) {
168-
tree.addChild(newState, elementType.name ? elementType.name : elementType, componentData);
181+
console.log('componentFound, calling tree.addChild');
182+
if (fromSibling) {
183+
tree.addSibling(newState, elementType.name ? elementType.name : elementType, componentData);
184+
} else {
185+
tree.addChild(newState, elementType.name ? elementType.name : elementType, componentData);
186+
}
169187
} else if (newState === 'stateless') {
170-
tree.addChild(newState, elementType.name ? elementType.name : elementType, componentData);
188+
if (fromSibling) {
189+
tree.addSibling(newState, elementType.name ? elementType.name : elementType, componentData);
190+
} else {
191+
tree.addChild(newState, elementType.name ? elementType.name : elementType, componentData);
192+
}
171193
}
172194

173195
// Recurse on children
174-
if (child) {
196+
197+
if (child) { // && !circularComponentTable.has(child)) {
175198
// If this node had state we appended to the children array,
176199
// so attach children to the newly appended child.
177200
// Otherwise, attach children to this same node.
201+
console.log('going into child');
202+
// circularComponentTable.set(child, true);
178203
if (tree.children.length > 0) {
179204
createTree(child, tree.children[tree.children.length - 1]);
180205
} else {
181206
createTree(child, tree);
182207
}
183208
}
184209
// Recurse on siblings
185-
if (sibling) createTree(sibling, tree);
210+
if (sibling) { // && !circularComponentTable.has(sibling)) {
211+
console.log('going into sibling');
212+
// circularComponentTable.set(sibling, true);
213+
createTree(sibling, tree, true);
214+
}
186215

216+
console.log('linkFiber.js: processed children and sibling, returning tree');
187217
return tree;
188218
}
189219

190-
191-
// function createUnfilteredTree(curFiber, parentNode) {
192-
// // on call from updateSnapShot, no parentNode provided, so create a root node
193-
// if(! parentNode) parentNode = new Tree('root');
194-
195-
// // Base case: parentNode's child or sibling pointed to null
196-
// if (!curFiber) return parentNode;
197-
198-
// let newChildNode = null;
199-
200-
// // If stateful, add to parentNode's children array, then inject new setState into fiber node
201-
// if (curFiber.stateNode && curFiber.stateNode.state) {
202-
// newChildNode = parentNode.appendChild(curFiber.stateNode);
203-
// // changeSetState(curFiber.stateNode);
204-
// newChildNode.isStateful = true;
205-
// }
206-
// else {
207-
208-
// }
209-
210-
// // Recurse to sibling; siblings that have state should be added to our parentNode
211-
// createTree(curFiber.sibling, parentNode);
212-
213-
// // Recurse to child; If this fiber was stateful, then we added a newChildNode here, and we want
214-
// // to attach further children to that. If this fiber wasn't stateful, we want to attach any
215-
// // children to our existing parentNode.
216-
// createTree(curFiber.child, newChildNode || parentNode);
217-
218-
// return parentNode;
219-
// }
220-
221-
222-
// ! BUG: skips 1st hook click
223220
function updateSnapShotTree() {
224-
/* let current;
225-
// If concurrent mode, grab current.child
226-
if (concurrent) {
227-
// we need a way to wait for current child to populate
228-
const promise = new Promise((resolve, reject) => {
229-
setTimeout(() => resolve(fiberRoot.current.child), 400);
230-
});
231-
current = await promise;
232-
current = fiberRoot.current.child;
233-
} else {
234-
current = fiberRoot.current;
235-
} */
236-
const { current } = fiberRoot; // Carlos: get rid of concurrent mode for now
237-
238-
// console.log('FIBER COMMITTED, new fiber is:', util.inspect(current, false, 4));
239-
// fs.appendFile('fiberlog.txt', util.inspect(current, false, 10));
240-
snap.tree = createTree(current); // Carlos: pass new hooks state here?
221+
console.log('linkFiber.js, updateSnapshotTree(), checking if we have fiberRoot to update');
222+
if (fiberRoot) {
223+
console.log('linkFiber.js, updateSnapshotTree(), fiberRoot found, updating snapshot', snap.tree);
224+
const { current } = fiberRoot;
225+
snap.tree = createTree(current);
226+
console.log('linkFiber.js, updateSnapshotTree(), completed snapshot', snap.tree);
227+
}
241228
}
242229

243-
return async container => {
244-
// Point fiberRoot to FiberRootNode
245-
if (container._internalRoot) {
246-
fiberRoot = container._internalRoot;
247-
} else {
248-
const {
249-
_reactRootContainer: { _internalRoot },
250-
_reactRootContainer,
251-
} = container;
252-
// Only assign internal root if it actually exists
253-
fiberRoot = _internalRoot || _reactRootContainer;
254-
}
230+
return async () => {
231+
// if (container._internalRoot) {
232+
// fiberRoot = container._internalRoot;
233+
// } else {
234+
// const {
235+
// _reactRootContainer: { _internalRoot },
236+
// _reactRootContainer,
237+
// } = container;
238+
// // Only assign internal root if it actually exists
239+
// fiberRoot = _internalRoot || _reactRootContainer;
240+
// }
241+
255242
const devTools = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
256243
const reactInstance = devTools ? devTools.renderers.get(1) : null;
244+
console.log('devTools:', devTools);
257245

258246
if (reactInstance && reactInstance.version) {
259247
devTools.onCommitFiberRoot = (function (original) {
260248
return function (...args) {
261249
fiberRoot = args[1];
262-
console.log('this is fiberRoot', fiberRoot)
250+
console.log('this is fiberRoot', fiberRoot);
263251
updateSnapShotTree();
252+
console.log('snap.tree is: ', snap.tree);
264253
sendSnapshot();
265254
return original(...args);
266255
};
@@ -271,6 +260,7 @@ module.exports = (snap, mode) => {
271260
// This message is sent from contentScript.js in chrome extension bundles
272261
window.addEventListener('message', ({ data: { action } }) => {
273262
if (action === 'contentScriptStarted') {
263+
console.log('content script started received at linkFiber.js')
274264
sendSnapshot();
275265
}
276266
});

dev-reactime/masterState.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
const componentActionsRecord = {};
66
let index = 0;
77

8-
module.exports = {
8+
// module.exports = {
9+
export default {
910
saveNew: (state, component) => {
1011
componentActionsRecord[index] = { state, component };
1112
index++;

dev-reactime/timeJump.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111

1212
/* eslint-disable no-param-reassign */
1313

14-
const componentActionsRecord = require('./masterState');
14+
// const componentActionsRecord = require('./masterState');
15+
import componentActionsRecord from './masterState';
1516

1617
// Carlos: origin is latest snapshot, linking to the fiber,
1718
// so changes to origin change app
18-
module.exports = (origin, mode) => {
19+
// module.exports = (origin, mode) => {
20+
export default (origin, mode) => {
1921
// Recursively change state of tree
2022
// Carlos: target is past state we are travelling to
2123

dev-reactime/tree.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,47 @@ class Tree {
1818
constructor(state, name = 'nameless', componentData = {}) {
1919
this.state = state === 'root' ? 'root' : JSON.parse(JSON.stringify(state));
2020
this.name = name;
21-
this.componentData = JSON.parse(JSON.stringify(componentData));
21+
this.componentData = componentData ? JSON.parse(JSON.stringify(componentData)) : {};
2222
this.children = [];
23+
this.parent = null; // ref to parent so we can add siblings
2324
}
2425

25-
addChild(state, name = this.name, componentData = this.componentData) {
26+
addChild(state, name, componentData) {
27+
console.log('tree.js: in addChild');
2628
this.children.push(new Tree(state, name, componentData));
29+
this.children[this.children.length - 1].parent = this;
30+
}
31+
32+
addSibling(state, name, componentData) {
33+
console.log('tree.js: in addChild');
34+
this.parent.children.push(new Tree(state, name, componentData));
35+
this.parent.children[this.children.length - 1].parent = this;
2736
}
2837

2938
cleanTreeCopy() {
30-
const copy = new Tree(this.state, this.name, this.componentData);
31-
let newChild;
32-
copy.children = this.children.map(child => {
33-
newChild = new Tree(child.state, child.name, child.componentData);
34-
newChild.children = child.children;
35-
return scrubUnserializableMembers(newChild);
36-
});
39+
// copies present node
40+
let copy = new Tree(this.state, this.name, this.componentData);
41+
copy = scrubUnserializableMembers(copy);
42+
copy.children = this.children;
43+
44+
// creates copy of each child of the present node
45+
copy.children = this.children.map(child => child.cleanTreeCopy());
46+
47+
// copy.children = this.children.map(child => {
48+
// newChild = new Tree(child.state, child.name, child.componentData);
49+
// newChild.children = child.children;
50+
// return scrubUnserializableMembers(newChild);
51+
// });
52+
53+
/*
3754
if (copy.children.length > 0) {
3855
copy.children.forEach(child => {
3956
if (child !== copy.children) {
4057
child = child.cleanTreeCopy();
41-
} else {
42-
child = null;
4358
}
59+
return null;
4460
});
45-
}
61+
} */
4662
return copy;
4763
}
4864

@@ -67,4 +83,4 @@ class Tree {
6783
}
6884
}
6985

70-
module.exports = Tree;
86+
export default Tree;

0 commit comments

Comments
 (0)