@zenfg/inspector 0.1.0-beta.2 → 0.1.0-beta.4

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.
Files changed (172) hide show
  1. package/GUIDE.md +182 -0
  2. package/README.md +60 -26
  3. package/THEMING.md +124 -0
  4. package/dist/FrameGraphInspector.d.ts +24 -8
  5. package/dist/FrameGraphInspector.d.ts.map +1 -1
  6. package/dist/FrameGraphInspector.js +151 -65
  7. package/dist/FrameGraphInspector.js.map +1 -1
  8. package/dist/capture.d.ts +5 -0
  9. package/dist/capture.d.ts.map +1 -0
  10. package/dist/capture.js +2 -0
  11. package/dist/capture.js.map +1 -0
  12. package/dist/debugCaptureModel.d.ts +28 -4
  13. package/dist/debugCaptureModel.d.ts.map +1 -1
  14. package/dist/debugCaptureModel.js +72 -16
  15. package/dist/debugCaptureModel.js.map +1 -1
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/panelAliasAnalysis.d.ts +1 -0
  20. package/dist/panelAliasAnalysis.d.ts.map +1 -1
  21. package/dist/panelAliasAnalysis.js +23 -54
  22. package/dist/panelAliasAnalysis.js.map +1 -1
  23. package/dist/panelCytoscapeGraphRenderer.d.ts +18 -3
  24. package/dist/panelCytoscapeGraphRenderer.d.ts.map +1 -1
  25. package/dist/panelCytoscapeGraphRenderer.js +183 -41
  26. package/dist/panelCytoscapeGraphRenderer.js.map +1 -1
  27. package/dist/panelDetailLayout.d.ts +27 -0
  28. package/dist/panelDetailLayout.d.ts.map +1 -0
  29. package/dist/panelDetailLayout.js +174 -0
  30. package/dist/panelDetailLayout.js.map +1 -0
  31. package/dist/panelDetailStyles.d.ts +2 -0
  32. package/dist/panelDetailStyles.d.ts.map +1 -0
  33. package/dist/panelDetailStyles.js +57 -0
  34. package/dist/panelDetailStyles.js.map +1 -0
  35. package/dist/panelDiagnosticsView.d.ts +10 -1
  36. package/dist/panelDiagnosticsView.d.ts.map +1 -1
  37. package/dist/panelDiagnosticsView.js +167 -58
  38. package/dist/panelDiagnosticsView.js.map +1 -1
  39. package/dist/panelDomHelpers.d.ts.map +1 -1
  40. package/dist/panelDomHelpers.js +6 -5
  41. package/dist/panelDomHelpers.js.map +1 -1
  42. package/dist/panelGraphLayout.d.ts +3 -2
  43. package/dist/panelGraphLayout.d.ts.map +1 -1
  44. package/dist/panelGraphLayout.js +20 -5
  45. package/dist/panelGraphLayout.js.map +1 -1
  46. package/dist/panelGraphRenderer.d.ts +10 -0
  47. package/dist/panelGraphRenderer.d.ts.map +1 -1
  48. package/dist/panelGraphRenderer.js.map +1 -1
  49. package/dist/panelGraphScene.d.ts +15 -26
  50. package/dist/panelGraphScene.d.ts.map +1 -1
  51. package/dist/panelGraphScene.js +191 -208
  52. package/dist/panelGraphScene.js.map +1 -1
  53. package/dist/panelGraphSearch.d.ts +16 -0
  54. package/dist/panelGraphSearch.d.ts.map +1 -0
  55. package/dist/panelGraphSearch.js +93 -0
  56. package/dist/panelGraphSearch.js.map +1 -0
  57. package/dist/panelGraphView.d.ts +82 -0
  58. package/dist/panelGraphView.d.ts.map +1 -1
  59. package/dist/panelGraphView.js +42 -9
  60. package/dist/panelGraphView.js.map +1 -1
  61. package/dist/panelGraphVisuals.d.ts +18 -6
  62. package/dist/panelGraphVisuals.d.ts.map +1 -1
  63. package/dist/panelGraphVisuals.js +156 -116
  64. package/dist/panelGraphVisuals.js.map +1 -1
  65. package/dist/panelInspectorView.d.ts +13 -0
  66. package/dist/panelInspectorView.d.ts.map +1 -1
  67. package/dist/panelInspectorView.js +326 -46
  68. package/dist/panelInspectorView.js.map +1 -1
  69. package/dist/panelListStyles.d.ts +3 -0
  70. package/dist/panelListStyles.d.ts.map +1 -0
  71. package/dist/panelListStyles.js +155 -0
  72. package/dist/panelListStyles.js.map +1 -0
  73. package/dist/panelMemoryStyles.d.ts +3 -0
  74. package/dist/panelMemoryStyles.d.ts.map +1 -0
  75. package/dist/panelMemoryStyles.js +42 -0
  76. package/dist/panelMemoryStyles.js.map +1 -0
  77. package/dist/panelMemoryView.d.ts +13 -1
  78. package/dist/panelMemoryView.d.ts.map +1 -1
  79. package/dist/panelMemoryView.js +161 -41
  80. package/dist/panelMemoryView.js.map +1 -1
  81. package/dist/panelPassesView.d.ts +15 -0
  82. package/dist/panelPassesView.d.ts.map +1 -1
  83. package/dist/panelPassesView.js +202 -72
  84. package/dist/panelPassesView.js.map +1 -1
  85. package/dist/panelRawView.d.ts +15 -0
  86. package/dist/panelRawView.d.ts.map +1 -0
  87. package/dist/panelRawView.js +105 -0
  88. package/dist/panelRawView.js.map +1 -0
  89. package/dist/panelResourcesView.d.ts +8 -0
  90. package/dist/panelResourcesView.d.ts.map +1 -1
  91. package/dist/panelResourcesView.js +62 -31
  92. package/dist/panelResourcesView.js.map +1 -1
  93. package/dist/panelSelection.d.ts +9 -1
  94. package/dist/panelSelection.d.ts.map +1 -1
  95. package/dist/panelSelection.js +36 -6
  96. package/dist/panelSelection.js.map +1 -1
  97. package/dist/panelTheme.d.ts +13 -0
  98. package/dist/panelTheme.d.ts.map +1 -0
  99. package/dist/panelTheme.js +104 -0
  100. package/dist/panelTheme.js.map +1 -0
  101. package/dist/panelTypes.d.ts +18 -4
  102. package/dist/panelTypes.d.ts.map +1 -1
  103. package/dist/panelTypes.js.map +1 -1
  104. package/dist/panelVisualTheme.d.ts +176 -71
  105. package/dist/panelVisualTheme.d.ts.map +1 -1
  106. package/dist/panelVisualTheme.js +34 -36
  107. package/dist/panelVisualTheme.js.map +1 -1
  108. package/dist/panelWorkbenchHelpers.d.ts +12 -1
  109. package/dist/panelWorkbenchHelpers.d.ts.map +1 -1
  110. package/dist/panelWorkbenchHelpers.js +63 -2
  111. package/dist/panelWorkbenchHelpers.js.map +1 -1
  112. package/dist/panelWorkbenchStyles.d.ts +2 -0
  113. package/dist/panelWorkbenchStyles.d.ts.map +1 -0
  114. package/dist/panelWorkbenchStyles.js +101 -0
  115. package/dist/panelWorkbenchStyles.js.map +1 -0
  116. package/dist/panelWorkbenchView.d.ts +16 -0
  117. package/dist/panelWorkbenchView.d.ts.map +1 -1
  118. package/dist/panelWorkbenchView.js +228 -50
  119. package/dist/panelWorkbenchView.js.map +1 -1
  120. package/dist/query.js.map +1 -1
  121. package/dist/styles.d.ts.map +1 -1
  122. package/dist/styles.js +161 -205
  123. package/dist/styles.js.map +1 -1
  124. package/dist/theme.d.ts +22 -0
  125. package/dist/theme.d.ts.map +1 -0
  126. package/dist/theme.js +10 -0
  127. package/dist/theme.js.map +1 -0
  128. package/dist/themeDefinitions.d.ts +251 -0
  129. package/dist/themeDefinitions.d.ts.map +1 -0
  130. package/dist/themeDefinitions.js +96 -0
  131. package/dist/themeDefinitions.js.map +1 -0
  132. package/dist/themePalette.d.ts +66 -0
  133. package/dist/themePalette.d.ts.map +1 -0
  134. package/dist/themePalette.js +37 -0
  135. package/dist/themePalette.js.map +1 -0
  136. package/dist/themes.css +165 -0
  137. package/package.json +44 -10
  138. package/src/FrameGraphInspector.ts +145 -68
  139. package/src/capture.ts +4 -0
  140. package/src/debugCaptureModel.ts +97 -21
  141. package/src/index.ts +6 -2
  142. package/src/panelAliasAnalysis.ts +24 -70
  143. package/src/panelCytoscapeGraphRenderer.ts +177 -40
  144. package/src/panelDetailLayout.ts +155 -0
  145. package/src/panelDetailStyles.ts +56 -0
  146. package/src/panelDiagnosticsView.ts +167 -86
  147. package/src/panelDomHelpers.ts +4 -5
  148. package/src/panelGraphLayout.ts +20 -5
  149. package/src/panelGraphRenderer.ts +7 -0
  150. package/src/panelGraphScene.ts +204 -292
  151. package/src/panelGraphSearch.ts +96 -0
  152. package/src/panelGraphView.ts +41 -9
  153. package/src/panelGraphVisuals.ts +152 -118
  154. package/src/panelInspectorView.ts +315 -48
  155. package/src/panelListStyles.ts +154 -0
  156. package/src/panelMemoryStyles.ts +41 -0
  157. package/src/panelMemoryView.ts +178 -53
  158. package/src/panelPassesView.ts +190 -137
  159. package/src/panelRawView.ts +99 -0
  160. package/src/panelResourcesView.ts +69 -56
  161. package/src/panelSelection.ts +39 -7
  162. package/src/panelTheme.ts +85 -0
  163. package/src/panelTypes.ts +16 -4
  164. package/src/panelVisualTheme.ts +38 -38
  165. package/src/panelWorkbenchHelpers.ts +62 -4
  166. package/src/panelWorkbenchStyles.ts +100 -0
  167. package/src/panelWorkbenchView.ts +201 -52
  168. package/src/query.ts +11 -11
  169. package/src/styles.ts +162 -205
  170. package/src/theme.ts +24 -0
  171. package/src/themeDefinitions.ts +103 -0
  172. package/src/themePalette.ts +44 -0
