@react-native/dev-middleware 0.74.0 → 0.74.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/createDevMiddleware.d.ts +8 -1
  2. package/dist/createDevMiddleware.js +12 -9
  3. package/dist/createDevMiddleware.js.flow +9 -1
  4. package/dist/index.flow.d.ts +2 -0
  5. package/dist/index.flow.js +16 -0
  6. package/dist/index.flow.js.flow +3 -0
  7. package/dist/inspector-proxy/Device.d.ts +3 -55
  8. package/dist/inspector-proxy/Device.js +254 -166
  9. package/dist/inspector-proxy/Device.js.flow +3 -59
  10. package/dist/inspector-proxy/DeviceEventReporter.d.ts +2 -12
  11. package/dist/inspector-proxy/DeviceEventReporter.js +37 -35
  12. package/dist/inspector-proxy/DeviceEventReporter.js.flow +2 -17
  13. package/dist/inspector-proxy/InspectorProxy.d.ts +1 -24
  14. package/dist/inspector-proxy/InspectorProxy.js +41 -30
  15. package/dist/inspector-proxy/InspectorProxy.js.flow +1 -24
  16. package/dist/inspector-proxy/cdp-types/messages.d.ts +39 -0
  17. package/dist/inspector-proxy/cdp-types/messages.js +1 -0
  18. package/dist/inspector-proxy/cdp-types/messages.js.flow +52 -0
  19. package/dist/inspector-proxy/cdp-types/protocol.d.ts +87 -0
  20. package/dist/inspector-proxy/cdp-types/protocol.js +1 -0
  21. package/dist/inspector-proxy/cdp-types/protocol.js.flow +106 -0
  22. package/dist/inspector-proxy/types.d.ts +60 -45
  23. package/dist/inspector-proxy/types.js.flow +62 -70
  24. package/dist/middleware/deprecated_openFlipperMiddleware.d.ts +1 -1
  25. package/dist/middleware/deprecated_openFlipperMiddleware.js.flow +1 -2
  26. package/dist/middleware/openDebuggerMiddleware.d.ts +1 -1
  27. package/dist/middleware/openDebuggerMiddleware.js +23 -8
  28. package/dist/middleware/openDebuggerMiddleware.js.flow +1 -2
  29. package/dist/types/EventReporter.d.ts +3 -3
  30. package/dist/types/EventReporter.js.flow +1 -1
  31. package/dist/types/Experiments.d.ts +4 -0
  32. package/dist/types/Experiments.js.flow +5 -0
  33. package/dist/utils/DefaultBrowserLauncher.js +1 -1
  34. package/dist/utils/getDevToolsFrontendUrl.d.ts +2 -0
  35. package/dist/utils/getDevToolsFrontendUrl.js +20 -4
  36. package/dist/utils/getDevToolsFrontendUrl.js.flow +3 -0
  37. package/package.json +13 -5
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and 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
+ * @flow strict-local
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import type { Commands, Events } from "./protocol";
13
+
14
+ // Note: A CDP event is a JSON-RPC notification with no `id` member.
15
+ export type CDPEvent<TEvent: $Keys<Events> = "unknown"> = $ReadOnly<{
16
+ method: TEvent,
17
+ params: Events[TEvent],
18
+ }>;
19
+
20
+ export type CDPRequest<TCommand: $Keys<Commands> = "unknown"> = $ReadOnly<{
21
+ method: TCommand,
22
+ params: Commands[TCommand]["paramsType"],
23
+ id: number,
24
+ }>;
25
+
26
+ export type CDPResponse<TCommand: $Keys<Commands> = "unknown"> =
27
+ | $ReadOnly<{
28
+ result: Commands[TCommand]["resultType"],
29
+ id: number,
30
+ }>
31
+ | $ReadOnly<{
32
+ error: CDPRequestError,
33
+ id: number,
34
+ }>;
35
+
36
+ export type CDPRequestError = $ReadOnly<{
37
+ code: number,
38
+ message: string,
39
+ data?: mixed,
40
+ }>;
41
+
42
+ export type CDPClientMessage =
43
+ | CDPRequest<"Debugger.getScriptSource">
44
+ | CDPRequest<"Debugger.scriptParsed">
45
+ | CDPRequest<"Debugger.setBreakpointByUrl">
46
+ | CDPRequest<>;
47
+
48
+ export type CDPServerMessage =
49
+ | CDPEvent<"Debugger.scriptParsed">
50
+ | CDPEvent<>
51
+ | CDPResponse<"Debugger.getScriptSource">
52
+ | CDPResponse<>;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and 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
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ type integer = number;
13
+ export interface Debugger {
14
+ GetScriptSourceParams: Readonly<{
15
+ /**
16
+ * Id of the script to get source for.
17
+ */
18
+ scriptId: string;
19
+ }>;
20
+ GetScriptSourceResult: Readonly<{
21
+ /**
22
+ * Script source (empty in case of Wasm bytecode).
23
+ */
24
+ scriptSource: string;
25
+ /**
26
+ * Wasm bytecode. (Encoded as a base64 string when passed over JSON)
27
+ */
28
+ bytecode?: string;
29
+ }>;
30
+ SetBreakpointByUrlParams: Readonly<{
31
+ /**
32
+ * Line number to set breakpoint at.
33
+ */
34
+ lineNumber: integer;
35
+ /**
36
+ * URL of the resources to set breakpoint on.
37
+ */
38
+ url?: string;
39
+ /**
40
+ * Regex pattern for the URLs of the resources to set breakpoints on. Either `url` or
41
+ * `urlRegex` must be specified.
42
+ */
43
+ urlRegex?: string;
44
+ /**
45
+ * Script hash of the resources to set breakpoint on.
46
+ */
47
+ scriptHash?: string;
48
+ /**
49
+ * Offset in the line to set breakpoint at.
50
+ */
51
+ columnNumber?: integer;
52
+ /**
53
+ * Expression to use as a breakpoint condition. When specified, debugger will only stop on the
54
+ * breakpoint if this expression evaluates to true.
55
+ */
56
+ condition?: string;
57
+ }>;
58
+ ScriptParsedEvent: Readonly<{
59
+ /**
60
+ * Identifier of the script parsed.
61
+ */
62
+ scriptId: string;
63
+ /**
64
+ * URL or name of the script parsed (if any).
65
+ */
66
+ url: string;
67
+ /**
68
+ * URL of source map associated with script (if any).
69
+ */
70
+ sourceMapURL: string;
71
+ }>;
72
+ }
73
+ export type Events = {
74
+ "Debugger.scriptParsed": Debugger["ScriptParsedEvent"];
75
+ [method: string]: unknown;
76
+ };
77
+ export type Commands = {
78
+ "Debugger.getScriptSource": {
79
+ paramsType: Debugger["GetScriptSourceParams"];
80
+ resultType: Debugger["GetScriptSourceResult"];
81
+ };
82
+ "Debugger.setBreakpointByUrl": {
83
+ paramsType: Debugger["SetBreakpointByUrlParams"];
84
+ resultType: void;
85
+ };
86
+ [method: string]: { paramsType: unknown; resultType: unknown };
87
+ };
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and 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
+ * @flow strict-local
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ // Adapted from https://github.com/ChromeDevTools/devtools-protocol/blob/master/types/protocol.d.ts
13
+
14
+ type integer = number;
15
+
16
+ export interface Debugger {
17
+ GetScriptSourceParams: $ReadOnly<{
18
+ /**
19
+ * Id of the script to get source for.
20
+ */
21
+ scriptId: string,
22
+ }>;
23
+
24
+ GetScriptSourceResult: $ReadOnly<{
25
+ /**
26
+ * Script source (empty in case of Wasm bytecode).
27
+ */
28
+ scriptSource: string,
29
+
30
+ /**
31
+ * Wasm bytecode. (Encoded as a base64 string when passed over JSON)
32
+ */
33
+ bytecode?: string,
34
+ }>;
35
+
36
+ SetBreakpointByUrlParams: $ReadOnly<{
37
+ /**
38
+ * Line number to set breakpoint at.
39
+ */
40
+ lineNumber: integer,
41
+
42
+ /**
43
+ * URL of the resources to set breakpoint on.
44
+ */
45
+ url?: string,
46
+
47
+ /**
48
+ * Regex pattern for the URLs of the resources to set breakpoints on. Either `url` or
49
+ * `urlRegex` must be specified.
50
+ */
51
+ urlRegex?: string,
52
+
53
+ /**
54
+ * Script hash of the resources to set breakpoint on.
55
+ */
56
+ scriptHash?: string,
57
+
58
+ /**
59
+ * Offset in the line to set breakpoint at.
60
+ */
61
+ columnNumber?: integer,
62
+
63
+ /**
64
+ * Expression to use as a breakpoint condition. When specified, debugger will only stop on the
65
+ * breakpoint if this expression evaluates to true.
66
+ */
67
+ condition?: string,
68
+ }>;
69
+
70
+ ScriptParsedEvent: $ReadOnly<{
71
+ /**
72
+ * Identifier of the script parsed.
73
+ */
74
+ scriptId: string,
75
+
76
+ /**
77
+ * URL or name of the script parsed (if any).
78
+ */
79
+ url: string,
80
+
81
+ /**
82
+ * URL of source map associated with script (if any).
83
+ */
84
+ sourceMapURL: string,
85
+ }>;
86
+ }
87
+
88
+ export type Events = {
89
+ "Debugger.scriptParsed": Debugger["ScriptParsedEvent"],
90
+ [method: string]: mixed,
91
+ };
92
+
93
+ export type Commands = {
94
+ "Debugger.getScriptSource": {
95
+ paramsType: Debugger["GetScriptSourceParams"],
96
+ resultType: Debugger["GetScriptSourceResult"],
97
+ },
98
+ "Debugger.setBreakpointByUrl": {
99
+ paramsType: Debugger["SetBreakpointByUrlParams"],
100
+ resultType: void,
101
+ },
102
+ [method: string]: {
103
+ paramsType: mixed,
104
+ resultType: mixed,
105
+ },
106
+ };
@@ -9,18 +9,52 @@
9
9
  * @oncall react_native
