@lukekaalim/act-insight 1.1.0 → 2.0.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 +14 -0
- package/InsightApp.module.css +36 -0
- package/InsightApp2.ts +82 -0
- package/TreeViewer.module.css +3 -8
- package/TreeViewer.ts +16 -12
- package/Virtual.ts +29 -11
- package/assets/icons/ancestor_column.png +0 -0
- package/assets/icons/ancestor_column.svg +26 -0
- package/assets/icons/ancestor_skip_row_column.png +0 -0
- package/assets/icons/ancestor_skip_row_column.svg +52 -0
- package/assets/icons/breakpoint.png +0 -0
- package/assets/icons/breakpoint.svg +33 -0
- package/assets/icons/breakpoint_arrow.png +0 -0
- package/assets/icons/breakpoint_arrow.svg +22 -0
- package/assets/icons/breakpoint_arrow_paused.png +0 -0
- package/assets/icons/breakpoint_arrow_paused.svg +38 -0
- package/assets/icons/breakpoint_panel.png +0 -0
- package/assets/icons/breakpoint_panel.svg +121 -0
- package/assets/icons/breakpoint_unset.png +0 -0
- package/assets/icons/breakpoint_unset.svg +26 -0
- package/assets/icons/bug.png +0 -0
- package/assets/icons/bug.svg +65 -0
- package/assets/icons/children.png +0 -0
- package/assets/icons/children.svg +38 -0
- package/assets/icons/collapse.png +0 -0
- package/assets/icons/collapse.svg +38 -0
- package/assets/icons/commit.png +0 -0
- package/assets/icons/commit.svg +30 -0
- package/assets/icons/commit_tree.png +0 -0
- package/assets/icons/commit_tree.svg +44 -0
- package/assets/icons/effect.png +0 -0
- package/assets/icons/effect.svg +28 -0
- package/assets/icons/expand.png +0 -0
- package/assets/icons/expand.svg +47 -0
- package/assets/icons/eye.png +0 -0
- package/assets/icons/eye.svg +36 -0
- package/assets/icons/eye_closed.png +0 -0
- package/assets/icons/eye_closed.svg +32 -0
- package/assets/icons/filter.png +0 -0
- package/assets/icons/filter.svg +22 -0
- package/assets/icons/graph.png +0 -0
- package/assets/icons/graph.svg +129 -0
- package/assets/icons/history_list.png +0 -0
- package/assets/icons/history_list.svg +60 -0
- package/assets/icons/hook.png +0 -0
- package/assets/icons/hook.svg +22 -0
- package/assets/icons/index.ts +76 -0
- package/assets/icons/inspector_panel.png +0 -0
- package/assets/icons/inspector_panel.svg +135 -0
- package/assets/icons/magnifying_glass.png +0 -0
- package/assets/icons/magnifying_glass.svg +39 -0
- package/assets/icons/pause.png +0 -0
- package/assets/icons/pause.svg +34 -0
- package/assets/icons/play.png +0 -0
- package/assets/icons/play.svg +23 -0
- package/assets/icons/reload.png +0 -0
- package/assets/icons/reload.svg +39 -0
- package/assets/icons/selection.png +0 -0
- package/assets/icons/selection.svg +22 -0
- package/assets/icons/side_effects.png +0 -0
- package/assets/icons/side_effects.svg +48 -0
- package/assets/icons/skip.png +0 -0
- package/assets/icons/skip.svg +22 -0
- package/assets/icons/source.svg +1366 -0
- package/assets/icons/step.png +0 -0
- package/assets/icons/step.svg +51 -0
- package/assets/icons/step_over_children.png +0 -0
- package/assets/icons/step_over_children.svg +57 -0
- package/assets/icons/thread.png +0 -0
- package/assets/icons/thread.svg +32 -0
- package/assets/icons/tree_column.png +0 -0
- package/assets/icons/tree_column.svg +26 -0
- package/assets/icons/tree_end.png +0 -0
- package/assets/icons/tree_end.svg +35 -0
- package/assets/icons/tree_junction.png +0 -0
- package/assets/icons/tree_junction.svg +35 -0
- package/assets/icons/vertical_grab_handle.png +0 -0
- package/assets/icons/vertical_grab_handle.svg +36 -0
- package/components/BreakpointPanel.ts +110 -0
- package/components/BreakpointToggle.ts +14 -0
- package/components/Button.ts +53 -0
- package/components/Checkbox.ts +17 -0
- package/components/CommitInspector.ts +161 -0
- package/components/CommitTree.ts +295 -0
- package/components/ControlBar.ts +60 -0
- package/components/EffectTable.ts +125 -0
- package/components/FiltersPanel.ts +45 -0
- package/components/HistoryList.ts +0 -0
- package/components/InspectorPanel.ts +54 -0
- package/components/PlaybackBar.ts +42 -0
- package/components/ThreadInspector.ts +26 -0
- package/components/index.module.css +414 -0
- package/lib/controller.ts +222 -0
- package/lib/list.ts +82 -0
- package/lib/selection.ts +32 -0
- package/package.json +4 -4
- package/public/icons/icons.svg +520 -0
- package/public/icons/icons__breakpoint.png +0 -0
- package/public/icons/icons__breakpoint.svg +30 -0
- package/public/icons/icons__breakpoint_panel.png +0 -0
- package/public/icons/icons__breakpoint_panel.svg +121 -0
- package/public/icons/icons__children.png +0 -0
- package/public/icons/icons__children.svg +38 -0
- package/public/icons/icons__eye.png +0 -0
- package/public/icons/icons__eye.svg +36 -0
- package/public/icons/icons__inspector_panel.png +0 -0
- package/public/icons/icons__inspector_panel.svg +131 -0
- package/public/icons/icons__magnifying_glass.png +0 -0
- package/public/icons/icons__magnifying_glass.svg +39 -0
- package/public/icons/icons__pause.png +0 -0
- package/public/icons/icons__pause.svg +34 -0
- package/public/icons/icons__play.png +0 -0
- package/public/icons/icons__play.svg +23 -0
- package/public/icons/icons__skip.png +0 -0
- package/public/icons/icons__skip.svg +22 -0
- package/public/icons/icons__step.png +0 -0
- package/public/icons/icons__step.svg +51 -0
- package/utils.ts +71 -7
- package/InsightApp.ts +0 -404
- package/MenuBar.module.css +0 -18
- package/MenuBar.ts +0 -39
- package/ScheduleControls.ts +0 -61
- package/lookup.ts +0 -185
|
Binary file
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
|
|
4
|
+
<svg
|
|
5
|
+
width="5.8500004mm"
|
|
6
|
+
height="5.9899998mm"
|
|
7
|
+
viewBox="0 0 5.8500004 5.99"
|
|
8
|
+
version="1.1"
|
|
9
|
+
id="svg1"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs
|
|
13
|
+
id="defs1">
|
|
14
|
+
<marker
|
|
15
|
+
style="overflow:visible"
|
|
16
|
+
id="Triangle"
|
|
17
|
+
refX="0"
|
|
18
|
+
refY="0"
|
|
19
|
+
orient="auto-start-reverse"
|
|
20
|
+
markerWidth="0.5"
|
|
21
|
+
markerHeight="0.5"
|
|
22
|
+
viewBox="0 0 1 1"
|
|
23
|
+
preserveAspectRatio="xMidYMid">
|
|
24
|
+
<path
|
|
25
|
+
transform="scale(0.5)"
|
|
26
|
+
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
|
27
|
+
d="M 5.77,0 -2.88,5 V -5 Z"
|
|
28
|
+
id="path135" />
|
|
29
|
+
</marker>
|
|
30
|
+
</defs>
|
|
31
|
+
<g
|
|
32
|
+
id="layer1"
|
|
33
|
+
transform="translate(-28.952292,-16.774322)">
|
|
34
|
+
<circle
|
|
35
|
+
style="fill:#5d7388;fill-opacity:1;stroke-width:0.293366"
|
|
36
|
+
id="path7"
|
|
37
|
+
cx="30.252504"
|
|
38
|
+
cy="20.765179"
|
|
39
|
+
r="1.0245281" />
|
|
40
|
+
<circle
|
|
41
|
+
style="fill:none;fill-opacity:1;stroke:#5d7388;stroke-width:0.178757;stroke-linejoin:miter;stroke-dasharray:0.178757, 0.357514;stroke-dashoffset:0;stroke-opacity:1"
|
|
42
|
+
id="path7-0"
|
|
43
|
+
cx="33.435463"
|
|
44
|
+
cy="20.764971"
|
|
45
|
+
r="1.0010481" />
|
|
46
|
+
<path
|
|
47
|
+
style="fill:none;fill-opacity:1;stroke:#5d7388;stroke-width:0.265;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Triangle)"
|
|
48
|
+
d="m 30.291345,18.72896 c 0,-1.675316 3.032323,-1.625056 3.049075,-0.134029"
|
|
49
|
+
id="path8" />
|
|
50
|
+
</g>
|
|
51
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
|
|
4
|
+
<svg
|
|
5
|
+
width="5.8500004mm"
|
|
6
|
+
height="5.9899998mm"
|
|
7
|
+
viewBox="0 0 5.8500004 5.99"
|
|
8
|
+
version="1.1"
|
|
9
|
+
id="svg1"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs
|
|
13
|
+
id="defs1">
|
|
14
|
+
<marker
|
|
15
|
+
style="overflow:visible"
|
|
16
|
+
id="marker20"
|
|
17
|
+
refX="0"
|
|
18
|
+
refY="0"
|
|
19
|
+
orient="auto-start-reverse"
|
|
20
|
+
markerWidth="0.40000001"
|
|
21
|
+
markerHeight="0.40000001"
|
|
22
|
+
viewBox="0 0 1 1"
|
|
23
|
+
preserveAspectRatio="xMidYMid">
|
|
24
|
+
<path
|
|
25
|
+
transform="scale(0.5)"
|
|
26
|
+
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
|
27
|
+
d="M 5.77,0 -2.88,5 V -5 Z"
|
|
28
|
+
id="path20" />
|
|
29
|
+
</marker>
|
|
30
|
+
</defs>
|
|
31
|
+
<g
|
|
32
|
+
id="layer1"
|
|
33
|
+
transform="translate(-50.872714,-18.201318)">
|
|
34
|
+
<circle
|
|
35
|
+
style="fill:#5d7388;fill-opacity:1;stroke-width:0.293366"
|
|
36
|
+
id="path7-2"
|
|
37
|
+
cx="52.589622"
|
|
38
|
+
cy="19.577124"
|
|
39
|
+
r="1.0245281" />
|
|
40
|
+
<circle
|
|
41
|
+
style="fill:none;fill-opacity:1;stroke:#5d7388;stroke-width:0.178757;stroke-linejoin:miter;stroke-dasharray:0.178757, 0.357514;stroke-dashoffset:0;stroke-opacity:1"
|
|
42
|
+
id="path7-0-2"
|
|
43
|
+
cx="52.596684"
|
|
44
|
+
cy="22.512857"
|
|
45
|
+
r="1.0010481" />
|
|
46
|
+
<path
|
|
47
|
+
style="fill:none;stroke:#5d7388;stroke-width:0.309;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker20)"
|
|
48
|
+
d="m 52.495635,19.592386 h 2.800478 v 3.439583 h -0.898786"
|
|
49
|
+
id="path29" />
|
|
50
|
+
<circle
|
|
51
|
+
style="fill:#ffffff;fill-opacity:1;stroke:#5d7388;stroke-width:0.303;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
52
|
+
id="path7-0-2-3-3"
|
|
53
|
+
cx="55.275337"
|
|
54
|
+
cy="20.537638"
|
|
55
|
+
r="0.57445872" />
|
|
56
|
+
</g>
|
|
57
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
|
|
4
|
+
<svg
|
|
5
|
+
width="8mm"
|
|
6
|
+
height="7.9999995mm"
|
|
7
|
+
viewBox="0 0 8 7.9999998"
|
|
8
|
+
version="1.1"
|
|
9
|
+
id="svg1"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs
|
|
13
|
+
id="defs1" />
|
|
14
|
+
<g
|
|
15
|
+
id="layer1"
|
|
16
|
+
transform="translate(24.71815,-42.68502)">
|
|
17
|
+
<rect
|
|
18
|
+
style="fill:#76c9ed;fill-opacity:1;stroke:#328ab0;stroke-width:0.432;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
19
|
+
id="rect22-3"
|
|
20
|
+
width="6.8986015"
|
|
21
|
+
height="2.1699133"
|
|
22
|
+
x="-24.247269"
|
|
23
|
+
y="45.683922"
|
|
24
|
+
ry="0.16047928" />
|
|
25
|
+
<circle
|
|
26
|
+
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.98822;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:0.494108, 0.494108;stroke-dashoffset:0;stroke-opacity:1"
|
|
27
|
+
id="path23-14"
|
|
28
|
+
cx="-23.132378"
|
|
29
|
+
cy="46.792686"
|
|
30
|
+
r="0.64924502" />
|
|
31
|
+
</g>
|
|
32
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
|
|
4
|
+
<svg
|
|
5
|
+
width="7.0000005mm"
|
|
6
|
+
height="6.9999995mm"
|
|
7
|
+
viewBox="0 0 7.0000005 6.9999998"
|
|
8
|
+
version="1.1"
|
|
9
|
+
id="svg1"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs
|
|
13
|
+
id="defs1" />
|
|
14
|
+
<g
|
|
15
|
+
id="layer1"
|
|
16
|
+
transform="translate(-46.911243,-25.967027)">
|
|
17
|
+
<rect
|
|
18
|
+
style="fill:#303b47;stroke:none;stroke-width:0.658013"
|
|
19
|
+
id="rect9"
|
|
20
|
+
width="0.5"
|
|
21
|
+
height="7.2143836"
|
|
22
|
+
x="50.11124"
|
|
23
|
+
y="25.872257"
|
|
24
|
+
ry="0" />
|
|
25
|
+
</g>
|
|
26
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
|
|
4
|
+
<svg
|
|
5
|
+
width="7.0000005mm"
|
|
6
|
+
height="6.9999995mm"
|
|
7
|
+
viewBox="0 0 7.0000005 6.9999998"
|
|
8
|
+
version="1.1"
|
|
9
|
+
id="svg1"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs
|
|
13
|
+
id="defs1" />
|
|
14
|
+
<g
|
|
15
|
+
id="layer1"
|
|
16
|
+
transform="translate(-54.871936,-25.895951)">
|
|
17
|
+
<rect
|
|
18
|
+
style="fill:#303b47;stroke:none;stroke-width:0.648216"
|
|
19
|
+
id="rect9-3"
|
|
20
|
+
width="0.5"
|
|
21
|
+
height="4.1817374"
|
|
22
|
+
x="58.071934"
|
|
23
|
+
y="25.718256"
|
|
24
|
+
ry="0" />
|
|
25
|
+
<rect
|
|
26
|
+
style="fill:#303b47;stroke:none;stroke-width:0.633772"
|
|
27
|
+
id="rect9-3-1"
|
|
28
|
+
width="0.5"
|
|
29
|
+
height="3.9974527"
|
|
30
|
+
x="29.39595"
|
|
31
|
+
y="-62.069386"
|
|
32
|
+
ry="0"
|
|
33
|
+
transform="rotate(90)" />
|
|
34
|
+
</g>
|
|
35
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
|
|
4
|
+
<svg
|
|
5
|
+
width="7.0000005mm"
|
|
6
|
+
height="6.9999995mm"
|
|
7
|
+
viewBox="0 0 7.0000005 6.9999998"
|
|
8
|
+
version="1.1"
|
|
9
|
+
id="svg1"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs
|
|
13
|
+
id="defs1" />
|
|
14
|
+
<g
|
|
15
|
+
id="layer1"
|
|
16
|
+
transform="translate(-63.022171,-26.014413)">
|
|
17
|
+
<rect
|
|
18
|
+
style="fill:#303b47;stroke:none;stroke-width:0.854903"
|
|
19
|
+
id="rect9-3-3"
|
|
20
|
+
width="0.5"
|
|
21
|
+
height="7.2736144"
|
|
22
|
+
x="66.222168"
|
|
23
|
+
y="25.810398"
|
|
24
|
+
ry="0" />
|
|
25
|
+
<rect
|
|
26
|
+
style="fill:#303b47;stroke:none;stroke-width:0.633772"
|
|
27
|
+
id="rect9-3-1-6"
|
|
28
|
+
width="0.5"
|
|
29
|
+
height="3.9974527"
|
|
30
|
+
x="29.514414"
|
|
31
|
+
y="-70.21962"
|
|
32
|
+
ry="0"
|
|
33
|
+
transform="rotate(90)" />
|
|
34
|
+
</g>
|
|
35
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
|
|
4
|
+
<svg
|
|
5
|
+
width="6.8287368mm"
|
|
6
|
+
height="13.142978mm"
|
|
7
|
+
viewBox="0 0 6.8287368 13.142978"
|
|
8
|
+
version="1.1"
|
|
9
|
+
id="svg1"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs
|
|
13
|
+
id="defs1" />
|
|
14
|
+
<g
|
|
15
|
+
id="layer1"
|
|
16
|
+
transform="translate(-27.994085,-37.773945)">
|
|
17
|
+
<circle
|
|
18
|
+
style="fill:none;fill-opacity:1;stroke:#767676;stroke-width:0.437;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
19
|
+
id="path42"
|
|
20
|
+
cx="31.501995"
|
|
21
|
+
cy="40.259155"
|
|
22
|
+
r="1.7168031" />
|
|
23
|
+
<circle
|
|
24
|
+
style="fill:none;fill-opacity:1;stroke:#767676;stroke-width:0.437;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
25
|
+
id="path42-6"
|
|
26
|
+
cx="31.501995"
|
|
27
|
+
cy="48.665573"
|
|
28
|
+
r="1.7168031" />
|
|
29
|
+
<circle
|
|
30
|
+
style="fill:none;fill-opacity:1;stroke:#767676;stroke-width:0.437;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
31
|
+
id="path42-6-5"
|
|
32
|
+
cx="31.501995"
|
|
33
|
+
cy="44.462364"
|
|
34
|
+
r="1.7168031" />
|
|
35
|
+
</g>
|
|
36
|
+
</svg>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Component, h, useState } from "@lukekaalim/act";
|
|
2
|
+
import { Breakpoints, DebugCache, toggleEffectBreakpoint } from "@lukekaalim/act-debug";
|
|
3
|
+
|
|
4
|
+
import classes from './index.module.css';
|
|
5
|
+
import { CommitPreview } from "../TreeViewer";
|
|
6
|
+
import { EffectButton, HookButton, IconButton } from "./Button";
|
|
7
|
+
import { InsightController, InsightState } from "../lib/controller";
|
|
8
|
+
import { icons } from "../assets/icons";
|
|
9
|
+
import { BreakpointToggle } from "./BreakpointToggle";
|
|
10
|
+
|
|
11
|
+
export type BreakpointPanelProps = {
|
|
12
|
+
state: InsightState,
|
|
13
|
+
controller: InsightController,
|
|
14
|
+
cache: DebugCache,
|
|
15
|
+
|
|
16
|
+
breakpoints: Readonly<Breakpoints>,
|
|
17
|
+
|
|
18
|
+
onBreakpointsChange(breakpoints: Breakpoints): void,
|
|
19
|
+
onStepPressed(): void,
|
|
20
|
+
onResumePressed(): void,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const BreakpointPanel: Component<BreakpointPanelProps> = ({ breakpoints, state, onBreakpointsChange, cache, controller }) => {
|
|
24
|
+
type Toggles = "threadStart" | "threadPass" | "effectsStart" | "threadSubmit" | 'effectsEnd'
|
|
25
|
+
|
|
26
|
+
const setBreakpointToggle = (toggle: Toggles) => (event: InputEvent) => {
|
|
27
|
+
const input = event.target as HTMLInputElement;
|
|
28
|
+
const nextBreakpoints: Breakpoints = { ...breakpoints, [toggle]: input.checked }
|
|
29
|
+
onBreakpointsChange(nextBreakpoints);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const commitBreakpoints = [...breakpoints.commits.values()];
|
|
33
|
+
const effectBreakpoints = [...breakpoints.effects.values()];
|
|
34
|
+
|
|
35
|
+
const [width, setWidth] = useState(300);
|
|
36
|
+
const [dragging, setDragging] = useState(false);
|
|
37
|
+
const onPointerDown = (event: PointerEvent) => {
|
|
38
|
+
setDragging(true);
|
|
39
|
+
(event.target as HTMLButtonElement).setPointerCapture(event.pointerId);
|
|
40
|
+
}
|
|
41
|
+
const onPointerMove = (event: PointerEvent) => {
|
|
42
|
+
if (dragging) {
|
|
43
|
+
setWidth(w => w + event.movementX)
|
|
44
|
+
// do something about moving it
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const onPointerUp = (event: PointerEvent) => {
|
|
48
|
+
setDragging(false);
|
|
49
|
+
(event.target as HTMLButtonElement).releasePointerCapture(event.pointerId);
|
|
50
|
+
}
|
|
51
|
+
// 'before-first-commit' | 'before-pass' | 'before-submit' | 'before-first-effect' | 'before-last-effect'
|
|
52
|
+
|
|
53
|
+
const start = state.thread && state.paused && !state.thread.started;
|
|
54
|
+
const submit = state.thread && state.paused && !state.thread.submitted && state.thread.pendingTasks.length === 0 && state.thread.missed.length === 0;
|
|
55
|
+
const pass = state.thread && state.paused && !state.thread.submitted && state.thread.pendingTasks.length === 0 && state.thread.missed.length !== 0;
|
|
56
|
+
|
|
57
|
+
return h('div', { className: classes.panelContainer, style: { width: `${width}px` } }, [
|
|
58
|
+
h('button', { classList: [classes.grabHandle, classes.right], onPointerDown, onPointerMove, onPointerUp }, h('img', { src: icons.vertical_grab_handle })),
|
|
59
|
+
h('div', { classList: [classes.panel] }, [
|
|
60
|
+
h('h4', {}, 'Breakpoint Controls'),
|
|
61
|
+
h('div', { className: classes.namedBreakpointList }, [
|
|
62
|
+
h('label', { className: start ? classes.hit : '' }, [
|
|
63
|
+
h('input', { type: 'checkbox', checked: breakpoints.threadStart, onInput: setBreakpointToggle('threadStart') }),
|
|
64
|
+
h('span', {}, 'Before First Commit'),
|
|
65
|
+
]),
|
|
66
|
+
h('label', { className: pass ? classes.hit : '' }, [
|
|
67
|
+
h('input', { type: 'checkbox', checked: breakpoints.threadPass, onInput: setBreakpointToggle('threadPass') }),
|
|
68
|
+
h('span', {}, 'On Before New Thread Pass'),
|
|
69
|
+
]),
|
|
70
|
+
h('label', { className: submit ? classes.hit : '' }, [
|
|
71
|
+
h('input', { type: 'checkbox', checked: breakpoints.threadSubmit, onInput: setBreakpointToggle('threadSubmit') }),
|
|
72
|
+
h('span', {}, 'On Submit to Renderer'),
|
|
73
|
+
]),
|
|
74
|
+
h('label', {}, [
|
|
75
|
+
h('input', { type: 'checkbox', checked: breakpoints.effectsStart, onInput: setBreakpointToggle('effectsStart') }),
|
|
76
|
+
h('span', {}, 'On First Effect'),
|
|
77
|
+
]),
|
|
78
|
+
h('label', {}, [
|
|
79
|
+
h('input', { type: 'checkbox', checked: breakpoints.effectsEnd, onInput: setBreakpointToggle('effectsEnd') }),
|
|
80
|
+
h('span', {}, 'On Last Effect'),
|
|
81
|
+
]),
|
|
82
|
+
]),
|
|
83
|
+
commitBreakpoints.length > 0 && [
|
|
84
|
+
h('h4', {}, 'Commits Breakpoints'),
|
|
85
|
+
h('ul', { className: classes.commitList }, commitBreakpoints.map(commitId => {
|
|
86
|
+
const commit = cache.getCommit(commitId);
|
|
87
|
+
if (!commit)
|
|
88
|
+
return null;
|
|
89
|
+
return h('li', {}, [
|
|
90
|
+
h(IconButton, { icon: 'breakpoint', title: 'Clear Breakpoint', onClick() {}, className: classes.commitRowBreakpointToggle }),
|
|
91
|
+
h(CommitPreview, { commit, onClick: () => {
|
|
92
|
+
controller.select({ type: 'commit', id: commitId })
|
|
93
|
+
} })
|
|
94
|
+
])
|
|
95
|
+
}))
|
|
96
|
+
],
|
|
97
|
+
effectBreakpoints.length > 0 && [
|
|
98
|
+
h('h4', {}, 'Effect Breakpoints'),
|
|
99
|
+
h('ul', { className: classes.effectList }, effectBreakpoints.map(effectId => {
|
|
100
|
+
return h('li', {}, [
|
|
101
|
+
h(BreakpointToggle, { toggled: true, onToggle(toggled) {
|
|
102
|
+
onBreakpointsChange(toggleEffectBreakpoint(breakpoints, effectId))
|
|
103
|
+
}, }),
|
|
104
|
+
h(EffectButton, { onClick() {}, effectId }),
|
|
105
|
+
])
|
|
106
|
+
}))
|
|
107
|
+
],
|
|
108
|
+
])
|
|
109
|
+
]);
|
|
110
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Component, h } from "@lukekaalim/act";
|
|
2
|
+
import { IconButton } from "./Button";
|
|
3
|
+
import classes from './index.module.css';
|
|
4
|
+
|
|
5
|
+
export type BreakpointToggleProps = {
|
|
6
|
+
toggled: boolean,
|
|
7
|
+
onToggle(toggled: boolean): void,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const BreakpointToggle: Component<BreakpointToggleProps> = ({ toggled, onToggle }) => {
|
|
11
|
+
return h(IconButton, { icon: toggled ? 'breakpoint' : 'breakpoint_unset', className: classes.breakpointToggle, onClick() {
|
|
12
|
+
onToggle(!toggled)
|
|
13
|
+
}, title: `Toggle Breakpoint` })
|
|
14
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Component, h, OpaqueID } from "@lukekaalim/act"
|
|
2
|
+
import { icons } from "../assets/icons"
|
|
3
|
+
import classes from './index.module.css';
|
|
4
|
+
import { CommitID, EffectID } from "@lukekaalim/act-recon";
|
|
5
|
+
|
|
6
|
+
export type IconButtonProps = {
|
|
7
|
+
icon: keyof typeof icons,
|
|
8
|
+
|
|
9
|
+
onClick(): void,
|
|
10
|
+
title?: string,
|
|
11
|
+
className?: string,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const IconButton: Component<IconButtonProps> = ({ icon, onClick, title, className, children }) => {
|
|
15
|
+
return h('button', { onClick, classList: [classes.iconButton, className || ''] }, [
|
|
16
|
+
h('img', { title: title || '', src: icons[icon] }),
|
|
17
|
+
children
|
|
18
|
+
])
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export type HookButtonProps = {
|
|
23
|
+
hookIndex: number,
|
|
24
|
+
|
|
25
|
+
onClick(): void,
|
|
26
|
+
}
|
|
27
|
+
export const HookButton: Component<HookButtonProps> = ({ onClick, hookIndex }) => {
|
|
28
|
+
return h(IconButton, { icon: 'hook', onClick }, `hook#${hookIndex}`)
|
|
29
|
+
}
|
|
30
|
+
export type EffectButtonProps = {
|
|
31
|
+
effectId: EffectID,
|
|
32
|
+
|
|
33
|
+
onClick(): void,
|
|
34
|
+
}
|
|
35
|
+
export const EffectButton: Component<EffectButtonProps> = ({ onClick, effectId }) => {
|
|
36
|
+
return h(IconButton, { icon: 'effect', onClick }, `effect#${effectId}`)
|
|
37
|
+
}
|
|
38
|
+
export type ThreadButtonProps = {
|
|
39
|
+
threadId: OpaqueID<"ThreadID">,
|
|
40
|
+
|
|
41
|
+
onClick(): void,
|
|
42
|
+
}
|
|
43
|
+
export const ThreadButton: Component<ThreadButtonProps> = ({ onClick, threadId }) => {
|
|
44
|
+
return h(IconButton, { icon: 'thread', onClick }, `thread#${threadId}`)
|
|
45
|
+
}
|
|
46
|
+
export type CommitButtonProps = {
|
|
47
|
+
commitId: CommitID,
|
|
48
|
+
|
|
49
|
+
onClick(): void,
|
|
50
|
+
}
|
|
51
|
+
export const CommitButton: Component<CommitButtonProps> = ({ onClick, commitId }) => {
|
|
52
|
+
return h(IconButton, { icon: 'commit', onClick }, `commit#${commitId}`)
|
|
53
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Component, h, Node } from "@lukekaalim/act"
|
|
2
|
+
|
|
3
|
+
export type CheckboxProps = {
|
|
4
|
+
label: Node,
|
|
5
|
+
checked: boolean,
|
|
6
|
+
onCheckedChange(nextChecked: boolean): void,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Checkbox: Component<CheckboxProps> = ({ label, checked, onCheckedChange }) => {
|
|
10
|
+
return h('label', {}, [
|
|
11
|
+
h('input', { type: 'checkbox', checked, onInput(e: InputEvent) {
|
|
12
|
+
const input = (e.target) as HTMLInputElement;
|
|
13
|
+
onCheckedChange(input.checked);
|
|
14
|
+
} }),
|
|
15
|
+
h('span', {}, label),
|
|
16
|
+
]);
|
|
17
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Component, h, useEffect, useState } from "@lukekaalim/act"
|
|
2
|
+
|
|
3
|
+
import { icons } from "../assets/icons"
|
|
4
|
+
import { EffectButton, HookButton, IconButton } from "./Button"
|
|
5
|
+
import classes from './index.module.css';
|
|
6
|
+
import { Breakpoints, CommitDetailsReport, CommitReport, DebugClient, toggleCommitBreakpoint, toggleEffectBreakpoint } from "@lukekaalim/act-debug";
|
|
7
|
+
import { useSelection } from "../lib/selection";
|
|
8
|
+
import { CommitPreview } from "../TreeViewer";
|
|
9
|
+
import { Filters, InsightController, InsightState, toggleCollapsedCommit } from "../lib/controller";
|
|
10
|
+
import { CommitAttributeTag } from "../AttributeTag";
|
|
11
|
+
import { getTextForValue } from "../utils";
|
|
12
|
+
import { getCommitBorder, getCommitColor } from "./CommitTree";
|
|
13
|
+
import { CommitID } from "@lukekaalim/act-recon";
|
|
14
|
+
import { BreakpointToggle } from "./BreakpointToggle";
|
|
15
|
+
|
|
16
|
+
export type CommitInspectorProps = {
|
|
17
|
+
commit: CommitReport,
|
|
18
|
+
|
|
19
|
+
client: DebugClient,
|
|
20
|
+
breakpoints: Breakpoints,
|
|
21
|
+
|
|
22
|
+
state: InsightState,
|
|
23
|
+
controller: InsightController,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const CommitInspector: Component<CommitInspectorProps> = ({ commit, breakpoints, client, state, controller }) => {
|
|
27
|
+
const hasBreakpoint = breakpoints.commits.has(commit.id);
|
|
28
|
+
|
|
29
|
+
const [details, setDetails] = useState<CommitDetailsReport | null>(null);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
setDetails(state.client.getDetails(commit.id));
|
|
32
|
+
}, [commit])
|
|
33
|
+
|
|
34
|
+
const onToggleBreakpoint = () => {
|
|
35
|
+
client.setBreakpoints(toggleCommitBreakpoint(breakpoints, commit.id));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const isCollapsed = state.filters.collapsed.has(commit.id);
|
|
39
|
+
const onToggleCollapse = () => {
|
|
40
|
+
controller.changeFilters(toggleCollapsedCommit(state.filters, commit.id))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const ancestors: CommitReport[] = [];
|
|
44
|
+
let parentId = commit.parent;
|
|
45
|
+
while (parentId) {
|
|
46
|
+
const parentCommit = state.client.cache.getCommit(parentId);
|
|
47
|
+
if (!parentCommit)
|
|
48
|
+
break;
|
|
49
|
+
ancestors.push(parentCommit);
|
|
50
|
+
parentId = parentCommit.parent;
|
|
51
|
+
}
|
|
52
|
+
ancestors.reverse();
|
|
53
|
+
|
|
54
|
+
const component = details && details.component;
|
|
55
|
+
|
|
56
|
+
const onCommitClick = (commitId: CommitID) => () => {
|
|
57
|
+
controller.select({ type: 'commit', id: commitId })
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const renderAncestor = (ancestor: CommitReport, isLast: boolean) => {
|
|
61
|
+
const color = getCommitColor(ancestor, state.client.cache, state.thread);
|
|
62
|
+
const border = getCommitBorder(ancestor, state.client.cache, state.thread);
|
|
63
|
+
|
|
64
|
+
return [
|
|
65
|
+
h(CommitPreview, { commit: ancestor, attributes: [], color, border, onClick: onCommitClick(ancestor.id) }),
|
|
66
|
+
!isLast && h('img', { src: icons.ancestor_column }),
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
const color = getCommitColor(commit, state.client.cache, state.thread);
|
|
70
|
+
const border = getCommitBorder(commit, state.client.cache, state.thread);
|
|
71
|
+
|
|
72
|
+
return h('div', { className: classes.commitInspector }, [
|
|
73
|
+
h("details", {}, [
|
|
74
|
+
h('summary', {}, h('strong', {}, 'Lineage')),
|
|
75
|
+
h('div', { className: classes.lineageColumn }, ancestors.map((a, i) => renderAncestor(a, i === ancestors.length - 1))),
|
|
76
|
+
]),
|
|
77
|
+
// preview
|
|
78
|
+
h('div', { className: classes.commitInspectorPreviewRow },
|
|
79
|
+
h(CommitPreview, { commit, attributes: [], color, border })
|
|
80
|
+
),
|
|
81
|
+
h('div', {}, [
|
|
82
|
+
h(CommitAttributeTag, { name: 'Id', value: commit.id.toString() }),
|
|
83
|
+
h(CommitAttributeTag, { name: 'Version', value: commit.version.toString() }),
|
|
84
|
+
!!(details && details.props.key && details.props.key.type === 'primitive') &&
|
|
85
|
+
h(CommitAttributeTag, { name: 'Key', value: details.props.key.value as string }),
|
|
86
|
+
]),
|
|
87
|
+
|
|
88
|
+
// quick controls
|
|
89
|
+
h('div', { className: classes.commitControlBar }, [
|
|
90
|
+
h(IconButton, { icon: hasBreakpoint ? 'breakpoint' : 'breakpoint_unset', onClick: onToggleBreakpoint }),
|
|
91
|
+
h(IconButton, { icon: 'selection', onClick() {} }),
|
|
92
|
+
h(IconButton, { icon: isCollapsed ? 'expand' : 'collapse', onClick: onToggleCollapse }),
|
|
93
|
+
h(IconButton, { icon: 'reload', onClick() { client.requestRender(commit.id) } }),
|
|
94
|
+
]),
|
|
95
|
+
h("details", {}, [
|
|
96
|
+
h('summary', {}, h('strong', {}, 'Children')),
|
|
97
|
+
h('ol', { className: classes.commitList }, commit.children.map(child => {
|
|
98
|
+
const childCommit = state.client.cache.getCommit(child);
|
|
99
|
+
if (!childCommit)
|
|
100
|
+
return null;
|
|
101
|
+
|
|
102
|
+
const color = getCommitColor(childCommit, state.client.cache, state.thread);
|
|
103
|
+
const border = getCommitBorder(childCommit, state.client.cache, state.thread);
|
|
104
|
+
return h('li', {}, h(CommitPreview, { color, border, commit: childCommit, attributes: [], onClick: onCommitClick(child) }))
|
|
105
|
+
})),
|
|
106
|
+
]),
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
// info
|
|
110
|
+
|
|
111
|
+
// state details
|
|
112
|
+
details && [
|
|
113
|
+
h('div', {}, [
|
|
114
|
+
h('button', {}, 'By Order'),
|
|
115
|
+
h('button', { disabled: true }, 'By Type'),
|
|
116
|
+
]),
|
|
117
|
+
|
|
118
|
+
h('h4', {}, 'Props'),
|
|
119
|
+
h('table', {},
|
|
120
|
+
Object.entries(details.props).map(([name, value]) => {
|
|
121
|
+
return h('tr', {}, [h('td', {}, name), h('td', {}, getTextForValue(value))])
|
|
122
|
+
})),
|
|
123
|
+
component && [
|
|
124
|
+
h('h4', {}, 'State'),
|
|
125
|
+
h('table', {},
|
|
126
|
+
component.stateValues.map((state) => {
|
|
127
|
+
return h('tr', {}, [
|
|
128
|
+
h('td', {}, h(HookButton, { onClick() {} , hookIndex: state.hookIndex })),
|
|
129
|
+
h('td', {}, getTextForValue(state.value))
|
|
130
|
+
])
|
|
131
|
+
})),
|
|
132
|
+
h('h4', {}, 'Effects'),
|
|
133
|
+
h('table', {},
|
|
134
|
+
component.effects.map((effectHook) => {
|
|
135
|
+
const queuedForUpdate = state.thread && state.thread.delta.effects.some(e => e.id === effectHook.effect);
|
|
136
|
+
const cleanupTask = state.thread && state.thread.effects.tasks.findIndex(t => t.id === effectHook.effect && t.type === 'cleanup')
|
|
137
|
+
const constructorTask = state.thread && state.thread.effects.tasks.findIndex(t => t.id === effectHook.effect && t.type === 'constructor')
|
|
138
|
+
|
|
139
|
+
return h('tr', { style: { background: queuedForUpdate ? '#a7ceff' : 'none' } }, [
|
|
140
|
+
h('td', {}, h(HookButton, { onClick() {} , hookIndex: effectHook.hookIndex })),
|
|
141
|
+
h('td', {}, h('div', { style: { display: 'flex' } }, [
|
|
142
|
+
h(BreakpointToggle, { onToggle() {
|
|
143
|
+
client.setBreakpoints(toggleEffectBreakpoint(breakpoints, effectHook.effect))
|
|
144
|
+
}, toggled: breakpoints.effects.has(effectHook.effect) }),
|
|
145
|
+
h(EffectButton, { onClick() {}, effectId: effectHook.effect }),
|
|
146
|
+
])),
|
|
147
|
+
])
|
|
148
|
+
})),
|
|
149
|
+
h('h4', {}, 'Contexts'),
|
|
150
|
+
h('table', {},
|
|
151
|
+
component.subscriptions.map((subscription) => {
|
|
152
|
+
return h('tr', {}, [
|
|
153
|
+
h('td', {}, h(HookButton, { onClick() {} , hookIndex: subscription.hookIndex })),
|
|
154
|
+
h('td', {}, subscription.context),
|
|
155
|
+
h('td', {}, subscription.provider),
|
|
156
|
+
])
|
|
157
|
+
})),
|
|
158
|
+
]
|
|
159
|
+
]
|
|
160
|
+
])
|
|
161
|
+
}
|