execbro 1.10.23 → 1.10.25

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 (141) hide show
  1. package/README.md +2 -1
  2. package/build/__tests__/helpers/fake-cdp-server.d.ts +9 -0
  3. package/build/__tests__/helpers/fake-cdp-server.d.ts.map +1 -1
  4. package/build/__tests__/helpers/fake-cdp-server.js +20 -2
  5. package/build/__tests__/helpers/fake-cdp-server.js.map +1 -1
  6. package/build/__tests__/integration/connection-health.test.js +8 -1
  7. package/build/__tests__/integration/connection-health.test.js.map +1 -1
  8. package/build/__tests__/integration/socket-close-midflight.test.d.ts +2 -0
  9. package/build/__tests__/integration/socket-close-midflight.test.d.ts.map +1 -0
  10. package/build/__tests__/integration/socket-close-midflight.test.js +106 -0
  11. package/build/__tests__/integration/socket-close-midflight.test.js.map +1 -0
  12. package/build/__tests__/integration/stale-target-probe.test.d.ts +2 -0
  13. package/build/__tests__/integration/stale-target-probe.test.d.ts.map +1 -0
  14. package/build/__tests__/integration/stale-target-probe.test.js +85 -0
  15. package/build/__tests__/integration/stale-target-probe.test.js.map +1 -0
  16. package/build/__tests__/unit/componentSource.test.d.ts +2 -0
  17. package/build/__tests__/unit/componentSource.test.d.ts.map +1 -0
  18. package/build/__tests__/unit/componentSource.test.js +67 -0
  19. package/build/__tests__/unit/componentSource.test.js.map +1 -0
  20. package/build/__tests__/unit/componentSourceResolve.test.d.ts +2 -0
  21. package/build/__tests__/unit/componentSourceResolve.test.d.ts.map +1 -0
  22. package/build/__tests__/unit/componentSourceResolve.test.js +91 -0
  23. package/build/__tests__/unit/componentSourceResolve.test.js.map +1 -0
  24. package/build/__tests__/unit/deviceResolution.test.d.ts +2 -0
  25. package/build/__tests__/unit/deviceResolution.test.d.ts.map +1 -0
  26. package/build/__tests__/unit/deviceResolution.test.js +108 -0
  27. package/build/__tests__/unit/deviceResolution.test.js.map +1 -0
  28. package/build/__tests__/unit/executor.test.js +48 -12
  29. package/build/__tests__/unit/executor.test.js.map +1 -1
  30. package/build/__tests__/unit/getLogsEmptyContract.test.d.ts +2 -0
  31. package/build/__tests__/unit/getLogsEmptyContract.test.d.ts.map +1 -0
  32. package/build/__tests__/unit/getLogsEmptyContract.test.js +99 -0
  33. package/build/__tests__/unit/getLogsEmptyContract.test.js.map +1 -0
  34. package/build/__tests__/unit/inspectorHarvest.test.d.ts +2 -0
  35. package/build/__tests__/unit/inspectorHarvest.test.d.ts.map +1 -0
  36. package/build/__tests__/unit/inspectorHarvest.test.js +61 -0
  37. package/build/__tests__/unit/inspectorHarvest.test.js.map +1 -0
  38. package/build/__tests__/unit/inspectorSource.test.d.ts +2 -0
  39. package/build/__tests__/unit/inspectorSource.test.d.ts.map +1 -0
  40. package/build/__tests__/unit/inspectorSource.test.js +74 -0
  41. package/build/__tests__/unit/inspectorSource.test.js.map +1 -0
  42. package/build/__tests__/unit/logDiagnosis.test.d.ts +2 -0
  43. package/build/__tests__/unit/logDiagnosis.test.d.ts.map +1 -0
  44. package/build/__tests__/unit/logDiagnosis.test.js +81 -0
  45. package/build/__tests__/unit/logDiagnosis.test.js.map +1 -0
  46. package/build/__tests__/unit/pendingExecutions.test.d.ts +2 -0
  47. package/build/__tests__/unit/pendingExecutions.test.d.ts.map +1 -0
  48. package/build/__tests__/unit/pendingExecutions.test.js +70 -0
  49. package/build/__tests__/unit/pendingExecutions.test.js.map +1 -0
  50. package/build/__tests__/unit/reloadAppAutoConnect.test.d.ts +2 -0
  51. package/build/__tests__/unit/reloadAppAutoConnect.test.d.ts.map +1 -0
  52. package/build/__tests__/unit/reloadAppAutoConnect.test.js +63 -0
  53. package/build/__tests__/unit/reloadAppAutoConnect.test.js.map +1 -0
  54. package/build/__tests__/unit/selectionBuffer.test.d.ts +2 -0
  55. package/build/__tests__/unit/selectionBuffer.test.d.ts.map +1 -0
  56. package/build/__tests__/unit/selectionBuffer.test.js +86 -0
  57. package/build/__tests__/unit/selectionBuffer.test.js.map +1 -0
  58. package/build/__tests__/unit/selectionPoller.test.d.ts +2 -0
  59. package/build/__tests__/unit/selectionPoller.test.d.ts.map +1 -0
  60. package/build/__tests__/unit/selectionPoller.test.js +109 -0
  61. package/build/__tests__/unit/selectionPoller.test.js.map +1 -0
  62. package/build/__tests__/unit/symbolicate.test.d.ts +2 -0
  63. package/build/__tests__/unit/symbolicate.test.d.ts.map +1 -0
  64. package/build/__tests__/unit/symbolicate.test.js +154 -0
  65. package/build/__tests__/unit/symbolicate.test.js.map +1 -0
  66. package/build/__tests__/unit/transportClassify.test.js +108 -7
  67. package/build/__tests__/unit/transportClassify.test.js.map +1 -1
  68. package/build/core/componentSource.d.ts +62 -0
  69. package/build/core/componentSource.d.ts.map +1 -0
  70. package/build/core/componentSource.js +268 -0
  71. package/build/core/componentSource.js.map +1 -0
  72. package/build/core/connection.d.ts +30 -0
  73. package/build/core/connection.d.ts.map +1 -1
  74. package/build/core/connection.js +101 -28
  75. package/build/core/connection.js.map +1 -1
  76. package/build/core/debugGlobals.d.ts.map +1 -1
  77. package/build/core/debugGlobals.js +89 -32
  78. package/build/core/debugGlobals.js.map +1 -1
  79. package/build/core/errors.d.ts +7 -1
  80. package/build/core/errors.d.ts.map +1 -1
  81. package/build/core/errors.js +8 -1
  82. package/build/core/errors.js.map +1 -1
  83. package/build/core/guides.js +1 -1
  84. package/build/core/index.d.ts +4 -1
  85. package/build/core/index.d.ts.map +1 -1
  86. package/build/core/index.js +4 -1
  87. package/build/core/index.js.map +1 -1
  88. package/build/core/inspector.d.ts +24 -0
  89. package/build/core/inspector.d.ts.map +1 -1
  90. package/build/core/inspector.js +58 -0
  91. package/build/core/inspector.js.map +1 -1
  92. package/build/core/jsExecute.d.ts +76 -1
  93. package/build/core/jsExecute.d.ts.map +1 -1
  94. package/build/core/jsExecute.js +193 -32
  95. package/build/core/jsExecute.js.map +1 -1
  96. package/build/core/logDiagnosis.d.ts +65 -0
  97. package/build/core/logDiagnosis.d.ts.map +1 -0
  98. package/build/core/logDiagnosis.js +51 -0
  99. package/build/core/logDiagnosis.js.map +1 -0
  100. package/build/core/register.d.ts.map +1 -1
  101. package/build/core/register.js +22 -6
  102. package/build/core/register.js.map +1 -1
  103. package/build/core/selectionBuffer.d.ts +42 -0
  104. package/build/core/selectionBuffer.d.ts.map +1 -0
  105. package/build/core/selectionBuffer.js +51 -0
  106. package/build/core/selectionBuffer.js.map +1 -0
  107. package/build/core/selectionPoller.d.ts +13 -0
  108. package/build/core/selectionPoller.d.ts.map +1 -0
  109. package/build/core/selectionPoller.js +102 -0
  110. package/build/core/selectionPoller.js.map +1 -0
  111. package/build/core/state.d.ts +10 -0
  112. package/build/core/state.d.ts.map +1 -1
  113. package/build/core/state.js +21 -0
  114. package/build/core/state.js.map +1 -1
  115. package/build/core/symbolicate.d.ts +18 -0
  116. package/build/core/symbolicate.d.ts.map +1 -0
  117. package/build/core/symbolicate.js +119 -0
  118. package/build/core/symbolicate.js.map +1 -0
  119. package/build/core/types.d.ts +8 -0
  120. package/build/core/types.d.ts.map +1 -1
  121. package/build/tools/componentTools.d.ts.map +1 -1
  122. package/build/tools/componentTools.js +78 -9
  123. package/build/tools/componentTools.js.map +1 -1
  124. package/build/tools/connectionTools.d.ts.map +1 -1
  125. package/build/tools/connectionTools.js +10 -4
  126. package/build/tools/connectionTools.js.map +1 -1
  127. package/build/tools/executionTools.js +7 -7
  128. package/build/tools/executionTools.js.map +1 -1
  129. package/build/tools/interactionTools.d.ts.map +1 -1
  130. package/build/tools/interactionTools.js +1 -0
  131. package/build/tools/interactionTools.js.map +1 -1
  132. package/build/tools/logTools.d.ts.map +1 -1
  133. package/build/tools/logTools.js +77 -69
  134. package/build/tools/logTools.js.map +1 -1
  135. package/build/tools/networkTools.d.ts.map +1 -1
  136. package/build/tools/networkTools.js +63 -13
  137. package/build/tools/networkTools.js.map +1 -1
  138. package/build/tools/screenshotTools.d.ts.map +1 -1
  139. package/build/tools/screenshotTools.js +3 -0
  140. package/build/tools/screenshotTools.js.map +1 -1
  141. package/package.json +1 -1