10
10
  */
11
11
 
12
- export type Page = { id: string; title: string; vm: string; app: string };
13
- export type WrappedEvent = {
12
+ /**
13
+ * A capability flag disables a specific feature/hack in the InspectorProxy
14
+ * layer by indicating that the target supports one or more modern CDP features.
15
+ */
16
+ export type TargetCapabilityFlags = Readonly<{
17
+ /**
18
+ * The target supports a stable page representation across reloads.
19
+ *
20
+ * In the proxy, this disables legacy page reload emulation and the
21
+ * additional '(Experimental)' target in `/json/list`.
22
+ *
23
+ * In the launch flow, this allows targets to be matched directly by `appId`.
24
+ */
25
+ nativePageReloads?: boolean;
26
+ /**
27
+ * The target supports fetching source code and source maps.
28
+ *
29
+ * In the proxy, this disables source fetching emulation and host rewrites.
30
+ */
31
+ nativeSourceCodeFetching?: boolean;
32
+ }>;
33
+ export type PageFromDevice = Readonly<{
34
+ id: string;
35
+ title: string;
36
+ vm: string;
37
+ app: string;
38
+ capabilities?: TargetCapabilityFlags;
39
+ }>;
40
+ export type Page = Required<PageFromDevice>;
41
+ export type WrappedEvent = Readonly<{
14
42
  event: "wrappedEvent";
15
- payload: { pageId: string; wrappedEvent: string };
16
- };
17
- export type ConnectRequest = { event: "connect"; payload: { pageId: string } };
18
- export type DisconnectRequest = {
43
+ payload: Readonly<{ pageId: string; wrappedEvent: string }>;
44
+ }>;
45
+ export type ConnectRequest = Readonly<{
46
+ event: "connect";
47
+ payload: Readonly<{ pageId: string }>;
48
+ }>;
49
+ export type DisconnectRequest = Readonly<{
19
50
  event: "disconnect";
20
- payload: { pageId: string };
21
- };
51
+ payload: Readonly<{ pageId: string }>;
52
+ }>;
22
53
  export type GetPagesRequest = { event: "getPages" };
