first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @format
*/
type DebuggerShellFlavor = "prebuilt" | "dev";
declare function unstable_spawnDebuggerShellWithArgs(
args: string[],
$$PARAM_1$$?: Readonly<{
mode?: "syncThenExit" | "detached";
flavor?: DebuggerShellFlavor;
prebuiltBinaryPath?: string;
}>,
): Promise<void>;
export type DebuggerShellPreparationResult = Readonly<{
code:
| "success"
| "not_implemented"
| "likely_offline"
| "platform_not_supported"
| "possible_corruption"
| "unexpected_error";
humanReadableMessage?: string;
verboseInfo?: string;
}>;
/**
* Attempts to prepare the debugger shell for use and returns a coded result
* that can be used to advise the user on how to proceed in case of failure.
* In particular, this function will attempt to download and extract an
* appropriate binary for the "prebuilt" flavor.
*
* This function should be called early during dev server startup, in parallel
* with other initialization steps, so that the debugger shell is ready to use
* instantly when the user tries to open it (and conversely, the user is
* informed ASAP if it is not ready to use).
*/
declare function unstable_prepareDebuggerShell(
flavor: DebuggerShellFlavor,
$$PARAM_1$$?: { prebuiltBinaryPath?: string },
): Promise<DebuggerShellPreparationResult>;
export { unstable_spawnDebuggerShellWithArgs, unstable_prepareDebuggerShell };

View File

@@ -0,0 +1,120 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true,
});
exports.unstable_prepareDebuggerShell = unstable_prepareDebuggerShell;
exports.unstable_spawnDebuggerShellWithArgs =
unstable_spawnDebuggerShellWithArgs;
var _LaunchUtils = require("./private/LaunchUtils");
const { spawn } = require("cross-spawn");
const path = require("path");
const DEVTOOLS_BINARY_DOTSLASH_FILE = path.join(
__dirname,
"../../bin/react-native-devtools",
);
async function unstable_spawnDebuggerShellWithArgs(
args,
{ mode = "detached", flavor = "prebuilt", prebuiltBinaryPath } = {},
) {
const [binaryPath, baseArgs] = getShellBinaryAndArgs(
flavor,
prebuiltBinaryPath,
);
return new Promise((resolve, reject) => {
const child = spawn(binaryPath, [...baseArgs, ...args], {
stdio: "inherit",
windowsHide: true,
detached: mode === "detached",
});
if (mode === "detached") {
child.on("spawn", () => {
resolve();
});
child.on("close", (code) => {
if (code !== 0) {
reject(
new Error(
`Failed to open debugger shell: exited with code ${code}`,
),
);
}
});
child.unref();
} else if (mode === "syncThenExit") {
child.on("close", function (code, signal) {
if (code === null) {
console.error("Debugger shell exited with signal", signal);
process.exit(1);
}
process.exit(code);
});
const handleTerminationSignal = function (signal) {
process.on(signal, function signalHandler() {
if (!child.killed) {
child.kill(signal);
}
});
};
handleTerminationSignal("SIGINT");
handleTerminationSignal("SIGTERM");
}
});
}
async function unstable_prepareDebuggerShell(
flavor,
{ prebuiltBinaryPath } = {},
) {
try {
switch (flavor) {
case "prebuilt":
const prebuiltResult = await (0,
_LaunchUtils.prepareDebuggerShellFromDotSlashFile)(
prebuiltBinaryPath ?? DEVTOOLS_BINARY_DOTSLASH_FILE,
);
if (prebuiltResult.code !== "success") {
return prebuiltResult;
}
break;
case "dev":
break;
default:
throw new Error(`Unknown flavor: ${flavor}`);
}
const [binaryPath, baseArgs] = getShellBinaryAndArgs(
flavor,
prebuiltBinaryPath,
);
const { code, stderr } = await (0, _LaunchUtils.spawnAndGetStderr)(
binaryPath,
[...baseArgs, "--version"],
);
if (code !== 0) {
return {
code: "unexpected_error",
verboseInfo: stderr,
};
}
return {
code: "success",
};
} catch (e) {
return {
code: "unexpected_error",
verboseInfo: e.message,
};
}
}
function getShellBinaryAndArgs(flavor, prebuiltBinaryPath) {
switch (flavor) {
case "prebuilt":
return [
require("fb-dotslash"),
[prebuiltBinaryPath ?? DEVTOOLS_BINARY_DOTSLASH_FILE],
];
case "dev":
return [require("electron"), [require.resolve("../electron")]];
default:
throw new Error(`Unknown flavor: ${flavor}`);
}
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
// The 'prebuilt' flavor will use the prebuilt shell binary (and the JavaScript embedded in it).
// The 'dev' flavor will use a stock Electron binary and run the shell code from the `electron/` directory.
type DebuggerShellFlavor = "prebuilt" | "dev";
declare function unstable_spawnDebuggerShellWithArgs(
args: string[],
$$PARAM_1$$?: $ReadOnly<{
// In 'syncAndExit' mode, the current process will block until the spawned process exits, and then it will exit
// with the same exit code as the spawned process.
// In 'detached' mode, the spawned process will be detached from the current process and the current process will
// continue to run normally.
mode?: "syncThenExit" | "detached",
flavor?: DebuggerShellFlavor,
prebuiltBinaryPath?: string,
}>,
): Promise<void>;
export type DebuggerShellPreparationResult = $ReadOnly<{
code:
| "success"
| "not_implemented"
| "likely_offline"
| "platform_not_supported"
| "possible_corruption"
| "unexpected_error",
humanReadableMessage?: string,
verboseInfo?: string,
}>;
/**
* Attempts to prepare the debugger shell for use and returns a coded result
* that can be used to advise the user on how to proceed in case of failure.
* In particular, this function will attempt to download and extract an
* appropriate binary for the "prebuilt" flavor.
*
* This function should be called early during dev server startup, in parallel
* with other initialization steps, so that the debugger shell is ready to use
* instantly when the user tries to open it (and conversely, the user is
* informed ASAP if it is not ready to use).
*/
declare function unstable_prepareDebuggerShell(
flavor: DebuggerShellFlavor,
$$PARAM_1$$?: { prebuiltBinaryPath?: string },
): Promise<DebuggerShellPreparationResult>;
export { unstable_spawnDebuggerShellWithArgs, unstable_prepareDebuggerShell };

View File

@@ -0,0 +1,19 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @format
*/
import type { DebuggerShellPreparationResult } from "../";
declare function spawnAndGetStderr(
command: string,
args: string[],
): Promise<{ code: number; stderr: string }>;
declare function prepareDebuggerShellFromDotSlashFile(
filePath: string,
): Promise<DebuggerShellPreparationResult>;
export { spawnAndGetStderr, prepareDebuggerShellFromDotSlashFile };

View File

@@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true,
});
exports.prepareDebuggerShellFromDotSlashFile =
prepareDebuggerShellFromDotSlashFile;
exports.spawnAndGetStderr = spawnAndGetStderr;
const { spawn } = require("cross-spawn");
async function spawnAndGetStderr(command, args) {
return new Promise((resolve, reject) => {
const child = spawn(command, args, {
stdio: ["ignore", "ignore", "pipe"],
encoding: "utf8",
windowsHide: true,
});
let stderr = "";
child.stderr.on("data", (data) => {
stderr += data;
});
child.on("error", (error) => {
reject(error);
});
child.on("close", (code, signal) => {
resolve({
code,
stderr,
});
});
});
}
async function prepareDebuggerShellFromDotSlashFile(filePath) {
const { code, stderr } = await spawnAndGetStderr(require("fb-dotslash"), [
"--",
"fetch",
filePath,
]);
if (code === 0) {
return {
code: "success",
};
}
if (
stderr.includes("dotslash error") &&
stderr.includes("no providers succeeded")
) {
if (stderr.includes("failed to verify artifact")) {
return {
code: "possible_corruption",
humanReadableMessage:
"Failed to verify the latest version of React Native DevTools. " +
"Using a fallback version instead. ",
verboseInfo: stderr,
};
}
return {
code: "likely_offline",
humanReadableMessage:
"Failed to download the latest version of React Native DevTools. " +
"Using a fallback version instead. " +
"Connect to the internet or check your network settings.",
verboseInfo: stderr,
};
}
if (
stderr.includes("dotslash error") &&
stderr.includes("platform not supported")
) {
return {
code: "platform_not_supported",
humanReadableMessage:
"The latest version of React Native DevTools is not supported on this platform. " +
"Using a fallback version instead.",
verboseInfo: stderr,
};
}
return {
code: "unexpected_error",
humanReadableMessage:
"An unexpected error occured while installing the latest version of React Native DevTools. " +
"Using a fallback version instead.",
verboseInfo: stderr,
};
}

View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
import type { DebuggerShellPreparationResult } from "../";
declare function spawnAndGetStderr(
command: string,
args: string[],
): Promise<{
code: number,
stderr: string,
}>;
declare function prepareDebuggerShellFromDotSlashFile(
filePath: string,
): Promise<DebuggerShellPreparationResult>;
export { spawnAndGetStderr, prepareDebuggerShellFromDotSlashFile };