bippy 0.0.23 → 0.0.24

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
@@ -2,76 +2,219 @@
2
2
 
3
3
  a hacky way to get fibers from react. used internally for [`react-scan`](https://github.com/aidenybai/react-scan).
4
4
 
5
- bippy works by setting a "fake" version of the `__REACT_DEVTOOLS_GLOBAL_HOOK__` object. this gives us access to react internals without actually using react devtools.
5
+ bippy works by monkey-patching `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` with [custom handlers](https://github.com/facebook/react/blob/6a4b46cd70d2672bc4be59dcb5b8dede22ed0cef/packages/react-refresh/src/ReactFreshRuntime.js#L427). this gives us access to react internals without needing to use react devtools.
6
6
 
7
7
  > [!WARNING]
8
8
  > this project uses react internals, which can change at any time. **this is not recommended for usage and may break production apps** - unless you acknowledge this risk and know exactly you're doing.
9
9
 
10
- ## example
10
+ ## tutorial: create a mini react-scan
11
11
 
12
- here i wrote a `getRenderInfo` function, where you're able to pass any component identifier and get back the number of times it rendered, as well as the total and self time. this is done by traversing the fiber tree during a [commit](https://react.dev/learn/render-and-commit) via `onCommitFiberRoot`.
12
+ [`react-scan`](https://github.com/aidenybai/react-scan) is a tool that highlights renders in your react app. under the hood, it uses bippy to detect rendered fibers.
13
13
 
14
- inspect it live [here](https://bippy.million.dev/).
14
+ fibers are how "work" is represented in react. each fiber either represents a composite (function/class component) or a host (dom element). [here is a live visualization](https://jser.pro/ddir/rie?reactVersion=18.3.1&snippetKey=hq8jm2ylzb9u8eh468) of what the fiber tree looks like, and here is a [deep dive article](https://jser.dev/2023-07-18-how-react-rerenders/).
15
+
16
+ a simplified version of a fiber looks roughly like this:
17
+
18
+ ```typescript
19
+ interface Fiber {
20
+ // component type (function/class)
21
+ type: any;
22
+
23
+ child: Fiber | null;
24
+ sibling: Fiber | null;
25
+
26
+ // parent fiber
27
+ return: Fiber | null;
28
+
29
+ // saved props input
30
+ memoizedProps: any;
31
+
32
+ // state (useState, useReducer, useSES, etc.)
33
+ memoizedState: any;
34
+
35
+ // contexts (useContext)
36
+ dependencies: Dependencies | null;
37
+ }
38
+ ```
39
+
40
+ however, fibers aren't directly accessible by the user. so, we have to hack our way around to accessing it.
41
+
42
+ luckily, react [reads from a property](https://github.com/facebook/react/blob/6a4b46cd70d2672bc4be59dcb5b8dede22ed0cef/packages/react-reconciler/src/ReactFiberDevToolsHook.js#L48) in the window object: `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` and runs handlers on it when certain events happen. this is intended for react devtools, but we can use it to our advantage.
43
+
44
+ here's what it roughly looks like:
45
+
46
+ ```typescript
47
+ interface __REACT_DEVTOOLS_GLOBAL_HOOK__ {
48
+ // list of renderers (react-dom, react-native, etc.)
49
+ renderers: Map<RendererID, ReactRenderer>;
50
+
51
+ // called when react has rendered everythign and ready to apply changes to the host tree (e.g. DOM mutations)
52
+ onCommitFiberRoot: (
53
+ rendererID: RendererID,
54
+ fiber: Record<string, unknown>,
55
+ commitPriority?: number,
56
+ didError?: boolean,
57
+ ) => void;
58
+ }
59
+ ```
60
+
61
+ we can use bippy's utils and the `onCommitFiberRoot` handler to detect renders!
62
+
63
+ ### 0. setup
64
+
65
+ first, [create a new react project via stackblitz](https://stackblitz.com/fork/github/vitejs/vite/tree/main/packages/create-vite/template-react?file=src/App.jsx&terminal=dev)
66
+
67
+ then, install bippy:
68
+
69
+ ```bash
70
+ npm install bippy
71
+ ```
72
+
73
+ finally, re-run the dev server:
74
+
75
+ ```bash
76
+ npm run dev
77
+ ```
78
+
79
+ ### 1. use `onCommitFiberRoot` to get fibers
80
+
81
+ let's use `instrument` to stub the `__REACT_DEVTOOLS_GLOBAL_HOOK__` object, and setup a custom handler for `onCommitFiberRoot`.
82
+
83
+ ```jsx
84
+ import { instrument } from 'bippy'; // must be imported BEFORE react
85
+
86
+ // rest of your code ...
87
+
88
+ instrument({
89
+ onCommitFiberRoot(rendererID, root) {
90
+ const fiberRoot = root.current;
91
+ console.log('fiberRoot', fiberRoot);
92
+ },
93
+ });
94
+ ```
95
+
96
+ running this should log `fiberRoot` to the console. i recommend you playing with this code to get a feel for how fibers work.
97
+
98
+ ### 2. create a fiber visitor
99
+
100
+ now, let's create a fiber visitor with `createFiberVisitor` to "visit" fibers that render. not every fiber actually renders, so we need to filter for the ones that do.
101
+
102
+ ```jsx
103
+ import { instrument, createFiberVisitor } from 'bippy'; // must be imported BEFORE react
104
+
105
+ // rest of your code ...
106
+
107
+ const visit = createFiberVisitor({
108
+ onRender(fiber) {
109
+ console.log('fiber render', fiber);
110
+ },
111
+ });
112
+
113
+ instrument({
114
+ onCommitFiberRoot(rendererID, root) {
115
+ visit(rendererID, root);
116
+ },
117
+ });
118
+ ```
119
+
120
+ ### 3. determine DOM nodes to highlight
121
+
122
+ next, we need to identify which DOM nodes we are going to highlight. we can do this by checking if the fiber is a host fiber, or if it's not, find the nearest host fiber.
15
123
 
16
124
  ```jsx
17
125
  import {
18
126
  instrument,
127
+ isHostFiber,
128
+ getNearestHostFiber,
19
129
  createFiberVisitor,
20
- getTimings,
21
- getDisplayName,
22
130
  } from 'bippy'; // must be imported BEFORE react
23
- import React, { useState } from 'react';
24
- import ReactDOM from 'react-dom/client';
25
-
26
- const componentRenderMap = new WeakMap();
27
-
28
- const visitor = createFiberVisitor({
29
- onRender(fiber, phase) {
30
- const componentType = fiber.elementType;
31
- if (
32
- typeof componentType !== 'function' &&
33
- (typeof componentType !== 'object' || !componentType)
34
- ) {
35
- return;
131
+
132
+ // rest of your code ...
133
+
134
+ const highlightFiber = (fiber) => {
135
+ if (!(fiber instanceof HTMLElement)) return;
136
+
137
+ console.log('highlight dom node', fiber.stateNode);
138
+ };
139
+
140
+ const visit = createFiberVisitor({
141
+ onRender(fiber) {
142
+ if (isHostFiber(fiber)) {
143
+ highlightFiber(fiber);
144
+ } else {
145
+ // can be a component
146
+ const hostFiber = getNearestHostFiber(fiber);
147
+ highlightFiber(hostFiber);
36
148
  }
37
- const render = componentRenderMap.get(componentType) || {
38
- count: 0,
39
- selfTime: 0,
40
- totalTime: 0,
41
- displayName: getDisplayName(componentType),
42
- };
43
- render.count++;
44
- const { selfTime, totalTime } = getTimings(fiber);
45
- render.selfTime += selfTime;
46
- render.totalTime += totalTime;
47
- componentRenderMap.set(componentType, render);
48
- console.log(phase, render);
49
149
  },
50
150
  });
51
151
 
52
152
  instrument({
53
- onCommitFiberRoot: (rendererID, fiberRoot) => {
54
- visitor(rendererID, fiberRoot);
153
+ onCommitFiberRoot(rendererID, root) {
154
+ visit(rendererID, root);
55
155
  },
56
156
  });
157
+ ```
158
+
159
+ ### 4. highlight DOM nodes
160
+
161
+ now, let's implement the `highlightFiber` function to highlight the DOM node. the simplest way is to just overlay a div (with a red border) on top of the DOM node.
57
162
 
58
- export const getRenderInfo = (componentType) => {
59
- return componentRenderMap.get(componentType);
163
+ ```jsx
164
+ import {
165
+ instrument,
166
+ isHostFiber,
167
+ getNearestHostFiber,
168
+ createFiberVisitor,
169
+ } from 'bippy'; // must be imported BEFORE react
170
+
171
+ // rest of your code ...
172
+
173
+ const highlightFiber = (fiber) => {
174
+ if (!(fiber.stateNode instanceof HTMLElement)) return;
175
+
176
+ const rect = fiber.stateNode.getBoundingClientRect();
177
+ const highlight = document.createElement('div');
178
+ highlight.style.border = '1px solid red';
179
+ highlight.style.position = 'fixed';
180
+ highlight.style.top = `${rect.top}px`;
181
+ highlight.style.left = `${rect.left}px`;
182
+ highlight.style.width = `${rect.width}px`;
183
+ highlight.style.height = `${rect.height}px`;
184
+ highlight.style.zIndex = 999999999;
185
+ document.documentElement.appendChild(highlight);
186
+ setTimeout(() => {
187
+ document.documentElement.removeChild(highlight);
188
+ }, 100);
60
189
  };
61
190
 
62
- function App() {
63
- const [count, setCount] = useState(0);
64
- const renderInfo = getRenderInfo(App);
65
- return (
66
- <button onClick={() => setCount(count + 1)}>
67
- rendered: {JSON.stringify(renderInfo, null, 2)}
68
- </button>
69
- );
70
- }
191
+ const visit = createFiberVisitor({
192
+ onRender(fiber) {
193
+ if (isHostFiber(fiber)) {
194
+ highlightFiber(fiber);
195
+ } else {
196
+ // can be a component
197
+ const hostFiber = getNearestHostFiber(fiber);
198
+ highlightFiber(hostFiber);
199
+ }
200
+ },
201
+ });
71
202
 
72
- ReactDOM.createRoot(document.getElementById('root')).render(<App />);
203
+ instrument({
204
+ onCommitFiberRoot(rendererID, root) {
205
+ visit(rendererID, root);
206
+ },
207
+ });
73
208
  ```
74
209
 
210
+ ### 5. profit
211
+
212
+ try a completed version [here](https://bippy.million.dev)
213
+
214
+ you can learn more about bippy by [reading the source code](https://github.com/aidenybai/bippy/blob/main/src/index.ts).
215
+
216
+ looking for a more robust version of our mini react-scan? try out [react-scan](https://github.com/aidenybai/react-scan).
217
+
75
218
  ## misc
76
219
 
77
220
  the original bippy character is owned and created by [@dairyfreerice](https://www.instagram.com/dairyfreerice). this project is not related to the bippy brand, i just think the character is cute
package/dist/index.cjs CHANGED
@@ -249,39 +249,43 @@ var checkDCE = (fn) => {
249
249
  };
250
250
  var NO_OP = () => {
251
251
  };
252
+ var installRDTHook = (onActive) => {
253
+ const renderers = /* @__PURE__ */ new Map();
254
+ let i = 0;
255
+ const rdtHook = {
256
+ checkDCE,
257
+ supportsFiber: true,
258
+ supportsFlight: true,
259
+ renderers,
260
+ onCommitFiberRoot: NO_OP,
261
+ onCommitFiberUnmount: NO_OP,
262
+ onPostCommitFiberRoot: NO_OP,
263
+ inject(renderer) {
264
+ const nextID = ++i;
265
+ renderers.set(nextID, renderer);
266
+ if (!rdtHook._instrumentationIsActive) {
267
+ rdtHook._instrumentationIsActive = true;
268
+ onActive?.();
269
+ }
270
+ return nextID;
271
+ },
272
+ _instrumentationSource: "bippy",
273
+ _instrumentationIsActive: false
274
+ };
275
+ try {
276
+ Object.defineProperty(globalThis, "__REACT_DEVTOOLS_GLOBAL_HOOK__", {
277
+ configurable: true,
278
+ value: rdtHook
279
+ });
280
+ } catch {
281
+ }
282
+ return rdtHook;
283
+ };
252
284
  var getRDTHook = (onActive) => {
253
285
  let rdtHook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
254
286
  if (rdtHook) onActive?.();
255
287
  if (!window.hasOwnProperty("__REACT_DEVTOOLS_GLOBAL_HOOK__")) {
256
- const renderers = /* @__PURE__ */ new Map();
257
- let i = 0;
258
- rdtHook ??= {
259
- checkDCE,
260
- supportsFiber: true,
261
- supportsFlight: true,
262
- renderers,
263
- onCommitFiberRoot: NO_OP,
264
- onCommitFiberUnmount: NO_OP,
265
- onPostCommitFiberRoot: NO_OP,
266
- inject(renderer) {
267
- const nextID = ++i;
268
- renderers.set(nextID, renderer);
269
- if (!rdtHook._instrumentationIsActive) {
270
- rdtHook._instrumentationIsActive = true;
271
- onActive?.();
272
- }
273
- return nextID;
274
- },
275
- _instrumentationSource: "bippy",
276
- _instrumentationIsActive: Boolean(rdtHook)
277
- };
278
- try {
279
- Object.defineProperty(globalThis, "__REACT_DEVTOOLS_GLOBAL_HOOK__", {
280
- configurable: true,
281
- value: rdtHook
282
- });
283
- } catch {
284
- }
288
+ rdtHook = installRDTHook(onActive);
285
289
  }
286
290
  return rdtHook;
287
291
  };
@@ -289,10 +293,6 @@ var isInstrumentationActive = () => {
289
293
  const rdtHook = getRDTHook();
290
294
  return Boolean(rdtHook._instrumentationIsActive) || isUsingRDT();
291
295
  };
292
- if (typeof window !== "undefined") {
293
- performance.now();
294
- getRDTHook();
295
- }
296
296
  var mountFiberRecursively = (onRender, firstChild, traverseSiblings) => {
297
297
  let fiber = firstChild;
298
298
  while (fiber != null) {
@@ -473,6 +473,11 @@ var instrument = ({
473
473
  }
474
474
  return devtoolsHook;
475
475
  };
476
+ var isBrowser = typeof document !== "undefined" && typeof document.createElement === "function";
477
+ var isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
478
+ if (isBrowser || !isNode) {
479
+ installRDTHook();
480
+ }
476
481
 
477
482
  exports.CONCURRENT_MODE_NUMBER = CONCURRENT_MODE_NUMBER;
478
483
  exports.CONCURRENT_MODE_SYMBOL_STRING = CONCURRENT_MODE_SYMBOL_STRING;
@@ -518,6 +523,7 @@ exports.getRDTHook = getRDTHook;
518
523
  exports.getTimings = getTimings;
519
524
  exports.getType = getType;
520
525
  exports.hasMemoCache = hasMemoCache;
526
+ exports.installRDTHook = installRDTHook;
521
527
  exports.instrument = instrument;
522
528
  exports.isCompositeFiber = isCompositeFiber;
523
529
  exports.isHostFiber = isHostFiber;
package/dist/index.d.cts CHANGED
@@ -50,7 +50,15 @@ declare const Snapshot = 1024;
50
50
  declare const Visibility = 8192;
51
51
  declare const MutationMask: number;
52
52
  declare const isValidElement: (element: unknown) => element is React.ReactElement;
53
+ /**
54
+ * Host fibers are DOM nodes in react-dom, `View` in react-native, etc.
55
+ */
53
56
  declare const isHostFiber: (fiber: Fiber) => boolean;
57
+ /**
58
+ * Composite fibers are functional, class components, etc.
59
+ *
60
+ * @see https://github.com/facebook/react/blob/865d2c418d5ba6fb4546e4b58616cd9b7701af85/packages/react/src/jsx/ReactJSXElement.js#L490
61
+ */
54
62
  declare const isCompositeFiber: (fiber: Fiber) => boolean;
55
63
  declare const traverseContexts: (fiber: Fiber, selector: (prevValue: {
56
64
  context: React.Context<unknown>;
@@ -66,6 +74,9 @@ declare const traverseState: (fiber: Fiber, selector: (prevValue: {
66
74
  }) => boolean | void) => boolean;
67
75
  declare const traverseProps: (fiber: Fiber, selector: (prevValue: unknown, nextValue: unknown) => boolean | void) => boolean;
68
76
  declare const didFiberRender: (fiber: Fiber) => boolean;
77
+ /**
78
+ * A commit is means reconciliation occured and the host tree is updated
79
+ */
69
80
  declare const didFiberCommit: (fiber: Fiber) => boolean;
70
81
  declare const getMutatedHostFibers: (fiber: Fiber) => Array<Fiber>;
71
82
  declare const getFiberStack: (fiber: Fiber) => any[];
@@ -81,6 +92,7 @@ declare const getType: (type: any) => any;
81
92
  declare const getDisplayName: (type: any) => string | null;
82
93
  declare const isUsingRDT: () => boolean;
83
94
  declare const detectReactBuildType: (renderer: ReactRenderer) => "development" | "production";
95
+ declare const installRDTHook: (onActive?: () => unknown) => ReactDevToolsGlobalHook;
84
96
  declare const getRDTHook: (onActive?: () => unknown) => ReactDevToolsGlobalHook;
85
97
  declare const isInstrumentationActive: () => boolean;
86
98
  type RenderHandler = <S>(fiber: Fiber, phase: 'mount' | 'update' | 'unmount', state?: S) => unknown;
@@ -88,10 +100,33 @@ declare const mountFiberRecursively: (onRender: RenderHandler, firstChild: Fiber
88
100
  declare const updateFiberRecursively: (onRender: RenderHandler, nextFiber: Fiber, prevFiber: Fiber, parentFiber: Fiber | null) => void;
89
101
  declare const unmountFiber: (onRender: RenderHandler, fiber: Fiber) => void;
90
102
  declare const unmountFiberChildrenRecursively: (onRender: RenderHandler, fiber: Fiber) => void;
103
+ /**
104
+ * Creates a fiber visitor function.
105
+ * @param options { onRender, onError }
106
+ * @example
107
+ * const visitor = createFiberVisitor({
108
+ * onRender(fiber, phase) {
109
+ * console.log(phase)
110
+ * },
111
+ * });
112
+ */
91
113
  declare const createFiberVisitor: ({ onRender: onRenderWithoutState, onError, }: {
92
114
  onRender: RenderHandler;
93
115
  onError?: (error: unknown) => unknown;
94
116
  }) => <S>(_rendererID: number, root: FiberRoot, state?: S) => void;
117
+ /**
118
+ * Instruments the DevTools hook.
119
+ * @param options { onCommitFiberRoot, onCommitFiberUnmount, onPostCommitFiberRoot, onActive, name }
120
+ * @example
121
+ * const hook = instrument({
122
+ * onActive() {
123
+ * console.log('initialized');
124
+ * },
125
+ * onCommitFiberRoot(rendererID, root) {
126
+ * console.log('fiberRoot', root.current)
127
+ * },
128
+ * });
129
+ */
95
130
  declare const instrument: ({ onCommitFiberRoot, onCommitFiberUnmount, onPostCommitFiberRoot, onActive, name, }: {
96
131
  onCommitFiberRoot?: (rendererID: number, root: FiberRoot, priority: void | number) => unknown;
97
132
  onCommitFiberUnmount?: (rendererID: number, root: FiberRoot) => unknown;
@@ -100,4 +135,4 @@ declare const instrument: ({ onCommitFiberRoot, onCommitFiberUnmount, onPostComm
100
135
  name?: string;
101
136
  }) => ReactDevToolsGlobalHook;
102
137
 
103
- export { CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_STRING, ChildDeletion, ClassComponentTag, Cloned, ContentReset, ContextConsumerTag, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponent, DidCapture, ForwardRefTag, Fragment, FunctionComponentTag, HostComponentTag, HostHoistableTag, HostRoot, HostSingletonTag, HostText, Hydrating, LegacyHiddenComponent, MemoComponentTag, MutationMask, OffscreenComponent, OffscreenComponentTag, PerformedWork, Placement, type ReactDevToolsGlobalHook, type ReactRenderer, Ref, SimpleMemoComponentTag, Snapshot, SuspenseComponentTag, Update, Visibility, createFiberVisitor, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberStack, getMutatedHostFibers, getNearestHostFiber, getRDTHook, getTimings, getType, hasMemoCache, instrument, isCompositeFiber, isHostFiber, isInstrumentationActive, isUsingRDT, isValidElement, mountFiberRecursively, shouldFilterFiber, traverseContexts, traverseFiber, traverseProps, traverseState, unmountFiber, unmountFiberChildrenRecursively, updateFiberRecursively };
138
+ export { CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_STRING, ChildDeletion, ClassComponentTag, Cloned, ContentReset, ContextConsumerTag, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponent, DidCapture, ForwardRefTag, Fragment, FunctionComponentTag, HostComponentTag, HostHoistableTag, HostRoot, HostSingletonTag, HostText, Hydrating, LegacyHiddenComponent, MemoComponentTag, MutationMask, OffscreenComponent, OffscreenComponentTag, PerformedWork, Placement, type ReactDevToolsGlobalHook, type ReactRenderer, Ref, SimpleMemoComponentTag, Snapshot, SuspenseComponentTag, Update, Visibility, createFiberVisitor, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberStack, getMutatedHostFibers, getNearestHostFiber, getRDTHook, getTimings, getType, hasMemoCache, installRDTHook, instrument, isCompositeFiber, isHostFiber, isInstrumentationActive, isUsingRDT, isValidElement, mountFiberRecursively, shouldFilterFiber, traverseContexts, traverseFiber, traverseProps, traverseState, unmountFiber, unmountFiberChildrenRecursively, updateFiberRecursively };
package/dist/index.d.ts CHANGED
@@ -50,7 +50,15 @@ declare const Snapshot = 1024;
50
50
  declare const Visibility = 8192;
51
51
  declare const MutationMask: number;
52
52
  declare const isValidElement: (element: unknown) => element is React.ReactElement;
53
+ /**
54
+ * Host fibers are DOM nodes in react-dom, `View` in react-native, etc.
55
+ */
53
56
  declare const isHostFiber: (fiber: Fiber) => boolean;
57
+ /**
58
+ * Composite fibers are functional, class components, etc.
59
+ *
60
+ * @see https://github.com/facebook/react/blob/865d2c418d5ba6fb4546e4b58616cd9b7701af85/packages/react/src/jsx/ReactJSXElement.js#L490
61
+ */
54
62
  declare const isCompositeFiber: (fiber: Fiber) => boolean;
55
63
  declare const traverseContexts: (fiber: Fiber, selector: (prevValue: {
56
64
  context: React.Context<unknown>;
@@ -66,6 +74,9 @@ declare const traverseState: (fiber: Fiber, selector: (prevValue: {
66
74
  }) => boolean | void) => boolean;
67
75
  declare const traverseProps: (fiber: Fiber, selector: (prevValue: unknown, nextValue: unknown) => boolean | void) => boolean;
68
76
  declare const didFiberRender: (fiber: Fiber) => boolean;
77
+ /**
78
+ * A commit is means reconciliation occured and the host tree is updated
79
+ */
69
80
  declare const didFiberCommit: (fiber: Fiber) => boolean;
70
81
  declare const getMutatedHostFibers: (fiber: Fiber) => Array<Fiber>;
71
82
  declare const getFiberStack: (fiber: Fiber) => any[];
@@ -81,6 +92,7 @@ declare const getType: (type: any) => any;
81
92
  declare const getDisplayName: (type: any) => string | null;
82
93
  declare const isUsingRDT: () => boolean;
83
94
  declare const detectReactBuildType: (renderer: ReactRenderer) => "development" | "production";
95
+ declare const installRDTHook: (onActive?: () => unknown) => ReactDevToolsGlobalHook;
84
96
  declare const getRDTHook: (onActive?: () => unknown) => ReactDevToolsGlobalHook;
85
97
  declare const isInstrumentationActive: () => boolean;
86
98
  type RenderHandler = <S>(fiber: Fiber, phase: 'mount' | 'update' | 'unmount', state?: S) => unknown;
@@ -88,10 +100,33 @@ declare const mountFiberRecursively: (onRender: RenderHandler, firstChild: Fiber
88
100
  declare const updateFiberRecursively: (onRender: RenderHandler, nextFiber: Fiber, prevFiber: Fiber, parentFiber: Fiber | null) => void;
89
101
  declare const unmountFiber: (onRender: RenderHandler, fiber: Fiber) => void;
90
102
  declare const unmountFiberChildrenRecursively: (onRender: RenderHandler, fiber: Fiber) => void;
103
+ /**
104
+ * Creates a fiber visitor function.
105
+ * @param options { onRender, onError }
106
+ * @example
107
+ * const visitor = createFiberVisitor({
108
+ * onRender(fiber, phase) {
109
+ * console.log(phase)
110
+ * },
111
+ * });
112
+ */
91
113
  declare const createFiberVisitor: ({ onRender: onRenderWithoutState, onError, }: {
92
114
  onRender: RenderHandler;
93
115
  onError?: (error: unknown) => unknown;
94
116
  }) => <S>(_rendererID: number, root: FiberRoot, state?: S) => void;
117
+ /**
118
+ * Instruments the DevTools hook.
119
+ * @param options { onCommitFiberRoot, onCommitFiberUnmount, onPostCommitFiberRoot, onActive, name }
120
+ * @example
121
+ * const hook = instrument({
122
+ * onActive() {
123
+ * console.log('initialized');
124
+ * },
125
+ * onCommitFiberRoot(rendererID, root) {
126
+ * console.log('fiberRoot', root.current)
127
+ * },
128
+ * });
129
+ */
95
130
  declare const instrument: ({ onCommitFiberRoot, onCommitFiberUnmount, onPostCommitFiberRoot, onActive, name, }: {
96
131
  onCommitFiberRoot?: (rendererID: number, root: FiberRoot, priority: void | number) => unknown;
97
132
  onCommitFiberUnmount?: (rendererID: number, root: FiberRoot) => unknown;
@@ -100,4 +135,4 @@ declare const instrument: ({ onCommitFiberRoot, onCommitFiberUnmount, onPostComm
100
135
  name?: string;
101
136
  }) => ReactDevToolsGlobalHook;
102
137
 
103
- export { CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_STRING, ChildDeletion, ClassComponentTag, Cloned, ContentReset, ContextConsumerTag, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponent, DidCapture, ForwardRefTag, Fragment, FunctionComponentTag, HostComponentTag, HostHoistableTag, HostRoot, HostSingletonTag, HostText, Hydrating, LegacyHiddenComponent, MemoComponentTag, MutationMask, OffscreenComponent, OffscreenComponentTag, PerformedWork, Placement, type ReactDevToolsGlobalHook, type ReactRenderer, Ref, SimpleMemoComponentTag, Snapshot, SuspenseComponentTag, Update, Visibility, createFiberVisitor, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberStack, getMutatedHostFibers, getNearestHostFiber, getRDTHook, getTimings, getType, hasMemoCache, instrument, isCompositeFiber, isHostFiber, isInstrumentationActive, isUsingRDT, isValidElement, mountFiberRecursively, shouldFilterFiber, traverseContexts, traverseFiber, traverseProps, traverseState, unmountFiber, unmountFiberChildrenRecursively, updateFiberRecursively };
138
+ export { CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_STRING, ChildDeletion, ClassComponentTag, Cloned, ContentReset, ContextConsumerTag, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponent, DidCapture, ForwardRefTag, Fragment, FunctionComponentTag, HostComponentTag, HostHoistableTag, HostRoot, HostSingletonTag, HostText, Hydrating, LegacyHiddenComponent, MemoComponentTag, MutationMask, OffscreenComponent, OffscreenComponentTag, PerformedWork, Placement, type ReactDevToolsGlobalHook, type ReactRenderer, Ref, SimpleMemoComponentTag, Snapshot, SuspenseComponentTag, Update, Visibility, createFiberVisitor, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberStack, getMutatedHostFibers, getNearestHostFiber, getRDTHook, getTimings, getType, hasMemoCache, installRDTHook, instrument, isCompositeFiber, isHostFiber, isInstrumentationActive, isUsingRDT, isValidElement, mountFiberRecursively, shouldFilterFiber, traverseContexts, traverseFiber, traverseProps, traverseState, unmountFiber, unmountFiberChildrenRecursively, updateFiberRecursively };
@@ -6,5 +6,5 @@ var Bippy=(function(exports){'use strict';/**
6
6
  * This source code is licensed under the MIT license found in the
7
7
  * LICENSE file in the root directory of this source tree.
8
8
  */
9
- var D=1,H=0,E=9,P=13,M=22,z=11,I=14,A=15,N=5,V=26,U=27,j=18,L=6,B=7,G=23,W=22,$=3,K=60111,R="Symbol(react.concurrent_mode)",_="Symbol(react.async_mode)",Y=1,J=2,Q=128,q=4096,X=4,Z=8,ee=16,te=32,ne=512,oe=1024,re=8192,ie=13366,le=e=>typeof e=="object"&&e!=null&&"$$typeof"in e&&["Symbol(react.element)","Symbol(react.transitional.element)"].includes(String(e.$$typeof)),d=e=>e.tag===5||e.tag===26||e.tag===27,se=e=>e.tag===0||e.tag===1||e.tag===15||e.tag===14||e.tag===11,ae=(e,t)=>{try{let o=e.dependencies,n=e.alternate?.dependencies;if(!o||!n||typeof o!="object"||!("firstContext"in o)||typeof n!="object"||!("firstContext"in n))return !1;let l=o.firstContext,r=n.firstContext;for(;l&&typeof l=="object"&&"memoizedValue"in l&&r&&typeof r=="object"&&"memoizedValue"in r;){if(t(l,r)===!0)return !0;l=l.next,r=r.next;}}catch{}return !1},ce=(e,t)=>{try{let o=e.memoizedState,n=e.alternate?.memoizedState;for(;o&&n;){if(t(o,n)===!0)return !0;o=o.next,n=n.next;}}catch{}return !1},ue=(e,t)=>{try{let o=e.memoizedProps,n=e.alternate?.memoizedProps||{},l=new Set([...Object.keys(n),...Object.keys(o)]);for(let r of l){let s=n?.[r],c=o?.[r];if(t(s,c)===!0)return !0}}catch{}return !1},C=e=>{let t=e.memoizedProps,o=e.alternate?.memoizedProps||{},n=e.flags??e.effectTag??0;switch(e.tag){case 1:case 0:case 9:case 11:case 14:case 15:return (n&1)===1;default:return e.alternate?o!==t||e.alternate.memoizedState!==e.memoizedState||e.alternate.ref!==e.ref:!0}},w=e=>!!(e.flags&22||e.subtreeFlags&22),me=e=>{let t=[],o=[e];for(;o.length;){let n=o.pop();n&&(d(n)&&w(n)&&C(n)&&t.push(n),n.child&&o.push(n.child),n.sibling&&o.push(n.sibling));}return t},pe=e=>{let t=[];for(;e.return;)t.push(e),e=e.return;let o=new Array(t.length);for(let n=0;n<t.length;n++)o[n]=t[t.length-n-1];return o},g=e=>{switch(e.tag){case 18:return !0;case 6:case 7:case 23:case 22:return !0;case 3:return !1;default:{let t=typeof e.type=="object"&&e.type!==null?e.type.$$typeof:e.type;switch(typeof t=="symbol"?t.toString():t){case 60111:case R:case _:return !0;default:return !1}}}},de=e=>{let t=b(e,d);return t||(t=b(e,d,!0)),t},b=(e,t,o=!1)=>{if(!e)return null;if(t(e)===!0)return e;let n=o?e.return:e.child;for(;n;){let l=b(n,t,o);if(l)return l;n=o?null:n.sibling;}return null},be=e=>{let t=e?.actualDuration??0,o=t,n=e?.child??null;for(;t>0&&n!=null;)o-=n.actualDuration??0,n=n.sibling;return {selfTime:o,totalTime:t}},fe=e=>!!e.updateQueue?.memoCache,y=e=>typeof e=="function"?e:typeof e=="object"&&e?y(e.type||e.render):null,Ce=e=>{if(typeof e!="function"&&!(typeof e=="object"&&e))return null;let t=e.displayName||e.name||null;return t||(e=y(e),e&&(e.displayName||e.name)||null)},k=()=>globalThis.__REACT_DEVTOOLS_BACKEND_MANAGER_INJECTED__!=null,ge=e=>{try{if(typeof e.version=="string"&&e.bundleType>0)return "development"}catch{}return "production"},v=e=>{try{Function.prototype.toString.call(e).indexOf("^_^")>-1&&setTimeout(()=>{throw new Error("React is running in production mode, but dead code elimination has not been applied. Read how to correctly configure React for production: https://reactjs.org/link/perf-use-production-build")});}catch{}},p=()=>{},h=e=>{let t=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;if(t&&e?.(),!window.hasOwnProperty("__REACT_DEVTOOLS_GLOBAL_HOOK__")){let o=new Map,n=0;t??={checkDCE:v,supportsFiber:!0,supportsFlight:!0,renderers:o,onCommitFiberRoot:p,onCommitFiberUnmount:p,onPostCommitFiberRoot:p,inject(l){let r=++n;return o.set(r,l),t._instrumentationIsActive||(t._instrumentationIsActive=!0,e?.()),r},_instrumentationSource:"bippy",_instrumentationIsActive:!!t};try{Object.defineProperty(globalThis,"__REACT_DEVTOOLS_GLOBAL_HOOK__",{configurable:!0,value:t});}catch{}}return t},he=()=>!!h()._instrumentationIsActive||k();typeof window<"u"&&(performance.now(),h());var m=(e,t,o)=>{let n=t;for(;n!=null;){if(!g(n)&&C(n)&&e(n,"mount"),n.tag===13)if(n.memoizedState!==null){let s=n.child,c=s?s.sibling:null;if(c){let i=c.child;i!==null&&m(e,i,!1);}}else {let s=null;n.child!==null&&(s=n.child.child),s!==null&&m(e,s,!1);}else n.child!=null&&m(e,n.child,!0);n=o?n.sibling:null;}},f=(e,t,o,n)=>{if(!o)return;let l=t.tag===13,r=!g(t);r&&C(t)&&e(t,"update");let s=l&&o.memoizedState!==null,c=l&&t.memoizedState!==null;if(s&&c){let i=t.child?.sibling??null,a=o.child?.sibling??null;i!==null&&a!==null&&f(e,i,a);}else if(s&&!c){let i=t.child;i!==null&&m(e,i,!0);}else if(!s&&c){T(e,o);let i=t.child?.sibling??null;i!==null&&m(e,i,!0);}else if(t.child!==o.child){let i=t.child;for(;i;){if(i.alternate){let a=i.alternate;f(e,i,a);}else m(e,i,!1);i=i.sibling;}}},S=(e,t)=>{(t.tag===3||!g(t))&&e(t,"unmount");},T=(e,t)=>{let o=t.tag===13&&t.memoizedState!==null,n=t.child;for(o&&(n=(t.child?.sibling??null)?.child??null);n!==null;)n.return!==null&&(S(e,n),T(e,n)),n=n.sibling;},O=0,F=new WeakMap,xe=({onRender:e,onError:t})=>(o,n,l)=>{let r=n.current,s=(a,u)=>e(a,u,l),c=F.get(n);c||(c={prevFiber:null,id:O++},F.set(n,c));let{prevFiber:i}=c;try{if(i!==null){let a=i&&i.memoizedState!=null&&i.memoizedState.element!=null&&i.memoizedState.isDehydrated!==!0,u=r.memoizedState!=null&&r.memoizedState.element!=null&&r.memoizedState.isDehydrated!==!0;!a&&u?m(s,r,!1):a&&u?f(s,r,r.alternate,null):a&&!u&&S(s,r);}else m(s,r,!1);}catch(a){if(t)t(a);else throw a}c.prevFiber=r;},Fe=({onCommitFiberRoot:e,onCommitFiberUnmount:t,onPostCommitFiberRoot:o,onActive:n,name:l})=>{let r=h(n);r._instrumentationSource=l??"bippy";let s=r.onCommitFiberRoot;e&&(r.onCommitFiberRoot=(a,u,x)=>{s&&s(a,u,x),e(a,u,x);});let c=r.onCommitFiberUnmount;t&&(r.onCommitFiberUnmount=(a,u)=>{c&&c(a,u),t(a,u);});let i=r.onPostCommitFiberRoot;return o&&(r.onPostCommitFiberRoot=(a,u)=>{i&&i(a,u);}),r};
10
- exports.CONCURRENT_MODE_NUMBER=K;exports.CONCURRENT_MODE_SYMBOL_STRING=R;exports.ChildDeletion=ee;exports.ClassComponentTag=D;exports.Cloned=Z;exports.ContentReset=te;exports.ContextConsumerTag=E;exports.DEPRECATED_ASYNC_MODE_SYMBOL_STRING=_;exports.DehydratedSuspenseComponent=j;exports.DidCapture=Q;exports.ForwardRefTag=z;exports.Fragment=B;exports.FunctionComponentTag=H;exports.HostComponentTag=N;exports.HostHoistableTag=V;exports.HostRoot=$;exports.HostSingletonTag=U;exports.HostText=L;exports.Hydrating=q;exports.LegacyHiddenComponent=G;exports.MemoComponentTag=I;exports.MutationMask=ie;exports.OffscreenComponent=W;exports.OffscreenComponentTag=M;exports.PerformedWork=Y;exports.Placement=J;exports.Ref=ne;exports.SimpleMemoComponentTag=A;exports.Snapshot=oe;exports.SuspenseComponentTag=P;exports.Update=X;exports.Visibility=re;exports.createFiberVisitor=xe;exports.detectReactBuildType=ge;exports.didFiberCommit=w;exports.didFiberRender=C;exports.getDisplayName=Ce;exports.getFiberStack=pe;exports.getMutatedHostFibers=me;exports.getNearestHostFiber=de;exports.getRDTHook=h;exports.getTimings=be;exports.getType=y;exports.hasMemoCache=fe;exports.instrument=Fe;exports.isCompositeFiber=se;exports.isHostFiber=d;exports.isInstrumentationActive=he;exports.isUsingRDT=k;exports.isValidElement=le;exports.mountFiberRecursively=m;exports.shouldFilterFiber=g;exports.traverseContexts=ae;exports.traverseFiber=b;exports.traverseProps=ue;exports.traverseState=ce;exports.unmountFiber=S;exports.unmountFiberChildrenRecursively=T;exports.updateFiberRecursively=f;return exports;})({});
9
+ var P=1,M=0,z=9,I=13,A=22,N=11,V=14,U=15,j=5,L=26,B=27,G=18,W=6,$=7,K=23,Y=22,J=3,Q=60111,_="Symbol(react.concurrent_mode)",k="Symbol(react.async_mode)",q=1,X=2,Z=128,ee=4096,te=4,ne=8,oe=16,re=32,ie=512,se=1024,le=8192,ae=13366,ce=e=>typeof e=="object"&&e!=null&&"$$typeof"in e&&["Symbol(react.element)","Symbol(react.transitional.element)"].includes(String(e.$$typeof)),d=e=>e.tag===5||e.tag===26||e.tag===27,ue=e=>e.tag===0||e.tag===1||e.tag===15||e.tag===14||e.tag===11,me=(e,n)=>{try{let o=e.dependencies,t=e.alternate?.dependencies;if(!o||!t||typeof o!="object"||!("firstContext"in o)||typeof t!="object"||!("firstContext"in t))return !1;let s=o.firstContext,r=t.firstContext;for(;s&&typeof s=="object"&&"memoizedValue"in s&&r&&typeof r=="object"&&"memoizedValue"in r;){if(n(s,r)===!0)return !0;s=s.next,r=r.next;}}catch{}return !1},pe=(e,n)=>{try{let o=e.memoizedState,t=e.alternate?.memoizedState;for(;o&&t;){if(n(o,t)===!0)return !0;o=o.next,t=t.next;}}catch{}return !1},de=(e,n)=>{try{let o=e.memoizedProps,t=e.alternate?.memoizedProps||{},s=new Set([...Object.keys(t),...Object.keys(o)]);for(let r of s){let l=t?.[r],c=o?.[r];if(n(l,c)===!0)return !0}}catch{}return !1},C=e=>{let n=e.memoizedProps,o=e.alternate?.memoizedProps||{},t=e.flags??e.effectTag??0;switch(e.tag){case 1:case 0:case 9:case 11:case 14:case 15:return (t&1)===1;default:return e.alternate?o!==n||e.alternate.memoizedState!==e.memoizedState||e.alternate.ref!==e.ref:!0}},w=e=>!!(e.flags&22||e.subtreeFlags&22),be=e=>{let n=[],o=[e];for(;o.length;){let t=o.pop();t&&(d(t)&&w(t)&&C(t)&&n.push(t),t.child&&o.push(t.child),t.sibling&&o.push(t.sibling));}return n},fe=e=>{let n=[];for(;e.return;)n.push(e),e=e.return;let o=new Array(n.length);for(let t=0;t<n.length;t++)o[t]=n[n.length-t-1];return o},g=e=>{switch(e.tag){case 18:return !0;case 6:case 7:case 23:case 22:return !0;case 3:return !1;default:{let n=typeof e.type=="object"&&e.type!==null?e.type.$$typeof:e.type;switch(typeof n=="symbol"?n.toString():n){case 60111:case _:case k:return !0;default:return !1}}}},Ce=e=>{let n=b(e,d);return n||(n=b(e,d,!0)),n},b=(e,n,o=!1)=>{if(!e)return null;if(n(e)===!0)return e;let t=o?e.return:e.child;for(;t;){let s=b(t,n,o);if(s)return s;t=o?null:t.sibling;}return null},ge=e=>{let n=e?.actualDuration??0,o=n,t=e?.child??null;for(;n>0&&t!=null;)o-=t.actualDuration??0,t=t.sibling;return {selfTime:o,totalTime:n}},he=e=>!!e.updateQueue?.memoCache,F=e=>typeof e=="function"?e:typeof e=="object"&&e?F(e.type||e.render):null,xe=e=>{if(typeof e!="function"&&!(typeof e=="object"&&e))return null;let n=e.displayName||e.name||null;return n||(e=F(e),e&&(e.displayName||e.name)||null)},v=()=>globalThis.__REACT_DEVTOOLS_BACKEND_MANAGER_INJECTED__!=null,Fe=e=>{try{if(typeof e.version=="string"&&e.bundleType>0)return "development"}catch{}return "production"},O=e=>{try{Function.prototype.toString.call(e).indexOf("^_^")>-1&&setTimeout(()=>{throw new Error("React is running in production mode, but dead code elimination has not been applied. Read how to correctly configure React for production: https://reactjs.org/link/perf-use-production-build")});}catch{}},p=()=>{},y=e=>{let n=new Map,o=0,t={checkDCE:O,supportsFiber:!0,supportsFlight:!0,renderers:n,onCommitFiberRoot:p,onCommitFiberUnmount:p,onPostCommitFiberRoot:p,inject(s){let r=++o;return n.set(r,s),t._instrumentationIsActive||(t._instrumentationIsActive=!0,e?.()),r},_instrumentationSource:"bippy",_instrumentationIsActive:!1};try{Object.defineProperty(globalThis,"__REACT_DEVTOOLS_GLOBAL_HOOK__",{configurable:!0,value:t});}catch{}return t},T=e=>{let n=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;return n&&e?.(),window.hasOwnProperty("__REACT_DEVTOOLS_GLOBAL_HOOK__")||(n=y(e)),n},ye=()=>!!T()._instrumentationIsActive||v(),m=(e,n,o)=>{let t=n;for(;t!=null;){if(!g(t)&&C(t)&&e(t,"mount"),t.tag===13)if(t.memoizedState!==null){let l=t.child,c=l?l.sibling:null;if(c){let i=c.child;i!==null&&m(e,i,!1);}}else {let l=null;t.child!==null&&(l=t.child.child),l!==null&&m(e,l,!1);}else t.child!=null&&m(e,t.child,!0);t=o?t.sibling:null;}},f=(e,n,o,t)=>{if(!o)return;let s=n.tag===13,r=!g(n);r&&C(n)&&e(n,"update");let l=s&&o.memoizedState!==null,c=s&&n.memoizedState!==null;if(l&&c){let i=n.child?.sibling??null,a=o.child?.sibling??null;i!==null&&a!==null&&f(e,i,a);}else if(l&&!c){let i=n.child;i!==null&&m(e,i,!0);}else if(!l&&c){S(e,o);let i=n.child?.sibling??null;i!==null&&m(e,i,!0);}else if(n.child!==o.child){let i=n.child;for(;i;){if(i.alternate){let a=i.alternate;f(e,i,a);}else m(e,i,!1);i=i.sibling;}}},R=(e,n)=>{(n.tag===3||!g(n))&&e(n,"unmount");},S=(e,n)=>{let o=n.tag===13&&n.memoizedState!==null,t=n.child;for(o&&(t=(n.child?.sibling??null)?.child??null);t!==null;)t.return!==null&&(R(e,t),S(e,t)),t=t.sibling;},D=0,x=new WeakMap,Te=({onRender:e,onError:n})=>(o,t,s)=>{let r=t.current,l=(a,u)=>e(a,u,s),c=x.get(t);c||(c={prevFiber:null,id:D++},x.set(t,c));let{prevFiber:i}=c;try{if(i!==null){let a=i&&i.memoizedState!=null&&i.memoizedState.element!=null&&i.memoizedState.isDehydrated!==!0,u=r.memoizedState!=null&&r.memoizedState.element!=null&&r.memoizedState.isDehydrated!==!0;!a&&u?m(l,r,!1):a&&u?f(l,r,r.alternate,null):a&&!u&&R(l,r);}else m(l,r,!1);}catch(a){if(n)n(a);else throw a}c.prevFiber=r;},Re=({onCommitFiberRoot:e,onCommitFiberUnmount:n,onPostCommitFiberRoot:o,onActive:t,name:s})=>{let r=T(t);r._instrumentationSource=s??"bippy";let l=r.onCommitFiberRoot;e&&(r.onCommitFiberRoot=(a,u,h)=>{l&&l(a,u,h),e(a,u,h);});let c=r.onCommitFiberUnmount;n&&(r.onCommitFiberUnmount=(a,u)=>{c&&c(a,u),n(a,u);});let i=r.onPostCommitFiberRoot;return o&&(r.onPostCommitFiberRoot=(a,u)=>{i&&i(a,u);}),r},H=typeof document<"u"&&typeof document.createElement=="function",E=typeof process<"u"&&process.versions!=null&&process.versions.node!=null;(H||!E)&&y();
10
+ exports.CONCURRENT_MODE_NUMBER=Q;exports.CONCURRENT_MODE_SYMBOL_STRING=_;exports.ChildDeletion=oe;exports.ClassComponentTag=P;exports.Cloned=ne;exports.ContentReset=re;exports.ContextConsumerTag=z;exports.DEPRECATED_ASYNC_MODE_SYMBOL_STRING=k;exports.DehydratedSuspenseComponent=G;exports.DidCapture=Z;exports.ForwardRefTag=N;exports.Fragment=$;exports.FunctionComponentTag=M;exports.HostComponentTag=j;exports.HostHoistableTag=L;exports.HostRoot=J;exports.HostSingletonTag=B;exports.HostText=W;exports.Hydrating=ee;exports.LegacyHiddenComponent=K;exports.MemoComponentTag=V;exports.MutationMask=ae;exports.OffscreenComponent=Y;exports.OffscreenComponentTag=A;exports.PerformedWork=q;exports.Placement=X;exports.Ref=ie;exports.SimpleMemoComponentTag=U;exports.Snapshot=se;exports.SuspenseComponentTag=I;exports.Update=te;exports.Visibility=le;exports.createFiberVisitor=Te;exports.detectReactBuildType=Fe;exports.didFiberCommit=w;exports.didFiberRender=C;exports.getDisplayName=xe;exports.getFiberStack=fe;exports.getMutatedHostFibers=be;exports.getNearestHostFiber=Ce;exports.getRDTHook=T;exports.getTimings=ge;exports.getType=F;exports.hasMemoCache=he;exports.installRDTHook=y;exports.instrument=Re;exports.isCompositeFiber=ue;exports.isHostFiber=d;exports.isInstrumentationActive=ye;exports.isUsingRDT=v;exports.isValidElement=ce;exports.mountFiberRecursively=m;exports.shouldFilterFiber=g;exports.traverseContexts=me;exports.traverseFiber=b;exports.traverseProps=de;exports.traverseState=pe;exports.unmountFiber=R;exports.unmountFiberChildrenRecursively=S;exports.updateFiberRecursively=f;return exports;})({});
package/dist/index.js CHANGED
@@ -247,39 +247,43 @@ var checkDCE = (fn) => {
247
247
  };
248
248
  var NO_OP = () => {
249
249
  };
250
+ var installRDTHook = (onActive) => {
251
+ const renderers = /* @__PURE__ */ new Map();
252
+ let i = 0;
253
+ const rdtHook = {
254
+ checkDCE,
255
+ supportsFiber: true,
256
+ supportsFlight: true,
257
+ renderers,
258
+ onCommitFiberRoot: NO_OP,
259
+ onCommitFiberUnmount: NO_OP,
260
+ onPostCommitFiberRoot: NO_OP,
261
+ inject(renderer) {
262
+ const nextID = ++i;
263
+ renderers.set(nextID, renderer);
264
+ if (!rdtHook._instrumentationIsActive) {
265
+ rdtHook._instrumentationIsActive = true;
266
+ onActive?.();
267
+ }
268
+ return nextID;
269
+ },
270
+ _instrumentationSource: "bippy",
271
+ _instrumentationIsActive: false
272
+ };
273
+ try {
274
+ Object.defineProperty(globalThis, "__REACT_DEVTOOLS_GLOBAL_HOOK__", {
275
+ configurable: true,
276
+ value: rdtHook
277
+ });
278
+ } catch {
279
+ }
280
+ return rdtHook;
281
+ };
250
282
  var getRDTHook = (onActive) => {
251
283
  let rdtHook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
252
284
  if (rdtHook) onActive?.();
253
285
  if (!window.hasOwnProperty("__REACT_DEVTOOLS_GLOBAL_HOOK__")) {
254
- const renderers = /* @__PURE__ */ new Map();
255
- let i = 0;
256
- rdtHook ??= {
257
- checkDCE,
258
- supportsFiber: true,
259
- supportsFlight: true,
260
- renderers,
261
- onCommitFiberRoot: NO_OP,
262
- onCommitFiberUnmount: NO_OP,
263
- onPostCommitFiberRoot: NO_OP,
264
- inject(renderer) {
265
- const nextID = ++i;
266
- renderers.set(nextID, renderer);
267
- if (!rdtHook._instrumentationIsActive) {
268
- rdtHook._instrumentationIsActive = true;
269
- onActive?.();
270
- }
271
- return nextID;
272
- },
273
- _instrumentationSource: "bippy",
274
- _instrumentationIsActive: Boolean(rdtHook)
275
- };
276
- try {
277
- Object.defineProperty(globalThis, "__REACT_DEVTOOLS_GLOBAL_HOOK__", {
278
- configurable: true,
279
- value: rdtHook
280
- });
281
- } catch {
282
- }
286
+ rdtHook = installRDTHook(onActive);
283
287
  }
284
288
  return rdtHook;
285
289
  };
@@ -287,10 +291,6 @@ var isInstrumentationActive = () => {
287
291
  const rdtHook = getRDTHook();
288
292
  return Boolean(rdtHook._instrumentationIsActive) || isUsingRDT();
289
293
  };
290
- if (typeof window !== "undefined") {
291
- performance.now();
292
- getRDTHook();
293
- }
294
294
  var mountFiberRecursively = (onRender, firstChild, traverseSiblings) => {
295
295
  let fiber = firstChild;
296
296
  while (fiber != null) {
@@ -471,5 +471,10 @@ var instrument = ({
471
471
  }
472
472
  return devtoolsHook;
473
473
  };
474
+ var isBrowser = typeof document !== "undefined" && typeof document.createElement === "function";
475
+ var isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
476
+ if (isBrowser || !isNode) {
477
+ installRDTHook();
478
+ }
474
479
 
475
- export { CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_STRING, ChildDeletion, ClassComponentTag, Cloned, ContentReset, ContextConsumerTag, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponent, DidCapture, ForwardRefTag, Fragment, FunctionComponentTag, HostComponentTag, HostHoistableTag, HostRoot, HostSingletonTag, HostText, Hydrating, LegacyHiddenComponent, MemoComponentTag, MutationMask, OffscreenComponent, OffscreenComponentTag, PerformedWork, Placement, Ref, SimpleMemoComponentTag, Snapshot, SuspenseComponentTag, Update, Visibility, createFiberVisitor, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberStack, getMutatedHostFibers, getNearestHostFiber, getRDTHook, getTimings, getType, hasMemoCache, instrument, isCompositeFiber, isHostFiber, isInstrumentationActive, isUsingRDT, isValidElement, mountFiberRecursively, shouldFilterFiber, traverseContexts, traverseFiber, traverseProps, traverseState, unmountFiber, unmountFiberChildrenRecursively, updateFiberRecursively };
480
+ export { CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_STRING, ChildDeletion, ClassComponentTag, Cloned, ContentReset, ContextConsumerTag, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponent, DidCapture, ForwardRefTag, Fragment, FunctionComponentTag, HostComponentTag, HostHoistableTag, HostRoot, HostSingletonTag, HostText, Hydrating, LegacyHiddenComponent, MemoComponentTag, MutationMask, OffscreenComponent, OffscreenComponentTag, PerformedWork, Placement, Ref, SimpleMemoComponentTag, Snapshot, SuspenseComponentTag, Update, Visibility, createFiberVisitor, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberStack, getMutatedHostFibers, getNearestHostFiber, getRDTHook, getTimings, getType, hasMemoCache, installRDTHook, instrument, isCompositeFiber, isHostFiber, isInstrumentationActive, isUsingRDT, isValidElement, mountFiberRecursively, shouldFilterFiber, traverseContexts, traverseFiber, traverseProps, traverseState, unmountFiber, unmountFiberChildrenRecursively, updateFiberRecursively };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bippy",
3
- "version": "0.0.23",
3
+ "version": "0.0.24",
4
4
  "description": "a hacky way to get fibers from react",
5
5
  "keywords": [
6
6
  "react",