@lukekaalim/act-insight 0.0.2-alpha.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/InsightApp.ts +364 -169
- package/ScheduleControls.ts +61 -0
- package/TreeViewer.module.css +10 -1
- package/TreeViewer.ts +34 -21
- package/Virtual.ts +64 -0
- package/index.ts +4 -1
- package/lookup.ts +185 -0
- package/package.json +4 -4
- package/utils.ts +59 -47
- package/vite.config.ts +4 -4
- package/CommitViewer.module.css +0 -5
- package/CommitViewer.ts +0 -104
- package/ThreadControls.ts +0 -22
- package/ThreadViewer.module.css +0 -5
- package/ThreadViewer.ts +0 -185
- package/debug.ts +0 -80
- package/devtool_page.ts +0 -0
- package/devtool_panel.ts +0 -0
- package/extension_main.ts +0 -0
- package/insight.test.ts +0 -29
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @lukekaalim/act-insight
|
|
2
2
|
|
|
3
|
+
## 1.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bcbd299: SSR API for @lukekaalim/act-web
|
|
8
|
+
- beec21c: Fixed Web text element rehydration, remove nodejs dependencies from dehydration
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies [bcbd299]
|
|
13
|
+
- Updated dependencies [beec21c]
|
|
14
|
+
- @lukekaalim/act-web@5.0.0
|
|
15
|
+
- @lukekaalim/act-recon@3.1.0
|
|
16
|
+
- @lukekaalim/act@4.1.0
|
|
17
|
+
- @lukekaalim/act-debug@1.0.1
|
|
18
|
+
|
|
19
|
+
## 1.0.0
|
|
20
|
+
|
|
21
|
+
### Major Changes
|
|
22
|
+
|
|
23
|
+
- afd247e: Another major refactor! So everything is broken. Good luck!
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [6658c01]
|
|
28
|
+
- Updated dependencies [bd0a076]
|
|
29
|
+
- Updated dependencies [fdf1557]
|
|
30
|
+
- Updated dependencies [7597a8f]
|
|
31
|
+
- Updated dependencies [ccb3900]
|
|
32
|
+
- Updated dependencies [afd247e]
|
|
33
|
+
- Updated dependencies [2984273]
|
|
34
|
+
- Updated dependencies [b3f6c49]
|
|
35
|
+
- Updated dependencies [c5e8775]
|
|
36
|
+
- @lukekaalim/act-web@4.0.0
|
|
37
|
+
- @lukekaalim/act-recon@3.0.0
|
|
38
|
+
- @lukekaalim/act@4.0.0
|
|
39
|
+
- @lukekaalim/act-debug@1.0.0
|
|
40
|
+
|
|
3
41
|
## 0.0.2-alpha.6
|
|
4
42
|
|
|
5
43
|
### Patch Changes
|
package/InsightApp.ts
CHANGED
|
@@ -1,209 +1,404 @@
|
|
|
1
|
-
import { Component,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { Component, h, useEffect, useMemo, useRef, useState } from '@lukekaalim/act';
|
|
2
|
+
import { CommitDetailsReport, CommitReport, DeltaReport, ReconcilerDebugController, ReconcilerDebugEventBus, ThreadReport, updateTreeReport, ValueReport, WorkTaskReport } from '@lukekaalim/act-debug';
|
|
3
|
+
import { CommitID } from '@lukekaalim/act-recon';
|
|
5
4
|
import { CommitPreview, TreeViewer } from './TreeViewer';
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import classes from './InsightApp.module.css';
|
|
11
|
-
import { InsightMode } from './mode';
|
|
12
|
-
import { MenuBar } from './MenuBar';
|
|
13
|
-
import { ThreadViewer } from './ThreadViewer';
|
|
14
|
-
import { DebuggerServer } from '@lukekaalim/act-debug';
|
|
15
|
-
import { CommitReport, CommitStateReport, TreeReport, updateTreeReport } from '@lukekaalim/act-debug/report';
|
|
5
|
+
import { ScheduleControls } from './ScheduleControls';
|
|
6
|
+
import { CommitLookupCache, ThreadLookupCache } from './lookup';
|
|
7
|
+
import { Virtual1D } from './Virtual';
|
|
8
|
+
import { CommitAttributeTag } from './AttributeTag';
|
|
16
9
|
|
|
17
10
|
export type InsightAppProps = {
|
|
18
|
-
|
|
11
|
+
controller: ReconcilerDebugController,
|
|
12
|
+
bus: ReconcilerDebugEventBus,
|
|
13
|
+
|
|
14
|
+
document: Document,
|
|
15
|
+
|
|
16
|
+
onReady(): void,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type InsightAppState = {
|
|
20
|
+
breakOnAfterUpdate: boolean,
|
|
21
|
+
breakOnBeforeUpdate: boolean,
|
|
22
|
+
|
|
23
|
+
commitBreakpoints: Set<CommitID>,
|
|
24
|
+
|
|
25
|
+
paused: boolean,
|
|
19
26
|
}
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const [
|
|
28
|
+
const INSIGHT_SETTINGS_LOCALSTORAGE_KEY = `INSIGHT_SETTINGS`;
|
|
29
|
+
|
|
30
|
+
export const InsightApp: Component<InsightAppProps> = ({ onReady, controller, bus, document = window.document }) => {
|
|
31
|
+
const [c, setRenderCounter] = useState(0);
|
|
32
|
+
|
|
33
|
+
const storedState = useMemo(() => {
|
|
34
|
+
const settings = window.localStorage.getItem(INSIGHT_SETTINGS_LOCALSTORAGE_KEY)
|
|
35
|
+
if (!settings)
|
|
36
|
+
return;
|
|
37
|
+
return JSON.parse(settings) as { breakOnAfterUpdate: boolean, breakOnBeforeUpdate: boolean };
|
|
38
|
+
}, [])
|
|
25
39
|
|
|
40
|
+
const [insightState, setInsightState] = useState<InsightAppState>({
|
|
41
|
+
commitBreakpoints: new Set(),
|
|
42
|
+
breakOnAfterUpdate: storedState ? storedState.breakOnAfterUpdate : false,
|
|
43
|
+
breakOnBeforeUpdate: storedState ? storedState.breakOnBeforeUpdate : false,
|
|
44
|
+
paused: false,
|
|
45
|
+
});
|
|
26
46
|
useEffect(() => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
setCommitState(event.report);
|
|
41
|
-
setCommitId(event.commitId);
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
server.ready();
|
|
46
|
-
return;
|
|
47
|
-
}, [server])
|
|
47
|
+
window.localStorage.setItem(INSIGHT_SETTINGS_LOCALSTORAGE_KEY, JSON.stringify({
|
|
48
|
+
breakOnAfterUpdate: insightState.breakOnAfterUpdate,
|
|
49
|
+
breakOnBeforeUpdate: insightState.breakOnBeforeUpdate,
|
|
50
|
+
}))
|
|
51
|
+
}, [insightState])
|
|
52
|
+
|
|
53
|
+
const commitCache = useRef(() => new CommitLookupCache()).current;
|
|
54
|
+
const deltaCache = useRef(() => new ThreadLookupCache(commitCache)).current;
|
|
55
|
+
|
|
56
|
+
useMemo(() => {
|
|
57
|
+
commitCache.setTree(controller.getTree())
|
|
58
|
+
deltaCache.reset();
|
|
59
|
+
}, [])
|
|
48
60
|
|
|
49
61
|
useEffect(() => {
|
|
50
|
-
|
|
51
|
-
server.commitState(commitId);
|
|
52
|
-
}, [tree, commitId])
|
|
62
|
+
console.log('[Insight] Populate Cache')
|
|
53
63
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
};
|
|
64
|
+
bus.externalUpdate = () => {
|
|
65
|
+
const delta = controller.getDelta();
|
|
66
|
+
const thread = controller.getThread();
|
|
58
67
|
|
|
59
|
-
|
|
60
|
-
}
|
|
68
|
+
commitCache.setTree(controller.getTree())
|
|
61
69
|
|
|
62
|
-
|
|
70
|
+
deltaCache.ingestDelta(delta);
|
|
71
|
+
deltaCache.ingestThread(thread);
|
|
72
|
+
setRenderCounter(c => c + 1);
|
|
73
|
+
}
|
|
63
74
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
75
|
+
bus.onThreadDone = (thread, delta) => {
|
|
76
|
+
console.log('[Insight] ThreadDone')
|
|
77
|
+
commitCache.ingest(delta);
|
|
78
|
+
deltaCache.ingestDelta(delta);
|
|
79
|
+
deltaCache.ingestThread(thread);
|
|
80
|
+
deltaCache.prevTask = null;
|
|
81
|
+
setRenderCounter(c => c + 1);
|
|
70
82
|
|
|
71
|
-
|
|
72
|
-
|
|
83
|
+
for (const subscriber of cacheSubscribers) {
|
|
84
|
+
subscriber();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
bus.thread.onQueue = (reason) => {
|
|
88
|
+
console.log('[Insight] OnQueue')
|
|
89
|
+
const thread = controller.getThread();
|
|
90
|
+
|
|
91
|
+
if (thread.reasons.length === 1) {
|
|
92
|
+
if (insightState.breakOnBeforeUpdate)
|
|
93
|
+
controller.scheduler.intercept = true;
|
|
73
94
|
|
|
74
|
-
|
|
95
|
+
commitCache.setTree(controller.getTree())
|
|
96
|
+
|
|
97
|
+
deltaCache.reset();
|
|
98
|
+
deltaCache.ingestThread(thread);
|
|
99
|
+
setRenderCounter(c => c + 1);
|
|
75
100
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
101
|
+
for (const subscriber of cacheSubscribers) {
|
|
102
|
+
subscriber();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
bus.thread.onWork = (prevTask, nextTask, isDone) => {
|
|
79
107
|
|
|
80
|
-
|
|
108
|
+
if (insightState.breakOnAfterUpdate && isDone) {
|
|
109
|
+
controller.scheduler.intercept = true;
|
|
110
|
+
}
|
|
111
|
+
if (nextTask && insightState.commitBreakpoints.has(nextTask.id)) {
|
|
112
|
+
controller.scheduler.intercept = true;
|
|
113
|
+
}
|
|
81
114
|
|
|
82
|
-
|
|
83
|
-
|
|
115
|
+
if (controller.scheduler.intercept) {
|
|
116
|
+
const thread = controller.getThread();
|
|
117
|
+
const delta = controller.getDelta();
|
|
118
|
+
|
|
119
|
+
deltaCache.ingestDelta(delta);
|
|
120
|
+
deltaCache.ingestThread(thread);
|
|
121
|
+
setRenderCounter(c => c + 1);
|
|
84
122
|
|
|
85
|
-
|
|
86
|
-
|
|
123
|
+
for (const subscriber of cacheSubscribers) {
|
|
124
|
+
subscriber();
|
|
125
|
+
}
|
|
87
126
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (currentThread)
|
|
93
|
-
setCurrentThread(WorkThread.clone(currentThread));
|
|
94
|
-
else
|
|
95
|
-
setCurrentThread(null);
|
|
96
|
-
}, 100, { leading: true, trailing: true, maxWait: 100 });
|
|
97
|
-
}, []);
|
|
127
|
+
if (prevTask)
|
|
128
|
+
deltaCache.prevTask = prevTask;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
98
131
|
|
|
99
|
-
|
|
132
|
+
onReady();
|
|
133
|
+
}, [controller, bus, insightState]);
|
|
134
|
+
|
|
135
|
+
const cacheSubscribers = useRef<Set<() => void>>(new Set()).current;
|
|
136
|
+
|
|
137
|
+
const scrollToCommitIndex = useMemo(() => {
|
|
138
|
+
return (index: number) => {
|
|
139
|
+
if (!viewportRef.current)
|
|
140
|
+
return;
|
|
141
|
+
const viewPortRect = viewportRef.current.getBoundingClientRect();
|
|
142
|
+
if (index) {
|
|
143
|
+
viewportRef.current.scrollTo({
|
|
144
|
+
top: (index * 33) - (viewPortRect.height / 2),
|
|
145
|
+
behavior: 'smooth'
|
|
146
|
+
})
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}, []);
|
|
100
151
|
|
|
101
152
|
useEffect(() => {
|
|
153
|
+
const { nextTask, prevTask } = deltaCache;
|
|
102
154
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
setTree(reconciler.tree);
|
|
106
|
-
updateThread();
|
|
107
|
-
});
|
|
155
|
+
const task = nextTask || prevTask;
|
|
156
|
+
const index = task && commits.findIndex(c => (nextTask && c.id === nextTask.id) || (prevTask && prevTask.id === c.id));
|
|
108
157
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
158
|
+
if (index && index !== -1) {
|
|
159
|
+
scrollToCommitIndex(index);
|
|
160
|
+
}
|
|
161
|
+
}, [deltaCache.prevTask, deltaCache.nextTask, scrollToCommitIndex])
|
|
162
|
+
|
|
163
|
+
const renderCommit = useMemo(() => (commitId: CommitID) => {
|
|
164
|
+
return h(CommitComponent, { commitId })
|
|
165
|
+
}, []);
|
|
166
|
+
|
|
167
|
+
const CommitComponent = useMemo((): Component<{ commitId: CommitID }> => ({ commitId }) => {
|
|
168
|
+
const [c, setRenderCounter] = useState(0);
|
|
169
|
+
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
const subscription = () => {
|
|
172
|
+
const commit = deltaCache.all.get(commitId);
|
|
173
|
+
const originalCommit = commitCache.map.get(commitId);
|
|
174
|
+
|
|
175
|
+
const inTaskList = deltaCache.allTasks.has(commitId);
|
|
176
|
+
|
|
177
|
+
if (commit !== originalCommit || inTaskList || (deltaCache.prevTask && deltaCache.prevTask.id === commitId))
|
|
178
|
+
setRenderCounter(c => c + 1);
|
|
179
|
+
}
|
|
180
|
+
cacheSubscribers.add(subscription);
|
|
181
|
+
subscription();
|
|
182
|
+
|
|
183
|
+
return () => {
|
|
184
|
+
console.log(`[Commit] Cleaning up ${commitId}`)
|
|
185
|
+
cacheSubscribers.delete(subscription);
|
|
186
|
+
}
|
|
187
|
+
}, [commitId])
|
|
188
|
+
|
|
189
|
+
const commit = deltaCache.all.get(commitId) || null;
|
|
190
|
+
if (!commit)
|
|
191
|
+
return (console.warn(`[Commit] Commit ${commitId} not found in delta cache`), null);
|
|
192
|
+
|
|
193
|
+
const color =
|
|
194
|
+
(deltaCache.nextTask && deltaCache.nextTask.id === commit.id) ? '#e1d600ff'
|
|
195
|
+
: deltaCache.targets.has(commit.id) ? '#db55e7ff'
|
|
196
|
+
: deltaCache.allTasks.has(commit.id) ? '#ea931aff'
|
|
197
|
+
: deltaCache.created.has(commit.id) ? (deltaCache.prevTask && deltaCache.prevTask.id === commit.id ? '#4bc847ff' : '#21a51cff')
|
|
198
|
+
: deltaCache.removed.has(commit.id) ? '#f25252ff'
|
|
199
|
+
: deltaCache.updated.has(commit.id) ? '#1ab9eaff'
|
|
200
|
+
: deltaCache.visited.has(commit.id) ? '#6f6f97ff'
|
|
201
|
+
: '#cacaca';
|
|
113
202
|
|
|
203
|
+
if (!commit)
|
|
204
|
+
return (console.log(`[Commit] ${commitId} not ready yet??`), null);
|
|
114
205
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
206
|
+
return useMemo(() => h(CommitPreview, { commit, renderCommit, color, onClick: () => setSelectedCommitId(commit.id) }), [
|
|
207
|
+
commit.version,
|
|
208
|
+
color,
|
|
209
|
+
])
|
|
119
210
|
}, [])
|
|
120
211
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return () => clearInterval(id);
|
|
127
|
-
}
|
|
128
|
-
}, [autoWork, reconciler])
|
|
212
|
+
const reload = () => {
|
|
213
|
+
commitCache.setTree(controller.getTree())
|
|
214
|
+
deltaCache.reset();
|
|
215
|
+
deltaCache.ingestDelta(controller.getDelta());
|
|
216
|
+
deltaCache.ingestThread(controller.getThread());
|
|
129
217
|
|
|
130
|
-
|
|
131
|
-
setPendingWork(false);
|
|
132
|
-
scheduler.work();
|
|
133
|
-
updateThread();
|
|
134
|
-
}
|
|
135
|
-
const onToggleAutoWork = (e: Event) => {
|
|
136
|
-
setAutoWork((e.target as HTMLInputElement).checked);
|
|
218
|
+
setRenderCounter(c => c + 1)
|
|
137
219
|
}
|
|
138
220
|
|
|
139
|
-
const
|
|
140
|
-
const onSelectCommit = (id: CommitID) => {
|
|
141
|
-
if (selectedCommit === id)
|
|
142
|
-
setSelectedCommit(null)
|
|
143
|
-
else
|
|
144
|
-
setSelectedCommit(id)
|
|
145
|
-
}
|
|
221
|
+
const viewportRef = useRef<HTMLElement | null>(null);
|
|
146
222
|
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
return null;
|
|
150
|
-
return h(CommitPreview, {
|
|
151
|
-
commit,
|
|
152
|
-
tree,
|
|
153
|
-
depth,
|
|
154
|
-
renderCommit: renderCommit(depth + 1),
|
|
155
|
-
onSelectCommit,
|
|
156
|
-
attributes: [
|
|
157
|
-
['Id', commit.id.toString()]
|
|
158
|
-
],
|
|
159
|
-
selectedCommits: new Set(selectedCommit ? [selectedCommit] : [])
|
|
160
|
-
})
|
|
161
|
-
}
|
|
223
|
+
const [selectedCommitId, setSelectedCommitId] = useState<CommitID | null>(null)
|
|
224
|
+
const [selectedCommitDetails, setSelectedCommitDetails] = useState<CommitDetailsReport | null>(null)
|
|
162
225
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
226
|
+
useEffect(() => {
|
|
227
|
+
if (!selectedCommitId)
|
|
228
|
+
return;
|
|
229
|
+
|
|
230
|
+
const details = controller.getDetails(selectedCommitId);
|
|
231
|
+
setSelectedCommitDetails(details)
|
|
232
|
+
}, [selectedCommitId])
|
|
233
|
+
|
|
234
|
+
const roots = [...deltaCache.roots.keys()];
|
|
235
|
+
const commits = deltaCache.getFlat();
|
|
236
|
+
|
|
237
|
+
const CHUNK_SIZE = 8;
|
|
238
|
+
|
|
239
|
+
return h('div', { style: { display: 'flex', 'flex-direction': 'column', position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 } }, [
|
|
240
|
+
h('div', { style: { flex: 0, display: 'flex' } }, [
|
|
241
|
+
h(ScheduleControls, {
|
|
242
|
+
controller: controller.scheduler,
|
|
243
|
+
bus: bus.scheduler,
|
|
244
|
+
reconciler: controller,
|
|
245
|
+
|
|
246
|
+
state: insightState,
|
|
247
|
+
onStateChange: setInsightState,
|
|
248
|
+
}),
|
|
249
|
+
h('button', { onClick: reload}, 'Reload'),
|
|
171
250
|
]),
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}),
|
|
179
|
-
],
|
|
180
|
-
selectedCommit && tree && [
|
|
181
|
-
h(CommitViewer, { tree, commitId: selectedCommit, reconciler })
|
|
182
|
-
]
|
|
183
|
-
])
|
|
184
|
-
]);
|
|
185
|
-
};
|
|
251
|
+
h('div', { style: { flex: 1, overflow: 'hidden', background: '#c0d7ddff', display: 'flex' } }, [
|
|
252
|
+
h('div', { style: { flex: 1 } },
|
|
253
|
+
//h(TreeViewer, { roots, renderCommit }),
|
|
254
|
+
h(Virtual1D, { viewportRef, windowRange: 5, chunkCount: commits.length / CHUNK_SIZE, chunkSize: (33 * CHUNK_SIZE), renderChunk(index) {
|
|
255
|
+
if (index < 0)
|
|
256
|
+
return null;
|
|
186
257
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
258
|
+
return Array.from({ length: CHUNK_SIZE }).map((_, chunkIndex) => {
|
|
259
|
+
const report = commits[(index * CHUNK_SIZE) + (chunkIndex)];
|
|
260
|
+
if (!report)
|
|
261
|
+
return null;
|
|
262
|
+
|
|
263
|
+
const color = getCommitColor(deltaCache, report.id);
|
|
264
|
+
|
|
265
|
+
const onClick = () => {
|
|
266
|
+
setSelectedCommitId(report.id);
|
|
267
|
+
};
|
|
268
|
+
const attributes: [string, string][] = [
|
|
269
|
+
insightState.commitBreakpoints.has(report.id) ? ['Breakpoint', 'Enabled'] as [string, string] : null
|
|
270
|
+
].filter(x => !!x)
|
|
271
|
+
|
|
272
|
+
return h('div', { style: { 'margin-left': ((report.distance - 1) * 32) + 'px', height: '33px' } }, [
|
|
273
|
+
h(CommitPreview, { color, commit: report, onClick, attributes })
|
|
274
|
+
])
|
|
275
|
+
});
|
|
276
|
+
}, })
|
|
277
|
+
),
|
|
278
|
+
h('div', { style: { 'min-width': '300px', flex: 0, background: '#ffdeabff' } }, [
|
|
279
|
+
deltaCache.thread && h('div', { }, [
|
|
280
|
+
h('dl', {}, [
|
|
281
|
+
h('dt', {}, 'Thread ID'),
|
|
282
|
+
h('dd', {}, deltaCache.thread.id),
|
|
283
|
+
h('dt', {}, 'Thread Done'),
|
|
284
|
+
h('dd', {}, deltaCache.thread.done.toString()),
|
|
285
|
+
h('dt', {}, 'Thread Passes'),
|
|
286
|
+
h('dd', {}, deltaCache.thread.passes),
|
|
287
|
+
h('dt', {}, 'Tasks (count)'),
|
|
288
|
+
h('dd', {}, deltaCache.thread.pendingTasks.length),
|
|
289
|
+
h('dt', {}, 'Visited (count)'),
|
|
290
|
+
h('dd', {}, deltaCache.thread.visited.length),
|
|
291
|
+
h('dt', {}, 'Created (count)'),
|
|
292
|
+
h('dd', {}, deltaCache.created.size),
|
|
293
|
+
h('dt', {}, 'Updated (count)'),
|
|
294
|
+
h('dd', {}, deltaCache.updated.size),
|
|
295
|
+
h('dt', {}, 'Removed (count)'),
|
|
296
|
+
h('dd', {}, deltaCache.removed.size),
|
|
297
|
+
h('dt', {}, 'MustRender '),
|
|
298
|
+
h('dd', {}, deltaCache.thread.mustRender.map(commitId => {
|
|
299
|
+
const commit = deltaCache.all.get(commitId);
|
|
300
|
+
if (!commit)
|
|
301
|
+
return null;
|
|
302
|
+
const color = getCommitColor(deltaCache, commitId);
|
|
303
|
+
|
|
304
|
+
return h(CommitPreview, {
|
|
305
|
+
commit,
|
|
306
|
+
color,
|
|
307
|
+
onClick: () => (scrollToCommitIndex(commits.indexOf(commit)), setSelectedCommitId(commitId))
|
|
308
|
+
})
|
|
309
|
+
})),
|
|
310
|
+
h('dt', {}, 'Missed'),
|
|
311
|
+
h('dd', {}, deltaCache.thread.missed.map(commitId => {
|
|
312
|
+
const commit = deltaCache.all.get(commitId);
|
|
313
|
+
if (!commit)
|
|
314
|
+
return null;
|
|
315
|
+
const color = getCommitColor(deltaCache, commitId);
|
|
196
316
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
317
|
+
return h(CommitPreview, {
|
|
318
|
+
commit,
|
|
319
|
+
color,
|
|
320
|
+
onClick: () => (scrollToCommitIndex(commits.indexOf(commit)), setSelectedCommitId(commitId))
|
|
321
|
+
})
|
|
322
|
+
})),
|
|
323
|
+
])
|
|
324
|
+
]),
|
|
325
|
+
h('hr'),
|
|
326
|
+
selectedCommitDetails && [
|
|
327
|
+
h(CommitPreview, {
|
|
328
|
+
commit: selectedCommitDetails.commit,
|
|
329
|
+
color: getCommitColor(deltaCache, selectedCommitDetails.commit.id),
|
|
330
|
+
onClick: () => (scrollToCommitIndex(commits.indexOf(selectedCommitDetails.commit)), setSelectedCommitId(selectedCommitDetails.commit.id))
|
|
331
|
+
}),
|
|
332
|
+
h('button', { onClick: () => {
|
|
333
|
+
setInsightState(state => {
|
|
334
|
+
const prev = state.commitBreakpoints;
|
|
335
|
+
if (prev.has(selectedCommitDetails.commit.id)) {
|
|
336
|
+
prev.delete(selectedCommitDetails.commit.id)
|
|
337
|
+
return { ...state, commitBreakpoints: new Set(prev) };
|
|
338
|
+
}
|
|
339
|
+
prev.add(selectedCommitDetails.commit.id)
|
|
340
|
+
return { ...state, commitBreakpoints: new Set(prev) }
|
|
341
|
+
})
|
|
342
|
+
}}, 'Toggle Breakpoint'),
|
|
343
|
+
h('h3', {}, 'Parent'),
|
|
344
|
+
(() => {
|
|
345
|
+
const parentId = selectedCommitDetails.commit.parent;
|
|
346
|
+
if (!parentId)
|
|
347
|
+
return 'NO PARENT';
|
|
348
|
+
const parent = deltaCache.all.get(parentId);
|
|
349
|
+
if (!parent)
|
|
350
|
+
return h(CommitAttributeTag, { name: 'ParentID', value: parentId.toString() });
|
|
351
|
+
|
|
352
|
+
return h(CommitPreview, {
|
|
353
|
+
commit: parent,
|
|
354
|
+
color: getCommitColor(deltaCache, parent.id),
|
|
355
|
+
onClick: () => (scrollToCommitIndex(commits.indexOf(parent)), setSelectedCommitId(parent.id))
|
|
356
|
+
});
|
|
357
|
+
})(),
|
|
358
|
+
h('h3', {}, 'Props'),
|
|
359
|
+
h('ul', {},
|
|
360
|
+
Object.entries(selectedCommitDetails.props).map(([prop, value]) => {
|
|
361
|
+
return h('li', {}, `${prop} = ${getTextForValue(value)}`);
|
|
362
|
+
})
|
|
363
|
+
)
|
|
364
|
+
]
|
|
365
|
+
])
|
|
366
|
+
])
|
|
367
|
+
])
|
|
200
368
|
}
|
|
201
369
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
370
|
+
|
|
371
|
+
export const getTextForValue = (value: ValueReport): string => {
|
|
372
|
+
switch (value.type) {
|
|
373
|
+
case 'primitive':
|
|
374
|
+
switch (typeof value.value) {
|
|
375
|
+
case 'object':
|
|
376
|
+
return `null`;
|
|
377
|
+
case 'string':
|
|
378
|
+
case 'boolean':
|
|
379
|
+
case 'number':
|
|
380
|
+
return value.value.toString();
|
|
381
|
+
}
|
|
382
|
+
case 'complex':
|
|
383
|
+
return value.name;
|
|
384
|
+
case 'undefined':
|
|
385
|
+
return `undefined`;
|
|
386
|
+
default:
|
|
387
|
+
return value;
|
|
388
|
+
}
|
|
209
389
|
}
|
|
390
|
+
|
|
391
|
+
const getCommitColor = (deltaCache: ThreadLookupCache, commitId: CommitID) => {
|
|
392
|
+
|
|
393
|
+
const color =
|
|
394
|
+
(deltaCache.nextTask && deltaCache.nextTask.id === commitId) ? '#e1d600ff'
|
|
395
|
+
: deltaCache.targets.has(commitId) ? '#db55e7ff'
|
|
396
|
+
: deltaCache.allTasks.has(commitId) ? '#ea931aff'
|
|
397
|
+
: deltaCache.created.has(commitId) ? (deltaCache.prevTask && deltaCache.prevTask.id === commitId ? '#4bc847ff' : '#21a51cff')
|
|
398
|
+
: deltaCache.removed.has(commitId) ? '#f25252ff'
|
|
399
|
+
: deltaCache.updated.has(commitId) ? '#1ab9eaff'
|
|
400
|
+
: deltaCache.visited.has(commitId) ? '#6f6f97ff'
|
|
401
|
+
: '#cacaca';
|
|
402
|
+
|
|
403
|
+
return color;
|
|
404
|
+
}
|