@@ -0,0 +1,96 @@
1
+ import type { FrameGraphDebugViewModel } from './debugCaptureModel.ts';
2
+ import { labelNode, labelResource } from './panelDomHelpers.ts';
3
+ import type { Selection } from './panelTypes.ts';
4
+
5
+ type SearchEntry = { readonly label: string; readonly kind: string; readonly text: string; readonly selection: Selection };
6
+
7
+ export class GraphSearch {
8
+ readonly root = document.createElement('div');
9
+ private readonly toggle = document.createElement('button');
10
+ private readonly popover = document.createElement('div');
11
+ private readonly input = document.createElement('input');
12
+ private readonly results = document.createElement('div');
13
+ private entries: SearchEntry[] = [];
14
+
15
+ constructor(private readonly onReveal: (selection: Selection) => void, id: string) {
16
+ this.root.className = 'zenfg-inspector-graph-search';
17
+ this.toggle.type = 'button';
18
+ this.toggle.textContent = 'Search';
19
+ this.toggle.setAttribute('aria-expanded', 'false');
20
+ this.toggle.setAttribute('aria-controls', id);
21
+ this.toggle.addEventListener('click', () => this.setOpen(this.popover.hidden !== false));
22
+ this.popover.className = 'zenfg-inspector-graph-search-popover';
23
+ this.popover.id = id;
24
+ this.popover.hidden = true;
25
+ this.input.type = 'search';
26
+ this.input.placeholder = 'Find pass, resource, group or output';
27
+ this.input.setAttribute('aria-label', 'Find in graph');
28
+ this.results.className = 'zenfg-inspector-graph-search-results';
29
+ this.results.setAttribute('aria-label', 'Graph search results');
30
+ this.results.hidden = true;
31
+ this.input.addEventListener('input', () => this.render());
32
+ this.root.addEventListener('keydown', (event) => {
33
+ if (event.key === 'Escape' && !this.popover.hidden) {
34
+ event.preventDefault();
35
+ event.stopPropagation();
36
+ this.setOpen(false);
37
+ } else if (event.key === 'ArrowDown' && event.target === this.input) {
38
+ event.preventDefault();
39
+ this.results.querySelector('button')?.focus();
40
+ }
41
+ });
42
+ this.popover.append(this.input, this.results);
43
+ this.root.append(this.toggle, this.popover);
44
+ }
45
+
46
+ private setOpen(open: boolean): void {
47
+ this.popover.hidden = !open;
48
+ this.toggle.setAttribute('aria-expanded', String(open));
49
+ if (open) this.input.focus();
50
+ else {
51
+ this.input.value = '';
52
+ this.results.hidden = true;
53
+ this.toggle.focus();
54
+ }
55
+ }
56
+
57
+ setSnapshot(snapshot: FrameGraphDebugViewModel): void {
58
+ this.entries = [
59
+ ...snapshot.nodes.map((node): SearchEntry => ({ label: labelNode(node), kind: 'Pass',
60
+ text: `${node.id} ${labelNode(node)} ${node.debugGroupId ? snapshot.groupById.get(node.debugGroupId)?.path.join(' / ') : ''}`,
61
+ selection: { kind: 'node', id: node.id } })),
62
+ ...snapshot.resources.map((resource): SearchEntry => ({ label: labelResource(resource), kind: 'Resource',
63
+ text: `${resource.id} ${labelResource(resource)}`, selection: { kind: 'resource', id: resource.id } })),
64
+ ...snapshot.debugGroups.map((group): SearchEntry => ({ label: group.path.join(' / '), kind: 'Group',
65
+ text: `${group.id} ${group.path.join(' / ')}`, selection: { kind: 'group', pathKey: group.pathKey } })),
66
+ ...snapshot.roots.filter((root) => root.reason !== 'side-effect').map((root): SearchEntry => ({
67
+ label: `${root.reason} · ${root.resource ? labelResource(root.resource) : root.key}`, kind: 'Output',
68
+ text: `${root.reason} ${root.resource?.id} ${root.resource?.label}`, selection: { kind: 'root', key: root.key },
69
+ })),
70
+ ];
71
+ this.render();
72
+ }
73
+
74
+ private render(): void {
75
+ const query = this.input.value.trim().toLocaleLowerCase();
76
+ this.results.replaceChildren();
77
+ this.results.hidden = !query;
78
+ if (!query) return;
79
+ const matches = this.entries.filter((entry) => entry.text.toLocaleLowerCase().includes(query));
80
+ const count = document.createElement('p');
81
+ count.setAttribute('role', 'status');
82
+ count.textContent = matches.length > 50 ? `Showing 50 of ${matches.length} results. Refine your search.` : `${matches.length} results`;
83
+ this.results.append(count);
84
+ for (const entry of matches.slice(0, 50)) {
85
+ const button = document.createElement('button');
86
+ button.type = 'button';
87
+ button.textContent = `${entry.kind} · ${entry.label}`;
88
+ button.title = `Show in Graph · ${entry.label}`;
89
+ button.addEventListener('click', () => {
90
+ this.setOpen(false);
91
+ this.onReveal(entry.selection);
92
+ });
93
+ this.results.append(button);
94
+ }
95
+ }
96
+ }
@@ -1,3 +1,4 @@
1
+ import { GRAPH_VISUAL_THEME } from './panelVisualTheme.ts';
1
2
  import type { FrameGraphDebugViewModel } from './debugCaptureModel.ts';