@@ -0,0 +1,154 @@
1
+ import { describe, it, expect, beforeEach, jest } from "@jest/globals";
2
+ import { parseStackString, symbolicateFrames, firstUserFrame, clearSymbolicateCache, } from "../../core/symbolicate.js";
3
+ const BUNDLE = "http://192.168.0.102:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true&transform.engine=hermes";
4
+ const REAL_STACK = [
5
+ "Error: react-stack-top-frame",
6
+ ` at anonymous (${BUNDLE}:19648:90)`,
7
+ ` at HomeScreen (${BUNDLE}:342013:64)`,
8
+ ` at react_stack_bottom_frame (${BUNDLE}:31478:29)`,
9
+ ].join("\n");
10
+ describe("parseStackString", () => {
11
+ it("parses named frames with URL, line and column", () => {
12
+ const frames = parseStackString(REAL_STACK);
13
+ expect(frames[0]).toEqual({
14
+ file: BUNDLE,
15
+ lineNumber: 19648,
16
+ column: 90,
17
+ methodName: "anonymous",
18
+ });
19
+ expect(frames[1].methodName).toBe("HomeScreen");
20
+ expect(frames[1].lineNumber).toBe(342013);
21
+ });
22
+ it("does not split on the colon inside http://", () => {
23
+ const frames = parseStackString(REAL_STACK);
24
+ expect(frames[0].file).toBe(BUNDLE);
25
+ expect(frames[0].file.startsWith("http://")).toBe(true);
26
+ });
27
+ it("skips the leading Error: line", () => {
28
+ const frames = parseStackString(REAL_STACK);
29
+ expect(frames.every((f) => f.methodName !== null)).toBe(true);
30
+ expect(frames.length).toBe(3);
31
+ });
32
+ it("parses anonymous frames with no method name", () => {
33
+ const frames = parseStackString(` at ${BUNDLE}:100:5`);
34
+ expect(frames[0]).toEqual({
35
+ file: BUNDLE,
36
+ lineNumber: 100,
37
+ column: 5,
38
+ methodName: null,
39
+ });
40
+ });
41
+ it("honours the limit argument", () => {
42
+ expect(parseStackString(REAL_STACK, 2).length).toBe(2);
43
+ });
44
+ it("returns an empty array for junk input", () => {
45
+ expect(parseStackString("")).toEqual([]);
46
+ expect(parseStackString("not a stack at all")).toEqual([]);
47
+ });
48
+ });
49
+ describe("firstUserFrame", () => {
50
+ it("returns the first frame not marked collapse", () => {
51
+ const frame = firstUserFrame([
52
+ { file: "/x/node_modules/react/a.js", lineNumber: 1, column: 1, methodName: "jsx", collapse: true },
53
+ { file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
54
+ ]);
55
+ expect(frame.file).toBe("/x/src/Home.tsx");
56
+ expect(frame.lineNumber).toBe(105);
57
+ });
58
+ it("returns null when every frame is collapsed", () => {
59
+ const frame = firstUserFrame([
60
+ { file: "/x/node_modules/react/a.js", lineNumber: 1, column: 1, methodName: "jsx", collapse: true },
61
+ ]);
62
+ expect(frame).toBeNull();
63
+ });
64
+ it("returns null for an empty list", () => {
65
+ expect(firstUserFrame([])).toBeNull();
66
+ });
67
+ });
68
+ describe("symbolicateFrames", () => {
69
+ beforeEach(() => {
70
+ clearSymbolicateCache();
71
+ globalThis.fetch = jest.fn();
72
+ });
73
+ it("POSTs to localhost on the port taken from the frame URL", async () => {
74
+ globalThis.fetch.mockResolvedValue({
75
+ ok: true,
76
+ json: async () => ({
77
+ stack: [
78
+ { file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
79
+ ],
80
+ }),
81
+ });
82
+ await symbolicateFrames([
83
+ { file: BUNDLE, lineNumber: 342013, column: 64, methodName: "HomeScreen" },
84
+ ]);
85
+ const [url, init] = globalThis.fetch.mock.calls[0];
86
+ expect(url).toBe("http://127.0.0.1:8081/symbolicate");
87
+ expect(init.method).toBe("POST");
88
+ // The file field must be sent verbatim — Metro matches it against its bundle registry.
89
+ expect(JSON.parse(init.body).stack[0].file).toBe(BUNDLE);
90
+ });
91
+ it("returns symbolicated frames with the collapse flag", async () => {
92
+ globalThis.fetch.mockResolvedValue({
93
+ ok: true,
94
+ json: async () => ({
95
+ stack: [
96
+ { file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
97
+ ],
98
+ }),
99
+ });
100
+ const out = await symbolicateFrames([
101
+ { file: BUNDLE, lineNumber: 342013, column: 64, methodName: "HomeScreen" },
102
+ ]);
103
+ expect(out).toEqual([
104
+ { file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
105
+ ]);
106
+ });
107
+ it("defaults collapse to false when Metro omits it", async () => {
108
+ globalThis.fetch.mockResolvedValue({
109
+ ok: true,
110
+ json: async () => ({ stack: [{ file: "/x/a.tsx", lineNumber: 1, column: 2, methodName: "A" }] }),
111
+ });
112
+ const out = await symbolicateFrames([{ file: BUNDLE, lineNumber: 1, column: 2, methodName: "A" }]);
113
+ expect(out[0].collapse).toBe(false);
114
+ });
115
+ it("serves a repeated frame from cache without a second fetch", async () => {
116
+ globalThis.fetch.mockResolvedValue({
117
+ ok: true,
118
+ json: async () => ({
119
+ stack: [{ file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false }],
120
+ }),
121
+ });
122
+ const frame = { file: BUNDLE, lineNumber: 342013, column: 64, methodName: "HomeScreen" };
123
+ await symbolicateFrames([frame]);
124
+ const second = await symbolicateFrames([frame]);
125
+ expect(globalThis.fetch.mock.calls.length).toBe(1);
126
+ expect(second[0].file).toBe("/x/src/Home.tsx");
127
+ });
128
+ it("returns null when Metro is unreachable", async () => {
129
+ globalThis.fetch.mockRejectedValue(new Error("ECONNREFUSED"));
130
+ const out = await symbolicateFrames([{ file: BUNDLE, lineNumber: 1, column: 1, methodName: "A" }]);
131
+ expect(out).toBeNull();
132
+ });
133
+ it("returns null on a non-ok response", async () => {
134
+ globalThis.fetch.mockResolvedValue({ ok: false, status: 500, json: async () => ({}) });
135
+ const out = await symbolicateFrames([{ file: BUNDLE, lineNumber: 1, column: 1, methodName: "A" }]);
136
+ expect(out).toBeNull();
137
+ });
138
+ it("returns an empty array without fetching when given no frames", async () => {
139
+ const out = await symbolicateFrames([]);
140
+ expect(out).toEqual([]);
141
+ expect(globalThis.fetch.mock.calls.length).toBe(0);
142
+ });
143
+ it("falls back to the frame origin when the URL has no port", async () => {
144
+ globalThis.fetch.mockResolvedValue({
145
+ ok: true,
146
+ json: async () => ({ stack: [{ file: "/a.tsx", lineNumber: 1, column: 1, methodName: "A", collapse: false }] }),
147
+ });
148
+ await symbolicateFrames([
149
+ { file: "http://example.com/bundle.js", lineNumber: 1, column: 1, methodName: "A" },
150
+ ]);
151
+ expect(globalThis.fetch.mock.calls[0][0]).toBe("http://example.com/symbolicate");
152
+ });
153
+ });
154
+ //# sourceMappingURL=symbolicate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbolicate.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/symbolicate.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,93 @@
1
1
  import { describe, expect, it } from "@jest/globals";
2
- import { classifyTransportError } from "../../core/jsExecute.js";
2
+ import { jest } from "@jest/globals";
3
+ import { classifyTransportError, isEvalTimeoutOnLiveSocket, classifyWithLivenessProbe, isTargetStillAdvertised } from "../../core/jsExecute.js";
4
+ // A "took too long" on a socket that is still OPEN is ambiguous: either the
5
+ // expression really was slow, or the CDP target went stale while the
6
+ // device-level socket kept answering pings. Only these cases are worth paying
7
+ // for a probe to disambiguate.
8
+ describe("isEvalTimeoutOnLiveSocket", () => {
9
+ const timeoutMsg = (ws) => `Timeout: Expression took too long to evaluate.\n\nConnection state: ws=${ws}, device="iPhone"`;
10
+ it("is true for a server-timer timeout on an open socket", () => {
11
+ expect(isEvalTimeoutOnLiveSocket(timeoutMsg("OPEN"), "server-timer")).toBe(true);
12
+ });
13
+ it("is false when the socket was closed (already a transport error)", () => {
14
+ expect(isEvalTimeoutOnLiveSocket(timeoutMsg("CLOSED"), "server-timer")).toBe(false);
15
+ });
16
+ it("is false for errors that did not come from the server timer", () => {
17
+ expect(isEvalTimeoutOnLiveSocket(timeoutMsg("OPEN"), "cdp")).toBe(false);
18
+ });
19
+ it("is false for unrelated failures", () => {
20
+ expect(isEvalTimeoutOnLiveSocket("ReferenceError: x is not defined", "logical")).toBe(false);
21
+ });
22
+ });
23
+ // The probe-backed upgrade lives behind an injectable seam so this can be
24
+ // exercised without a real socket. Driving it through executeInApp instead
25
+ // would reach attemptQuickReconnect -> scanMetroPorts(), which scans real
26
+ // localhost ports and would latch onto whatever Metro the developer has running.
27
+ describe("classifyWithLivenessProbe", () => {
28
+ const timeoutMsg = (ws) => `Timeout: Expression took too long to evaluate.\n\nConnection state: ws=${ws}, device="iPhone"`;
29
+ const fakeApp = { ws: {}, port: 8081, deviceInfo: { id: "page-1" } };
30
+ const listed = async () => true;
31
+ const gone = async () => false;
32
+ it("keeps a ws=OPEN timeout logical when the probe answers", async () => {
33
+ const probe = jest.fn(async () => true);
34
+ const result = await classifyWithLivenessProbe(timeoutMsg("OPEN"), "server-timer", fakeApp, probe, gone);
35
+ expect(result).toEqual({ kind: "logical" });
36
+ expect(probe).toHaveBeenCalledTimes(1);
37
+ });
38
+ // The case that bit us on-device: a 15s busy loop silences the probe just
39
+ // like a dead context would. Metro still lists the page, so this must stay
40
+ // logical — upgrading it triggers a retry that re-runs the expression.
41
+ it("keeps a blocked JS thread logical while Metro still lists the target", async () => {
42
+ const probe = jest.fn(async () => false);
43
+ const result = await classifyWithLivenessProbe(timeoutMsg("OPEN"), "server-timer", fakeApp, probe, listed);
44
+ expect(result).toEqual({ kind: "logical" });
45
+ });
46
+ it("upgrades to stale_target only when the probe is silent AND the target is gone", async () => {
47
+ const probe = jest.fn(async () => false);
48
+ const result = await classifyWithLivenessProbe(timeoutMsg("OPEN"), "server-timer", fakeApp, probe, gone);
49
+ expect(result).toEqual({ kind: "transport", pattern: "stale_target" });
50
+ });
51
+ it("does not spend a probe when the socket was already closed", async () => {
52
+ const probe = jest.fn(async () => false);
53
+ const result = await classifyWithLivenessProbe(timeoutMsg("CLOSED"), "server-timer", fakeApp, probe, gone);
54
+ expect(result).toMatchObject({ kind: "transport", pattern: "ws_closed" });
55
+ expect(probe).not.toHaveBeenCalled();
56
+ });
57
+ it("does not spend a probe on unrelated logical errors", async () => {
58
+ const probe = jest.fn(async () => false);
59
+ const result = await classifyWithLivenessProbe("ReferenceError: x", "logical", fakeApp, probe, gone);
60
+ expect(result).toEqual({ kind: "logical" });
61
+ expect(probe).not.toHaveBeenCalled();
62
+ });
63
+ it("stays logical when there is no app to probe", async () => {
64
+ const probe = jest.fn(async () => false);
65
+ const result = await classifyWithLivenessProbe(timeoutMsg("OPEN"), "server-timer", null, probe, gone);
66
+ expect(result).toEqual({ kind: "logical" });
67
+ expect(probe).not.toHaveBeenCalled();
68
+ });
69
+ });
70
+ describe("isTargetStillAdvertised", () => {
71
+ const app = { port: 8081, deviceInfo: { id: "page-1" } };
72
+ it("is true when Metro still lists our page id", async () => {
73
+ const fetchTargets = async () => [{ id: "page-1" }, { id: "page-2" }];
74
+ expect(await isTargetStillAdvertised(app, fetchTargets)).toBe(true);
75
+ });
76
+ it("is false when Metro lists other pages but not ours", async () => {
77
+ const fetchTargets = async () => [{ id: "page-9" }];
78
+ expect(await isTargetStillAdvertised(app, fetchTargets)).toBe(false);
79
+ });
80
+ // fetchDevices returns [] on any network error. Treating that as "gone"
81
+ // would let a Metro blip trigger a reconnect that re-runs the expression.
82
+ it("is true when the target list comes back empty", async () => {
83
+ const fetchTargets = async () => [];
84
+ expect(await isTargetStillAdvertised(app, fetchTargets)).toBe(true);
85
+ });
86
+ it("is true when we have no page id to compare", async () => {
87
+ const fetchTargets = async () => [{ id: "page-9" }];
88
+ expect(await isTargetStillAdvertised({ port: 8081, deviceInfo: {} }, fetchTargets)).toBe(true);
89
+ });
90
+ });
3
91
  describe("classifyTransportError — positive cases", () => {
4
92
  it("matches 'No apps connected'", () => {
5
93
  expect(classifyTransportError("No apps connected. Run 'scan_metro' first.", "logical")).toMatchObject({
@@ -31,18 +119,31 @@ describe("classifyTransportError — positive cases", () => {
31
119
  pattern: "target_closed",
32
120
  });
33
121
  });
34
- it("matches CDP-side 'Expression took too long to evaluate'", () => {
35
- expect(classifyTransportError("Expression took too long to evaluate", "cdp")).toMatchObject({
36
- kind: "transport",
37
- pattern: "cdp_eval_too_long",
38
- });
39
- });
40
122
  });
41
123
  describe("classifyTransportError — negative cases (must NOT auto-retry)", () => {
42
124
  it("does NOT match server-side timer text", () => {
43
125
  const serverTimerMsg = "Timeout: Expression took too long to evaluate.\n\nConnection state: ws=OPEN...";
44
126
  expect(classifyTransportError(serverTimerMsg, "server-timer")).toEqual({ kind: "logical" });
45
127
  });
128
+ // Backstop for the race where our timer fires before the socket's close
129
+ // handler has failed the in-flight call. A timer expiry is only "logical"
130
+ // if the transport was actually alive when it fired.
131
+ it("DOES match server-timer text when the socket was already closed", () => {
132
+ const closedMsg = "Timeout: Expression took too long to evaluate.\n\nConnection state: ws=CLOSED, device=\"iPhone\"";
133
+ expect(classifyTransportError(closedMsg, "server-timer")).toMatchObject({
134
+ kind: "transport",
135
+ pattern: "ws_closed",
136
+ });
137
+ });
138
+ // "took too long" on a live socket is a slow expression, not a dead
139
+ // transport — the 1s ping/pong keepalive terminates genuinely dead sockets
140
+ // within ~2s, so anything still OPEN after a multi-second timeout had a
141
+ // working transport the whole time. Retrying it just burns the timeout again.
142
+ it("does NOT match an eval-too-long message while the socket is alive", () => {
143
+ expect(classifyTransportError("Expression took too long to evaluate", "cdp")).toEqual({
144
+ kind: "logical",
145
+ });
146
+ });
46
147
  it("does NOT match 'no component matched'", () => {
47
148
  expect(classifyTransportError("No component matched pattern Foo", "logical")).toEqual({ kind: "logical" });
48
149
  });
@@ -1 +1 @@
1
- {"version":3,"file":"transportClassify.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/transportClassify.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transportClassify.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/transportClassify.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { ComponentStack, SelectionFrame } from "./selectionBuffer.js";
2
+ export interface ProbeResult {
3
+ active: boolean;
4
+ selected: boolean;
5
+ changed: boolean;
6
+ element?: string;
7
+ path?: string;
8
+ hierarchy?: string[];
9
+ frame?: SelectionFrame | null;
10
+ style?: Record<string, unknown> | null;
11
+ }
12
+ export interface HarvestResult {
13
+ stacks: ComponentStack[];
14
+ error?: string;
15
+ }
16
+ /**
17
+ * Cheap per-tick probe. Deliberately does NO measurement — it runs every
18
+ * 500-2000ms and must stay inexpensive. Reports whether RN's inspector is
19
+ * mounted and whether its selection changed since the previous tick.
20
+ */
21
+ export declare function buildSelectionProbeExpression(): string;
22
+ /**
23
+ * Hit-tests at (x, y) and harvests raw _debugStack strings up the return chain.
24
+ * Measures host fibers, so this runs only when the probe reports a change -
25
+ * once per tap, never per tick.
26
+ *
27
+ * Prefers _debugSource when present (React < 19, already source coordinates);
28
+ * otherwise emits the raw _debugStack string for host-side symbolication.
29
+ *
30
+ * The cap is deliberately generous. Real trees bury the nearest user component
31
+ * deep behind library wrappers - measured on a production app, a tapped SearchBar
32
+ * sat 12 ancestors above the hit fiber (SVG icon, Pressable and View wrappers in
33
+ * between) and HomeScreen sat at 22. Collapsed library frames are dropped
34
+ * host-side, so a larger walk improves recall without bloating the output; the
35
+ * extra frames cost nothing beyond one batched, cached symbolicate request.
36
+ */
37
+ export declare function buildDebugStackHarvestExpression(x: number, y: number, maxAncestors?: number): string;
38
+ export interface RawComponentStack {
39
+ component: string;
40
+ stack: string;
41
+ /** Present only on React < 19, where _debugSource still exists. */
42
+ file?: string;
43
+ lineNumber?: number;
44
+ column?: number;
45
+ }
46
+ export interface SourceLocation {
47
+ file: string;
48
+ line: number;
49
+ column: number;
50
+ }
51
+ export interface ResolvedAncestor {
52
+ component: string;
53
+ file: string;
54
+ line: number;
55
+ }
56
+ export interface ResolvedSource {
57
+ source: SourceLocation | null;
58
+ ancestors: ResolvedAncestor[];
59
+ sourceUnavailable?: string;
60
+ }
61
+ export declare function resolveStacksToSource(stacks: RawComponentStack[]): Promise<ResolvedSource>;
62
+ //# sourceMappingURL=componentSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentSource.d.ts","sourceRoot":"","sources":["../../src/core/componentSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3E,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAkBD;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CAmEtD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gCAAgC,CAC5C,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,YAAY,GAAE,MAAW,GAC1B,MAAM,CAwGR;AAED,MAAM,WAAW,iBAAiB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AASD,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CA2DhG"}