@expo/metro-runtime 3.0.0 → 3.0.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/build/HMRClient.js +43 -15
- package/build/HMRClient.js.map +1 -1
- package/build/HMRClient.native.js +3 -1
- package/build/HMRClient.native.js.map +1 -1
- package/build/LoadingView.d.ts +6 -0
- package/build/LoadingView.d.ts.map +1 -1
- package/build/LoadingView.js +12 -4
- package/build/LoadingView.js.map +1 -1
- package/build/LoadingView.native.js +7 -2
- package/build/LoadingView.native.js.map +1 -1
- package/build/async-require/buildAsyncRequire.js +7 -3
- package/build/async-require/buildAsyncRequire.js.map +1 -1
- package/build/async-require/buildUrlForBundle.js +5 -1
- package/build/async-require/buildUrlForBundle.js.map +1 -1
- package/build/async-require/buildUrlForBundle.native.js +5 -1
- package/build/async-require/buildUrlForBundle.native.js.map +1 -1
- package/build/async-require/fetchAsync.d.ts +6 -0
- package/build/async-require/fetchAsync.d.ts.map +1 -1
- package/build/async-require/fetchAsync.js +6 -3
- package/build/async-require/fetchAsync.js.map +1 -1
- package/build/async-require/fetchAsync.native.js +13 -6
- package/build/async-require/fetchAsync.native.js.map +1 -1
- package/build/async-require/fetchThenEval.d.ts +1 -6
- package/build/async-require/fetchThenEval.d.ts.map +1 -1
- package/build/async-require/fetchThenEval.js +5 -31
- package/build/async-require/fetchThenEval.js.map +1 -1
- package/build/async-require/fetchThenEval.web.js +6 -2
- package/build/async-require/fetchThenEval.web.js.map +1 -1
- package/build/async-require/fetchThenEvalJs.d.ts +7 -0
- package/build/async-require/fetchThenEvalJs.d.ts.map +1 -0
- package/build/async-require/fetchThenEvalJs.js +36 -0
- package/build/async-require/fetchThenEvalJs.js.map +1 -0
- package/build/async-require/index.js +4 -2
- package/build/async-require/index.js.map +1 -1
- package/build/async-require/index.native.d.ts +7 -0
- package/build/async-require/index.native.d.ts.map +1 -0
- package/build/async-require/index.native.js +14 -0
- package/build/async-require/index.native.js.map +1 -0
- package/build/async-require/loadBundle.js +10 -6
- package/build/async-require/loadBundle.js.map +1 -1
- package/build/effects.d.ts +0 -1
- package/build/effects.js +7 -10
- package/build/effects.js.map +1 -1
- package/build/error-overlay/Data/LogBoxData.d.ts.map +1 -1
- package/build/error-overlay/Data/LogBoxData.js +82 -33
- package/build/error-overlay/Data/LogBoxData.js.map +1 -1
- package/build/error-overlay/Data/LogBoxLog.js +29 -2
- package/build/error-overlay/Data/LogBoxLog.js.map +1 -1
- package/build/error-overlay/Data/LogBoxSymbolication.js +12 -4
- package/build/error-overlay/Data/LogBoxSymbolication.js.map +1 -1
- package/build/error-overlay/Data/LogContext.js +17 -9
- package/build/error-overlay/Data/LogContext.js.map +1 -1
- package/build/error-overlay/Data/parseLogBoxLog.d.ts.map +1 -1
- package/build/error-overlay/Data/parseLogBoxLog.js +20 -11
- package/build/error-overlay/Data/parseLogBoxLog.js.map +1 -1
- package/build/error-overlay/ErrorOverlay.d.ts.map +1 -1
- package/build/error-overlay/ErrorOverlay.js +73 -41
- package/build/error-overlay/ErrorOverlay.js.map +1 -1
- package/build/error-overlay/LogBox.js +3 -1
- package/build/error-overlay/LogBox.js.map +1 -1
- package/build/error-overlay/LogBox.web.d.ts.map +1 -1
- package/build/error-overlay/LogBox.web.js +4 -3
- package/build/error-overlay/LogBox.web.js.map +1 -1
- package/build/error-overlay/UI/AnsiHighlight.js +15 -8
- package/build/error-overlay/UI/AnsiHighlight.js.map +1 -1
- package/build/error-overlay/UI/LogBoxButton.js +35 -8
- package/build/error-overlay/UI/LogBoxButton.js.map +1 -1
- package/build/error-overlay/UI/LogBoxMessage.js +13 -6
- package/build/error-overlay/UI/LogBoxMessage.js.map +1 -1
- package/build/error-overlay/UI/LogBoxStyle.js +31 -14
- package/build/error-overlay/UI/LogBoxStyle.js.map +1 -1
- package/build/error-overlay/UI/constants.js +5 -2
- package/build/error-overlay/UI/constants.js.map +1 -1
- package/build/error-overlay/formatProjectFilePath.js +7 -2
- package/build/error-overlay/formatProjectFilePath.js.map +1 -1
- package/build/error-overlay/index.d.ts.map +1 -1
- package/build/error-overlay/index.js +19 -9
- package/build/error-overlay/index.js.map +1 -1
- package/build/error-overlay/modules/ExceptionsManager/index.js +8 -3
- package/build/error-overlay/modules/ExceptionsManager/index.js.map +1 -1
- package/build/error-overlay/modules/ExceptionsManager/index.native.js +7 -2
- package/build/error-overlay/modules/ExceptionsManager/index.native.js.map +1 -1
- package/build/error-overlay/modules/NativeLogBox/index.js +10 -5
- package/build/error-overlay/modules/NativeLogBox/index.js.map +1 -1
- package/build/error-overlay/modules/NativeLogBox/index.native.js +7 -2
- package/build/error-overlay/modules/NativeLogBox/index.native.js.map +1 -1
- package/build/error-overlay/modules/openFileInEditor/index.js +3 -1
- package/build/error-overlay/modules/openFileInEditor/index.js.map +1 -1
- package/build/error-overlay/modules/openFileInEditor/index.native.js +7 -2
- package/build/error-overlay/modules/openFileInEditor/index.native.js.map +1 -1
- package/build/error-overlay/modules/parseErrorStack/index.d.ts.map +1 -1
- package/build/error-overlay/modules/parseErrorStack/index.js +10 -7
- package/build/error-overlay/modules/parseErrorStack/index.js.map +1 -1
- package/build/error-overlay/modules/parseErrorStack/parseHermesStack.js +8 -2
- package/build/error-overlay/modules/parseErrorStack/parseHermesStack.js.map +1 -1
- package/build/error-overlay/modules/stringifySafe/index.js +6 -2
- package/build/error-overlay/modules/stringifySafe/index.js.map +1 -1
- package/build/error-overlay/modules/symbolicateStackTrace/index.js +3 -1
- package/build/error-overlay/modules/symbolicateStackTrace/index.js.map +1 -1
- package/build/error-overlay/modules/symbolicateStackTrace/index.native.js +7 -2
- package/build/error-overlay/modules/symbolicateStackTrace/index.native.js.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorCodeFrame.d.ts.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorCodeFrame.js +52 -22
- package/build/error-overlay/overlay/LogBoxInspectorCodeFrame.js.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorFooter.js +48 -18
- package/build/error-overlay/overlay/LogBoxInspectorFooter.js.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorHeader.js +53 -23
- package/build/error-overlay/overlay/LogBoxInspectorHeader.js.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorMessageHeader.js +43 -13
- package/build/error-overlay/overlay/LogBoxInspectorMessageHeader.js.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorSection.js +39 -9
- package/build/error-overlay/overlay/LogBoxInspectorSection.js.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorSourceMapStatus.js +41 -14
- package/build/error-overlay/overlay/LogBoxInspectorSourceMapStatus.js.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorStackFrame.js +44 -14
- package/build/error-overlay/overlay/LogBoxInspectorStackFrame.js.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorStackFrames.d.ts.map +1 -1
- package/build/error-overlay/overlay/LogBoxInspectorStackFrames.js +55 -24
- package/build/error-overlay/overlay/LogBoxInspectorStackFrames.js.map +1 -1
- package/build/error-overlay/toast/ErrorToast.d.ts.map +1 -1
- package/build/error-overlay/toast/ErrorToast.js +48 -21
- package/build/error-overlay/toast/ErrorToast.js.map +1 -1
- package/build/error-overlay/toast/ErrorToastContainer.js +9 -3
- package/build/error-overlay/toast/ErrorToastContainer.js.map +1 -1
- package/build/error-overlay/toast/ErrorToastContainer.web.d.ts.map +1 -1
- package/build/error-overlay/toast/ErrorToastContainer.web.js +49 -21
- package/build/error-overlay/toast/ErrorToastContainer.web.js.map +1 -1
- package/build/error-overlay/toast/ErrorToastMessage.js +37 -7
- package/build/error-overlay/toast/ErrorToastMessage.js.map +1 -1
- package/build/error-overlay/useRejectionHandler.js +16 -9
- package/build/error-overlay/useRejectionHandler.js.map +1 -1
- package/build/getDevServer.d.ts.map +1 -1
- package/build/getDevServer.js +10 -9
- package/build/getDevServer.js.map +1 -1
- package/build/getDevServer.native.js +7 -2
- package/build/getDevServer.native.js.map +1 -1
- package/build/index.d.ts +7 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +12 -8
- package/build/index.js.map +1 -1
- package/build/location/Location.js +7 -2
- package/build/location/Location.js.map +1 -1
- package/build/location/Location.native.js +12 -4
- package/build/location/Location.native.js.map +1 -1
- package/build/location/install.native.js +16 -11
- package/build/location/install.native.js.map +1 -1
- package/build/setupHMR.js +28 -26
- package/build/setupHMR.js.map +1 -1
- package/build/symbolicate.js +25 -4
- package/build/symbolicate.js.map +1 -1
- package/package.json +5 -2
- package/src/HMRClient.native.ts +3 -0
- package/src/HMRClient.ts +316 -0
- package/src/LoadingView.native.ts +3 -0
- package/src/LoadingView.ts +24 -0
- package/src/__mocks__/LoadingView.ts +4 -0
- package/src/async-require/buildAsyncRequire.ts +34 -0
- package/src/async-require/buildUrlForBundle.native.ts +28 -0
- package/src/async-require/buildUrlForBundle.ts +18 -0
- package/src/async-require/fetchAsync.native.ts +72 -0
- package/src/async-require/fetchAsync.ts +19 -0
- package/src/async-require/fetchThenEval.ts +1 -0
- package/src/async-require/fetchThenEval.web.ts +70 -0
- package/src/async-require/fetchThenEvalJs.ts +39 -0
- package/src/async-require/index.native.ts +15 -0
- package/src/async-require/index.ts +10 -0
- package/src/async-require/loadBundle.ts +46 -0
- package/src/effects.native.ts +0 -0
- package/src/effects.ts +11 -0
- package/src/error-overlay/Data/LogBoxData.tsx +438 -0
- package/src/error-overlay/Data/LogBoxLog.ts +221 -0
- package/src/error-overlay/Data/LogBoxSymbolication.tsx +64 -0
- package/src/error-overlay/Data/LogContext.tsx +41 -0
- package/src/error-overlay/Data/parseLogBoxLog.tsx +342 -0
- package/src/error-overlay/ErrorOverlay.tsx +191 -0
- package/src/error-overlay/LogBox.ts +51 -0
- package/src/error-overlay/LogBox.web.ts +174 -0
- package/src/error-overlay/UI/AnsiHighlight.tsx +96 -0
- package/src/error-overlay/UI/LogBoxButton.tsx +63 -0
- package/src/error-overlay/UI/LogBoxMessage.tsx +73 -0
- package/src/error-overlay/UI/LogBoxStyle.ts +64 -0
- package/src/error-overlay/UI/constants.ts +7 -0
- package/src/error-overlay/formatProjectFilePath.ts +38 -0
- package/src/error-overlay/index.tsx +34 -0
- package/src/error-overlay/modules/ExceptionsManager/index.native.ts +4 -0
- package/src/error-overlay/modules/ExceptionsManager/index.ts +82 -0
- package/src/error-overlay/modules/NativeLogBox/index.native.ts +3 -0
- package/src/error-overlay/modules/NativeLogBox/index.tsx +27 -0
- package/src/error-overlay/modules/openFileInEditor/index.native.ts +3 -0
- package/src/error-overlay/modules/openFileInEditor/index.ts +16 -0
- package/src/error-overlay/modules/parseErrorStack/index.ts +26 -0
- package/src/error-overlay/modules/parseErrorStack/parseHermesStack.ts +3 -0
- package/src/error-overlay/modules/stringifySafe/index.ts +115 -0
- package/src/error-overlay/modules/symbolicateStackTrace/index.native.ts +3 -0
- package/src/error-overlay/modules/symbolicateStackTrace/index.ts +39 -0
- package/src/error-overlay/overlay/LogBoxInspectorCodeFrame.tsx +102 -0
- package/src/error-overlay/overlay/LogBoxInspectorFooter.tsx +111 -0
- package/src/error-overlay/overlay/LogBoxInspectorHeader.tsx +167 -0
- package/src/error-overlay/overlay/LogBoxInspectorMessageHeader.tsx +116 -0
- package/src/error-overlay/overlay/LogBoxInspectorSection.tsx +52 -0
- package/src/error-overlay/overlay/LogBoxInspectorSourceMapStatus.tsx +125 -0
- package/src/error-overlay/overlay/LogBoxInspectorStackFrame.tsx +89 -0
- package/src/error-overlay/overlay/LogBoxInspectorStackFrames.tsx +201 -0
- package/src/error-overlay/toast/ErrorToast.tsx +167 -0
- package/src/error-overlay/toast/ErrorToastContainer.tsx +9 -0
- package/src/error-overlay/toast/ErrorToastContainer.web.tsx +92 -0
- package/src/error-overlay/toast/ErrorToastMessage.tsx +28 -0
- package/src/error-overlay/useRejectionHandler.ts +61 -0
- package/src/getDevServer.native.ts +3 -0
- package/src/getDevServer.ts +34 -0
- package/src/index.ts +12 -0
- package/src/location/Location.native.ts +201 -0
- package/src/location/Location.ts +3 -0
- package/src/location/install.native.ts +90 -0
- package/src/location/install.ts +0 -0
- package/src/messageSocket.ts +25 -0
- package/src/setupFastRefresh.ts +30 -0
- package/src/setupHMR.ts +28 -0
- package/src/symbolicate.ts +6 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 650 Industries.
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
import React, { useCallback, useMemo } from 'react';
|
|
9
|
+
import { StyleSheet, View } from 'react-native';
|
|
10
|
+
|
|
11
|
+
import { ErrorToast } from './ErrorToast';
|
|
12
|
+
import * as LogBoxData from '../Data/LogBoxData';
|
|
13
|
+
import { LogBoxLog } from '../Data/LogBoxLog';
|
|
14
|
+
import { useLogs } from '../Data/LogContext';
|
|
15
|
+
import { useRejectionHandler } from '../useRejectionHandler';
|
|
16
|
+
|
|
17
|
+
export function ErrorToastContainer() {
|
|
18
|
+
useRejectionHandler();
|
|
19
|
+
const { logs, isDisabled } = useLogs();
|
|
20
|
+
if (!logs.length || isDisabled) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return <ErrorToastStack logs={logs} />;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function ErrorToastStack({ logs }: { logs: LogBoxLog[] }) {
|
|
27
|
+
const onDismissWarns = useCallback(() => {
|
|
28
|
+
LogBoxData.clearWarnings();
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
const onDismissErrors = useCallback(() => {
|
|
32
|
+
LogBoxData.clearErrors();
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
const setSelectedLog = useCallback((index: number): void => {
|
|
36
|
+
LogBoxData.setSelectedLog(index);
|
|
37
|
+
}, []);
|
|
38
|
+
|
|
39
|
+
function openLog(log: LogBoxLog) {
|
|
40
|
+
let index = logs.length - 1;
|
|
41
|
+
|
|
42
|
+
// Stop at zero because if we don't find any log, we'll open the first log.
|
|
43
|
+
while (index > 0 && logs[index] !== log) {
|
|
44
|
+
index -= 1;
|
|
45
|
+
}
|
|
46
|
+
setSelectedLog(index);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const warnings = useMemo(() => logs.filter((log) => log.level === 'warn'), [logs]);
|
|
50
|
+
|
|
51
|
+
const errors = useMemo(
|
|
52
|
+
() => logs.filter((log) => log.level === 'error' || log.level === 'fatal'),
|
|
53
|
+
[logs]
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<View style={styles.list}>
|
|
58
|
+
{warnings.length > 0 && (
|
|
59
|
+
<ErrorToast
|
|
60
|
+
log={warnings[warnings.length - 1]}
|
|
61
|
+
level="warn"
|
|
62
|
+
totalLogCount={warnings.length}
|
|
63
|
+
onPressOpen={() => openLog(warnings[warnings.length - 1])}
|
|
64
|
+
onPressDismiss={onDismissWarns}
|
|
65
|
+
/>
|
|
66
|
+
)}
|
|
67
|
+
|
|
68
|
+
{errors.length > 0 && (
|
|
69
|
+
<ErrorToast
|
|
70
|
+
log={errors[errors.length - 1]}
|
|
71
|
+
level="error"
|
|
72
|
+
totalLogCount={errors.length}
|
|
73
|
+
onPressOpen={() => openLog(errors[errors.length - 1])}
|
|
74
|
+
onPressDismiss={onDismissErrors}
|
|
75
|
+
/>
|
|
76
|
+
)}
|
|
77
|
+
</View>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const styles = StyleSheet.create({
|
|
82
|
+
list: {
|
|
83
|
+
bottom: 6,
|
|
84
|
+
left: 10,
|
|
85
|
+
right: 10,
|
|
86
|
+
maxWidth: 320,
|
|
87
|
+
// @ts-expect-error
|
|
88
|
+
position: 'fixed',
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
export default LogBoxData.withSubscription(ErrorToastContainer);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet, Text } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { Message as MessageType } from '../Data/parseLogBoxLog';
|
|
5
|
+
import { LogBoxMessage } from '../UI/LogBoxMessage';
|
|
6
|
+
import * as LogBoxStyle from '../UI/LogBoxStyle';
|
|
7
|
+
|
|
8
|
+
export function ErrorToastMessage({ message }: { message?: MessageType }) {
|
|
9
|
+
return (
|
|
10
|
+
<Text numberOfLines={1} style={styles.text}>
|
|
11
|
+
{message && <LogBoxMessage plaintext message={message} style={styles.substitutionText} />}
|
|
12
|
+
</Text>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const styles = StyleSheet.create({
|
|
17
|
+
text: {
|
|
18
|
+
userSelect: 'none',
|
|
19
|
+
paddingLeft: 8,
|
|
20
|
+
color: LogBoxStyle.getTextColor(1),
|
|
21
|
+
flex: 1,
|
|
22
|
+
fontSize: 14,
|
|
23
|
+
lineHeight: 22,
|
|
24
|
+
},
|
|
25
|
+
substitutionText: {
|
|
26
|
+
color: LogBoxStyle.getTextColor(0.6),
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import ExceptionsManager from './modules/ExceptionsManager';
|
|
4
|
+
|
|
5
|
+
function useStackTraceLimit(limit: number) {
|
|
6
|
+
const current = React.useRef(0);
|
|
7
|
+
React.useEffect(() => {
|
|
8
|
+
try {
|
|
9
|
+
// @ts-expect-error: StackTraceLimit is not defined in the Error type
|
|
10
|
+
const currentLimit = Error.stackTraceLimit;
|
|
11
|
+
// @ts-expect-error: StackTraceLimit is not defined in the Error type
|
|
12
|
+
Error.stackTraceLimit = limit;
|
|
13
|
+
current.current = currentLimit;
|
|
14
|
+
} catch {}
|
|
15
|
+
return () => {
|
|
16
|
+
try {
|
|
17
|
+
// @ts-expect-error: StackTraceLimit is not defined in the Error type
|
|
18
|
+
Error.stackTraceLimit = current.current;
|
|
19
|
+
} catch {}
|
|
20
|
+
};
|
|
21
|
+
}, [limit]);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function useRejectionHandler() {
|
|
25
|
+
const hasError = React.useRef(false);
|
|
26
|
+
|
|
27
|
+
useStackTraceLimit(35);
|
|
28
|
+
|
|
29
|
+
React.useEffect(() => {
|
|
30
|
+
function onUnhandledError(ev: ErrorEvent) {
|
|
31
|
+
hasError.current = true;
|
|
32
|
+
|
|
33
|
+
const error = ev?.error;
|
|
34
|
+
if (!error || !(error instanceof Error) || typeof error.stack !== 'string') {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
ExceptionsManager.handleException(error);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function onUnhandledRejection(ev: PromiseRejectionEvent) {
|
|
42
|
+
hasError.current = true;
|
|
43
|
+
|
|
44
|
+
const reason = ev?.reason;
|
|
45
|
+
if (!reason || !(reason instanceof Error) || typeof reason.stack !== 'string') {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
ExceptionsManager.handleException(reason);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
window.addEventListener('unhandledrejection', onUnhandledRejection);
|
|
53
|
+
window.addEventListener('error', onUnhandledError);
|
|
54
|
+
return () => {
|
|
55
|
+
window.removeEventListener('error', onUnhandledError);
|
|
56
|
+
window.removeEventListener('unhandledrejection', onUnhandledRejection);
|
|
57
|
+
};
|
|
58
|
+
}, []);
|
|
59
|
+
|
|
60
|
+
return hasError;
|
|
61
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import qs from 'qs';
|
|
2
|
+
|
|
3
|
+
const getDevServer = () => {
|
|
4
|
+
// Disable for SSR
|
|
5
|
+
if (typeof window === 'undefined') {
|
|
6
|
+
return {
|
|
7
|
+
bundleLoadedFromServer: true,
|
|
8
|
+
fullBundleUrl: '',
|
|
9
|
+
url: '',
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
// The bundle is always loaded from a server in the browser.
|
|
15
|
+
bundleLoadedFromServer: true,
|
|
16
|
+
|
|
17
|
+
/** URL but ensures that platform query param is added. */
|
|
18
|
+
get fullBundleUrl() {
|
|
19
|
+
if (document?.currentScript && 'src' in document.currentScript) {
|
|
20
|
+
return document.currentScript.src;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const url = window.location.toString();
|
|
24
|
+
const query = qs.parse(url);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
location.origin + location.pathname + '?' + qs.stringify({ ...query, platform: 'web' })
|
|
28
|
+
);
|
|
29
|
+
},
|
|
30
|
+
url: location.origin + location.pathname,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default getDevServer;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2023 650 Industries.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import './location/install';
|
|
9
|
+
// IMPORT POSITION MATTERS FOR FAST REFRESH ON WEB
|
|
10
|
+
import './effects';
|
|
11
|
+
// vvv EVERYTHING ELSE vvv
|
|
12
|
+
import './async-require';
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// Copyright © 2023 650 Industries.
|
|
2
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
3
|
+
|
|
4
|
+
import URL from 'url-parse';
|
|
5
|
+
|
|
6
|
+
class DOMException extends Error {
|
|
7
|
+
constructor(message: string, name: string) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = name;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// The differences between the definitions of `Location` and `WorkerLocation`
|
|
14
|
+
// are because of the `LegacyUnforgeable` attribute only specified upon
|
|
15
|
+
// `Location`'s properties. See:
|
|
16
|
+
// - https://html.spec.whatwg.org/multipage/history.html#the-location-interface
|
|
17
|
+
// - https://heycam.github.io/webidl/#LegacyUnforgeable
|
|
18
|
+
class Location {
|
|
19
|
+
constructor(href: string | null = null) {
|
|
20
|
+
const url = new URL(
|
|
21
|
+
// @ts-expect-error
|
|
22
|
+
href
|
|
23
|
+
);
|
|
24
|
+
// @ts-expect-error
|
|
25
|
+
url.username = '';
|
|
26
|
+
// @ts-expect-error
|
|
27
|
+
url.password = '';
|
|
28
|
+
Object.defineProperties(this, {
|
|
29
|
+
hash: {
|
|
30
|
+
get() {
|
|
31
|
+
return url.hash;
|
|
32
|
+
},
|
|
33
|
+
set() {
|
|
34
|
+
throw new DOMException(`Cannot set "location.hash".`, 'NotSupportedError');
|
|
35
|
+
},
|
|
36
|
+
enumerable: true,
|
|
37
|
+
},
|
|
38
|
+
host: {
|
|
39
|
+
get() {
|
|
40
|
+
return url.host;
|
|
41
|
+
},
|
|
42
|
+
set() {
|
|
43
|
+
throw new DOMException(`Cannot set "location.host".`, 'NotSupportedError');
|
|
44
|
+
},
|
|
45
|
+
enumerable: true,
|
|
46
|
+
},
|
|
47
|
+
hostname: {
|
|
48
|
+
get() {
|
|
49
|
+
return url.hostname;
|
|
50
|
+
},
|
|
51
|
+
set() {
|
|
52
|
+
throw new DOMException(`Cannot set "location.hostname".`, 'NotSupportedError');
|
|
53
|
+
},
|
|
54
|
+
enumerable: true,
|
|
55
|
+
},
|
|
56
|
+
href: {
|
|
57
|
+
get() {
|
|
58
|
+
return url.href;
|
|
59
|
+
},
|
|
60
|
+
set() {
|
|
61
|
+
throw new DOMException(`Cannot set "location.href".`, 'NotSupportedError');
|
|
62
|
+
},
|
|
63
|
+
enumerable: true,
|
|
64
|
+
},
|
|
65
|
+
origin: {
|
|
66
|
+
get() {
|
|
67
|
+
return url.origin;
|
|
68
|
+
},
|
|
69
|
+
enumerable: true,
|
|
70
|
+
},
|
|
71
|
+
pathname: {
|
|
72
|
+
get() {
|
|
73
|
+
return url.pathname;
|
|
74
|
+
},
|
|
75
|
+
set() {
|
|
76
|
+
throw new DOMException(`Cannot set "location.pathname".`, 'NotSupportedError');
|
|
77
|
+
},
|
|
78
|
+
enumerable: true,
|
|
79
|
+
},
|
|
80
|
+
port: {
|
|
81
|
+
get() {
|
|
82
|
+
return url.port;
|
|
83
|
+
},
|
|
84
|
+
set() {
|
|
85
|
+
throw new DOMException(`Cannot set "location.port".`, 'NotSupportedError');
|
|
86
|
+
},
|
|
87
|
+
enumerable: true,
|
|
88
|
+
},
|
|
89
|
+
protocol: {
|
|
90
|
+
get() {
|
|
91
|
+
return url.protocol;
|
|
92
|
+
},
|
|
93
|
+
set() {
|
|
94
|
+
throw new DOMException(`Cannot set "location.protocol".`, 'NotSupportedError');
|
|
95
|
+
},
|
|
96
|
+
enumerable: true,
|
|
97
|
+
},
|
|
98
|
+
search: {
|
|
99
|
+
get() {
|
|
100
|
+
// @ts-expect-error
|
|
101
|
+
return url.search;
|
|
102
|
+
},
|
|
103
|
+
set() {
|
|
104
|
+
throw new DOMException(`Cannot set "location.search".`, 'NotSupportedError');
|
|
105
|
+
},
|
|
106
|
+
enumerable: true,
|
|
107
|
+
},
|
|
108
|
+
ancestorOrigins: {
|
|
109
|
+
get() {
|
|
110
|
+
return {
|
|
111
|
+
length: 0,
|
|
112
|
+
item: () => null,
|
|
113
|
+
contains: () => false,
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
enumerable: true,
|
|
117
|
+
},
|
|
118
|
+
assign: {
|
|
119
|
+
value: function assign() {
|
|
120
|
+
throw new DOMException(`Cannot call "location.assign()".`, 'NotSupportedError');
|
|
121
|
+
},
|
|
122
|
+
enumerable: true,
|
|
123
|
+
},
|
|
124
|
+
reload: {
|
|
125
|
+
value: function reload() {
|
|
126
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
127
|
+
// NOTE: This does change how native fast refresh works. The upstream metro-runtime will check
|
|
128
|
+
// if `location.reload` exists before falling back on an implementation that is nearly identical to
|
|
129
|
+
// this. The main difference is that on iOS there is a "reason" message sent, but at the time of writing
|
|
130
|
+
// this, that message is unused (ref: `RCTTriggerReloadCommandNotification`).
|
|
131
|
+
const DevSettings = (require('react-native') as typeof import('react-native'))
|
|
132
|
+
.DevSettings;
|
|
133
|
+
return DevSettings.reload();
|
|
134
|
+
} else {
|
|
135
|
+
throw new DOMException(`Cannot call "location.reload()".`, 'NotSupportedError');
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
enumerable: true,
|
|
139
|
+
},
|
|
140
|
+
replace: {
|
|
141
|
+
value: function replace() {
|
|
142
|
+
throw new DOMException(`Cannot call "location.replace()".`, 'NotSupportedError');
|
|
143
|
+
},
|
|
144
|
+
enumerable: true,
|
|
145
|
+
},
|
|
146
|
+
toString: {
|
|
147
|
+
value: function toString() {
|
|
148
|
+
return url.href;
|
|
149
|
+
},
|
|
150
|
+
enumerable: true,
|
|
151
|
+
},
|
|
152
|
+
[Symbol.for('Expo.privateCustomInspect')]: {
|
|
153
|
+
value(inspect: any) {
|
|
154
|
+
const object = {
|
|
155
|
+
hash: this.hash,
|
|
156
|
+
host: this.host,
|
|
157
|
+
hostname: this.hostname,
|
|
158
|
+
href: this.href,
|
|
159
|
+
origin: this.origin,
|
|
160
|
+
pathname: this.pathname,
|
|
161
|
+
port: this.port,
|
|
162
|
+
protocol: this.protocol,
|
|
163
|
+
search: this.search,
|
|
164
|
+
};
|
|
165
|
+
return `${this.constructor.name} ${inspect(object)}`;
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
Object.defineProperties(Location.prototype, {
|
|
173
|
+
[Symbol.toString()]: {
|
|
174
|
+
value: 'Location',
|
|
175
|
+
configurable: true,
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
let location: Location | undefined = undefined;
|
|
180
|
+
|
|
181
|
+
export function setLocationHref(href: string) {
|
|
182
|
+
location = new Location(href);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function install() {
|
|
186
|
+
Object.defineProperty(global, 'Location', {
|
|
187
|
+
value: Location,
|
|
188
|
+
configurable: true,
|
|
189
|
+
writable: true,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
Object.defineProperty(window, 'location', {
|
|
193
|
+
get() {
|
|
194
|
+
return location;
|
|
195
|
+
},
|
|
196
|
+
set() {
|
|
197
|
+
throw new DOMException(`Cannot set "location".`, 'NotSupportedError');
|
|
198
|
+
},
|
|
199
|
+
enumerable: true,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// This MUST be first to ensure that `fetch` is defined in the React Native environment.
|
|
2
|
+
import 'react-native/Libraries/Core/InitializeCore';
|
|
3
|
+
|
|
4
|
+
import Constants from 'expo-constants';
|
|
5
|
+
import URL from 'url-parse';
|
|
6
|
+
|
|
7
|
+
import { install, setLocationHref } from './Location';
|
|
8
|
+
import getDevServer from '../getDevServer';
|
|
9
|
+
|
|
10
|
+
let hasWarned = false;
|
|
11
|
+
|
|
12
|
+
const manifest = Constants.expoConfig as Record<string, any> | null;
|
|
13
|
+
|
|
14
|
+
// Add a development warning for fetch requests with relative paths
|
|
15
|
+
// to ensure developers are aware of the need to configure a production
|
|
16
|
+
// base URL in the Expo config (app.json) under `expo.extra.router.origin`.
|
|
17
|
+
function warnProductionOriginNotConfigured(requestUrl: string) {
|
|
18
|
+
if (hasWarned) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
hasWarned = true;
|
|
22
|
+
if (!manifest?.extra?.router?.origin) {
|
|
23
|
+
console.warn(
|
|
24
|
+
`The relative fetch request "${requestUrl}" will not work in production until the Expo Router Config Plugin (app.json) is configured with the \`origin\` prop set to the base URL of your web server, e.g. \`{ plugins: [["expo-router", { origin: "..." }]] }\`. [Learn more](https://expo.github.io/router/docs/lab/runtime-location)`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// TODO: This would be better if native and tied as close to the JS engine as possible, i.e. it should
|
|
30
|
+
// reflect the exact location of the JS file that was executed.
|
|
31
|
+
function getBaseUrl() {
|
|
32
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
33
|
+
// e.g. http://localhost:19006
|
|
34
|
+
return getDevServer().url?.replace(/\/$/, '');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// TODO: Make it official by moving out of `extra`
|
|
38
|
+
const productionBaseUrl = manifest?.extra?.router?.origin;
|
|
39
|
+
|
|
40
|
+
if (!productionBaseUrl) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Ensure no trailing slash
|
|
45
|
+
return productionBaseUrl?.replace(/\/$/, '');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function wrapFetchWithWindowLocation(fetch: Function & { __EXPO_BASE_URL_POLYFILLED?: boolean }) {
|
|
49
|
+
if (fetch.__EXPO_BASE_URL_POLYFILLED) {
|
|
50
|
+
return fetch;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const _fetch = (...props: any[]) => {
|
|
54
|
+
if (props[0] && typeof props[0] === 'string' && props[0].startsWith('/')) {
|
|
55
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
56
|
+
warnProductionOriginNotConfigured(props[0]);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
props[0] = new URL(props[0], window.location?.origin).toString();
|
|
60
|
+
} else if (props[0] && typeof props[0] === 'object') {
|
|
61
|
+
if (props[0].url && typeof props[0].url === 'string' && props[0].url.startsWith('/')) {
|
|
62
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
63
|
+
warnProductionOriginNotConfigured(props[0]);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
props[0].url = new URL(props[0].url, window.location?.origin).toString();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return fetch(...props);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
_fetch.__EXPO_BASE_URL_POLYFILLED = true;
|
|
73
|
+
|
|
74
|
+
return _fetch;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (manifest?.extra?.router?.origin !== false) {
|
|
78
|
+
// Polyfill window.location in native runtimes.
|
|
79
|
+
if (typeof window !== 'undefined' && !window.location) {
|
|
80
|
+
const url = getBaseUrl();
|
|
81
|
+
if (url) {
|
|
82
|
+
setLocationHref(url);
|
|
83
|
+
install();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Polyfill native fetch to support relative URLs
|
|
87
|
+
Object.defineProperty(global, 'fetch', {
|
|
88
|
+
value: wrapFetchWithWindowLocation(fetch),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* eslint-env browser */
|
|
2
|
+
|
|
3
|
+
// Setup websocket messages for reloading the page from the command line.
|
|
4
|
+
// This is normally setup on the native client.
|
|
5
|
+
|
|
6
|
+
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
|
|
7
|
+
const messageSocket = new WebSocket(`${protocol}://${window.location.host}/message`);
|
|
8
|
+
messageSocket.onmessage = (message) => {
|
|
9
|
+
const data = JSON.parse(String(message.data));
|
|
10
|
+
switch (data.method) {
|
|
11
|
+
case 'sendDevCommand':
|
|
12
|
+
switch (data.params.name) {
|
|
13
|
+
case 'reload':
|
|
14
|
+
window.location.reload();
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
break;
|
|
18
|
+
case 'reload':
|
|
19
|
+
window.location.reload();
|
|
20
|
+
break;
|
|
21
|
+
case 'devMenu':
|
|
22
|
+
// no-op
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// This needs to run before the renderer initializes.
|
|
2
|
+
|
|
3
|
+
const ReactRefreshRuntime = require('react-refresh/runtime');
|
|
4
|
+
ReactRefreshRuntime.injectIntoGlobalHook(global);
|
|
5
|
+
|
|
6
|
+
const Refresh = {
|
|
7
|
+
performFullRefresh() {
|
|
8
|
+
location.reload();
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
createSignatureFunctionForTransform: ReactRefreshRuntime.createSignatureFunctionForTransform,
|
|
12
|
+
|
|
13
|
+
isLikelyComponentType: ReactRefreshRuntime.isLikelyComponentType,
|
|
14
|
+
|
|
15
|
+
getFamilyByType: ReactRefreshRuntime.getFamilyByType,
|
|
16
|
+
|
|
17
|
+
register: ReactRefreshRuntime.register,
|
|
18
|
+
|
|
19
|
+
performReactRefresh() {
|
|
20
|
+
if (ReactRefreshRuntime.hasUnrecoverableErrors()) {
|
|
21
|
+
location.reload();
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
ReactRefreshRuntime.performReactRefresh();
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// The metro require polyfill can not have dependencies (applies for all polyfills).
|
|
29
|
+
// Expose `Refresh` by assigning it to global to make it available in the polyfill.
|
|
30
|
+
global[(global.__METRO_GLOBAL_PREFIX__ || '') + '__ReactRefresh'] = Refresh;
|
package/src/setupHMR.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import HMRClient from './HMRClient';
|
|
2
|
+
|
|
3
|
+
// Sets up developer tools for React Native web.
|
|
4
|
+
// We assume full control over the console and send JavaScript logs to Metro.
|
|
5
|
+
// [
|
|
6
|
+
// 'trace',
|
|
7
|
+
// 'info',
|
|
8
|
+
// 'warn',
|
|
9
|
+
// 'error',
|
|
10
|
+
// 'log',
|
|
11
|
+
// 'group',
|
|
12
|
+
// 'groupCollapsed',
|
|
13
|
+
// 'groupEnd',
|
|
14
|
+
// 'debug',
|
|
15
|
+
// ].forEach(level => {
|
|
16
|
+
// const originalFunction = console[level];
|
|
17
|
+
// console[level] = function (...args: readonly any[]) {
|
|
18
|
+
// HMRClient.log(
|
|
19
|
+
// // @ts-expect-error
|
|
20
|
+
// level, args);
|
|
21
|
+
// originalFunction.apply(console, args);
|
|
22
|
+
// };
|
|
23
|
+
// });
|
|
24
|
+
|
|
25
|
+
HMRClient.log('log', [`[web] Logs will appear in the browser console`]);
|
|
26
|
+
|
|
27
|
+
// This is called native on native platforms
|
|
28
|
+
HMRClient.setup({ isEnabled: true });
|