File size: 2,491 Bytes
4e23b01 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | import { IInstantiationService } from '#/_base/di/instantiation';
import type { InstantiationService } from '#/_base/di/instantiationService';
import { ScopeActivation, registerScopedService } from '#/_base/di/scope';
import { LifecycleScope } from '#/app/scopes';
import {
IDebugGraphService,
type DebugGraph,
type DebugGraphEdge,
type DebugGraphNode,
} from './debugGraph';
import { walkScopeContainers } from './scopeTree';
export class DebugGraphService implements IDebugGraphService {
declare readonly _serviceBrand: undefined;
private readonly root: InstantiationService;
constructor(@IInstantiationService instantiation: IInstantiationService) {
this.root = instantiation as InstantiationService;
}
graph(): DebugGraph {
const infos = walkScopeContainers(this.root);
const pathByContainer = new Map<InstantiationService, string>(
infos.map((info) => [info.container, info.path]),
);
const nodes = new Map<string, DebugGraphNode>();
for (const info of infos) {
const states = new Map(
info.container.cascade.unitsSnapshot().map((unit) => [unit.token, unit]),
);
for (const registration of info.container.servicesSnapshot()) {
const id = nodeId(info.path, registration.token);
nodes.set(id, {
id,
token: registration.token,
scopePath: info.path,
uid: registration.uid,
state: states.get(registration.token)?.state,
});
}
}
const pathOf = (scope: object): string =>
pathByContainer.get(scope as InstantiationService) ??
`#${this.root.cascadeTree.seqOf(scope)}`;
const edges: DebugGraphEdge[] = [];
const endpointNode = (path: string, token: string): string => {
const id = nodeId(path, token);
if (!nodes.has(id)) {
nodes.set(id, { id, token, scopePath: path });
}
return id;
};
for (const edge of this.root.dependencyGraph.edges()) {
edges.push({
from: endpointNode(pathOf(edge.consumer.scope), edge.consumer.token.toString()),
to: endpointNode(pathOf(edge.dependency.scope), edge.dependency.token.toString()),
kind: edge.kind,
});
}
return { nodes: [...nodes.values()], edges };
}
}
function nodeId(scopePath: string, token: string): string {
return `${scopePath}::${token}`;
}
registerScopedService(
LifecycleScope.App,
IDebugGraphService,
DebugGraphService,
ScopeActivation.OnDemand,
'debug',
);
|