Skip to content
Open
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
12 changes: 7 additions & 5 deletions devtools/projects/ng-devtools-backend/src/lib/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
load("//devtools/tools:defaults.bzl", "ts_project", "ts_test_library", "zoneless_web_test_suite")

package(default_visibility = ["//visibility:public"])
package(default_visibility = ["//devtools:__subpackages__"])

ts_project(
name = "lib",
Expand All @@ -9,8 +9,8 @@ ts_project(
":client_event_subscribers",
"//devtools/projects/ng-devtools-backend/src/lib/component-inspector",
"//devtools/projects/ng-devtools-backend/src/lib/directive-forest",
"//devtools/projects/ng-devtools-backend/src/lib/hooks",
"//devtools/projects/ng-devtools-backend/src/lib/ng-debug-api",
"//devtools/projects/ng-devtools-backend/src/lib/profiling/profiler",
"//devtools/projects/ng-devtools-backend/src/lib/state-serializer",
"//devtools/projects/protocol",
],
Expand Down Expand Up @@ -130,8 +130,8 @@ ts_test_library(
],
deps = [
":client_event_subscribers",
"//:node_modules/rxjs",
"//devtools/projects/ng-devtools-backend/src/lib/hooks",
"//devtools/projects/ng-devtools-backend/src/lib/directive-forest:identity-tracker",
"//devtools/projects/ng-devtools-backend/src/lib/profiling/profiler",
"//devtools/projects/protocol",
"//devtools/projects/shared-utils",
],
Expand All @@ -149,8 +149,10 @@ ts_project(
"//:node_modules/rxjs",
"//devtools/projects/ng-devtools-backend/src/lib/component-inspector",
"//devtools/projects/ng-devtools-backend/src/lib/component-tree",
"//devtools/projects/ng-devtools-backend/src/lib/hooks",
"//devtools/projects/ng-devtools-backend/src/lib/directive-forest:manager",
"//devtools/projects/ng-devtools-backend/src/lib/ng-debug-api",
"//devtools/projects/ng-devtools-backend/src/lib/profiling",
"//devtools/projects/ng-devtools-backend/src/lib/profiling/profiler",
"//devtools/projects/ng-devtools-backend/src/lib/state-serializer",
"//devtools/projects/ng-devtools-backend/src/lib/utils",
"//devtools/projects/protocol",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import {Events, MessageBus} from '../../../protocol';
import {subscribeToClientEvents} from './client-event-subscribers';
import {appIsAngular, appIsAngularIvy, appIsSupportedAngularVersion} from '../../../shared-utils';
import {DirectiveForestHooks} from './hooks/hooks';
import {of} from 'rxjs';
import {Profiler} from './profiling/profiler';
import {NodeArray} from './directive-forest/identity-tracker';

describe('ClientEventSubscriber', () => {
let messageBusMock: MessageBus<Events>;
Expand Down Expand Up @@ -43,7 +43,7 @@ describe('ClientEventSubscriber', () => {
});

it('should setup inspector', () => {
subscribeToClientEvents(messageBusMock, {directiveForestHooks: MockDirectiveForestHooks});
subscribeToClientEvents(messageBusMock, {profiler: MockProfiler});

expect(messageBusMock.on).toHaveBeenCalledWith('inspectorStart', jasmine.any(Function));
expect(messageBusMock.on).toHaveBeenCalledWith('inspectorEnd', jasmine.any(Function));
Expand All @@ -66,10 +66,8 @@ function mockAngular() {
return appNode;
}

class MockDirectiveForestHooks extends DirectiveForestHooks {
profiler = {
subscribe: () => {},
changeDetection$: of(),
} as any as DirectiveForestHooks['profiler'];
initialize = () => {};
class MockProfiler extends Profiler {
override destroy(): void {}

override onIndexForest(_: NodeArray, __: NodeArray): void {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ import {
updateState,
} from './component-tree/component-tree';
import {unHighlight} from './highlighter';
import {disableTimingAPI, enableTimingAPI, initializeOrGetDirectiveForestHooks} from './hooks';
import {start as startProfiling, stop as stopProfiling} from './hooks/capture';
import {DirectiveForestHooks} from './hooks/hooks';
import {start as startProfiling, stop as stopProfiling} from './profiling/capture';
import {disableTimingAPI, enableTimingAPI} from './profiling/timing-api';
import {getProfiler, Profiler} from './profiling/profiler';
import {ComponentTreeNode} from './interfaces';
import {ngDebugClient, ngDebugDependencyInjectionApiIsSupported} from './ng-debug-api/ng-debug-api';
import {getSupportedApis} from './ng-debug-api/supported-apis';
Expand All @@ -63,13 +63,14 @@ import {serializeDirectiveState, serializeValue} from './state-serializer/state-
import {runOutsideAngular, unwrapSignal} from './utils/general';
import {sanitizeObject} from './utils/serialization';
import {SignalGraphRef} from './utils/signal-graph-ref';
import {getDirectiveForestManager} from './directive-forest/manager';

type InspectorRef = {ref: ComponentInspector | null};

export const subscribeToClientEvents = (
messageBus: MessageBus<Events>,
depsForTestOnly?: {
directiveForestHooks?: typeof DirectiveForestHooks;
profiler?: new (...args: any[]) => Profiler;
},
): void => {
const inspector: InspectorRef = {ref: null};
Expand Down Expand Up @@ -125,8 +126,8 @@ export const subscribeToClientEvents = (
// update requests, instead we want to request an update at most
// once every 250ms
runOutsideAngular(() => {
initializeOrGetDirectiveForestHooks(depsForTestOnly)
.profiler.changeDetection$.pipe(debounceTime(250))
getProfiler(depsForTestOnly)
.changeDetection$.pipe(debounceTime(250))
.subscribe(() => messageBus.emit('componentTreeDirty'));
});
}
Expand All @@ -145,10 +146,10 @@ const getLatestComponentExplorerViewCallback =
// We want to force re-indexing of the component tree.
// Pressing the refresh button means the user saw stuck UI.

initializeOrGetDirectiveForestHooks().indexForest();
getDirectiveForestManager().indexForest();

const forest = prepareForestForSerialization(
initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest(),
getDirectiveForestManager().getIndexedDirectiveForest(),
ngDebugDependencyInjectionApiIsSupported(),
);

Expand All @@ -157,10 +158,7 @@ const getLatestComponentExplorerViewCallback =
return;
}

const state = getLatestComponentState(
query,
initializeOrGetDirectiveForestHooks().getDirectiveForest(),
);
const state = getLatestComponentState(query, getDirectiveForestManager().getDirectiveForest());

if (state) {
const {directiveProperties} = state;
Expand Down Expand Up @@ -214,7 +212,7 @@ const stopProfilingCallback = (messageBus: MessageBus<Events>) => () => {
const selectedComponentCallback = (inspector: InspectorRef) => (position: ElementPosition) => {
const node = queryDirectiveForest(
position,
initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest(),
getDirectiveForestManager().getIndexedDirectiveForest(),
);
setConsoleReference({node, position});
inspector.ref?.highlightByPosition(position);
Expand All @@ -225,7 +223,7 @@ const getNestedPropertiesCallback =
const emitEmpty = () => messageBus.emit('nestedProperties', [position, {props: {}}, propPath]);
const node = queryDirectiveForest(
position.element,
initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest(),
getDirectiveForestManager().getIndexedDirectiveForest(),
);
if (!node) {
return emitEmpty();
Expand Down Expand Up @@ -256,7 +254,7 @@ const getSignalNestedPropertiesCallback =
messageBus.emit('signalNestedProperties', [position, {props: {}}, propPath]);
const node = queryDirectiveForest(
position.element,
initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest(),
getDirectiveForestManager().getIndexedDirectiveForest(),
);
if (!node || !node.nativeElement) {
return emitEmpty();
Expand Down Expand Up @@ -340,7 +338,7 @@ const checkForAngular = (messageBus: MessageBus<Events>): void => {
}

if (appIsIvy && appIsAngularInDevMode() && appIsSupportedAngularVersion()) {
initializeOrGetDirectiveForestHooks();
getDirectiveForestManager();
}

const devMode = appIsAngularInDevMode();
Expand Down Expand Up @@ -402,7 +400,7 @@ export interface SerializableComponentTreeNode extends DevToolsNode<
}

function getRouterInstance() {
const forest = initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest();
const forest = getDirectiveForestManager().getIndexedDirectiveForest();
const rootNode = forest[0];

if (!rootNode || !rootNode.nativeElement) {
Expand Down Expand Up @@ -433,12 +431,12 @@ const prepareForestForSerialization = (
? {
name: node.component.name,
isElement: node.component.isElement,
id: initializeOrGetDirectiveForestHooks().getDirectiveId(node.component.instance)!,
id: getDirectiveForestManager().getDirectiveId(node.component.instance)!,
}
: null,
directives: node.directives?.map((d) => ({
name: d.name,
id: initializeOrGetDirectiveForestHooks().getDirectiveId(d.instance)!,
id: getDirectiveForestManager().getDirectiveId(d.instance)!,
})),
children: prepareForestForSerialization(node.children, includeResolutionPath),
hydration: node.hydration,
Expand Down Expand Up @@ -582,7 +580,7 @@ const logProvider = (
const getTransferStateCallback = (messageBus: MessageBus<Events>) => () => {
const ng = ngDebugClient();

const forest = initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest();
const forest = getDirectiveForestManager().getIndexedDirectiveForest();
if (forest.length === 0) {
messageBus.emit('transferStateData', [null]);
return;
Expand Down Expand Up @@ -641,7 +639,7 @@ const getSignalGraphCallback = (messageBus: MessageBus<Events>) => (element: Ele
// get injector from position
const node = queryDirectiveForest(
element,
initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest(),
getDirectiveForestManager().getIndexedDirectiveForest(),
);
if (!node) {
messageBus.emit('latestSignalGraph', [null]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
load("//devtools/tools:defaults.bzl", "ts_project", "ts_test_library", "zoneless_web_test_suite")

package(default_visibility = ["//visibility:public"])
package(default_visibility = ["//devtools:__subpackages__"])

ts_project(
name = "component-inspector",
Expand All @@ -9,7 +9,8 @@ ts_project(
"//devtools/projects/ng-devtools-backend/src/lib:highlighter",
"//devtools/projects/ng-devtools-backend/src/lib:interfaces",
"//devtools/projects/ng-devtools-backend/src/lib/component-tree",
"//devtools/projects/ng-devtools-backend/src/lib/hooks",
"//devtools/projects/ng-devtools-backend/src/lib/directive-forest:manager",
"//devtools/projects/ng-devtools-backend/src/lib/profiling",
"//devtools/projects/protocol",
],
)
Expand All @@ -21,13 +22,7 @@ ts_test_library(
],
deps = [
":component-inspector",
"//:node_modules/@angular/core",
"//devtools/projects/ng-devtools-backend/src/lib:highlighter",
"//devtools/projects/ng-devtools-backend/src/lib:interfaces",
"//devtools/projects/ng-devtools-backend/src/lib/component-tree",
"//devtools/projects/ng-devtools-backend/src/lib/hooks",
"//devtools/projects/ng-devtools-backend/src/lib/utils",
"//devtools/projects/protocol",
"//devtools/projects/ng-devtools-backend/src/lib/directive-forest:manager",
],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import {initializeOrGetDirectiveForestHooks} from '../hooks';
import {getDirectiveForestManager} from '../directive-forest/manager';
import {ComponentInspector} from './component-inspector';

describe('ComponentInspector', () => {
Expand Down Expand Up @@ -45,6 +45,6 @@ describe('ComponentInspector', () => {
});

it('should always retrieve the same forest hook', () => {
expect(initializeOrGetDirectiveForestHooks()).toBe(initializeOrGetDirectiveForestHooks());
expect(getDirectiveForestManager()).toBe(getDirectiveForestManager());
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ import {
removeHydrationHighlights,
unHighlight,
} from '../highlighter';
import {initializeOrGetDirectiveForestHooks} from '../hooks';
import {getDirectiveForestManager} from '../directive-forest/manager';
import {ComponentTreeNode} from '../interfaces';

interface Type<T> extends Function {
new (...args: any[]): T;
}

export interface ComponentInspectorOptions {
onComponentEnter: (id: number) => void;
onComponentSelect: (id: number) => void;
Expand Down Expand Up @@ -65,7 +66,7 @@ export class ComponentInspector {

if (this._selectedComponent.component && this._selectedComponent.host) {
this._onComponentSelect(
initializeOrGetDirectiveForestHooks().getDirectiveId(this._selectedComponent.component)!,
getDirectiveForestManager().getDirectiveId(this._selectedComponent.component)!,
);
}
}
Expand All @@ -82,7 +83,7 @@ export class ComponentInspector {
if (this._selectedComponent.component && this._selectedComponent.host) {
highlightSelectedElement(this._selectedComponent.host);
this._onComponentEnter(
initializeOrGetDirectiveForestHooks().getDirectiveId(this._selectedComponent.component)!,
getDirectiveForestManager().getDirectiveId(this._selectedComponent.component)!,
);
}
}
Expand All @@ -102,15 +103,15 @@ export class ComponentInspector {
}

highlightByPosition(position: ElementPosition): void {
const forest: ComponentTreeNode[] = initializeOrGetDirectiveForestHooks().getDirectiveForest();
const forest: ComponentTreeNode[] = getDirectiveForestManager().getDirectiveForest();
const elementToHighlight: HTMLElement | null = findNodeInForest(position, forest);
if (elementToHighlight) {
highlightSelectedElement(elementToHighlight);
}
}

highlightHydrationNodes(): void {
const forest: ComponentTreeNode[] = initializeOrGetDirectiveForestHooks().getDirectiveForest();
const forest: ComponentTreeNode[] = getDirectiveForestManager().getDirectiveForest();

// drop the root nodes, we don't want to highlight it
const forestWithoutRoots = forest.flatMap((rootNode) => rootNode.children);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
load("//devtools/tools:defaults.bzl", "ts_project", "ts_test_library", "zoneless_web_test_suite")

package(default_visibility = ["//visibility:public"])
package(default_visibility = ["//devtools:__subpackages__"])

ts_project(
name = "directive-forest",
srcs = glob(
include = ["*.ts"],
exclude = ["*.spec.ts"],
exclude = [
"*.spec.ts",
"identity-tracker.ts",
"manager.ts",
],
),
deps = [
"//:node_modules/@angular/core",
Expand All @@ -22,13 +26,40 @@ ts_project(
],
)

ts_project(
name = "identity-tracker",
srcs = [
"identity-tracker.ts",
],
deps = [
"//devtools/projects/ng-devtools-backend/src/lib:interfaces",
"//devtools/projects/ng-devtools-backend/src/lib/component-tree",
"//devtools/projects/protocol",
],
)

ts_project(
name = "manager",
srcs = [
"manager.ts",
],
deps = [
":identity-tracker",
"//devtools/projects/ng-devtools-backend/src/lib:interfaces",
"//devtools/projects/ng-devtools-backend/src/lib/profiling/profiler",
"//devtools/projects/protocol",
],
)

ts_test_library(
name = "test_lib",
srcs = [
"identity-tracker.spec.ts",
"render-tree.spec.ts",
],
deps = [
":directive-forest",
":identity-tracker",
"//:node_modules/@angular/core",
"//devtools/projects/ng-devtools-backend/src/lib:interfaces",
"//devtools/projects/ng-devtools-backend/src/lib/utils",
Expand Down
Loading
Loading