@react-navigation/devtools 6.0.2 → 6.0.3

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.
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var stacktraceParser = _interopRequireWildcard(require("stacktrace-parser"));
9
+
10
+ var _parseHermesStack = _interopRequireDefault(require("./parseHermesStack"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
+
16
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
+
18
+ /**
19
+ * Copyright (c) Facebook, Inc. and its affiliates.
20
+ *
21
+ * This source code is licensed under the MIT license found in the
22
+ * LICENSE file in the root directory of this source tree.
23
+ */
24
+ function convertHermesStack(stack) {
25
+ const frames = [];
26
+
27
+ for (const entry of stack.entries) {
28
+ if (entry.type !== 'FRAME') {
29
+ continue;
30
+ }
31
+
32
+ const {
33
+ location,
34
+ functionName
35
+ } = entry;
36
+
37
+ if (location.type === 'NATIVE') {
38
+ continue;
39
+ }
40
+
41
+ frames.push({
42
+ methodName: functionName,
43
+ file: location.sourceUrl,
44
+ lineNumber: location.line1Based,
45
+ column: location.type === 'SOURCE' ? location.column1Based - 1 : location.virtualOffset0Based
46
+ });
47
+ }
48
+
49
+ return frames;
50
+ }
51
+
52
+ function parseErrorStack(errorStack) {
53
+ if (!errorStack) {
54
+ return [];
55
+ }
56
+
57
+ const parsedStack = Array.isArray(errorStack) ? errorStack : global.HermesInternal ? convertHermesStack((0, _parseHermesStack.default)(errorStack)) : stacktraceParser.parse(errorStack).map(frame => ({ ...frame,
58
+ column: frame.column != null ? frame.column - 1 : null
59
+ }));
60
+ return parsedStack;
61
+ }
62
+
63
+ var _default = parseErrorStack;
64
+ exports.default = _default;
65
+ //# sourceMappingURL=parseErrorStack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["parseErrorStack.tsx"],"names":["convertHermesStack","stack","frames","entry","entries","type","location","functionName","push","methodName","file","sourceUrl","lineNumber","line1Based","column","column1Based","virtualOffset0Based","parseErrorStack","errorStack","parsedStack","Array","isArray","global","HermesInternal","stacktraceParser","parse","map","frame"],"mappings":";;;;;;;AAOA;;AAEA;;;;;;;;AATA;AACA;AACA;AACA;AACA;AACA;AAaA,SAASA,kBAAT,CAA4BC,KAA5B,EAAoE;AAClE,QAAMC,MAAM,GAAG,EAAf;;AACA,OAAK,MAAMC,KAAX,IAAoBF,KAAK,CAACG,OAA1B,EAAmC;AACjC,QAAID,KAAK,CAACE,IAAN,KAAe,OAAnB,EAA4B;AAC1B;AACD;;AACD,UAAM;AAAEC,MAAAA,QAAF;AAAYC,MAAAA;AAAZ,QAA6BJ,KAAnC;;AACA,QAAIG,QAAQ,CAACD,IAAT,KAAkB,QAAtB,EAAgC;AAC9B;AACD;;AACDH,IAAAA,MAAM,CAACM,IAAP,CAAY;AACVC,MAAAA,UAAU,EAAEF,YADF;AAEVG,MAAAA,IAAI,EAAEJ,QAAQ,CAACK,SAFL;AAGVC,MAAAA,UAAU,EAAEN,QAAQ,CAACO,UAHX;AAIVC,MAAAA,MAAM,EACJR,QAAQ,CAACD,IAAT,KAAkB,QAAlB,GACIC,QAAQ,CAACS,YAAT,GAAwB,CAD5B,GAEIT,QAAQ,CAACU;AAPL,KAAZ;AASD;;AACD,SAAOd,MAAP;AACD;;AAED,SAASe,eAAT,CAAyBC,UAAzB,EAA2E;AACzE,MAAI,CAACA,UAAL,EAAiB;AACf,WAAO,EAAP;AACD;;AAED,QAAMC,WAAW,GAAGC,KAAK,CAACC,OAAN,CAAcH,UAAd,IAChBA,UADgB,GAEfI,MAAD,CAAgBC,cAAhB,GACAvB,kBAAkB,CAAC,+BAAiBkB,UAAjB,CAAD,CADlB,GAEAM,gBAAgB,CAACC,KAAjB,CAAuBP,UAAvB,EAAmCQ,GAAnC,CAAwCC,KAAD,KAAY,EACjD,GAAGA,KAD8C;AAEjDb,IAAAA,MAAM,EAAEa,KAAK,CAACb,MAAN,IAAgB,IAAhB,GAAuBa,KAAK,CAACb,MAAN,GAAe,CAAtC,GAA0C;AAFD,GAAZ,CAAvC,CAJJ;AASA,SAAOK,WAAP;AACD;;eAEcF,e","sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport * as stacktraceParser from 'stacktrace-parser';\n\nimport parseHermesStack, { HermesParsedStack } from './parseHermesStack';\n\ninterface StackFrame {\n methodName: string;\n file: string;\n lineNumber: number;\n column: number;\n}\n\nfunction convertHermesStack(stack: HermesParsedStack): StackFrame[] {\n const frames = [];\n for (const entry of stack.entries) {\n if (entry.type !== 'FRAME') {\n continue;\n }\n const { location, functionName } = entry;\n if (location.type === 'NATIVE') {\n continue;\n }\n frames.push({\n methodName: functionName,\n file: location.sourceUrl,\n lineNumber: location.line1Based,\n column:\n location.type === 'SOURCE'\n ? location.column1Based - 1\n : location.virtualOffset0Based,\n });\n }\n return frames;\n}\n\nfunction parseErrorStack(errorStack?: string | StackFrame[]): StackFrame[] {\n if (!errorStack) {\n return [];\n }\n\n const parsedStack = Array.isArray(errorStack)\n ? errorStack\n : (global as any).HermesInternal\n ? convertHermesStack(parseHermesStack(errorStack))\n : stacktraceParser.parse(errorStack).map((frame) => ({\n ...frame,\n column: frame.column != null ? frame.column - 1 : null,\n }));\n\n return parsedStack as StackFrame[];\n}\n\nexport default parseErrorStack;\n"]}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = parseHermesStack;
7
+
8
+ /**
9
+ * Copyright (c) Facebook, Inc. and its affiliates.
10
+ *
11
+ * This source code is licensed under the MIT license found in the
12
+ * LICENSE file in the root directory of this source tree.
13
+ */
14
+ // Capturing groups:
15
+ // 1. function name
16
+ // 2. is this a native stack frame?
17
+ // 3. is this a bytecode address or a source location?
18
+ // 4. source URL (filename)
19
+ // 5. line number (1 based)
20
+ // 6. column number (1 based) or virtual offset (0 based)
21
+ const RE_FRAME = /^ {0,4}at (.+?)(?: \((native)\)?| \((address at )?(.*?):(\d+):(\d+)\))$/; // Capturing groups:
22
+ // 1. count of skipped frames
23
+
24
+ const RE_SKIPPED = /^ {0,4}... skipping (\d) frames$/;
25
+
26
+ function parseLine(line) {
27
+ const asFrame = line.match(RE_FRAME);
28
+
29
+ if (asFrame) {
30
+ return {
31
+ type: 'FRAME',
32
+ functionName: asFrame[1],
33
+ location: asFrame[2] === 'native' ? {
34
+ type: 'NATIVE'
35
+ } : asFrame[3] === 'address at ' ? {
36
+ type: 'BYTECODE',
37
+ sourceUrl: asFrame[4],
38
+ line1Based: Number.parseInt(asFrame[5], 10),
39
+ virtualOffset0Based: Number.parseInt(asFrame[6], 10)
40
+ } : {
41
+ type: 'SOURCE',
42
+ sourceUrl: asFrame[4],
43
+ line1Based: Number.parseInt(asFrame[5], 10),
44
+ column1Based: Number.parseInt(asFrame[6], 10)
45
+ }
46
+ };
47
+ }
48
+
49
+ const asSkipped = line.match(RE_SKIPPED);
50
+
51
+ if (asSkipped) {
52
+ return {
53
+ type: 'SKIPPED',
54
+ count: Number.parseInt(asSkipped[1], 10)
55
+ };
56
+ }
57
+
58
+ return undefined;
59
+ }
60
+
61
+ function parseHermesStack(stack) {
62
+ const lines = stack.split(/\n/);
63
+ let entries = [];
64
+ let lastMessageLine = -1;
65
+
66
+ for (let i = 0; i < lines.length; ++i) {
67
+ const line = lines[i];
68
+
69
+ if (!line) {
70
+ continue;
71
+ }
72
+
73
+ const entry = parseLine(line);
74
+
75
+ if (entry) {
76
+ entries.push(entry);
77
+ continue;
78
+ } // No match - we're still in the message
79
+
80
+
81
+ lastMessageLine = i;
82
+ entries = [];
83
+ }
84
+
85
+ const message = lines.slice(0, lastMessageLine + 1).join('\n');
86
+ return {
87
+ message,
88
+ entries
89
+ };
90
+ }
91
+ //# sourceMappingURL=parseHermesStack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["parseHermesStack.tsx"],"names":["RE_FRAME","RE_SKIPPED","parseLine","line","asFrame","match","type","functionName","location","sourceUrl","line1Based","Number","parseInt","virtualOffset0Based","column1Based","asSkipped","count","undefined","parseHermesStack","stack","lines","split","entries","lastMessageLine","i","length","entry","push","message","slice","join"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AA2CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMA,QAAQ,GACZ,yEADF,C,CAGA;AACA;;AACA,MAAMC,UAAU,GAAG,kCAAnB;;AAEA,SAASC,SAAT,CAAmBC,IAAnB,EAA+D;AAC7D,QAAMC,OAAO,GAAGD,IAAI,CAACE,KAAL,CAAWL,QAAX,CAAhB;;AACA,MAAII,OAAJ,EAAa;AACX,WAAO;AACLE,MAAAA,IAAI,EAAE,OADD;AAELC,MAAAA,YAAY,EAAEH,OAAO,CAAC,CAAD,CAFhB;AAGLI,MAAAA,QAAQ,EACNJ,OAAO,CAAC,CAAD,CAAP,KAAe,QAAf,GACI;AAAEE,QAAAA,IAAI,EAAE;AAAR,OADJ,GAEIF,OAAO,CAAC,CAAD,CAAP,KAAe,aAAf,GACA;AACEE,QAAAA,IAAI,EAAE,UADR;AAEEG,QAAAA,SAAS,EAAEL,OAAO,CAAC,CAAD,CAFpB;AAGEM,QAAAA,UAAU,EAAEC,MAAM,CAACC,QAAP,CAAgBR,OAAO,CAAC,CAAD,CAAvB,EAA4B,EAA5B,CAHd;AAIES,QAAAA,mBAAmB,EAAEF,MAAM,CAACC,QAAP,CAAgBR,OAAO,CAAC,CAAD,CAAvB,EAA4B,EAA5B;AAJvB,OADA,GAOA;AACEE,QAAAA,IAAI,EAAE,QADR;AAEEG,QAAAA,SAAS,EAAEL,OAAO,CAAC,CAAD,CAFpB;AAGEM,QAAAA,UAAU,EAAEC,MAAM,CAACC,QAAP,CAAgBR,OAAO,CAAC,CAAD,CAAvB,EAA4B,EAA5B,CAHd;AAIEU,QAAAA,YAAY,EAAEH,MAAM,CAACC,QAAP,CAAgBR,OAAO,CAAC,CAAD,CAAvB,EAA4B,EAA5B;AAJhB;AAbD,KAAP;AAoBD;;AACD,QAAMW,SAAS,GAAGZ,IAAI,CAACE,KAAL,CAAWJ,UAAX,CAAlB;;AACA,MAAIc,SAAJ,EAAe;AACb,WAAO;AACLT,MAAAA,IAAI,EAAE,SADD;AAELU,MAAAA,KAAK,EAAEL,MAAM,CAACC,QAAP,CAAgBG,SAAS,CAAC,CAAD,CAAzB,EAA8B,EAA9B;AAFF,KAAP;AAID;;AACD,SAAOE,SAAP;AACD;;AAEc,SAASC,gBAAT,CAA0BC,KAA1B,EAA4D;AACzE,QAAMC,KAAK,GAAGD,KAAK,CAACE,KAAN,CAAY,IAAZ,CAAd;AACA,MAAIC,OAAO,GAAG,EAAd;AACA,MAAIC,eAAe,GAAG,CAAC,CAAvB;;AACA,OAAK,IAAIC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGJ,KAAK,CAACK,MAA1B,EAAkC,EAAED,CAApC,EAAuC;AACrC,UAAMrB,IAAI,GAAGiB,KAAK,CAACI,CAAD,CAAlB;;AACA,QAAI,CAACrB,IAAL,EAAW;AACT;AACD;;AACD,UAAMuB,KAAK,GAAGxB,SAAS,CAACC,IAAD,CAAvB;;AACA,QAAIuB,KAAJ,EAAW;AACTJ,MAAAA,OAAO,CAACK,IAAR,CAAaD,KAAb;AACA;AACD,KAToC,CAUrC;;;AACAH,IAAAA,eAAe,GAAGC,CAAlB;AACAF,IAAAA,OAAO,GAAG,EAAV;AACD;;AACD,QAAMM,OAAO,GAAGR,KAAK,CAACS,KAAN,CAAY,CAAZ,EAAeN,eAAe,GAAG,CAAjC,EAAoCO,IAApC,CAAyC,IAAzC,CAAhB;AACA,SAAO;AAAEF,IAAAA,OAAF;AAAWN,IAAAA;AAAX,GAAP;AACD","sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\ninterface HermesStackLocationNative {\n type: 'NATIVE';\n}\n\ninterface HermesStackLocationSource {\n type: 'SOURCE';\n sourceUrl: string;\n line1Based: number;\n column1Based: number;\n}\n\ninterface HermesStackLocationBytecode {\n type: 'BYTECODE';\n sourceUrl: string;\n line1Based: number;\n virtualOffset0Based: number;\n}\n\ntype HermesStackLocation =\n | HermesStackLocationNative\n | HermesStackLocationSource\n | HermesStackLocationBytecode;\n\ninterface HermesStackEntryFrame {\n type: 'FRAME';\n location: HermesStackLocation;\n functionName: string;\n}\n\ninterface HermesStackEntrySkipped {\n type: 'SKIPPED';\n count: number;\n}\n\ntype HermesStackEntry = HermesStackEntryFrame | HermesStackEntrySkipped;\n\nexport interface HermesParsedStack {\n message: string;\n entries: HermesStackEntry[];\n}\n\n// Capturing groups:\n// 1. function name\n// 2. is this a native stack frame?\n// 3. is this a bytecode address or a source location?\n// 4. source URL (filename)\n// 5. line number (1 based)\n// 6. column number (1 based) or virtual offset (0 based)\nconst RE_FRAME =\n /^ {0,4}at (.+?)(?: \\((native)\\)?| \\((address at )?(.*?):(\\d+):(\\d+)\\))$/;\n\n// Capturing groups:\n// 1. count of skipped frames\nconst RE_SKIPPED = /^ {0,4}... skipping (\\d) frames$/;\n\nfunction parseLine(line: string): HermesStackEntry | undefined {\n const asFrame = line.match(RE_FRAME);\n if (asFrame) {\n return {\n type: 'FRAME',\n functionName: asFrame[1],\n location:\n asFrame[2] === 'native'\n ? { type: 'NATIVE' }\n : asFrame[3] === 'address at '\n ? {\n type: 'BYTECODE',\n sourceUrl: asFrame[4],\n line1Based: Number.parseInt(asFrame[5], 10),\n virtualOffset0Based: Number.parseInt(asFrame[6], 10),\n }\n : {\n type: 'SOURCE',\n sourceUrl: asFrame[4],\n line1Based: Number.parseInt(asFrame[5], 10),\n column1Based: Number.parseInt(asFrame[6], 10),\n },\n };\n }\n const asSkipped = line.match(RE_SKIPPED);\n if (asSkipped) {\n return {\n type: 'SKIPPED',\n count: Number.parseInt(asSkipped[1], 10),\n };\n }\n return undefined;\n}\n\nexport default function parseHermesStack(stack: string): HermesParsedStack {\n const lines = stack.split(/\\n/);\n let entries = [];\n let lastMessageLine = -1;\n for (let i = 0; i < lines.length; ++i) {\n const line = lines[i];\n if (!line) {\n continue;\n }\n const entry = parseLine(line);\n if (entry) {\n entries.push(entry);\n continue;\n }\n // No match - we're still in the message\n lastMessageLine = i;\n entries = [];\n }\n const message = lines.slice(0, lastMessageLine + 1).join('\\n');\n return { message, entries };\n}\n"]}
@@ -9,6 +9,8 @@ var _deepEqual = _interopRequireDefault(require("deep-equal"));
9
9
 
10
10
  var React = _interopRequireWildcard(require("react"));
11
11
 
12
+ var _parseErrorStack = _interopRequireDefault(require("./parseErrorStack"));
13
+
12
14
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
13
15
 
14
16
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -31,21 +33,7 @@ function useDevToolsBase(ref, callback) {
31
33
  return undefined;
32
34
  }
33
35
 
34
- const frames = stack.split('\n').slice(2).map(line => {
35
- const partMatch = line.match(/^((.+)@)?(.+):(\d+):(\d+)$/);
36
-
37
- if (!partMatch) {
38
- return null;
39
- }
40
-
41
- const [,, methodName, file, lineNumber, column] = partMatch;
42
- return {
43
- methodName,
44
- file,
45
- lineNumber: Number(lineNumber),
46
- column: Number(column)
47
- };
48
- }).filter(Boolean);
36
+ const frames = (0, _parseErrorStack.default)(stack).slice(2).filter(frame => frame.file !== '[native code]');
49
37
  const urlMatch = (_frames$ = frames[0]) === null || _frames$ === void 0 ? void 0 : (_frames$$file = _frames$.file) === null || _frames$$file === void 0 ? void 0 : _frames$$file.match(/^https?:\/\/.+(:\d+)?\//);
50
38
 
51
39
  if (!urlMatch) {
@@ -1 +1 @@
1
- {"version":3,"sources":["useDevToolsBase.tsx"],"names":["useDevToolsBase","ref","callback","lastStateRef","React","useRef","lastActionRef","callbackRef","lastResetRef","undefined","useEffect","current","symbolicate","stack","frames","split","slice","map","line","partMatch","match","methodName","file","lineNumber","column","Number","filter","Boolean","urlMatch","result","fetch","method","body","JSON","stringify","then","res","json","it","collapse","join","err","pendingPromiseRef","Promise","resolve","send","useCallback","data","catch","timer","unsubscribeAction","unsubscribeState","initialize","setInterval","clearTimeout","state","getRootState","type","navigation","addListener","e","action","noop","lastState","lastChange","resetRoot"],"mappings":";;;;;;;AAKA;;AACA;;;;;;;;AA6Be,SAASA,eAAT,CACbC,GADa,EAEbC,QAFa,EAGb;AACA,QAAMC,YAAY,GAAGC,KAAK,CAACC,MAAN,EAArB;AACA,QAAMC,aAAa,GACjBF,KAAK,CAACC,MAAN,EADF;AAIA,QAAME,WAAW,GAAGH,KAAK,CAACC,MAAN,CAAaH,QAAb,CAApB;AACA,QAAMM,YAAY,GAAGJ,KAAK,CAACC,MAAN,CAA0CI,SAA1C,CAArB;AAEAL,EAAAA,KAAK,CAACM,SAAN,CAAgB,MAAM;AACpBH,IAAAA,WAAW,CAACI,OAAZ,GAAsBT,QAAtB;AACD,GAFD;;AAIA,QAAMU,WAAW,GAAG,MAAOC,KAAP,IAAqC;AAAA;;AACvD,QAAIA,KAAK,IAAI,IAAb,EAAmB;AACjB,aAAOJ,SAAP;AACD;;AAED,UAAMK,MAAM,GAAGD,KAAK,CACjBE,KADY,CACN,IADM,EAEZC,KAFY,CAEN,CAFM,EAGZC,GAHY,CAGPC,IAAD,IAA6B;AAChC,YAAMC,SAAS,GAAGD,IAAI,CAACE,KAAL,CAAW,4BAAX,CAAlB;;AAEA,UAAI,CAACD,SAAL,EAAgB;AACd,eAAO,IAAP;AACD;;AAED,YAAM,IAAKE,UAAL,EAAiBC,IAAjB,EAAuBC,UAAvB,EAAmCC,MAAnC,IAA6CL,SAAnD;AAEA,aAAO;AACLE,QAAAA,UADK;AAELC,QAAAA,IAFK;AAGLC,QAAAA,UAAU,EAAEE,MAAM,CAACF,UAAD,CAHb;AAILC,QAAAA,MAAM,EAAEC,MAAM,CAACD,MAAD;AAJT,OAAP;AAMD,KAlBY,EAmBZE,MAnBY,CAmBLC,OAnBK,CAAf;AAqBA,UAAMC,QAAQ,eAAGd,MAAM,CAAC,CAAD,CAAT,8DAAG,SAAWQ,IAAd,kDAAG,cAAiBF,KAAjB,CAAuB,yBAAvB,CAAjB;;AAEA,QAAI,CAACQ,QAAL,EAAe;AACb,aAAOf,KAAP;AACD;;AAED,QAAI;AACF,YAAMgB,MAAmB,GAAG,MAAMC,KAAK,CAAE,GAAEF,QAAQ,CAAC,CAAD,CAAI,aAAhB,EAA8B;AACnEG,QAAAA,MAAM,EAAE,MAD2D;AAEnEC,QAAAA,IAAI,EAAEC,IAAI,CAACC,SAAL,CAAe;AAAErB,UAAAA,KAAK,EAAEC;AAAT,SAAf;AAF6D,OAA9B,CAAL,CAG/BqB,IAH+B,CAGzBC,GAAD,IAASA,GAAG,CAACC,IAAJ,EAHiB,CAAlC;AAKA,aAAOR,MAAM,CAAChB,KAAP,CACJa,MADI,CACIY,EAAD,IAAQ,CAACA,EAAE,CAACC,QADf,EAEJtB,GAFI,CAGH,CAAC;AAAEI,QAAAA,UAAF;AAAcC,QAAAA,IAAd;AAAoBC,QAAAA,UAApB;AAAgCC,QAAAA;AAAhC,OAAD,KACG,GAAEH,UAAW,IAAGC,IAAK,IAAGC,UAAW,IAAGC,MAAO,EAJ7C,EAMJgB,IANI,CAMC,IAND,CAAP;AAOD,KAbD,CAaE,OAAOC,GAAP,EAAY;AACZ,aAAO5B,KAAP;AACD;AACF,GAhDD;;AAkDA,QAAM6B,iBAAiB,GAAGtC,KAAK,CAACC,MAAN,CAA4BsC,OAAO,CAACC,OAAR,EAA5B,CAA1B;AAEA,QAAMC,IAAI,GAAGzC,KAAK,CAAC0C,WAAN,CAAmBC,IAAD,IAAsB;AACnD;AACA;AACAL,IAAAA,iBAAiB,CAAC/B,OAAlB,GAA4B+B,iBAAiB,CAAC/B,OAAlB,CACzBqC,KADyB,CACnB,MAAM,CACX;AACD,KAHyB,EAIzBb,IAJyB,CAIpB,YAAY;AAChB,UAAIY,IAAI,CAAClC,KAAT,EAAgB;AACd,YAAIA,KAAJ;;AAEA,YAAI;AACFA,UAAAA,KAAK,GAAG,MAAMD,WAAW,CAACmC,IAAI,CAAClC,KAAN,CAAzB;AACD,SAFD,CAEE,OAAO4B,GAAP,EAAY,CACZ;AACD;;AAEDlC,QAAAA,WAAW,CAACI,OAAZ,CAAoB,EAAE,GAAGoC,IAAL;AAAWlC,UAAAA;AAAX,SAApB;AACD,OAVD,MAUO;AACLN,QAAAA,WAAW,CAACI,OAAZ,CAAoBoC,IAApB;AACD;AACF,KAlByB,CAA5B;AAmBD,GAtBY,EAsBV,EAtBU,CAAb;AAwBA3C,EAAAA,KAAK,CAACM,SAAN,CAAgB,MAAM;AACpB,QAAIuC,KAAJ;AACA,QAAIC,iBAAJ;AACA,QAAIC,gBAAJ;;AAEA,UAAMC,UAAU,GAAG,YAAY;AAC7B,UAAI,CAACnD,GAAG,CAACU,OAAT,EAAkB;AAChB;AACA,cAAM,IAAIgC,OAAJ,CAAmBC,OAAD,IAAa;AACnCK,UAAAA,KAAK,GAAGI,WAAW,CAAC,MAAM;AACxB,gBAAIpD,GAAG,CAACU,OAAR,EAAiB;AACfiC,cAAAA,OAAO;AACPU,cAAAA,YAAY,CAACL,KAAD,CAAZ;AACA,oBAAMM,KAAK,GAAGtD,GAAG,CAACU,OAAJ,CAAY6C,YAAZ,EAAd;AAEArD,cAAAA,YAAY,CAACQ,OAAb,GAAuB4C,KAAvB;AACAhD,cAAAA,WAAW,CAACI,OAAZ,CAAoB;AAAE8C,gBAAAA,IAAI,EAAE,MAAR;AAAgBF,gBAAAA;AAAhB,eAApB;AACD;AACF,WATkB,EAShB,GATgB,CAAnB;AAUD,SAXK,CAAN;AAYD;;AAED,YAAMG,UAAU,GAAGzD,GAAG,CAACU,OAAvB;AAEAuC,MAAAA,iBAAiB,GAAGQ,UAAU,CAACC,WAAX,CAAuB,mBAAvB,EAA6CC,CAAD,IAAO;AACrE,cAAMC,MAAM,GAAGD,CAAC,CAACb,IAAF,CAAOc,MAAtB;;AAEA,YAAID,CAAC,CAACb,IAAF,CAAOe,IAAX,EAAiB;AACf;AACAjB,UAAAA,IAAI,CAAC;AACHY,YAAAA,IAAI,EAAE,QADH;AAEHI,YAAAA,MAFG;AAGHN,YAAAA,KAAK,EAAEpD,YAAY,CAACQ,OAHjB;AAIHE,YAAAA,KAAK,EAAE+C,CAAC,CAACb,IAAF,CAAOlC;AAJX,WAAD,CAAJ;AAMD,SARD,MAQO;AACLP,UAAAA,aAAa,CAACK,OAAd,GAAwBiD,CAAC,CAACb,IAA1B;AACD;AACF,OAdmB,CAApB;AAgBAI,MAAAA,gBAAgB,GAAGO,UAAU,CAACC,WAAX,CAAuB,OAAvB,EAAiCC,CAAD,IAAO;AACxD;AACA,YACEpD,YAAY,CAACG,OAAb,IACA,wBAAUH,YAAY,CAACG,OAAvB,EAAgCiD,CAAC,CAACb,IAAF,CAAOQ,KAAvC,CAFF,EAGE;AACApD,UAAAA,YAAY,CAACQ,OAAb,GAAuBF,SAAvB;AACA;AACD;;AAED,cAAM8C,KAAK,GAAGG,UAAU,CAACF,YAAX,EAAd;AACA,cAAMO,SAAS,GAAG5D,YAAY,CAACQ,OAA/B;AACA,cAAMqD,UAAU,GAAG1D,aAAa,CAACK,OAAjC;AAEAL,QAAAA,aAAa,CAACK,OAAd,GAAwBF,SAAxB;AACAN,QAAAA,YAAY,CAACQ,OAAb,GAAuB4C,KAAvB,CAfwD,CAiBxD;;AACA,YAAIS,UAAU,KAAKvD,SAAf,IAA4B,wBAAU8C,KAAV,EAAiBQ,SAAjB,CAAhC,EAA6D;AAC3D;AACD;;AAEDlB,QAAAA,IAAI,CAAC;AACHY,UAAAA,IAAI,EAAE,QADH;AAEHI,UAAAA,MAAM,EAAEG,UAAU,GAAGA,UAAU,CAACH,MAAd,GAAuB;AAAEJ,YAAAA,IAAI,EAAE;AAAR,WAFtC;AAGHF,UAAAA,KAHG;AAIH1C,UAAAA,KAAK,EAAEmD,UAAF,aAAEA,UAAF,uBAAEA,UAAU,CAAEnD;AAJhB,SAAD,CAAJ;AAMD,OA5BkB,CAAnB;AA6BD,KAhED;;AAkEAuC,IAAAA,UAAU;AAEV,WAAO,MAAM;AAAA;;AACX,4BAAAF,iBAAiB,UAAjB;AACA,2BAAAC,gBAAgB,UAAhB;AACAG,MAAAA,YAAY,CAACL,KAAD,CAAZ;AACD,KAJD;AAKD,GA9ED,EA8EG,CAAChD,GAAD,EAAM4C,IAAN,CA9EH;AAgFA,QAAMoB,SAAS,GAAG7D,KAAK,CAAC0C,WAAN,CACfS,KAAD,IAA4B;AAC1B,QAAItD,GAAG,CAACU,OAAR,EAAiB;AACfH,MAAAA,YAAY,CAACG,OAAb,GAAuB4C,KAAvB;AACAtD,MAAAA,GAAG,CAACU,OAAJ,CAAYsD,SAAZ,CAAsBV,KAAtB;AACD;AACF,GANe,EAOhB,CAACtD,GAAD,CAPgB,CAAlB;AAUA,SAAO;AAAEgE,IAAAA;AAAF,GAAP;AACD","sourcesContent":["import type {\n NavigationAction,\n NavigationContainerRef,\n NavigationState,\n} from '@react-navigation/core';\nimport deepEqual from 'deep-equal';\nimport * as React from 'react';\n\ntype StackFrame = {\n lineNumber: number | null;\n column: number | null;\n file: string | null;\n methodName: string;\n};\n\ntype StackFrameResult = StackFrame & {\n collapse: boolean;\n};\n\ntype StackResult = {\n stack: StackFrameResult[];\n};\n\ntype InitData = {\n type: 'init';\n state: NavigationState | undefined;\n};\n\ntype ActionData = {\n type: 'action';\n action: NavigationAction;\n state: NavigationState | undefined;\n stack: string | undefined;\n};\n\nexport default function useDevToolsBase(\n ref: React.RefObject<NavigationContainerRef<any>>,\n callback: (result: InitData | ActionData) => void\n) {\n const lastStateRef = React.useRef<NavigationState | undefined>();\n const lastActionRef =\n React.useRef<\n { action: NavigationAction; stack: string | undefined } | undefined\n >();\n const callbackRef = React.useRef(callback);\n const lastResetRef = React.useRef<NavigationState | undefined>(undefined);\n\n React.useEffect(() => {\n callbackRef.current = callback;\n });\n\n const symbolicate = async (stack: string | undefined) => {\n if (stack == null) {\n return undefined;\n }\n\n const frames = stack\n .split('\\n')\n .slice(2)\n .map((line): StackFrame | null => {\n const partMatch = line.match(/^((.+)@)?(.+):(\\d+):(\\d+)$/);\n\n if (!partMatch) {\n return null;\n }\n\n const [, , methodName, file, lineNumber, column] = partMatch;\n\n return {\n methodName,\n file,\n lineNumber: Number(lineNumber),\n column: Number(column),\n };\n })\n .filter(Boolean) as StackFrame[];\n\n const urlMatch = frames[0]?.file?.match(/^https?:\\/\\/.+(:\\d+)?\\//);\n\n if (!urlMatch) {\n return stack;\n }\n\n try {\n const result: StackResult = await fetch(`${urlMatch[0]}symbolicate`, {\n method: 'POST',\n body: JSON.stringify({ stack: frames }),\n }).then((res) => res.json());\n\n return result.stack\n .filter((it) => !it.collapse)\n .map(\n ({ methodName, file, lineNumber, column }) =>\n `${methodName}@${file}:${lineNumber}:${column}`\n )\n .join('\\n');\n } catch (err) {\n return stack;\n }\n };\n\n const pendingPromiseRef = React.useRef<Promise<void>>(Promise.resolve());\n\n const send = React.useCallback((data: ActionData) => {\n // We need to make sure that our callbacks executed in the same order\n // So we add check if the last promise is settled before sending the next one\n pendingPromiseRef.current = pendingPromiseRef.current\n .catch(() => {\n // Ignore any errors from the last promise\n })\n .then(async () => {\n if (data.stack) {\n let stack: string | undefined;\n\n try {\n stack = await symbolicate(data.stack);\n } catch (err) {\n // Ignore errors from symbolicate\n }\n\n callbackRef.current({ ...data, stack });\n } else {\n callbackRef.current(data);\n }\n });\n }, []);\n\n React.useEffect(() => {\n let timer: any;\n let unsubscribeAction: (() => void) | undefined;\n let unsubscribeState: (() => void) | undefined;\n\n const initialize = async () => {\n if (!ref.current) {\n // If the navigation object isn't ready yet, wait for it\n await new Promise<void>((resolve) => {\n timer = setInterval(() => {\n if (ref.current) {\n resolve();\n clearTimeout(timer);\n const state = ref.current.getRootState();\n\n lastStateRef.current = state;\n callbackRef.current({ type: 'init', state });\n }\n }, 100);\n });\n }\n\n const navigation = ref.current!;\n\n unsubscribeAction = navigation.addListener('__unsafe_action__', (e) => {\n const action = e.data.action;\n\n if (e.data.noop) {\n // Even if the state didn't change, it's useful to show the action\n send({\n type: 'action',\n action,\n state: lastStateRef.current,\n stack: e.data.stack,\n });\n } else {\n lastActionRef.current = e.data;\n }\n });\n\n unsubscribeState = navigation.addListener('state', (e) => {\n // Don't show the action in dev tools if the state is what we sent to reset earlier\n if (\n lastResetRef.current &&\n deepEqual(lastResetRef.current, e.data.state)\n ) {\n lastStateRef.current = undefined;\n return;\n }\n\n const state = navigation.getRootState();\n const lastState = lastStateRef.current;\n const lastChange = lastActionRef.current;\n\n lastActionRef.current = undefined;\n lastStateRef.current = state;\n\n // If we don't have an action and the state didn't change, then it's probably extraneous\n if (lastChange === undefined && deepEqual(state, lastState)) {\n return;\n }\n\n send({\n type: 'action',\n action: lastChange ? lastChange.action : { type: '@@UNKNOWN' },\n state,\n stack: lastChange?.stack,\n });\n });\n };\n\n initialize();\n\n return () => {\n unsubscribeAction?.();\n unsubscribeState?.();\n clearTimeout(timer);\n };\n }, [ref, send]);\n\n const resetRoot = React.useCallback(\n (state: NavigationState) => {\n if (ref.current) {\n lastResetRef.current = state;\n ref.current.resetRoot(state);\n }\n },\n [ref]\n );\n\n return { resetRoot };\n}\n"]}
1
+ {"version":3,"sources":["useDevToolsBase.tsx"],"names":["useDevToolsBase","ref","callback","lastStateRef","React","useRef","lastActionRef","callbackRef","lastResetRef","undefined","useEffect","current","symbolicate","stack","frames","slice","filter","frame","file","urlMatch","match","result","fetch","method","body","JSON","stringify","then","res","json","it","collapse","map","methodName","lineNumber","column","join","err","pendingPromiseRef","Promise","resolve","send","useCallback","data","catch","timer","unsubscribeAction","unsubscribeState","initialize","setInterval","clearTimeout","state","getRootState","type","navigation","addListener","e","action","noop","lastState","lastChange","resetRoot"],"mappings":"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","sourcesContent":["import type {\n NavigationAction,\n NavigationContainerRef,\n NavigationState,\n} from '@react-navigation/core';\nimport deepEqual from 'deep-equal';\nimport * as React from 'react';\n\nimport parseErrorStack from './parseErrorStack';\n\ntype StackFrame = {\n lineNumber: number | null;\n column: number | null;\n file: string | null;\n methodName: string;\n};\n\ntype StackFrameResult = StackFrame & {\n collapse: boolean;\n};\n\ntype StackResult = {\n stack: StackFrameResult[];\n};\n\ntype InitData = {\n type: 'init';\n state: NavigationState | undefined;\n};\n\ntype ActionData = {\n type: 'action';\n action: NavigationAction;\n state: NavigationState | undefined;\n stack: string | undefined;\n};\n\nexport default function useDevToolsBase(\n ref: React.RefObject<NavigationContainerRef<any>>,\n callback: (result: InitData | ActionData) => void\n) {\n const lastStateRef = React.useRef<NavigationState | undefined>();\n const lastActionRef =\n React.useRef<\n { action: NavigationAction; stack: string | undefined } | undefined\n >();\n const callbackRef = React.useRef(callback);\n const lastResetRef = React.useRef<NavigationState | undefined>(undefined);\n\n React.useEffect(() => {\n callbackRef.current = callback;\n });\n\n const symbolicate = async (stack: string | undefined) => {\n if (stack == null) {\n return undefined;\n }\n\n const frames = parseErrorStack(stack)\n .slice(2)\n .filter((frame) => frame.file !== '[native code]');\n\n const urlMatch = frames[0]?.file?.match(/^https?:\\/\\/.+(:\\d+)?\\//);\n\n if (!urlMatch) {\n return stack;\n }\n\n try {\n const result: StackResult = await fetch(`${urlMatch[0]}symbolicate`, {\n method: 'POST',\n body: JSON.stringify({ stack: frames }),\n }).then((res) => res.json());\n\n return result.stack\n .filter((it) => !it.collapse)\n .map(\n ({ methodName, file, lineNumber, column }) =>\n `${methodName}@${file}:${lineNumber}:${column}`\n )\n .join('\\n');\n } catch (err) {\n return stack;\n }\n };\n\n const pendingPromiseRef = React.useRef<Promise<void>>(Promise.resolve());\n\n const send = React.useCallback((data: ActionData) => {\n // We need to make sure that our callbacks executed in the same order\n // So we add check if the last promise is settled before sending the next one\n pendingPromiseRef.current = pendingPromiseRef.current\n .catch(() => {\n // Ignore any errors from the last promise\n })\n .then(async () => {\n if (data.stack) {\n let stack: string | undefined;\n\n try {\n stack = await symbolicate(data.stack);\n } catch (err) {\n // Ignore errors from symbolicate\n }\n\n callbackRef.current({ ...data, stack });\n } else {\n callbackRef.current(data);\n }\n });\n }, []);\n\n React.useEffect(() => {\n let timer: any;\n let unsubscribeAction: (() => void) | undefined;\n let unsubscribeState: (() => void) | undefined;\n\n const initialize = async () => {\n if (!ref.current) {\n // If the navigation object isn't ready yet, wait for it\n await new Promise<void>((resolve) => {\n timer = setInterval(() => {\n if (ref.current) {\n resolve();\n clearTimeout(timer);\n const state = ref.current.getRootState();\n\n lastStateRef.current = state;\n callbackRef.current({ type: 'init', state });\n }\n }, 100);\n });\n }\n\n const navigation = ref.current!;\n\n unsubscribeAction = navigation.addListener('__unsafe_action__', (e) => {\n const action = e.data.action;\n\n if (e.data.noop) {\n // Even if the state didn't change, it's useful to show the action\n send({\n type: 'action',\n action,\n state: lastStateRef.current,\n stack: e.data.stack,\n });\n } else {\n lastActionRef.current = e.data;\n }\n });\n\n unsubscribeState = navigation.addListener('state', (e) => {\n // Don't show the action in dev tools if the state is what we sent to reset earlier\n if (\n lastResetRef.current &&\n deepEqual(lastResetRef.current, e.data.state)\n ) {\n lastStateRef.current = undefined;\n return;\n }\n\n const state = navigation.getRootState();\n const lastState = lastStateRef.current;\n const lastChange = lastActionRef.current;\n\n lastActionRef.current = undefined;\n lastStateRef.current = state;\n\n // If we don't have an action and the state didn't change, then it's probably extraneous\n if (lastChange === undefined && deepEqual(state, lastState)) {\n return;\n }\n\n send({\n type: 'action',\n action: lastChange ? lastChange.action : { type: '@@UNKNOWN' },\n state,\n stack: lastChange?.stack,\n });\n });\n };\n\n initialize();\n\n return () => {\n unsubscribeAction?.();\n unsubscribeState?.();\n clearTimeout(timer);\n };\n }, [ref, send]);\n\n const resetRoot = React.useCallback(\n (state: NavigationState) => {\n if (ref.current) {\n lastResetRef.current = state;\n ref.current.resetRoot(state);\n }\n },\n [ref]\n );\n\n return { resetRoot };\n}\n"]}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
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
+ import * as stacktraceParser from 'stacktrace-parser';
8
+ import parseHermesStack from './parseHermesStack';
9
+
10
+ function convertHermesStack(stack) {
11
+ const frames = [];
12
+
13
+ for (const entry of stack.entries) {
14
+ if (entry.type !== 'FRAME') {
15
+ continue;
16
+ }
17
+
18
+ const {
19
+ location,
20
+ functionName
21
+ } = entry;
22
+
23
+ if (location.type === 'NATIVE') {
24
+ continue;
25
+ }
26
+
27
+ frames.push({
28
+ methodName: functionName,
29
+ file: location.sourceUrl,
30
+ lineNumber: location.line1Based,
31
+ column: location.type === 'SOURCE' ? location.column1Based - 1 : location.virtualOffset0Based
32
+ });
33
+ }
34
+
35
+ return frames;
36
+ }
37
+
38
+ function parseErrorStack(errorStack) {
39
+ if (!errorStack) {
40
+ return [];
41
+ }
42
+
43
+ const parsedStack = Array.isArray(errorStack) ? errorStack : global.HermesInternal ? convertHermesStack(parseHermesStack(errorStack)) : stacktraceParser.parse(errorStack).map(frame => ({ ...frame,
44
+ column: frame.column != null ? frame.column - 1 : null
45
+ }));
46
+ return parsedStack;
47
+ }
48
+
49
+ export default parseErrorStack;
50
+ //# sourceMappingURL=parseErrorStack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["parseErrorStack.tsx"],"names":["stacktraceParser","parseHermesStack","convertHermesStack","stack","frames","entry","entries","type","location","functionName","push","methodName","file","sourceUrl","lineNumber","line1Based","column","column1Based","virtualOffset0Based","parseErrorStack","errorStack","parsedStack","Array","isArray","global","HermesInternal","parse","map","frame"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AAEA,OAAO,KAAKA,gBAAZ,MAAkC,mBAAlC;AAEA,OAAOC,gBAAP,MAAoD,oBAApD;;AASA,SAASC,kBAAT,CAA4BC,KAA5B,EAAoE;AAClE,QAAMC,MAAM,GAAG,EAAf;;AACA,OAAK,MAAMC,KAAX,IAAoBF,KAAK,CAACG,OAA1B,EAAmC;AACjC,QAAID,KAAK,CAACE,IAAN,KAAe,OAAnB,EAA4B;AAC1B;AACD;;AACD,UAAM;AAAEC,MAAAA,QAAF;AAAYC,MAAAA;AAAZ,QAA6BJ,KAAnC;;AACA,QAAIG,QAAQ,CAACD,IAAT,KAAkB,QAAtB,EAAgC;AAC9B;AACD;;AACDH,IAAAA,MAAM,CAACM,IAAP,CAAY;AACVC,MAAAA,UAAU,EAAEF,YADF;AAEVG,MAAAA,IAAI,EAAEJ,QAAQ,CAACK,SAFL;AAGVC,MAAAA,UAAU,EAAEN,QAAQ,CAACO,UAHX;AAIVC,MAAAA,MAAM,EACJR,QAAQ,CAACD,IAAT,KAAkB,QAAlB,GACIC,QAAQ,CAACS,YAAT,GAAwB,CAD5B,GAEIT,QAAQ,CAACU;AAPL,KAAZ;AASD;;AACD,SAAOd,MAAP;AACD;;AAED,SAASe,eAAT,CAAyBC,UAAzB,EAA2E;AACzE,MAAI,CAACA,UAAL,EAAiB;AACf,WAAO,EAAP;AACD;;AAED,QAAMC,WAAW,GAAGC,KAAK,CAACC,OAAN,CAAcH,UAAd,IAChBA,UADgB,GAEfI,MAAD,CAAgBC,cAAhB,GACAvB,kBAAkB,CAACD,gBAAgB,CAACmB,UAAD,CAAjB,CADlB,GAEApB,gBAAgB,CAAC0B,KAAjB,CAAuBN,UAAvB,EAAmCO,GAAnC,CAAwCC,KAAD,KAAY,EACjD,GAAGA,KAD8C;AAEjDZ,IAAAA,MAAM,EAAEY,KAAK,CAACZ,MAAN,IAAgB,IAAhB,GAAuBY,KAAK,CAACZ,MAAN,GAAe,CAAtC,GAA0C;AAFD,GAAZ,CAAvC,CAJJ;AASA,SAAOK,WAAP;AACD;;AAED,eAAeF,eAAf","sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport * as stacktraceParser from 'stacktrace-parser';\n\nimport parseHermesStack, { HermesParsedStack } from './parseHermesStack';\n\ninterface StackFrame {\n methodName: string;\n file: string;\n lineNumber: number;\n column: number;\n}\n\nfunction convertHermesStack(stack: HermesParsedStack): StackFrame[] {\n const frames = [];\n for (const entry of stack.entries) {\n if (entry.type !== 'FRAME') {\n continue;\n }\n const { location, functionName } = entry;\n if (location.type === 'NATIVE') {\n continue;\n }\n frames.push({\n methodName: functionName,\n file: location.sourceUrl,\n lineNumber: location.line1Based,\n column:\n location.type === 'SOURCE'\n ? location.column1Based - 1\n : location.virtualOffset0Based,\n });\n }\n return frames;\n}\n\nfunction parseErrorStack(errorStack?: string | StackFrame[]): StackFrame[] {\n if (!errorStack) {\n return [];\n }\n\n const parsedStack = Array.isArray(errorStack)\n ? errorStack\n : (global as any).HermesInternal\n ? convertHermesStack(parseHermesStack(errorStack))\n : stacktraceParser.parse(errorStack).map((frame) => ({\n ...frame,\n column: frame.column != null ? frame.column - 1 : null,\n }));\n\n return parsedStack as StackFrame[];\n}\n\nexport default parseErrorStack;\n"]}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
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
+ // Capturing groups:
8
+ // 1. function name
9
+ // 2. is this a native stack frame?
10
+ // 3. is this a bytecode address or a source location?
11
+ // 4. source URL (filename)
12
+ // 5. line number (1 based)
13
+ // 6. column number (1 based) or virtual offset (0 based)
14
+ const RE_FRAME = /^ {0,4}at (.+?)(?: \((native)\)?| \((address at )?(.*?):(\d+):(\d+)\))$/; // Capturing groups:
15
+ // 1. count of skipped frames
16
+
17
+ const RE_SKIPPED = /^ {0,4}... skipping (\d) frames$/;
18
+
19
+ function parseLine(line) {
20
+ const asFrame = line.match(RE_FRAME);
21
+
22
+ if (asFrame) {
23
+ return {
24
+ type: 'FRAME',
25
+ functionName: asFrame[1],
26
+ location: asFrame[2] === 'native' ? {
27
+ type: 'NATIVE'
28
+ } : asFrame[3] === 'address at ' ? {
29
+ type: 'BYTECODE',
30
+ sourceUrl: asFrame[4],
31
+ line1Based: Number.parseInt(asFrame[5], 10),
32
+ virtualOffset0Based: Number.parseInt(asFrame[6], 10)
33
+ } : {
34
+ type: 'SOURCE',
35
+ sourceUrl: asFrame[4],
36
+ line1Based: Number.parseInt(asFrame[5], 10),
37
+ column1Based: Number.parseInt(asFrame[6], 10)
38
+ }
39
+ };
40
+ }
41
+
42
+ const asSkipped = line.match(RE_SKIPPED);
43
+
44
+ if (asSkipped) {
45
+ return {
46
+ type: 'SKIPPED',
47
+ count: Number.parseInt(asSkipped[1], 10)
48
+ };
49
+ }
50
+
51
+ return undefined;
52
+ }
53
+
54
+ export default function parseHermesStack(stack) {
55
+ const lines = stack.split(/\n/);
56
+ let entries = [];
57
+ let lastMessageLine = -1;
58
+
59
+ for (let i = 0; i < lines.length; ++i) {
60
+ const line = lines[i];
61
+
62
+ if (!line) {
63
+ continue;
64
+ }
65
+
66
+ const entry = parseLine(line);
67
+
68
+ if (entry) {
69
+ entries.push(entry);
70
+ continue;
71
+ } // No match - we're still in the message
72
+
73
+
74
+ lastMessageLine = i;
75
+ entries = [];
76
+ }
77
+
78
+ const message = lines.slice(0, lastMessageLine + 1).join('\n');
79
+ return {
80
+ message,
81
+ entries
82
+ };
83
+ }
84
+ //# sourceMappingURL=parseHermesStack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["parseHermesStack.tsx"],"names":["RE_FRAME","RE_SKIPPED","parseLine","line","asFrame","match","type","functionName","location","sourceUrl","line1Based","Number","parseInt","virtualOffset0Based","column1Based","asSkipped","count","undefined","parseHermesStack","stack","lines","split","entries","lastMessageLine","i","length","entry","push","message","slice","join"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AA2CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMA,QAAQ,GACZ,yEADF,C,CAGA;AACA;;AACA,MAAMC,UAAU,GAAG,kCAAnB;;AAEA,SAASC,SAAT,CAAmBC,IAAnB,EAA+D;AAC7D,QAAMC,OAAO,GAAGD,IAAI,CAACE,KAAL,CAAWL,QAAX,CAAhB;;AACA,MAAII,OAAJ,EAAa;AACX,WAAO;AACLE,MAAAA,IAAI,EAAE,OADD;AAELC,MAAAA,YAAY,EAAEH,OAAO,CAAC,CAAD,CAFhB;AAGLI,MAAAA,QAAQ,EACNJ,OAAO,CAAC,CAAD,CAAP,KAAe,QAAf,GACI;AAAEE,QAAAA,IAAI,EAAE;AAAR,OADJ,GAEIF,OAAO,CAAC,CAAD,CAAP,KAAe,aAAf,GACA;AACEE,QAAAA,IAAI,EAAE,UADR;AAEEG,QAAAA,SAAS,EAAEL,OAAO,CAAC,CAAD,CAFpB;AAGEM,QAAAA,UAAU,EAAEC,MAAM,CAACC,QAAP,CAAgBR,OAAO,CAAC,CAAD,CAAvB,EAA4B,EAA5B,CAHd;AAIES,QAAAA,mBAAmB,EAAEF,MAAM,CAACC,QAAP,CAAgBR,OAAO,CAAC,CAAD,CAAvB,EAA4B,EAA5B;AAJvB,OADA,GAOA;AACEE,QAAAA,IAAI,EAAE,QADR;AAEEG,QAAAA,SAAS,EAAEL,OAAO,CAAC,CAAD,CAFpB;AAGEM,QAAAA,UAAU,EAAEC,MAAM,CAACC,QAAP,CAAgBR,OAAO,CAAC,CAAD,CAAvB,EAA4B,EAA5B,CAHd;AAIEU,QAAAA,YAAY,EAAEH,MAAM,CAACC,QAAP,CAAgBR,OAAO,CAAC,CAAD,CAAvB,EAA4B,EAA5B;AAJhB;AAbD,KAAP;AAoBD;;AACD,QAAMW,SAAS,GAAGZ,IAAI,CAACE,KAAL,CAAWJ,UAAX,CAAlB;;AACA,MAAIc,SAAJ,EAAe;AACb,WAAO;AACLT,MAAAA,IAAI,EAAE,SADD;AAELU,MAAAA,KAAK,EAAEL,MAAM,CAACC,QAAP,CAAgBG,SAAS,CAAC,CAAD,CAAzB,EAA8B,EAA9B;AAFF,KAAP;AAID;;AACD,SAAOE,SAAP;AACD;;AAED,eAAe,SAASC,gBAAT,CAA0BC,KAA1B,EAA4D;AACzE,QAAMC,KAAK,GAAGD,KAAK,CAACE,KAAN,CAAY,IAAZ,CAAd;AACA,MAAIC,OAAO,GAAG,EAAd;AACA,MAAIC,eAAe,GAAG,CAAC,CAAvB;;AACA,OAAK,IAAIC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGJ,KAAK,CAACK,MAA1B,EAAkC,EAAED,CAApC,EAAuC;AACrC,UAAMrB,IAAI,GAAGiB,KAAK,CAACI,CAAD,CAAlB;;AACA,QAAI,CAACrB,IAAL,EAAW;AACT;AACD;;AACD,UAAMuB,KAAK,GAAGxB,SAAS,CAACC,IAAD,CAAvB;;AACA,QAAIuB,KAAJ,EAAW;AACTJ,MAAAA,OAAO,CAACK,IAAR,CAAaD,KAAb;AACA;AACD,KAToC,CAUrC;;;AACAH,IAAAA,eAAe,GAAGC,CAAlB;AACAF,IAAAA,OAAO,GAAG,EAAV;AACD;;AACD,QAAMM,OAAO,GAAGR,KAAK,CAACS,KAAN,CAAY,CAAZ,EAAeN,eAAe,GAAG,CAAjC,EAAoCO,IAApC,CAAyC,IAAzC,CAAhB;AACA,SAAO;AAAEF,IAAAA,OAAF;AAAWN,IAAAA;AAAX,GAAP;AACD","sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\ninterface HermesStackLocationNative {\n type: 'NATIVE';\n}\n\ninterface HermesStackLocationSource {\n type: 'SOURCE';\n sourceUrl: string;\n line1Based: number;\n column1Based: number;\n}\n\ninterface HermesStackLocationBytecode {\n type: 'BYTECODE';\n sourceUrl: string;\n line1Based: number;\n virtualOffset0Based: number;\n}\n\ntype HermesStackLocation =\n | HermesStackLocationNative\n | HermesStackLocationSource\n | HermesStackLocationBytecode;\n\ninterface HermesStackEntryFrame {\n type: 'FRAME';\n location: HermesStackLocation;\n functionName: string;\n}\n\ninterface HermesStackEntrySkipped {\n type: 'SKIPPED';\n count: number;\n}\n\ntype HermesStackEntry = HermesStackEntryFrame | HermesStackEntrySkipped;\n\nexport interface HermesParsedStack {\n message: string;\n entries: HermesStackEntry[];\n}\n\n// Capturing groups:\n// 1. function name\n// 2. is this a native stack frame?\n// 3. is this a bytecode address or a source location?\n// 4. source URL (filename)\n// 5. line number (1 based)\n// 6. column number (1 based) or virtual offset (0 based)\nconst RE_FRAME =\n /^ {0,4}at (.+?)(?: \\((native)\\)?| \\((address at )?(.*?):(\\d+):(\\d+)\\))$/;\n\n// Capturing groups:\n// 1. count of skipped frames\nconst RE_SKIPPED = /^ {0,4}... skipping (\\d) frames$/;\n\nfunction parseLine(line: string): HermesStackEntry | undefined {\n const asFrame = line.match(RE_FRAME);\n if (asFrame) {\n return {\n type: 'FRAME',\n functionName: asFrame[1],\n location:\n asFrame[2] === 'native'\n ? { type: 'NATIVE' }\n : asFrame[3] === 'address at '\n ? {\n type: 'BYTECODE',\n sourceUrl: asFrame[4],\n line1Based: Number.parseInt(asFrame[5], 10),\n virtualOffset0Based: Number.parseInt(asFrame[6], 10),\n }\n : {\n type: 'SOURCE',\n sourceUrl: asFrame[4],\n line1Based: Number.parseInt(asFrame[5], 10),\n column1Based: Number.parseInt(asFrame[6], 10),\n },\n };\n }\n const asSkipped = line.match(RE_SKIPPED);\n if (asSkipped) {\n return {\n type: 'SKIPPED',\n count: Number.parseInt(asSkipped[1], 10),\n };\n }\n return undefined;\n}\n\nexport default function parseHermesStack(stack: string): HermesParsedStack {\n const lines = stack.split(/\\n/);\n let entries = [];\n let lastMessageLine = -1;\n for (let i = 0; i < lines.length; ++i) {\n const line = lines[i];\n if (!line) {\n continue;\n }\n const entry = parseLine(line);\n if (entry) {\n entries.push(entry);\n continue;\n }\n // No match - we're still in the message\n lastMessageLine = i;\n entries = [];\n }\n const message = lines.slice(0, lastMessageLine + 1).join('\\n');\n return { message, entries };\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import deepEqual from 'deep-equal';
2
2
  import * as React from 'react';
3
+ import parseErrorStack from './parseErrorStack';
3
4
  export default function useDevToolsBase(ref, callback) {
4
5
  const lastStateRef = React.useRef();
5
6
  const lastActionRef = React.useRef();
@@ -16,21 +17,7 @@ export default function useDevToolsBase(ref, callback) {
16
17
  return undefined;
17
18
  }
18
19
 
19
- const frames = stack.split('\n').slice(2).map(line => {
20
- const partMatch = line.match(/^((.+)@)?(.+):(\d+):(\d+)$/);
21
-
22
- if (!partMatch) {
23
- return null;
24
- }
25
-
26
- const [,, methodName, file, lineNumber, column] = partMatch;
27
- return {
28
- methodName,
29
- file,
30
- lineNumber: Number(lineNumber),
31
- column: Number(column)
32
- };
33
- }).filter(Boolean);
20
+ const frames = parseErrorStack(stack).slice(2).filter(frame => frame.file !== '[native code]');
34
21
  const urlMatch = (_frames$ = frames[0]) === null || _frames$ === void 0 ? void 0 : (_frames$$file = _frames$.file) === null || _frames$$file === void 0 ? void 0 : _frames$$file.match(/^https?:\/\/.+(:\d+)?\//);
35
22
 
36
23
  if (!urlMatch) {
@@ -1 +1 @@
1
- {"version":3,"sources":["useDevToolsBase.tsx"],"names":["deepEqual","React","useDevToolsBase","ref","callback","lastStateRef","useRef","lastActionRef","callbackRef","lastResetRef","undefined","useEffect","current","symbolicate","stack","frames","split","slice","map","line","partMatch","match","methodName","file","lineNumber","column","Number","filter","Boolean","urlMatch","result","fetch","method","body","JSON","stringify","then","res","json","it","collapse","join","err","pendingPromiseRef","Promise","resolve","send","useCallback","data","catch","timer","unsubscribeAction","unsubscribeState","initialize","setInterval","clearTimeout","state","getRootState","type","navigation","addListener","e","action","noop","lastState","lastChange","resetRoot"],"mappings":"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","sourcesContent":["import type {\n NavigationAction,\n NavigationContainerRef,\n NavigationState,\n} from '@react-navigation/core';\nimport deepEqual from 'deep-equal';\nimport * as React from 'react';\n\ntype StackFrame = {\n lineNumber: number | null;\n column: number | null;\n file: string | null;\n methodName: string;\n};\n\ntype StackFrameResult = StackFrame & {\n collapse: boolean;\n};\n\ntype StackResult = {\n stack: StackFrameResult[];\n};\n\ntype InitData = {\n type: 'init';\n state: NavigationState | undefined;\n};\n\ntype ActionData = {\n type: 'action';\n action: NavigationAction;\n state: NavigationState | undefined;\n stack: string | undefined;\n};\n\nexport default function useDevToolsBase(\n ref: React.RefObject<NavigationContainerRef<any>>,\n callback: (result: InitData | ActionData) => void\n) {\n const lastStateRef = React.useRef<NavigationState | undefined>();\n const lastActionRef =\n React.useRef<\n { action: NavigationAction; stack: string | undefined } | undefined\n >();\n const callbackRef = React.useRef(callback);\n const lastResetRef = React.useRef<NavigationState | undefined>(undefined);\n\n React.useEffect(() => {\n callbackRef.current = callback;\n });\n\n const symbolicate = async (stack: string | undefined) => {\n if (stack == null) {\n return undefined;\n }\n\n const frames = stack\n .split('\\n')\n .slice(2)\n .map((line): StackFrame | null => {\n const partMatch = line.match(/^((.+)@)?(.+):(\\d+):(\\d+)$/);\n\n if (!partMatch) {\n return null;\n }\n\n const [, , methodName, file, lineNumber, column] = partMatch;\n\n return {\n methodName,\n file,\n lineNumber: Number(lineNumber),\n column: Number(column),\n };\n })\n .filter(Boolean) as StackFrame[];\n\n const urlMatch = frames[0]?.file?.match(/^https?:\\/\\/.+(:\\d+)?\\//);\n\n if (!urlMatch) {\n return stack;\n }\n\n try {\n const result: StackResult = await fetch(`${urlMatch[0]}symbolicate`, {\n method: 'POST',\n body: JSON.stringify({ stack: frames }),\n }).then((res) => res.json());\n\n return result.stack\n .filter((it) => !it.collapse)\n .map(\n ({ methodName, file, lineNumber, column }) =>\n `${methodName}@${file}:${lineNumber}:${column}`\n )\n .join('\\n');\n } catch (err) {\n return stack;\n }\n };\n\n const pendingPromiseRef = React.useRef<Promise<void>>(Promise.resolve());\n\n const send = React.useCallback((data: ActionData) => {\n // We need to make sure that our callbacks executed in the same order\n // So we add check if the last promise is settled before sending the next one\n pendingPromiseRef.current = pendingPromiseRef.current\n .catch(() => {\n // Ignore any errors from the last promise\n })\n .then(async () => {\n if (data.stack) {\n let stack: string | undefined;\n\n try {\n stack = await symbolicate(data.stack);\n } catch (err) {\n // Ignore errors from symbolicate\n }\n\n callbackRef.current({ ...data, stack });\n } else {\n callbackRef.current(data);\n }\n });\n }, []);\n\n React.useEffect(() => {\n let timer: any;\n let unsubscribeAction: (() => void) | undefined;\n let unsubscribeState: (() => void) | undefined;\n\n const initialize = async () => {\n if (!ref.current) {\n // If the navigation object isn't ready yet, wait for it\n await new Promise<void>((resolve) => {\n timer = setInterval(() => {\n if (ref.current) {\n resolve();\n clearTimeout(timer);\n const state = ref.current.getRootState();\n\n lastStateRef.current = state;\n callbackRef.current({ type: 'init', state });\n }\n }, 100);\n });\n }\n\n const navigation = ref.current!;\n\n unsubscribeAction = navigation.addListener('__unsafe_action__', (e) => {\n const action = e.data.action;\n\n if (e.data.noop) {\n // Even if the state didn't change, it's useful to show the action\n send({\n type: 'action',\n action,\n state: lastStateRef.current,\n stack: e.data.stack,\n });\n } else {\n lastActionRef.current = e.data;\n }\n });\n\n unsubscribeState = navigation.addListener('state', (e) => {\n // Don't show the action in dev tools if the state is what we sent to reset earlier\n if (\n lastResetRef.current &&\n deepEqual(lastResetRef.current, e.data.state)\n ) {\n lastStateRef.current = undefined;\n return;\n }\n\n const state = navigation.getRootState();\n const lastState = lastStateRef.current;\n const lastChange = lastActionRef.current;\n\n lastActionRef.current = undefined;\n lastStateRef.current = state;\n\n // If we don't have an action and the state didn't change, then it's probably extraneous\n if (lastChange === undefined && deepEqual(state, lastState)) {\n return;\n }\n\n send({\n type: 'action',\n action: lastChange ? lastChange.action : { type: '@@UNKNOWN' },\n state,\n stack: lastChange?.stack,\n });\n });\n };\n\n initialize();\n\n return () => {\n unsubscribeAction?.();\n unsubscribeState?.();\n clearTimeout(timer);\n };\n }, [ref, send]);\n\n const resetRoot = React.useCallback(\n (state: NavigationState) => {\n if (ref.current) {\n lastResetRef.current = state;\n ref.current.resetRoot(state);\n }\n },\n [ref]\n );\n\n return { resetRoot };\n}\n"]}
1
+ {"version":3,"sources":["useDevToolsBase.tsx"],"names":["deepEqual","React","parseErrorStack","useDevToolsBase","ref","callback","lastStateRef","useRef","lastActionRef","callbackRef","lastResetRef","undefined","useEffect","current","symbolicate","stack","frames","slice","filter","frame","file","urlMatch","match","result","fetch","method","body","JSON","stringify","then","res","json","it","collapse","map","methodName","lineNumber","column","join","err","pendingPromiseRef","Promise","resolve","send","useCallback","data","catch","timer","unsubscribeAction","unsubscribeState","initialize","setInterval","clearTimeout","state","getRootState","type","navigation","addListener","e","action","noop","lastState","lastChange","resetRoot"],"mappings":"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","sourcesContent":["import type {\n NavigationAction,\n NavigationContainerRef,\n NavigationState,\n} from '@react-navigation/core';\nimport deepEqual from 'deep-equal';\nimport * as React from 'react';\n\nimport parseErrorStack from './parseErrorStack';\n\ntype StackFrame = {\n lineNumber: number | null;\n column: number | null;\n file: string | null;\n methodName: string;\n};\n\ntype StackFrameResult = StackFrame & {\n collapse: boolean;\n};\n\ntype StackResult = {\n stack: StackFrameResult[];\n};\n\ntype InitData = {\n type: 'init';\n state: NavigationState | undefined;\n};\n\ntype ActionData = {\n type: 'action';\n action: NavigationAction;\n state: NavigationState | undefined;\n stack: string | undefined;\n};\n\nexport default function useDevToolsBase(\n ref: React.RefObject<NavigationContainerRef<any>>,\n callback: (result: InitData | ActionData) => void\n) {\n const lastStateRef = React.useRef<NavigationState | undefined>();\n const lastActionRef =\n React.useRef<\n { action: NavigationAction; stack: string | undefined } | undefined\n >();\n const callbackRef = React.useRef(callback);\n const lastResetRef = React.useRef<NavigationState | undefined>(undefined);\n\n React.useEffect(() => {\n callbackRef.current = callback;\n });\n\n const symbolicate = async (stack: string | undefined) => {\n if (stack == null) {\n return undefined;\n }\n\n const frames = parseErrorStack(stack)\n .slice(2)\n .filter((frame) => frame.file !== '[native code]');\n\n const urlMatch = frames[0]?.file?.match(/^https?:\\/\\/.+(:\\d+)?\\//);\n\n if (!urlMatch) {\n return stack;\n }\n\n try {\n const result: StackResult = await fetch(`${urlMatch[0]}symbolicate`, {\n method: 'POST',\n body: JSON.stringify({ stack: frames }),\n }).then((res) => res.json());\n\n return result.stack\n .filter((it) => !it.collapse)\n .map(\n ({ methodName, file, lineNumber, column }) =>\n `${methodName}@${file}:${lineNumber}:${column}`\n )\n .join('\\n');\n } catch (err) {\n return stack;\n }\n };\n\n const pendingPromiseRef = React.useRef<Promise<void>>(Promise.resolve());\n\n const send = React.useCallback((data: ActionData) => {\n // We need to make sure that our callbacks executed in the same order\n // So we add check if the last promise is settled before sending the next one\n pendingPromiseRef.current = pendingPromiseRef.current\n .catch(() => {\n // Ignore any errors from the last promise\n })\n .then(async () => {\n if (data.stack) {\n let stack: string | undefined;\n\n try {\n stack = await symbolicate(data.stack);\n } catch (err) {\n // Ignore errors from symbolicate\n }\n\n callbackRef.current({ ...data, stack });\n } else {\n callbackRef.current(data);\n }\n });\n }, []);\n\n React.useEffect(() => {\n let timer: any;\n let unsubscribeAction: (() => void) | undefined;\n let unsubscribeState: (() => void) | undefined;\n\n const initialize = async () => {\n if (!ref.current) {\n // If the navigation object isn't ready yet, wait for it\n await new Promise<void>((resolve) => {\n timer = setInterval(() => {\n if (ref.current) {\n resolve();\n clearTimeout(timer);\n const state = ref.current.getRootState();\n\n lastStateRef.current = state;\n callbackRef.current({ type: 'init', state });\n }\n }, 100);\n });\n }\n\n const navigation = ref.current!;\n\n unsubscribeAction = navigation.addListener('__unsafe_action__', (e) => {\n const action = e.data.action;\n\n if (e.data.noop) {\n // Even if the state didn't change, it's useful to show the action\n send({\n type: 'action',\n action,\n state: lastStateRef.current,\n stack: e.data.stack,\n });\n } else {\n lastActionRef.current = e.data;\n }\n });\n\n unsubscribeState = navigation.addListener('state', (e) => {\n // Don't show the action in dev tools if the state is what we sent to reset earlier\n if (\n lastResetRef.current &&\n deepEqual(lastResetRef.current, e.data.state)\n ) {\n lastStateRef.current = undefined;\n return;\n }\n\n const state = navigation.getRootState();\n const lastState = lastStateRef.current;\n const lastChange = lastActionRef.current;\n\n lastActionRef.current = undefined;\n lastStateRef.current = state;\n\n // If we don't have an action and the state didn't change, then it's probably extraneous\n if (lastChange === undefined && deepEqual(state, lastState)) {\n return;\n }\n\n send({\n type: 'action',\n action: lastChange ? lastChange.action : { type: '@@UNKNOWN' },\n state,\n stack: lastChange?.stack,\n });\n });\n };\n\n initialize();\n\n return () => {\n unsubscribeAction?.();\n unsubscribeState?.();\n clearTimeout(timer);\n };\n }, [ref, send]);\n\n const resetRoot = React.useCallback(\n (state: NavigationState) => {\n if (ref.current) {\n lastResetRef.current = state;\n ref.current.resetRoot(state);\n }\n },\n [ref]\n );\n\n return { resetRoot };\n}\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
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
+ interface StackFrame {
8
+ methodName: string;
9
+ file: string;
10
+ lineNumber: number;
11
+ column: number;
12
+ }
13
+ declare function parseErrorStack(errorStack?: string | StackFrame[]): StackFrame[];
14
+ export default parseErrorStack;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
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
+ interface HermesStackLocationNative {
8
+ type: 'NATIVE';
9
+ }
10
+ interface HermesStackLocationSource {
11
+ type: 'SOURCE';
12
+ sourceUrl: string;
13
+ line1Based: number;
14
+ column1Based: number;
15
+ }
16
+ interface HermesStackLocationBytecode {
17
+ type: 'BYTECODE';
18
+ sourceUrl: string;
19
+ line1Based: number;
20
+ virtualOffset0Based: number;
21
+ }
22
+ declare type HermesStackLocation = HermesStackLocationNative | HermesStackLocationSource | HermesStackLocationBytecode;
23
+ interface HermesStackEntryFrame {
24
+ type: 'FRAME';
25
+ location: HermesStackLocation;
26
+ functionName: string;
27
+ }
28
+ interface HermesStackEntrySkipped {
29
+ type: 'SKIPPED';
30
+ count: number;
31
+ }
32
+ declare type HermesStackEntry = HermesStackEntryFrame | HermesStackEntrySkipped;
33
+ export interface HermesParsedStack {
34
+ message: string;
35
+ entries: HermesStackEntry[];
36
+ }
37
+ export default function parseHermesStack(stack: string): HermesParsedStack;
38
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@react-navigation/devtools",
3
3
  "description": "Developer tools for React Navigation",
4
- "version": "6.0.2",
4
+ "version": "6.0.3",
5
5
  "keywords": [
6
6
  "react",
7
7
  "react-native",
@@ -37,10 +37,11 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "deep-equal": "^2.0.5",
40
- "nanoid": "^3.1.23"
40
+ "nanoid": "^3.1.23",
41
+ "stacktrace-parser": "^0.1.10"
41
42
  },
42
43
  "devDependencies": {
43
- "@react-navigation/core": "^6.0.2",
44
+ "@react-navigation/core": "^6.0.3",
44
45
  "@testing-library/react-native": "^7.2.0",
45
46
  "@types/deep-equal": "^1.0.1",
46
47
  "@types/react": "^17.0.9",
@@ -67,5 +68,5 @@
67
68
  ]
68
69
  ]
69
70
  },
70
- "gitHead": "38ac69f17ee314f96d3d4bcee02349fa4a02d422"
71
+ "gitHead": "66a007b0649e443b528e6875df292563d0ed426c"
71
72
  }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
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 * as stacktraceParser from 'stacktrace-parser';
9
+
10
+ import parseHermesStack, { HermesParsedStack } from './parseHermesStack';
11
+
12
+ interface StackFrame {
13
+ methodName: string;
14
+ file: string;
15
+ lineNumber: number;
16
+ column: number;
17
+ }
18
+
19
+ function convertHermesStack(stack: HermesParsedStack): StackFrame[] {
20
+ const frames = [];
21
+ for (const entry of stack.entries) {
22
+ if (entry.type !== 'FRAME') {
23
+ continue;
24
+ }
25
+ const { location, functionName } = entry;
26
+ if (location.type === 'NATIVE') {
27
+ continue;
28
+ }
29
+ frames.push({
30
+ methodName: functionName,
31
+ file: location.sourceUrl,
32
+ lineNumber: location.line1Based,
33
+ column:
34
+ location.type === 'SOURCE'
35
+ ? location.column1Based - 1
36
+ : location.virtualOffset0Based,
37
+ });
38
+ }
39
+ return frames;
40
+ }
41
+
42
+ function parseErrorStack(errorStack?: string | StackFrame[]): StackFrame[] {
43
+ if (!errorStack) {
44
+ return [];
45
+ }
46
+
47
+ const parsedStack = Array.isArray(errorStack)
48
+ ? errorStack
49
+ : (global as any).HermesInternal
50
+ ? convertHermesStack(parseHermesStack(errorStack))
51
+ : stacktraceParser.parse(errorStack).map((frame) => ({
52
+ ...frame,
53
+ column: frame.column != null ? frame.column - 1 : null,
54
+ }));
55
+
56
+ return parsedStack as StackFrame[];
57
+ }
58
+
59
+ export default parseErrorStack;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
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
+ interface HermesStackLocationNative {
9
+ type: 'NATIVE';
10
+ }
11
+
12
+ interface HermesStackLocationSource {
13
+ type: 'SOURCE';
14
+ sourceUrl: string;
15
+ line1Based: number;
16
+ column1Based: number;
17
+ }
18
+
19
+ interface HermesStackLocationBytecode {
20
+ type: 'BYTECODE';
21
+ sourceUrl: string;
22
+ line1Based: number;
23
+ virtualOffset0Based: number;
24
+ }
25
+
26
+ type HermesStackLocation =
27
+ | HermesStackLocationNative
28
+ | HermesStackLocationSource
29
+ | HermesStackLocationBytecode;
30
+
31
+ interface HermesStackEntryFrame {
32
+ type: 'FRAME';
33
+ location: HermesStackLocation;
34
+ functionName: string;
35
+ }
36
+
37
+ interface HermesStackEntrySkipped {
38
+ type: 'SKIPPED';
39
+ count: number;
40
+ }
41
+
42
+ type HermesStackEntry = HermesStackEntryFrame | HermesStackEntrySkipped;
43
+
44
+ export interface HermesParsedStack {
45
+ message: string;
46
+ entries: HermesStackEntry[];
47
+ }
48
+
49
+ // Capturing groups:
50
+ // 1. function name
51
+ // 2. is this a native stack frame?
52
+ // 3. is this a bytecode address or a source location?
53
+ // 4. source URL (filename)
54
+ // 5. line number (1 based)
55
+ // 6. column number (1 based) or virtual offset (0 based)
56
+ const RE_FRAME =
57
+ /^ {0,4}at (.+?)(?: \((native)\)?| \((address at )?(.*?):(\d+):(\d+)\))$/;
58
+
59
+ // Capturing groups:
60
+ // 1. count of skipped frames
61
+ const RE_SKIPPED = /^ {0,4}... skipping (\d) frames$/;
62
+
63
+ function parseLine(line: string): HermesStackEntry | undefined {
64
+ const asFrame = line.match(RE_FRAME);
65
+ if (asFrame) {
66
+ return {
67
+ type: 'FRAME',
68
+ functionName: asFrame[1],
69
+ location:
70
+ asFrame[2] === 'native'
71
+ ? { type: 'NATIVE' }
72
+ : asFrame[3] === 'address at '
73
+ ? {
74
+ type: 'BYTECODE',
75
+ sourceUrl: asFrame[4],
76
+ line1Based: Number.parseInt(asFrame[5], 10),
77
+ virtualOffset0Based: Number.parseInt(asFrame[6], 10),
78
+ }
79
+ : {
80
+ type: 'SOURCE',
81
+ sourceUrl: asFrame[4],
82
+ line1Based: Number.parseInt(asFrame[5], 10),
83
+ column1Based: Number.parseInt(asFrame[6], 10),
84
+ },
85
+ };
86
+ }
87
+ const asSkipped = line.match(RE_SKIPPED);
88
+ if (asSkipped) {
89
+ return {
90
+ type: 'SKIPPED',
91
+ count: Number.parseInt(asSkipped[1], 10),
92
+ };
93
+ }
94
+ return undefined;
95
+ }
96
+
97
+ export default function parseHermesStack(stack: string): HermesParsedStack {
98
+ const lines = stack.split(/\n/);
99
+ let entries = [];
100
+ let lastMessageLine = -1;
101
+ for (let i = 0; i < lines.length; ++i) {
102
+ const line = lines[i];
103
+ if (!line) {
104
+ continue;
105
+ }
106
+ const entry = parseLine(line);
107
+ if (entry) {
108
+ entries.push(entry);
109
+ continue;
110
+ }
111
+ // No match - we're still in the message
112
+ lastMessageLine = i;
113
+ entries = [];
114
+ }
115
+ const message = lines.slice(0, lastMessageLine + 1).join('\n');
116
+ return { message, entries };
117
+ }
@@ -6,6 +6,8 @@ import type {
6
6
  import deepEqual from 'deep-equal';
7
7
  import * as React from 'react';
8
8
 
9
+ import parseErrorStack from './parseErrorStack';
10
+
9
11
  type StackFrame = {
10
12
  lineNumber: number | null;
11
13
  column: number | null;
@@ -54,26 +56,9 @@ export default function useDevToolsBase(
54
56
  return undefined;
55
57
  }
56
58
 
57
- const frames = stack
58
- .split('\n')
59
+ const frames = parseErrorStack(stack)
59
60
  .slice(2)
60
- .map((line): StackFrame | null => {
61
- const partMatch = line.match(/^((.+)@)?(.+):(\d+):(\d+)$/);
62
-
63
- if (!partMatch) {
64
- return null;
65
- }
66
-
67
- const [, , methodName, file, lineNumber, column] = partMatch;
68
-
69
- return {
70
- methodName,
71
- file,
72
- lineNumber: Number(lineNumber),
73
- column: Number(column),
74
- };
75
- })
76
- .filter(Boolean) as StackFrame[];
61
+ .filter((frame) => frame.file !== '[native code]');
77
62
 
78
63
  const urlMatch = frames[0]?.file?.match(/^https?:\/\/.+(:\d+)?\//);
79
64