bippy 0.5.32 → 0.5.34
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 +58 -69
- package/dist/core.cjs +1 -1
- package/dist/core.d.cts +6 -5
- package/dist/core.d.ts +6 -5
- package/dist/core.js +1 -1
- package/dist/core2.d.cts +1 -1
- package/dist/core2.d.ts +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.iife.js +1 -1
- package/dist/install-hook-only.d.cts +1 -1
- package/dist/install-hook-only.iife.js +1 -1
- package/dist/rdt-hook.cjs +1 -1
- package/dist/rdt-hook.js +1 -1
- package/dist/source.cjs +12 -12
- package/dist/source.d.cts +4 -2
- package/dist/source.d.ts +4 -2
- package/dist/source.js +13 -13
- package/package.json +34 -37
- package/src/core.ts +91 -194
- package/src/index.ts +2 -2
- package/src/install-hook-only.ts +1 -1
- package/src/rdt-hook.ts +19 -27
- package/src/source/constants.ts +13 -14
- package/src/source/get-display-name-from-source.ts +10 -20
- package/src/source/get-source.ts +26 -31
- package/src/source/index.ts +6 -6
- package/src/source/owner-stack.ts +83 -127
- package/src/source/parse-stack.ts +46 -92
- package/src/source/symbolication.ts +19 -54
- package/src/types.ts +18 -43
package/src/core.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// [!!!] IMPORTANT: do not import React in this file
|
|
2
2
|
// since it will be executed before the react devtools hook is created
|
|
3
3
|
|
|
4
|
-
import type * as React from
|
|
4
|
+
import type * as React from "react";
|
|
5
5
|
|
|
6
6
|
import type {
|
|
7
7
|
ContextDependency,
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
MemoizedState,
|
|
11
11
|
ReactDevToolsGlobalHook,
|
|
12
12
|
ReactRenderer,
|
|
13
|
-
} from
|
|
13
|
+
} from "./types.js";
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
16
|
BIPPY_INSTRUMENTATION_STRING,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
hasRDTHook,
|
|
19
19
|
isReactRefresh,
|
|
20
20
|
isRealReactDevtools,
|
|
21
|
-
} from
|
|
21
|
+
} from "./rdt-hook.js";
|
|
22
22
|
|
|
23
23
|
// https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactWorkTags.js
|
|
24
24
|
export const FunctionComponentTag = 0;
|
|
@@ -43,11 +43,10 @@ export const ActivityComponentTag = 28;
|
|
|
43
43
|
export const ViewTransitionComponentTag = 30;
|
|
44
44
|
|
|
45
45
|
export const CONCURRENT_MODE_NUMBER = 0xeacf;
|
|
46
|
-
export const ELEMENT_TYPE_SYMBOL_STRING =
|
|
47
|
-
export const TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING =
|
|
48
|
-
|
|
49
|
-
export const
|
|
50
|
-
export const DEPRECATED_ASYNC_MODE_SYMBOL_STRING = 'Symbol(react.async_mode)';
|
|
46
|
+
export const ELEMENT_TYPE_SYMBOL_STRING = "Symbol(react.element)";
|
|
47
|
+
export const TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING = "Symbol(react.transitional.element)";
|
|
48
|
+
export const CONCURRENT_MODE_SYMBOL_STRING = "Symbol(react.concurrent_mode)";
|
|
49
|
+
export const DEPRECATED_ASYNC_MODE_SYMBOL_STRING = "Symbol(react.async_mode)";
|
|
51
50
|
|
|
52
51
|
// https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberFlags.js
|
|
53
52
|
const PerformedWork = 0b1;
|
|
@@ -60,43 +59,34 @@ const ContentReset = 0b100000;
|
|
|
60
59
|
const Snapshot = 0b10000000000;
|
|
61
60
|
const Visibility = 0b10000000000000;
|
|
62
61
|
const MutationMask =
|
|
63
|
-
Placement |
|
|
64
|
-
Update |
|
|
65
|
-
ChildDeletion |
|
|
66
|
-
ContentReset |
|
|
67
|
-
Hydrating |
|
|
68
|
-
Visibility |
|
|
69
|
-
Snapshot;
|
|
62
|
+
Placement | Update | ChildDeletion | ContentReset | Hydrating | Visibility | Snapshot;
|
|
70
63
|
|
|
71
64
|
/**
|
|
72
65
|
* Returns `true` if object is a React Element.
|
|
73
66
|
*
|
|
74
67
|
* @see https://react.dev/reference/react/isValidElement
|
|
75
68
|
*/
|
|
76
|
-
export const isValidElement = (
|
|
77
|
-
element
|
|
78
|
-
): element is React.ReactElement =>
|
|
79
|
-
typeof element === 'object' &&
|
|
69
|
+
export const isValidElement = (element: unknown): element is React.ReactElement =>
|
|
70
|
+
typeof element === "object" &&
|
|
80
71
|
element != null &&
|
|
81
|
-
|
|
72
|
+
"$$typeof" in element &&
|
|
82
73
|
// react 18 uses Symbol.for('react.element'), react 19 uses Symbol.for('react.transitional.element')
|
|
83
|
-
[
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
].includes(String(element.$$typeof));
|
|
74
|
+
[ELEMENT_TYPE_SYMBOL_STRING, TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING].includes(
|
|
75
|
+
String(element.$$typeof),
|
|
76
|
+
);
|
|
87
77
|
|
|
88
78
|
/**
|
|
89
79
|
* Returns `true` if object is a React Fiber.
|
|
90
80
|
*/
|
|
91
81
|
export const isValidFiber = (fiber: unknown): fiber is Fiber =>
|
|
92
|
-
typeof fiber ===
|
|
82
|
+
typeof fiber === "object" &&
|
|
93
83
|
fiber != null &&
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
84
|
+
"tag" in fiber &&
|
|
85
|
+
"stateNode" in fiber &&
|
|
86
|
+
"return" in fiber &&
|
|
87
|
+
"child" in fiber &&
|
|
88
|
+
"sibling" in fiber &&
|
|
89
|
+
"flags" in fiber;
|
|
100
90
|
|
|
101
91
|
/**
|
|
102
92
|
* Returns `true` if fiber is a host fiber. Host fibers are DOM nodes in react-dom, `View` in react-native, etc.
|
|
@@ -112,7 +102,7 @@ export const isHostFiber = (fiber: Fiber): boolean => {
|
|
|
112
102
|
case HostSingletonTag:
|
|
113
103
|
return true;
|
|
114
104
|
default:
|
|
115
|
-
return typeof fiber.type ===
|
|
105
|
+
return typeof fiber.type === "string";
|
|
116
106
|
}
|
|
117
107
|
};
|
|
118
108
|
|
|
@@ -138,21 +128,17 @@ export const isCompositeFiber = (fiber: Fiber): boolean => {
|
|
|
138
128
|
* Returns `true` if the object is a {@link Fiber}
|
|
139
129
|
*/
|
|
140
130
|
export const isFiber = (maybeFiber: unknown): maybeFiber is Fiber => {
|
|
141
|
-
if (!maybeFiber || typeof maybeFiber !==
|
|
131
|
+
if (!maybeFiber || typeof maybeFiber !== "object") return false;
|
|
142
132
|
// this is a fast check. pendingProps will ALWAYS exist in fiber
|
|
143
133
|
// `containerInfo` is in FiberRootNode, not FiberNode
|
|
144
|
-
return
|
|
134
|
+
return "pendingProps" in maybeFiber && !("containerInfo" in maybeFiber);
|
|
145
135
|
};
|
|
146
136
|
|
|
147
137
|
/**
|
|
148
138
|
* Returns `true` if the two {@link Fiber}s are the same reference
|
|
149
139
|
*/
|
|
150
140
|
export const areFiberEqual = (fiberA: Fiber, fiberB: Fiber): boolean => {
|
|
151
|
-
return
|
|
152
|
-
fiberA === fiberB ||
|
|
153
|
-
fiberA.alternate === fiberB ||
|
|
154
|
-
fiberB.alternate === fiberA
|
|
155
|
-
);
|
|
141
|
+
return fiberA === fiberB || fiberA.alternate === fiberB || fiberB.alternate === fiberA;
|
|
156
142
|
};
|
|
157
143
|
|
|
158
144
|
/**
|
|
@@ -171,24 +157,18 @@ export const traverseContexts = (
|
|
|
171
157
|
|
|
172
158
|
if (!nextDependencies || !prevDependencies) return false;
|
|
173
159
|
if (
|
|
174
|
-
typeof nextDependencies !==
|
|
175
|
-
!(
|
|
176
|
-
typeof prevDependencies !==
|
|
177
|
-
!(
|
|
160
|
+
typeof nextDependencies !== "object" ||
|
|
161
|
+
!("firstContext" in nextDependencies) ||
|
|
162
|
+
typeof prevDependencies !== "object" ||
|
|
163
|
+
!("firstContext" in prevDependencies)
|
|
178
164
|
) {
|
|
179
165
|
return false;
|
|
180
166
|
}
|
|
181
|
-
let nextContext: ContextDependency<unknown> | null | undefined =
|
|
182
|
-
|
|
183
|
-
let prevContext: ContextDependency<unknown> | null | undefined =
|
|
184
|
-
prevDependencies.firstContext;
|
|
167
|
+
let nextContext: ContextDependency<unknown> | null | undefined = nextDependencies.firstContext;
|
|
168
|
+
let prevContext: ContextDependency<unknown> | null | undefined = prevDependencies.firstContext;
|
|
185
169
|
while (
|
|
186
|
-
(nextContext &&
|
|
187
|
-
|
|
188
|
-
'memoizedValue' in nextContext) ||
|
|
189
|
-
(prevContext &&
|
|
190
|
-
typeof prevContext === 'object' &&
|
|
191
|
-
'memoizedValue' in prevContext)
|
|
170
|
+
(nextContext && typeof nextContext === "object" && "memoizedValue" in nextContext) ||
|
|
171
|
+
(prevContext && typeof prevContext === "object" && "memoizedValue" in prevContext)
|
|
192
172
|
) {
|
|
193
173
|
if (selector(nextContext, prevContext) === true) return true;
|
|
194
174
|
|
|
@@ -211,8 +191,7 @@ export const traverseState = (
|
|
|
211
191
|
): boolean => {
|
|
212
192
|
try {
|
|
213
193
|
let nextState: MemoizedState | null | undefined = fiber.memoizedState;
|
|
214
|
-
let prevState: MemoizedState | null | undefined =
|
|
215
|
-
fiber.alternate?.memoizedState;
|
|
194
|
+
let prevState: MemoizedState | null | undefined = fiber.alternate?.memoizedState;
|
|
216
195
|
|
|
217
196
|
while (nextState || prevState) {
|
|
218
197
|
if (selector(nextState, prevState) === true) return true;
|
|
@@ -229,20 +208,13 @@ export const traverseState = (
|
|
|
229
208
|
*/
|
|
230
209
|
export const traverseProps = (
|
|
231
210
|
fiber: Fiber,
|
|
232
|
-
selector: (
|
|
233
|
-
propName: string,
|
|
234
|
-
nextValue: unknown,
|
|
235
|
-
prevValue: unknown,
|
|
236
|
-
) => boolean | void,
|
|
211
|
+
selector: (propName: string, nextValue: unknown, prevValue: unknown) => boolean | void,
|
|
237
212
|
): boolean => {
|
|
238
213
|
try {
|
|
239
214
|
const nextProps = fiber.memoizedProps;
|
|
240
215
|
const prevProps = fiber.alternate?.memoizedProps || {};
|
|
241
216
|
|
|
242
|
-
const allKeys = new Set([
|
|
243
|
-
...Object.keys(nextProps),
|
|
244
|
-
...Object.keys(prevProps),
|
|
245
|
-
]);
|
|
217
|
+
const allKeys = new Set([...Object.keys(nextProps), ...Object.keys(prevProps)]);
|
|
246
218
|
|
|
247
219
|
for (const propName of allKeys) {
|
|
248
220
|
const prevValue = prevProps?.[propName];
|
|
@@ -260,8 +232,7 @@ export const traverseProps = (
|
|
|
260
232
|
export const didFiberRender = (fiber: Fiber): boolean => {
|
|
261
233
|
const nextProps = fiber.memoizedProps;
|
|
262
234
|
const prevProps = fiber.alternate?.memoizedProps || {};
|
|
263
|
-
const flags =
|
|
264
|
-
fiber.flags ?? (fiber as unknown as { effectTag: number }).effectTag ?? 0;
|
|
235
|
+
const flags = fiber.flags ?? (fiber as unknown as { effectTag: number }).effectTag ?? 0;
|
|
265
236
|
|
|
266
237
|
switch (fiber.tag) {
|
|
267
238
|
case ClassComponentTag:
|
|
@@ -289,7 +260,7 @@ export const didFiberRender = (fiber: Fiber): boolean => {
|
|
|
289
260
|
export const didFiberCommit = (fiber: Fiber): boolean => {
|
|
290
261
|
return Boolean(
|
|
291
262
|
(fiber.flags & (MutationMask | Cloned)) !== 0 ||
|
|
292
|
-
|
|
263
|
+
(fiber.subtreeFlags & (MutationMask | Cloned)) !== 0,
|
|
293
264
|
);
|
|
294
265
|
};
|
|
295
266
|
|
|
@@ -358,14 +329,10 @@ export const shouldFilterFiber = (fiber: Fiber): boolean => {
|
|
|
358
329
|
|
|
359
330
|
default: {
|
|
360
331
|
const symbolOrNumber =
|
|
361
|
-
typeof fiber.type ===
|
|
362
|
-
? fiber.type.$$typeof
|
|
363
|
-
: fiber.type;
|
|
332
|
+
typeof fiber.type === "object" && fiber.type !== null ? fiber.type.$$typeof : fiber.type;
|
|
364
333
|
|
|
365
334
|
const typeSymbol =
|
|
366
|
-
typeof symbolOrNumber ===
|
|
367
|
-
? symbolOrNumber.toString()
|
|
368
|
-
: symbolOrNumber;
|
|
335
|
+
typeof symbolOrNumber === "symbol" ? symbolOrNumber.toString() : symbolOrNumber;
|
|
369
336
|
|
|
370
337
|
switch (typeSymbol) {
|
|
371
338
|
case CONCURRENT_MODE_NUMBER:
|
|
@@ -383,10 +350,7 @@ export const shouldFilterFiber = (fiber: Fiber): boolean => {
|
|
|
383
350
|
/**
|
|
384
351
|
* Returns the nearest host {@link Fiber} to the current {@link Fiber}.
|
|
385
352
|
*/
|
|
386
|
-
export const getNearestHostFiber = (
|
|
387
|
-
fiber: Fiber,
|
|
388
|
-
ascending = false,
|
|
389
|
-
): Fiber | null => {
|
|
353
|
+
export const getNearestHostFiber = (fiber: Fiber, ascending = false): Fiber | null => {
|
|
390
354
|
let hostFiber = traverseFiber(fiber, isHostFiber, ascending);
|
|
391
355
|
if (!hostFiber) {
|
|
392
356
|
hostFiber = traverseFiber(fiber, isHostFiber, !ascending);
|
|
@@ -467,11 +431,7 @@ export function traverseFiber(
|
|
|
467
431
|
|
|
468
432
|
let child = ascending ? fiber.return : fiber.child;
|
|
469
433
|
while (child) {
|
|
470
|
-
const match = traverseFiberSync(
|
|
471
|
-
child,
|
|
472
|
-
selector as (node: Fiber) => boolean | void,
|
|
473
|
-
ascending,
|
|
474
|
-
);
|
|
434
|
+
const match = traverseFiberSync(child, selector as (node: Fiber) => boolean | void, ascending);
|
|
475
435
|
if (match) return match;
|
|
476
436
|
child = ascending ? null : child.sibling;
|
|
477
437
|
}
|
|
@@ -523,9 +483,7 @@ export const traverseFiberAsync = async (
|
|
|
523
483
|
* console.log(selfTime, totalTime);
|
|
524
484
|
* ```
|
|
525
485
|
*/
|
|
526
|
-
export const getTimings = (
|
|
527
|
-
fiber?: Fiber | null,
|
|
528
|
-
): { selfTime: number; totalTime: number } => {
|
|
486
|
+
export const getTimings = (fiber?: Fiber | null): { selfTime: number; totalTime: number } => {
|
|
529
487
|
const totalTime = fiber?.actualDuration ?? 0;
|
|
530
488
|
let selfTime = totalTime;
|
|
531
489
|
// TODO: calculate a DOM time, which is just host component summed up
|
|
@@ -541,9 +499,7 @@ export const getTimings = (
|
|
|
541
499
|
* Returns `true` if the {@link Fiber} uses React Compiler's memo cache.
|
|
542
500
|
*/
|
|
543
501
|
export const hasMemoCache = (fiber: Fiber): boolean => {
|
|
544
|
-
return Boolean(
|
|
545
|
-
(fiber.updateQueue as unknown as { memoCache: unknown })?.memoCache,
|
|
546
|
-
);
|
|
502
|
+
return Boolean((fiber.updateQueue as unknown as { memoCache: unknown })?.memoCache);
|
|
547
503
|
};
|
|
548
504
|
|
|
549
505
|
type FiberType =
|
|
@@ -556,14 +512,13 @@ type FiberType =
|
|
|
556
512
|
*/
|
|
557
513
|
export const getType = (type: unknown): null | React.ComponentType<unknown> => {
|
|
558
514
|
const currentType = type as FiberType;
|
|
559
|
-
if (typeof currentType ===
|
|
515
|
+
if (typeof currentType === "function") {
|
|
560
516
|
return currentType;
|
|
561
517
|
}
|
|
562
|
-
if (typeof currentType ===
|
|
518
|
+
if (typeof currentType === "object" && currentType) {
|
|
563
519
|
// memo / forwardRef case
|
|
564
520
|
return getType(
|
|
565
|
-
(currentType as React.MemoExoticComponent<React.ComponentType<unknown>>)
|
|
566
|
-
.type ||
|
|
521
|
+
(currentType as React.MemoExoticComponent<React.ComponentType<unknown>>).type ||
|
|
567
522
|
(currentType as { render: React.ComponentType<unknown> }).render,
|
|
568
523
|
);
|
|
569
524
|
}
|
|
@@ -575,13 +530,10 @@ export const getType = (type: unknown): null | React.ComponentType<unknown> => {
|
|
|
575
530
|
*/
|
|
576
531
|
export const getDisplayName = (type: unknown): null | string => {
|
|
577
532
|
const currentType = type as FiberType;
|
|
578
|
-
if (typeof currentType ===
|
|
533
|
+
if (typeof currentType === "string") {
|
|
579
534
|
return currentType;
|
|
580
535
|
}
|
|
581
|
-
if (
|
|
582
|
-
typeof currentType !== 'function' &&
|
|
583
|
-
!(typeof currentType === 'object' && currentType)
|
|
584
|
-
) {
|
|
536
|
+
if (typeof currentType !== "function" && !(typeof currentType === "object" && currentType)) {
|
|
585
537
|
return null;
|
|
586
538
|
}
|
|
587
539
|
const name = currentType.displayName || currentType.name || null;
|
|
@@ -594,15 +546,13 @@ export const getDisplayName = (type: unknown): null | string => {
|
|
|
594
546
|
/**
|
|
595
547
|
* Returns the build type of the React renderer.
|
|
596
548
|
*/
|
|
597
|
-
export const detectReactBuildType = (
|
|
598
|
-
renderer: ReactRenderer,
|
|
599
|
-
): 'development' | 'production' => {
|
|
549
|
+
export const detectReactBuildType = (renderer: ReactRenderer): "development" | "production" => {
|
|
600
550
|
try {
|
|
601
|
-
if (typeof renderer.version ===
|
|
602
|
-
return
|
|
551
|
+
if (typeof renderer.version === "string" && renderer.bundleType > 0) {
|
|
552
|
+
return "development";
|
|
603
553
|
}
|
|
604
554
|
} catch {}
|
|
605
|
-
return
|
|
555
|
+
return "production";
|
|
606
556
|
};
|
|
607
557
|
|
|
608
558
|
/**
|
|
@@ -624,9 +574,7 @@ export const getLatestFiber = (fiber: Fiber): Fiber => {
|
|
|
624
574
|
const alternate = fiber.alternate;
|
|
625
575
|
if (!alternate) return fiber;
|
|
626
576
|
if (alternate.actualStartTime && fiber.actualStartTime) {
|
|
627
|
-
return alternate.actualStartTime > fiber.actualStartTime
|
|
628
|
-
? alternate
|
|
629
|
-
: fiber;
|
|
577
|
+
return alternate.actualStartTime > fiber.actualStartTime ? alternate : fiber;
|
|
630
578
|
}
|
|
631
579
|
for (const root of _fiberRoots) {
|
|
632
580
|
const latestFiber = traverseFiber(root.current, (innerFiber) => {
|
|
@@ -637,13 +585,9 @@ export const getLatestFiber = (fiber: Fiber): Fiber => {
|
|
|
637
585
|
return fiber;
|
|
638
586
|
};
|
|
639
587
|
|
|
640
|
-
export type RenderHandler = <S>(
|
|
641
|
-
fiber: Fiber,
|
|
642
|
-
phase: RenderPhase,
|
|
643
|
-
state?: S,
|
|
644
|
-
) => unknown;
|
|
588
|
+
export type RenderHandler = <S>(fiber: Fiber, phase: RenderPhase, state?: S) => unknown;
|
|
645
589
|
|
|
646
|
-
export type RenderPhase =
|
|
590
|
+
export type RenderPhase = "mount" | "unmount" | "update";
|
|
647
591
|
|
|
648
592
|
let fiberId = 0;
|
|
649
593
|
export const fiberIdMap = new WeakMap<Fiber, number>();
|
|
@@ -680,7 +624,7 @@ export const mountFiberRecursively = (
|
|
|
680
624
|
}
|
|
681
625
|
const shouldIncludeInTree = !shouldFilterFiber(fiber);
|
|
682
626
|
if (shouldIncludeInTree && didFiberRender(fiber)) {
|
|
683
|
-
onRender(fiber,
|
|
627
|
+
onRender(fiber, "mount");
|
|
684
628
|
}
|
|
685
629
|
|
|
686
630
|
if (fiber.tag === SuspenseComponentTag) {
|
|
@@ -690,9 +634,7 @@ export const mountFiberRecursively = (
|
|
|
690
634
|
// get the fallback child from the inner fragment and mount
|
|
691
635
|
// it as if it was our own child. Updates handle this too.
|
|
692
636
|
const primaryChildFragment = fiber.child;
|
|
693
|
-
const fallbackChildFragment = primaryChildFragment
|
|
694
|
-
? primaryChildFragment.sibling
|
|
695
|
-
: null;
|
|
637
|
+
const fallbackChildFragment = primaryChildFragment ? primaryChildFragment.sibling : null;
|
|
696
638
|
if (fallbackChildFragment) {
|
|
697
639
|
const fallbackChild = fallbackChildFragment.child;
|
|
698
640
|
if (fallbackChild !== null) {
|
|
@@ -701,8 +643,7 @@ export const mountFiberRecursively = (
|
|
|
701
643
|
}
|
|
702
644
|
} else {
|
|
703
645
|
let primaryChild: Fiber | null = null;
|
|
704
|
-
const areSuspenseChildrenConditionallyWrapped =
|
|
705
|
-
(OffscreenComponentTag as number) === -1;
|
|
646
|
+
const areSuspenseChildrenConditionallyWrapped = (OffscreenComponentTag as number) === -1;
|
|
706
647
|
if (areSuspenseChildrenConditionallyWrapped) {
|
|
707
648
|
primaryChild = fiber.child;
|
|
708
649
|
} else if (fiber.child !== null) {
|
|
@@ -737,7 +678,7 @@ export const updateFiberRecursively = (
|
|
|
737
678
|
|
|
738
679
|
const shouldIncludeInTree = !shouldFilterFiber(nextFiber);
|
|
739
680
|
if (shouldIncludeInTree && didFiberRender(nextFiber)) {
|
|
740
|
-
onRender(nextFiber,
|
|
681
|
+
onRender(nextFiber, "update");
|
|
741
682
|
}
|
|
742
683
|
|
|
743
684
|
// The behavior of timed-out Suspense trees is unique.
|
|
@@ -762,12 +703,7 @@ export const updateFiberRecursively = (
|
|
|
762
703
|
const prevFallbackChildSet = prevFiber.child?.sibling ?? null;
|
|
763
704
|
|
|
764
705
|
if (nextFallbackChildSet !== null && prevFallbackChildSet !== null) {
|
|
765
|
-
updateFiberRecursively(
|
|
766
|
-
onRender,
|
|
767
|
-
nextFallbackChildSet,
|
|
768
|
-
prevFallbackChildSet,
|
|
769
|
-
nextFiber,
|
|
770
|
-
);
|
|
706
|
+
updateFiberRecursively(onRender, nextFallbackChildSet, prevFallbackChildSet, nextFiber);
|
|
771
707
|
}
|
|
772
708
|
} else if (prevDidTimeout && !nextDidTimeOut) {
|
|
773
709
|
// Fallback -> Primary:
|
|
@@ -828,17 +764,13 @@ export const unmountFiber = (onRender: RenderHandler, fiber: Fiber): void => {
|
|
|
828
764
|
const isRoot = fiber.tag === HostRootTag;
|
|
829
765
|
|
|
830
766
|
if (isRoot || !shouldFilterFiber(fiber)) {
|
|
831
|
-
onRender(fiber,
|
|
767
|
+
onRender(fiber, "unmount");
|
|
832
768
|
}
|
|
833
769
|
};
|
|
834
770
|
|
|
835
|
-
export const unmountFiberChildrenRecursively = (
|
|
836
|
-
onRender: RenderHandler,
|
|
837
|
-
fiber: Fiber,
|
|
838
|
-
): void => {
|
|
771
|
+
export const unmountFiberChildrenRecursively = (onRender: RenderHandler, fiber: Fiber): void => {
|
|
839
772
|
// We might meet a nested Suspense on our way.
|
|
840
|
-
const isTimedOutSuspense =
|
|
841
|
-
fiber.tag === SuspenseComponentTag && fiber.memoizedState !== null;
|
|
773
|
+
const isTimedOutSuspense = fiber.tag === SuspenseComponentTag && fiber.memoizedState !== null;
|
|
842
774
|
let child = fiber.child;
|
|
843
775
|
|
|
844
776
|
if (isTimedOutSuspense) {
|
|
@@ -878,11 +810,8 @@ const rootInstanceMap = new WeakMap<
|
|
|
878
810
|
* console.log(phase)
|
|
879
811
|
* })
|
|
880
812
|
*/
|
|
881
|
-
export const traverseRenderedFibers = (
|
|
882
|
-
root:
|
|
883
|
-
onRender: RenderHandler,
|
|
884
|
-
): void => {
|
|
885
|
-
const fiber = 'current' in root ? root.current : root;
|
|
813
|
+
export const traverseRenderedFibers = (root: FiberRoot, onRender: RenderHandler): void => {
|
|
814
|
+
const fiber = "current" in root ? root.current : root;
|
|
886
815
|
|
|
887
816
|
let rootInstance = rootInstanceMap.get(root);
|
|
888
817
|
|
|
@@ -922,9 +851,9 @@ export const traverseRenderedFibers = (
|
|
|
922
851
|
rootInstance.prevFiber = fiber;
|
|
923
852
|
};
|
|
924
853
|
|
|
925
|
-
let _overrideProps: null | ReactRenderer[
|
|
926
|
-
let _overrideHookState: null | ReactRenderer[
|
|
927
|
-
let _overrideContext: null | ReactRenderer[
|
|
854
|
+
let _overrideProps: null | ReactRenderer["overrideProps"] = null;
|
|
855
|
+
let _overrideHookState: null | ReactRenderer["overrideHookState"] = null;
|
|
856
|
+
let _overrideContext: null | ReactRenderer["overrideContext"] = null;
|
|
928
857
|
|
|
929
858
|
export const injectOverrideMethods = () => {
|
|
930
859
|
if (!hasRDTHook()) return null;
|
|
@@ -943,12 +872,7 @@ export const injectOverrideMethods = () => {
|
|
|
943
872
|
try {
|
|
944
873
|
if (_overrideHookState) {
|
|
945
874
|
const prevOverrideHookState = _overrideHookState;
|
|
946
|
-
_overrideHookState = (
|
|
947
|
-
fiber: Fiber,
|
|
948
|
-
id: string,
|
|
949
|
-
path: string[],
|
|
950
|
-
value: unknown,
|
|
951
|
-
) => {
|
|
875
|
+
_overrideHookState = (fiber: Fiber, id: string, path: string[], value: unknown) => {
|
|
952
876
|
let current = fiber.memoizedState;
|
|
953
877
|
for (let i = 0; i < Number(id); i++) {
|
|
954
878
|
if (!current?.next) break;
|
|
@@ -957,7 +881,7 @@ export const injectOverrideMethods = () => {
|
|
|
957
881
|
|
|
958
882
|
if (current?.queue) {
|
|
959
883
|
const queue = current.queue;
|
|
960
|
-
if (isPOJO(queue) &&
|
|
884
|
+
if (isPOJO(queue) && "dispatch" in queue) {
|
|
961
885
|
const dispatch = queue.dispatch as (value: unknown) => void;
|
|
962
886
|
dispatch(value);
|
|
963
887
|
return;
|
|
@@ -973,11 +897,7 @@ export const injectOverrideMethods = () => {
|
|
|
973
897
|
|
|
974
898
|
if (_overrideProps) {
|
|
975
899
|
const prevOverrideProps = _overrideProps;
|
|
976
|
-
_overrideProps = (
|
|
977
|
-
fiber: Fiber,
|
|
978
|
-
path: Array<string>,
|
|
979
|
-
value: unknown,
|
|
980
|
-
) => {
|
|
900
|
+
_overrideProps = (fiber: Fiber, path: Array<string>, value: unknown) => {
|
|
981
901
|
prevOverrideProps(fiber, path, value);
|
|
982
902
|
renderer.overrideProps?.(fiber, path, value);
|
|
983
903
|
};
|
|
@@ -985,20 +905,15 @@ export const injectOverrideMethods = () => {
|
|
|
985
905
|
_overrideProps = renderer.overrideProps;
|
|
986
906
|
}
|
|
987
907
|
|
|
988
|
-
_overrideContext = (
|
|
989
|
-
fiber: Fiber,
|
|
990
|
-
contextType: unknown,
|
|
991
|
-
path: string[],
|
|
992
|
-
value: unknown,
|
|
993
|
-
) => {
|
|
908
|
+
_overrideContext = (fiber: Fiber, contextType: unknown, path: string[], value: unknown) => {
|
|
994
909
|
let current: Fiber | null = fiber;
|
|
995
910
|
while (current) {
|
|
996
911
|
const type = current.type as { Provider?: unknown };
|
|
997
912
|
if (type === contextType || type?.Provider === contextType) {
|
|
998
913
|
if (_overrideProps) {
|
|
999
|
-
_overrideProps(current, [
|
|
914
|
+
_overrideProps(current, ["value", ...path], value);
|
|
1000
915
|
if (current.alternate) {
|
|
1001
|
-
_overrideProps(current.alternate, [
|
|
916
|
+
_overrideProps(current.alternate, ["value", ...path], value);
|
|
1002
917
|
}
|
|
1003
918
|
}
|
|
1004
919
|
break;
|
|
@@ -1014,7 +929,7 @@ export const injectOverrideMethods = () => {
|
|
|
1014
929
|
|
|
1015
930
|
const isPOJO = (maybePOJO: unknown): maybePOJO is Record<string, unknown> => {
|
|
1016
931
|
return (
|
|
1017
|
-
Object.prototype.toString.call(maybePOJO) ===
|
|
932
|
+
Object.prototype.toString.call(maybePOJO) === "[object Object]" &&
|
|
1018
933
|
(Object.getPrototypeOf(maybePOJO) === Object.prototype ||
|
|
1019
934
|
Object.getPrototypeOf(maybePOJO) === null)
|
|
1020
935
|
);
|
|
@@ -1044,10 +959,7 @@ const buildPathsFromValue = (
|
|
|
1044
959
|
return paths;
|
|
1045
960
|
};
|
|
1046
961
|
|
|
1047
|
-
export const overrideProps = (
|
|
1048
|
-
fiber: Fiber,
|
|
1049
|
-
partialValue: Record<string, unknown>,
|
|
1050
|
-
) => {
|
|
962
|
+
export const overrideProps = (fiber: Fiber, partialValue: Record<string, unknown>) => {
|
|
1051
963
|
injectOverrideMethods();
|
|
1052
964
|
|
|
1053
965
|
const paths = buildPathsFromValue(partialValue);
|
|
@@ -1108,18 +1020,10 @@ export const overrideContext = (
|
|
|
1108
1020
|
export interface InstrumentationOptions {
|
|
1109
1021
|
name?: string;
|
|
1110
1022
|
onActive?: () => unknown;
|
|
1111
|
-
onCommitFiberRoot?: (
|
|
1112
|
-
rendererID: number,
|
|
1113
|
-
root: FiberRoot,
|
|
1114
|
-
priority: number | void,
|
|
1115
|
-
) => unknown;
|
|
1023
|
+
onCommitFiberRoot?: (rendererID: number, root: FiberRoot, priority: number | void) => unknown;
|
|
1116
1024
|
onCommitFiberUnmount?: (rendererID: number, fiber: Fiber) => unknown;
|
|
1117
1025
|
onPostCommitFiberRoot?: (rendererID: number, root: FiberRoot) => unknown;
|
|
1118
|
-
onScheduleFiberRoot?: (
|
|
1119
|
-
rendererID: number,
|
|
1120
|
-
root: FiberRoot,
|
|
1121
|
-
children: React.ReactNode,
|
|
1122
|
-
) => unknown;
|
|
1026
|
+
onScheduleFiberRoot?: (rendererID: number, root: FiberRoot, children: React.ReactNode) => unknown;
|
|
1123
1027
|
}
|
|
1124
1028
|
|
|
1125
1029
|
/**
|
|
@@ -1134,9 +1038,7 @@ export interface InstrumentationOptions {
|
|
|
1134
1038
|
* },
|
|
1135
1039
|
* });
|
|
1136
1040
|
*/
|
|
1137
|
-
export const instrument = (
|
|
1138
|
-
options: InstrumentationOptions,
|
|
1139
|
-
): ReactDevToolsGlobalHook => {
|
|
1041
|
+
export const instrument = (options: InstrumentationOptions): ReactDevToolsGlobalHook => {
|
|
1140
1042
|
const rdtHook = getRDTHook(options.onActive);
|
|
1141
1043
|
|
|
1142
1044
|
rdtHook._instrumentationSource = options.name ?? BIPPY_INSTRUMENTATION_STRING;
|
|
@@ -1192,18 +1094,17 @@ export const getFiberFromHostInstance = <T>(hostInstance: T): Fiber | null => {
|
|
|
1192
1094
|
}
|
|
1193
1095
|
}
|
|
1194
1096
|
|
|
1195
|
-
if (typeof hostInstance ===
|
|
1196
|
-
if (
|
|
1097
|
+
if (typeof hostInstance === "object" && hostInstance != null) {
|
|
1098
|
+
if ("_reactRootContainer" in hostInstance) {
|
|
1197
1099
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1198
|
-
return (hostInstance._reactRootContainer as any)?._internalRoot?.current
|
|
1199
|
-
?.child;
|
|
1100
|
+
return (hostInstance._reactRootContainer as any)?._internalRoot?.current?.child;
|
|
1200
1101
|
}
|
|
1201
1102
|
|
|
1202
1103
|
for (const key in hostInstance) {
|
|
1203
1104
|
if (
|
|
1204
|
-
key.startsWith(
|
|
1205
|
-
key.startsWith(
|
|
1206
|
-
key.startsWith(
|
|
1105
|
+
key.startsWith("__reactContainer$") ||
|
|
1106
|
+
key.startsWith("__reactInternalInstance$") ||
|
|
1107
|
+
key.startsWith("__reactFiber")
|
|
1207
1108
|
) {
|
|
1208
1109
|
return (hostInstance[key] || null) as Fiber | null;
|
|
1209
1110
|
}
|
|
@@ -1240,12 +1141,12 @@ export const secure = (
|
|
|
1240
1141
|
const rdtHook = getRDTHook();
|
|
1241
1142
|
|
|
1242
1143
|
for (const renderer of rdtHook.renderers.values()) {
|
|
1243
|
-
const [majorVersion] = renderer.version.split(
|
|
1144
|
+
const [majorVersion] = renderer.version.split(".");
|
|
1244
1145
|
if (Number(majorVersion) < (secureOptions.minReactMajorVersion ?? 17)) {
|
|
1245
1146
|
isSecure = false;
|
|
1246
1147
|
}
|
|
1247
1148
|
const buildType = detectReactBuildType(renderer);
|
|
1248
|
-
if (buildType ===
|
|
1149
|
+
if (buildType === "development") {
|
|
1249
1150
|
isDevelopment = true;
|
|
1250
1151
|
} else if (!secureOptions.dangerouslyRunInProduction) {
|
|
1251
1152
|
isSecure = false;
|
|
@@ -1305,11 +1206,7 @@ export const secure = (
|
|
|
1305
1206
|
}
|
|
1306
1207
|
};
|
|
1307
1208
|
|
|
1308
|
-
if (
|
|
1309
|
-
!isRDTHookInstalled &&
|
|
1310
|
-
!isUsingRealReactDevtools &&
|
|
1311
|
-
!isUsingReactRefresh
|
|
1312
|
-
) {
|
|
1209
|
+
if (!isRDTHookInstalled && !isUsingRealReactDevtools && !isUsingReactRefresh) {
|
|
1313
1210
|
timeout = setTimeout(() => {
|
|
1314
1211
|
if (isDevelopment) {
|
|
1315
1212
|
secureOptions.onError?.(INSTALL_ERROR);
|
|
@@ -1321,5 +1218,5 @@ export const secure = (
|
|
|
1321
1218
|
return options;
|
|
1322
1219
|
};
|
|
1323
1220
|
|
|
1324
|
-
export * from
|
|
1325
|
-
export type * from
|
|
1221
|
+
export * from "./rdt-hook.js";
|
|
1222
|
+
export type * from "./types.js";
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "./install-hook-only.js";
|
|
2
2
|
|
|
3
|
-
export * from
|
|
3
|
+
export * from "./core.js";
|
package/src/install-hook-only.ts
CHANGED