23
- export type GetPagesResponse = { event: "getPages"; payload: Array<Page> };
54
+ export type GetPagesResponse = {
55
+ event: "getPages";
56
+ payload: ReadonlyArray<PageFromDevice>;
57
+ };
24
58
  export type MessageFromDevice =
25
59
  | GetPagesResponse
26
60
  | WrappedEvent
@@ -30,7 +64,7 @@ export type MessageToDevice =
30
64
  | WrappedEvent
31
65
  | ConnectRequest
32
66
  | DisconnectRequest;
33
- export type PageDescription = {
67
+ export type PageDescription = Readonly<{
34
68
  id: string;
35
69
  description: string;
36
70
  title: string;
@@ -38,41 +72,22 @@ export type PageDescription = {
38
72
  devtoolsFrontendUrl: string;
39
73
  type: string;
40
74
  webSocketDebuggerUrl: string;
41
- };
75
+ deviceName: string;
76
+ vm: string;
77
+ reactNative: Readonly<{
78
+ logicalDeviceId: string;
79
+ capabilities: Page["capabilities"];
80
+ }>;
81
+ }>;
42
82
  export type JsonPagesListResponse = Array<PageDescription>;
43
- export type JsonVersionResponse = {
83
+ export type JsonVersionResponse = Readonly<{
44
84
  Browser: string;
45
85
  "Protocol-Version": string;
46
- };
47
- /**
48
- * Types were exported from https://github.com/ChromeDevTools/devtools-protocol/blob/master/types/protocol.d.ts
49
- */
50
-
51
- export type SetBreakpointByUrlRequest = {
52
- id: number;
53
- method: "Debugger.setBreakpointByUrl";
54
- params: {
55
- lineNumber: number;
56
- url?: string;
57
- urlRegex?: string;
58
- scriptHash?: string;
59
- columnNumber?: number;
60
- condition?: string;
61
- };
62
- };
63
- export type GetScriptSourceRequest = {
64
- id: number;
65
- method: "Debugger.getScriptSource";
66
- params: { scriptId: string };
67
- };
68
- export type GetScriptSourceResponse = {
69
- scriptSource: string;
70
- /**
71
- * Wasm bytecode.
72
- */
73
- bytecode?: string;
74
- };
75
- export type ErrorResponse = { error: { message: string } };
76
- export type DebuggerRequest =
77
- | SetBreakpointByUrlRequest
78
- | GetScriptSourceRequest;
86
+ }>;
87
+ export type JSONSerializable =
88
+ | boolean
89
+ | number
90
+ | string
91
+ | null
92
+ | ReadonlyArray<JSONSerializable>
93
+ | { readonly [$$Key$$: string]: JSONSerializable };
@@ -4,57 +4,78 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @flow
7
+ * @flow strict-local
8
8
  * @format
9
9
  * @oncall react_native
10
10
  */
11
11
 
12
+ /**
13
+ * A capability flag disables a specific feature/hack in the InspectorProxy
14
+ * layer by indicating that the target supports one or more modern CDP features.
15
+ */
16
+ export type TargetCapabilityFlags = $ReadOnly<{
17
+ /**
18
+ * The target supports a stable page representation across reloads.
19
+ *
20
+ * In the proxy, this disables legacy page reload emulation and the
21
+ * additional '(Experimental)' target in `/json/list`.
22
+ *
23
+ * In the launch flow, this allows targets to be matched directly by `appId`.
24
+ */
25
+ nativePageReloads?: boolean,
26
+
27
+ /**
28
+ * The target supports fetching source code and source maps.
29
+ *
30
+ * In the proxy, this disables source fetching emulation and host rewrites.
31
+ */
32
+ nativeSourceCodeFetching?: boolean,
33
+ }>;
34
+
12
35
  // Page information received from the device. New page is created for
13
36
  // each new instance of VM and can appear when user reloads React Native
14
37
  // application.
15
- export type Page = {
38
+
39
+ export type PageFromDevice = $ReadOnly<{
16
40
  id: string,
17
41
  title: string,
18
42
  vm: string,
19
43
  app: string,
20
- ...
21
- };
44
+ capabilities?: TargetCapabilityFlags,
45
+ }>;
46
+
47
+ export type Page = Required<PageFromDevice>;
22
48
 
23
49
  // Chrome Debugger Protocol message/event passed between device and debugger.
24
- export type WrappedEvent = {
50
+ export type WrappedEvent = $ReadOnly<{
25
51
  event: "wrappedEvent",
26
- payload: {
52
+ payload: $ReadOnly<{
27
53
  pageId: string,
28
54
  wrappedEvent: string,
29
- ...
30
- },
31
- ...
32
- };
55
+ }>,
56
+ }>;
33
57
 
34
58
  // Request sent from Inspector Proxy to Device when new debugger is connected
35
59
  // to particular page.
36
- export type ConnectRequest = {
60
+ export type ConnectRequest = $ReadOnly<{
37
61
  event: "connect",
38
- payload: { pageId: string, ... },
39
- ...
40
- };
62
+ payload: $ReadOnly<{ pageId: string }>,
63
+ }>;
41
64
 
42
65
  // Request sent from Inspector Proxy to Device to notify that debugger is
43
66
  // disconnected.
44
- export type DisconnectRequest = {
67
+ export type DisconnectRequest = $ReadOnly<{
45
68
  event: "disconnect",
46
- payload: { pageId: string, ... },
47
- ...
48
- };
69
+ payload: $ReadOnly<{ pageId: string }>,
70
+ }>;
49
71
 
50
72
  // Request sent from Inspector Proxy to Device to get a list of pages.
51
- export type GetPagesRequest = { event: "getPages", ... };
73
+ export type GetPagesRequest = { event: "getPages" };
52
74
 
53
75
  // Response to GetPagesRequest containing a list of page infos.
54
76
  export type GetPagesResponse = {
55
77
  event: "getPages",
56
- payload: Array<Page>,
57
- ...
78
+ payload: $ReadOnlyArray<PageFromDevice>,
58
79
  };
59
80
 
60
81
  // Union type for all possible messages sent from device to Inspector Proxy.
@@ -71,7 +92,7 @@ export type MessageToDevice =
71
92
  | DisconnectRequest;
72
93
 
73
94
  // Page description object that is sent in response to /json HTTP request from debugger.
74
- export type PageDescription = {
95
+ export type PageDescription = $ReadOnly<{
75
96
  id: string,
76
97
  description: string,
77
98
  title: string,
@@ -79,57 +100,28 @@ export type PageDescription = {
79
100
  devtoolsFrontendUrl: string,
80
101
  type: string,
81
102
  webSocketDebuggerUrl: string,
82
- ...
83
- };
103
+ deviceName: string,
104
+ vm: string,
105
+ // Metadata specific to React Native
106
+ reactNative: $ReadOnly<{
107
+ logicalDeviceId: string,
108
+ capabilities: Page["capabilities"],
109
+ }>,
110
+ }>;
111
+
84
112
  export type JsonPagesListResponse = Array<PageDescription>;
85
113
 
86
114
  // Response to /json/version HTTP request from the debugger specifying browser type and
87
115
  // Chrome protocol version.
88
- export type JsonVersionResponse = {
116
+ export type JsonVersionResponse = $ReadOnly<{
89
117
  Browser: string,
90
118
  "Protocol-Version": string,
91
- ...
92
- };
93
-
94
- /**
95
- * Types were exported from https://github.com/ChromeDevTools/devtools-protocol/blob/master/types/protocol.d.ts
96
- */
97
-
98
- export type SetBreakpointByUrlRequest = {
99
- id: number,
100
- method: "Debugger.setBreakpointByUrl",
101
- params: {
102
- lineNumber: number,
103
- url?: string,
104
- urlRegex?: string,
105
- scriptHash?: string,
106
- columnNumber?: number,
107
- condition?: string,
108
- },
109
- };
110
-
111
- export type GetScriptSourceRequest = {
112
- id: number,
113
- method: "Debugger.getScriptSource",
114
- params: {
115
- scriptId: string,
116
- },
117
- };
118
-
119
- export type GetScriptSourceResponse = {
120
- scriptSource: string,
121
- /**
122
- * Wasm bytecode.
123
- */
124
- bytecode?: string,
125
- };
126
-
127
- export type ErrorResponse = {
128
- error: {
129
- message: string,
130
- },
131
- };
132
-
133
- export type DebuggerRequest =
134
- | SetBreakpointByUrlRequest
135
- | GetScriptSourceRequest;
119
+ }>;
120
+
121
+ export type JSONSerializable =
122
+ | boolean
123
+ | number
124
+ | string
125
+ | null
126
+ | $ReadOnlyArray<JSONSerializable>
127
+ | { +[string]: JSONSerializable };
@@ -9,8 +9,8 @@
9
9
  * @oncall react_native
10
10
  */
11
11
 
12
- import type { NextHandleFunction } from "connect";
13
12
  import type { Logger } from "../types/Logger";
13
+ import type { NextHandleFunction } from "connect";
14
14
  type Options = Readonly<{ logger?: Logger }>;
15
15
  /**
16
16
  * Open the legacy Flipper debugger (Hermes).
@@ -9,9 +9,8 @@
9
9
  * @oncall react_native
10
10
  */
11
11
 
12
- import type { NextHandleFunction } from "connect";
13
12
  import type { Logger } from "../types/Logger";
14
-
13
+ import type { NextHandleFunction } from "connect";
15
14
  type Options = $ReadOnly<{
16
15
  logger?: Logger,
17
16
  }>;
@@ -9,12 +9,12 @@
9
9
  * @oncall react_native
10
10
  */
11
11
 
12
- import type { NextHandleFunction } from "connect";
13
12
  import type { InspectorProxyQueries } from "../inspector-proxy/InspectorProxy";
14
13
  import type { BrowserLauncher } from "../types/BrowserLauncher";
15
14
  import type { EventReporter } from "../types/EventReporter";
16
15
  import type { Experiments } from "../types/Experiments";
17
16
  import type { Logger } from "../types/Logger";
17
+ import type { NextHandleFunction } from "connect";
18
18
  type Options = Readonly<{
19
19
  serverBaseUrl: string;
20
20
  logger?: Logger;
@@ -4,10 +4,10 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true,
5
5
  });
6
6
  exports.default = openDebuggerMiddleware;
7
- var _url = _interopRequireDefault(require("url"));
8
7
  var _getDevToolsFrontendUrl = _interopRequireDefault(
9
8
  require("../utils/getDevToolsFrontendUrl")
10
9
  );
10
+ var _url = _interopRequireDefault(require("url"));
11
11
  function _interopRequireDefault(obj) {
12
12
  return obj && obj.__esModule ? obj : { default: obj };
13
13
  }
@@ -45,20 +45,28 @@ function openDebuggerMiddleware({
45
45
  (experiments.enableOpenDebuggerRedirect && req.method === "GET")
46
46
  ) {
47
47
  const { query } = _url.default.parse(req.url, true);
48
- const { appId } = query;
48
+ const { appId, device } = query;
49
49
  const targets = inspectorProxy.getPageDescriptions().filter(
50
50
  // Only use targets with better reloading support
51
51
  (app) =>
52
- app.title === "React Native Experimental (Improved Chrome Reloads)"
52
+ app.title === "React Native Experimental (Improved Chrome Reloads)" ||
53
+ app.reactNative.capabilities?.nativePageReloads === true
53
54
  );
54
55
  let target;
55
56
  const launchType = req.method === "POST" ? "launch" : "redirect";
56
- if (typeof appId === "string") {
57
+ if (typeof appId === "string" || typeof device === "string") {
57
58
  logger?.info(
58
59
  (launchType === "launch" ? "Launching" : "Redirecting to") +
59
60
  " JS debugger (experimental)..."
60
61
  );
61
- target = targets.find((_target) => _target.description === appId);
62
+ if (typeof device === "string") {
63
+ target = targets.find(
64
+ (_target) => _target.reactNative.logicalDeviceId === device
65
+ );
66
+ }
67
+ if (!target && typeof appId === "string") {
68
+ target = targets.find((_target) => _target.description === appId);
69
+ }
62
70
  } else {
63
71
  logger?.info(
64
72
  (launchType === "launch" ? "Launching" : "Redirecting to") +
@@ -83,11 +91,16 @@ function openDebuggerMiddleware({
83
91
  try {
84
92
  switch (launchType) {
85
93
  case "launch":
86
- await debuggerInstances.get(appId)?.kill();
94
+ const frontendInstanceId =
95
+ device != null
96
+ ? "device:" + device
97
+ : "app:" + (appId ?? "<null>");
98
+ await debuggerInstances.get(frontendInstanceId)?.kill();
87
99
  debuggerInstances.set(
88
- appId,
100
+ frontendInstanceId,
89
101
  await browserLauncher.launchDebuggerAppWindow(
90
102
  (0, _getDevToolsFrontendUrl.default)(
103
+ experiments,
91
104
  target.webSocketDebuggerUrl,
92
105
  serverBaseUrl
93
106
  )
@@ -98,6 +111,7 @@ function openDebuggerMiddleware({
98
111
  case "redirect":
99
112
  res.writeHead(302, {
100
113
  Location: (0, _getDevToolsFrontendUrl.default)(
114
+ experiments,
101
115
  target.webSocketDebuggerUrl,
102
116
  // Use a relative URL.
103
117
  ""
@@ -111,7 +125,8 @@ function openDebuggerMiddleware({
111
125
  type: "launch_debugger_frontend",
112
126
  launchType,
113
127
  status: "success",
114
- appId,
128
+ appId: appId ?? null,
129
+ deviceId: device ?? null,
115
130
  });
116
131
  return;
117
132
  } catch (e) {
@@ -9,13 +9,12 @@
9
9
  * @oncall react_native
10
10
  */
11
11
 
12
- import type { NextHandleFunction } from "connect";
13
12
  import type { InspectorProxyQueries } from "../inspector-proxy/InspectorProxy";
14
13
  import type { BrowserLauncher } from "../types/BrowserLauncher";
15
14
  import type { EventReporter } from "../types/EventReporter";
16
15
  import type { Experiments } from "../types/Experiments";
17
16
  import type { Logger } from "../types/Logger";
18
-
17
+ import type { NextHandleFunction } from "connect";
19
18
  type Options = $ReadOnly<{
20
19
  serverBaseUrl: string,
21
20
  logger?: Logger,