react-debug-updates 0.1.6 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,23 @@
1
1
  # react-debug-updates
2
2
 
3
- Visual debugging overlays and console logging for React re-renders. See exactly which components re-render, how often, how long they take, and *why* they re-rendered — all without modifying your components.
3
+ See exactly which React components re-render, how often, how long they take, and *why* — all without modifying your components.
4
4
 
5
5
  ![highlight overlays](https://img.shields.io/badge/overlays-visual%20highlights-61dafb) ![zero config](https://img.shields.io/badge/setup-zero%20config-green)
6
6
 
7
7
  <img src="demo.gif" alt="demo" width="852" height="476" />
8
8
 
9
+ ## Why?
10
+
11
+ I was working on an Electron app and spent hours trying to get the official React DevTools to work with it. DevTools' Electron integration is fragile, poorly documented, and breaks between versions. I just needed to see which components were re-rendering so I could fix performance issues.
12
+
13
+ So I wrote this — a plug-and-play one-liner that gives you visual highlight overlays and console logging for React re-renders. No browser extension, no Electron hacks, no configuration. Works in any React web environment — browsers, Electron, iframes.
14
+
9
15
  ## How it works
10
16
 
11
- Hooks into `__REACT_DEVTOOLS_GLOBAL_HOOK__` to intercept every React commit. Works in any React web environment browsers, Electron, iframes no React DevTools extension required. No wrappers, no HOCs, no code changes — just call `attachRenderLogger()` and you get:
17
+ Hooks into `__REACT_DEVTOOLS_GLOBAL_HOOK__` to intercept every React commit. Uses the same fiber tree diffing approach as React DevTools to detect which components actually re-rendered. No React DevTools extension required. No wrappers, no HOCs, no code changes — just call `monitor()` and you get:
12
18
 
13
- - **Console logging** — grouped, color-coded re-render reports with component tree paths and render durations
14
19
  - **Visual overlays** — highlight boxes on re-rendered DOM nodes with a heat-map color scale (blue → red as render count increases)
20
+ - **Console logging** — grouped, color-coded re-render reports with component tree paths and render durations
15
21
  - **Cause detection** — pinpoint *which* `useState`, `useReducer`, `useSyncExternalStore`, or `useContext` hook triggered each re-render, with previous→next values
16
22
 
17
23
  ## Install
@@ -26,30 +32,38 @@ pnpm add react-debug-updates
26
32
 
27
33
  ## Quick start
28
34
 
29
- Import and call `attachRenderLogger` **before** React renders anything — ideally at the very top of your entry point. This ensures the hook is in place before the first commit.
35
+ Import and call `monitor` **before** React renders anything — ideally at the very top of your entry point. This ensures the hook is in place before the first commit.
30
36
 
31
37
  ```ts
32
- import { attachRenderLogger } from "react-debug-updates";
38
+ import { monitor } from "react-debug-updates";
33
39
 
34
- // Call before React renders top of your entry point
35
- const logger = attachRenderLogger({
36
- highlight: true,
37
- showCauses: true,
38
- });
40
+ // One-liner overlays + console logging out of the box
41
+ const updates = monitor();
39
42
 
40
43
  // Later, to clean up:
41
- logger?.disconnect();
44
+ updates?.stop();
42
45
  ```
43
46
 
44
47
  ### Dev-only guard
45
48
 
46
49
  ```ts
47
50
  if (process.env.NODE_ENV === "development") {
48
- const { attachRenderLogger } = await import("react-debug-updates");
49
- attachRenderLogger({ highlight: true, showCauses: true });
51
+ const { monitor } = await import("react-debug-updates");
52
+ monitor();
50
53
  }
51
54
  ```
52
55
 
56
+ ### With options
57
+
58
+ ```ts
59
+ monitor({
60
+ showCauses: true,
61
+ opacity: 0.5,
62
+ showLabels: false,
63
+ silent: true, // overlays only, no console output
64
+ });
65
+ ```
66
+
53
67
  ## Requirements
54
68
 
55
69
  - A **React dev build** (which automatically creates `__REACT_DEVTOOLS_GLOBAL_HOOK__`) — no browser extension needed
@@ -57,36 +71,31 @@ if (process.env.NODE_ENV === "development") {
57
71
 
58
72
  ## API
59
73
 
60
- ### `attachRenderLogger(options?): RenderLogger | null`
74
+ ### `monitor(options?): UpdateMonitor | null`
61
75
 
62
- Returns a `RenderLogger` handle, or `null` if the DevTools hook is not available.
76
+ Returns an `UpdateMonitor` handle, or `null` if the DevTools hook is not available.
63
77
 
64
78
  #### Options
65
79
 
66
80
  | Option | Type | Default | Description |
67
81
  | --- | --- | --- | --- |
68
- | `silent` | `boolean` | `false` | Suppress console output |
69
82
  | `mode` | `"self-triggered" \| "all"` | `"self-triggered"` | `"self-triggered"` tracks only components whose own state changed. `"all"` includes children swept by parent updates |
70
- | `bufferSize` | `number` | `500` | Max entries kept in the ring buffer |
71
- | `filter` | `(entry: RenderEntry) => boolean` | — | Return `false` to skip an entry |
72
- | `highlight` | `boolean \| HighlightOptions` | `false` | Enable visual overlay highlights |
73
83
  | `showCauses` | `boolean` | `false` | Detect and display why each component re-rendered |
74
-
75
- #### `HighlightOptions`
76
-
77
- | Option | Type | Default | Description |
78
- | --- | --- | --- | --- |
79
- | `flushInterval` | `number` | `250` | Milliseconds between overlay flush cycles |
80
- | `animationDuration` | `number` | `1200` | Overlay fade-out animation duration (ms) |
84
+ | `silent` | `boolean` | `false` | Suppress console output |
85
+ | `overlay` | `boolean` | `true` | Enable visual highlight overlays |
81
86
  | `showLabels` | `boolean` | `true` | Show text labels (name, count, duration, cause) above overlays |
82
87
  | `opacity` | `number` | `0.3` | Peak opacity of overlay highlights (0–1) |
88
+ | `flushInterval` | `number` | `250` | Milliseconds between overlay flush cycles |
89
+ | `animationDuration` | `number` | `1200` | Overlay fade-out animation duration (ms) |
90
+ | `bufferSize` | `number` | `500` | Max entries kept in the ring buffer |
91
+ | `filter` | `(entry: RenderEntry) => boolean` | — | Return `false` to skip an entry |
83
92
 
84
- ### `RenderLogger`
93
+ ### `UpdateMonitor`
85
94
 
86
95
  | Property | Type | Description |
87
96
  | --- | --- | --- |
88
97
  | `entries` | `RenderEntry[]` | Ring buffer of recorded re-render entries |
89
- | `disconnect` | `() => void` | Unhook from React and remove all overlays |
98
+ | `stop` | `() => void` | Unhook from React and remove all overlays |
90
99
 
91
100
  ### `RenderEntry`
92
101
 
package/dist/fiber.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Fiber, PendingEntry } from "./types.js";
1
+ import type { Fiber, DetectedRender } from "./types.js";
2
2
  export declare const FiberTag: {
3
3
  readonly FunctionComponent: 0;
4
4
  readonly ClassComponent: 1;
@@ -10,4 +10,4 @@ export declare const FiberTag: {
10
10
  export declare function getComponentName(fiber: Fiber): string | null;
11
11
  export declare function findNearestDOMNode(fiber: Fiber): HTMLElement | null;
12
12
  export declare function getFiberPath(fiber: Fiber, maxDepth?: number): string;
13
- export declare function collectPending(root: Fiber, mode: "self-triggered" | "all", trackCauses: boolean): PendingEntry[];
13
+ export declare function detectRenders(root: Fiber, mode: "self-triggered" | "all"): DetectedRender[];
package/dist/format.d.ts CHANGED
@@ -1,6 +1,8 @@
1
- import type { UpdateCause } from "./types.js";
1
+ import type { HighlightEntry, UpdateCause } from "./types.js";
2
2
  export declare function formatValue(value: unknown, maxLength?: number): string;
3
3
  /** Compact summary for overlay labels. */
4
4
  export declare function formatCausesShort(causes: UpdateCause[]): string;
5
5
  /** Detailed lines for console output. */
6
6
  export declare function formatCausesConsole(causes: UpdateCause[]): string[];
7
+ /** Log re-renders as a collapsed console group. */
8
+ export declare function logRerendersToConsole(entries: HighlightEntry[], showCauses: boolean): void;
@@ -0,0 +1,5 @@
1
+ import type { OverlayConfig, HighlightEntry } from "./types.js";
2
+ export declare function createHighlighter(config: OverlayConfig): {
3
+ push: (entry: HighlightEntry) => void;
4
+ dispose: () => void;
5
+ };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { attachRenderLogger } from "./logger.js";
2
- export type { LoggerOptions, RenderLogger, RenderEntry, HighlightOptions, UpdateCause, } from "./types.js";
1
+ export { monitor } from "./monitor.js";
2
+ export type { MonitorOptions, UpdateMonitor, RenderEntry, UpdateCause, } from "./types.js";
@@ -0,0 +1,14 @@
1
+ import type { MonitorOptions, UpdateMonitor } from "./types.js";
2
+ /**
3
+ * Start monitoring React re-renders.
4
+ *
5
+ * Hooks into `__REACT_DEVTOOLS_GLOBAL_HOOK__.onCommitFiberRoot` to intercept
6
+ * every React commit. Records re-render entries, optionally logs them to the
7
+ * console, and optionally shows visual highlight overlays on re-rendered DOM nodes.
8
+ *
9
+ * Call this **before** React renders anything — ideally at the very top of
10
+ * your entry point.
11
+ *
12
+ * Returns an `UpdateMonitor` handle, or `null` if the DevTools hook is not found.
13
+ */
14
+ export declare function monitor(options?: MonitorOptions): UpdateMonitor | null;
@@ -1,64 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const STATE_HOOKS = /* @__PURE__ */ new Set([
4
- "useState",
5
- "useReducer",
6
- "useSyncExternalStore"
7
- ]);
8
- const HOOKS_WITHOUT_NODE = /* @__PURE__ */ new Set(["useContext"]);
9
- function detectCauses(fiber) {
10
- const alternate = fiber.alternate;
11
- if (!alternate) return [];
12
- const causes = [];
13
- if (fiber.memoizedProps !== alternate.memoizedProps) {
14
- causes.push({ kind: "props" });
15
- }
16
- if (fiber.tag === FiberTag.ClassComponent) {
17
- if (fiber.memoizedState !== alternate.memoizedState) {
18
- causes.push({ kind: "class-state" });
19
- }
20
- return causes;
21
- }
22
- const hookTypes = fiber._debugHookTypes;
23
- if (!hookTypes) {
24
- if (fiber.memoizedState !== alternate.memoizedState) {
25
- causes.push({ kind: "unknown" });
26
- }
27
- return causes;
28
- }
29
- let currentNode = fiber.memoizedState;
30
- let previousNode = alternate.memoizedState;
31
- let hasContextHook = false;
32
- let anyStateHookChanged = false;
33
- for (let i = 0; i < hookTypes.length; i++) {
34
- const type = hookTypes[i];
35
- if (HOOKS_WITHOUT_NODE.has(type)) {
36
- if (type === "useContext") hasContextHook = true;
37
- continue;
38
- }
39
- if (STATE_HOOKS.has(type) && currentNode && previousNode) {
40
- if (!Object.is(currentNode.memoizedState, previousNode.memoizedState)) {
41
- anyStateHookChanged = true;
42
- causes.push({
43
- kind: "hook",
44
- hookIndex: i,
45
- hookType: type,
46
- previousValue: previousNode.memoizedState,
47
- nextValue: currentNode.memoizedState
48
- });
49
- }
50
- }
51
- currentNode = (currentNode == null ? void 0 : currentNode.next) ?? null;
52
- previousNode = (previousNode == null ? void 0 : previousNode.next) ?? null;
53
- }
54
- if (hasContextHook && !anyStateHookChanged && fiber.memoizedProps === alternate.memoizedProps) {
55
- causes.push({ kind: "hook", hookType: "useContext" });
56
- }
57
- if (causes.length === 0 && fiber.memoizedProps === alternate.memoizedProps) {
58
- causes.push({ kind: "unknown" });
59
- }
60
- return causes;
61
- }
62
3
  const FiberTag = {
63
4
  FunctionComponent: 0,
64
5
  ClassComponent: 1,
@@ -113,25 +54,15 @@ function isSelfTriggered(fiber) {
113
54
  function didFiberRender(nextFiber) {
114
55
  return (nextFiber.flags & PerformedWork) === PerformedWork;
115
56
  }
116
- function collectPending(root, mode, trackCauses) {
117
- const entries = [];
57
+ function detectRenders(root, mode) {
58
+ const results = [];
118
59
  const selfTriggeredOnly = mode === "self-triggered";
119
60
  const previousRoot = root.alternate;
120
- if (!previousRoot) return entries;
61
+ if (!previousRoot) return results;
121
62
  function walk(nextFiber, previousFiber, depth) {
122
63
  if (COMPONENT_TAGS.has(nextFiber.tag) && previousFiber !== null && previousFiber !== nextFiber && // same object → bailed-out subtree
123
64
  didFiberRender(nextFiber) && (!selfTriggeredOnly || isSelfTriggered(nextFiber))) {
124
- const name = getComponentName(nextFiber);
125
- if (name) {
126
- entries.push({
127
- component: name,
128
- path: getFiberPath(nextFiber),
129
- duration: nextFiber.actualDuration ?? 0,
130
- depth,
131
- domNode: findNearestDOMNode(nextFiber),
132
- causes: trackCauses ? detectCauses(nextFiber) : []
133
- });
134
- }
65
+ results.push({ fiber: nextFiber, depth });
135
66
  }
136
67
  let nextChild = nextFiber.child;
137
68
  let previousChildAtSameIndex = (previousFiber == null ? void 0 : previousFiber.child) ?? null;
@@ -148,7 +79,66 @@ function collectPending(root, mode, trackCauses) {
148
79
  }
149
80
  }
150
81
  walk(root, previousRoot, 0);
151
- return entries;
82
+ return results;
83
+ }
84
+ const STATE_HOOKS = /* @__PURE__ */ new Set([
85
+ "useState",
86
+ "useReducer",
87
+ "useSyncExternalStore"
88
+ ]);
89
+ const HOOKS_WITHOUT_NODE = /* @__PURE__ */ new Set(["useContext"]);
90
+ function detectCauses(fiber) {
91
+ const alternate = fiber.alternate;
92
+ if (!alternate) return [];
93
+ const causes = [];
94
+ if (fiber.memoizedProps !== alternate.memoizedProps) {
95
+ causes.push({ kind: "props" });
96
+ }
97
+ if (fiber.tag === FiberTag.ClassComponent) {
98
+ if (fiber.memoizedState !== alternate.memoizedState) {
99
+ causes.push({ kind: "class-state" });
100
+ }
101
+ return causes;
102
+ }
103
+ const hookTypes = fiber._debugHookTypes;
104
+ if (!hookTypes) {
105
+ if (fiber.memoizedState !== alternate.memoizedState) {
106
+ causes.push({ kind: "unknown" });
107
+ }
108
+ return causes;
109
+ }
110
+ let currentNode = fiber.memoizedState;
111
+ let previousNode = alternate.memoizedState;
112
+ let hasContextHook = false;
113
+ let anyStateHookChanged = false;
114
+ for (let i = 0; i < hookTypes.length; i++) {
115
+ const type = hookTypes[i];
116
+ if (HOOKS_WITHOUT_NODE.has(type)) {
117
+ if (type === "useContext") hasContextHook = true;
118
+ continue;
119
+ }
120
+ if (STATE_HOOKS.has(type) && currentNode && previousNode) {
121
+ if (!Object.is(currentNode.memoizedState, previousNode.memoizedState)) {
122
+ anyStateHookChanged = true;
123
+ causes.push({
124
+ kind: "hook",
125
+ hookIndex: i,
126
+ hookType: type,
127
+ previousValue: previousNode.memoizedState,
128
+ nextValue: currentNode.memoizedState
129
+ });
130
+ }
131
+ }
132
+ currentNode = (currentNode == null ? void 0 : currentNode.next) ?? null;
133
+ previousNode = (previousNode == null ? void 0 : previousNode.next) ?? null;
134
+ }
135
+ if (hasContextHook && !anyStateHookChanged && fiber.memoizedProps === alternate.memoizedProps) {
136
+ causes.push({ kind: "hook", hookType: "useContext" });
137
+ }
138
+ if (causes.length === 0 && fiber.memoizedProps === alternate.memoizedProps) {
139
+ causes.push({ kind: "unknown" });
140
+ }
141
+ return causes;
152
142
  }
153
143
  function formatValue(value, maxLength = 50) {
154
144
  var _a;
@@ -212,6 +202,29 @@ function formatCausesConsole(causes) {
212
202
  }
213
203
  return lines;
214
204
  }
205
+ function logRerendersToConsole(entries, showCauses) {
206
+ if (entries.length === 0) return;
207
+ console.groupCollapsed(
208
+ `%c⚛ ${entries.length} re-render${entries.length > 1 ? "s" : ""}`,
209
+ "color: #61dafb; font-weight: bold"
210
+ );
211
+ for (let i = 0; i < entries.length; i++) {
212
+ const entry = entries[i];
213
+ const durationText = entry.duration > 0 ? ` (${entry.duration.toFixed(2)}ms)` : "";
214
+ console.log(
215
+ `%c${entry.component}%c ${entry.path}${durationText}`,
216
+ "color: #e8e82e; font-weight: bold",
217
+ "color: #888"
218
+ );
219
+ if (showCauses && entry.causes.length > 0) {
220
+ const lines = formatCausesConsole(entry.causes);
221
+ for (const line of lines) {
222
+ console.log(`%c${line}`, "color: #aaa");
223
+ }
224
+ }
225
+ }
226
+ console.groupEnd();
227
+ }
215
228
  const ANIMATION_NAME = "__rdu-fade";
216
229
  const injectedWindows = /* @__PURE__ */ new WeakSet();
217
230
  function ensureStylesheet(win) {
@@ -309,13 +322,7 @@ function heatColor(count, alpha) {
309
322
  const lightness = 55 - normalizedCount * 10;
310
323
  return `hsla(${hue}, ${saturation}%, ${lightness}%, ${alpha})`;
311
324
  }
312
- const HIGHLIGHT_DEFAULTS = {
313
- flushInterval: 250,
314
- animationDuration: 1200,
315
- showLabels: true,
316
- opacity: 0.3
317
- };
318
- function createBatcher(options) {
325
+ function createHighlighter(config) {
319
326
  let pending = [];
320
327
  let timer = null;
321
328
  function flush() {
@@ -368,10 +375,10 @@ function createBatcher(options) {
368
375
  style.height = `${rect.height}px`;
369
376
  style.backgroundColor = fillColor;
370
377
  style.border = `1.5px solid ${borderColor}`;
371
- style.setProperty("--rdu-opacity", String(options.opacity));
372
- style.animation = `${OVERLAY_ANIMATION_NAME} ${options.animationDuration}ms ease-out forwards`;
378
+ style.setProperty("--rdu-opacity", String(config.opacity));
379
+ style.animation = `${OVERLAY_ANIMATION_NAME} ${config.animationDuration}ms ease-out forwards`;
373
380
  const label = element.firstElementChild;
374
- if (options.showLabels) {
381
+ if (config.showLabels) {
375
382
  const countText = coalesced.count > 1 ? ` ×${coalesced.count}` : "";
376
383
  const durationText = coalesced.totalDuration > 0 ? ` ${coalesced.totalDuration.toFixed(1)}ms` : "";
377
384
  const causeText = coalesced.causeSummary ? ` (${coalesced.causeSummary})` : "";
@@ -386,7 +393,7 @@ function createBatcher(options) {
386
393
  function push(entry) {
387
394
  pending.push(entry);
388
395
  if (!timer) {
389
- timer = setInterval(flush, options.flushInterval);
396
+ timer = setInterval(flush, config.flushInterval);
390
397
  }
391
398
  }
392
399
  function dispose() {
@@ -398,14 +405,18 @@ function createBatcher(options) {
398
405
  }
399
406
  return { push, dispose };
400
407
  }
401
- function attachRenderLogger(options = {}) {
408
+ function monitor(options = {}) {
402
409
  const {
403
410
  silent = false,
404
411
  bufferSize = 500,
405
412
  filter,
406
- highlight = false,
413
+ overlay = true,
407
414
  mode = "self-triggered",
408
- showCauses = false
415
+ showCauses = false,
416
+ flushInterval = 250,
417
+ animationDuration = 1200,
418
+ showLabels = true,
419
+ opacity = 0.3
409
420
  } = options;
410
421
  const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
411
422
  if (!hook) {
@@ -414,56 +425,46 @@ function attachRenderLogger(options = {}) {
414
425
  );
415
426
  return null;
416
427
  }
417
- const highlightOptions = highlight ? {
418
- ...HIGHLIGHT_DEFAULTS,
419
- ...typeof highlight === "object" ? highlight : {}
420
- } : null;
421
- const batcher = highlightOptions ? createBatcher(highlightOptions) : null;
428
+ const highlighter = overlay ? createHighlighter({ flushInterval, animationDuration, showLabels, opacity }) : null;
422
429
  const entries = [];
423
430
  const previousOnCommit = hook.onCommitFiberRoot.bind(hook);
424
431
  hook.onCommitFiberRoot = (rendererID, root, priorityLevel) => {
425
432
  previousOnCommit(rendererID, root, priorityLevel);
426
- const pendingEntries = collectPending(root.current, mode, showCauses);
427
- for (let i = 0; i < pendingEntries.length; i++) {
428
- const pendingEntry = pendingEntries[i];
429
- const entry = {
430
- component: pendingEntry.component,
431
- path: pendingEntry.path,
432
- duration: pendingEntry.duration,
433
+ const detectedRenders = detectRenders(root.current, mode);
434
+ if (detectedRenders.length === 0) return;
435
+ const highlightEntries = [];
436
+ for (let i = 0; i < detectedRenders.length; i++) {
437
+ const { fiber, depth } = detectedRenders[i];
438
+ const name = getComponentName(fiber);
439
+ if (!name) continue;
440
+ const highlightEntry = {
441
+ component: name,
442
+ path: getFiberPath(fiber),
443
+ duration: fiber.actualDuration ?? 0,
444
+ depth,
445
+ domNode: findNearestDOMNode(fiber),
446
+ causes: showCauses ? detectCauses(fiber) : []
447
+ };
448
+ const renderEntry = {
449
+ component: highlightEntry.component,
450
+ path: highlightEntry.path,
451
+ duration: highlightEntry.duration,
433
452
  timestamp: performance.now(),
434
- causes: pendingEntry.causes
453
+ causes: highlightEntry.causes
435
454
  };
436
- if (filter && !filter(entry)) continue;
455
+ if (filter && !filter(renderEntry)) continue;
437
456
  if (entries.length >= bufferSize) entries.shift();
438
- entries.push(entry);
439
- batcher == null ? void 0 : batcher.push(pendingEntry);
457
+ entries.push(renderEntry);
458
+ highlightEntries.push(highlightEntry);
459
+ highlighter == null ? void 0 : highlighter.push(highlightEntry);
440
460
  }
441
- if (!silent && pendingEntries.length > 0) {
442
- console.groupCollapsed(
443
- `%c⚛ ${pendingEntries.length} re-render${pendingEntries.length > 1 ? "s" : ""}`,
444
- "color: #61dafb; font-weight: bold"
445
- );
446
- for (let i = 0; i < pendingEntries.length; i++) {
447
- const pendingEntry = pendingEntries[i];
448
- const durationText = pendingEntry.duration > 0 ? ` (${pendingEntry.duration.toFixed(2)}ms)` : "";
449
- console.log(
450
- `%c${pendingEntry.component}%c ${pendingEntry.path}${durationText}`,
451
- "color: #e8e82e; font-weight: bold",
452
- "color: #888"
453
- );
454
- if (showCauses && pendingEntry.causes.length > 0) {
455
- const lines = formatCausesConsole(pendingEntry.causes);
456
- for (const line of lines) {
457
- console.log(`%c${line}`, "color: #aaa");
458
- }
459
- }
460
- }
461
- console.groupEnd();
461
+ if (!silent) {
462
+ logRerendersToConsole(highlightEntries, showCauses);
462
463
  }
463
464
  };
464
- const disconnect = () => {
465
+ const stop = () => {
465
466
  hook.onCommitFiberRoot = previousOnCommit;
466
- batcher == null ? void 0 : batcher.dispose();
467
+ highlighter == null ? void 0 : highlighter.dispose();
467
468
  disposeAllOverlays();
468
469
  };
469
470
  if (!silent) {
@@ -472,7 +473,7 @@ function attachRenderLogger(options = {}) {
472
473
  "color: #61dafb; font-weight: bold"
473
474
  );
474
475
  }
475
- return { entries, disconnect };
476
+ return { entries, stop };
476
477
  }
477
- exports.attachRenderLogger = attachRenderLogger;
478
+ exports.monitor = monitor;
478
479
  //# sourceMappingURL=react-debug-updates.cjs.map