pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/angular/angular/commit/84d757446bf3889f32805ab34246baf33b99ba84

refactor(devtools): use WeakRef in idToInjector map for injector cleanup · angular/angular@84d7574 · GitHub
Skip to content

Commit 84d7574

Browse files
AleksanderBodurrimattrbeck
authored andcommitted
refactor(devtools): use WeakRef in idToInjector map for injector cleanup
Replace the manual injectorsSeen cleanup mechanism with WeakRef and FinalizationRegistry. The old approach worked but coupled cleanup to the UI change detection and required tracking seen injectors across traversal. WeakRef lets the browser handle this naturally, removing the injectorsSeen set and the manual cleanup loop.
1 parent a617967 commit 84d7574

3 files changed

Lines changed: 26 additions & 56 deletions

File tree

devtools/projects/ng-devtools-backend/src/lib/client-event-subscribers.ts

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import {
4040
getInjectorResolutionPath,
4141
getLatestComponentState,
4242
idToInjector,
43-
injectorsSeen,
4443
isElementInjector,
4544
getDirectiveCdStrategy,
4645
logValue,
@@ -146,22 +145,6 @@ const getLatestComponentExplorerViewCallback =
146145
ngDebugDependencyInjectionApiIsSupported(),
147146
);
148147

149-
// cleanup injector id mappings
150-
for (const injectorId of idToInjector.keys()) {
151-
if (!injectorsSeen.has(injectorId)) {
152-
const injector = idToInjector.get(injectorId)!;
153-
if (isElementInjector(injector)) {
154-
const element = getElementInjectorElement(injector);
155-
if (element) {
156-
nodeInjectorToResolutionPath.delete(element);
157-
}
158-
}
159-
160-
idToInjector.delete(injectorId);
161-
}
162-
}
163-
injectorsSeen.clear();
164-
165148
if (!query) {
166149
messageBus.emit('latestComponentExplorerView', [{forest}]);
167150
return;
@@ -479,21 +462,17 @@ function getNodeDIResolutionPath(node: ComponentTreeNode): SerializedInjector[]
479462
nodeInjectorToResolutionPath.set(element, serializeResolutionPath(resolutionPaths));
480463
}
481464

482-
const serializedPath = nodeInjectorToResolutionPath.get(element)!;
483-
for (const injector of serializedPath) {
484-
injectorsSeen.add(injector.id);
485-
}
486-
487-
return serializedPath;
465+
return nodeInjectorToResolutionPath.get(element)!;
488466
}
489467

490468
const getInjectorProvidersCallback =
491469
(messageBus: MessageBus<Events>) => (injector: SerializedInjector) => {
492-
if (!idToInjector.has(injector.id)) {
470+
const resolvedInjector = idToInjector.get(injector.id)?.deref();
471+
if (!resolvedInjector) {
493472
return;
494473
}
495474

496-
const providerRecords = getInjectorProviders(idToInjector.get(injector.id)!);
475+
const providerRecords = getInjectorProviders(resolvedInjector);
497476
const allProviderRecords: SerializedProviderRecord[] = [];
498477

499478
const tokenToRecords: Map<any, SerializedProviderRecord[]> = new Map();
@@ -544,12 +523,11 @@ const logProvider = (
544523
serializedInjector: SerializedInjector,
545524
serializedProvider: SerializedProviderRecord,
546525
): void => {
547-
if (!idToInjector.has(serializedInjector.id)) {
526+
const injector = idToInjector.get(serializedInjector.id)?.deref();
527+
if (!injector) {
548528
return;
549529
}
550530

551-
const injector = idToInjector.get(serializedInjector.id)!;
552-
553531
const providerRecords = getInjectorProviders(injector);
554532

555533
console.group(
@@ -621,11 +599,11 @@ const getInjectorInstance = (
621599
serializedInjector: SerializedInjector,
622600
serializedProvider: SerializedProviderRecord,
623601
) => {
624-
if (!idToInjector.has(serializedInjector.id)) {
602+
const injector = idToInjector.get(serializedInjector.id)?.deref();
603+
if (!injector) {
625604
return;
626605
}
627606

628-
const injector = idToInjector.get(serializedInjector.id)!;
629607
const providerRecords = getInjectorProviders(injector);
630608

631609
if (typeof serializedProvider.index === 'number') {

devtools/projects/ng-devtools-backend/src/lib/component-tree/component-tree.ts

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,26 @@ import {unwrapSignal} from '../utils';
5353

5454
export const injectorToId = new WeakMap<Injector | HTMLElement, string>();
5555
export const nodeInjectorToResolutionPath = new WeakMap<HTMLElement, SerializedInjector[]>();
56-
export const idToInjector = new Map<string, Injector>();
57-
export const injectorsSeen = new Set<string>();
56+
export const idToInjector = new Map<string, WeakRef<Injector>>();
57+
const injectorFinalizer = new FinalizationRegistry<string>((id) => {
58+
idToInjector.delete(id);
59+
});
5860
let injectorId = 0;
5961

6062
export function getInjectorId() {
6163
return `${injectorId++}`;
6264
}
6365

66+
function getOrCreateInjectorId(key: Injector | HTMLElement, injector: Injector): string {
67+
if (!injectorToId.has(key)) {
68+
const newId = getInjectorId();
69+
injectorToId.set(key, newId);
70+
idToInjector.set(newId, new WeakRef(injector));
71+
injectorFinalizer.register(injector, newId);
72+
}
73+
return injectorToId.get(key)!;
74+
}
75+
6476
const INTERNAL_TOKENS = [
6577
'ElementRef',
6678
'Renderer2',
@@ -172,18 +184,8 @@ export const getLatestComponentState = (
172184
};
173185

174186
function serializeElementInjectorWithId(injector: Injector): SerializedInjector | null {
175-
let id: string;
176187
const element = getElementInjectorElement(injector);
177-
178-
if (!injectorToId.has(element)) {
179-
id = getInjectorId();
180-
injectorToId.set(element, id);
181-
idToInjector.set(id, injector);
182-
}
183-
184-
id = injectorToId.get(element)!;
185-
idToInjector.set(id, injector);
186-
injectorsSeen.add(id);
188+
const id = getOrCreateInjectorId(element, injector);
187189

188190
const serializedInjector = serializeInjector(injector);
189191
if (serializedInjector === null) {
@@ -202,17 +204,7 @@ function serializeInjectorWithId(injector: Injector): SerializedInjector | null
202204
}
203205

204206
function serializeEnvironmentInjectorWithId(injector: Injector): SerializedInjector | null {
205-
let id: string;
206-
207-
if (!injectorToId.has(injector)) {
208-
id = getInjectorId();
209-
injectorToId.set(injector, id);
210-
idToInjector.set(id, injector);
211-
}
212-
213-
id = injectorToId.get(injector)!;
214-
idToInjector.set(id, injector);
215-
injectorsSeen.add(id);
207+
const id = getOrCreateInjectorId(injector, injector);
216208

217209
const serializedInjector = serializeInjector(injector);
218210
if (serializedInjector === null) {

devtools/tsconfig.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"moduleResolution": "bundler",
1414
"esModuleInterop": true,
1515
"importHelpers": true,
16-
"target": "es2020",
17-
"lib": ["es2020", "dom", "dom.iterable"],
16+
"target": "es2022",
17+
"lib": ["es2022", "dom", "dom.iterable"],
1818
"types": ["chrome"],
1919
// TODO: Have an IDE specific tsconfig file
2020
"paths": {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy