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

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 (62) hide show
  1. package/README.md +63 -1
  2. package/dist/FrameGraphInspector.d.ts +2 -5
  3. package/dist/FrameGraphInspector.d.ts.map +1 -1
  4. package/dist/FrameGraphInspector.js +16 -38
  5. package/dist/FrameGraphInspector.js.map +1 -1
  6. package/dist/debugCaptureModel.d.ts +9 -4
  7. package/dist/debugCaptureModel.d.ts.map +1 -1
  8. package/dist/debugCaptureModel.js +36 -14
  9. package/dist/debugCaptureModel.js.map +1 -1
  10. package/dist/panelCytoscapeGraphRenderer.d.ts +3 -1
  11. package/dist/panelCytoscapeGraphRenderer.d.ts.map +1 -1
  12. package/dist/panelCytoscapeGraphRenderer.js +39 -19
  13. package/dist/panelCytoscapeGraphRenderer.js.map +1 -1
  14. package/dist/panelDiagnosticsView.js +2 -2
  15. package/dist/panelDiagnosticsView.js.map +1 -1
  16. package/dist/panelGraphLayout.d.ts.map +1 -1
  17. package/dist/panelGraphLayout.js +15 -1
  18. package/dist/panelGraphLayout.js.map +1 -1
  19. package/dist/panelGraphScene.d.ts +14 -26
  20. package/dist/panelGraphScene.d.ts.map +1 -1
  21. package/dist/panelGraphScene.js +141 -195
  22. package/dist/panelGraphScene.js.map +1 -1
  23. package/dist/panelGraphView.d.ts.map +1 -1
  24. package/dist/panelGraphView.js +31 -9
  25. package/dist/panelGraphView.js.map +1 -1
  26. package/dist/panelGraphVisuals.d.ts +7 -3
  27. package/dist/panelGraphVisuals.d.ts.map +1 -1
  28. package/dist/panelGraphVisuals.js +45 -80
  29. package/dist/panelGraphVisuals.js.map +1 -1
  30. package/dist/panelInspectorView.d.ts +5 -0
  31. package/dist/panelInspectorView.d.ts.map +1 -1
  32. package/dist/panelInspectorView.js +99 -13
  33. package/dist/panelInspectorView.js.map +1 -1
  34. package/dist/panelSelection.js +2 -2
  35. package/dist/panelSelection.js.map +1 -1
  36. package/dist/panelTypes.d.ts +8 -3
  37. package/dist/panelTypes.d.ts.map +1 -1
  38. package/dist/panelTypes.js.map +1 -1
  39. package/dist/panelVisualTheme.d.ts +21 -13
  40. package/dist/panelVisualTheme.d.ts.map +1 -1
  41. package/dist/panelVisualTheme.js +15 -7
  42. package/dist/panelVisualTheme.js.map +1 -1
  43. package/dist/panelWorkbenchHelpers.js +1 -1
  44. package/dist/panelWorkbenchHelpers.js.map +1 -1
  45. package/dist/styles.d.ts.map +1 -1
  46. package/dist/styles.js +16 -12
  47. package/dist/styles.js.map +1 -1
  48. package/package.json +2 -2
  49. package/src/FrameGraphInspector.ts +17 -39
  50. package/src/debugCaptureModel.ts +44 -19
  51. package/src/panelCytoscapeGraphRenderer.ts +38 -18
  52. package/src/panelDiagnosticsView.ts +3 -3
  53. package/src/panelGraphLayout.ts +15 -1
  54. package/src/panelGraphScene.ts +153 -279
  55. package/src/panelGraphView.ts +31 -9
  56. package/src/panelGraphVisuals.ts +46 -82
  57. package/src/panelInspectorView.ts +104 -16
  58. package/src/panelSelection.ts +2 -2
  59. package/src/panelTypes.ts +9 -3
  60. package/src/panelVisualTheme.ts +18 -7
  61. package/src/panelWorkbenchHelpers.ts +2 -2
  62. package/src/styles.ts +16 -12
@@ -1,3 +1,10 @@
1
+ /** Semantic identity within one recording, independent of root array order. */
2
+ export function rootKey(root) {
3
+ return root.reason === 'side-effect' ? JSON.stringify([root.reason, root.nodeId])
4
+ : JSON.stringify([root.reason, root.resourceId, root.range?.kind === 'buffer'
5
+ ? ['buffer', root.range.offset, root.range.size]
6
+ : root.range?.regions.map((r) => [r.baseMipLevel, r.mipLevelCount, r.aspect, r.baseArrayLayer, r.arrayLayerCount, r.baseDepthSlice, r.depthSliceCount]) ?? null]);
7
+ }
1
8
  export function createDebugViewModel(snapshot, source = { kind: 'programmatic', label: 'Programmatic' }) {
2
9
  const compilation = snapshot.graph;
3
10
  const unavailable = new Set(snapshot.capture.migration?.unavailableFacts ?? []);
@@ -79,6 +86,7 @@ export function createDebugViewModel(snapshot, source = { kind: 'programmatic',
79
86
  kind: resource.kind,
80
87
  label: resource.label,
81
88
  origin: resource.origin,
89
+ initialContents: resource.initialContents,
82
90
  debugGroupId: resource.groupId,
83
91
  usageFlags: resource.usageFlags,
84
92
  lifetime: resource.lifetime,
@@ -91,8 +99,8 @@ export function createDebugViewModel(snapshot, source = { kind: 'programmatic',
91
99
  resource: resourceRef(dependency.resourceId),
92
100
  }));
93
101
  const roots = compilation.roots.map((root) => ({
94
- reason: root.reason,
95
- nodeId: root.nodeId,
102
+ ...root,
103
+ key: rootKey(root),
96
104
  resource: root.resourceId === undefined ? undefined : resourceRef(root.resourceId),
97
105
  }));
98
106
  const culledNodes = compilation.nodes
@@ -287,9 +295,23 @@ function validateDebugGroupReferences(compilation, knownGroupIds) {
287
295
  }
288
296
  }
289
297
  }
