Repository: facebook/react
File: packages/react-devtools-shared/src/devtools/store.js (JavaScript)

Code before:
export default class Store extends EventEmitter<{
  backendVersion: [],
  collapseNodesByDefault: [],
  componentFilters: [],
  error: [Error],
  hookSettings: [$ReadOnly<DevToolsHookSettings>],
  settingsUpdated: [$ReadOnly<DevToolsHookSettings>],
  mutated: [[Array<number>, Map<number, number>]],
  recordChangeDescriptions: [],
  roots: [],
  rootSupportsBasicProfiling: [],
  rootSupportsTimelineProfiling: [],
  supportsNativeStyleEditor: [],
  supportsReloadAndProfile: [],
  unsupportedBridgeProtocolDetected: [],
  unsupportedRendererVersionDetected: [],
}> {
  // If the backend version is new enough to report its (NPM) version, this is it.
  // This version may be displayed by the frontend for debugging purposes.
  _backendVersion: string | null = null;

  _bridge: FrontendBridge;

  // Computed whenever _errorsAndWarnings Map changes.
  _cachedUniqueErrorCount: number = 0;
  _cachedUniqueWarningCount: number = 0;
  _cachedErrorAndWarningTuples: ErrorAndWarningTuples | null = null;

  // Should new nodes be collapsed by default when added to the tree?
  _collapseNodesByDefault: boolean = true;

  _componentFilters: Array<ComponentFilter>;

  // Map of ID to number of recorded error and warning message IDs.
  _errorsAndWarnings: Map<number, {errorCount: number, warningCount: number}> =
    new Map();

  // At least one of the injected renderers contains (DEV only) owner metadata.
  _hasOwnerMetadata: boolean = false;

  // Map of ID to (mutable) Element.
  // Elements are mutated to avoid excessive cloning during tree updates.
  // The InspectedElement Suspense cache also relies on this mutability for its WeakMap usage.
  _idToElement: Map<number, Element> = new Map();

  // Should the React Native style editor panel be shown?
  _isNativeStyleEditorSupported: boolean = false;

  // Can the backend use the Storage API (e.g. localStorage)?
  // If not, features like reload-and-profile will not work correctly and must be disabled.
  _isBackendStorageAPISupported: boolean = false;

Review comment (performance):
Nit on naming: "unique" isn't really accurate, i.e. in the example from PR desc, every error can still be different, even if they originate from the same component.

If I understand the PR example correctly, it's a "count of components with any [errors/warnings]".

Maybe we can pick a concise version of the following?

```suggestion
  _cachedComponentWithAnyErrorCount: number = 0;
  _cachedComponentWIthAnyWarningCount: number = 0;
```

Code after:
export default class Store extends EventEmitter<{
  backendVersion: [],
  collapseNodesByDefault: [],
  componentFilters: [],
  error: [Error],
  hookSettings: [$ReadOnly<DevToolsHookSettings>],
  settingsUpdated: [$ReadOnly<DevToolsHookSettings>],
  mutated: [[Array<number>, Map<number, number>]],
  recordChangeDescriptions: [],
  roots: [],
  rootSupportsBasicProfiling: [],
  rootSupportsTimelineProfiling: [],
  supportsNativeStyleEditor: [],
  supportsReloadAndProfile: [],
  unsupportedBridgeProtocolDetected: [],
  unsupportedRendererVersionDetected: [],
}> {
  // If the backend version is new enough to report its (NPM) version, this is it.
  // This version may be displayed by the frontend for debugging purposes.
  _backendVersion: string | null = null;

  _bridge: FrontendBridge;

  // Computed whenever _errorsAndWarnings Map changes.
  _cachedComponentWithErrorCount: number = 0;
  _cachedComponentWithWarningCount: number = 0;
  _cachedErrorAndWarningTuples: ErrorAndWarningTuples | null = null;

  // Should new nodes be collapsed by default when added to the tree?
  _collapseNodesByDefault: boolean = true;

  _componentFilters: Array<ComponentFilter>;

  // Map of ID to number of recorded error and warning message IDs.
  _errorsAndWarnings: Map<number, {errorCount: number, warningCount: number}> =
    new Map();

  // At least one of the injected renderers contains (DEV only) owner metadata.
  _hasOwnerMetadata: boolean = false;

  // Map of ID to (mutable) Element.
  // Elements are mutated to avoid excessive cloning during tree updates.
  // The InspectedElement Suspense cache also relies on this mutability for its WeakMap usage.
  _idToElement: Map<number, Element> = new Map();

  // Should the React Native style editor panel be shown?
  _isNativeStyleEditorSupported: boolean = false;

  // Can the backend use the Storage API (e.g. localStorage)?
  // If not, features like reload-and-profile will not work correctly and must be disabled.
  _isBackendStorageAPISupported: boolean = false;