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 { IDebugLedgerService, type DebugLedgerNode, type DebugUnit } from './debugLedger'; import { scopeContainerLabel } from './scopeTree'; export class DebugLedgerService implements IDebugLedgerService { declare readonly _serviceBrand: undefined; private readonly root: InstantiationService; constructor(@IInstantiationService instantiation: IInstantiationService) { this.root = instantiation as InstantiationService; } tree(): DebugLedgerNode { return this._node(this.root, scopeContainerLabel(this.root)); } private _node(container: InstantiationService, path: string): DebugLedgerNode { return { path, label: scopeContainerLabel(container), units: joinUnits(container), ledger: container.ledger.entries(), children: container.children.map((child) => this._node(child, `${path}/${scopeContainerLabel(child)}`), ), }; } } function joinUnits(container: InstantiationService): DebugUnit[] { const states = new Map(container.cascade.unitsSnapshot().map((unit) => [unit.token, unit])); return container.servicesSnapshot().map((registration) => { const unit = states.get(registration.token); return { token: registration.token, uid: registration.uid, state: unit?.state, error: unit?.error, everActive: unit?.everActive, inFlight: unit?.inFlight, }; }); } registerScopedService( LifecycleScope.App, IDebugLedgerService, DebugLedgerService, ScopeActivation.OnDemand, 'debug', );