298
+ /** Declaration boundaries are topological, not per-range initial-value provenance. */
299
+ export function declarationEntrances(nodes, accesses, edges) {
300
+ const retained = new Set(nodes.map((node) => node.id));
301
+ const incoming = new Set(edges.map((edge) => JSON.stringify([edge.resource.id, edge.toNodeId])));
302
+ const seen = new Set();
303
+ return accesses.filter((access) => {
304
+ const key = JSON.stringify([access.resource.id, access.nodeId]);
305
+ if (!retained.has(access.nodeId) || incoming.has(key) || seen.has(key))
306
+ return false;
307
+ seen.add(key);
308
+ return true;
309
+ });
310
+ }
290
311
  function buildDebugGroupSummaries(input) {
291
312
  const groupsById = new Map(input.groups.map((group) => [group.id, group]));
292
313
  const resourcesById = new Map(input.resources.map((resource) => [resource.id, resource]));
314
+ const entrances = declarationEntrances(input.nodes, input.accessEdges, input.edges);
293
315
  const isInGroup = (candidateId, groupId) => (candidateId !== undefined && groupsById.get(candidateId)?.ancestorIds.includes(groupId) === true);
294
316
  return input.groups.map((group) => {
295
317
  const retained = input.nodes.filter((node) => isInGroup(node.debugGroupId, group.id));
@@ -310,23 +332,22 @@ function buildDebugGroupSummaries(input) {
310
332
  if (fromInside && !toInside)
311
333
  outputIds.add(edge.resource.id);
312
334
  }
313
- for (const access of input.accessEdges) {
314
- if (!retainedIds.has(access.nodeId))
315
- continue;
316
- const resource = resourcesById.get(access.resource.id);
317
- const hasRetainedValueProducer = input.edges.some((edge) => (edge.toNodeId === access.nodeId
318
- && edge.resource.id === access.resource.id
319
- && edge.kind === 'value'));
320
- if (access.mode === 'read' && resource && resource.origin !== 'transient' && !hasRetainedValueProducer) {
321
- inputIds.add(resource.id);
322
- }
335
+ for (const access of entrances) {
336
+ const fromInside = isInGroup(resourcesById.get(access.resource.id)?.debugGroupId, group.id);
337
+ const toInside = retainedIds.has(access.nodeId);
338
+ if (!fromInside && toInside)
339
+ inputIds.add(access.resource.id);
340
+ if (fromInside && !toInside)
341
+ outputIds.add(access.resource.id);
323
342
  }
343
+ const outputRoots = [];
324
344
  for (const root of input.roots) {
325
345
  if (!root.resource)
326
346
  continue;
327
- if (input.accessEdges.some((access) => retainedIds.has(access.nodeId)
328
- && access.resource.id === root.resource.id && access.mode === 'write')) {
347
+ if (root.resolution?.producerNodeIds.some((id) => retainedIds.has(id))
348
+ || root.resolution?.usesInitialContents && isInGroup(resourcesById.get(root.resource.id)?.debugGroupId, group.id)) {
329
349
  outputIds.add(root.resource.id);
350
+ outputRoots.push(root);
330
351
  }
331
352
  }
332
353
  const registeredTransient = input.resources.filter((resource) => resource.origin === 'transient'
@@ -349,6 +370,7 @@ function buildDebugGroupSummaries(input) {
349
370
  nodeKindCounts,
350
371
  inputResources: [...inputIds].map((id) => resourcesById.get(id)).filter(Boolean),
351
372
  outputResources: [...outputIds].map((id) => resourcesById.get(id)).filter(Boolean),
373
+ outputRoots,
352
374
  registeredTransientResourceCount: registeredTransient.length,
353
375
  accessedTransientResourceCount: accessedTransientIds.size,
354
376
  physicalAllocationCount: allocationIds.size,
@@ -1 +1 @@
1
- {"version":3,"file":"debugCaptureModel.js","sourceRoot":"","sources":["../src/debugCaptureModel.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tFrameGraphSnapshot,\n\tFrameGraphSnapshotAccessKind,\n\tFrameGraphSnapshotBufferRange,\n\tFrameGraphSnapshotGpuTimings,\n\tFrameGraphSnapshotNodeKind,\n\tFrameGraphSnapshotResourceKind,\n\tFrameGraphSnapshotResourceOrigin,\n\tFrameGraphSnapshotRootReason,\n\tFrameGraphSnapshotSegment,\n\tFrameGraphSnapshotTextureRegion,\n\tFrameGraphSnapshotWriteContents,\n} from '@zenfg/snapshot';\n\ntype ResourceAccessMode = 'read' | 'write';\n\nexport type FrameGraphDebugExecutionSegment = FrameGraphSnapshotSegment & {\n\treadonly index: number;\n};\n\nexport type FrameGraphDebugResourceRef = {\n readonly id: string;\n readonly kind: FrameGraphSnapshotResourceKind;\n readonly label?: string;\n};\n\ntype FrameGraphDebugAccessEdgeBase = {\n\treadonly accessId: string;\n\treadonly nodeId: string;\n readonly resource: FrameGraphDebugResourceRef;\n\treadonly access: FrameGraphSnapshotAccessKind;\n\treadonly textureViewId?: string;\n\treadonly textureRegion?: FrameGraphSnapshotTextureRegion;\n\treadonly bufferRange?: FrameGraphSnapshotBufferRange;\n};\n\nexport type FrameGraphDebugAccessEdge = FrameGraphDebugAccessEdgeBase & (\n | {\n readonly mode: 'read';\n readonly producesValue: false;\n readonly contents?: never;\n }\n | {\n readonly mode: 'write';\n\t\treadonly contents: FrameGraphSnapshotWriteContents;\n readonly producesValue: boolean;\n }\n);\n\nexport type FrameGraphDebugAccess = FrameGraphDebugAccessEdge extends infer TAccess\n\t? TAccess extends FrameGraphDebugAccessEdge ? Omit<TAccess, 'nodeId'> : never\n : never;\n\nexport type FrameGraphDebugNode = {\n\treadonly id: string;\n readonly order: number;\n\treadonly kind: FrameGraphSnapshotNodeKind;\n readonly label?: string;\n\treadonly sideEffect: boolean;\n\treadonly debugGroupId?: string;\n readonly gpuDurationMicros?: number;\n readonly reads: readonly FrameGraphDebugAccess[];\n readonly writes: readonly FrameGraphDebugAccess[];\n};\n\nexport type FrameGraphDebugResource = FrameGraphDebugResourceRef & {\n\treadonly origin: FrameGraphSnapshotResourceOrigin;\n\treadonly debugGroupId?: string;\n\treadonly usageFlags: readonly string[];\n readonly lifetime?: { readonly firstUse: number; readonly lastUse: number };\n\treadonly physicalResourceId?: string;\n\treadonly descriptor?: FrameGraphSnapshot['graph']['resources'][number]['descriptor'];\n\treadonly estimatedByteSize?: number;\n};\n\nexport type FrameGraphDebugEdge = {\n\treadonly fromNodeId: string;\n\treadonly toNodeId: string;\n readonly resource: FrameGraphDebugResourceRef;\n readonly kind: 'value' | 'ordering';\n};\n\nexport type FrameGraphDebugRoot = {\n\treadonly reason: FrameGraphSnapshotRootReason;\n\treadonly nodeId?: string;\n readonly resource?: FrameGraphDebugResourceRef;\n};\n\nexport type FrameGraphDebugCulledNode = {\n readonly node: Omit<FrameGraphDebugNode, 'order'>;\n readonly reason: string;\n};\n\nexport type FrameGraphDebugPhysicalAllocation = {\n\treadonly id: string;\n\treadonly kind: FrameGraphSnapshotResourceKind;\n\treadonly compatibilityClassId: string;\n\treadonly estimatedByteSize?: number;\n\treadonly resourceIds: readonly string[];\n};\n\nexport type FrameGraphDebugGroupSummary = {\n\treadonly retainedNodeCount: number;\n\treadonly culledNodeCount: number;\n\treadonly nodeKindCounts: Readonly<Partial<Record<FrameGraphSnapshotNodeKind, number>>>;\n\treadonly inputResources: readonly FrameGraphDebugResourceRef[];\n\treadonly outputResources: readonly FrameGraphDebugResourceRef[];\n\treadonly registeredTransientResourceCount: number;\n\treadonly accessedTransientResourceCount: number;\n\treadonly physicalAllocationCount: number;\n\treadonly executionSegmentCount: number;\n\treadonly externalSubmissionCount: number;\n\treadonly gpuWorkDurationMicros: number;\n\treadonly timedNodeCount: number;\n\treadonly timingEligibleNodeCount: number;\n};\n\nexport type FrameGraphDebugGroup = {\n\treadonly id: string;\n\treadonly parentId?: string;\n\treadonly label: string;\n\treadonly path: readonly string[];\n\t/** Stable while same-named siblings retain their recording-order occurrence. */\n\treadonly pathKey: string;\n\treadonly depth: number;\n\t/** Ordered ancestor ids from root through this group. */\n\treadonly ancestorIds: readonly string[];\n\treadonly summary: FrameGraphDebugGroupSummary;\n};\n\nexport type FrameGraphDebugMetrics = {\n\treadonly timingEligibleNodeCount: number;\n\treadonly timedNodeCount: number;\n\treadonly slowestNode?: FrameGraphDebugNode;\n\treadonly transientEstimatedByteSize?: number;\n\treadonly logicalCapacityBytes?: number;\n\treadonly physicalEstimatedBytes?: number;\n\treadonly aliasReuseBytes?: number;\n\treadonly aliasedAllocationCount: number;\n};\n\nexport type FrameGraphDebugSnapshotSource = {\n\treadonly kind: 'live' | 'file' | 'programmatic';\n\treadonly label: string;\n\treadonly migratedFromLegacy?: boolean;\n};\n\nexport type FrameGraphDebugViewModel = {\n\treadonly protocol: FrameGraphSnapshot;\n\treadonly source: FrameGraphDebugSnapshotSource;\n readonly frameIndex: number;\n readonly nodes: readonly FrameGraphDebugNode[];\n readonly resources: readonly FrameGraphDebugResource[];\n readonly edges: readonly FrameGraphDebugEdge[];\n readonly accessEdges: readonly FrameGraphDebugAccessEdge[];\n readonly roots: readonly FrameGraphDebugRoot[];\n readonly culledNodes: readonly FrameGraphDebugCulledNode[];\n\treadonly physicalAllocations: readonly FrameGraphDebugPhysicalAllocation[];\n\treadonly debugGroups: readonly FrameGraphDebugGroup[];\n\treadonly executionSegments: readonly FrameGraphDebugExecutionSegment[];\n\treadonly textureViewById: ReadonlyMap<string, FrameGraphSnapshot['graph']['textureViews'][number]>;\n\treadonly nodeById: ReadonlyMap<string, FrameGraphDebugNode>;\n\treadonly resourceById: ReadonlyMap<string, FrameGraphDebugResource>;\n\treadonly groupById: ReadonlyMap<string, FrameGraphDebugGroup>;\n\treadonly groupByPathKey: ReadonlyMap<string, FrameGraphDebugGroup>;\n\treadonly allocationById: ReadonlyMap<string, FrameGraphDebugPhysicalAllocation>;\n\treadonly accessesByNodeId: ReadonlyMap<string, readonly FrameGraphDebugAccessEdge[]>;\n\treadonly accessesByResourceId: ReadonlyMap<string, readonly FrameGraphDebugAccessEdge[]>;\n\treadonly segmentByNodeId: ReadonlyMap<string, FrameGraphDebugExecutionSegment>;\n\treadonly segmentByIndex: ReadonlyMap<number, FrameGraphDebugExecutionSegment>;\n\treadonly metrics: FrameGraphDebugMetrics;\n readonly profiling:\n | {\n readonly status: 'available';\n readonly frameIndex: number;\n\t\t\treadonly timings: readonly { readonly nodeId: string; readonly gpuDurationMicros: number }[];\n readonly gpuFrameDurationMicros: number;\n }\n | {\n readonly status: 'unavailable';\n readonly frameIndex: number;\n\t\t\treadonly reason: Extract<FrameGraphSnapshotGpuTimings, { readonly status: 'unavailable' }>['reason'];\n readonly timings: readonly [];\n };\n\treadonly resourcePool: FrameGraphSnapshot['memory']['poolReport'];\n\treadonly availability: {\n\t\treadonly groups: boolean;\n\t\treadonly textureViews: boolean;\n\t\treadonly recordingOrder: boolean;\n\t\treadonly accessRegions: boolean;\n\t};\n};\n\nexport function createDebugViewModel(\n\tsnapshot: FrameGraphSnapshot,\n\tsource: FrameGraphDebugSnapshotSource = { kind: 'programmatic', label: 'Programmatic' },\n): FrameGraphDebugViewModel {\n\tconst compilation = snapshot.graph;\n\tconst unavailable = new Set(snapshot.capture.migration?.unavailableFacts ?? []);\n\tconst availability = {\n\t\tgroups: !unavailable.has('graph.groups'),\n\t\ttextureViews: !unavailable.has('graph.textureViews'),\n\t\trecordingOrder: !unavailable.has('graph.nodes.recordingOrder'),\n\t\taccessRegions: !unavailable.has('graph.accesses.regions'),\n\t};\n\tconst resolvedSource: FrameGraphDebugSnapshotSource = snapshot.capture.migration?.sourceFormat === 'legacy-v0'\n\t\t? { ...source, migratedFromLegacy: true }\n\t\t: source;\n\tconst gpuTiming = snapshot.timings.gpu;\n\tconst resourcePool = snapshot.memory.poolReport;\n\tconst normalizedGroups = normalizeDebugGroups(compilation);\n\tconst knownGroupIds = new Set(normalizedGroups.map((group) => group.id));\n\tvalidateDebugGroupReferences(compilation, knownGroupIds);\n\tconst resourcesById = new Map(compilation.resources.map((resource) => [resource.id, resource]));\n\tconst resourceRef = (resourceId: string): FrameGraphDebugResourceRef => {\n const resource = resourcesById.get(resourceId);\n if (!resource) {\n throw new Error(`Compilation report references unknown resource ${resourceId}.`);\n }\n return { id: resource.id, kind: resource.kind, label: resource.label };\n };\n const accessEdges = compilation.accesses.map((access): FrameGraphDebugAccessEdge => {\n const common = {\n accessId: access.id,\n nodeId: access.nodeId,\n resource: resourceRef(access.resourceId),\n access: access.access,\n textureViewId: access.textureViewId,\n textureRegion: access.textureRegion,\n bufferRange: access.bufferRange,\n };\n return access.mode === 'read'\n ? { ...common, mode: 'read', producesValue: false }\n : {\n ...common,\n mode: 'write',\n contents: access.contents,\n producesValue: access.producesValue,\n };\n });\n\tconst accessesByNode = new Map<string, FrameGraphDebugAccessEdge[]>();\n\tconst accessesByResource = new Map<string, FrameGraphDebugAccessEdge[]>();\n for (const access of accessEdges) {\n const nodeAccesses = accessesByNode.get(access.nodeId) ?? [];\n nodeAccesses.push(access);\n accessesByNode.set(access.nodeId, nodeAccesses);\n\t\tconst resourceAccesses = accessesByResource.get(access.resource.id) ?? [];\n\t\tresourceAccesses.push(access);\n\t\taccessesByResource.set(access.resource.id, resourceAccesses);\n }\n\tconst timings = gpuTiming.status === 'available'\n ? new Map(gpuTiming.nodes.map((timing) => [timing.nodeId, timing.durationMicros]))\n : new Map<string, number>();\n\tconst nodeAccesses = (nodeId: string, mode: ResourceAccessMode): FrameGraphDebugAccess[] => (\n (accessesByNode.get(nodeId) ?? [])\n .filter((access) => access.mode === mode)\n\t\t\t.map(({ nodeId: _nodeId, ...access }) => access)\n\t);\n\tconst nodes: FrameGraphDebugNode[] = compilation.nodes\n\t\t.filter((node) => node.compileState.status === 'retained')\n\t\t.sort((a, b) => a.compileState.status === 'retained' && b.compileState.status === 'retained'\n\t\t\t? a.compileState.executionOrder - b.compileState.executionOrder\n\t\t\t: 0)\n\t\t.map((node) => ({\n\t\tid: node.id,\n\t\torder: node.compileState.status === 'retained' ? node.compileState.executionOrder : 0,\n\t\tkind: node.kind,\n\t\tlabel: node.label,\n\t\tsideEffect: node.sideEffect,\n\t\tdebugGroupId: node.groupId,\n\t\tgpuDurationMicros: timings.get(node.id),\n\t\treads: nodeAccesses(node.id, 'read'),\n\t\twrites: nodeAccesses(node.id, 'write'),\n\t}));\n\tconst resources: FrameGraphDebugResource[] = compilation.resources.map((resource) => ({\n\t\tid: resource.id,\n\t\tkind: resource.kind,\n\t\tlabel: resource.label,\n\t\torigin: resource.origin,\n\t\tdebugGroupId: resource.groupId,\n\t\tusageFlags: resource.usageFlags,\n\t\tlifetime: resource.lifetime,\n\t\tphysicalResourceId: resource.allocationId,\n\t\tdescriptor: resource.descriptor,\n\t\testimatedByteSize: resource.estimatedByteSize,\n\t}));\n\tconst edges: FrameGraphDebugEdge[] = compilation.dependencies.map((dependency) => ({\n\t\t...dependency,\n\t\tresource: resourceRef(dependency.resourceId),\n\t}));\n\tconst roots: FrameGraphDebugRoot[] = compilation.roots.map((root) => ({\n\t\treason: root.reason,\n\t\tnodeId: root.nodeId,\n\t\tresource: root.resourceId === undefined ? undefined : resourceRef(root.resourceId),\n\t}));\n\tconst culledNodes: FrameGraphDebugCulledNode[] = compilation.nodes\n\t\t.filter((node) => node.compileState.status === 'culled')\n\t\t.map((node) => ({\n\t\tnode: {\n\t\t\tid: node.id,\n\t\t\tkind: node.kind,\n\t\t\tlabel: node.label,\n\t\t\tsideEffect: node.sideEffect,\n\t\t\tdebugGroupId: node.groupId,\n\t\t\treads: nodeAccesses(node.id, 'read'),\n\t\t\twrites: nodeAccesses(node.id, 'write'),\n\t\t},\n\t\treason: node.compileState.status === 'culled' ? node.compileState.reason : 'unknown',\n\t}));\n\tconst resourceIdsByAllocation = new Map<string, string[]>();\n\tfor (const resource of compilation.resources) {\n\t\tif (resource.allocationId === undefined) continue;\n\t\tconst resourceIds = resourceIdsByAllocation.get(resource.allocationId) ?? [];\n\t\tresourceIds.push(resource.id);\n\t\tresourceIdsByAllocation.set(resource.allocationId, resourceIds);\n\t}\n\tconst physicalAllocations: FrameGraphDebugPhysicalAllocation[] = snapshot.memory.allocationReport.status === 'available'\n\t\t? snapshot.memory.allocationReport.allocations.map((allocation) => ({\n\t\t\t...allocation,\n\t\t\tresourceIds: resourceIdsByAllocation.get(allocation.id) ?? [],\n\t\t}))\n\t\t: [];\n\tconst executionSegments: FrameGraphDebugExecutionSegment[] = compilation.segments.map((segment) => ({\n\t\t...segment,\n\t\tindex: segment.order,\n\t}));\n\tconst debugGroups = buildDebugGroupSummaries({\n\t\tgroups: normalizedGroups,\n\t\tnodes,\n\t\tculledNodes,\n\t\tresources,\n\t\taccessEdges,\n\t\tedges,\n\t\troots,\n\t\texecutionSegments,\n\t});\n\tconst nodeById = new Map(nodes.map((node) => [node.id, node]));\n\tconst resourceById = new Map(resources.map((resource) => [resource.id, resource]));\n\tconst groupById = new Map(debugGroups.map((group) => [group.id, group]));\n\tconst groupByPathKey = new Map(debugGroups.map((group) => [group.pathKey, group]));\n\tconst allocationById = new Map(physicalAllocations.map((allocation) => [allocation.id, allocation]));\n\tconst textureViewById = new Map(compilation.textureViews.map((view) => [view.id, view]));\n\tconst segmentByNodeId = new Map<string, FrameGraphDebugExecutionSegment>();\n\tconst segmentByIndex = new Map(executionSegments.map((segment) => [segment.index, segment]));\n\tfor (const segment of executionSegments) {\n\t\tfor (const nodeId of segment.nodeIds) segmentByNodeId.set(nodeId, segment);\n\t}\n\tconst timingEligibleNodes = nodes.filter((node) => node.kind === 'render' || node.kind === 'compute');\n\tconst timedNodes = timingEligibleNodes.filter((node) => node.gpuDurationMicros !== undefined);\n\tconst slowestNode = timedNodes.reduce<FrameGraphDebugNode | undefined>((slowest, node) => (\n\t\t!slowest || node.gpuDurationMicros! > slowest.gpuDurationMicros! ? node : slowest\n\t), undefined);\n\tconst transientResources = resources.filter((resource) => resource.origin === 'transient');\n\tconst transientEstimatedByteSize = sumKnown(transientResources.map((resource) => resource.estimatedByteSize));\n\tconst physicalEstimatedBytes = sumKnown(physicalAllocations.map((allocation) => allocation.estimatedByteSize));\n\tconst logicalAllocationSizes = transientResources\n\t\t.filter((resource) => resource.physicalResourceId !== undefined)\n\t\t.map((resource) => allocationById.get(resource.physicalResourceId!)?.estimatedByteSize);\n\tconst logicalCapacityBytes = sumKnown(logicalAllocationSizes);\n\tconst metrics: FrameGraphDebugMetrics = {\n\t\ttimingEligibleNodeCount: timingEligibleNodes.length,\n\t\ttimedNodeCount: timedNodes.length,\n\t\tslowestNode,\n\t\ttransientEstimatedByteSize,\n\t\tlogicalCapacityBytes,\n\t\tphysicalEstimatedBytes,\n\t\taliasReuseBytes: logicalCapacityBytes === undefined || physicalEstimatedBytes === undefined\n\t\t\t? undefined\n\t\t\t: Math.max(0, logicalCapacityBytes - physicalEstimatedBytes),\n\t\taliasedAllocationCount: physicalAllocations.filter((allocation) => allocation.resourceIds.length > 1).length,\n\t};\n\n\treturn {\n\t\tprotocol: snapshot,\n\t\tsource: resolvedSource,\n\t\tframeIndex: snapshot.capture.frameIndex,\n\t\tnodes,\n\t\tresources,\n\t\tedges,\n\t\taccessEdges,\n\t\troots,\n\t\tculledNodes,\n\t\tphysicalAllocations,\n\t\tdebugGroups,\n\t\texecutionSegments,\n\t\ttextureViewById,\n\t\tnodeById,\n\t\tresourceById,\n\t\tgroupById,\n\t\tgroupByPathKey,\n\t\tallocationById,\n\t\taccessesByNodeId: accessesByNode,\n\t\taccessesByResourceId: accessesByResource,\n\t\tsegmentByNodeId,\n\t\tsegmentByIndex,\n\t\tmetrics,\n profiling: gpuTiming.status === 'available'\n ? {\n status: 'available',\n frameIndex: snapshot.capture.frameIndex,\n timings: gpuTiming.nodes.map((timing) => ({\n nodeId: timing.nodeId,\n gpuDurationMicros: timing.durationMicros,\n })),\n gpuFrameDurationMicros: gpuTiming.frameSpanMicros,\n }\n : {\n status: 'unavailable',\n frameIndex: snapshot.capture.frameIndex,\n timings: [],\n reason: gpuTiming.reason,\n },\n\t\tresourcePool,\n\t\tavailability,\n\t};\n}\n\nfunction sumKnown(values: readonly (number | undefined)[]): number | undefined {\n\tlet total = 0;\n\tfor (const value of values) {\n\t\tif (value === undefined) return undefined;\n\t\ttotal += value;\n\t}\n\treturn total;\n}\n\ntype NormalizedDebugGroup = Omit<FrameGraphDebugGroup, 'summary'>;\n\nfunction normalizeDebugGroups(compilation: FrameGraphSnapshot['graph']): NormalizedDebugGroup[] {\n\tconst rawGroups = compilation.groups;\n\tconst rawById = new Map<string, FrameGraphSnapshot['graph']['groups'][number]>();\n\tconst siblingOccurrences = new Map<string, number>();\n\tconst nextOccurrenceByParent = new Map<string | undefined, Map<string, number>>();\n\tfor (const group of rawGroups) {\n\t\tif (rawById.has(group.id)) {\n\t\t\tthrow new Error(`Compilation report contains duplicate debug group id ${group.id}.`);\n\t\t}\n\t\tconst label = group.label.trim();\n\t\tif (label.length === 0) {\n\t\t\tthrow new Error(`Compilation report debug group ${group.id} has an empty label.`);\n\t\t}\n\t\trawById.set(group.id, { ...group, label });\n\t\tconst nextOccurrenceByLabel = nextOccurrenceByParent.get(group.parentId) ?? new Map<string, number>();\n\t\tconst occurrence = nextOccurrenceByLabel.get(label) ?? 0;\n\t\tsiblingOccurrences.set(group.id, occurrence);\n\t\tnextOccurrenceByLabel.set(label, occurrence + 1);\n\t\tnextOccurrenceByParent.set(group.parentId, nextOccurrenceByLabel);\n\t}\n\n\tconst normalizedById = new Map<string, NormalizedDebugGroup>();\n\tconst identityPathById = new Map<string, readonly (readonly [label: string, siblingOccurrence: number])[]>();\n\tconst visiting = new Set<string>();\n\tconst resolve = (id: string): NormalizedDebugGroup => {\n\t\tconst existing = normalizedById.get(id);\n\t\tif (existing) return existing;\n\t\tconst raw = rawById.get(id);\n\t\tif (!raw) throw new Error(`Compilation report references unknown debug group ${id}.`);\n\t\tif (visiting.has(id)) throw new Error(`Compilation report debug group ${id} has a parent cycle.`);\n\t\tvisiting.add(id);\n\t\tconst parent = raw.parentId === undefined ? undefined : resolve(raw.parentId);\n\t\tconst path = [...(parent?.path ?? []), raw.label];\n\t\tconst identityPath = [\n\t\t\t...(raw.parentId === undefined ? [] : identityPathById.get(raw.parentId)!),\n\t\t\t[raw.label, siblingOccurrences.get(raw.id)!] as const,\n\t\t];\n\t\tconst ancestorIds = [...(parent?.ancestorIds ?? []), raw.id];\n\t\tconst normalized: NormalizedDebugGroup = {\n\t\t\tid: raw.id,\n\t\t\tparentId: raw.parentId,\n\t\t\tlabel: raw.label,\n\t\t\tpath,\n\t\t\tpathKey: JSON.stringify(identityPath),\n\t\t\tdepth: path.length - 1,\n\t\t\tancestorIds,\n\t\t};\n\t\tvisiting.delete(id);\n\t\tidentityPathById.set(id, identityPath);\n\t\tnormalizedById.set(id, normalized);\n\t\treturn normalized;\n\t};\n\treturn rawGroups.map((group) => resolve(group.id));\n}\n\nfunction validateDebugGroupReferences(\n\tcompilation: FrameGraphSnapshot['graph'],\n\tknownGroupIds: ReadonlySet<string>,\n): void {\n\tfor (const entry of [...compilation.nodes, ...compilation.resources]) {\n\t\tif (entry.groupId !== undefined && !knownGroupIds.has(entry.groupId)) {\n\t\t\tthrow new Error(`Compilation report references unknown debug group ${entry.groupId}.`);\n\t\t}\n\t}\n}\n\nfunction buildDebugGroupSummaries(input: {\n\treadonly groups: readonly NormalizedDebugGroup[];\n\treadonly nodes: readonly FrameGraphDebugNode[];\n\treadonly culledNodes: readonly FrameGraphDebugCulledNode[];\n\treadonly resources: readonly FrameGraphDebugResource[];\n\treadonly accessEdges: readonly FrameGraphDebugAccessEdge[];\n\treadonly edges: readonly FrameGraphDebugEdge[];\n\treadonly roots: readonly FrameGraphDebugRoot[];\n\treadonly executionSegments: readonly FrameGraphDebugExecutionSegment[];\n}): FrameGraphDebugGroup[] {\n\tconst groupsById = new Map(input.groups.map((group) => [group.id, group]));\n\tconst resourcesById = new Map(input.resources.map((resource) => [resource.id, resource]));\n\tconst isInGroup = (candidateId: string | undefined, groupId: string) => (\n\t\tcandidateId !== undefined && groupsById.get(candidateId)?.ancestorIds.includes(groupId) === true\n\t);\n\n\treturn input.groups.map((group): FrameGraphDebugGroup => {\n\t\tconst retained = input.nodes.filter((node) => isInGroup(node.debugGroupId, group.id));\n\t\tconst culled = input.culledNodes.filter((entry) => isInGroup(entry.node.debugGroupId, group.id));\n\t\tconst retainedIds = new Set(retained.map((node) => node.id));\n\t\tconst allIds = new Set([...retainedIds, ...culled.map((entry) => entry.node.id)]);\n\t\tconst nodeKindCounts: Partial<Record<FrameGraphSnapshotNodeKind, number>> = {};\n\t\tfor (const node of [...retained, ...culled.map((entry) => entry.node)]) {\n\t\t\tnodeKindCounts[node.kind] = (nodeKindCounts[node.kind] ?? 0) + 1;\n\t\t}\n\n\t\tconst inputIds = new Set<string>();\n\t\tconst outputIds = new Set<string>();\n\t\tfor (const edge of input.edges) {\n\t\t\tconst fromInside = retainedIds.has(edge.fromNodeId);\n\t\t\tconst toInside = retainedIds.has(edge.toNodeId);\n\t\t\tif (!fromInside && toInside) inputIds.add(edge.resource.id);\n\t\t\tif (fromInside && !toInside) outputIds.add(edge.resource.id);\n\t\t}\n\t\tfor (const access of input.accessEdges) {\n\t\t\tif (!retainedIds.has(access.nodeId)) continue;\n\t\t\tconst resource = resourcesById.get(access.resource.id);\n\t\t\tconst hasRetainedValueProducer = input.edges.some((edge) => (\n\t\t\t\tedge.toNodeId === access.nodeId\n\t\t\t\t&& edge.resource.id === access.resource.id\n\t\t\t\t&& edge.kind === 'value'\n\t\t\t));\n\t\t\tif (access.mode === 'read' && resource && resource.origin !== 'transient' && !hasRetainedValueProducer) {\n\t\t\t\tinputIds.add(resource.id);\n\t\t\t}\n\t\t}\n\t\tfor (const root of input.roots) {\n\t\t\tif (!root.resource) continue;\n\t\t\tif (input.accessEdges.some((access) => retainedIds.has(access.nodeId)\n\t\t\t\t&& access.resource.id === root.resource!.id && access.mode === 'write')) {\n\t\t\t\toutputIds.add(root.resource.id);\n\t\t\t}\n\t\t}\n\n\t\tconst registeredTransient = input.resources.filter((resource) => resource.origin === 'transient'\n\t\t\t&& isInGroup(resource.debugGroupId, group.id));\n\t\tconst registeredTransientIds = new Set(registeredTransient.map((resource) => resource.id));\n\t\tconst accessedTransientIds = new Set(input.accessEdges\n\t\t\t.filter((access) => allIds.has(access.nodeId) && registeredTransientIds.has(access.resource.id))\n\t\t\t.map((access) => access.resource.id));\n\t\tconst allocationIds = new Set(registeredTransient.flatMap((resource) => (\n\t\t\tresource.physicalResourceId === undefined ? [] : [resource.physicalResourceId]\n\t\t)));\n\t\tconst segmentIds = new Set(input.executionSegments\n\t\t\t.filter((segment) => segment.nodeIds.some((id) => retainedIds.has(id)))\n\t\t\t.map((segment) => segment.index));\n\t\tconst timingEligible = retained.filter((node) => node.kind === 'render' || node.kind === 'compute');\n\t\tconst timed = timingEligible.filter((node) => node.gpuDurationMicros !== undefined);\n\n\t\treturn {\n\t\t\t...group,\n\t\t\tsummary: {\n\t\t\t\tretainedNodeCount: retained.length,\n\t\t\t\tculledNodeCount: culled.length,\n\t\t\t\tnodeKindCounts,\n\t\t\t\tinputResources: [...inputIds].map((id) => resourcesById.get(id)!).filter(Boolean),\n\t\t\t\toutputResources: [...outputIds].map((id) => resourcesById.get(id)!).filter(Boolean),\n\t\t\t\tregisteredTransientResourceCount: registeredTransient.length,\n\t\t\t\taccessedTransientResourceCount: accessedTransientIds.size,\n\t\t\t\tphysicalAllocationCount: allocationIds.size,\n\t\t\t\texecutionSegmentCount: segmentIds.size,\n\t\t\t\texternalSubmissionCount: retained.filter((node) => node.kind === 'external-submission').length,\n\t\t\t\tgpuWorkDurationMicros: timed.reduce((sum, node) => sum + node.gpuDurationMicros!, 0),\n\t\t\t\ttimedNodeCount: timed.length,\n\t\t\t\ttimingEligibleNodeCount: timingEligible.length,\n\t\t\t},\n\t\t};\n\t});\n}\n"]}
1
+ {"version":3,"file":"debugCaptureModel.js","sourceRoot":"","sources":["../src/debugCaptureModel.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tFrameGraphSnapshot,\n\tFrameGraphSnapshotAccessKind,\n\tFrameGraphSnapshotBufferRange,\n\tFrameGraphSnapshotGpuTimings,\n\tFrameGraphSnapshotNodeKind,\n\tFrameGraphSnapshotResourceKind,\n\tFrameGraphSnapshotResourceOrigin,\n\tFrameGraphSnapshotRoot,\n\tFrameGraphSnapshotSegment,\n\tFrameGraphSnapshotTextureRegion,\n\tFrameGraphSnapshotWriteContents,\n} from '@zenfg/snapshot';\n\ntype ResourceAccessMode = 'read' | 'write';\n\nexport type FrameGraphDebugExecutionSegment = FrameGraphSnapshotSegment & {\n\treadonly index: number;\n};\n\nexport type FrameGraphDebugResourceRef = {\n readonly id: string;\n readonly kind: FrameGraphSnapshotResourceKind;\n readonly label?: string;\n};\n\ntype FrameGraphDebugAccessEdgeBase = {\n\treadonly accessId: string;\n\treadonly nodeId: string;\n readonly resource: FrameGraphDebugResourceRef;\n\treadonly access: FrameGraphSnapshotAccessKind;\n\treadonly textureViewId?: string;\n\treadonly textureRegion?: FrameGraphSnapshotTextureRegion;\n\treadonly bufferRange?: FrameGraphSnapshotBufferRange;\n};\n\nexport type FrameGraphDebugAccessEdge = FrameGraphDebugAccessEdgeBase & (\n | {\n readonly mode: 'read';\n readonly producesValue: false;\n readonly contents?: never;\n }\n | {\n readonly mode: 'write';\n\t\treadonly contents: FrameGraphSnapshotWriteContents;\n readonly producesValue: boolean;\n }\n);\n\nexport type FrameGraphDebugAccess = FrameGraphDebugAccessEdge extends infer TAccess\n\t? TAccess extends FrameGraphDebugAccessEdge ? Omit<TAccess, 'nodeId'> : never\n : never;\n\nexport type FrameGraphDebugNode = {\n\treadonly id: string;\n readonly order: number;\n\treadonly kind: FrameGraphSnapshotNodeKind;\n readonly label?: string;\n\treadonly sideEffect: boolean;\n\treadonly debugGroupId?: string;\n readonly gpuDurationMicros?: number;\n readonly reads: readonly FrameGraphDebugAccess[];\n readonly writes: readonly FrameGraphDebugAccess[];\n};\n\nexport type FrameGraphDebugResource = FrameGraphDebugResourceRef & {\n\treadonly origin: FrameGraphSnapshotResourceOrigin;\n\treadonly initialContents?: 'defined' | 'undefined';\n\treadonly debugGroupId?: string;\n\treadonly usageFlags: readonly string[];\n readonly lifetime?: { readonly firstUse: number; readonly lastUse: number };\n\treadonly physicalResourceId?: string;\n\treadonly descriptor?: FrameGraphSnapshot['graph']['resources'][number]['descriptor'];\n\treadonly estimatedByteSize?: number;\n};\n\nexport type FrameGraphDebugEdge = {\n\treadonly fromNodeId: string;\n\treadonly toNodeId: string;\n readonly resource: FrameGraphDebugResourceRef;\n readonly kind: 'value' | 'ordering';\n};\n\nexport type FrameGraphDebugRoot = FrameGraphSnapshotRoot & {\n\treadonly key: string;\n readonly resource?: FrameGraphDebugResourceRef;\n};\n\n/** Semantic identity within one recording, independent of root array order. */\nexport function rootKey(root: FrameGraphSnapshotRoot): string {\n\treturn root.reason === 'side-effect' ? JSON.stringify([root.reason, root.nodeId])\n\t\t: JSON.stringify([root.reason, root.resourceId, root.range?.kind === 'buffer'\n\t\t\t? ['buffer', root.range.offset, root.range.size]\n\t\t\t: root.range?.regions.map((r) => [r.baseMipLevel, r.mipLevelCount, r.aspect, r.baseArrayLayer, r.arrayLayerCount, r.baseDepthSlice, r.depthSliceCount]) ?? null]);\n}\n\nexport type FrameGraphDebugCulledNode = {\n readonly node: Omit<FrameGraphDebugNode, 'order'>;\n readonly reason: string;\n};\n\nexport type FrameGraphDebugPhysicalAllocation = {\n\treadonly id: string;\n\treadonly kind: FrameGraphSnapshotResourceKind;\n\treadonly compatibilityClassId: string;\n\treadonly estimatedByteSize?: number;\n\treadonly resourceIds: readonly string[];\n};\n\nexport type FrameGraphDebugGroupSummary = {\n\treadonly retainedNodeCount: number;\n\treadonly culledNodeCount: number;\n\treadonly nodeKindCounts: Readonly<Partial<Record<FrameGraphSnapshotNodeKind, number>>>;\n\treadonly inputResources: readonly FrameGraphDebugResourceRef[];\n\treadonly outputResources: readonly FrameGraphDebugResourceRef[];\n\treadonly outputRoots: readonly FrameGraphDebugRoot[];\n\treadonly registeredTransientResourceCount: number;\n\treadonly accessedTransientResourceCount: number;\n\treadonly physicalAllocationCount: number;\n\treadonly executionSegmentCount: number;\n\treadonly externalSubmissionCount: number;\n\treadonly gpuWorkDurationMicros: number;\n\treadonly timedNodeCount: number;\n\treadonly timingEligibleNodeCount: number;\n};\n\nexport type FrameGraphDebugGroup = {\n\treadonly id: string;\n\treadonly parentId?: string;\n\treadonly label: string;\n\treadonly path: readonly string[];\n\t/** Stable while same-named siblings retain their recording-order occurrence. */\n\treadonly pathKey: string;\n\treadonly depth: number;\n\t/** Ordered ancestor ids from root through this group. */\n\treadonly ancestorIds: readonly string[];\n\treadonly summary: FrameGraphDebugGroupSummary;\n};\n\nexport type FrameGraphDebugMetrics = {\n\treadonly timingEligibleNodeCount: number;\n\treadonly timedNodeCount: number;\n\treadonly slowestNode?: FrameGraphDebugNode;\n\treadonly transientEstimatedByteSize?: number;\n\treadonly logicalCapacityBytes?: number;\n\treadonly physicalEstimatedBytes?: number;\n\treadonly aliasReuseBytes?: number;\n\treadonly aliasedAllocationCount: number;\n};\n\nexport type FrameGraphDebugSnapshotSource = {\n\treadonly kind: 'live' | 'file' | 'programmatic';\n\treadonly label: string;\n\treadonly migratedFromLegacy?: boolean;\n};\n\nexport type FrameGraphDebugViewModel = {\n\treadonly protocol: FrameGraphSnapshot;\n\treadonly source: FrameGraphDebugSnapshotSource;\n readonly frameIndex: number;\n readonly nodes: readonly FrameGraphDebugNode[];\n readonly resources: readonly FrameGraphDebugResource[];\n readonly edges: readonly FrameGraphDebugEdge[];\n readonly accessEdges: readonly FrameGraphDebugAccessEdge[];\n readonly roots: readonly FrameGraphDebugRoot[];\n readonly culledNodes: readonly FrameGraphDebugCulledNode[];\n\treadonly physicalAllocations: readonly FrameGraphDebugPhysicalAllocation[];\n\treadonly debugGroups: readonly FrameGraphDebugGroup[];\n\treadonly executionSegments: readonly FrameGraphDebugExecutionSegment[];\n\treadonly textureViewById: ReadonlyMap<string, FrameGraphSnapshot['graph']['textureViews'][number]>;\n\treadonly nodeById: ReadonlyMap<string, FrameGraphDebugNode>;\n\treadonly resourceById: ReadonlyMap<string, FrameGraphDebugResource>;\n\treadonly groupById: ReadonlyMap<string, FrameGraphDebugGroup>;\n\treadonly groupByPathKey: ReadonlyMap<string, FrameGraphDebugGroup>;\n\treadonly allocationById: ReadonlyMap<string, FrameGraphDebugPhysicalAllocation>;\n\treadonly accessesByNodeId: ReadonlyMap<string, readonly FrameGraphDebugAccessEdge[]>;\n\treadonly accessesByResourceId: ReadonlyMap<string, readonly FrameGraphDebugAccessEdge[]>;\n\treadonly segmentByNodeId: ReadonlyMap<string, FrameGraphDebugExecutionSegment>;\n\treadonly segmentByIndex: ReadonlyMap<number, FrameGraphDebugExecutionSegment>;\n\treadonly metrics: FrameGraphDebugMetrics;\n readonly profiling:\n | {\n readonly status: 'available';\n readonly frameIndex: number;\n\t\t\treadonly timings: readonly { readonly nodeId: string; readonly gpuDurationMicros: number }[];\n readonly gpuFrameDurationMicros: number;\n }\n | {\n readonly status: 'unavailable';\n readonly frameIndex: number;\n\t\t\treadonly reason: Extract<FrameGraphSnapshotGpuTimings, { readonly status: 'unavailable' }>['reason'];\n readonly timings: readonly [];\n };\n\treadonly resourcePool: FrameGraphSnapshot['memory']['poolReport'];\n\treadonly availability: {\n\t\treadonly groups: boolean;\n\t\treadonly textureViews: boolean;\n\t\treadonly recordingOrder: boolean;\n\t\treadonly accessRegions: boolean;\n\t};\n};\n\nexport function createDebugViewModel(\n\tsnapshot: FrameGraphSnapshot,\n\tsource: FrameGraphDebugSnapshotSource = { kind: 'programmatic', label: 'Programmatic' },\n): FrameGraphDebugViewModel {\n\tconst compilation = snapshot.graph;\n\tconst unavailable = new Set(snapshot.capture.migration?.unavailableFacts ?? []);\n\tconst availability = {\n\t\tgroups: !unavailable.has('graph.groups'),\n\t\ttextureViews: !unavailable.has('graph.textureViews'),\n\t\trecordingOrder: !unavailable.has('graph.nodes.recordingOrder'),\n\t\taccessRegions: !unavailable.has('graph.accesses.regions'),\n\t};\n\tconst resolvedSource: FrameGraphDebugSnapshotSource = snapshot.capture.migration?.sourceFormat === 'legacy-v0'\n\t\t? { ...source, migratedFromLegacy: true }\n\t\t: source;\n\tconst gpuTiming = snapshot.timings.gpu;\n\tconst resourcePool = snapshot.memory.poolReport;\n\tconst normalizedGroups = normalizeDebugGroups(compilation);\n\tconst knownGroupIds = new Set(normalizedGroups.map((group) => group.id));\n\tvalidateDebugGroupReferences(compilation, knownGroupIds);\n\tconst resourcesById = new Map(compilation.resources.map((resource) => [resource.id, resource]));\n\tconst resourceRef = (resourceId: string): FrameGraphDebugResourceRef => {\n const resource = resourcesById.get(resourceId);\n if (!resource) {\n throw new Error(`Compilation report references unknown resource ${resourceId}.`);\n }\n return { id: resource.id, kind: resource.kind, label: resource.label };\n };\n const accessEdges = compilation.accesses.map((access): FrameGraphDebugAccessEdge => {\n const common = {\n accessId: access.id,\n nodeId: access.nodeId,\n resource: resourceRef(access.resourceId),\n access: access.access,\n textureViewId: access.textureViewId,\n textureRegion: access.textureRegion,\n bufferRange: access.bufferRange,\n };\n return access.mode === 'read'\n ? { ...common, mode: 'read', producesValue: false }\n : {\n ...common,\n mode: 'write',\n contents: access.contents,\n producesValue: access.producesValue,\n };\n });\n\tconst accessesByNode = new Map<string, FrameGraphDebugAccessEdge[]>();\n\tconst accessesByResource = new Map<string, FrameGraphDebugAccessEdge[]>();\n for (const access of accessEdges) {\n const nodeAccesses = accessesByNode.get(access.nodeId) ?? [];\n nodeAccesses.push(access);\n accessesByNode.set(access.nodeId, nodeAccesses);\n\t\tconst resourceAccesses = accessesByResource.get(access.resource.id) ?? [];\n\t\tresourceAccesses.push(access);\n\t\taccessesByResource.set(access.resource.id, resourceAccesses);\n }\n\tconst timings = gpuTiming.status === 'available'\n ? new Map(gpuTiming.nodes.map((timing) => [timing.nodeId, timing.durationMicros]))\n : new Map<string, number>();\n\tconst nodeAccesses = (nodeId: string, mode: ResourceAccessMode): FrameGraphDebugAccess[] => (\n (accessesByNode.get(nodeId) ?? [])\n .filter((access) => access.mode === mode)\n\t\t\t.map(({ nodeId: _nodeId, ...access }) => access)\n\t);\n\tconst nodes: FrameGraphDebugNode[] = compilation.nodes\n\t\t.filter((node) => node.compileState.status === 'retained')\n\t\t.sort((a, b) => a.compileState.status === 'retained' && b.compileState.status === 'retained'\n\t\t\t? a.compileState.executionOrder - b.compileState.executionOrder\n\t\t\t: 0)\n\t\t.map((node) => ({\n\t\tid: node.id,\n\t\torder: node.compileState.status === 'retained' ? node.compileState.executionOrder : 0,\n\t\tkind: node.kind,\n\t\tlabel: node.label,\n\t\tsideEffect: node.sideEffect,\n\t\tdebugGroupId: node.groupId,\n\t\tgpuDurationMicros: timings.get(node.id),\n\t\treads: nodeAccesses(node.id, 'read'),\n\t\twrites: nodeAccesses(node.id, 'write'),\n\t}));\n\tconst resources: FrameGraphDebugResource[] = compilation.resources.map((resource) => ({\n\t\tid: resource.id,\n\t\tkind: resource.kind,\n\t\tlabel: resource.label,\n\t\torigin: resource.origin,\n\t\tinitialContents: resource.initialContents,\n\t\tdebugGroupId: resource.groupId,\n\t\tusageFlags: resource.usageFlags,\n\t\tlifetime: resource.lifetime,\n\t\tphysicalResourceId: resource.allocationId,\n\t\tdescriptor: resource.descriptor,\n\t\testimatedByteSize: resource.estimatedByteSize,\n\t}));\n\tconst edges: FrameGraphDebugEdge[] = compilation.dependencies.map((dependency) => ({\n\t\t...dependency,\n\t\tresource: resourceRef(dependency.resourceId),\n\t}));\n\tconst roots: FrameGraphDebugRoot[] = compilation.roots.map((root) => ({\n\t\t...root,\n\t\tkey: rootKey(root),\n\t\tresource: root.resourceId === undefined ? undefined : resourceRef(root.resourceId),\n\t}));\n\tconst culledNodes: FrameGraphDebugCulledNode[] = compilation.nodes\n\t\t.filter((node) => node.compileState.status === 'culled')\n\t\t.map((node) => ({\n\t\tnode: {\n\t\t\tid: node.id,\n\t\t\tkind: node.kind,\n\t\t\tlabel: node.label,\n\t\t\tsideEffect: node.sideEffect,\n\t\t\tdebugGroupId: node.groupId,\n\t\t\treads: nodeAccesses(node.id, 'read'),\n\t\t\twrites: nodeAccesses(node.id, 'write'),\n\t\t},\n\t\treason: node.compileState.status === 'culled' ? node.compileState.reason : 'unknown',\n\t}));\n\tconst resourceIdsByAllocation = new Map<string, string[]>();\n\tfor (const resource of compilation.resources) {\n\t\tif (resource.allocationId === undefined) continue;\n\t\tconst resourceIds = resourceIdsByAllocation.get(resource.allocationId) ?? [];\n\t\tresourceIds.push(resource.id);\n\t\tresourceIdsByAllocation.set(resource.allocationId, resourceIds);\n\t}\n\tconst physicalAllocations: FrameGraphDebugPhysicalAllocation[] = snapshot.memory.allocationReport.status === 'available'\n\t\t? snapshot.memory.allocationReport.allocations.map((allocation) => ({\n\t\t\t...allocation,\n\t\t\tresourceIds: resourceIdsByAllocation.get(allocation.id) ?? [],\n\t\t}))\n\t\t: [];\n\tconst executionSegments: FrameGraphDebugExecutionSegment[] = compilation.segments.map((segment) => ({\n\t\t...segment,\n\t\tindex: segment.order,\n\t}));\n\tconst debugGroups = buildDebugGroupSummaries({\n\t\tgroups: normalizedGroups,\n\t\tnodes,\n\t\tculledNodes,\n\t\tresources,\n\t\taccessEdges,\n\t\tedges,\n\t\troots,\n\t\texecutionSegments,\n\t});\n\tconst nodeById = new Map(nodes.map((node) => [node.id, node]));\n\tconst resourceById = new Map(resources.map((resource) => [resource.id, resource]));\n\tconst groupById = new Map(debugGroups.map((group) => [group.id, group]));\n\tconst groupByPathKey = new Map(debugGroups.map((group) => [group.pathKey, group]));\n\tconst allocationById = new Map(physicalAllocations.map((allocation) => [allocation.id, allocation]));\n\tconst textureViewById = new Map(compilation.textureViews.map((view) => [view.id, view]));\n\tconst segmentByNodeId = new Map<string, FrameGraphDebugExecutionSegment>();\n\tconst segmentByIndex = new Map(executionSegments.map((segment) => [segment.index, segment]));\n\tfor (const segment of executionSegments) {\n\t\tfor (const nodeId of segment.nodeIds) segmentByNodeId.set(nodeId, segment);\n\t}\n\tconst timingEligibleNodes = nodes.filter((node) => node.kind === 'render' || node.kind === 'compute');\n\tconst timedNodes = timingEligibleNodes.filter((node) => node.gpuDurationMicros !== undefined);\n\tconst slowestNode = timedNodes.reduce<FrameGraphDebugNode | undefined>((slowest, node) => (\n\t\t!slowest || node.gpuDurationMicros! > slowest.gpuDurationMicros! ? node : slowest\n\t), undefined);\n\tconst transientResources = resources.filter((resource) => resource.origin === 'transient');\n\tconst transientEstimatedByteSize = sumKnown(transientResources.map((resource) => resource.estimatedByteSize));\n\tconst physicalEstimatedBytes = sumKnown(physicalAllocations.map((allocation) => allocation.estimatedByteSize));\n\tconst logicalAllocationSizes = transientResources\n\t\t.filter((resource) => resource.physicalResourceId !== undefined)\n\t\t.map((resource) => allocationById.get(resource.physicalResourceId!)?.estimatedByteSize);\n\tconst logicalCapacityBytes = sumKnown(logicalAllocationSizes);\n\tconst metrics: FrameGraphDebugMetrics = {\n\t\ttimingEligibleNodeCount: timingEligibleNodes.length,\n\t\ttimedNodeCount: timedNodes.length,\n\t\tslowestNode,\n\t\ttransientEstimatedByteSize,\n\t\tlogicalCapacityBytes,\n\t\tphysicalEstimatedBytes,\n\t\taliasReuseBytes: logicalCapacityBytes === undefined || physicalEstimatedBytes === undefined\n\t\t\t? undefined\n\t\t\t: Math.max(0, logicalCapacityBytes - physicalEstimatedBytes),\n\t\taliasedAllocationCount: physicalAllocations.filter((allocation) => allocation.resourceIds.length > 1).length,\n\t};\n\n\treturn {\n\t\tprotocol: snapshot,\n\t\tsource: resolvedSource,\n\t\tframeIndex: snapshot.capture.frameIndex,\n\t\tnodes,\n\t\tresources,\n\t\tedges,\n\t\taccessEdges,\n\t\troots,\n\t\tculledNodes,\n\t\tphysicalAllocations,\n\t\tdebugGroups,\n\t\texecutionSegments,\n\t\ttextureViewById,\n\t\tnodeById,\n\t\tresourceById,\n\t\tgroupById,\n\t\tgroupByPathKey,\n\t\tallocationById,\n\t\taccessesByNodeId: accessesByNode,\n\t\taccessesByResourceId: accessesByResource,\n\t\tsegmentByNodeId,\n\t\tsegmentByIndex,\n\t\tmetrics,\n profiling: gpuTiming.status === 'available'\n ? {\n status: 'available',\n frameIndex: snapshot.capture.frameIndex,\n timings: gpuTiming.nodes.map((timing) => ({\n nodeId: timing.nodeId,\n gpuDurationMicros: timing.durationMicros,\n })),\n gpuFrameDurationMicros: gpuTiming.frameSpanMicros,\n }\n : {\n status: 'unavailable',\n frameIndex: snapshot.capture.frameIndex,\n timings: [],\n reason: gpuTiming.reason,\n },\n\t\tresourcePool,\n\t\tavailability,\n\t};\n}\n\nfunction sumKnown(values: readonly (number | undefined)[]): number | undefined {\n\tlet total = 0;\n\tfor (const value of values) {\n\t\tif (value === undefined) return undefined;\n\t\ttotal += value;\n\t}\n\treturn total;\n}\n\ntype NormalizedDebugGroup = Omit<FrameGraphDebugGroup, 'summary'>;\n\nfunction normalizeDebugGroups(compilation: FrameGraphSnapshot['graph']): NormalizedDebugGroup[] {\n\tconst rawGroups = compilation.groups;\n\tconst rawById = new Map<string, FrameGraphSnapshot['graph']['groups'][number]>();\n\tconst siblingOccurrences = new Map<string, number>();\n\tconst nextOccurrenceByParent = new Map<string | undefined, Map<string, number>>();\n\tfor (const group of rawGroups) {\n\t\tif (rawById.has(group.id)) {\n\t\t\tthrow new Error(`Compilation report contains duplicate debug group id ${group.id}.`);\n\t\t}\n\t\tconst label = group.label.trim();\n\t\tif (label.length === 0) {\n\t\t\tthrow new Error(`Compilation report debug group ${group.id} has an empty label.`);\n\t\t}\n\t\trawById.set(group.id, { ...group, label });\n\t\tconst nextOccurrenceByLabel = nextOccurrenceByParent.get(group.parentId) ?? new Map<string, number>();\n\t\tconst occurrence = nextOccurrenceByLabel.get(label) ?? 0;\n\t\tsiblingOccurrences.set(group.id, occurrence);\n\t\tnextOccurrenceByLabel.set(label, occurrence + 1);\n\t\tnextOccurrenceByParent.set(group.parentId, nextOccurrenceByLabel);\n\t}\n\n\tconst normalizedById = new Map<string, NormalizedDebugGroup>();\n\tconst identityPathById = new Map<string, readonly (readonly [label: string, siblingOccurrence: number])[]>();\n\tconst visiting = new Set<string>();\n\tconst resolve = (id: string): NormalizedDebugGroup => {\n\t\tconst existing = normalizedById.get(id);\n\t\tif (existing) return existing;\n\t\tconst raw = rawById.get(id);\n\t\tif (!raw) throw new Error(`Compilation report references unknown debug group ${id}.`);\n\t\tif (visiting.has(id)) throw new Error(`Compilation report debug group ${id} has a parent cycle.`);\n\t\tvisiting.add(id);\n\t\tconst parent = raw.parentId === undefined ? undefined : resolve(raw.parentId);\n\t\tconst path = [...(parent?.path ?? []), raw.label];\n\t\tconst identityPath = [\n\t\t\t...(raw.parentId === undefined ? [] : identityPathById.get(raw.parentId)!),\n\t\t\t[raw.label, siblingOccurrences.get(raw.id)!] as const,\n\t\t];\n\t\tconst ancestorIds = [...(parent?.ancestorIds ?? []), raw.id];\n\t\tconst normalized: NormalizedDebugGroup = {\n\t\t\tid: raw.id,\n\t\t\tparentId: raw.parentId,\n\t\t\tlabel: raw.label,\n\t\t\tpath,\n\t\t\tpathKey: JSON.stringify(identityPath),\n\t\t\tdepth: path.length - 1,\n\t\t\tancestorIds,\n\t\t};\n\t\tvisiting.delete(id);\n\t\tidentityPathById.set(id, identityPath);\n\t\tnormalizedById.set(id, normalized);\n\t\treturn normalized;\n\t};\n\treturn rawGroups.map((group) => resolve(group.id));\n}\n\nfunction validateDebugGroupReferences(\n\tcompilation: FrameGraphSnapshot['graph'],\n\tknownGroupIds: ReadonlySet<string>,\n): void {\n\tfor (const entry of [...compilation.nodes, ...compilation.resources]) {\n\t\tif (entry.groupId !== undefined && !knownGroupIds.has(entry.groupId)) {\n\t\t\tthrow new Error(`Compilation report references unknown debug group ${entry.groupId}.`);\n\t\t}\n\t}\n}\n\n/** Declaration boundaries are topological, not per-range initial-value provenance. */\nexport function declarationEntrances(\n\tnodes: readonly FrameGraphDebugNode[],\n\taccesses: readonly FrameGraphDebugAccessEdge[],\n\tedges: readonly FrameGraphDebugEdge[],\n): readonly FrameGraphDebugAccessEdge[] {\n\tconst retained = new Set(nodes.map((node) => node.id));\n\tconst incoming = new Set(edges.map((edge) => JSON.stringify([edge.resource.id, edge.toNodeId])));\n\tconst seen = new Set<string>();\n\treturn accesses.filter((access) => {\n\t\tconst key = JSON.stringify([access.resource.id, access.nodeId]);\n\t\tif (!retained.has(access.nodeId) || incoming.has(key) || seen.has(key)) return false;\n\t\tseen.add(key);\n\t\treturn true;\n\t});\n}\n\nfunction buildDebugGroupSummaries(input: {\n\treadonly groups: readonly NormalizedDebugGroup[];\n\treadonly nodes: readonly FrameGraphDebugNode[];\n\treadonly culledNodes: readonly FrameGraphDebugCulledNode[];\n\treadonly resources: readonly FrameGraphDebugResource[];\n\treadonly accessEdges: readonly FrameGraphDebugAccessEdge[];\n\treadonly edges: readonly FrameGraphDebugEdge[];\n\treadonly roots: readonly FrameGraphDebugRoot[];\n\treadonly executionSegments: readonly FrameGraphDebugExecutionSegment[];\n}): FrameGraphDebugGroup[] {\n\tconst groupsById = new Map(input.groups.map((group) => [group.id, group]));\n\tconst resourcesById = new Map(input.resources.map((resource) => [resource.id, resource]));\n\tconst entrances = declarationEntrances(input.nodes, input.accessEdges, input.edges);\n\tconst isInGroup = (candidateId: string | undefined, groupId: string) => (\n\t\tcandidateId !== undefined && groupsById.get(candidateId)?.ancestorIds.includes(groupId) === true\n\t);\n\n\treturn input.groups.map((group): FrameGraphDebugGroup => {\n\t\tconst retained = input.nodes.filter((node) => isInGroup(node.debugGroupId, group.id));\n\t\tconst culled = input.culledNodes.filter((entry) => isInGroup(entry.node.debugGroupId, group.id));\n\t\tconst retainedIds = new Set(retained.map((node) => node.id));\n\t\tconst allIds = new Set([...retainedIds, ...culled.map((entry) => entry.node.id)]);\n\t\tconst nodeKindCounts: Partial<Record<FrameGraphSnapshotNodeKind, number>> = {};\n\t\tfor (const node of [...retained, ...culled.map((entry) => entry.node)]) {\n\t\t\tnodeKindCounts[node.kind] = (nodeKindCounts[node.kind] ?? 0) + 1;\n\t\t}\n\n\t\tconst inputIds = new Set<string>();\n\t\tconst outputIds = new Set<string>();\n\t\tfor (const edge of input.edges) {\n\t\t\tconst fromInside = retainedIds.has(edge.fromNodeId);\n\t\t\tconst toInside = retainedIds.has(edge.toNodeId);\n\t\t\tif (!fromInside && toInside) inputIds.add(edge.resource.id);\n\t\t\tif (fromInside && !toInside) outputIds.add(edge.resource.id);\n\t\t}\n\t\tfor (const access of entrances) {\n\t\t\tconst fromInside = isInGroup(resourcesById.get(access.resource.id)?.debugGroupId, group.id);\n\t\t\tconst toInside = retainedIds.has(access.nodeId);\n\t\t\tif (!fromInside && toInside) inputIds.add(access.resource.id);\n\t\t\tif (fromInside && !toInside) outputIds.add(access.resource.id);\n\t\t}\n\t\tconst outputRoots: FrameGraphDebugRoot[] = [];\n\t\tfor (const root of input.roots) {\n\t\t\tif (!root.resource) continue;\n\t\t\tif (root.resolution?.producerNodeIds.some((id) => retainedIds.has(id))\n\t\t\t\t|| root.resolution?.usesInitialContents && isInGroup(resourcesById.get(root.resource.id)?.debugGroupId, group.id)) {\n\t\t\t\toutputIds.add(root.resource.id);\n\t\t\t\toutputRoots.push(root);\n\t\t\t}\n\t\t}\n\n\t\tconst registeredTransient = input.resources.filter((resource) => resource.origin === 'transient'\n\t\t\t&& isInGroup(resource.debugGroupId, group.id));\n\t\tconst registeredTransientIds = new Set(registeredTransient.map((resource) => resource.id));\n\t\tconst accessedTransientIds = new Set(input.accessEdges\n\t\t\t.filter((access) => allIds.has(access.nodeId) && registeredTransientIds.has(access.resource.id))\n\t\t\t.map((access) => access.resource.id));\n\t\tconst allocationIds = new Set(registeredTransient.flatMap((resource) => (\n\t\t\tresource.physicalResourceId === undefined ? [] : [resource.physicalResourceId]\n\t\t)));\n\t\tconst segmentIds = new Set(input.executionSegments\n\t\t\t.filter((segment) => segment.nodeIds.some((id) => retainedIds.has(id)))\n\t\t\t.map((segment) => segment.index));\n\t\tconst timingEligible = retained.filter((node) => node.kind === 'render' || node.kind === 'compute');\n\t\tconst timed = timingEligible.filter((node) => node.gpuDurationMicros !== undefined);\n\n\t\treturn {\n\t\t\t...group,\n\t\t\tsummary: {\n\t\t\t\tretainedNodeCount: retained.length,\n\t\t\t\tculledNodeCount: culled.length,\n\t\t\t\tnodeKindCounts,\n\t\t\t\tinputResources: [...inputIds].map((id) => resourcesById.get(id)!).filter(Boolean),\n\t\t\t\toutputResources: [...outputIds].map((id) => resourcesById.get(id)!).filter(Boolean),\n\t\t\t\toutputRoots,\n\t\t\t\tregisteredTransientResourceCount: registeredTransient.length,\n\t\t\t\taccessedTransientResourceCount: accessedTransientIds.size,\n\t\t\t\tphysicalAllocationCount: allocationIds.size,\n\t\t\t\texecutionSegmentCount: segmentIds.size,\n\t\t\t\texternalSubmissionCount: retained.filter((node) => node.kind === 'external-submission').length,\n\t\t\t\tgpuWorkDurationMicros: timed.reduce((sum, node) => sum + node.gpuDurationMicros!, 0),\n\t\t\t\ttimedNodeCount: timed.length,\n\t\t\t\ttimingEligibleNodeCount: timingEligible.length,\n\t\t\t},\n\t\t};\n\t});\n}\n"]}
@@ -40,7 +40,7 @@ export declare class CytoscapeGraphRenderer implements GraphRenderer {
40
40
  private anchorTargetContentKey;
41
41
  private failedSceneContentKey;
42
42
  private overview;
43
- private lastTap;
43
+ private pendingGroupTap;
44
44
  constructor(host: HTMLElement, environment?: GraphRendererEnvironment);
45
45
  render(request: GraphRenderRequest): void;
46
46
  resize(): void;
@@ -60,6 +60,8 @@ export declare class CytoscapeGraphRenderer implements GraphRenderer {
60
60
  private updateSemanticZoom;
61
61
  private positionTooltip;
62
62
  private hideTooltip;
63
+ private cancelGroupTap;
64
+ private clearHover;
63
65
  private showStatus;
64
66
  private hideStatus;
65
67
  private resolveCurrentRequest;
@@ -1 +1 @@
1
- {"version":3,"file":"panelCytoscapeGraphRenderer.d.ts","sourceRoot":"","sources":["../src/panelCytoscapeGraphRenderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"panelCytoscapeGraphRenderer.d.ts","sourceRoot":"","sources":["../src/panelCytoscapeGraphRenderer.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,7 @@ export class CytoscapeGraphRenderer {
25
25
  anchorTargetContentKey;
26
26
  failedSceneContentKey;
27
27
  overview = false;
28
- lastTap;
28
+ pendingGroupTap;
29
29
  constructor(host, environment = browserGraphRendererEnvironment) {
30
30
  this.host = host;
31
31
  this.environment = environment;
@@ -34,6 +34,8 @@ export class CytoscapeGraphRenderer {
34
34
  this.tooltip = environment.createElement('div');
35
35
  this.tooltip.className = 'zenfg-inspector-graph-tooltip';
36
36
  this.tooltip.hidden = true;
37
+ // Cytoscape's node mouseout is not guaranteed when leaving its canvas directly.
38
+ this.canvasHost.addEventListener('pointerleave', () => this.clearHover());
37
39
  this.status = environment.createElement('div');
38
40
  this.status.className = 'zenfg-inspector-graph-status';
39
41
  this.status.hidden = true;
@@ -52,6 +54,14 @@ export class CytoscapeGraphRenderer {
52
54
  render(request) {
53
55
  if (this.destroyed)
54
56
  return;
57
+ if (this.latestRequest?.scene !== request.scene
58
+ || (this.latestRequest?.selected && selectionKey(this.latestRequest.selected)) !== (request.selected && selectionKey(request.selected))) {
59
+ this.cancelGroupTap();
60
+ }
61
+ if ((!request.hovered && !this.tooltip.hidden) || this.latestRequest?.scene.contentKey !== request.scene.contentKey) {
62
+ this.hideTooltip();
63
+ this.core?.elements().removeClass('semantic-hover');
64
+ }
55
65
  this.latestRequest = request;
56
66
  if (request.fit) {
57
67
  this.fitTargetContentKey = request.scene.contentKey;
@@ -105,6 +115,7 @@ export class CytoscapeGraphRenderer {
105
115
  relayout() {
106
116
  if (!this.latestRequest || this.destroyed)
107
117
  return;
118
+ this.cancelGroupTap();
108
119
  this.failedSceneContentKey = undefined;
109
120
  this.forceRelayout = true;
110
121
  this.fitTargetContentKey = this.latestRequest.scene.contentKey;
@@ -118,6 +129,7 @@ export class CytoscapeGraphRenderer {
118
129
  if (this.destroyed)
119
130
  return;
120
131
  this.destroyed = true;
132
+ this.cancelGroupTap();
121
133
  this.requestVersion++;
122
134
  this.resizeSubscription?.disconnect();
123
135
  this.hideTooltip();
@@ -284,22 +296,28 @@ export class CytoscapeGraphRenderer {
284
296
  return;
285
297
  const id = event.target.id();
286
298
  const selection = request.scene.interaction.selectionByElementId.get(id);
287
- if (selection)
288
- request.onSelect(selection);
289
- const now = performance.now();
290
- if (this.lastTap?.id === id && now - this.lastTap.at <= 350 && selection?.kind === 'group') {
299
+ const doubleTap = this.pendingGroupTap?.id === id;
300
+ this.cancelGroupTap();
301
+ if (selection?.kind !== 'group') {
302
+ if (selection)
303
+ request.onSelect(selection);
304
+ }
305
+ else if (doubleTap) {
291
306
  request.onToggleGroup(selection.pathKey);
292
- this.lastTap = undefined;
293
307
  }
294
308
  else {
295
- this.lastTap = { id, at: now };
309
+ // Defer group selection so expansion does not replace the inspected resource.
310
+ this.pendingGroupTap = { id, timer: setTimeout(() => {
311
+ this.pendingGroupTap = undefined;
312
+ this.interactiveRequest()?.onSelect(selection);
313
+ }, 350) };
296
314
  }
297
315
  };
298
316
  core.on('tap', 'node', selectElement);
299
317
  core.on('tap', 'edge', selectElement);
300
318
  core.on('tap', (event) => {
301
319
  if (event.target === core)
302
- this.lastTap = undefined;
320
+ this.cancelGroupTap();
303
321
  });
304
322
  const hoverElement = (event) => {
305
323
  const request = this.interactiveRequest();
@@ -321,10 +339,7 @@ export class CytoscapeGraphRenderer {
321
339
  const moveTooltip = (event) => this.positionTooltip(event.renderedPosition);
322
340
  core.on('mousemove', 'node', moveTooltip);
323
341
  core.on('mousemove', 'edge', moveTooltip);
324
- const clearHover = () => {
325
- this.hideTooltip();
326
- this.latestRequest?.onHover(undefined);
327
- };
342
+ const clearHover = () => this.clearHover();
328
343
  core.on('mouseout', 'node', clearHover);
329
344
  core.on('mouseout', 'edge', clearHover);
330
345
  core.on('zoom', () => this.updateSemanticZoom());
@@ -340,7 +355,7 @@ export class CytoscapeGraphRenderer {
340
355
  core.batch(() => {
341
356
  core.elements().removeClass('semantic-selected semantic-hover');
342
357
  if (request.hovered) {
343
- for (const id of request.scene.interaction.relatedElementIdsBySelection.get(selectionKey(request.hovered)) ?? []) {
358
+ for (const id of request.scene.interaction.hoverElementIdsBySelection.get(selectionKey(request.hovered)) ?? []) {
344
359
  core.getElementById(id).addClass('semantic-hover');
345
360
  }
346
361
  }
@@ -402,7 +417,15 @@ export class CytoscapeGraphRenderer {
402
417
  hideTooltip() {
403
418
  this.tooltip.hidden = true;
404
419
  this.tooltip.textContent = '';
405
- this.lastTap = undefined;
420
+ }
421
+ cancelGroupTap() {
422
+ if (this.pendingGroupTap)
423
+ clearTimeout(this.pendingGroupTap.timer);
424
+ this.pendingGroupTap = undefined;
425
+ }
426
+ clearHover() {
427
+ this.hideTooltip();
428
+ this.latestRequest?.onHover(undefined);
406
429
  }
407
430
  showStatus(kind, message, retry = false) {
408
431
  this.status.dataset.state = kind;
@@ -507,8 +530,8 @@ function nodeRenderableData(node) {
507
530
  : 160;
508
531
  return {
509
532
  kind: node.kind,
510
- passKind: node.kind === 'pass' || node.kind === 'culled-pass' ? node.passKind : undefined,
511
- resourceKind: node.kind === 'resource' ? node.resourceKind : undefined,
533
+ passKind: node.kind === 'pass' ? node.passKind : undefined,
534
+ resourceKind: (node.kind === 'resource' || node.kind === 'root') ? node.resourceKind : undefined,
512
535
  collapsed: node.kind === 'group' && node.collapsed ? 1 : 0,
513
536
  hasCulled: node.kind === 'group' && node.culledNodeCount > 0 ? 1 : 0,
514
537
  depthBand: node.kind === 'group' ? node.depthBand : undefined,
@@ -536,9 +559,6 @@ function edgeRenderableData(edge) {
536
559
  const detailLabel = graphEdgeDisplayLabel(edge);
537
560
  return {
538
561
  kind: edge.kind,
539
- dependencyKind: edge.kind === 'dependency' ? edge.dependencyKind : undefined,
540
- accessMode: edge.kind === 'access' ? edge.accessMode : undefined,
541
- dashed: edge.kind === 'access' && edge.dashed ? 1 : 0,
542
562
  detailLabel,
543
563
  displayLabel: detailLabel,
544
564
  tooltip: edge.title,