bippy 0.6.1-dev.3a24abf → 0.6.1-dev.b88fcb4
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/LICENSE +1 -1
- package/README.md +7 -1
- package/dist/core.cjs +1 -1
- package/dist/core.d.cts +39 -41
- package/dist/core.d.ts +39 -41
- package/dist/core.js +1 -1
- package/dist/core2.cjs +1 -1
- package/dist/core2.d.cts +11 -3
- package/dist/core2.d.ts +11 -3
- package/dist/core2.js +1 -1
- package/dist/{types.d.cts → errors.d.cts} +205 -31
- package/dist/{types.d.ts → errors.d.ts} +205 -31
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.iife.js +1 -1
- package/dist/index.js +1 -1
- package/dist/install-hook-only.cjs +1 -1
- package/dist/install-hook-only.d.cts +8 -0
- package/dist/install-hook-only.d.ts +8 -0
- package/dist/install-hook-only.iife.js +1 -1
- package/dist/install-hook-only.js +1 -1
- package/dist/rdt-hook.cjs +1 -1
- package/dist/rdt-hook.js +1 -1
- package/dist/source.cjs +13 -13
- package/dist/source.d.cts +27 -9
- package/dist/source.d.ts +27 -9
- package/dist/source.js +13 -13
- package/package.json +10 -6
- package/src/core.ts +269 -224
- package/src/errors.ts +99 -0
- package/src/rdt-hook.ts +154 -99
- package/src/react-internals/generated/react-work-tags.ts +314 -0
- package/src/react-internals/index.ts +67 -0
- package/src/react-internals/semver.ts +78 -0
- package/src/{types.ts → react-internals/types.ts} +13 -3
- package/src/source/error-stack.ts +11 -0
- package/src/source/get-display-name-from-source.ts +1 -1
- package/src/source/get-source.ts +2 -2
- package/src/source/index.ts +9 -1
- package/src/source/inspect-hooks.ts +199 -165
- package/src/source/owner-stack.ts +26 -39
- package/src/source/parse-debug-stack.ts +4 -4
- package/src/source/parse-hook-names.ts +1 -1
- package/src/source/symbolication.ts +468 -101
- package/src/generated/react-work-tags.ts +0 -169
- package/src/react-internals.ts +0 -67
- package/src/unsubscribe.ts +0 -17
package/src/core.ts
CHANGED
|
@@ -10,78 +10,44 @@ import type {
|
|
|
10
10
|
MemoizedState,
|
|
11
11
|
ReactDevToolsGlobalHook,
|
|
12
12
|
ReactRenderer,
|
|
13
|
-
} from "./
|
|
13
|
+
} from "./react-internals/index.js";
|
|
14
|
+
|
|
15
|
+
import { BippyInstrumentationError, BippyReactDevToolsError, runWithBippyError } from "./errors.js";
|
|
14
16
|
|
|
15
17
|
import {
|
|
16
18
|
_onActiveListeners,
|
|
17
19
|
BIPPY_INSTRUMENTATION_STRING,
|
|
20
|
+
createUnsubscribe,
|
|
18
21
|
getRDTHook,
|
|
19
22
|
hasRDTHook,
|
|
20
23
|
isRealReactDevtools,
|
|
24
|
+
onRDTHookReplace,
|
|
21
25
|
onRendererInject,
|
|
22
26
|
} from "./rdt-hook.js";
|
|
27
|
+
import type { Unsubscribe } from "./rdt-hook.js";
|
|
23
28
|
import {
|
|
24
|
-
|
|
25
|
-
CONCURRENT_MODE_NUMBER,
|
|
26
|
-
CONCURRENT_MODE_SYMBOL_DESCRIPTION,
|
|
27
|
-
CONCURRENT_MODE_SYMBOL_STRING,
|
|
28
|
-
ContextConsumerTag,
|
|
29
|
-
DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION,
|
|
30
|
-
DEPRECATED_ASYNC_MODE_SYMBOL_STRING,
|
|
31
|
-
DehydratedSuspenseComponentTag,
|
|
32
|
-
ELEMENT_TYPE_SYMBOL_STRING,
|
|
33
|
-
ForwardRefTag,
|
|
34
|
-
FragmentTag,
|
|
35
|
-
FunctionComponentTag,
|
|
36
|
-
HostComponentTag,
|
|
37
|
-
HostHoistableTag,
|
|
38
|
-
HostRootTag,
|
|
39
|
-
HostSingletonTag,
|
|
40
|
-
HostTextTag,
|
|
41
|
-
LegacyHiddenComponentTag,
|
|
42
|
-
MemoComponentTag,
|
|
29
|
+
getReactWorkTagsForFiber,
|
|
43
30
|
MutationMask,
|
|
44
|
-
OffscreenComponentTag,
|
|
45
31
|
ReactBuildType,
|
|
46
32
|
ReactFiberFlags,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
} from "./react-internals.js";
|
|
51
|
-
import { toUnsubscribe, type Unsubscribe } from "./unsubscribe.js";
|
|
33
|
+
ReactSymbols,
|
|
34
|
+
setReactWorkTagsForFiber,
|
|
35
|
+
} from "./react-internals/index.js";
|
|
52
36
|
|
|
37
|
+
export { getReactWorkTags, ReactSymbols } from "./react-internals/index.js";
|
|
38
|
+
export type { ReactWorkTagMap, ReactWorkTagVersion } from "./react-internals/index.js";
|
|
53
39
|
export {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
FragmentTag,
|
|
66
|
-
FunctionComponentTag,
|
|
67
|
-
HostComponentTag,
|
|
68
|
-
HostHoistableTag,
|
|
69
|
-
HostPortalTag,
|
|
70
|
-
HostRootTag,
|
|
71
|
-
HostSingletonTag,
|
|
72
|
-
HostTextTag,
|
|
73
|
-
LazyComponentTag,
|
|
74
|
-
LegacyHiddenComponentTag,
|
|
75
|
-
MemoComponentTag,
|
|
76
|
-
OffscreenComponentTag,
|
|
77
|
-
SimpleMemoComponentTag,
|
|
78
|
-
SuspenseComponentTag,
|
|
79
|
-
SuspenseListComponentTag,
|
|
80
|
-
TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING,
|
|
81
|
-
ViewTransitionComponentTag,
|
|
82
|
-
} from "./react-internals.js";
|
|
83
|
-
|
|
84
|
-
const { Cloned, PerformedWork } = ReactFiberFlags;
|
|
40
|
+
BippyError,
|
|
41
|
+
BippyHookInstallationError,
|
|
42
|
+
BippyHookInspectionError,
|
|
43
|
+
BippyHookListenerError,
|
|
44
|
+
BippyHookRenderError,
|
|
45
|
+
BippyInstrumentationError,
|
|
46
|
+
BippyReactBuildError,
|
|
47
|
+
BippyReactDevToolsError,
|
|
48
|
+
BippySourceMapError,
|
|
49
|
+
BippyUnsupportedHookError,
|
|
50
|
+
} from "./errors.js";
|
|
85
51
|
|
|
86
52
|
const isObjectRecord = (value: unknown): value is Record<string, unknown> =>
|
|
87
53
|
typeof value === "object" && value !== null;
|
|
@@ -113,6 +79,20 @@ interface FiberSelector {
|
|
|
113
79
|
(node: Fiber): boolean | Promise<boolean | void> | void;
|
|
114
80
|
}
|
|
115
81
|
|
|
82
|
+
export interface FiberTimings {
|
|
83
|
+
selfTime: number;
|
|
84
|
+
totalTime: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface RenderHandler {
|
|
88
|
+
<State>(fiber: Fiber, phase: RenderPhase, state?: State): unknown;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface ValueWrite {
|
|
92
|
+
path: string[];
|
|
93
|
+
value: unknown;
|
|
94
|
+
}
|
|
95
|
+
|
|
116
96
|
/**
|
|
117
97
|
* Returns `true` if object is a React Element.
|
|
118
98
|
*
|
|
@@ -122,9 +102,8 @@ export const isValidElement = (element: unknown): element is React.ReactElement
|
|
|
122
102
|
typeof element === "object" &&
|
|
123
103
|
element !== null &&
|
|
124
104
|
"$$typeof" in element &&
|
|
125
|
-
|
|
126
|
-
String(element.$$typeof)
|
|
127
|
-
);
|
|
105
|
+
(String(element.$$typeof) === ReactSymbols.LEGACY_ELEMENT_SYMBOL_STRING ||
|
|
106
|
+
String(element.$$typeof) === ReactSymbols.ELEMENT_SYMBOL_STRING);
|
|
128
107
|
|
|
129
108
|
/**
|
|
130
109
|
* Returns `true` if object is a React Fiber.
|
|
@@ -139,17 +118,21 @@ export const isValidFiber = (fiber: unknown): fiber is Fiber =>
|
|
|
139
118
|
"sibling" in fiber &&
|
|
140
119
|
"flags" in fiber;
|
|
141
120
|
|
|
121
|
+
const isFiberRoot = (fiberRoot: unknown): fiberRoot is FiberRoot =>
|
|
122
|
+
isObjectRecord(fiberRoot) && isValidFiber(fiberRoot.current);
|
|
123
|
+
|
|
142
124
|
/**
|
|
143
125
|
* Returns `true` if fiber is a host fiber. Host fibers are DOM nodes in react-dom, `View` in react-native, etc.
|
|
144
126
|
*
|
|
145
127
|
* @see https://reactnative.dev/architecture/glossary#host-view-tree-and-host-view
|
|
146
128
|
*/
|
|
147
129
|
export const isHostFiber = (fiber: Fiber): fiber is HostFiber => {
|
|
130
|
+
const workTags = getReactWorkTagsForFiber(fiber);
|
|
148
131
|
switch (fiber.tag) {
|
|
149
|
-
case
|
|
150
|
-
case
|
|
151
|
-
case
|
|
152
|
-
case
|
|
132
|
+
case workTags.HostComponent:
|
|
133
|
+
case workTags.HostText:
|
|
134
|
+
case workTags.HostHoistable:
|
|
135
|
+
case workTags.HostSingleton:
|
|
153
136
|
return true;
|
|
154
137
|
default:
|
|
155
138
|
return false;
|
|
@@ -162,12 +145,13 @@ export const isHostFiber = (fiber: Fiber): fiber is HostFiber => {
|
|
|
162
145
|
* @see https://reactnative.dev/architecture/glossary#react-composite-components
|
|
163
146
|
*/
|
|
164
147
|
export const isCompositeFiber = (fiber: Fiber): boolean => {
|
|
148
|
+
const workTags = getReactWorkTagsForFiber(fiber);
|
|
165
149
|
switch (fiber.tag) {
|
|
166
|
-
case
|
|
167
|
-
case
|
|
168
|
-
case
|
|
169
|
-
case
|
|
170
|
-
case
|
|
150
|
+
case workTags.ClassComponent:
|
|
151
|
+
case workTags.ForwardRef:
|
|
152
|
+
case workTags.FunctionComponent:
|
|
153
|
+
case workTags.MemoComponent:
|
|
154
|
+
case workTags.SimpleMemoComponent:
|
|
171
155
|
return true;
|
|
172
156
|
default:
|
|
173
157
|
return false;
|
|
@@ -275,15 +259,16 @@ export const didFiberRender = (fiber: Fiber): boolean => {
|
|
|
275
259
|
const nextProps = fiber.memoizedProps;
|
|
276
260
|
const prevProps = fiber.alternate?.memoizedProps || {};
|
|
277
261
|
const flags = fiber.flags ?? fiber.effectTag ?? 0;
|
|
262
|
+
const workTags = getReactWorkTagsForFiber(fiber);
|
|
278
263
|
|
|
279
264
|
switch (fiber.tag) {
|
|
280
|
-
case
|
|
281
|
-
case
|
|
282
|
-
case
|
|
283
|
-
case
|
|
284
|
-
case
|
|
285
|
-
case
|
|
286
|
-
return (flags & PerformedWork) === PerformedWork;
|
|
265
|
+
case workTags.ClassComponent:
|
|
266
|
+
case workTags.ContextConsumer:
|
|
267
|
+
case workTags.ForwardRef:
|
|
268
|
+
case workTags.FunctionComponent:
|
|
269
|
+
case workTags.MemoComponent:
|
|
270
|
+
case workTags.SimpleMemoComponent: {
|
|
271
|
+
return (flags & ReactFiberFlags.PerformedWork) === ReactFiberFlags.PerformedWork;
|
|
287
272
|
}
|
|
288
273
|
default:
|
|
289
274
|
// Host nodes (DOM, root, etc.)
|
|
@@ -301,8 +286,8 @@ export const didFiberRender = (fiber: Fiber): boolean => {
|
|
|
301
286
|
*/
|
|
302
287
|
export const didFiberCommit = (fiber: Fiber): boolean => {
|
|
303
288
|
return Boolean(
|
|
304
|
-
(fiber.flags & (MutationMask | Cloned)) !== 0 ||
|
|
305
|
-
(fiber.subtreeFlags & (MutationMask | Cloned)) !== 0,
|
|
289
|
+
(fiber.flags & (MutationMask | ReactFiberFlags.Cloned)) !== 0 ||
|
|
290
|
+
(fiber.subtreeFlags & (MutationMask | ReactFiberFlags.Cloned)) !== 0,
|
|
306
291
|
);
|
|
307
292
|
};
|
|
308
293
|
|
|
@@ -351,8 +336,9 @@ export const getFiberStack = (fiber: Fiber): Fiber[] => {
|
|
|
351
336
|
* Returns `true` if the {@link Fiber} should be filtered out during reconciliation.
|
|
352
337
|
*/
|
|
353
338
|
const shouldFilterFiber = (fiber: Fiber): boolean => {
|
|
339
|
+
const workTags = getReactWorkTagsForFiber(fiber);
|
|
354
340
|
switch (fiber.tag) {
|
|
355
|
-
case
|
|
341
|
+
case workTags.DehydratedSuspenseComponent:
|
|
356
342
|
// TODO: ideally we would show dehydrated Suspense immediately.
|
|
357
343
|
// However, it has some special behavior (like disconnecting
|
|
358
344
|
// an alternate and turning into real Suspense) which breaks DevTools.
|
|
@@ -360,13 +346,13 @@ const shouldFilterFiber = (fiber: Fiber): boolean => {
|
|
|
360
346
|
// https://github.com/bvaughn/react-devtools-experimental/issues/197
|
|
361
347
|
return true;
|
|
362
348
|
|
|
363
|
-
case
|
|
364
|
-
case
|
|
365
|
-
case
|
|
366
|
-
case
|
|
349
|
+
case workTags.Fragment:
|
|
350
|
+
case workTags.HostText:
|
|
351
|
+
case workTags.LegacyHiddenComponent:
|
|
352
|
+
case workTags.OffscreenComponent:
|
|
367
353
|
return true;
|
|
368
354
|
|
|
369
|
-
case
|
|
355
|
+
case workTags.HostRoot:
|
|
370
356
|
// It is never valid to filter the root element.
|
|
371
357
|
return false;
|
|
372
358
|
|
|
@@ -376,15 +362,15 @@ const shouldFilterFiber = (fiber: Fiber): boolean => {
|
|
|
376
362
|
|
|
377
363
|
if (typeof symbolOrNumber === "symbol") {
|
|
378
364
|
return (
|
|
379
|
-
symbolOrNumber.description === CONCURRENT_MODE_SYMBOL_DESCRIPTION ||
|
|
380
|
-
symbolOrNumber.description === DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION
|
|
365
|
+
symbolOrNumber.description === ReactSymbols.CONCURRENT_MODE_SYMBOL_DESCRIPTION ||
|
|
366
|
+
symbolOrNumber.description === ReactSymbols.DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION
|
|
381
367
|
);
|
|
382
368
|
}
|
|
383
369
|
|
|
384
370
|
switch (symbolOrNumber) {
|
|
385
|
-
case CONCURRENT_MODE_NUMBER:
|
|
386
|
-
case CONCURRENT_MODE_SYMBOL_STRING:
|
|
387
|
-
case DEPRECATED_ASYNC_MODE_SYMBOL_STRING:
|
|
371
|
+
case ReactSymbols.CONCURRENT_MODE_NUMBER:
|
|
372
|
+
case ReactSymbols.CONCURRENT_MODE_SYMBOL_STRING:
|
|
373
|
+
case ReactSymbols.DEPRECATED_ASYNC_MODE_SYMBOL_STRING:
|
|
388
374
|
return true;
|
|
389
375
|
|
|
390
376
|
default:
|
|
@@ -448,75 +434,67 @@ export function traverseFiber(
|
|
|
448
434
|
selector: (node: Fiber) => Promise<boolean | void>,
|
|
449
435
|
ascending?: boolean,
|
|
450
436
|
): Promise<Fiber | null>;
|
|
437
|
+
export function traverseFiber(
|
|
438
|
+
fiber: Fiber | null,
|
|
439
|
+
selector: FiberSelector,
|
|
440
|
+
ascending?: boolean,
|
|
441
|
+
): Fiber | null | Promise<Fiber | null>;
|
|
451
442
|
export function traverseFiber(
|
|
452
443
|
fiber: Fiber | null,
|
|
453
444
|
selector: FiberSelector,
|
|
454
445
|
ascending = false,
|
|
455
446
|
): Fiber | null | Promise<Fiber | null> {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
const firstResult = selector(fiber);
|
|
459
|
-
if (firstResult instanceof Promise) {
|
|
460
|
-
return (async () => {
|
|
461
|
-
if ((await firstResult) === true) return fiber;
|
|
462
|
-
|
|
463
|
-
let child = ascending ? fiber.return : fiber.child;
|
|
464
|
-
while (child) {
|
|
465
|
-
const match = await traverseFiberAsync(child, selector, ascending);
|
|
466
|
-
if (match) return match;
|
|
467
|
-
child = ascending ? null : child.sibling;
|
|
468
|
-
}
|
|
469
|
-
return null;
|
|
470
|
-
})();
|
|
471
|
-
}
|
|
447
|
+
return traverseFiberInternal(fiber, selector, ascending);
|
|
448
|
+
}
|
|
472
449
|
|
|
473
|
-
|
|
450
|
+
const isPromiseLike = <Result>(value: unknown): value is PromiseLike<Result> =>
|
|
451
|
+
(typeof value === "object" || typeof value === "function") &&
|
|
452
|
+
value !== null &&
|
|
453
|
+
"then" in value &&
|
|
454
|
+
typeof value.then === "function";
|
|
474
455
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
return
|
|
482
|
-
}
|
|
456
|
+
const traverseFiberChildren = (
|
|
457
|
+
fiber: Fiber,
|
|
458
|
+
selector: FiberSelector,
|
|
459
|
+
ascending: boolean,
|
|
460
|
+
): Fiber | null | Promise<Fiber | null> => {
|
|
461
|
+
const firstChild = ascending ? fiber.return : fiber.child;
|
|
462
|
+
return traverseFiberSiblings(firstChild, selector, ascending);
|
|
463
|
+
};
|
|
483
464
|
|
|
484
|
-
const
|
|
465
|
+
const traverseFiberSiblings = (
|
|
485
466
|
fiber: Fiber | null,
|
|
486
467
|
selector: FiberSelector,
|
|
487
|
-
ascending
|
|
488
|
-
): Fiber | null => {
|
|
468
|
+
ascending: boolean,
|
|
469
|
+
): Fiber | null | Promise<Fiber | null> => {
|
|
489
470
|
if (!fiber) return null;
|
|
490
|
-
const selection = selector(fiber);
|
|
491
|
-
if (selection instanceof Promise) return null;
|
|
492
|
-
if (selection === true) return fiber;
|
|
493
|
-
|
|
494
|
-
let child = ascending ? fiber.return : fiber.child;
|
|
495
|
-
while (child) {
|
|
496
|
-
const match = traverseFiberSync(child, selector, ascending);
|
|
497
|
-
if (match) return match;
|
|
498
471
|
|
|
499
|
-
|
|
472
|
+
const nextSibling = ascending ? null : fiber.sibling;
|
|
473
|
+
const match = traverseFiberInternal(fiber, selector, ascending);
|
|
474
|
+
if (isPromiseLike<Fiber | null>(match)) {
|
|
475
|
+
return Promise.resolve(match).then(
|
|
476
|
+
(resolvedMatch) => resolvedMatch ?? traverseFiberSiblings(nextSibling, selector, ascending),
|
|
477
|
+
);
|
|
500
478
|
}
|
|
501
|
-
return
|
|
479
|
+
return match ?? traverseFiberSiblings(nextSibling, selector, ascending);
|
|
502
480
|
};
|
|
503
481
|
|
|
504
|
-
const
|
|
482
|
+
const traverseFiberInternal = (
|
|
505
483
|
fiber: Fiber | null,
|
|
506
484
|
selector: FiberSelector,
|
|
507
|
-
ascending
|
|
508
|
-
): Promise<Fiber | null> => {
|
|
485
|
+
ascending: boolean,
|
|
486
|
+
): Fiber | null | Promise<Fiber | null> => {
|
|
509
487
|
if (!fiber) return null;
|
|
510
|
-
if ((await selector(fiber)) === true) return fiber;
|
|
511
|
-
|
|
512
|
-
let child = ascending ? fiber.return : fiber.child;
|
|
513
|
-
while (child) {
|
|
514
|
-
const match = await traverseFiberAsync(child, selector, ascending);
|
|
515
|
-
if (match) return match;
|
|
516
488
|
|
|
517
|
-
|
|
489
|
+
const selection = selector(fiber);
|
|
490
|
+
if (isPromiseLike<boolean | void>(selection)) {
|
|
491
|
+
return Promise.resolve(selection).then((didSelectFiber) =>
|
|
492
|
+
didSelectFiber === true ? fiber : traverseFiberChildren(fiber, selector, ascending),
|
|
493
|
+
);
|
|
518
494
|
}
|
|
519
|
-
return
|
|
495
|
+
if (selection === true) return fiber;
|
|
496
|
+
|
|
497
|
+
return traverseFiberChildren(fiber, selector, ascending);
|
|
520
498
|
};
|
|
521
499
|
|
|
522
500
|
/**
|
|
@@ -528,7 +506,7 @@ const traverseFiberAsync = async (
|
|
|
528
506
|
* console.log(selfTime, totalTime);
|
|
529
507
|
* ```
|
|
530
508
|
*/
|
|
531
|
-
export const getTimings = (fiber?: Fiber | null):
|
|
509
|
+
export const getTimings = (fiber?: Fiber | null): FiberTimings => {
|
|
532
510
|
const totalTime = fiber?.actualDuration ?? 0;
|
|
533
511
|
let selfTime = totalTime;
|
|
534
512
|
// TODO: calculate a DOM time, which is just host component summed up
|
|
@@ -605,35 +583,35 @@ export const getLatestFiber = (fiber: Fiber): Fiber => {
|
|
|
605
583
|
}
|
|
606
584
|
for (const root of _fiberRoots) {
|
|
607
585
|
const latestFiber = traverseFiber(root.current, (innerFiber) => {
|
|
608
|
-
if (innerFiber === fiber) return true;
|
|
586
|
+
if (innerFiber === fiber || innerFiber === alternate) return true;
|
|
609
587
|
});
|
|
610
588
|
if (latestFiber) return latestFiber;
|
|
611
589
|
}
|
|
612
590
|
return fiber;
|
|
613
591
|
};
|
|
614
592
|
|
|
615
|
-
export type RenderHandler = <S>(fiber: Fiber, phase: RenderPhase, state?: S) => unknown;
|
|
616
|
-
|
|
617
593
|
export type RenderPhase = "mount" | "unmount" | "update";
|
|
618
594
|
|
|
619
|
-
let
|
|
595
|
+
let nextFiberId = 0;
|
|
620
596
|
const fiberIdMap = new WeakMap<Fiber, number>();
|
|
621
597
|
|
|
622
|
-
export const setFiberId = (fiber: Fiber,
|
|
623
|
-
fiberIdMap.set(fiber,
|
|
598
|
+
export const setFiberId = (fiber: Fiber, fiberId: number = nextFiberId++): void => {
|
|
599
|
+
fiberIdMap.set(fiber, fiberId);
|
|
600
|
+
if (Number.isSafeInteger(fiberId) && fiberId >= nextFiberId) {
|
|
601
|
+
nextFiberId = fiberId + 1;
|
|
602
|
+
}
|
|
624
603
|
};
|
|
625
604
|
|
|
626
|
-
// Fiber alternates share an identity across double-buffered commits.
|
|
627
605
|
export const getFiberId = (fiber: Fiber): number => {
|
|
628
|
-
let
|
|
629
|
-
if (
|
|
630
|
-
|
|
606
|
+
let currentFiberId = fiberIdMap.get(fiber);
|
|
607
|
+
if (currentFiberId === undefined && fiber.alternate) {
|
|
608
|
+
currentFiberId = fiberIdMap.get(fiber.alternate);
|
|
631
609
|
}
|
|
632
|
-
if (
|
|
633
|
-
|
|
634
|
-
setFiberId(fiber,
|
|
610
|
+
if (currentFiberId === undefined) {
|
|
611
|
+
currentFiberId = nextFiberId++;
|
|
612
|
+
setFiberId(fiber, currentFiberId);
|
|
635
613
|
}
|
|
636
|
-
return
|
|
614
|
+
return currentFiberId;
|
|
637
615
|
};
|
|
638
616
|
|
|
639
617
|
const mountFiberRecursively = (
|
|
@@ -652,7 +630,7 @@ const mountFiberRecursively = (
|
|
|
652
630
|
onRender(fiber, "mount");
|
|
653
631
|
}
|
|
654
632
|
|
|
655
|
-
if (fiber.tag ===
|
|
633
|
+
if (fiber.tag === getReactWorkTagsForFiber(fiber).SuspenseComponent) {
|
|
656
634
|
const isTimedOut = fiber.memoizedState !== null;
|
|
657
635
|
if (isTimedOut) {
|
|
658
636
|
// Special case: if Suspense mounts in a timed-out state,
|
|
@@ -682,7 +660,7 @@ const mountFiberRecursively = (
|
|
|
682
660
|
const updateFiberRecursively = (
|
|
683
661
|
onRender: RenderHandler,
|
|
684
662
|
nextFiber: Fiber,
|
|
685
|
-
prevFiber: Fiber,
|
|
663
|
+
prevFiber: Fiber | null,
|
|
686
664
|
parentFiber: Fiber | null,
|
|
687
665
|
): void => {
|
|
688
666
|
if (!fiberIdMap.has(nextFiber)) {
|
|
@@ -693,7 +671,7 @@ const updateFiberRecursively = (
|
|
|
693
671
|
getFiberId(prevFiber);
|
|
694
672
|
}
|
|
695
673
|
|
|
696
|
-
const isSuspense = nextFiber.tag ===
|
|
674
|
+
const isSuspense = nextFiber.tag === getReactWorkTagsForFiber(nextFiber).SuspenseComponent;
|
|
697
675
|
|
|
698
676
|
const shouldIncludeInTree = !shouldFilterFiber(nextFiber);
|
|
699
677
|
if (shouldIncludeInTree && didFiberRender(nextFiber)) {
|
|
@@ -780,7 +758,7 @@ const updateFiberRecursively = (
|
|
|
780
758
|
};
|
|
781
759
|
|
|
782
760
|
const unmountFiber = (onRender: RenderHandler, fiber: Fiber): void => {
|
|
783
|
-
const isRoot = fiber.tag ===
|
|
761
|
+
const isRoot = fiber.tag === getReactWorkTagsForFiber(fiber).HostRoot;
|
|
784
762
|
|
|
785
763
|
if (isRoot || !shouldFilterFiber(fiber)) {
|
|
786
764
|
onRender(fiber, "unmount");
|
|
@@ -789,7 +767,8 @@ const unmountFiber = (onRender: RenderHandler, fiber: Fiber): void => {
|
|
|
789
767
|
|
|
790
768
|
const unmountFiberChildrenRecursively = (onRender: RenderHandler, fiber: Fiber): void => {
|
|
791
769
|
// We might meet a nested Suspense on our way.
|
|
792
|
-
const isTimedOutSuspense =
|
|
770
|
+
const isTimedOutSuspense =
|
|
771
|
+
fiber.tag === getReactWorkTagsForFiber(fiber).SuspenseComponent && fiber.memoizedState !== null;
|
|
793
772
|
let child = fiber.child;
|
|
794
773
|
|
|
795
774
|
if (isTimedOutSuspense) {
|
|
@@ -815,7 +794,7 @@ const unmountFiberChildrenRecursively = (onRender: RenderHandler, fiber: Fiber):
|
|
|
815
794
|
|
|
816
795
|
let commitId = 0;
|
|
817
796
|
const rootInstanceMap = new WeakMap<
|
|
818
|
-
FiberRoot,
|
|
797
|
+
Fiber | FiberRoot,
|
|
819
798
|
{
|
|
820
799
|
id: number;
|
|
821
800
|
prevFiber: Fiber | null;
|
|
@@ -829,7 +808,7 @@ const rootInstanceMap = new WeakMap<
|
|
|
829
808
|
* console.log(phase)
|
|
830
809
|
* })
|
|
831
810
|
*/
|
|
832
|
-
export const traverseRenderedFibers = (root: FiberRoot, onRender: RenderHandler): void => {
|
|
811
|
+
export const traverseRenderedFibers = (root: Fiber | FiberRoot, onRender: RenderHandler): void => {
|
|
833
812
|
const fiber = "current" in root ? root.current : root;
|
|
834
813
|
|
|
835
814
|
let rootInstance = rootInstanceMap.get(root);
|
|
@@ -878,9 +857,8 @@ let areOverrideRenderersWired = false;
|
|
|
878
857
|
const wireOverrideRenderers = (): void => {
|
|
879
858
|
if (!hasRDTHook()) return;
|
|
880
859
|
const rdtHook = getRDTHook();
|
|
881
|
-
if (!rdtHook?.renderers) return;
|
|
882
860
|
|
|
883
|
-
|
|
861
|
+
setHookEventDispatchers(rdtHook);
|
|
884
862
|
for (const renderer of rdtHook.renderers.values()) {
|
|
885
863
|
overrideRenderers.add(renderer);
|
|
886
864
|
}
|
|
@@ -897,14 +875,13 @@ const getRootRenderer = (fiber: Fiber): ReactRenderer | null => {
|
|
|
897
875
|
while (hostRootFiber.return) {
|
|
898
876
|
hostRootFiber = hostRootFiber.return;
|
|
899
877
|
}
|
|
900
|
-
const
|
|
878
|
+
const fiberRoot = hostRootFiber.stateNode;
|
|
879
|
+
if (!isFiberRoot(fiberRoot)) return null;
|
|
880
|
+
const rendererId = rootRendererIds.get(fiberRoot);
|
|
901
881
|
if (rendererId === undefined) return null;
|
|
902
|
-
return getRDTHook().renderers
|
|
882
|
+
return getRDTHook().renderers.get(rendererId) ?? null;
|
|
903
883
|
};
|
|
904
884
|
|
|
905
|
-
// dispatch to the renderer that owns the fiber's root when known; renderers
|
|
906
|
-
// that never committed through bippy's hook patch fall back to "try all",
|
|
907
|
-
// which matches the pre-ownership behavior for single-renderer apps
|
|
908
885
|
const resolveOverrideRenderers = (fiber: Fiber): ReactRenderer[] => {
|
|
909
886
|
wireOverrideRenderers();
|
|
910
887
|
const rootRenderer = getRootRenderer(fiber);
|
|
@@ -930,7 +907,7 @@ const getHookStateDispatch = (
|
|
|
930
907
|
hookIndex: number,
|
|
931
908
|
): ((value: unknown) => void) | null => {
|
|
932
909
|
let hookState = fiber.memoizedState;
|
|
933
|
-
for (let
|
|
910
|
+
for (let currentHookIndex = 0; currentHookIndex < hookIndex; currentHookIndex++) {
|
|
934
911
|
if (!hookState?.next) return null;
|
|
935
912
|
hookState = hookState.next;
|
|
936
913
|
}
|
|
@@ -963,28 +940,33 @@ const isPOJO = (maybePOJO: unknown): maybePOJO is Record<string, unknown> => {
|
|
|
963
940
|
const buildPathsFromValue = (
|
|
964
941
|
maybePOJO: Record<string, unknown>,
|
|
965
942
|
basePath: string[] = [],
|
|
966
|
-
|
|
943
|
+
ancestors = new WeakSet<object>(),
|
|
944
|
+
): ValueWrite[] => {
|
|
967
945
|
if (!isPOJO(maybePOJO)) {
|
|
968
946
|
return [{ path: basePath, value: maybePOJO }];
|
|
969
947
|
}
|
|
948
|
+
if (ancestors.has(maybePOJO)) {
|
|
949
|
+
return [{ path: basePath, value: maybePOJO }];
|
|
950
|
+
}
|
|
970
951
|
|
|
971
|
-
|
|
952
|
+
ancestors.add(maybePOJO);
|
|
953
|
+
const paths: ValueWrite[] = [];
|
|
972
954
|
|
|
973
|
-
for (const key
|
|
974
|
-
const value = maybePOJO[key];
|
|
955
|
+
for (const [key, value] of Object.entries(maybePOJO)) {
|
|
975
956
|
const path = basePath.concat(key);
|
|
976
957
|
|
|
977
958
|
if (isPOJO(value)) {
|
|
978
|
-
paths.push(...buildPathsFromValue(value, path));
|
|
959
|
+
paths.push(...buildPathsFromValue(value, path, ancestors));
|
|
979
960
|
} else {
|
|
980
961
|
paths.push({ path, value });
|
|
981
962
|
}
|
|
982
963
|
}
|
|
983
964
|
|
|
965
|
+
ancestors.delete(maybePOJO);
|
|
984
966
|
return paths;
|
|
985
967
|
};
|
|
986
968
|
|
|
987
|
-
const buildValueWrites = (partialValue: unknown):
|
|
969
|
+
const buildValueWrites = (partialValue: unknown): ValueWrite[] =>
|
|
988
970
|
isPOJO(partialValue) ? buildPathsFromValue(partialValue) : [{ path: [], value: partialValue }];
|
|
989
971
|
|
|
990
972
|
export const overrideProps = (fiber: Fiber, partialValue: Record<string, unknown>) => {
|
|
@@ -1048,18 +1030,26 @@ export interface InstrumentationOptions {
|
|
|
1048
1030
|
onScheduleFiberRoot?: (rendererID: number, root: FiberRoot, children: React.ReactNode) => unknown;
|
|
1049
1031
|
}
|
|
1050
1032
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
const
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1033
|
+
interface InstrumentationSubscription {
|
|
1034
|
+
options: InstrumentationOptions;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
const instrumentationSubscriptions = new Set<InstrumentationSubscription>();
|
|
1038
|
+
|
|
1039
|
+
const runInstrumentationCallback = (
|
|
1040
|
+
instrumentationName: string,
|
|
1041
|
+
callbackName: string,
|
|
1042
|
+
callback: () => unknown,
|
|
1043
|
+
): void => {
|
|
1044
|
+
runWithBippyError(
|
|
1045
|
+
callback,
|
|
1046
|
+
(cause) => new BippyInstrumentationError(instrumentationName, callbackName, cause),
|
|
1047
|
+
);
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
const runReactDevToolsCallback = (callbackName: string, callback: () => unknown): void => {
|
|
1051
|
+
runWithBippyError(callback, (cause) => new BippyReactDevToolsError(callbackName, cause));
|
|
1052
|
+
};
|
|
1063
1053
|
|
|
1064
1054
|
interface HookDispatchers {
|
|
1065
1055
|
onCommitFiberRoot: ReactDevToolsGlobalHook["onCommitFiberRoot"];
|
|
@@ -1069,6 +1059,7 @@ interface HookDispatchers {
|
|
|
1069
1059
|
}
|
|
1070
1060
|
|
|
1071
1061
|
const hookDispatchers = new WeakMap<ReactDevToolsGlobalHook, Partial<HookDispatchers>>();
|
|
1062
|
+
let didSubscribeToHookReplacements = false;
|
|
1072
1063
|
|
|
1073
1064
|
const rootRendererIds = new WeakMap<FiberRoot, number>();
|
|
1074
1065
|
|
|
@@ -1077,7 +1068,7 @@ const rootRendererIds = new WeakMap<FiberRoot, number>();
|
|
|
1077
1068
|
// next instrument() call installs a fresh wrapper over it; a superseded
|
|
1078
1069
|
// wrapper still forwards the previous chain but skips the listeners so
|
|
1079
1070
|
// they never fire twice.
|
|
1080
|
-
const
|
|
1071
|
+
const setHookEventDispatchers = (rdtHook: ReactDevToolsGlobalHook): void => {
|
|
1081
1072
|
const dispatchers = hookDispatchers.get(rdtHook) ?? {};
|
|
1082
1073
|
hookDispatchers.set(rdtHook, dispatchers);
|
|
1083
1074
|
|
|
@@ -1092,8 +1083,13 @@ const ensureHookDispatchesToListeners = (rdtHook: ReactDevToolsGlobalHook): void
|
|
|
1092
1083
|
priority,
|
|
1093
1084
|
didError,
|
|
1094
1085
|
) => {
|
|
1095
|
-
prevOnCommitFiberRoot
|
|
1086
|
+
if (prevOnCommitFiberRoot) {
|
|
1087
|
+
runReactDevToolsCallback("onCommitFiberRoot", () =>
|
|
1088
|
+
prevOnCommitFiberRoot.call(rdtHook, rendererID, root, priority, didError),
|
|
1089
|
+
);
|
|
1090
|
+
}
|
|
1096
1091
|
if (hookDispatchers.get(rdtHook)?.onCommitFiberRoot !== dispatchCommitFiberRoot) return;
|
|
1092
|
+
setReactWorkTagsForFiber(root.current, rdtHook.renderers.get(rendererID));
|
|
1097
1093
|
const rootMemoizedState = root.current.memoizedState;
|
|
1098
1094
|
const isUnmounting =
|
|
1099
1095
|
rootMemoizedState === null ||
|
|
@@ -1106,8 +1102,14 @@ const ensureHookDispatchesToListeners = (rdtHook: ReactDevToolsGlobalHook): void
|
|
|
1106
1102
|
_fiberRoots.add(root);
|
|
1107
1103
|
rootRendererIds.set(root, rendererID);
|
|
1108
1104
|
}
|
|
1109
|
-
for (const
|
|
1110
|
-
|
|
1105
|
+
for (const { options } of instrumentationSubscriptions) {
|
|
1106
|
+
if (options.onCommitFiberRoot) {
|
|
1107
|
+
runInstrumentationCallback(
|
|
1108
|
+
options.name ?? BIPPY_INSTRUMENTATION_STRING,
|
|
1109
|
+
"onCommitFiberRoot",
|
|
1110
|
+
() => options.onCommitFiberRoot?.(rendererID, root, priority, didError),
|
|
1111
|
+
);
|
|
1112
|
+
}
|
|
1111
1113
|
}
|
|
1112
1114
|
};
|
|
1113
1115
|
dispatchers.onCommitFiberRoot = dispatchCommitFiberRoot;
|
|
@@ -1123,12 +1125,23 @@ const ensureHookDispatchesToListeners = (rdtHook: ReactDevToolsGlobalHook): void
|
|
|
1123
1125
|
rendererID,
|
|
1124
1126
|
fiber,
|
|
1125
1127
|
) => {
|
|
1126
|
-
|
|
1128
|
+
setReactWorkTagsForFiber(fiber, rdtHook.renderers.get(rendererID));
|
|
1129
|
+
if (prevOnCommitFiberUnmount) {
|
|
1130
|
+
runReactDevToolsCallback("onCommitFiberUnmount", () =>
|
|
1131
|
+
prevOnCommitFiberUnmount.call(rdtHook, rendererID, fiber),
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1127
1134
|
if (hookDispatchers.get(rdtHook)?.onCommitFiberUnmount !== dispatchCommitFiberUnmount) {
|
|
1128
1135
|
return;
|
|
1129
1136
|
}
|
|
1130
|
-
for (const
|
|
1131
|
-
|
|
1137
|
+
for (const { options } of instrumentationSubscriptions) {
|
|
1138
|
+
if (options.onCommitFiberUnmount) {
|
|
1139
|
+
runInstrumentationCallback(
|
|
1140
|
+
options.name ?? BIPPY_INSTRUMENTATION_STRING,
|
|
1141
|
+
"onCommitFiberUnmount",
|
|
1142
|
+
() => options.onCommitFiberUnmount?.(rendererID, fiber),
|
|
1143
|
+
);
|
|
1144
|
+
}
|
|
1132
1145
|
}
|
|
1133
1146
|
};
|
|
1134
1147
|
dispatchers.onCommitFiberUnmount = dispatchCommitFiberUnmount;
|
|
@@ -1144,12 +1157,22 @@ const ensureHookDispatchesToListeners = (rdtHook: ReactDevToolsGlobalHook): void
|
|
|
1144
1157
|
rendererID,
|
|
1145
1158
|
root,
|
|
1146
1159
|
) => {
|
|
1147
|
-
prevOnPostCommitFiberRoot
|
|
1160
|
+
if (prevOnPostCommitFiberRoot) {
|
|
1161
|
+
runReactDevToolsCallback("onPostCommitFiberRoot", () =>
|
|
1162
|
+
prevOnPostCommitFiberRoot.call(rdtHook, rendererID, root),
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1148
1165
|
if (hookDispatchers.get(rdtHook)?.onPostCommitFiberRoot !== dispatchPostCommitFiberRoot) {
|
|
1149
1166
|
return;
|
|
1150
1167
|
}
|
|
1151
|
-
for (const
|
|
1152
|
-
|
|
1168
|
+
for (const { options } of instrumentationSubscriptions) {
|
|
1169
|
+
if (options.onPostCommitFiberRoot) {
|
|
1170
|
+
runInstrumentationCallback(
|
|
1171
|
+
options.name ?? BIPPY_INSTRUMENTATION_STRING,
|
|
1172
|
+
"onPostCommitFiberRoot",
|
|
1173
|
+
() => options.onPostCommitFiberRoot?.(rendererID, root),
|
|
1174
|
+
);
|
|
1175
|
+
}
|
|
1153
1176
|
}
|
|
1154
1177
|
};
|
|
1155
1178
|
dispatchers.onPostCommitFiberRoot = dispatchPostCommitFiberRoot;
|
|
@@ -1166,10 +1189,20 @@ const ensureHookDispatchesToListeners = (rdtHook: ReactDevToolsGlobalHook): void
|
|
|
1166
1189
|
root,
|
|
1167
1190
|
children,
|
|
1168
1191
|
) => {
|
|
1169
|
-
prevOnScheduleFiberRoot
|
|
1192
|
+
if (prevOnScheduleFiberRoot) {
|
|
1193
|
+
runReactDevToolsCallback("onScheduleFiberRoot", () =>
|
|
1194
|
+
prevOnScheduleFiberRoot.call(rdtHook, rendererID, root, children),
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
1170
1197
|
if (hookDispatchers.get(rdtHook)?.onScheduleFiberRoot !== dispatchScheduleFiberRoot) return;
|
|
1171
|
-
for (const
|
|
1172
|
-
|
|
1198
|
+
for (const { options } of instrumentationSubscriptions) {
|
|
1199
|
+
if (options.onScheduleFiberRoot) {
|
|
1200
|
+
runInstrumentationCallback(
|
|
1201
|
+
options.name ?? BIPPY_INSTRUMENTATION_STRING,
|
|
1202
|
+
"onScheduleFiberRoot",
|
|
1203
|
+
() => options.onScheduleFiberRoot?.(rendererID, root, children),
|
|
1204
|
+
);
|
|
1205
|
+
}
|
|
1173
1206
|
}
|
|
1174
1207
|
};
|
|
1175
1208
|
dispatchers.onScheduleFiberRoot = dispatchScheduleFiberRoot;
|
|
@@ -1182,8 +1215,7 @@ const ensureHookDispatchesToListeners = (rdtHook: ReactDevToolsGlobalHook): void
|
|
|
1182
1215
|
* dispatches to a set of listeners, so multiple `instrument` calls compose
|
|
1183
1216
|
* without stacking patches. Returns an unsubscribe function that removes
|
|
1184
1217
|
* exactly the handlers this call registered.
|
|
1185
|
-
* The
|
|
1186
|
-
* bippy subscriptions through `using`.
|
|
1218
|
+
* The unsubscribe function can also be disposed through `using`.
|
|
1187
1219
|
* @example
|
|
1188
1220
|
* const unsubscribe = instrument({
|
|
1189
1221
|
* onActive() {
|
|
@@ -1196,30 +1228,31 @@ const ensureHookDispatchesToListeners = (rdtHook: ReactDevToolsGlobalHook): void
|
|
|
1196
1228
|
* unsubscribe();
|
|
1197
1229
|
*/
|
|
1198
1230
|
export const instrument = (options: InstrumentationOptions): Unsubscribe => {
|
|
1199
|
-
const
|
|
1231
|
+
const onActiveListener = options.onActive;
|
|
1232
|
+
const onActive = onActiveListener
|
|
1233
|
+
? () =>
|
|
1234
|
+
runInstrumentationCallback(
|
|
1235
|
+
options.name ?? BIPPY_INSTRUMENTATION_STRING,
|
|
1236
|
+
"onActive",
|
|
1237
|
+
onActiveListener,
|
|
1238
|
+
)
|
|
1239
|
+
: undefined;
|
|
1240
|
+
const rdtHook = getRDTHook(onActive);
|
|
1241
|
+
|
|
1242
|
+
if (!didSubscribeToHookReplacements) {
|
|
1243
|
+
onRDTHookReplace(setHookEventDispatchers);
|
|
1244
|
+
didSubscribeToHookReplacements = true;
|
|
1245
|
+
}
|
|
1200
1246
|
|
|
1201
1247
|
rdtHook._instrumentationSource = options.name ?? BIPPY_INSTRUMENTATION_STRING;
|
|
1202
1248
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
onCommitFiberUnmount,
|
|
1209
|
-
onPostCommitFiberRoot,
|
|
1210
|
-
onScheduleFiberRoot,
|
|
1211
|
-
} = options;
|
|
1212
|
-
if (onCommitFiberRoot) commitFiberRootListeners.add(onCommitFiberRoot);
|
|
1213
|
-
if (onCommitFiberUnmount) commitFiberUnmountListeners.add(onCommitFiberUnmount);
|
|
1214
|
-
if (onPostCommitFiberRoot) postCommitFiberRootListeners.add(onPostCommitFiberRoot);
|
|
1215
|
-
if (onScheduleFiberRoot) scheduleFiberRootListeners.add(onScheduleFiberRoot);
|
|
1216
|
-
|
|
1217
|
-
return toUnsubscribe(() => {
|
|
1249
|
+
setHookEventDispatchers(rdtHook);
|
|
1250
|
+
const subscription: InstrumentationSubscription = { options };
|
|
1251
|
+
instrumentationSubscriptions.add(subscription);
|
|
1252
|
+
|
|
1253
|
+
return createUnsubscribe(() => {
|
|
1218
1254
|
if (onActive) _onActiveListeners.delete(onActive);
|
|
1219
|
-
|
|
1220
|
-
if (onCommitFiberUnmount) commitFiberUnmountListeners.delete(onCommitFiberUnmount);
|
|
1221
|
-
if (onPostCommitFiberRoot) postCommitFiberRootListeners.delete(onPostCommitFiberRoot);
|
|
1222
|
-
if (onScheduleFiberRoot) scheduleFiberRootListeners.delete(onScheduleFiberRoot);
|
|
1255
|
+
instrumentationSubscriptions.delete(subscription);
|
|
1223
1256
|
});
|
|
1224
1257
|
};
|
|
1225
1258
|
|
|
@@ -1307,6 +1340,18 @@ export const getFiberFromHostInstance = <T>(hostInstance: T): Fiber | null => {
|
|
|
1307
1340
|
return null;
|
|
1308
1341
|
};
|
|
1309
1342
|
|
|
1310
|
-
export
|
|
1311
|
-
|
|
1312
|
-
|
|
1343
|
+
export {
|
|
1344
|
+
BIPPY_INSTRUMENTATION_STRING,
|
|
1345
|
+
_onActiveListeners,
|
|
1346
|
+
_renderers,
|
|
1347
|
+
getRDTHook,
|
|
1348
|
+
hasRDTHook,
|
|
1349
|
+
installRDTHook,
|
|
1350
|
+
isRealReactDevtools,
|
|
1351
|
+
onRendererInject,
|
|
1352
|
+
patchRDTHook,
|
|
1353
|
+
safelyInstallRDTHook,
|
|
1354
|
+
version,
|
|
1355
|
+
} from "./rdt-hook.js";
|
|
1356
|
+
export type { Unsubscribe } from "./rdt-hook.js";
|
|
1357
|
+
export type * from "./react-internals/index.js";
|