bippy 0.6.1-dev.61475ed → 0.6.1-dev.d7876ea
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 +32 -48
- package/dist/core.cjs +1 -1
- package/dist/core.d.cts +42 -56
- package/dist/core.d.ts +42 -56
- package/dist/core.js +1 -1
- package/dist/core2.cjs +9 -0
- package/dist/core2.d.cts +3 -3
- package/dist/core2.d.ts +3 -3
- package/dist/core2.js +9 -0
- package/dist/errors.d.cts +436 -0
- package/dist/errors.d.ts +436 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -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 +1 -1
- package/dist/install-hook-only.d.ts +1 -1
- 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 +14 -4
- package/dist/source.d.cts +18 -9
- package/dist/source.d.ts +18 -9
- package/dist/source.js +14 -4
- package/package.json +21 -15
- package/src/core.ts +343 -253
- package/src/errors.ts +99 -0
- package/src/generated/react-work-tags.d.ts +261 -0
- package/src/generated/react-work-tags.js +240 -0
- package/src/rdt-hook.ts +154 -149
- package/src/react-internals.ts +65 -0
- package/src/semver.ts +78 -0
- package/src/source/constants.ts +1 -1
- package/src/source/error-stack.ts +11 -0
- package/src/source/get-source.ts +2 -1
- package/src/source/index.ts +9 -1
- package/src/source/inspect-hooks.ts +199 -164
- package/src/source/owner-stack.ts +84 -114
- package/src/source/parse-debug-stack.ts +4 -4
- package/src/source/parse-stack.ts +1 -1
- package/src/source/symbolication.ts +365 -89
- package/src/types.ts +165 -334
- package/src/unsubscribe.ts +2 -2
- package/dist/get-source.cjs +0 -19
- package/dist/get-source.js +0 -19
- package/dist/react-refresh.cjs +0 -9
- package/dist/react-refresh.d.cts +0 -66
- package/dist/react-refresh.d.ts +0 -66
- package/dist/react-refresh.js +0 -9
- package/dist/unsubscribe.d.cts +0 -298
- package/dist/unsubscribe.d.ts +0 -298
- package/src/react-refresh/constants.ts +0 -9
- package/src/react-refresh/detect-hmr-transport.ts +0 -33
- package/src/react-refresh/index.ts +0 -173
- package/src/react-refresh/metro-hmr-transport.ts +0 -188
- package/src/react-refresh/next-webpack-hmr-transport.ts +0 -72
- package/src/react-refresh/normalize-hmr-file-path.ts +0 -24
- package/src/react-refresh/types.ts +0 -7
- package/src/react-refresh/vite-hmr-transport.ts +0 -116
|
@@ -1,33 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Fiber,
|
|
6
|
-
ForwardRefTag,
|
|
7
|
-
FunctionComponentTag,
|
|
8
|
-
getRDTHook,
|
|
9
|
-
HostComponentTag,
|
|
10
|
-
HostHoistableTag,
|
|
11
|
-
HostSingletonTag,
|
|
12
|
-
LazyComponentTag,
|
|
13
|
-
SimpleMemoComponentTag,
|
|
14
|
-
SuspenseComponentTag,
|
|
15
|
-
SuspenseListComponentTag,
|
|
16
|
-
ViewTransitionComponentTag,
|
|
17
|
-
getDisplayName,
|
|
18
|
-
traverseFiber,
|
|
19
|
-
} from "../core.js";
|
|
20
|
-
import { ServerComponentInfo } from "../types.js";
|
|
1
|
+
import { getDisplayName, getType, traverseFiber } from "../core.js";
|
|
2
|
+
import { _renderers, getRDTHook } from "../rdt-hook.js";
|
|
3
|
+
import { getReactWorkTagsForFiber } from "../react-internals.js";
|
|
4
|
+
import type { Fiber, RendererDispatcherRef, ServerComponentInfo } from "../types.js";
|
|
21
5
|
import {
|
|
22
6
|
SERVER_FRAME_MARKER,
|
|
23
7
|
SERVER_ENV_PATTERN,
|
|
24
8
|
SERVER_COMPONENT_URL_PREFIXES,
|
|
25
9
|
} from "./constants.js";
|
|
26
|
-
|
|
10
|
+
import { getPrepareStackTrace, setPrepareStackTrace } from "./error-stack.js";
|
|
27
11
|
import { parseDebugStack } from "./parse-debug-stack.js";
|
|
28
12
|
import { parseStack, StackFrame } from "./parse-stack.js";
|
|
29
13
|
import { symbolicateStack } from "./symbolication.js";
|
|
30
14
|
|
|
15
|
+
interface RendererDispatcherSnapshot {
|
|
16
|
+
currentDispatcherRef: RendererDispatcherRef;
|
|
17
|
+
value: unknown;
|
|
18
|
+
}
|
|
19
|
+
|
|
31
20
|
export const hasDebugStack = (
|
|
32
21
|
fiber: Fiber,
|
|
33
22
|
): fiber is Fiber & {
|
|
@@ -37,13 +26,10 @@ export const hasDebugStack = (
|
|
|
37
26
|
};
|
|
38
27
|
|
|
39
28
|
const isFiberOwner = (owner: Fiber | ServerComponentInfo): owner is Fiber =>
|
|
40
|
-
|
|
29
|
+
"tag" in owner && typeof owner.tag === "number";
|
|
41
30
|
|
|
42
|
-
// react's typings (and bippy's Fiber, which mirrors them) declare _debugOwner
|
|
43
|
-
// as a Fiber, but react 19 flight sets a ReactComponentInfo object for server
|
|
44
|
-
// component owners
|
|
45
31
|
const getDebugOwner = (fiber: Fiber): Fiber | ServerComponentInfo | undefined =>
|
|
46
|
-
fiber._debugOwner
|
|
32
|
+
fiber._debugOwner ?? undefined;
|
|
47
33
|
|
|
48
34
|
/**
|
|
49
35
|
* Locates a frame inside the fiber's own function body without invoking it:
|
|
@@ -90,26 +76,41 @@ export const getDefinitionFrameFromOwnedChild = (fiber: Fiber): StackFrame | nul
|
|
|
90
76
|
return null;
|
|
91
77
|
};
|
|
92
78
|
|
|
93
|
-
const
|
|
79
|
+
const getRendererDispatcherRefs = (): RendererDispatcherRef[] => {
|
|
94
80
|
const rdtHook = getRDTHook();
|
|
95
|
-
|
|
81
|
+
const renderers = new Set([..._renderers, ...rdtHook.renderers.values()]);
|
|
82
|
+
const currentDispatcherRefs: RendererDispatcherRef[] = [];
|
|
83
|
+
const seenCurrentDispatcherRefs = new Set<object>();
|
|
84
|
+
for (const renderer of renderers) {
|
|
96
85
|
const currentDispatcherRef = renderer.currentDispatcherRef;
|
|
97
|
-
if (currentDispatcherRef
|
|
98
|
-
|
|
86
|
+
if (!currentDispatcherRef || seenCurrentDispatcherRefs.has(currentDispatcherRef)) continue;
|
|
87
|
+
seenCurrentDispatcherRefs.add(currentDispatcherRef);
|
|
88
|
+
currentDispatcherRefs.push(currentDispatcherRef);
|
|
89
|
+
}
|
|
90
|
+
return currentDispatcherRefs;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const clearRendererDispatchers = (): RendererDispatcherSnapshot[] => {
|
|
94
|
+
const dispatcherSnapshots: RendererDispatcherSnapshot[] = [];
|
|
95
|
+
for (const currentDispatcherRef of getRendererDispatcherRefs()) {
|
|
96
|
+
const value =
|
|
97
|
+
"H" in currentDispatcherRef ? currentDispatcherRef.H : currentDispatcherRef.current;
|
|
98
|
+
dispatcherSnapshots.push({ currentDispatcherRef, value });
|
|
99
|
+
if ("H" in currentDispatcherRef) {
|
|
100
|
+
currentDispatcherRef.H = null;
|
|
101
|
+
} else {
|
|
102
|
+
currentDispatcherRef.current = null;
|
|
99
103
|
}
|
|
100
104
|
}
|
|
101
|
-
return
|
|
105
|
+
return dispatcherSnapshots;
|
|
102
106
|
};
|
|
103
107
|
|
|
104
|
-
const
|
|
105
|
-
for (const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
} else {
|
|
111
|
-
currentDispatcherRef.current = value;
|
|
112
|
-
}
|
|
108
|
+
const restoreRendererDispatchers = (dispatcherSnapshots: RendererDispatcherSnapshot[]): void => {
|
|
109
|
+
for (const { currentDispatcherRef, value } of dispatcherSnapshots) {
|
|
110
|
+
if ("H" in currentDispatcherRef) {
|
|
111
|
+
currentDispatcherRef.H = value;
|
|
112
|
+
} else {
|
|
113
|
+
currentDispatcherRef.current = value;
|
|
113
114
|
}
|
|
114
115
|
}
|
|
115
116
|
};
|
|
@@ -146,49 +147,31 @@ const describeNativeComponentFrame = (
|
|
|
146
147
|
return cachedFrame;
|
|
147
148
|
}
|
|
148
149
|
|
|
149
|
-
const previousPrepareStackTrace =
|
|
150
|
-
|
|
151
|
-
(Error as { prepareStackTrace?: typeof Error.prepareStackTrace }).prepareStackTrace = undefined;
|
|
150
|
+
const previousPrepareStackTrace = getPrepareStackTrace();
|
|
151
|
+
setPrepareStackTrace(undefined);
|
|
152
152
|
reEntry = true;
|
|
153
153
|
|
|
154
|
-
const
|
|
155
|
-
setCurrentDispatcher(null);
|
|
154
|
+
const dispatcherSnapshots = clearRendererDispatchers();
|
|
156
155
|
const previousConsoleError = console.error;
|
|
157
156
|
const previousConsoleWarn = console.warn;
|
|
158
157
|
console.error = () => {};
|
|
159
158
|
console.warn = () => {};
|
|
160
159
|
try {
|
|
161
|
-
|
|
162
|
-
* Finding a common stack frame between sample and control errors can be
|
|
163
|
-
* tricky given the different types and levels of stack trace truncation from
|
|
164
|
-
* different JS VMs. So instead we'll attempt to control what that common
|
|
165
|
-
* frame should be through this object method:
|
|
166
|
-
* Having both the sample and control errors be in the function under the
|
|
167
|
-
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
|
|
168
|
-
* `displayName` properties of the function ensures that a stack
|
|
169
|
-
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
|
|
170
|
-
* it for both control and sample stacks.
|
|
171
|
-
*/
|
|
160
|
+
// HACK: Run the control and sample under the same property name so their stacks share a frame.
|
|
172
161
|
const RunInRootFrame = {
|
|
173
|
-
DetermineComponentFrameRoot() {
|
|
162
|
+
DetermineComponentFrameRoot(this: void) {
|
|
174
163
|
let control: unknown;
|
|
175
164
|
try {
|
|
176
|
-
// This should throw.
|
|
177
165
|
if (construct) {
|
|
178
|
-
// Something should be setting the props in the constructor.
|
|
179
166
|
const ThrowingConstructor = function () {
|
|
180
167
|
throw Error();
|
|
181
168
|
};
|
|
182
169
|
Object.defineProperty(ThrowingConstructor.prototype, "props", {
|
|
183
170
|
set: function () {
|
|
184
|
-
// We use a throwing setter instead of frozen or non-writable props
|
|
185
|
-
// because that won't throw in a non-strict mode function.
|
|
186
171
|
throw Error();
|
|
187
172
|
},
|
|
188
173
|
});
|
|
189
174
|
if (typeof Reflect === "object" && Reflect.construct) {
|
|
190
|
-
// We construct a different control for this case to include any extra
|
|
191
|
-
// frames added by the construct call.
|
|
192
175
|
try {
|
|
193
176
|
Reflect.construct(ThrowingConstructor, []);
|
|
194
177
|
} catch (caughtError) {
|
|
@@ -197,13 +180,11 @@ const describeNativeComponentFrame = (
|
|
|
197
180
|
Reflect.construct(component, [], ThrowingConstructor);
|
|
198
181
|
} else {
|
|
199
182
|
try {
|
|
200
|
-
|
|
201
|
-
ThrowingConstructor.call();
|
|
183
|
+
Function.prototype.apply.call(ThrowingConstructor, undefined, []);
|
|
202
184
|
} catch (caughtError) {
|
|
203
185
|
control = caughtError;
|
|
204
186
|
}
|
|
205
|
-
|
|
206
|
-
component.call(ThrowingConstructor.prototype);
|
|
187
|
+
Function.prototype.apply.call(component, ThrowingConstructor.prototype, []);
|
|
207
188
|
}
|
|
208
189
|
} else {
|
|
209
190
|
try {
|
|
@@ -211,22 +192,17 @@ const describeNativeComponentFrame = (
|
|
|
211
192
|
} catch (caughtError) {
|
|
212
193
|
control = caughtError;
|
|
213
194
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
// TODO: Implement component stacks for async client components?
|
|
223
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-promises -- we literally check if this is a promise here
|
|
224
|
-
if (maybePromise && typeof maybePromise.catch === "function") {
|
|
225
|
-
maybePromise.catch(() => {});
|
|
195
|
+
const maybePromise = Function.prototype.apply.call(component, undefined, []);
|
|
196
|
+
if (
|
|
197
|
+
typeof maybePromise === "object" &&
|
|
198
|
+
maybePromise !== null &&
|
|
199
|
+
"catch" in maybePromise &&
|
|
200
|
+
typeof maybePromise.catch === "function"
|
|
201
|
+
) {
|
|
202
|
+
maybePromise.catch(() => undefined);
|
|
226
203
|
}
|
|
227
204
|
}
|
|
228
205
|
} catch (sample: unknown) {
|
|
229
|
-
// This is inlined manually because closure doesn't do it for us.
|
|
230
206
|
if (
|
|
231
207
|
sample instanceof Error &&
|
|
232
208
|
control instanceof Error &&
|
|
@@ -239,21 +215,18 @@ const describeNativeComponentFrame = (
|
|
|
239
215
|
},
|
|
240
216
|
};
|
|
241
217
|
|
|
242
|
-
|
|
243
|
-
|
|
218
|
+
Object.defineProperty(RunInRootFrame.DetermineComponentFrameRoot, "displayName", {
|
|
219
|
+
value: "DetermineComponentFrameRoot",
|
|
220
|
+
});
|
|
244
221
|
const namePropDescriptor = Object.getOwnPropertyDescriptor(
|
|
245
222
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
246
223
|
RunInRootFrame.DetermineComponentFrameRoot,
|
|
247
224
|
"name",
|
|
248
225
|
);
|
|
249
|
-
// Before ES6, the `name` property was not configurable.
|
|
250
226
|
if (namePropDescriptor?.configurable) {
|
|
251
|
-
// V8 utilizes a function's `name` property when generating a stack trace.
|
|
252
227
|
Object.defineProperty(
|
|
253
228
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
254
229
|
RunInRootFrame.DetermineComponentFrameRoot,
|
|
255
|
-
// Configurable properties can be updated even if its writable descriptor
|
|
256
|
-
// is set to `false`.
|
|
257
230
|
"name",
|
|
258
231
|
{ value: "DetermineComponentFrameRoot" },
|
|
259
232
|
);
|
|
@@ -338,9 +311,9 @@ const describeNativeComponentFrame = (
|
|
|
338
311
|
} finally {
|
|
339
312
|
reEntry = false;
|
|
340
313
|
|
|
341
|
-
|
|
314
|
+
setPrepareStackTrace(previousPrepareStackTrace);
|
|
342
315
|
|
|
343
|
-
|
|
316
|
+
restoreRendererDispatchers(dispatcherSnapshots);
|
|
344
317
|
console.error = previousConsoleError;
|
|
345
318
|
console.warn = previousConsoleWarn;
|
|
346
319
|
}
|
|
@@ -353,35 +326,34 @@ const describeNativeComponentFrame = (
|
|
|
353
326
|
|
|
354
327
|
// https://github.com/facebook/react/blob/ac3e705a18696168acfcaed39dce0cfaa6be8836/packages/react-reconciler/src/ReactFiberComponentStack.js#L180
|
|
355
328
|
export const describeFiber = (fiber: Fiber, childFiber: Fiber | null): string => {
|
|
356
|
-
const tag = fiber.tag as number;
|
|
357
329
|
let stackFrame = "";
|
|
358
|
-
|
|
359
|
-
|
|
330
|
+
const workTags = getReactWorkTagsForFiber(fiber);
|
|
331
|
+
switch (fiber.tag) {
|
|
332
|
+
case workTags.ActivityComponent:
|
|
360
333
|
stackFrame = describeBuiltInComponentFrame("Activity");
|
|
361
334
|
break;
|
|
362
|
-
case
|
|
335
|
+
case workTags.ClassComponent:
|
|
363
336
|
stackFrame = describeNativeComponentFrame(fiber.type, true);
|
|
364
337
|
break;
|
|
365
|
-
case
|
|
366
|
-
stackFrame = describeNativeComponentFrame(
|
|
367
|
-
(fiber.type as { render: React.ComponentType<unknown> }).render,
|
|
368
|
-
false,
|
|
369
|
-
);
|
|
338
|
+
case workTags.ForwardRef:
|
|
339
|
+
stackFrame = describeNativeComponentFrame(getType(fiber.type) ?? fiber.type, false);
|
|
370
340
|
break;
|
|
371
|
-
case
|
|
372
|
-
case
|
|
341
|
+
case workTags.FunctionComponent:
|
|
342
|
+
case workTags.SimpleMemoComponent:
|
|
373
343
|
stackFrame = describeNativeComponentFrame(fiber.type, false);
|
|
374
344
|
break;
|
|
375
|
-
case
|
|
376
|
-
case
|
|
377
|
-
case
|
|
378
|
-
|
|
345
|
+
case workTags.HostComponent:
|
|
346
|
+
case workTags.HostHoistable:
|
|
347
|
+
case workTags.HostSingleton:
|
|
348
|
+
if (typeof fiber.type === "string") {
|
|
349
|
+
stackFrame = describeBuiltInComponentFrame(fiber.type);
|
|
350
|
+
}
|
|
379
351
|
break;
|
|
380
|
-
case
|
|
352
|
+
case workTags.LazyComponent:
|
|
381
353
|
// TODO: When we support Thenables as component types we should rename this.
|
|
382
354
|
stackFrame = describeBuiltInComponentFrame("Lazy");
|
|
383
355
|
break;
|
|
384
|
-
case
|
|
356
|
+
case workTags.SuspenseComponent:
|
|
385
357
|
if (fiber.child !== childFiber && childFiber !== null) {
|
|
386
358
|
// If we came from the second Fiber then we're in the Suspense Fallback.
|
|
387
359
|
stackFrame = describeBuiltInComponentFrame("Suspense Fallback");
|
|
@@ -389,10 +361,10 @@ export const describeFiber = (fiber: Fiber, childFiber: Fiber | null): string =>
|
|
|
389
361
|
stackFrame = describeBuiltInComponentFrame("Suspense");
|
|
390
362
|
}
|
|
391
363
|
break;
|
|
392
|
-
case
|
|
364
|
+
case workTags.SuspenseListComponent:
|
|
393
365
|
stackFrame = describeBuiltInComponentFrame("SuspenseList");
|
|
394
366
|
break;
|
|
395
|
-
case
|
|
367
|
+
case workTags.ViewTransitionComponent:
|
|
396
368
|
// Note: enableViewTransition feature flag is not available in this codebase,
|
|
397
369
|
// so we'll always include ViewTransition
|
|
398
370
|
stackFrame = describeBuiltInComponentFrame("ViewTransition");
|
|
@@ -421,8 +393,8 @@ export const getFallbackParentStack = (thisFiber: Fiber): string => {
|
|
|
421
393
|
// Since we don't have __DEV__ in this codebase, we'll check for _debugInfo
|
|
422
394
|
const debugInfo = currentFiber._debugInfo;
|
|
423
395
|
if (debugInfo && Array.isArray(debugInfo)) {
|
|
424
|
-
for (let
|
|
425
|
-
const debugEntry = debugInfo[
|
|
396
|
+
for (let debugInfoIndex = debugInfo.length - 1; debugInfoIndex >= 0; debugInfoIndex--) {
|
|
397
|
+
const debugEntry = debugInfo[debugInfoIndex];
|
|
426
398
|
if (typeof debugEntry.name === "string") {
|
|
427
399
|
componentStack += describeDebugInfoFrame(debugEntry.name, debugEntry.env);
|
|
428
400
|
}
|
|
@@ -460,14 +432,10 @@ export const getFallbackParentStack = (thisFiber: Fiber): string => {
|
|
|
460
432
|
* @see https://github.com/facebook/react/blob/main/packages/react-devtools-shared/src/backend/shared/DevToolsOwnerStack.js#L12
|
|
461
433
|
*/
|
|
462
434
|
export const formatOwnerStack = (stack: string): string => {
|
|
463
|
-
const prevPrepareStackTrace = Error.prepareStackTrace;
|
|
464
|
-
// HACK: V8 API allows undefined but bun-types declares it as non-optional
|
|
465
|
-
(Error as { prepareStackTrace?: typeof Error.prepareStackTrace }).prepareStackTrace = undefined;
|
|
466
435
|
let formattedStack = stack;
|
|
467
436
|
if (!formattedStack) {
|
|
468
437
|
return "";
|
|
469
438
|
}
|
|
470
|
-
Error.prepareStackTrace = prevPrepareStackTrace;
|
|
471
439
|
|
|
472
440
|
if (formattedStack.startsWith("Error: react-stack-top-frame\n")) {
|
|
473
441
|
// V8's default formatting prefixes with the error message which we
|
|
@@ -660,7 +628,9 @@ export const getParentStack = async (
|
|
|
660
628
|
const enrichedStackFrames = fallbackStackFrames.map((stackFrame): StackFrame => {
|
|
661
629
|
const isServerFrame =
|
|
662
630
|
(stackFrame.source?.includes(SERVER_FRAME_MARKER) ?? false) ||
|
|
663
|
-
(stackFrame.source
|
|
631
|
+
(stackFrame.source !== null &&
|
|
632
|
+
stackFrame.source !== undefined &&
|
|
633
|
+
SERVER_ENV_PATTERN.test(stackFrame.source));
|
|
664
634
|
|
|
665
635
|
if (isServerFrame) {
|
|
666
636
|
return getEnrichedServerStackFrame(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JSX_FACTORY_FRAME_COUNT, REACT_STACK_BOTTOM_FRAME_PATTERNS } from "./constants.js";
|
|
2
|
+
import { getPrepareStackTrace, setPrepareStackTrace } from "./error-stack.js";
|
|
2
3
|
import { parseStack, StackFrame } from "./parse-stack.js";
|
|
3
4
|
|
|
4
5
|
interface V8CallSite {
|
|
@@ -117,14 +118,13 @@ export const parseDebugStack = (debugStack: Error): ParsedDebugStack => {
|
|
|
117
118
|
}
|
|
118
119
|
return stackString;
|
|
119
120
|
};
|
|
120
|
-
const previousPrepareStackTrace =
|
|
121
|
-
|
|
122
|
-
Error.prepareStackTrace = collectFramesAndFormatStack as typeof Error.prepareStackTrace;
|
|
121
|
+
const previousPrepareStackTrace = getPrepareStackTrace();
|
|
122
|
+
setPrepareStackTrace(collectFramesAndFormatStack);
|
|
123
123
|
let stackString: string;
|
|
124
124
|
try {
|
|
125
125
|
stackString = String(debugStack.stack);
|
|
126
126
|
} finally {
|
|
127
|
-
|
|
127
|
+
setPrepareStackTrace(previousPrepareStackTrace);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
const result = structuredResult ?? parseMaterializedStack(stackString);
|
|
@@ -67,7 +67,7 @@ export const extractLocation = (
|
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
const applySlice = <T>(lines: T[], options?: ParseOptions): T[] => {
|
|
70
|
-
if (options && options.slice
|
|
70
|
+
if (options && options.slice !== null && options.slice !== undefined) {
|
|
71
71
|
if (Array.isArray(options.slice)) return lines.slice(options.slice[0], options.slice[1]);
|
|
72
72
|
return lines.slice(0, options.slice);
|
|
73
73
|
}
|