@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.
Files changed (219) hide show
  1. package/build/HMRClient.js +43 -15
  2. package/build/HMRClient.js.map +1 -1
  3. package/build/HMRClient.native.js +3 -1
  4. package/build/HMRClient.native.js.map +1 -1
  5. package/build/LoadingView.d.ts +6 -0
  6. package/build/LoadingView.d.ts.map +1 -1
  7. package/build/LoadingView.js +12 -4
  8. package/build/LoadingView.js.map +1 -1
  9. package/build/LoadingView.native.js +7 -2
  10. package/build/LoadingView.native.js.map +1 -1
  11. package/build/async-require/buildAsyncRequire.js +7 -3
  12. package/build/async-require/buildAsyncRequire.js.map +1 -1
  13. package/build/async-require/buildUrlForBundle.js +5 -1
  14. package/build/async-require/buildUrlForBundle.js.map +1 -1
  15. package/build/async-require/buildUrlForBundle.native.js +5 -1
  16. package/build/async-require/buildUrlForBundle.native.js.map +1 -1
  17. package/build/async-require/fetchAsync.d.ts +6 -0
  18. package/build/async-require/fetchAsync.d.ts.map +1 -1
  19. package/build/async-require/fetchAsync.js +6 -3
  20. package/build/async-require/fetchAsync.js.map +1 -1
  21. package/build/async-require/fetchAsync.native.js +13 -6
  22. package/build/async-require/fetchAsync.native.js.map +1 -1
  23. package/build/async-require/fetchThenEval.d.ts +1 -6
  24. package/build/async-require/fetchThenEval.d.ts.map +1 -1
  25. package/build/async-require/fetchThenEval.js +5 -31
  26. package/build/async-require/fetchThenEval.js.map +1 -1
  27. package/build/async-require/fetchThenEval.web.js +6 -2
  28. package/build/async-require/fetchThenEval.web.js.map +1 -1
  29. package/build/async-require/fetchThenEvalJs.d.ts +7 -0
  30. package/build/async-require/fetchThenEvalJs.d.ts.map +1 -0
  31. package/build/async-require/fetchThenEvalJs.js +36 -0
  32. package/build/async-require/fetchThenEvalJs.js.map +1 -0
  33. package/build/async-require/index.js +4 -2
  34. package/build/async-require/index.js.map +1 -1
  35. package/build/async-require/index.native.d.ts +7 -0
  36. package/build/async-require/index.native.d.ts.map +1 -0
  37. package/build/async-require/index.native.js +14 -0
  38. package/build/async-require/index.native.js.map +1 -0
  39. package/build/async-require/loadBundle.js +10 -6
  40. package/build/async-require/loadBundle.js.map +1 -1
  41. package/build/effects.d.ts +0 -1
  42. package/build/effects.js +7 -10
  43. package/build/effects.js.map +1 -1
  44. package/build/error-overlay/Data/LogBoxData.d.ts.map +1 -1
  45. package/build/error-overlay/Data/LogBoxData.js +82 -33
  46. package/build/error-overlay/Data/LogBoxData.js.map +1 -1
  47. package/build/error-overlay/Data/LogBoxLog.js +29 -2
  48. package/build/error-overlay/Data/LogBoxLog.js.map +1 -1
  49. package/build/error-overlay/Data/LogBoxSymbolication.js +12 -4
  50. package/build/error-overlay/Data/LogBoxSymbolication.js.map +1 -1
  51. package/build/error-overlay/Data/LogContext.js +17 -9
  52. package/build/error-overlay/Data/LogContext.js.map +1 -1
  53. package/build/error-overlay/Data/parseLogBoxLog.d.ts.map +1 -1
  54. package/build/error-overlay/Data/parseLogBoxLog.js +20 -11
  55. package/build/error-overlay/Data/parseLogBoxLog.js.map +1 -1
  56. package/build/error-overlay/ErrorOverlay.d.ts.map +1 -1
  57. package/build/error-overlay/ErrorOverlay.js +73 -41
  58. package/build/error-overlay/ErrorOverlay.js.map +1 -1
  59. package/build/error-overlay/LogBox.js +3 -1
  60. package/build/error-overlay/LogBox.js.map +1 -1
  61. package/build/error-overlay/LogBox.web.d.ts.map +1 -1
  62. package/build/error-overlay/LogBox.web.js +4 -3
  63. package/build/error-overlay/LogBox.web.js.map +1 -1
  64. package/build/error-overlay/UI/AnsiHighlight.js +15 -8
  65. package/build/error-overlay/UI/AnsiHighlight.js.map +1 -1
  66. package/build/error-overlay/UI/LogBoxButton.js +35 -8
  67. package/build/error-overlay/UI/LogBoxButton.js.map +1 -1
  68. package/build/error-overlay/UI/LogBoxMessage.js +13 -6
  69. package/build/error-overlay/UI/LogBoxMessage.js.map +1 -1
  70. package/build/error-overlay/UI/LogBoxStyle.js +31 -14
  71. package/build/error-overlay/UI/LogBoxStyle.js.map +1 -1
  72. package/build/error-overlay/UI/constants.js +5 -2
  73. package/build/error-overlay/UI/constants.js.map +1 -1
  74. package/build/error-overlay/formatProjectFilePath.js +7 -2
  75. package/build/error-overlay/formatProjectFilePath.js.map +1 -1
  76. package/build/error-overlay/index.d.ts.map +1 -1
  77. package/build/error-overlay/index.js +19 -9
  78. package/build/error-overlay/index.js.map +1 -1
  79. package/build/error-overlay/modules/ExceptionsManager/index.js +8 -3
  80. package/build/error-overlay/modules/ExceptionsManager/index.js.map +1 -1
  81. package/build/error-overlay/modules/ExceptionsManager/index.native.js +7 -2
  82. package/build/error-overlay/modules/ExceptionsManager/index.native.js.map +1 -1
  83. package/build/error-overlay/modules/NativeLogBox/index.js +10 -5
  84. package/build/error-overlay/modules/NativeLogBox/index.js.map +1 -1
  85. package/build/error-overlay/modules/NativeLogBox/index.native.js +7 -2
  86. package/build/error-overlay/modules/NativeLogBox/index.native.js.map +1 -1
  87. package/build/error-overlay/modules/openFileInEditor/index.js +3 -1
  88. package/build/error-overlay/modules/openFileInEditor/index.js.map +1 -1
  89. package/build/error-overlay/modules/openFileInEditor/index.native.js +7 -2
  90. package/build/error-overlay/modules/openFileInEditor/index.native.js.map +1 -1
  91. package/build/error-overlay/modules/parseErrorStack/index.d.ts.map +1 -1
  92. package/build/error-overlay/modules/parseErrorStack/index.js +10 -7
  93. package/build/error-overlay/modules/parseErrorStack/index.js.map +1 -1
  94. package/build/error-overlay/modules/parseErrorStack/parseHermesStack.js +8 -2
  95. package/build/error-overlay/modules/parseErrorStack/parseHermesStack.js.map +1 -1
  96. package/build/error-overlay/modules/stringifySafe/index.js +6 -2
  97. package/build/error-overlay/modules/stringifySafe/index.js.map +1 -1
  98. package/build/error-overlay/modules/symbolicateStackTrace/index.js +3 -1
  99. package/build/error-overlay/modules/symbolicateStackTrace/index.js.map +1 -1
  100. package/build/error-overlay/modules/symbolicateStackTrace/index.native.js +7 -2
  101. package/build/error-overlay/modules/symbolicateStackTrace/index.native.js.map +1 -1
  102. package/build/error-overlay/overlay/LogBoxInspectorCodeFrame.d.ts.map +1 -1
  103. package/build/error-overlay/overlay/LogBoxInspectorCodeFrame.js +52 -22
  104. package/build/error-overlay/overlay/LogBoxInspectorCodeFrame.js.map +1 -1
  105. package/build/error-overlay/overlay/LogBoxInspectorFooter.js +48 -18
  106. package/build/error-overlay/overlay/LogBoxInspectorFooter.js.map +1 -1
  107. package/build/error-overlay/overlay/LogBoxInspectorHeader.js +53 -23
  108. package/build/error-overlay/overlay/LogBoxInspectorHeader.js.map +1 -1
  109. package/build/error-overlay/overlay/LogBoxInspectorMessageHeader.js +43 -13
  110. package/build/error-overlay/overlay/LogBoxInspectorMessageHeader.js.map +1 -1
  111. package/build/error-overlay/overlay/LogBoxInspectorSection.js +39 -9
  112. package/build/error-overlay/overlay/LogBoxInspectorSection.js.map +1 -1
  113. package/build/error-overlay/overlay/LogBoxInspectorSourceMapStatus.js +41 -14
  114. package/build/error-overlay/overlay/LogBoxInspectorSourceMapStatus.js.map +1 -1
  115. package/build/error-overlay/overlay/LogBoxInspectorStackFrame.js +44 -14
  116. package/build/error-overlay/overlay/LogBoxInspectorStackFrame.js.map +1 -1
  117. package/build/error-overlay/overlay/LogBoxInspectorStackFrames.d.ts.map +1 -1
  118. package/build/error-overlay/overlay/LogBoxInspectorStackFrames.js +55 -24
  119. package/build/error-overlay/overlay/LogBoxInspectorStackFrames.js.map +1 -1
  120. package/build/error-overlay/toast/ErrorToast.d.ts.map +1 -1
  121. package/build/error-overlay/toast/ErrorToast.js +48 -21
  122. package/build/error-overlay/toast/ErrorToast.js.map +1 -1
  123. package/build/error-overlay/toast/ErrorToastContainer.js +9 -3
  124. package/build/error-overlay/toast/ErrorToastContainer.js.map +1 -1
  125. package/build/error-overlay/toast/ErrorToastContainer.web.d.ts.map +1 -1
  126. package/build/error-overlay/toast/ErrorToastContainer.web.js +49 -21
  127. package/build/error-overlay/toast/ErrorToastContainer.web.js.map +1 -1
  128. package/build/error-overlay/toast/ErrorToastMessage.js +37 -7
  129. package/build/error-overlay/toast/ErrorToastMessage.js.map +1 -1
  130. package/build/error-overlay/useRejectionHandler.js +16 -9
  131. package/build/error-overlay/useRejectionHandler.js.map +1 -1
  132. package/build/getDevServer.d.ts.map +1 -1
  133. package/build/getDevServer.js +10 -9
  134. package/build/getDevServer.js.map +1 -1
  135. package/build/getDevServer.native.js +7 -2
  136. package/build/getDevServer.native.js.map +1 -1
  137. package/build/index.d.ts +7 -0
  138. package/build/index.d.ts.map +1 -1
  139. package/build/index.js +12 -8
  140. package/build/index.js.map +1 -1
  141. package/build/location/Location.js +7 -2
  142. package/build/location/Location.js.map +1 -1
  143. package/build/location/Location.native.js +12 -4
  144. package/build/location/Location.native.js.map +1 -1
  145. package/build/location/install.native.js +16 -11
  146. package/build/location/install.native.js.map +1 -1
  147. package/build/setupHMR.js +28 -26
  148. package/build/setupHMR.js.map +1 -1
  149. package/build/symbolicate.js +25 -4
  150. package/build/symbolicate.js.map +1 -1
  151. package/package.json +5 -2
  152. package/src/HMRClient.native.ts +3 -0
  153. package/src/HMRClient.ts +316 -0
  154. package/src/LoadingView.native.ts +3 -0
  155. package/src/LoadingView.ts +24 -0
  156. package/src/__mocks__/LoadingView.ts +4 -0
  157. package/src/async-require/buildAsyncRequire.ts +34 -0
  158. package/src/async-require/buildUrlForBundle.native.ts +28 -0
  159. package/src/async-require/buildUrlForBundle.ts +18 -0
  160. package/src/async-require/fetchAsync.native.ts +72 -0
  161. package/src/async-require/fetchAsync.ts +19 -0
  162. package/src/async-require/fetchThenEval.ts +1 -0
  163. package/src/async-require/fetchThenEval.web.ts +70 -0
  164. package/src/async-require/fetchThenEvalJs.ts +39 -0
  165. package/src/async-require/index.native.ts +15 -0
  166. package/src/async-require/index.ts +10 -0
  167. package/src/async-require/loadBundle.ts +46 -0
  168. package/src/effects.native.ts +0 -0
  169. package/src/effects.ts +11 -0
  170. package/src/error-overlay/Data/LogBoxData.tsx +438 -0
  171. package/src/error-overlay/Data/LogBoxLog.ts +221 -0
  172. package/src/error-overlay/Data/LogBoxSymbolication.tsx +64 -0
  173. package/src/error-overlay/Data/LogContext.tsx +41 -0
  174. package/src/error-overlay/Data/parseLogBoxLog.tsx +342 -0
  175. package/src/error-overlay/ErrorOverlay.tsx +191 -0
  176. package/src/error-overlay/LogBox.ts +51 -0
  177. package/src/error-overlay/LogBox.web.ts +174 -0
  178. package/src/error-overlay/UI/AnsiHighlight.tsx +96 -0
  179. package/src/error-overlay/UI/LogBoxButton.tsx +63 -0
  180. package/src/error-overlay/UI/LogBoxMessage.tsx +73 -0
  181. package/src/error-overlay/UI/LogBoxStyle.ts +64 -0
  182. package/src/error-overlay/UI/constants.ts +7 -0
  183. package/src/error-overlay/formatProjectFilePath.ts +38 -0
  184. package/src/error-overlay/index.tsx +34 -0
  185. package/src/error-overlay/modules/ExceptionsManager/index.native.ts +4 -0
  186. package/src/error-overlay/modules/ExceptionsManager/index.ts +82 -0
  187. package/src/error-overlay/modules/NativeLogBox/index.native.ts +3 -0
  188. package/src/error-overlay/modules/NativeLogBox/index.tsx +27 -0
  189. package/src/error-overlay/modules/openFileInEditor/index.native.ts +3 -0
  190. package/src/error-overlay/modules/openFileInEditor/index.ts +16 -0
  191. package/src/error-overlay/modules/parseErrorStack/index.ts +26 -0
  192. package/src/error-overlay/modules/parseErrorStack/parseHermesStack.ts +3 -0
  193. package/src/error-overlay/modules/stringifySafe/index.ts +115 -0
  194. package/src/error-overlay/modules/symbolicateStackTrace/index.native.ts +3 -0
  195. package/src/error-overlay/modules/symbolicateStackTrace/index.ts +39 -0
  196. package/src/error-overlay/overlay/LogBoxInspectorCodeFrame.tsx +102 -0
  197. package/src/error-overlay/overlay/LogBoxInspectorFooter.tsx +111 -0
  198. package/src/error-overlay/overlay/LogBoxInspectorHeader.tsx +167 -0
  199. package/src/error-overlay/overlay/LogBoxInspectorMessageHeader.tsx +116 -0
  200. package/src/error-overlay/overlay/LogBoxInspectorSection.tsx +52 -0
  201. package/src/error-overlay/overlay/LogBoxInspectorSourceMapStatus.tsx +125 -0
  202. package/src/error-overlay/overlay/LogBoxInspectorStackFrame.tsx +89 -0
  203. package/src/error-overlay/overlay/LogBoxInspectorStackFrames.tsx +201 -0
  204. package/src/error-overlay/toast/ErrorToast.tsx +167 -0
  205. package/src/error-overlay/toast/ErrorToastContainer.tsx +9 -0
  206. package/src/error-overlay/toast/ErrorToastContainer.web.tsx +92 -0
  207. package/src/error-overlay/toast/ErrorToastMessage.tsx +28 -0
  208. package/src/error-overlay/useRejectionHandler.ts +61 -0
  209. package/src/getDevServer.native.ts +3 -0
  210. package/src/getDevServer.ts +34 -0
  211. package/src/index.ts +12 -0
  212. package/src/location/Location.native.ts +201 -0
  213. package/src/location/Location.ts +3 -0
  214. package/src/location/install.native.ts +90 -0
  215. package/src/location/install.ts +0 -0
  216. package/src/messageSocket.ts +25 -0
  217. package/src/setupFastRefresh.ts +30 -0
  218. package/src/setupHMR.ts +28 -0
  219. package/src/symbolicate.ts +6 -0
