Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export abstract class ApplicationOperations {
abstract selectDomElement(position: ElementPosition, target: Frame): void;
abstract inspect(directivePosition: DirectivePosition, objectPath: string[], target: Frame): void;
abstract inspectSignal(position: SignalNodePosition, target: Frame): void;
abstract setSignalBreakpoint(position: SignalNodePosition, target: Frame): void;
abstract viewSourceFromRouter(name: string, type: string, target: Frame): void;
abstract setStorageItems(items: {[key: string]: unknown}): Promise<void>;
abstract getStorageItems(items: string[]): Promise<{[key: string]: unknown}>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
[graph]="signalGraph.graph()!"
[element]="signalGraph.element()!"
(gotoSource)="gotoSource($event)"
(setBreakpoint)="setBreakpoint($event)"
(expandCluster)="expandCluster($event)"
(highlightDeps)="highlightDeps($event)"
(close)="detailsVisible.set(false)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ export class SignalGraphPaneComponent {
);
}

setBreakpoint(node: DevtoolsSignalGraphNode) {
const frame = this.frameManager.selectedFrame();
this.appOperations.setSignalBreakpoint(
{
element: this.signalGraph.element()!,
signalId: node.id,
},
frame!,
);
}

expandCluster(clusterId: string) {
this.visualizer().expandCluster(clusterId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@
>
<mat-icon> code </mat-icon>
</button>
<button
ng-button
size="compact"
class="action-btn"
btnType="secondary"
(click)="setBreakpoint.emit(node)"
[disabled]="!node.debuggable"
matTooltip="Set breakpoint"
>
<mat-icon> fiber_manual_record </mat-icon>
</button>
} @else if (isClusterNode) {
<button
ng-button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export class SignalDetailsComponent {
protected readonly element = input.required<ElementPosition>();

protected readonly gotoSource = output<DevtoolsSignalGraphNode>();
protected readonly setBreakpoint = output<DevtoolsSignalGraphNode>();
protected readonly expandCluster = output<string>();
protected readonly highlightDeps = output<{
node: DevtoolsSignalGraphNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ export class ChromeApplicationOperations extends ApplicationOperations {
this.runInInspectedWindow(inspectSignal, target);
}

override setSignalBreakpoint(position: SignalNodePosition, target: Frame): void {
const setBreakpoint = `
(() => {
const fn = inspectedApplication.findSignalNodeByPosition('${JSON.stringify(position)}');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be that we want to use stringifyAndEscape to follow the same standard that was added at #69309?

Suggested change
const fn = inspectedApplication.findSignalNodeByPosition('${JSON.stringify(position)}');
const fn = inspectedApplication.findSignalNodeByPosition('${stringifyAndEscape(position)}');

if (fn) {
debug(fn);
inspect(fn);
} else {
console.warn('Could not find signal function to debug');
}
})()
`;
this.runInInspectedWindow(setBreakpoint, target);
}

override viewSourceFromRouter(name: string, type: string, target: Frame): void {
const viewSource = `inspect(inspectedApplication.findConstructorByNameForRouter('${name}', '${type}'))`;
this.runInInspectedWindow(viewSource, target);
Expand Down
7 changes: 7 additions & 0 deletions devtools/src/demo-application-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ export class DemoApplicationOperations extends ApplicationOperations {
return;
}

override setSignalBreakpoint(position: SignalNodePosition): void {
console.warn(
'setSignalBreakpoint() is not implemented because the demo app runs in an Iframe',
);
return;
}

override viewSourceFromRouter(name: string, type: string): void {
console.warn(
'viewSourceFromRouter() is not implemented because the demo app runs in an Iframe',
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/render3/util/signal_debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ function getNodesAndEdgesFromSignalMap(signalMap: ReadonlyMap<ReactiveNode, Reac
debuggableFn: consumer.lView?.[CONTEXT]?.constructor as (() => unknown) | undefined,
id,
});
} else if (isEffectNode(consumer)) {
debugSignalGraphNodes.push({
label: consumer.debugName,
kind: consumer.kind,
epoch: consumer.version,
debuggableFn: consumer.fn,
id,
});
} else {
debugSignalGraphNodes.push({
label: consumer.debugName,
Expand Down
2 changes: 2 additions & 0 deletions packages/core/test/acceptance/signal_debug_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ describe('getSignalGraph', () => {

const effectNode = nodes.find((node) => node.label === 'primitiveSignalEffect')!;
expect(effectNode).toBeDefined();
expect(effectNode.debuggableFn).toBeDefined();
expect(typeof effectNode.debuggableFn).toBe('function');

const signalNode = nodes.find((node) => node.label === 'primitiveSignal')!;
expect(signalNode).toBeDefined();
Expand Down
Loading