2
3
  import { CytoscapeGraphRenderer } from './panelCytoscapeGraphRenderer.ts';
3
4
  import { createGraphScene, type GraphScene } from './panelGraphScene.ts';
@@ -22,7 +23,8 @@ export function renderGraphView(
22
23
  onToggleGroup: (pathKey: string) => void,
23
24
  ): void {
24
25
  const scene = resolveGraphScene(graphView, snapshot);
25
- renderGraphLegend(graphView.legend, scene);
26
+ if (!graphView.theme) graphView.refreshTheme?.();
27
+ renderGraphLegend(graphView.legend, snapshot, graphView.theme, graphView.showResourceDeclarations);
26
28
  const elementCount = scene.nodes.length + scene.edges.length;
27
29
  const layoutElementBudget = graphView.layoutElementBudget ?? Number.MAX_SAFE_INTEGER;
28
30
  if (elementCount > layoutElementBudget) {
@@ -39,16 +41,21 @@ export function renderGraphView(
39
41
  graphView.renderer ??= new CytoscapeGraphRenderer(graphView.host);
40
42
  graphView.renderer.render({
41
43
  scene,
44
+ theme: graphView.theme,
45
+ onVisible: graphView.refreshTheme,
42
46
  selected,
43
47
  hovered,
44
48
  fit: graphView.fitOnNextRender,
45
49
  anchorElementId: graphView.anchorElementIdOnNextRender,
50
+ reveal: graphView.revealOnNextRender,
51
+ captureRevision: graphView.captureRevision,
46
52
  onSelect,
47
53
  onHover,
48
54
  onToggleGroup,
49
55
  });
50
56
  graphView.fitOnNextRender = false;
51
57
  graphView.anchorElementIdOnNextRender = undefined;
58
+ graphView.revealOnNextRender = undefined;
52
59
  }
53
60
 
54
61
  export function resolveGraphScene(
@@ -56,15 +63,15 @@ export function resolveGraphScene(
56
63
  snapshot: FrameGraphDebugViewModel,
57
64
  ): GraphScene {
58
65
  const optionsKey = JSON.stringify([
59
- graphView.graphMode,
60
66
  graphView.groupsEnabled,
67
+ graphView.showResourceDeclarations ?? true,
61
68
  [...graphView.expandedGroupPaths].sort(),
62
69
  ]);
63
70
  const cached = graphSceneCache.get(graphView);
64
71
  if (cached?.snapshot === snapshot && cached.optionsKey === optionsKey) return cached.scene;
65
72
  const scene = createGraphScene(snapshot, {
66
- mode: graphView.graphMode,
67
73
  groupsEnabled: graphView.groupsEnabled,
74
+ showResourceDeclarations: graphView.showResourceDeclarations,
68
75
  expandedGroupPaths: graphView.expandedGroupPaths,
69
76
  });
70
77
  graphSceneCache.set(graphView, { snapshot, optionsKey, scene });
@@ -76,6 +83,7 @@ export function fitGraph(graphView: GraphViewState): void {
76
83
  }
77
84
 
78
85
  export function resizeGraph(graphView: GraphViewState): void {
86
+ graphView.refreshTheme?.();
79
87
  graphView.renderer?.resize();
80
88
  }
81
89
 
@@ -85,13 +93,26 @@ export function destroyGraph(graphView: GraphViewState): void {
85
93
  graphSceneCache.delete(graphView);
86
94
  }
87
95
 
88
- function renderGraphLegend(host: HTMLElement | undefined, scene: GraphScene): void {
96
+ export function renderGraphLegend(host: HTMLElement | undefined, snapshot: FrameGraphDebugViewModel, theme = GRAPH_VISUAL_THEME, showResourceDeclarations = true): void {
89
97
  if (!host) return;
90
- const entries = createGraphLegend(scene);
91
- const key = entries.map((entry) => entry.key).join('|');
98
+ const entries = createGraphLegend(snapshot, theme, showResourceDeclarations);
99
+ const key = JSON.stringify(entries);
92
100
  if (host.dataset.legendKey === key) return;
93
101
  host.dataset.legendKey = key;
94
- host.replaceChildren(...entries.map((entry) => {
102
+ host.replaceChildren();
103
+ let group: HTMLElement | undefined;
104
+ for (const entry of entries) {
105
+ if (group?.getAttribute('aria-label') !== entry.group) {
106
+ group = document.createElement('span');
107
+ group.className = 'zenfg-inspector-legend-group';
108
+ group.setAttribute('role', 'group');
109
+ group.setAttribute('aria-label', entry.group);
110
+ const heading = document.createElement('span');
111
+ heading.className = 'zenfg-inspector-legend-heading';
112
+ heading.textContent = entry.group;
113
+ group.appendChild(heading);
114
+ host.appendChild(group);
115
+ }
95
116
  const item = document.createElement('span');
96
117
  item.className = 'zenfg-inspector-legend-item';
97
118
  const swatch = document.createElement('span');
@@ -100,9 +121,20 @@ function renderGraphLegend(host: HTMLElement | undefined, scene: GraphScene): vo
100
121
  if (entry.lineStyle) swatch.dataset.lineStyle = entry.lineStyle;
101
122
  if (entry.hollowArrow) swatch.dataset.hollowArrow = 'true';
102
123
  swatch.style.setProperty('--zenfg-inspector-legend-color', entry.color);
124
+ if (entry.shape === 'cut-rectangle' || entry.shape === 'tag') {
125
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
126
+ svg.setAttribute('viewBox', '0 0 20 14');
127
+ svg.setAttribute('aria-hidden', 'true');
128
+ const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
129
+ polygon.setAttribute('points', entry.shape === 'tag'
130
+ ? '1,1 16,1 19,7 16,13 1,13'
131
+ : '4,1 16,1 19,4 19,10 16,13 4,13 1,10 1,4');
132
+ svg.appendChild(polygon);
133
+ swatch.appendChild(svg);
134
+ }
103
135
  const label = document.createElement('span');
104
136
  label.textContent = entry.label;
105
137
  item.append(swatch, label);
106
- return item;
107
- }));
138
+ group!.appendChild(item);
139
+ }
108
140
  }