@react-native/debugger-shell 0.81.0-nightly-20250531-cddfe4a03
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/__tests__/electron-dependency-test.js +41 -0
- package/dist/electron/MainInstanceEntryPoint.d.ts +9 -0
- package/dist/electron/MainInstanceEntryPoint.js +76 -0
- package/dist/electron/MainInstanceEntryPoint.js.flow +9 -0
- package/dist/electron/index.d.ts +9 -0
- package/dist/electron/index.js +11 -0
- package/dist/electron/index.js.flow +9 -0
- package/dist/node/index.d.ts +15 -0
- package/dist/node/index.js +57 -0
- package/dist/node/index.js.flow +22 -0
- package/package.json +39 -0
- package/src/electron/MainInstanceEntryPoint.js +104 -0
- package/src/electron/index.flow.js +22 -0
- package/src/electron/index.js +19 -0
- package/src/node/index.flow.js +77 -0
- package/src/node/index.js +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @react-native/debugger-shell
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Experimental Electron-based shell for React Native DevTools. This package is not part of React Native's public API.
|
|
6
|
+
|
|
7
|
+
## Why Electron?
|
|
8
|
+
|
|
9
|
+
The React Native DevTools frontend is based on Chrome DevTools, which is a web app, but is not particularly portable: it's designed to run in Chromium, and Chromium only. Prior to `@react-native/debugger-shell`, we would run it in [hosted mode](https://chromium.googlesource.com/devtools/devtools-frontend/+/main/docs/get_the_code.md#running-in-hosted-mode) in an instance of Chrome or Edge.
|
|
10
|
+
|
|
11
|
+
Relying on hosted mode presents a variety of UX issues in the debugging workflow, such as the need to ask developers to install a particular browser before they can debug in React Native, and the inability to foreground/reuse existing debugger windows when relaunching the debugger for the same app. In order to address these issues effectively, we fundamentally need to leave the browser sandbox and run the debugger in a shell we can bundle with React Native, and whose behavior we can control.
|
|
12
|
+
|
|
13
|
+
Electron is a tried-and-tested framework for the *specific* task of embedding a Chromium browser in a portable, customized shell. As a rule we'll hold a high bar for performance and reliability, and we'll only add features to the shell if they are strictly necessary to complement the DevTools frontend's built-in capabilities.
|
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const semver = require('semver');
|
|
14
|
+
|
|
15
|
+
// This test ensures that the electron dependency declared in our package.json
|
|
16
|
+
// is semver-satisfied by the actual version of the electron package we're using.
|
|
17
|
+
// While this is normally the job of a package manager like Yarn, in our case we
|
|
18
|
+
// may use Yarn forced resolutions that defeat versioning, so we want additional
|
|
19
|
+
// safety to ensure the target of the resolution is in sync with the declared dependency.
|
|
20
|
+
describe('Electron dependency', () => {
|
|
21
|
+
test('should be semver-satisfied by the actual electron version', () => {
|
|
22
|
+
// $FlowIssue[untyped-import] - package.json is not typed
|
|
23
|
+
const ourPackageJson = require('../package.json');
|
|
24
|
+
|
|
25
|
+
const declaredElectronVersion = ourPackageJson.dependencies.electron;
|
|
26
|
+
expect(declaredElectronVersion).toBeTruthy();
|
|
27
|
+
|
|
28
|
+
// $FlowIssue[untyped-import] - package.json is not typed
|
|
29
|
+
const electronPackageJson = require('electron/package.json');
|
|
30
|
+
|
|
31
|
+
const actualElectronVersion = electronPackageJson.version;
|
|
32
|
+
expect(actualElectronVersion).toBeTruthy();
|
|
33
|
+
|
|
34
|
+
const isSatisfied = semver.satisfies(
|
|
35
|
+
actualElectronVersion,
|
|
36
|
+
declaredElectronVersion,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
expect(isSatisfied).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { BrowserWindow, app, shell } = require("electron");
|
|
4
|
+
const util = require("util");
|
|
5
|
+
const windowMetadata = new WeakMap();
|
|
6
|
+
function handleLaunchArgs(argv) {
|
|
7
|
+
const {
|
|
8
|
+
values: { frontendUrl, windowKey },
|
|
9
|
+
} = util.parseArgs({
|
|
10
|
+
options: {
|
|
11
|
+
frontendUrl: {
|
|
12
|
+
type: "string",
|
|
13
|
+
},
|
|
14
|
+
windowKey: {
|
|
15
|
+
type: "string",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
args: argv,
|
|
19
|
+
});
|
|
20
|
+
const existingWindow = BrowserWindow.getAllWindows().find((window) => {
|
|
21
|
+
const metadata = windowMetadata.get(window);
|
|
22
|
+
if (!metadata) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return metadata.windowKey === windowKey;
|
|
26
|
+
});
|
|
27
|
+
if (existingWindow) {
|
|
28
|
+
if (existingWindow.isVisible()) {
|
|
29
|
+
existingWindow.flashFrame(true);
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
existingWindow.flashFrame(false);
|
|
32
|
+
}, 1000);
|
|
33
|
+
}
|
|
34
|
+
if (process.platform === "darwin") {
|
|
35
|
+
app.focus({
|
|
36
|
+
steal: true,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
existingWindow.focus();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const frontendWindow = new BrowserWindow({
|
|
43
|
+
width: 1200,
|
|
44
|
+
height: 600,
|
|
45
|
+
webPreferences: {
|
|
46
|
+
partition: "persist:react-native-devtools",
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
frontendWindow.webContents.setWindowOpenHandler(({ url }) => {
|
|
50
|
+
shell.openExternal(url);
|
|
51
|
+
return {
|
|
52
|
+
action: "deny",
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
frontendWindow.loadURL(frontendUrl);
|
|
56
|
+
windowMetadata.set(frontendWindow, {
|
|
57
|
+
windowKey,
|
|
58
|
+
});
|
|
59
|
+
if (process.platform === "darwin") {
|
|
60
|
+
app.focus({
|
|
61
|
+
steal: true,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
app.whenReady().then(() => {
|
|
66
|
+
handleLaunchArgs(process.argv.slice(2));
|
|
67
|
+
app.on(
|
|
68
|
+
"second-instance",
|
|
69
|
+
(event, electronArgv, workingDirectory, additionalData) => {
|
|
70
|
+
handleLaunchArgs(additionalData.argv);
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
app.on("window-all-closed", function () {
|
|
75
|
+
app.quit();
|
|
76
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
*/
|
|
10
|
+
|
|
11
|
+
declare function unstable_spawnDebuggerShellWithArgs(
|
|
12
|
+
args: string[],
|
|
13
|
+
$$PARAM_1$$?: Readonly<{ mode?: "syncThenExit" | "detached" }>
|
|
14
|
+
): Promise<void>;
|
|
15
|
+
export { unstable_spawnDebuggerShellWithArgs };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.unstable_spawnDebuggerShellWithArgs =
|
|
7
|
+
unstable_spawnDebuggerShellWithArgs;
|
|
8
|
+
const { spawn } = require("cross-spawn");
|
|
9
|
+
async function unstable_spawnDebuggerShellWithArgs(
|
|
10
|
+
args,
|
|
11
|
+
{ mode = "detached" } = {}
|
|
12
|
+
) {
|
|
13
|
+
const electronPath = require("electron");
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const child = spawn(
|
|
16
|
+
electronPath,
|
|
17
|
+
[require.resolve("../electron"), ...args],
|
|
18
|
+
{
|
|
19
|
+
stdio: "inherit",
|
|
20
|
+
windowsHide: true,
|
|
21
|
+
detached: mode === "detached",
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
if (mode === "detached") {
|
|
25
|
+
child.on("spawn", () => {
|
|
26
|
+
resolve();
|
|
27
|
+
});
|
|
28
|
+
child.on("close", (code) => {
|
|
29
|
+
if (code !== 0) {
|
|
30
|
+
reject(
|
|
31
|
+
new Error(
|
|
32
|
+
`Failed to open debugger shell: ${electronPath} exited with code ${code}`
|
|
33
|
+
)
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
child.unref();
|
|
38
|
+
} else if (mode === "syncThenExit") {
|
|
39
|
+
child.on("close", function (code, signal) {
|
|
40
|
+
if (code === null) {
|
|
41
|
+
console.error(electronPath, "exited with signal", signal);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
process.exit(code);
|
|
45
|
+
});
|
|
46
|
+
const handleTerminationSignal = function (signal) {
|
|
47
|
+
process.on(signal, function signalHandler() {
|
|
48
|
+
if (!child.killed) {
|
|
49
|
+
child.kill(signal);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
handleTerminationSignal("SIGINT");
|
|
54
|
+
handleTerminationSignal("SIGTERM");
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
*/
|
|
10
|
+
|
|
11
|
+
declare function unstable_spawnDebuggerShellWithArgs(
|
|
12
|
+
args: string[],
|
|
13
|
+
$$PARAM_1$$?: $ReadOnly<{
|
|
14
|
+
// In 'syncAndExit' mode, the current process will block until the spawned process exits, and then it will exit
|
|
15
|
+
// with the same exit code as the spawned process.
|
|
16
|
+
// In 'detached' mode, the spawned process will be detached from the current process and the current process will
|
|
17
|
+
// continue to run normally.
|
|
18
|
+
mode?: "syncThenExit" | "detached",
|
|
19
|
+
}>
|
|
20
|
+
): Promise<void>;
|
|
21
|
+
|
|
22
|
+
export { unstable_spawnDebuggerShellWithArgs };
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@react-native/debugger-shell",
|
|
3
|
+
"version": "0.81.0-nightly-20250531-cddfe4a03",
|
|
4
|
+
"description": "Experimental debugger shell for React Native for use with @react-native/debugger-frontend",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react-native",
|
|
7
|
+
"tools"
|
|
8
|
+
],
|
|
9
|
+
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/debugger-shell#readme",
|
|
10
|
+
"bugs": "https://github.com/facebook/react-native/issues",
|
|
11
|
+
"main": "./dist/node/index.js",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"node": "./dist/node/index.js",
|
|
15
|
+
"electron": "./dist/electron/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./package.json": "./package.json"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"dev": "electron src/electron"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/facebook/react-native.git",
|
|
25
|
+
"directory": "packages/debugger-shell"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18",
|
|
30
|
+
"electron": ">=36.2.0"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"cross-spawn": "^7.0.6",
|
|
34
|
+
"electron": "36.2.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"semver": "^7.1.3"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
*/
|
|
10
|
+
|
|
11
|
+
// $FlowFixMe[unclear-type] We have no Flow types for the Electron API.
|
|
12
|
+
const {BrowserWindow, app, shell} = require('electron') as any;
|
|
13
|
+
const util = require('util');
|
|
14
|
+
|
|
15
|
+
const windowMetadata = new WeakMap<
|
|
16
|
+
typeof BrowserWindow,
|
|
17
|
+
$ReadOnly<{
|
|
18
|
+
windowKey: string,
|
|
19
|
+
}>,
|
|
20
|
+
>();
|
|
21
|
+
|
|
22
|
+
function handleLaunchArgs(argv: string[]) {
|
|
23
|
+
const {
|
|
24
|
+
values: {frontendUrl, windowKey},
|
|
25
|
+
} = util.parseArgs({
|
|
26
|
+
options: {
|
|
27
|
+
frontendUrl: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
},
|
|
30
|
+
windowKey: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
args: argv,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Find an existing window for this app and launch configuration.
|
|
38
|
+
const existingWindow = BrowserWindow.getAllWindows().find(window => {
|
|
39
|
+
const metadata = windowMetadata.get(window);
|
|
40
|
+
if (!metadata) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return metadata.windowKey === windowKey;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (existingWindow) {
|
|
47
|
+
// If the window is already visible, flash it.
|
|
48
|
+
if (existingWindow.isVisible()) {
|
|
49
|
+
existingWindow.flashFrame(true);
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
existingWindow.flashFrame(false);
|
|
52
|
+
}, 1000);
|
|
53
|
+
}
|
|
54
|
+
if (process.platform === 'darwin') {
|
|
55
|
+
app.focus({
|
|
56
|
+
steal: true,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
existingWindow.focus();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Create the browser window.
|
|
64
|
+
const frontendWindow = new BrowserWindow({
|
|
65
|
+
width: 1200,
|
|
66
|
+
height: 600,
|
|
67
|
+
webPreferences: {
|
|
68
|
+
partition: 'persist:react-native-devtools',
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Open links in the default browser instead of in new Electron windows.
|
|
73
|
+
frontendWindow.webContents.setWindowOpenHandler(({url}) => {
|
|
74
|
+
shell.openExternal(url);
|
|
75
|
+
return {action: 'deny'};
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
frontendWindow.loadURL(frontendUrl);
|
|
79
|
+
|
|
80
|
+
windowMetadata.set(frontendWindow, {
|
|
81
|
+
windowKey,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (process.platform === 'darwin') {
|
|
85
|
+
app.focus({
|
|
86
|
+
steal: true,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
app.whenReady().then(() => {
|
|
92
|
+
handleLaunchArgs(process.argv.slice(2));
|
|
93
|
+
|
|
94
|
+
app.on(
|
|
95
|
+
'second-instance',
|
|
96
|
+
(event, electronArgv, workingDirectory, additionalData) => {
|
|
97
|
+
handleLaunchArgs(additionalData.argv);
|
|
98
|
+
},
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
app.on('window-all-closed', function () {
|
|
103
|
+
app.quit();
|
|
104
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
*/
|
|
10
|
+
|
|
11
|
+
// $FlowFixMe[unclear-type] We have no Flow types for the Electron API.
|
|
12
|
+
const {app} = require('electron') as any;
|
|
13
|
+
|
|
14
|
+
const gotTheLock = app.requestSingleInstanceLock({
|
|
15
|
+
argv: process.argv.slice(2),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
if (!gotTheLock) {
|
|
19
|
+
app.quit();
|
|
20
|
+
} else {
|
|
21
|
+
require('./MainInstanceEntryPoint.js');
|
|
22
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/*::
|
|
12
|
+
export type * from './index.flow';
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
if (!process.env.BUILD_EXCLUDE_BABEL_REGISTER) {
|
|
16
|
+
require('../../../../scripts/babel-register').registerForMonorepo();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = require('./index.flow');
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
*/
|
|
10
|
+
|
|
11
|
+
const {spawn} = require('cross-spawn');
|
|
12
|
+
|
|
13
|
+
async function unstable_spawnDebuggerShellWithArgs(
|
|
14
|
+
args: string[],
|
|
15
|
+
{
|
|
16
|
+
mode = 'detached',
|
|
17
|
+
}: $ReadOnly<{
|
|
18
|
+
// In 'syncAndExit' mode, the current process will block until the spawned process exits, and then it will exit
|
|
19
|
+
// with the same exit code as the spawned process.
|
|
20
|
+
// In 'detached' mode, the spawned process will be detached from the current process and the current process will
|
|
21
|
+
// continue to run normally.
|
|
22
|
+
mode?: 'syncThenExit' | 'detached',
|
|
23
|
+
}> = {},
|
|
24
|
+
): Promise<void> {
|
|
25
|
+
// NOTE: Internally at Meta, this is aliased to a workspace that is
|
|
26
|
+
// API-compatible with the 'electron' package, but contains prebuilt binaries
|
|
27
|
+
// that do not need to be downloaded in a postinstall action.
|
|
28
|
+
const electronPath = require('electron');
|
|
29
|
+
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const child = spawn(
|
|
32
|
+
electronPath,
|
|
33
|
+
[require.resolve('../electron'), ...args],
|
|
34
|
+
{
|
|
35
|
+
stdio: 'inherit',
|
|
36
|
+
windowsHide: true,
|
|
37
|
+
detached: mode === 'detached',
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
if (mode === 'detached') {
|
|
41
|
+
child.on('spawn', () => {
|
|
42
|
+
resolve();
|
|
43
|
+
});
|
|
44
|
+
child.on('close', (code /*: number */) => {
|
|
45
|
+
if (code !== 0) {
|
|
46
|
+
reject(
|
|
47
|
+
new Error(
|
|
48
|
+
`Failed to open debugger shell: ${electronPath} exited with code ${code}`,
|
|
49
|
+
),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
child.unref();
|
|
54
|
+
} else if (mode === 'syncThenExit') {
|
|
55
|
+
child.on('close', function (code, signal) {
|
|
56
|
+
if (code === null) {
|
|
57
|
+
console.error(electronPath, 'exited with signal', signal);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
process.exit(code);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const handleTerminationSignal = function (signal: string) {
|
|
64
|
+
process.on(signal, function signalHandler() {
|
|
65
|
+
if (!child.killed) {
|
|
66
|
+
child.kill(signal);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
handleTerminationSignal('SIGINT');
|
|
72
|
+
handleTerminationSignal('SIGTERM');
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export {unstable_spawnDebuggerShellWithArgs};
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/*::
|
|
12
|
+
export type * from './index.flow';
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
if (!process.env.BUILD_EXCLUDE_BABEL_REGISTER) {
|
|
16
|
+
require('../../../../scripts/babel-register').registerForMonorepo();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export * from './index.flow';
|