bippy 0.7.2 → 0.7.3-dev.09bae5a
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 +12 -79
- package/dist/core.cjs +1 -1
- package/dist/core.js +1 -1
- package/dist/errors.d.cts +59 -9
- package/dist/errors.d.ts +59 -9
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +34 -58
- package/dist/index.d.ts +36 -60
- package/dist/index.js +1 -1
- package/dist/install-hook-only.cjs +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 +11 -11
- package/dist/source.d.cts +47 -18
- package/dist/source.d.ts +47 -18
- package/dist/source.js +12 -12
- package/package.json +7 -35
- package/src/call-listener.ts +13 -0
- package/src/core.ts +367 -282
- package/src/rdt-hook.ts +159 -87
- package/src/react-internals/current-fiber.ts +84 -0
- package/src/react-internals/generated/react-work-tags.ts +3 -0
- package/src/react-internals/index.ts +38 -11
- package/src/react-internals/types.ts +33 -6
- package/src/react.ts +141 -55
- package/src/source/constants.ts +11 -9
- package/src/source/get-display-name-from-source.ts +10 -3
- package/src/source/get-source.ts +42 -157
- package/src/source/index.ts +17 -3
- package/src/source/inspect-hooks.ts +198 -49
- package/src/source/normalize-file-name.ts +416 -0
- package/src/source/owner-stack.ts +43 -35
- package/src/source/parse-debug-stack.ts +1 -1
- package/src/source/parse-hook-names.ts +15 -8
- package/src/source/parse-stack.ts +114 -64
- package/src/source/renderer-dispatchers.ts +9 -4
- package/src/source/symbolication.ts +131 -70
package/src/react.ts
CHANGED
|
@@ -1,76 +1,162 @@
|
|
|
1
1
|
import "./install-hook-only.js";
|
|
2
|
-
import
|
|
3
|
-
import { isFiber } from "./core.js";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { isFiber, traverseFiber } from "./core.js";
|
|
4
|
+
import { _renderers } from "./rdt-hook.js";
|
|
5
|
+
import { getCurrentFiberFromRoot } from "./react-internals/current-fiber.js";
|
|
4
6
|
import type { Fiber } from "./react-internals/index.js";
|
|
5
7
|
|
|
6
8
|
export type { Fiber } from "./react-internals/index.js";
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const subscribeToEmptyStore = (): (() => void) => unsubscribeFromEmptyStore;
|
|
12
|
-
const useSyncExternalStore: unknown = Reflect.get(React, "useSyncExternalStore");
|
|
10
|
+
interface RenderMarker {
|
|
11
|
+
(state: undefined): undefined;
|
|
12
|
+
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
interface ReducerQueue {
|
|
15
|
+
lastRenderedReducer: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface FiberCapture {
|
|
19
|
+
fiber: Fiber;
|
|
20
|
+
queue: ReducerQueue | null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const isReducerQueue = (value: unknown): value is ReducerQueue =>
|
|
24
|
+
typeof value === "object" && value !== null && "lastRenderedReducer" in value;
|
|
25
|
+
|
|
26
|
+
const hasRenderMarker = (fiber: Fiber, renderMarker: RenderMarker): boolean => {
|
|
27
|
+
for (let hook = fiber.memoizedState; hook; hook = hook.next) {
|
|
28
|
+
if (Array.isArray(hook.memoizedState) && hook.memoizedState[0] === renderMarker) return true;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const getReducerQueue = (fiber: Fiber, renderMarker: RenderMarker): ReducerQueue | null => {
|
|
34
|
+
for (let hook = fiber.memoizedState; hook; hook = hook.next) {
|
|
35
|
+
if (isReducerQueue(hook.queue) && hook.queue.lastRenderedReducer === renderMarker)
|
|
36
|
+
return hook.queue;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const getDevToolsFiber = (renderMarker: RenderMarker): Fiber | null => {
|
|
42
|
+
for (const renderer of _renderers) {
|
|
43
|
+
try {
|
|
44
|
+
const fiber = renderer.getCurrentFiber?.();
|
|
45
|
+
if (fiber && isFiber(fiber) && hasRenderMarker(fiber, renderMarker)) return fiber;
|
|
46
|
+
} catch {}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const captureReducerFiber = (
|
|
52
|
+
renderMarker: RenderMarker,
|
|
53
|
+
shouldCapture: boolean,
|
|
54
|
+
): FiberCapture | null => {
|
|
55
|
+
let originalBind: typeof Function.prototype.bind | undefined;
|
|
56
|
+
if (shouldCapture) {
|
|
57
|
+
try {
|
|
58
|
+
originalBind = Function.prototype.bind;
|
|
59
|
+
} catch {}
|
|
60
|
+
}
|
|
61
|
+
if (!originalBind) {
|
|
62
|
+
React.useReducer(renderMarker, undefined);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let capture: FiberCapture | null = null;
|
|
67
|
+
let isCapturing = true;
|
|
68
|
+
// HACK: Production React binds a new reducer's Fiber and queue; validate the private reducer marker, not argument positions.
|
|
18
69
|
const bindProxy = new Proxy(originalBind, {
|
|
19
|
-
apply: (bind,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
70
|
+
apply: (bind, callback, boundArguments) => {
|
|
71
|
+
if (isCapturing && !capture) {
|
|
72
|
+
try {
|
|
73
|
+
const queue = boundArguments.find(
|
|
74
|
+
(argument): argument is ReducerQueue =>
|
|
75
|
+
isReducerQueue(argument) && argument.lastRenderedReducer === renderMarker,
|
|
76
|
+
);
|
|
77
|
+
if (queue) {
|
|
78
|
+
const fiber = boundArguments.find(
|
|
79
|
+
(argument): argument is Fiber => isFiber(argument) && isFiber(argument.return),
|
|
80
|
+
);
|
|
81
|
+
if (fiber) capture = { fiber, queue };
|
|
82
|
+
}
|
|
83
|
+
} catch {}
|
|
23
84
|
}
|
|
24
|
-
return Reflect.apply(bind,
|
|
85
|
+
return Reflect.apply(bind, callback, boundArguments);
|
|
25
86
|
},
|
|
26
87
|
});
|
|
27
|
-
Reflect.set(Function.prototype, "bind", bindProxy);
|
|
28
88
|
|
|
29
89
|
try {
|
|
30
|
-
|
|
90
|
+
try {
|
|
91
|
+
Reflect.set(Function.prototype, "bind", bindProxy);
|
|
92
|
+
} catch {}
|
|
93
|
+
React.useReducer(renderMarker, undefined);
|
|
94
|
+
return capture;
|
|
31
95
|
} finally {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
96
|
+
isCapturing = false;
|
|
97
|
+
capture = null;
|
|
98
|
+
try {
|
|
99
|
+
if (Function.prototype.bind === bindProxy) {
|
|
100
|
+
Reflect.set(Function.prototype, "bind", originalBind);
|
|
101
|
+
}
|
|
102
|
+
} catch {}
|
|
35
103
|
}
|
|
36
|
-
|
|
37
|
-
return capturedFiber;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const useExternalStoreCapture = (): void => {
|
|
41
|
-
Reflect.apply(useSyncExternalStore, React, [
|
|
42
|
-
subscribeToEmptyStore,
|
|
43
|
-
readEmptySnapshot,
|
|
44
|
-
readEmptySnapshot,
|
|
45
|
-
]);
|
|
46
104
|
};
|
|
47
105
|
|
|
48
|
-
|
|
49
|
-
|
|
106
|
+
// HACK: React <16.13 attaches hooks after render; the shared reducer queue validates the root-walk fallback.
|
|
107
|
+
const getRenderingFiberFromRoot = (
|
|
108
|
+
{ fiber, queue }: FiberCapture,
|
|
109
|
+
renderMarker: RenderMarker,
|
|
110
|
+
): Fiber | null => {
|
|
111
|
+
if (queue?.lastRenderedReducer !== renderMarker) return null;
|
|
112
|
+
let rootFiber = fiber;
|
|
113
|
+
while (rootFiber.return) rootFiber = rootFiber.return;
|
|
114
|
+
const root = rootFiber.stateNode;
|
|
115
|
+
if (typeof root !== "object" || root === null || !("current" in root) || !isFiber(root.current)) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const renderingRoot = root.current.alternate;
|
|
119
|
+
const renderingFiber = getCurrentFiberFromRoot(fiber)?.alternate;
|
|
120
|
+
if (renderingFiber) {
|
|
121
|
+
let ancestor = renderingFiber;
|
|
122
|
+
while (ancestor.return) ancestor = ancestor.return;
|
|
123
|
+
if (ancestor === renderingRoot) return renderingFiber;
|
|
124
|
+
}
|
|
125
|
+
return traverseFiber(renderingRoot, (candidate) => {
|
|
126
|
+
if (candidate !== fiber && candidate !== fiber.alternate) return false;
|
|
127
|
+
let parent = candidate;
|
|
128
|
+
while (parent.return) parent = parent.return;
|
|
129
|
+
return parent === renderingRoot;
|
|
130
|
+
});
|
|
50
131
|
};
|
|
51
132
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
const
|
|
133
|
+
export const useFiber = (): Fiber | undefined => {
|
|
134
|
+
"use no memo";
|
|
135
|
+
const fiberRef = React.useRef<FiberCapture | null>(null);
|
|
136
|
+
const renderMarker: RenderMarker = (state) => state;
|
|
137
|
+
React.useMemo(() => renderMarker, [renderMarker]);
|
|
138
|
+
const devToolsFiber = fiberRef.current ? null : getDevToolsFiber(renderMarker);
|
|
139
|
+
const capture = captureReducerFiber(renderMarker, !fiberRef.current && !devToolsFiber);
|
|
140
|
+
if (devToolsFiber) {
|
|
141
|
+
fiberRef.current = {
|
|
142
|
+
fiber: devToolsFiber,
|
|
143
|
+
queue: getReducerQueue(devToolsFiber, renderMarker),
|
|
144
|
+
};
|
|
145
|
+
return devToolsFiber;
|
|
146
|
+
}
|
|
147
|
+
const knownCapture = capture ?? fiberRef.current;
|
|
148
|
+
if (!knownCapture) return undefined;
|
|
149
|
+
const knownFiber = knownCapture.fiber;
|
|
59
150
|
const fiber =
|
|
60
|
-
|
|
61
|
-
(
|
|
62
|
-
?
|
|
63
|
-
:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}, [fiber]);
|
|
71
|
-
|
|
151
|
+
capture?.fiber ??
|
|
152
|
+
(hasRenderMarker(knownFiber, renderMarker)
|
|
153
|
+
? knownFiber
|
|
154
|
+
: knownFiber.alternate && hasRenderMarker(knownFiber.alternate, renderMarker)
|
|
155
|
+
? knownFiber.alternate
|
|
156
|
+
: getRenderingFiberFromRoot(knownCapture, renderMarker));
|
|
157
|
+
if (fiber) {
|
|
158
|
+
knownCapture.fiber = fiber;
|
|
159
|
+
fiberRef.current = knownCapture;
|
|
160
|
+
}
|
|
72
161
|
return fiber ?? undefined;
|
|
73
162
|
};
|
|
74
|
-
|
|
75
|
-
export const useFiber =
|
|
76
|
-
typeof useSyncExternalStore === "function" ? useFiberWithExternalStore : useFiberWithReducer;
|
package/src/source/constants.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
export const SCHEME_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
|
|
2
2
|
|
|
3
3
|
export const INTERNAL_SCHEME_PREFIXES = [
|
|
4
|
-
"
|
|
5
|
-
"file:///",
|
|
4
|
+
"rspack-internal://",
|
|
6
5
|
"webpack-internal://",
|
|
7
|
-
"webpack://",
|
|
8
|
-
"node:",
|
|
9
6
|
"turbopack://",
|
|
7
|
+
"webpack://",
|
|
8
|
+
"rspack://",
|
|
9
|
+
"parcel://",
|
|
10
10
|
"metro://",
|
|
11
|
-
"
|
|
11
|
+
"file:///",
|
|
12
|
+
"rsc://",
|
|
13
|
+
"node:",
|
|
14
|
+
"bun:",
|
|
12
15
|
"/(app-pages-browser)/",
|
|
16
|
+
"/app-pages-browser/",
|
|
13
17
|
] as const;
|
|
14
18
|
|
|
15
19
|
export const ABOUT_REACT_PREFIX = "about://React/";
|
|
@@ -21,13 +25,11 @@ export const ANONYMOUS_FILE_PATTERNS = ["<anonymous>", "eval", ""] as const;
|
|
|
21
25
|
export const SOURCE_FILE_EXTENSION_REGEX = /\.(cjs|cts|js|jsx|mdx|mjs|mts|ts|tsx)$/;
|
|
22
26
|
|
|
23
27
|
export const BUNDLED_FILE_PATTERN_REGEX =
|
|
24
|
-
/(\.min|bundle|chunk|vendor|vendors|runtime|polyfill|polyfills)\.(js|mjs|cjs)$|(chunk|bundle|vendor|vendors|runtime|polyfill|polyfills|framework|app|main|index)[-_.][A-Za-z0-9_-]{4,}\.(js|mjs|cjs)$|[\da-f]{8,}\.(js|mjs|cjs)$|[-_.][\da-f]{20,}\.(js|mjs|cjs)$|\/dist\/|\/build\/|\/.next\/|\/out\/|\/node_modules\/|\.webpack\.|\.vite\.|\.turbopack
|
|
28
|
+
/(\.min|bundle|chunk|vendor|vendors|runtime|polyfill|polyfills)\.(js|mjs|cjs)$|(chunk|bundle|vendor|vendors|runtime|polyfill|polyfills|framework|app|main|index)[-_.][A-Za-z0-9_-]{4,}\.(js|mjs|cjs)$|[\da-f]{8,}\.(js|mjs|cjs)$|[-_.][\da-f]{20,}\.(js|mjs|cjs)$|\/dist\/|\/build\/|\/.next\/|\/out\/|\/node_modules\/|\/_next\/|\/_expo\/|\/_nuxt\/|\/@vite\/|\/@react-refresh|\/\.parcel-cache\/|\/\.expo\/|\/\.rsbuild\/|\/\.vite\/|\/\.svelte-kit\/|\/\.astro\/|\/\.nuxt\/|\/\.angular\/|\.webpack\.|\.vite\.|\.turbopack\.|\[root-of-the-server\]/i;
|
|
25
29
|
|
|
26
30
|
export const QUERY_PARAMETER_PATTERN_REGEX = /^\?[\w~.-]+(?:=[^&#]*)?(?:&[\w~.-]+(?:=[^&#]*)?)*$/;
|
|
27
31
|
|
|
28
|
-
export const
|
|
29
|
-
|
|
30
|
-
export const SERVER_ENV_PATTERN = /\(at [^)]+\)$/;
|
|
32
|
+
export const SERVER_ENV_PATTERN = /\[[^\]]+\]$/;
|
|
31
33
|
|
|
32
34
|
export const REACT_STACK_BOTTOM_FRAME_PATTERNS = [
|
|
33
35
|
"react_stack_bottom_frame",
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
getSourceFromSourceMap,
|
|
7
7
|
getSourceMap,
|
|
8
8
|
type SourceFetch,
|
|
9
|
+
type SourceMapRequestOptions,
|
|
9
10
|
} from "./symbolication.js";
|
|
10
11
|
import type { StackFrame } from "./parse-stack.js";
|
|
11
12
|
|
|
@@ -53,8 +54,9 @@ const extractComponentNameFromSource = (
|
|
|
53
54
|
|
|
54
55
|
export const getDisplayNameFromSource = async (
|
|
55
56
|
fiber: Fiber,
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
shouldUseCache = true,
|
|
58
|
+
sourceFetch?: SourceFetch,
|
|
59
|
+
requestOptions: SourceMapRequestOptions = {},
|
|
58
60
|
): Promise<string | null> => {
|
|
59
61
|
const stackFrame =
|
|
60
62
|
getDefinitionFrameFromOwnedChild(fiber) ??
|
|
@@ -64,7 +66,12 @@ export const getDisplayNameFromSource = async (
|
|
|
64
66
|
return getDisplayName(fiber.type);
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
const bundleSourceMap = await getSourceMap(
|
|
69
|
+
const bundleSourceMap = await getSourceMap(
|
|
70
|
+
stackFrame.fileName,
|
|
71
|
+
shouldUseCache,
|
|
72
|
+
sourceFetch,
|
|
73
|
+
requestOptions,
|
|
74
|
+
);
|
|
68
75
|
|
|
69
76
|
if (!bundleSourceMap) {
|
|
70
77
|
return getDisplayName(fiber.type);
|
package/src/source/get-source.ts
CHANGED
|
@@ -2,15 +2,6 @@ import type { Fiber } from "../react-internals/index.js";
|
|
|
2
2
|
import { getDisplayName } from "../core.js";
|
|
3
3
|
|
|
4
4
|
import type { FiberSource } from "./types.js";
|
|
5
|
-
import {
|
|
6
|
-
SCHEME_REGEX,
|
|
7
|
-
INTERNAL_SCHEME_PREFIXES,
|
|
8
|
-
ABOUT_REACT_PREFIX,
|
|
9
|
-
ANONYMOUS_FILE_PATTERNS,
|
|
10
|
-
SOURCE_FILE_EXTENSION_REGEX,
|
|
11
|
-
BUNDLED_FILE_PATTERN_REGEX,
|
|
12
|
-
QUERY_PARAMETER_PATTERN_REGEX,
|
|
13
|
-
} from "./constants.js";
|
|
14
5
|
import { getDefinitionFrameFromOwnedChild, getParentStack, hasDebugStack } from "./owner-stack.js";
|
|
15
6
|
import { parseDebugStack } from "./parse-debug-stack.js";
|
|
16
7
|
import { parseStack, type StackFrame } from "./parse-stack.js";
|
|
@@ -19,6 +10,7 @@ import {
|
|
|
19
10
|
getSourceMap,
|
|
20
11
|
symbolicateStack,
|
|
21
12
|
type SourceFetch,
|
|
13
|
+
type SourceMapRequestOptions,
|
|
22
14
|
} from "./symbolication.js";
|
|
23
15
|
|
|
24
16
|
export const hasDebugSource = (
|
|
@@ -67,10 +59,17 @@ const getUsageFrameFromDebugStack = (fiber: Fiber): StackFrame | null => {
|
|
|
67
59
|
return null;
|
|
68
60
|
};
|
|
69
61
|
|
|
62
|
+
export const getRawSource = (fiber: Fiber): FiberSource | null => {
|
|
63
|
+
if (hasDebugSource(fiber)) return fiber._debugSource;
|
|
64
|
+
const stackFrame = getUsageFrameFromDebugStack(fiber) ?? getDefinitionFrameFromOwnedChild(fiber);
|
|
65
|
+
return stackFrame ? toFiberSource(stackFrame) : null;
|
|
66
|
+
};
|
|
67
|
+
|
|
70
68
|
const getSourceByComponentName = async (
|
|
71
69
|
fiber: Fiber,
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
shouldUseCache: boolean,
|
|
71
|
+
sourceFetch: SourceFetch | undefined,
|
|
72
|
+
requestOptions: SourceMapRequestOptions,
|
|
74
73
|
): Promise<FiberSource | null> => {
|
|
75
74
|
const functionName = getDisplayName(fiber.type);
|
|
76
75
|
if (!functionName) return null;
|
|
@@ -83,7 +82,7 @@ const getSourceByComponentName = async (
|
|
|
83
82
|
continue;
|
|
84
83
|
}
|
|
85
84
|
visitedFileNames.add(fileName);
|
|
86
|
-
const sourceMap = await getSourceMap(fileName,
|
|
85
|
+
const sourceMap = await getSourceMap(fileName, shouldUseCache, sourceFetch, requestOptions);
|
|
87
86
|
if (!sourceMap) continue;
|
|
88
87
|
const source = getSourceFromSourceMapByFunctionName(sourceMap, functionName);
|
|
89
88
|
if (source && !source.isIgnoreListed) return toFiberSource(source);
|
|
@@ -119,156 +118,42 @@ const getSourceByComponentName = async (
|
|
|
119
118
|
*/
|
|
120
119
|
export const getSource = async (
|
|
121
120
|
fiber: Fiber,
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
shouldUseCache = true,
|
|
122
|
+
sourceFetch?: SourceFetch,
|
|
123
|
+
requestOptions: SourceMapRequestOptions = {},
|
|
124
124
|
): Promise<FiberSource | null> => {
|
|
125
|
-
if (hasDebugSource(fiber))
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
125
|
+
if (hasDebugSource(fiber)) return fiber._debugSource;
|
|
126
|
+
const rawSource = getRawSource(fiber);
|
|
127
|
+
if (rawSource) {
|
|
128
|
+
const [symbolicatedFrame] = await symbolicateStack(
|
|
129
|
+
[
|
|
130
|
+
{
|
|
131
|
+
columnNumber: rawSource.columnNumber,
|
|
132
|
+
fileName: rawSource.fileName,
|
|
133
|
+
functionName: rawSource.functionName,
|
|
134
|
+
lineNumber: rawSource.lineNumber,
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
shouldUseCache,
|
|
138
|
+
sourceFetch,
|
|
139
|
+
requestOptions,
|
|
140
|
+
);
|
|
141
|
+
const symbolicatedSource = toFiberSource(symbolicatedFrame);
|
|
142
|
+
if (symbolicatedSource) return symbolicatedSource;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const parentStackFrames = await getParentStack(
|
|
146
|
+
fiber,
|
|
147
|
+
shouldUseCache,
|
|
148
|
+
sourceFetch,
|
|
149
|
+
requestOptions,
|
|
150
|
+
);
|
|
140
151
|
for (const stackFrame of parentStackFrames) {
|
|
141
152
|
if (stackFrame.fileName) {
|
|
142
153
|
return toFiberSource(stackFrame);
|
|
143
154
|
}
|
|
144
155
|
}
|
|
145
|
-
return getSourceByComponentName(fiber,
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const getPathSegmentCount = (path: string): number => path.split("/").filter(Boolean).length;
|
|
149
|
-
|
|
150
|
-
const stripSingleBasePathPrefix = (path: string): string => {
|
|
151
|
-
const firstSlashIndex = path.indexOf("/", 1);
|
|
152
|
-
if (firstSlashIndex === -1) {
|
|
153
|
-
return path;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const basePath = path.slice(0, firstSlashIndex);
|
|
157
|
-
if (getPathSegmentCount(basePath) !== 1) {
|
|
158
|
-
return path;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const remainderPath = path.slice(firstSlashIndex);
|
|
162
|
-
if (!SOURCE_FILE_EXTENSION_REGEX.test(remainderPath)) {
|
|
163
|
-
return path;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const remainderSegments = remainderPath.split("/").filter(Boolean);
|
|
167
|
-
if (remainderSegments.length < 2) {
|
|
168
|
-
return path;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const firstRemainderSegment = remainderSegments[0];
|
|
172
|
-
if (firstRemainderSegment.startsWith("@")) {
|
|
173
|
-
return path;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (firstRemainderSegment.length > 4) {
|
|
177
|
-
return path;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return remainderPath;
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
export const normalizeFileName = (fileName: string): string => {
|
|
184
|
-
if (!fileName) {
|
|
185
|
-
return "";
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (ANONYMOUS_FILE_PATTERNS.some((pattern) => pattern === fileName)) {
|
|
189
|
-
return "";
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
let normalizedFileName = fileName;
|
|
193
|
-
const isWindowsDrivePath = /^[a-zA-Z]:[\\/]/.test(normalizedFileName);
|
|
194
|
-
|
|
195
|
-
const isHttpUrl =
|
|
196
|
-
normalizedFileName.startsWith("http://") || normalizedFileName.startsWith("https://");
|
|
197
|
-
if (isHttpUrl) {
|
|
198
|
-
try {
|
|
199
|
-
const parsedUrl = new URL(normalizedFileName);
|
|
200
|
-
normalizedFileName = parsedUrl.pathname;
|
|
201
|
-
} catch {}
|
|
202
|
-
normalizedFileName = stripSingleBasePathPrefix(normalizedFileName);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (normalizedFileName.startsWith(ABOUT_REACT_PREFIX)) {
|
|
206
|
-
const remainder = normalizedFileName.slice(ABOUT_REACT_PREFIX.length);
|
|
207
|
-
const slashIndex = remainder.indexOf("/");
|
|
208
|
-
const colonIndex = remainder.indexOf(":");
|
|
209
|
-
|
|
210
|
-
if (slashIndex !== -1 && (colonIndex === -1 || slashIndex < colonIndex)) {
|
|
211
|
-
normalizedFileName = remainder.slice(slashIndex + 1);
|
|
212
|
-
} else {
|
|
213
|
-
normalizedFileName = remainder;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
let didStripPrefix = true;
|
|
218
|
-
while (didStripPrefix) {
|
|
219
|
-
didStripPrefix = false;
|
|
220
|
-
for (const prefix of INTERNAL_SCHEME_PREFIXES) {
|
|
221
|
-
if (normalizedFileName.startsWith(prefix)) {
|
|
222
|
-
normalizedFileName = normalizedFileName.slice(prefix.length);
|
|
223
|
-
|
|
224
|
-
if (prefix === "file:///") {
|
|
225
|
-
normalizedFileName = `/${normalizedFileName.replace(/^\/+/, "")}`;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
didStripPrefix = true;
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (!isWindowsDrivePath) {
|
|
235
|
-
const schemeMatch = normalizedFileName.match(SCHEME_REGEX);
|
|
236
|
-
if (schemeMatch) {
|
|
237
|
-
normalizedFileName = normalizedFileName.slice(schemeMatch[0].length);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (normalizedFileName.startsWith("//")) {
|
|
242
|
-
const firstPathSlashIndex = normalizedFileName.indexOf("/", 2);
|
|
243
|
-
normalizedFileName =
|
|
244
|
-
firstPathSlashIndex === -1 ? "" : normalizedFileName.slice(firstPathSlashIndex);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const queryParameterIndex = normalizedFileName.indexOf("?");
|
|
248
|
-
if (queryParameterIndex !== -1) {
|
|
249
|
-
const potentialQueryParameters = normalizedFileName.slice(queryParameterIndex);
|
|
250
|
-
if (QUERY_PARAMETER_PATTERN_REGEX.test(potentialQueryParameters)) {
|
|
251
|
-
normalizedFileName = normalizedFileName.slice(0, queryParameterIndex);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return normalizedFileName;
|
|
156
|
+
return getSourceByComponentName(fiber, shouldUseCache, sourceFetch, requestOptions);
|
|
256
157
|
};
|
|
257
158
|
|
|
258
|
-
export
|
|
259
|
-
const normalizedFileName = normalizeFileName(fileName);
|
|
260
|
-
|
|
261
|
-
if (!normalizedFileName) {
|
|
262
|
-
return false;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (!SOURCE_FILE_EXTENSION_REGEX.test(normalizedFileName)) {
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (BUNDLED_FILE_PATTERN_REGEX.test(normalizedFileName)) {
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return true;
|
|
274
|
-
};
|
|
159
|
+
export { isSourceFile, normalizeFileName } from "./normalize-file-name.js";
|
package/src/source/index.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
1
|
+
export {
|
|
2
|
+
formatOwnerStack,
|
|
3
|
+
getDefinitionFrameFromOwnedChild,
|
|
4
|
+
getFallbackParentStack,
|
|
5
|
+
getOwnerStack,
|
|
6
|
+
getParentStack,
|
|
7
|
+
getRawOwnerStack,
|
|
8
|
+
hasDebugStack,
|
|
9
|
+
} from "./owner-stack.js";
|
|
10
|
+
export { getRawSource, getSource, isSourceFile, normalizeFileName } from "./get-source.js";
|
|
3
11
|
export {
|
|
4
12
|
getSourceContentFromSourceMap,
|
|
5
13
|
getSourceFromSourceMap,
|
|
@@ -23,5 +31,11 @@ export {
|
|
|
23
31
|
BippySourceMapError,
|
|
24
32
|
BippyUnsupportedHookError,
|
|
25
33
|
} from "../errors.js";
|
|
26
|
-
export {
|
|
34
|
+
export {
|
|
35
|
+
getFiberHooks,
|
|
36
|
+
inspectHooks,
|
|
37
|
+
type HookSource,
|
|
38
|
+
type HooksNode,
|
|
39
|
+
type HooksTree,
|
|
40
|
+
} from "./inspect-hooks.js";
|
|
27
41
|
export { parseHookNames, type HookNames } from "./parse-hook-names.js";
|