@office-iss/react-native-win32 0.74.4 → 0.75.0-preview.2
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/.flowconfig +9 -4
- package/CHANGELOG.json +569 -51
- package/CHANGELOG.md +173 -30
- package/Libraries/Animated/AnimatedImplementation.js +2 -0
- package/Libraries/Animated/NativeAnimatedHelper.js +4 -0
- package/Libraries/Animated/NativeAnimatedHelper.win32.js +4 -0
- package/Libraries/Animated/createAnimatedComponent.js +10 -4
- package/Libraries/Animated/useAnimatedProps.js +56 -28
- package/Libraries/BatchedBridge/MessageQueue.js +1 -0
- package/Libraries/Components/Button.js +10 -5
- package/Libraries/Components/Button.win32.js +1 -0
- package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +11 -2
- package/Libraries/Components/Pressable/Pressable.js +13 -6
- package/Libraries/Components/Pressable/Pressable.win32.js +13 -6
- package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +4 -0
- package/Libraries/Components/ScrollView/ScrollView.js +109 -29
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +6 -0
- package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +13 -1
- package/Libraries/Components/StatusBar/StatusBar.js +1 -21
- package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +0 -15
- package/Libraries/Components/TextInput/InputAccessoryView.js +10 -1
- package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +0 -12
- package/Libraries/Components/TextInput/TextInput.d.ts +0 -19
- package/Libraries/Components/TextInput/TextInput.js +14 -70
- package/Libraries/Components/TextInput/TextInput.win32.js +15 -72
- package/Libraries/Components/Touchable/Touchable.js +2 -2
- package/Libraries/Components/Touchable/TouchableHighlight.d.ts +4 -10
- package/Libraries/Components/Touchable/TouchableHighlight.js +3 -1
- package/Libraries/Components/Touchable/TouchableOpacity.d.ts +4 -32
- package/Libraries/Components/Touchable/TouchableOpacity.js +3 -1
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.d.ts +8 -0
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +117 -111
- package/Libraries/Components/View/ReactNativeStyleAttributes.js +6 -0
- package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -0
- package/Libraries/Components/View/ReactNativeViewAttributes.win32.js +1 -0
- package/Libraries/Components/View/View.js +0 -11
- package/Libraries/Components/View/View.win32.js +0 -11
- package/Libraries/Components/View/ViewAccessibility.js +4 -4
- package/Libraries/Components/View/ViewAccessibility.win32.js +6 -6
- package/Libraries/Components/View/ViewPropTypes.d.ts +7 -49
- package/Libraries/Components/View/ViewPropTypes.js +7 -0
- package/Libraries/Components/View/ViewPropTypes.win32.js +7 -0
- package/Libraries/Core/Devtools/loadBundleFromServer.js +3 -3
- package/Libraries/Core/Devtools/loadBundleFromServer.win32.js +153 -0
- package/Libraries/Core/Devtools/parseErrorStack.js +5 -5
- package/Libraries/Core/Devtools/parseHermesStack.js +22 -16
- package/Libraries/Core/ErrorHandlers.js +116 -0
- package/Libraries/Core/ExceptionsManager.js +2 -2
- package/Libraries/Core/ReactNativeVersion.js +3 -3
- package/Libraries/Core/setUpDeveloperTools.js +3 -1
- package/Libraries/Core/setUpPerformance.js +6 -4
- package/Libraries/Core/setUpReactDevTools.js +70 -10
- package/Libraries/Core/setUpTimers.js +50 -31
- package/Libraries/Debugging/DebuggingOverlayRegistry.js +1 -1
- package/Libraries/Image/Image.android.js +23 -13
- package/Libraries/Image/Image.d.ts +14 -15
- package/Libraries/Image/Image.ios.js +21 -11
- package/Libraries/Image/Image.win32.js +5 -3
- package/Libraries/Image/ImageProps.js +16 -5
- package/Libraries/Image/ImageTypes.flow.js +7 -2
- package/Libraries/Image/ImageUtils.js +1 -0
- package/Libraries/Image/ImageViewNativeComponent.js +2 -1
- package/Libraries/Inspector/ElementBox.js +6 -3
- package/Libraries/Inspector/ElementProperties.js +1 -1
- package/Libraries/Interaction/TouchHistoryMath.js +4 -4
- package/Libraries/IntersectionObserver/IntersectionObserverManager.js +6 -26
- package/Libraries/JSInspector/NetworkAgent.js +1 -1
- package/Libraries/LogBox/Data/LogBoxData.js +39 -29
- package/Libraries/LogBox/Data/LogBoxLog.js +114 -2
- package/Libraries/LogBox/Data/parseLogBoxLog.js +168 -53
- package/Libraries/LogBox/LogBox.js +29 -12
- package/Libraries/LogBox/LogBoxNotificationContainer.js +4 -0
- package/Libraries/LogBox/UI/LogBoxInspector.js +8 -70
- package/Libraries/LogBox/UI/LogBoxInspectorBody.js +87 -0
- package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +6 -42
- package/Libraries/LogBox/UI/LogBoxInspectorFooterButton.js +58 -0
- package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +5 -66
- package/Libraries/LogBox/UI/LogBoxInspectorHeader.win32.js +8 -52
- package/Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js +76 -0
- package/Libraries/LogBox/UI/LogBoxInspectorReactFrames.js +8 -5
- package/Libraries/LogBox/UI/LogBoxInspectorReactFrames.win32.js +8 -5
- package/Libraries/LogBox/UI/LogBoxNotification.js +13 -152
- package/Libraries/LogBox/UI/LogBoxNotificationCountBadge.js +63 -0
- package/Libraries/LogBox/UI/LogBoxNotificationDismissButton.js +67 -0
- package/Libraries/LogBox/UI/LogBoxNotificationMessage.js +57 -0
- package/Libraries/NativeComponent/BaseViewConfig.android.js +5 -0
- package/Libraries/NativeComponent/BaseViewConfig.ios.js +5 -0
- package/Libraries/NativeComponent/BaseViewConfig.win32.js +5 -0
- package/Libraries/NativeComponent/NativeComponentRegistry.js +12 -5
- package/Libraries/NativeComponent/StaticViewConfigValidator.js +3 -0
- package/Libraries/Network/XMLHttpRequest.js +5 -1
- package/Libraries/NewAppScreen/components/LearnMoreLinks.js +3 -3
- package/Libraries/Pressability/Pressability.js +3 -51
- package/Libraries/Pressability/Pressability.win32.js +3 -51
- package/Libraries/ReactNative/AppContainer-dev.js +3 -2
- package/Libraries/ReactNative/AppContainer-prod.js +2 -1
- package/Libraries/ReactNative/AppContainer.js +2 -0
- package/Libraries/ReactNative/AppRegistry.d.ts +7 -0
- package/Libraries/ReactNative/AppRegistry.js +10 -4
- package/Libraries/ReactNative/BridgelessUIManager.js +1 -21
- package/Libraries/ReactNative/FabricUIManager.js +0 -51
- package/Libraries/ReactNative/ReactFabricPublicInstance/warnForStyleProps.js +1 -0
- package/Libraries/ReactNative/RendererImplementation.js +20 -2
- package/Libraries/ReactNative/UIManager.d.ts +0 -21
- package/Libraries/ReactNative/UIManagerProperties.js +0 -3
- package/Libraries/ReactNative/__mocks__/FabricUIManager.js +5 -341
- package/Libraries/ReactNative/getNativeComponentAttributes.js +8 -8
- package/Libraries/ReactNative/renderApplication.js +3 -0
- package/Libraries/Renderer/implementations/ReactFabric-dev.js +15682 -27088
- package/Libraries/Renderer/implementations/ReactFabric-prod.js +5082 -4381
- package/Libraries/Renderer/implementations/ReactFabric-profiling.js +3480 -2571
- package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +15943 -27543
- package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +5303 -4606
- package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +3450 -2572
- package/Libraries/Renderer/shims/ReactFabric.js +2 -2
- package/Libraries/Renderer/shims/ReactFeatureFlags.js +2 -2
- package/Libraries/Renderer/shims/ReactNative.js +2 -3
- package/Libraries/Renderer/shims/ReactNativeTypes.js +24 -3
- package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +2 -2
- package/Libraries/Renderer/shims/createReactNativeComponentClass.js +2 -2
- package/Libraries/Share/Share.d.ts +16 -10
- package/Libraries/Share/Share.js +14 -15
- package/Libraries/StyleSheet/StyleSheet.d.ts +1 -1
- package/Libraries/StyleSheet/StyleSheet.js +3 -10
- package/Libraries/StyleSheet/StyleSheet.win32.js +3 -10
- package/Libraries/StyleSheet/StyleSheetTypes.d.ts +21 -21
- package/Libraries/StyleSheet/StyleSheetTypes.js +24 -18
- package/Libraries/StyleSheet/flattenStyle.js +1 -0
- package/Libraries/StyleSheet/processFilter.js +132 -0
- package/Libraries/StyleSheet/processTransform.js +18 -3
- package/Libraries/Text/Text.js +151 -128
- package/Libraries/Text/Text.win32.js +163 -138
- package/Libraries/Text/TextNativeComponent.js +5 -4
- package/Libraries/Text/TextNativeComponent.win32.js +5 -4
- package/Libraries/Text/TextProps.js +6 -6
- package/Libraries/Text/TextProps.win32.js +6 -6
- package/Libraries/TurboModule/TurboModuleRegistry.js +2 -1
- package/Libraries/Types/CodegenTypes.js +3 -0
- package/Libraries/Utilities/{LoadingView.android.js → DevLoadingView.js} +33 -11
- package/Libraries/Utilities/Dimensions.js +1 -0
- package/Libraries/Utilities/Dimensions.win32.js +1 -0
- package/Libraries/Utilities/HMRClient.js +36 -8
- package/Libraries/Utilities/HMRClientProdShim.js +1 -0
- package/Libraries/Utilities/Platform.android.js +5 -5
- package/Libraries/Utilities/Platform.d.ts +1 -1
- package/Libraries/Utilities/Platform.flow.js +2 -2
- package/Libraries/Utilities/Platform.flow.win32.js +3 -3
- package/Libraries/Utilities/Platform.ios.js +1 -1
- package/Libraries/Utilities/Platform.win32.js +1 -1
- package/Libraries/Utilities/RCTLog.js +1 -0
- package/Libraries/Utilities/ReactNativeTestTools.js +12 -24
- package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +11 -6
- package/Libraries/__tests__/ButtonWin32-test.js +7 -6
- package/Libraries/promiseRejectionTrackingOptions.js +1 -0
- package/jest/mockComponent.js +7 -0
- package/jest/renderer.js +25 -14
- package/jest/setup.js +19 -13
- package/jest.config.js +2 -1
- package/overrides.json +32 -31
- package/package.json +27 -25
- package/rn-get-polyfills.js +1 -0
- package/src/private/core/composeStyles.js +27 -0
- package/src/private/featureflags/ReactNativeFeatureFlags.js +93 -33
- package/src/private/featureflags/ReactNativeFeatureFlagsBase.js +23 -4
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +56 -0
- package/src/private/fusebox/setUpFuseboxReactDevToolsDispatcher.js +108 -0
- package/src/private/specs/modules/NativeBlobModule.js +4 -2
- package/src/private/specs/modules/NativeDevSettings.js +1 -0
- package/src/private/specs/modules/NativePlatformConstantsAndroid.js +1 -1
- package/src/private/specs/modules/NativePlatformConstantsIOS.js +1 -1
- package/src/private/specs/modules/NativePlatformConstantsWin.js +1 -1
- package/src/private/specs/modules/NativePushNotificationManagerIOS.js +0 -4
- package/src/private/specs/modules/NativeUIManager.js +0 -7
- package/src/private/webapis/dom/geometry/DOMRectReadOnly.js +24 -24
- package/src/private/webapis/dom/nodes/ReactNativeElement.js +11 -14
- package/src/private/webapis/dom/nodes/ReadOnlyCharacterData.js +2 -3
- package/src/private/webapis/dom/nodes/ReadOnlyElement.js +24 -54
- package/src/private/webapis/dom/nodes/ReadOnlyNode.js +5 -13
- package/src/private/webapis/dom/nodes/specs/NativeDOM.js +468 -0
- package/src/private/webapis/dom/nodes/specs/__mocks__/NativeDOMMock.js +413 -0
- package/src/private/webapis/dom/oldstylecollections/DOMRectList.js +4 -4
- package/src/private/webapis/dom/oldstylecollections/HTMLCollection.js +4 -4
- package/src/private/webapis/dom/oldstylecollections/NodeList.js +5 -5
- package/src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks.js +34 -0
- package/src/private/webapis/microtasks/specs/NativeMicrotasks.js +21 -0
- package/src/private/webapis/performance/EventCounts.js +1 -1
- package/src/private/webapis/performance/MemoryInfo.js +9 -9
- package/src/private/webapis/performance/Performance.js +10 -56
- package/src/private/webapis/performance/PerformanceObserver.js +30 -22
- package/src/private/webapis/performance/RawPerformanceEntry.js +2 -7
- package/src/private/webapis/performance/ReactNativeStartupTiming.js +18 -18
- package/src/private/webapis/performance/UserTiming.js +63 -0
- package/src/private/webapis/performance/{NativePerformance.js → specs/NativePerformance.js} +3 -2
- package/src/private/webapis/performance/{NativePerformanceObserver.js → specs/NativePerformanceObserver.js} +2 -2
- package/src/private/webapis/performance/{__mocks__ → specs/__mocks__}/NativePerformance.js +1 -1
- package/src/private/webapis/performance/{__mocks__ → specs/__mocks__}/NativePerformanceObserver.js +3 -4
- package/src-win/Libraries/Components/View/ViewPropTypes.d.ts +7 -49
- package/types/modules/globals.d.ts +4 -0
- package/Libraries/Components/ScrollView/ScrollView.win32.js +0 -1915
- package/Libraries/NativeModules/specs/NativeAnimationsDebugModule.js +0 -13
- package/Libraries/Utilities/LoadingView.ios.js +0 -50
- package/Libraries/Utilities/LoadingView.js +0 -16
- package/jest/ReactNativeInternalFeatureFlagsMock.js +0 -13
- package/src/private/featureflags/NativeReactNativeFeatureFlags.js +0 -44
- package/src/private/featureflags/__tests__/ReactNativeFeatureFlags-test.js +0 -92
- package/src/private/specs/modules/NativeAnimationsDebugModule.js +0 -20
- package/src/private/webapis/dom/oldstylecollections/__tests__/DOMRectList-test.js +0 -85
- package/src/private/webapis/dom/oldstylecollections/__tests__/HTMLCollection-test.js +0 -80
- package/src/private/webapis/dom/oldstylecollections/__tests__/NodeList-test.js +0 -161
- package/src/private/webapis/performance/__tests__/EventCounts-test.js +0 -116
- package/src/private/webapis/performance/__tests__/NativePerformanceMock-test.js +0 -82
- package/src/private/webapis/performance/__tests__/NativePerformanceObserverMock-test.js +0 -108
- package/src/private/webapis/performance/__tests__/Performance-test.js +0 -117
- package/src/private/webapis/performance/__tests__/PerformanceObserver-test.js +0 -208
|
@@ -8,30 +8,32 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
('use strict');
|
|
12
|
-
|
|
13
11
|
import type {ExtendedError} from '../../Core/ExtendedError';
|
|
14
12
|
import type {LogLevel} from './LogBoxLog';
|
|
15
13
|
import type {
|
|
16
14
|
Category,
|
|
17
15
|
ComponentStack,
|
|
16
|
+
ComponentStackType,
|
|
18
17
|
ExtendedExceptionData,
|
|
19
18
|
Message,
|
|
20
19
|
} from './parseLogBoxLog';
|
|
21
20
|
|
|
22
21
|
import parseErrorStack from '../../Core/Devtools/parseErrorStack';
|
|
22
|
+
import NativeDevSettings from '../../NativeModules/specs/NativeDevSettings';
|
|
23
23
|
import NativeLogBox from '../../NativeModules/specs/NativeLogBox';
|
|
24
24
|
import LogBoxLog from './LogBoxLog';
|
|
25
25
|
import {parseLogBoxException} from './parseLogBoxLog';
|
|
26
26
|
import * as React from 'react';
|
|
27
|
+
|
|
27
28
|
export type LogBoxLogs = Set<LogBoxLog>;
|
|
28
|
-
export type LogData = $ReadOnly<{
|
|
29
|
+
export type LogData = $ReadOnly<{
|
|
29
30
|
level: LogLevel,
|
|
30
31
|
message: Message,
|
|
31
32
|
category: Category,
|
|
32
33
|
componentStack: ComponentStack,
|
|
34
|
+
componentStackType: ComponentStackType | null,
|
|
33
35
|
stack?: string,
|
|
34
|
-
|
|
36
|
+
}>;
|
|
35
37
|
|
|
36
38
|
export type Observer = (
|
|
37
39
|
$ReadOnly<{|
|
|
@@ -72,6 +74,7 @@ let logs: LogBoxLogs = new Set();
|
|
|
72
74
|
let updateTimeout: $FlowFixMe | null = null;
|
|
73
75
|
let _isDisabled = false;
|
|
74
76
|
let _selectedIndex = -1;
|
|
77
|
+
let hasShownFuseboxWarningsMigrationMessage = false;
|
|
75
78
|
|
|
76
79
|
let warningFilter: WarningFilter = function (format) {
|
|
77
80
|
return {
|
|
@@ -193,6 +196,11 @@ function appendNewLog(newLog: LogBoxLog) {
|
|
|
193
196
|
}
|
|
194
197
|
|
|
195
198
|
export function addLog(log: LogData): void {
|
|
199
|
+
if (log.level === 'warn' && global.__FUSEBOX_HAS_FULL_CONSOLE_SUPPORT__) {
|
|
200
|
+
// Under Fusebox, don't report warnings to LogBox.
|
|
201
|
+
showFuseboxWarningsMigrationMessageOnce();
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
196
204
|
const errorForStackTrace = new Error();
|
|
197
205
|
|
|
198
206
|
// Parsing logs are expensive so we schedule this
|
|
@@ -209,6 +217,7 @@ export function addLog(log: LogData): void {
|
|
|
209
217
|
stack,
|
|
210
218
|
category: log.category,
|
|
211
219
|
componentStack: log.componentStack,
|
|
220
|
+
componentStackType: log.componentStackType || 'legacy',
|
|
212
221
|
}),
|
|
213
222
|
);
|
|
214
223
|
} catch (error) {
|
|
@@ -449,32 +458,33 @@ export function withSubscription(
|
|
|
449
458
|
this._subscription.unsubscribe();
|
|
450
459
|
}
|
|
451
460
|
}
|
|
452
|
-
|
|
453
|
-
_handleDismiss = (): void => {
|
|
454
|
-
// Here we handle the cases when the log is dismissed and it
|
|
455
|
-
// was either the last log, or when the current index
|
|
456
|
-
// is now outside the bounds of the log array.
|
|
457
|
-
const {selectedLogIndex, logs: stateLogs} = this.state;
|
|
458
|
-
const logsArray = Array.from(stateLogs);
|
|
459
|
-
if (selectedLogIndex != null) {
|
|
460
|
-
if (logsArray.length - 1 <= 0) {
|
|
461
|
-
setSelectedLog(-1);
|
|
462
|
-
} else if (selectedLogIndex >= logsArray.length - 1) {
|
|
463
|
-
setSelectedLog(selectedLogIndex - 1);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
dismiss(logsArray[selectedLogIndex]);
|
|
467
|
-
}
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
_handleMinimize = (): void => {
|
|
471
|
-
setSelectedLog(-1);
|
|
472
|
-
};
|
|
473
|
-
|
|
474
|
-
_handleSetSelectedLog = (index: number): void => {
|
|
475
|
-
setSelectedLog(index);
|
|
476
|
-
};
|
|
477
461
|
}
|
|
478
462
|
|
|
479
463
|
return LogBoxStateSubscription;
|
|
480
464
|
}
|
|
465
|
+
|
|
466
|
+
function showFuseboxWarningsMigrationMessageOnce() {
|
|
467
|
+
if (hasShownFuseboxWarningsMigrationMessage) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
hasShownFuseboxWarningsMigrationMessage = true;
|
|
471
|
+
appendNewLog(
|
|
472
|
+
new LogBoxLog({
|
|
473
|
+
level: 'warn',
|
|
474
|
+
message: {
|
|
475
|
+
content: 'Open debugger to view warnings.',
|
|
476
|
+
substitutions: [],
|
|
477
|
+
},
|
|
478
|
+
isComponentError: false,
|
|
479
|
+
stack: [],
|
|
480
|
+
category: 'fusebox-warnings-migration',
|
|
481
|
+
componentStack: [],
|
|
482
|
+
onNotificationPress: () => {
|
|
483
|
+
if (NativeDevSettings.openDebugger) {
|
|
484
|
+
NativeDevSettings.openDebugger();
|
|
485
|
+
}
|
|
486
|
+
clearWarnings();
|
|
487
|
+
},
|
|
488
|
+
}),
|
|
489
|
+
);
|
|
490
|
+
}
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
Category,
|
|
14
14
|
CodeFrame,
|
|
15
15
|
ComponentStack,
|
|
16
|
+
ComponentStackType,
|
|
16
17
|
Message,
|
|
17
18
|
} from './parseLogBoxLog';
|
|
18
19
|
|
|
@@ -22,23 +23,58 @@ type SymbolicationStatus = 'NONE' | 'PENDING' | 'COMPLETE' | 'FAILED';
|
|
|
22
23
|
|
|
23
24
|
export type LogLevel = 'warn' | 'error' | 'fatal' | 'syntax';
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
// TODO: once component stacks are fully supported, we can refactor
|
|
27
|
+
// ComponentStack to just be Stack and remove these conversions fns.
|
|
28
|
+
function convertComponentStateToStack(componentStack: ComponentStack): Stack {
|
|
29
|
+
return componentStack.map(frame => ({
|
|
30
|
+
column: frame?.location?.column,
|
|
31
|
+
file: frame.fileName,
|
|
32
|
+
lineNumber: frame?.location?.row,
|
|
33
|
+
methodName: frame.content,
|
|
34
|
+
collapse: false,
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function convertStackToComponentStack(stack: Stack): ComponentStack {
|
|
39
|
+
const componentStack = [];
|
|
40
|
+
for (let i = 0; i < stack.length; i++) {
|
|
41
|
+
const frame = stack[i];
|
|
42
|
+
// NOTE: Skip stack frames missing location.
|
|
43
|
+
if (frame.lineNumber != null && frame.column != null) {
|
|
44
|
+
componentStack.push({
|
|
45
|
+
fileName: frame?.file || '',
|
|
46
|
+
location: {
|
|
47
|
+
row: frame.lineNumber,
|
|
48
|
+
column: frame.column,
|
|
49
|
+
},
|
|
50
|
+
content: frame.methodName,
|
|
51
|
+
collapse: false,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return componentStack;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type LogBoxLogData = $ReadOnly<{
|
|
26
59
|
level: LogLevel,
|
|
27
60
|
type?: ?string,
|
|
28
61
|
message: Message,
|
|
29
62
|
stack: Stack,
|
|
30
63
|
category: string,
|
|
64
|
+
componentStackType?: ComponentStackType,
|
|
31
65
|
componentStack: ComponentStack,
|
|
32
66
|
codeFrame?: ?CodeFrame,
|
|
33
67
|
isComponentError: boolean,
|
|
34
68
|
extraData?: mixed,
|
|
35
|
-
|
|
69
|
+
onNotificationPress?: ?() => void,
|
|
70
|
+
}>;
|
|
36
71
|
|
|
37
72
|
class LogBoxLog {
|
|
38
73
|
message: Message;
|
|
39
74
|
type: ?string;
|
|
40
75
|
category: Category;
|
|
41
76
|
componentStack: ComponentStack;
|
|
77
|
+
componentStackType: ComponentStackType;
|
|
42
78
|
stack: Stack;
|
|
43
79
|
count: number;
|
|
44
80
|
level: LogLevel;
|
|
@@ -54,6 +90,20 @@ class LogBoxLog {
|
|
|
54
90
|
stack: null,
|
|
55
91
|
status: 'NONE',
|
|
56
92
|
};
|
|
93
|
+
symbolicatedComponentStack:
|
|
94
|
+
| $ReadOnly<{|error: null, componentStack: null, status: 'NONE'|}>
|
|
95
|
+
| $ReadOnly<{|error: null, componentStack: null, status: 'PENDING'|}>
|
|
96
|
+
| $ReadOnly<{|
|
|
97
|
+
error: null,
|
|
98
|
+
componentStack: ComponentStack,
|
|
99
|
+
status: 'COMPLETE',
|
|
100
|
+
|}>
|
|
101
|
+
| $ReadOnly<{|error: Error, componentStack: null, status: 'FAILED'|}> = {
|
|
102
|
+
error: null,
|
|
103
|
+
componentStack: null,
|
|
104
|
+
status: 'NONE',
|
|
105
|
+
};
|
|
106
|
+
onNotificationPress: ?() => void;
|
|
57
107
|
|
|
58
108
|
constructor(data: LogBoxLogData) {
|
|
59
109
|
this.level = data.level;
|
|
@@ -62,10 +112,12 @@ class LogBoxLog {
|
|
|
62
112
|
this.stack = data.stack;
|
|
63
113
|
this.category = data.category;
|
|
64
114
|
this.componentStack = data.componentStack;
|
|
115
|
+
this.componentStackType = data.componentStackType || 'legacy';
|
|
65
116
|
this.codeFrame = data.codeFrame;
|
|
66
117
|
this.isComponentError = data.isComponentError;
|
|
67
118
|
this.extraData = data.extraData;
|
|
68
119
|
this.count = 1;
|
|
120
|
+
this.onNotificationPress = data.onNotificationPress;
|
|
69
121
|
}
|
|
70
122
|
|
|
71
123
|
incrementCount(): void {
|
|
@@ -78,6 +130,15 @@ class LogBoxLog {
|
|
|
78
130
|
: this.stack;
|
|
79
131
|
}
|
|
80
132
|
|
|
133
|
+
getAvailableComponentStack(): ComponentStack {
|
|
134
|
+
if (this.componentStackType === 'legacy') {
|
|
135
|
+
return this.componentStack;
|
|
136
|
+
}
|
|
137
|
+
return this.symbolicatedComponentStack.status === 'COMPLETE'
|
|
138
|
+
? this.symbolicatedComponentStack.componentStack
|
|
139
|
+
: this.componentStack;
|
|
140
|
+
}
|
|
141
|
+
|
|
81
142
|
retrySymbolicate(callback?: (status: SymbolicationStatus) => void): void {
|
|
82
143
|
if (this.symbolicated.status !== 'COMPLETE') {
|
|
83
144
|
LogBoxSymbolication.deleteStack(this.stack);
|
|
@@ -102,6 +163,25 @@ class LogBoxLog {
|
|
|
102
163
|
this.updateStatus(error, null, null, callback);
|
|
103
164
|
},
|
|
104
165
|
);
|
|
166
|
+
if (this.componentStack != null && this.componentStackType === 'stack') {
|
|
167
|
+
this.updateComponentStackStatus(null, null, null, callback);
|
|
168
|
+
const componentStackFrames = convertComponentStateToStack(
|
|
169
|
+
this.componentStack,
|
|
170
|
+
);
|
|
171
|
+
LogBoxSymbolication.symbolicate(componentStackFrames, []).then(
|
|
172
|
+
data => {
|
|
173
|
+
this.updateComponentStackStatus(
|
|
174
|
+
null,
|
|
175
|
+
convertStackToComponentStack(data.stack),
|
|
176
|
+
null,
|
|
177
|
+
callback,
|
|
178
|
+
);
|
|
179
|
+
},
|
|
180
|
+
error => {
|
|
181
|
+
this.updateComponentStackStatus(error, null, null, callback);
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
}
|
|
105
185
|
}
|
|
106
186
|
}
|
|
107
187
|
|
|
@@ -140,6 +220,38 @@ class LogBoxLog {
|
|
|
140
220
|
callback(this.symbolicated.status);
|
|
141
221
|
}
|
|
142
222
|
}
|
|
223
|
+
|
|
224
|
+
updateComponentStackStatus(
|
|
225
|
+
error: ?Error,
|
|
226
|
+
componentStack: ?ComponentStack,
|
|
227
|
+
codeFrame: ?CodeFrame,
|
|
228
|
+
callback?: (status: SymbolicationStatus) => void,
|
|
229
|
+
): void {
|
|
230
|
+
const lastStatus = this.symbolicatedComponentStack.status;
|
|
231
|
+
if (error != null) {
|
|
232
|
+
this.symbolicatedComponentStack = {
|
|
233
|
+
error,
|
|
234
|
+
componentStack: null,
|
|
235
|
+
status: 'FAILED',
|
|
236
|
+
};
|
|
237
|
+
} else if (componentStack != null) {
|
|
238
|
+
this.symbolicatedComponentStack = {
|
|
239
|
+
error: null,
|
|
240
|
+
componentStack,
|
|
241
|
+
status: 'COMPLETE',
|
|
242
|
+
};
|
|
243
|
+
} else {
|
|
244
|
+
this.symbolicatedComponentStack = {
|
|
245
|
+
error: null,
|
|
246
|
+
componentStack: null,
|
|
247
|
+
status: 'PENDING',
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (callback && lastStatus !== this.symbolicatedComponentStack.status) {
|
|
252
|
+
callback(this.symbolicatedComponentStack.status);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
143
255
|
}
|
|
144
256
|
|
|
145
257
|
export default LogBoxLog;
|
|
@@ -18,11 +18,62 @@ import ansiRegex from 'ansi-regex';
|
|
|
18
18
|
|
|
19
19
|
const ANSI_REGEX = ansiRegex().source;
|
|
20
20
|
|
|
21
|
-
const
|
|
21
|
+
const RE_TRANSFORM_ERROR = /^TransformError /;
|
|
22
|
+
const RE_COMPONENT_STACK_LINE = /\n {4}(in|at) /;
|
|
23
|
+
const RE_COMPONENT_STACK_LINE_GLOBAL = /\n {4}(in|at) /g;
|
|
24
|
+
const RE_COMPONENT_STACK_LINE_OLD = / {4}in/;
|
|
25
|
+
const RE_COMPONENT_STACK_LINE_NEW = / {4}at/;
|
|
26
|
+
const RE_COMPONENT_STACK_LINE_STACK_FRAME = /@.*\n/;
|
|
27
|
+
|
|
28
|
+
// "TransformError " (Optional) and either "SyntaxError: " or "ReferenceError: "
|
|
29
|
+
// Capturing groups:
|
|
30
|
+
// 1: error message
|
|
31
|
+
// 2: file path
|
|
32
|
+
// 3: line number
|
|
33
|
+
// 4: column number
|
|
34
|
+
// \n\n
|
|
35
|
+
// 5: code frame
|
|
36
|
+
const RE_BABEL_TRANSFORM_ERROR_FORMAT =
|
|
22
37
|
/^(?:TransformError )?(?:SyntaxError: |ReferenceError: )(.*): (.*) \((\d+):(\d+)\)\n\n([\s\S]+)/;
|
|
23
38
|
|
|
39
|
+
// Capturing groups:
|
|
40
|
+
// 1: component name
|
|
41
|
+
// "at"
|
|
42
|
+
// 2: file path including extension
|
|
43
|
+
// 3: line number
|
|
44
|
+
const RE_COMPONENT_STACK_WITH_SOURCE =
|
|
45
|
+
/(.*) \(at (.*\.(?:js|jsx|ts|tsx)):([\d]+)\)/;
|
|
46
|
+
|
|
47
|
+
// Capturing groups:
|
|
48
|
+
// 1: component name
|
|
49
|
+
// "at"
|
|
50
|
+
// 2: parent component name
|
|
51
|
+
const RE_COMPONENT_STACK_NO_SOURCE = /(.*) \(created by .*\)/;
|
|
52
|
+
|
|
53
|
+
// Capturing groups:
|
|
54
|
+
// - non-capturing "TransformError " (optional)
|
|
55
|
+
// - non-capturing Error message
|
|
56
|
+
// 1: file path
|
|
57
|
+
// 2: file name
|
|
58
|
+
// 3: error message
|
|
59
|
+
// 4: code frame, which includes code snippet indicators or terminal escape sequences for formatting.
|
|
60
|
+
const RE_BABEL_CODE_FRAME_ERROR_FORMAT =
|
|
61
|
+
// eslint-disable-next-line no-control-regex
|
|
62
|
+
/^(?:TransformError )?(?:.*):? (?:.*?)(\/.*): ([\s\S]+?)\n([ >]{2}[\d\s]+ \|[\s\S]+|\u{001b}[\s\S]+)/u;
|
|
63
|
+
|
|
64
|
+
// Capturing groups:
|
|
65
|
+
// - non-capturing "InternalError Metro has encountered an error:"
|
|
66
|
+
// 1: error title
|
|
67
|
+
// 2: error message
|
|
68
|
+
// 3: file path
|
|
69
|
+
// 4: line number
|
|
70
|
+
// 5: column number
|
|
71
|
+
// 6: code frame, which includes code snippet indicators or terminal escape sequences for formatting.
|
|
72
|
+
const RE_METRO_ERROR_FORMAT =
|
|
73
|
+
/^(?:InternalError Metro has encountered an error:) (.*): (.*) \((\d+):(\d+)\)\n\n([\s\S]+)/u;
|
|
74
|
+
|
|
24
75
|
// https://github.com/babel/babel/blob/33dbb85e9e9fe36915273080ecc42aee62ed0ade/packages/babel-code-frame/src/index.ts#L183-L184
|
|
25
|
-
const
|
|
76
|
+
const RE_BABEL_CODE_FRAME_MARKER_PATTERN = new RegExp(
|
|
26
77
|
[
|
|
27
78
|
// Beginning of a line (per 'm' flag)
|
|
28
79
|
'^',
|
|
@@ -42,12 +93,14 @@ const BABEL_CODE_FRAME_MARKER_PATTERN = new RegExp(
|
|
|
42
93
|
'm',
|
|
43
94
|
);
|
|
44
95
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
96
|
+
export function hasComponentStack(args: $ReadOnlyArray<mixed>): boolean {
|
|
97
|
+
for (const arg of args) {
|
|
98
|
+
if (typeof arg === 'string' && isComponentStack(arg)) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
51
104
|
|
|
52
105
|
export type ExtendedExceptionData = ExceptionData & {
|
|
53
106
|
isComponentError: boolean,
|
|
@@ -79,6 +132,7 @@ export type Message = $ReadOnly<{|
|
|
|
79
132
|
|}>;
|
|
80
133
|
|
|
81
134
|
export type ComponentStack = $ReadOnlyArray<CodeFrame>;
|
|
135
|
+
export type ComponentStackType = 'legacy' | 'stack';
|
|
82
136
|
|
|
83
137
|
const SUBSTITUTION = UTFSequence.BOM + '%s';
|
|
84
138
|
|
|
@@ -158,9 +212,12 @@ export function parseInterpolation(args: $ReadOnlyArray<mixed>): $ReadOnly<{|
|
|
|
158
212
|
}
|
|
159
213
|
|
|
160
214
|
function isComponentStack(consoleArgument: string) {
|
|
161
|
-
const isOldComponentStackFormat =
|
|
162
|
-
|
|
163
|
-
const
|
|
215
|
+
const isOldComponentStackFormat =
|
|
216
|
+
RE_COMPONENT_STACK_LINE_OLD.test(consoleArgument);
|
|
217
|
+
const isNewComponentStackFormat =
|
|
218
|
+
RE_COMPONENT_STACK_LINE_NEW.test(consoleArgument);
|
|
219
|
+
const isNewJSCComponentStackFormat =
|
|
220
|
+
RE_COMPONENT_STACK_LINE_STACK_FRAME.test(consoleArgument);
|
|
164
221
|
|
|
165
222
|
return (
|
|
166
223
|
isOldComponentStackFormat ||
|
|
@@ -169,42 +226,62 @@ function isComponentStack(consoleArgument: string) {
|
|
|
169
226
|
);
|
|
170
227
|
}
|
|
171
228
|
|
|
172
|
-
export function parseComponentStack(message: string):
|
|
229
|
+
export function parseComponentStack(message: string): {
|
|
230
|
+
type: ComponentStackType,
|
|
231
|
+
stack: ComponentStack,
|
|
232
|
+
} {
|
|
173
233
|
// In newer versions of React, the component stack is formatted as a call stack frame.
|
|
174
234
|
// First try to parse the component stack as a call stack frame, and if that doesn't
|
|
175
235
|
// work then we'll fallback to the old custom component stack format parsing.
|
|
176
236
|
const stack = parseErrorStack(message);
|
|
177
237
|
if (stack && stack.length > 0) {
|
|
178
|
-
return
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
238
|
+
return {
|
|
239
|
+
type: 'stack',
|
|
240
|
+
stack: stack.map(frame => ({
|
|
241
|
+
content: frame.methodName,
|
|
242
|
+
collapse: frame.collapse || false,
|
|
243
|
+
fileName: frame.file == null ? 'unknown' : frame.file,
|
|
244
|
+
location: {
|
|
245
|
+
column: frame.column == null ? -1 : frame.column,
|
|
246
|
+
row: frame.lineNumber == null ? -1 : frame.lineNumber,
|
|
247
|
+
},
|
|
248
|
+
})),
|
|
249
|
+
};
|
|
187
250
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
.split(/\n {4}in /g)
|
|
251
|
+
const legacyStack = message
|
|
252
|
+
.split(RE_COMPONENT_STACK_LINE_GLOBAL)
|
|
191
253
|
.map(s => {
|
|
192
254
|
if (!s) {
|
|
193
255
|
return null;
|
|
194
256
|
}
|
|
195
|
-
const match = s.match(
|
|
196
|
-
if (
|
|
197
|
-
|
|
257
|
+
const match = s.match(RE_COMPONENT_STACK_WITH_SOURCE);
|
|
258
|
+
if (match) {
|
|
259
|
+
let [content, fileName, row] = match.slice(1);
|
|
260
|
+
return {
|
|
261
|
+
content,
|
|
262
|
+
fileName,
|
|
263
|
+
location: {column: -1, row: parseInt(row, 10)},
|
|
264
|
+
};
|
|
198
265
|
}
|
|
199
266
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
267
|
+
// In some cases, the component stack doesn't have a source.
|
|
268
|
+
const matchWithoutSource = s.match(RE_COMPONENT_STACK_NO_SOURCE);
|
|
269
|
+
if (matchWithoutSource) {
|
|
270
|
+
return {
|
|
271
|
+
content: matchWithoutSource[1],
|
|
272
|
+
fileName: '',
|
|
273
|
+
location: null,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return null;
|
|
206
278
|
})
|
|
207
279
|
.filter(Boolean);
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
type: 'legacy',
|
|
283
|
+
stack: legacyStack,
|
|
284
|
+
};
|
|
208
285
|
}
|
|
209
286
|
|
|
210
287
|
export function parseLogBoxException(
|
|
@@ -213,7 +290,7 @@ export function parseLogBoxException(
|
|
|
213
290
|
const message =
|
|
214
291
|
error.originalMessage != null ? error.originalMessage : 'Unknown';
|
|
215
292
|
|
|
216
|
-
const metroInternalError = message.match(
|
|
293
|
+
const metroInternalError = message.match(RE_METRO_ERROR_FORMAT);
|
|
217
294
|
if (metroInternalError) {
|
|
218
295
|
const [content, fileName, row, column, codeFrame] =
|
|
219
296
|
metroInternalError.slice(1);
|
|
@@ -223,6 +300,7 @@ export function parseLogBoxException(
|
|
|
223
300
|
type: 'Metro Error',
|
|
224
301
|
stack: [],
|
|
225
302
|
isComponentError: false,
|
|
303
|
+
componentStackType: 'legacy',
|
|
226
304
|
componentStack: [],
|
|
227
305
|
codeFrame: {
|
|
228
306
|
fileName,
|
|
@@ -241,7 +319,7 @@ export function parseLogBoxException(
|
|
|
241
319
|
};
|
|
242
320
|
}
|
|
243
321
|
|
|
244
|
-
const babelTransformError = message.match(
|
|
322
|
+
const babelTransformError = message.match(RE_BABEL_TRANSFORM_ERROR_FORMAT);
|
|
245
323
|
if (babelTransformError) {
|
|
246
324
|
// Transform errors are thrown from inside the Babel transformer.
|
|
247
325
|
const [fileName, content, row, column, codeFrame] =
|
|
@@ -251,6 +329,7 @@ export function parseLogBoxException(
|
|
|
251
329
|
level: 'syntax',
|
|
252
330
|
stack: [],
|
|
253
331
|
isComponentError: false,
|
|
332
|
+
componentStackType: 'legacy',
|
|
254
333
|
componentStack: [],
|
|
255
334
|
codeFrame: {
|
|
256
335
|
fileName,
|
|
@@ -271,8 +350,8 @@ export function parseLogBoxException(
|
|
|
271
350
|
|
|
272
351
|
// Perform a cheap match first before trying to parse the full message, which
|
|
273
352
|
// can get expensive for arbitrary input.
|
|
274
|
-
if (
|
|
275
|
-
const babelCodeFrameError = message.match(
|
|
353
|
+
if (RE_BABEL_CODE_FRAME_MARKER_PATTERN.test(message)) {
|
|
354
|
+
const babelCodeFrameError = message.match(RE_BABEL_CODE_FRAME_ERROR_FORMAT);
|
|
276
355
|
|
|
277
356
|
if (babelCodeFrameError) {
|
|
278
357
|
// Codeframe errors are thrown from any use of buildCodeFrameError.
|
|
@@ -281,6 +360,7 @@ export function parseLogBoxException(
|
|
|
281
360
|
level: 'syntax',
|
|
282
361
|
stack: [],
|
|
283
362
|
isComponentError: false,
|
|
363
|
+
componentStackType: 'legacy',
|
|
284
364
|
componentStack: [],
|
|
285
365
|
codeFrame: {
|
|
286
366
|
fileName,
|
|
@@ -297,11 +377,12 @@ export function parseLogBoxException(
|
|
|
297
377
|
}
|
|
298
378
|
}
|
|
299
379
|
|
|
300
|
-
if (message.match(
|
|
380
|
+
if (message.match(RE_TRANSFORM_ERROR)) {
|
|
301
381
|
return {
|
|
302
382
|
level: 'syntax',
|
|
303
383
|
stack: error.stack,
|
|
304
384
|
isComponentError: error.isComponentError,
|
|
385
|
+
componentStackType: 'legacy',
|
|
305
386
|
componentStack: [],
|
|
306
387
|
message: {
|
|
307
388
|
content: message,
|
|
@@ -314,24 +395,39 @@ export function parseLogBoxException(
|
|
|
314
395
|
|
|
315
396
|
const componentStack = error.componentStack;
|
|
316
397
|
if (error.isFatal || error.isComponentError) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
398
|
+
if (componentStack != null) {
|
|
399
|
+
const {type, stack} = parseComponentStack(componentStack);
|
|
400
|
+
return {
|
|
401
|
+
level: 'fatal',
|
|
402
|
+
stack: error.stack,
|
|
403
|
+
isComponentError: error.isComponentError,
|
|
404
|
+
componentStackType: type,
|
|
405
|
+
componentStack: stack,
|
|
406
|
+
extraData: error.extraData,
|
|
407
|
+
...parseInterpolation([message]),
|
|
408
|
+
};
|
|
409
|
+
} else {
|
|
410
|
+
return {
|
|
411
|
+
level: 'fatal',
|
|
412
|
+
stack: error.stack,
|
|
413
|
+
isComponentError: error.isComponentError,
|
|
414
|
+
componentStackType: 'legacy',
|
|
415
|
+
componentStack: [],
|
|
416
|
+
extraData: error.extraData,
|
|
417
|
+
...parseInterpolation([message]),
|
|
418
|
+
};
|
|
419
|
+
}
|
|
326
420
|
}
|
|
327
421
|
|
|
328
422
|
if (componentStack != null) {
|
|
329
423
|
// It is possible that console errors have a componentStack.
|
|
424
|
+
const {type, stack} = parseComponentStack(componentStack);
|
|
330
425
|
return {
|
|
331
426
|
level: 'error',
|
|
332
427
|
stack: error.stack,
|
|
333
428
|
isComponentError: error.isComponentError,
|
|
334
|
-
|
|
429
|
+
componentStackType: type,
|
|
430
|
+
componentStack: stack,
|
|
335
431
|
extraData: error.extraData,
|
|
336
432
|
...parseInterpolation([message]),
|
|
337
433
|
};
|
|
@@ -348,14 +444,28 @@ export function parseLogBoxException(
|
|
|
348
444
|
};
|
|
349
445
|
}
|
|
350
446
|
|
|
447
|
+
export function withoutANSIColorStyles(message: mixed): mixed {
|
|
448
|
+
if (typeof message !== 'string') {
|
|
449
|
+
return message;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
return message.replace(
|
|
453
|
+
// eslint-disable-next-line no-control-regex
|
|
454
|
+
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
|
|
455
|
+
'',
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
|
|
351
459
|
export function parseLogBoxLog(args: $ReadOnlyArray<mixed>): {|
|
|
352
460
|
componentStack: ComponentStack,
|
|
461
|
+
componentStackType: ComponentStackType,
|
|
353
462
|
category: Category,
|
|
354
463
|
message: Message,
|
|
355
464
|
|} {
|
|
356
|
-
const message = args[0];
|
|
465
|
+
const message = withoutANSIColorStyles(args[0]);
|
|
357
466
|
let argsWithoutComponentStack: Array<mixed> = [];
|
|
358
467
|
let componentStack: ComponentStack = [];
|
|
468
|
+
let componentStackType = 'legacy';
|
|
359
469
|
|
|
360
470
|
// Extract component stack from warnings like "Some warning%s".
|
|
361
471
|
if (
|
|
@@ -367,16 +477,18 @@ export function parseLogBoxLog(args: $ReadOnlyArray<mixed>): {|
|
|
|
367
477
|
if (typeof lastArg === 'string' && isComponentStack(lastArg)) {
|
|
368
478
|
argsWithoutComponentStack = args.slice(0, -1);
|
|
369
479
|
argsWithoutComponentStack[0] = message.slice(0, -2);
|
|
370
|
-
|
|
480
|
+
const {type, stack} = parseComponentStack(lastArg);
|
|
481
|
+
componentStack = stack;
|
|
482
|
+
componentStackType = type;
|
|
371
483
|
}
|
|
372
484
|
}
|
|
373
485
|
|
|
374
|
-
if (componentStack.length === 0) {
|
|
486
|
+
if (componentStack.length === 0 && argsWithoutComponentStack.length === 0) {
|
|
375
487
|
// Try finding the component stack elsewhere.
|
|
376
488
|
for (const arg of args) {
|
|
377
489
|
if (typeof arg === 'string' && isComponentStack(arg)) {
|
|
378
490
|
// Strip out any messages before the component stack.
|
|
379
|
-
let messageEndIndex = arg.search(
|
|
491
|
+
let messageEndIndex = arg.search(RE_COMPONENT_STACK_LINE);
|
|
380
492
|
if (messageEndIndex < 0) {
|
|
381
493
|
// Handle JSC component stacks.
|
|
382
494
|
messageEndIndex = arg.search(/\n/);
|
|
@@ -385,7 +497,9 @@ export function parseLogBoxLog(args: $ReadOnlyArray<mixed>): {|
|
|
|
385
497
|
argsWithoutComponentStack.push(arg.slice(0, messageEndIndex));
|
|
386
498
|
}
|
|
387
499
|
|
|
388
|
-
|
|
500
|
+
const {type, stack} = parseComponentStack(arg);
|
|
501
|
+
componentStack = stack;
|
|
502
|
+
componentStackType = type;
|
|
389
503
|
} else {
|
|
390
504
|
argsWithoutComponentStack.push(arg);
|
|
391
505
|
}
|
|
@@ -395,5 +509,6 @@ export function parseLogBoxLog(args: $ReadOnlyArray<mixed>): {|
|
|
|
395
509
|
return {
|
|
396
510
|
...parseInterpolation(argsWithoutComponentStack),
|
|
397
511
|
componentStack,
|
|
512
|
+
componentStackType,
|
|
398
513
|
};
|
|
399
514
|
}
|