@@ -0,0 +1,16 @@
1
+ declare const process: any;
2
+
3
+ function openFileInEditor(file: string, lineNumber: number) {
4
+ if (process.env.NODE_ENV !== 'production') {
5
+ // TODO: This is not a great URL since it now blocks users from accessing the `/open-stack-frame` url in their router
6
+ // ideally it would be something like `/_devtools/open-stack-frame`.
7
+ const baseUrl = window.location.protocol + '//' + window.location.host;
8
+
9
+ fetch(baseUrl + '/open-stack-frame', {
10
+ method: 'POST',
11
+ body: JSON.stringify({ file, lineNumber }),
12
+ });
13
+ }
14
+ }
15
+
16
+ export default openFileInEditor;
@@ -0,0 +1,26 @@
1
+ import { parse, StackFrame } from 'stacktrace-parser';
2
+
3
+ function parseErrorStack(stack?: string): (StackFrame & { collapse?: boolean })[] {
4
+ if (stack == null) {
5
+ return [];
6
+ }
7
+ if (Array.isArray(stack)) {
8
+ return stack;
9
+ }
10
+
11
+ // This file seems to be web-only, so we can remove this.
12
+ // // Native support for parsing for non-standard Hermes stack traces.
13
+ // if (global.HermesInternal) {
14
+ // return require('./parseHermesStack').parseErrorStack(stack);
15
+ // }
16
+
17
+ return parse(stack).map((frame) => {
18
+ // frame.file will mostly look like `http://localhost:8081/index.bundle?platform=web&dev=true&hot=false`
19
+ return {
20
+ ...frame,
21
+ column: frame.column != null ? frame.column - 1 : null,
22
+ };
23
+ });
24
+ }
25
+
26
+ export default parseErrorStack;
@@ -0,0 +1,3 @@
1
+ import parseErrorStack from 'react-native/Libraries/Core/Devtools/parseErrorStack';
2
+
3
+ export { parseErrorStack };
@@ -0,0 +1,115 @@
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
+
9
+ /**
10
+ * Tries to stringify with JSON.stringify and toString, but catches exceptions
11
+ * (e.g. from circular objects) and always returns a string and never throws.
12
+ */
13
+ export function createStringifySafeWithLimits(limits: {
14
+ maxDepth?: number;
15
+ maxStringLimit?: number;
16
+ maxArrayLimit?: number;
17
+ maxObjectKeysLimit?: number;
18
+ }): (foo: any) => string {
19
+ const {
20
+ maxDepth = Number.POSITIVE_INFINITY,
21
+ maxStringLimit = Number.POSITIVE_INFINITY,
22
+ maxArrayLimit = Number.POSITIVE_INFINITY,
23
+ maxObjectKeysLimit = Number.POSITIVE_INFINITY,
24
+ } = limits;
25
+ const stack: any[] = [];
26
+ function replacer(this: unknown, _key: string, value: any): any {
27
+ while (stack.length && this !== stack[0]) {
28
+ stack.shift();
29
+ }
30
+
31
+ if (typeof value === 'string') {
32
+ const truncatedString = '...(truncated)...';
33
+ if (value.length > maxStringLimit + truncatedString.length) {
34
+ return value.substring(0, maxStringLimit) + truncatedString;
35
+ }
36
+ return value;
37
+ }
38
+ if (typeof value !== 'object' || value === null) {
39
+ return value;
40
+ }
41
+
42
+ let retval = value;
43
+ if (Array.isArray(value)) {
44
+ if (stack.length >= maxDepth) {
45
+ retval = `[ ... array with ${value.length} values ... ]`;
46
+ } else if (value.length > maxArrayLimit) {
47
+ retval = value
48
+ .slice(0, maxArrayLimit)
49
+ .concat([`... extra ${value.length - maxArrayLimit} values truncated ...`]);
50
+ }
51
+ } else {
52
+ // Add refinement after Array.isArray call.
53
+ if (typeof value !== 'object') {
54
+ throw new Error('This was already found earlier');
55
+ }
56
+ const keys = Object.keys(value);
57
+ if (stack.length >= maxDepth) {
58
+ retval = `{ ... object with ${keys.length} keys ... }`;
59
+ } else if (keys.length > maxObjectKeysLimit) {
60
+ // Return a sample of the keys.
61
+ retval = {};
62
+ for (const k of keys.slice(0, maxObjectKeysLimit)) {
63
+ retval[k] = value[k];
64
+ }
65
+ const truncatedKey = '...(truncated keys)...';
66
+ retval[truncatedKey] = keys.length - maxObjectKeysLimit;
67
+ }
68
+ }
69
+ stack.unshift(retval);
70
+ return retval;
71
+ }
72
+
73
+ return function stringifySafe(arg: any): string {
74
+ if (arg === undefined) {
75
+ return 'undefined';
76
+ } else if (arg === null) {
77
+ return 'null';
78
+ } else if (typeof arg === 'function') {
79
+ try {
80
+ return arg.toString();
81
+ } catch {
82
+ return '[function unknown]';
83
+ }
84
+ } else if (arg instanceof Error) {
85
+ return arg.name + ': ' + arg.message;
86
+ } else {
87
+ // Perform a try catch, just in case the object has a circular
88
+ // reference or stringify throws for some other reason.
89
+ try {
90
+ const ret = JSON.stringify(arg, replacer);
91
+ if (ret === undefined) {
92
+ return '["' + typeof arg + '" failed to stringify]';
93
+ }
94
+ return ret;
95
+ } catch {
96
+ if (typeof arg.toString === 'function') {
97
+ try {
98
+ // $FlowFixMe[incompatible-use] : toString shouldn't take any arguments in general.
99
+ return arg.toString();
100
+ } catch {}
101
+ }
102
+ }
103
+ }
104
+ return '["' + typeof arg + '" failed to stringify]';
105
+ };
106
+ }
107
+
108
+ const stringifySafe = createStringifySafeWithLimits({
109
+ maxDepth: 10,
110
+ maxStringLimit: 100,
111
+ maxArrayLimit: 50,
112
+ maxObjectKeysLimit: 50,
113
+ });
114
+
115
+ export default stringifySafe;
@@ -0,0 +1,3 @@
1
+ import symbolicateStackTrace from 'react-native/Libraries/Core/Devtools/symbolicateStackTrace';
2
+
3
+ export default symbolicateStackTrace;
@@ -0,0 +1,39 @@
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
+
9
+ import { StackFrame } from 'stacktrace-parser';
10
+
11
+ export type CodeFrame = {
12
+ content: string;
13
+ location?: {
14
+ row: number;
15
+ column: number;
16
+ [key: string]: any;
17
+ };
18
+ fileName: string;
19
+ };
20
+
21
+ export type SymbolicatedStackTrace = {
22
+ stack: StackFrame[];
23
+ codeFrame?: CodeFrame;
24
+ };
25
+
26
+ async function symbolicateStackTrace(stack: StackFrame[]): Promise<SymbolicatedStackTrace> {
27
+ const baseUrl =
28
+ typeof window === 'undefined'
29
+ ? process.env.EXPO_DEV_SERVER_ORIGIN
30
+ : window.location.protocol + '//' + window.location.host;
31
+
32
+ const response = await fetch(baseUrl + '/symbolicate', {
33
+ method: 'POST',
34
+ body: JSON.stringify({ stack }),
35
+ });
36
+ return await response.json();
37
+ }
38
+
39
+ export default symbolicateStackTrace;
@@ -0,0 +1,102 @@
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 from 'react';
9
+ import { ScrollView, StyleSheet, Text, View } from 'react-native';
10
+
11
+ import { LogBoxInspectorSection } from './LogBoxInspectorSection';
12
+ import type { CodeFrame } from '../Data/parseLogBoxLog';
13
+ import { Ansi } from '../UI/AnsiHighlight';
14
+ import { LogBoxButton } from '../UI/LogBoxButton';
15
+ import * as LogBoxStyle from '../UI/LogBoxStyle';
16
+ import { CODE_FONT } from '../UI/constants';
17
+ import { formatProjectFilePath } from '../formatProjectFilePath';
18
+ import openFileInEditor from '../modules/openFileInEditor';
19
+
20
+ declare const process: any;
21
+
22
+ export function LogBoxInspectorCodeFrame({ codeFrame }: { codeFrame?: CodeFrame }) {
23
+ if (codeFrame == null) {
24
+ return null;
25
+ }
26
+
27
+ function getFileName() {
28
+ return formatProjectFilePath(process.env.EXPO_PROJECT_ROOT, codeFrame?.fileName);
29
+ }
30
+
31
+ function getLocation() {
32
+ const location = codeFrame?.location;
33
+ if (location != null) {
34
+ return ` (${location.row}:${location.column + 1 /* Code frame columns are zero indexed */})`;
35
+ }
36
+
37
+ return null;
38
+ }
39
+
40
+ return (
41
+ <LogBoxInspectorSection heading="Source">
42
+ <View style={styles.box}>
43
+ <View style={styles.frame}>
44
+ <ScrollView horizontal>
45
+ <Ansi style={styles.content} text={codeFrame.content} />
46
+ </ScrollView>
47
+ </View>
48
+ <LogBoxButton
49
+ backgroundColor={{
50
+ default: 'transparent',
51
+ pressed: LogBoxStyle.getBackgroundDarkColor(1),
52
+ }}
53
+ style={styles.button}
54
+ onPress={() => {
55
+ openFileInEditor(codeFrame.fileName, codeFrame.location?.row ?? 0);
56
+ }}>
57
+ <Text style={styles.fileText}>
58
+ {getFileName()}
59
+ {getLocation()}
60
+ </Text>
61
+ </LogBoxButton>
62
+ </View>
63
+ </LogBoxInspectorSection>
64
+ );
65
+ }
66
+
67
+ const styles = StyleSheet.create({
68
+ box: {
69
+ backgroundColor: LogBoxStyle.getBackgroundColor(),
70
+ borderWidth: 1,
71
+ borderColor: '#323232',
72
+ marginLeft: 10,
73
+ marginRight: 10,
74
+ marginTop: 5,
75
+ borderRadius: 3,
76
+ },
77
+ frame: {
78
+ padding: 10,
79
+ borderBottomColor: LogBoxStyle.getTextColor(0.1),
80
+ borderBottomWidth: 1,
81
+ },
82
+ button: {
83
+ paddingTop: 10,
84
+ paddingBottom: 10,
85
+ },
86
+ content: {
87
+ color: LogBoxStyle.getTextColor(1),
88
+ fontSize: 12,
89
+ includeFontPadding: false,
90
+ lineHeight: 20,
91
+ fontFamily: CODE_FONT,
92
+ },
93
+ fileText: {
94
+ userSelect: 'none',
95
+ color: LogBoxStyle.getTextColor(0.5),
96
+ textAlign: 'center',
97
+ flex: 1,
98
+ fontSize: 16,
99
+ includeFontPadding: false,
100
+ fontFamily: CODE_FONT,
101
+ },
102
+ });
@@ -0,0 +1,111 @@
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 from 'react';
9
+ import { Pressable, StyleSheet, Text, View } from 'react-native';
10
+
11
+ import { useSelectedLog } from '../Data/LogContext';
12
+ import * as LogBoxStyle from '../UI/LogBoxStyle';
13
+
14
+ type Props = {
15
+ onDismiss: () => void;
16
+ onMinimize: () => void;
17
+ };
18
+
19
+ export function LogBoxInspectorFooter(props: Props) {
20
+ const log = useSelectedLog();
21
+
22
+ if (['static', 'syntax'].includes(log.level)) {
23
+ return (
24
+ <View style={styles.root}>
25
+ <View style={styles.button}>
26
+ <Text style={styles.syntaxErrorText}>This error cannot be dismissed.</Text>
27
+ </View>
28
+ </View>
29
+ );
30
+ }
31
+
32
+ return (
33
+ <View style={styles.root}>
34
+ <FooterButton text="Dismiss" onPress={props.onDismiss} />
35
+ <FooterButton text="Minimize" onPress={props.onMinimize} />
36
+ </View>
37
+ );
38
+ }
39
+
40
+ function FooterButton({ text, onPress }: { onPress: () => void; text: string }) {
41
+ return (
42
+ <Pressable onPress={onPress} style={{ flex: 1 }}>
43
+ {({
44
+ /** @ts-expect-error: react-native types are broken. */
45
+ hovered,
46
+ pressed,
47
+ }) => (
48
+ <View
49
+ style={[
50
+ buttonStyles.safeArea,
51
+ {
52
+ // @ts-expect-error: web-only type
53
+ transitionDuration: '150ms',
54
+ backgroundColor: pressed
55
+ ? '#323232'
56
+ : hovered
57
+ ? '#111111'
58
+ : LogBoxStyle.getBackgroundColor(),
59
+ },
60
+ ]}>
61
+ <View style={buttonStyles.content}>
62
+ <Text style={buttonStyles.label}>{text}</Text>
63
+ </View>
64
+ </View>
65
+ )}
66
+ </Pressable>
67
+ );
68
+ }
69
+
70
+ const buttonStyles = StyleSheet.create({
71
+ safeArea: {
72
+ flex: 1,
73
+ borderTopWidth: 1,
74
+ borderColor: '#323232',
75
+ // paddingBottom: DeviceInfo.getConstants().isIPhoneX_deprecated ? 30 : 0,
76
+ },
77
+ content: {
78
+ alignItems: 'center',
79
+ height: 48,
80
+ justifyContent: 'center',
81
+ },
82
+ label: {
83
+ userSelect: 'none',
84
+ color: LogBoxStyle.getTextColor(1),
85
+ fontSize: 14,
86
+ includeFontPadding: false,
87
+ lineHeight: 20,
88
+ },
89
+ });
90
+
91
+ const styles = StyleSheet.create({
92
+ root: {
93
+ backgroundColor: LogBoxStyle.getBackgroundColor(1),
94
+ boxShadow: `0 -2px 0 2px #000`,
95
+ flexDirection: 'row',
96
+ },
97
+ button: {
98
+ flex: 1,
99
+ },
100
+ syntaxErrorText: {
101
+ textAlign: 'center',
102
+ width: '100%',
103
+ height: 48,
104
+ fontSize: 14,
105
+ lineHeight: 20,
106
+ paddingTop: 20,
107
+ paddingBottom: 50,
108
+ fontStyle: 'italic',
109
+ color: LogBoxStyle.getTextColor(0.6),
110
+ },
111
+ });
@@ -0,0 +1,167 @@
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 from 'react';
9
+ import { Image, Platform, StatusBar, StyleSheet, Text, View } from 'react-native';
10
+
11
+ import type { LogLevel } from '../Data/LogBoxLog';
12
+ import { useLogs } from '../Data/LogContext';
13
+ import { LogBoxButton } from '../UI/LogBoxButton';
14
+ import * as LogBoxStyle from '../UI/LogBoxStyle';
15
+
16
+ type Props = {
17
+ onSelectIndex: (selectedIndex: number) => void;
18
+ level: LogLevel;
19
+ };
20
+
21
+ export function LogBoxInspectorHeader(props: Props) {
22
+ const { selectedLogIndex: selectedIndex, logs } = useLogs();
23
+ const total = logs.length;
24
+
25
+ if (props.level === 'syntax') {
26
+ return (
27
+ <View style={[styles.safeArea, styles[props.level]]}>
28
+ <View style={styles.header}>
29
+ <View style={styles.title}>
30
+ <Text style={styles.titleText}>Failed to compile</Text>
31
+ </View>
32
+ </View>
33
+ </View>
34
+ );
35
+ }
36
+
37
+ const prevIndex = selectedIndex - 1 < 0 ? total - 1 : selectedIndex - 1;
38
+ const nextIndex = selectedIndex + 1 > total - 1 ? 0 : selectedIndex + 1;
39
+
40
+ const titleText = `Log ${selectedIndex + 1} of ${total}`;
41
+
42
+ return (
43
+ <View style={[styles.safeArea, styles[props.level]]}>
44
+ <View style={styles.header}>
45
+ <LogBoxInspectorHeaderButton
46
+ disabled={total <= 1}
47
+ level={props.level}
48
+ image={require('@expo/metro-runtime/assets/chevron-left.png')}
49
+ onPress={() => props.onSelectIndex(prevIndex)}
50
+ />
51
+ <View style={styles.title}>
52
+ <Text style={styles.titleText}>{titleText}</Text>
53
+ </View>
54
+ <LogBoxInspectorHeaderButton
55
+ disabled={total <= 1}
56
+ level={props.level}
57
+ image={require('@expo/metro-runtime/assets/chevron-right.png')}
58
+ onPress={() => props.onSelectIndex(nextIndex)}
59
+ />
60
+ </View>
61
+ </View>
62
+ );
63
+ }
64
+
65
+ const backgroundForLevel = (level: LogLevel) =>
66
+ ({
67
+ warn: {
68
+ default: 'transparent',
69
+ pressed: LogBoxStyle.getWarningDarkColor(),
70
+ },
71
+ error: {
72
+ default: 'transparent',
73
+ pressed: LogBoxStyle.getErrorDarkColor(),
74
+ },
75
+ fatal: {
76
+ default: 'transparent',
77
+ pressed: LogBoxStyle.getFatalDarkColor(),
78
+ },
79
+ syntax: {
80
+ default: 'transparent',
81
+ pressed: LogBoxStyle.getFatalDarkColor(),
82
+ },
83
+ static: {
84
+ default: 'transparent',
85
+ pressed: LogBoxStyle.getFatalDarkColor(),
86
+ },
87
+ })[level];
88
+
89
+ function LogBoxInspectorHeaderButton(props: {
90
+ disabled: boolean;
91
+ image: number;
92
+ level: LogLevel;
93
+ onPress?: () => void;
94
+ }) {
95
+ return (
96
+ <LogBoxButton
97
+ backgroundColor={backgroundForLevel(props.level)}
98
+ onPress={props.disabled ? undefined : props.onPress}
99
+ style={headerStyles.button}>
100
+ {props.disabled ? null : (
101
+ <Image
102
+ source={props.image}
103
+ tintColor={LogBoxStyle.getTextColor()}
104
+ style={headerStyles.buttonImage}
105
+ />
106
+ )}
107
+ </LogBoxButton>
108
+ );
109
+ }
110
+
111
+ const headerStyles = StyleSheet.create({
112
+ button: {
113
+ alignItems: 'center',
114
+ justifyContent: 'center',
115
+ aspectRatio: 1,
116
+ marginRight: 6,
117
+ marginLeft: 6,
118
+ borderRadius: 3,
119
+ },
120
+ buttonImage: {
121
+ height: 14,
122
+ width: 8,
123
+ },
124
+ });
125
+
126
+ const styles = StyleSheet.create({
127
+ syntax: {
128
+ backgroundColor: LogBoxStyle.getFatalColor(),
129
+ },
130
+ static: {
131
+ backgroundColor: LogBoxStyle.getFatalColor(),
132
+ },
133
+ fatal: {
134
+ backgroundColor: LogBoxStyle.getFatalColor(),
135
+ },
136
+ warn: {
137
+ backgroundColor: LogBoxStyle.getWarningColor(),
138
+ },
139
+ error: {
140
+ backgroundColor: LogBoxStyle.getErrorColor(),
141
+ },
142
+ header: {
143
+ flexDirection: 'row',
144
+ alignItems: 'center',
145
+
146
+ paddingHorizontal: 8,
147
+ height: Platform.select({
148
+ default: 48,
149
+ ios: 44,
150
+ }),
151
+ },
152
+ title: {
153
+ alignItems: 'center',
154
+ flex: 1,
155
+ justifyContent: 'center',
156
+ },
157
+ titleText: {
158
+ color: LogBoxStyle.getTextColor(),
159
+ fontSize: 16,
160
+ fontWeight: '600',
161
+ includeFontPadding: false,
162
+ lineHeight: 20,
163
+ },
164
+ safeArea: {
165
+ paddingTop: Platform.OS !== 'ios' ? StatusBar.currentHeight : 40,
166
+ },
167
+ });
@@ -0,0 +1,116 @@
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 from 'react';
9
+ import { StyleSheet, Text, View } from 'react-native';
10
+
11
+ import type { LogLevel } from '../Data/LogBoxLog';
12
+ import type { Message } from '../Data/parseLogBoxLog';
13
+ import { LogBoxMessage } from '../UI/LogBoxMessage';
14
+ import * as LogBoxStyle from '../UI/LogBoxStyle';
15
+
16
+ type Props = {
17
+ collapsed: boolean;
18
+ message: Message;
19
+ level: LogLevel;
20
+ title: string;
21
+ onPress: () => void;
22
+ };
23
+
24
+ const SHOW_MORE_MESSAGE_LENGTH = 300;
25
+
26
+ function ShowMoreButton({
27
+ message,
28
+ collapsed,
29
+ onPress,
30
+ }: Pick<Props, 'collapsed' | 'message' | 'onPress'>) {
31
+ if (message.content.length < SHOW_MORE_MESSAGE_LENGTH || !collapsed) {
32
+ return null;
33
+ }
34
+ return (
35
+ <Text style={styles.collapse} onPress={onPress}>
36
+ ... See More
37
+ </Text>
38
+ );
39
+ }
40
+
41
+ export function LogBoxInspectorMessageHeader(props: Props) {
42
+ return (
43
+ <View style={styles.body}>
44
+ <View style={styles.heading}>
45
+ <Text style={[styles.headingText, styles[props.level]]}>{props.title}</Text>
46
+ </View>
47
+ <Text style={styles.bodyText}>
48
+ <LogBoxMessage
49
+ maxLength={props.collapsed ? SHOW_MORE_MESSAGE_LENGTH : Infinity}
50
+ message={props.message}
51
+ style={styles.messageText}
52
+ />
53
+ <ShowMoreButton {...props} />
54
+ </Text>
55
+ </View>
56
+ );
57
+ }
58
+
59
+ const styles = StyleSheet.create({
60
+ body: {
61
+ backgroundColor: LogBoxStyle.getBackgroundColor(1),
62
+ boxShadow: `0 2px 0 2px #00000080`,
63
+ },
64
+ bodyText: {
65
+ color: LogBoxStyle.getTextColor(1),
66
+ fontSize: 14,
67
+ includeFontPadding: false,
68
+ lineHeight: 20,
69
+ fontWeight: '500',
70
+ paddingHorizontal: 12,
71
+ paddingBottom: 10,
72
+ },
73
+ heading: {
74
+ alignItems: 'center',
75
+ flexDirection: 'row',
76
+ paddingHorizontal: 12,
77
+ marginTop: 10,
78
+ marginBottom: 5,
79
+ },
80
+ headingText: {
81
+ flex: 1,
82
+ fontSize: 20,
83
+ fontWeight: '600',
84
+ includeFontPadding: false,
85
+ lineHeight: 28,
86
+ },
87
+ warn: {
88
+ color: LogBoxStyle.getWarningColor(1),
89
+ },
90
+ error: {
91
+ color: LogBoxStyle.getErrorColor(1),
92
+ },
93
+ fatal: {
94
+ color: LogBoxStyle.getFatalColor(1),
95
+ },
96
+ syntax: {
97
+ color: LogBoxStyle.getFatalColor(1),
98
+ },
99
+ static: {
100
+ color: LogBoxStyle.getFatalColor(1),
101
+ },
102
+ messageText: {
103
+ color: LogBoxStyle.getTextColor(0.6),
104
+ },
105
+ collapse: {
106
+ color: LogBoxStyle.getTextColor(0.7),
107
+ fontSize: 14,
108
+ fontWeight: '300',
109
+ lineHeight: 12,
110
+ },
111
+ button: {
112
+ paddingVertical: 5,
113
+ paddingHorizontal: 10,
114
+ borderRadius: 3,
115
+ },
116
+ });