Skip to content

Commit

Permalink
Copy jsinspector-modern directory (main)
Browse files Browse the repository at this point in the history
  • Loading branch information
huntie authored and Saadnajmi committed Jul 8, 2024
1 parent fd15f76 commit 030be0b
Show file tree
Hide file tree
Showing 75 changed files with 11,000 additions and 195 deletions.

This file was deleted.

118 changes: 118 additions & 0 deletions packages/react-native/ReactCommon/jsinspector-modern/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
load("@fbsource//tools/build_defs:glob_defs.bzl", "subdir_glob")
load("@fbsource//tools/build_defs:platform_defs.bzl", "ANDROID", "APPLE", "CXX", "FBCODE", "WINDOWS")
load("@fbsource//tools/build_defs/oss:rn_defs.bzl", "react_native_xplat_target")
load("@fbsource//xplat/hermes/defs:hermes.bzl", "hermes_is_debugger_enabled")
load("@fbsource//xplat/js/react-native-github/packages/react-native/ReactCommon/jsinspector-modern:DEFS.bzl", "get_fusebox_enabled_flags")
load("//tools/build_defs/oss:rn_defs.bzl", "get_hermes_shared_library_preprocessor_flags", "rn_xplat_cxx_library", "rn_xplat_cxx_test")

oncall("react_native")

EXPORTED_HEADERS = [
"CdpJson.h",
"ConsoleMessage.h",
"ExecutionContext.h",
"ExecutionContextManager.h",
"FallbackRuntimeTargetDelegate.h",
"HostAgent.h",
"HostCommand.h",
"HostTarget.h",
"InspectorFlags.h",
"InspectorInterfaces.h",
"InspectorPackagerConnection.h",
"InstanceAgent.h",
"InstanceTarget.h",
"ReactCdp.h",
"RuntimeAgent.h",
"RuntimeAgentDelegate.h",
"RuntimeTarget.h",
"ScopedExecutor.h",
"SessionState.h",
"StackTrace.h",
"UniqueMonostate.h",
"WeakList.h",
"WebSocketInterfaces.h",
]

rn_xplat_cxx_library(
name = "jsinspector",
srcs = glob(
["*.cpp"],
),
headers = subdir_glob(
[
("", "*.def"),
("", "*.h"),
],
prefix = "jsinspector-modern",
),
header_namespace = "",
exported_headers = subdir_glob(
[
("", header)
for header in EXPORTED_HEADERS
],
prefix = "jsinspector-modern",
),
compiler_flags_disallow_vendor_extensions = True,
compiler_flags_strict_warnings = True,
# jsinspector contains singletons that hold app-global state (InspectorFlags, InspectorImpl).
# Placing it in a shared library makes the singletons safe to use from arbitrary shared libraries
# (even ones that don't depend on one another).
fbandroid_preferred_linkage = "shared",
labels = [
"pfh:ReactNative_CommonInfrastructurePlaceholder",
],
platforms = (ANDROID, APPLE, CXX, FBCODE, WINDOWS),
preprocessor_flags = get_hermes_shared_library_preprocessor_flags() + get_fusebox_enabled_flags() + ([
"-DHERMES_ENABLE_DEBUGGER",
] if hermes_is_debugger_enabled() else []),
tests = [
":tests",
],
visibility = [
"PUBLIC",
],
windows_compiler_flags = ["/WX-"], # Do not treat all warnings as errors
deps = [
"//third-party/glog:glog",
"//xplat/folly:dynamic",
"//xplat/folly:json",
react_native_xplat_target("reactperflogger:reactperflogger"),
react_native_xplat_target("react/featureflags:featureflags"),
react_native_xplat_target("runtimeexecutor:runtimeexecutor"),
],
exported_deps = ["//xplat/jsi:jsi"],
)

rn_xplat_cxx_test(
name = "tests",
srcs = glob([
"tests/**/*.cpp",
]),
headers = glob(["tests/**/*.h"]),
contacts = ["[email protected]"],
cxx_labels = [
"asan-ubsan",
],
platforms = (ANDROID, APPLE, WINDOWS, CXX),
deps = [
":jsinspector",
"//third-party/googletest:gmock_main",
"//third-party/googletest:gtest_main",
"//xplat/ReactNative/react/jsi:hermesinstance",
"//xplat/folly:dynamic",
"//xplat/folly:executor",
"//xplat/folly:format",
"//xplat/folly:json",
"//xplat/folly:json_pointer",
"//xplat/folly:scope_guard",
"//xplat/folly:shared_mutex",
"//xplat/folly:system_thread_id",
"//xplat/folly:thread_local",
"//xplat/folly/executors:manual_executor",
"//xplat/folly/executors:queued_immediate_executor",
"//xplat/hermes/API:HermesAPI",
react_native_xplat_target("hermes/inspector-modern:chrome"),
react_native_xplat_target("react/runtime:runtime"),
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ add_compile_options(
-std=c++20)

file(GLOB jsinspector_SRC CONFIGURE_DEPENDS *.cpp)
# jsinspector contains singletons that hold app-global state (InspectorFlags, InspectorImpl).
# Placing it in a shared library makes the singletons safe to use from arbitrary shared libraries
# (even ones that don't depend on one another).
add_library(jsinspector SHARED ${jsinspector_SRC})

target_include_directories(jsinspector PUBLIC ${REACT_COMMON_DIR})

target_link_libraries(jsinspector
folly_runtime
glog
react_featureflags
runtimeexecutor
reactperflogger
)
27 changes: 27 additions & 0 deletions packages/react-native/ReactCommon/jsinspector-modern/CONCEPTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# jsinspector-modern concepts

## CDP object model

### Target

A debuggable entity that a debugger frontend can connect to.

### Target Delegate

An interface between a Target class and the underlying debuggable entity. For example, HostTargetDelegate is used by HostTarget to send host-related events to the native platform implementation.

### Target Controller

A private interface exposed by a Target class to its Sessions/Agents. For example, HostTargetController is used by HostAgent to safely access the host's HostTargetDelegate, without exposing HostTarget's other private state.

### Session

A single connection between a debugger frontend and a target. There can be multiple active sessions connected to the same target.

### Agent

A handler for a subset of CDP messages for a specific target as part of a specific session.

### Agent Delegate

An interface between an Agent class and some integration-specific, per-session logic/state it relies on (that does not fit in a Target Delegate). For example, a RuntimeAgentDelegate is used by RuntimeAgent to host Hermes's native CDP handler and delegate messages to it. The interface may look exactly like an Agent (purely CDP messages in/out) or there may be a more involved API to expose state/functionality needed by the Agent.
72 changes: 72 additions & 0 deletions packages/react-native/ReactCommon/jsinspector-modern/CdpJson.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* 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.
*/

#include "CdpJson.h"

#include <folly/dynamic.h>
#include <folly/json.h>

namespace facebook::react::jsinspector_modern::cdp {

PreparsedRequest preparse(std::string_view message) {
folly::dynamic parsed = folly::parseJson(message);
return PreparsedRequest{
.id = parsed["id"].getInt(),
.method = parsed["method"].getString(),
.params = parsed.count("params") != 0u ? parsed["params"] : nullptr};
}

std::string PreparsedRequest::toJson() const {
folly::dynamic obj = folly::dynamic::object;
obj["id"] = id;
obj["method"] = method;
if (params != nullptr) {
obj["params"] = params;
}
return folly::toJson(obj);
}

std::string jsonError(
std::optional<RequestId> id,
ErrorCode code,
std::optional<std::string> message) {
auto dynamicError = folly::dynamic::object("code", static_cast<int>(code));
if (message) {
dynamicError("message", *message);
}
return folly::toJson(
(id ? folly::dynamic::object("id", *id)
: folly::dynamic::object("id", nullptr))(
"error", std::move(dynamicError)));
}

std::string jsonResult(RequestId id, const folly::dynamic& result) {
return folly::toJson(folly::dynamic::object("id", id)("result", result));
}

std::string jsonNotification(
std::string_view method,
std::optional<folly::dynamic> params) {
auto dynamicNotification = folly::dynamic::object("method", method);
if (params) {
dynamicNotification("params", *params);
}
return folly::toJson(std::move(dynamicNotification));
}

std::string jsonRequest(
RequestId id,
std::string_view method,
std::optional<folly::dynamic> params) {
auto dynamicRequest = folly::dynamic::object("id", id)("method", method);
if (params) {
dynamicRequest("params", *params);
}
return folly::toJson(std::move(dynamicRequest));
}

} // namespace facebook::react::jsinspector_modern::cdp
138 changes: 138 additions & 0 deletions packages/react-native/ReactCommon/jsinspector-modern/CdpJson.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* 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.
*/

#pragma once

#include <folly/dynamic.h>
#include <folly/json.h>
#include <string>
#include <string_view>

namespace facebook::react::jsinspector_modern::cdp {

using RequestId = long long;

/**
* Error codes to be used in CDP responses.
* https://www.jsonrpc.org/specification#error_object
*/
enum class ErrorCode {
ParseError = -32700,
InvalidRequest = -32600,
MethodNotFound = -32601,
InvalidParams = -32602,
InternalError = -32603
/* -32000 to -32099: Implementation-defined server errors. */
};

/**
* An incoming CDP request that has been parsed into a more usable form.
*/
struct PreparsedRequest {
public:
/**
* The ID of the request.
*/
RequestId id{};

/**
* The name of the method being invoked.
*/
std::string method;

/**
* The parameters passed to the method, if any.
*/
folly::dynamic params;

/**
* Equality operator, useful for unit tests
*/
inline bool operator==(const PreparsedRequest& rhs) const {
return id == rhs.id && method == rhs.method && params == rhs.params;
}

std::string toJson() const;
};

/**
* Parse a JSON-encoded CDP request into its constituent parts.
* \throws ParseError If the input cannot be parsed.
* \throws TypeError If the input does not conform to the expected format.
*/
PreparsedRequest preparse(std::string_view message);

/**
* A type error that may be thrown while preparsing a request, or while
* accessing dynamic params on a request.
*/
using TypeError = folly::TypeError;

/**
* A parse error that may be thrown while preparsing a request.
*/
using ParseError = folly::json::parse_error;

/**
* Helper functions for creating CDP (loosely JSON-RPC) messages of various
* types, returning a JSON string ready for sending over the wire.
*/

/**
* Returns a JSON-formatted string representing an error.
*
* {"id": <id>, "error": { "code": <code>, "message": <message> }}
*
* \param id Request ID. Mandatory, null only if the request omitted it or
* could not be parsed.
* \param code Integer code from cdp::ErrorCode.
* \param message Optional, brief human-readable error message.
*/
std::string jsonError(
std::optional<RequestId> id,
ErrorCode code,
std::optional<std::string> message = std::nullopt);

/**
* Returns a JSON-formatted string representing a successful response.
*
* {"id": <id>, "result": <result>}
*
* \param id The id of the request that this response corresponds to.
* \param result Result payload, defaulting to {}.
*/
std::string jsonResult(
RequestId id,
const folly::dynamic& result = folly::dynamic::object());

/**
* Returns a JSON-formatted string representing a unilateral notification.
*
* {"method": <method>, "params": <params>}
*
* \param method Notification (aka "event") method.
* \param params Optional payload object.
*/
std::string jsonNotification(
std::string_view method,
std::optional<folly::dynamic> params = std::nullopt);

/**
* Returns a JSON-formatted string representing a request.
*
* {"id": <id>, "method": <method>, "params": <params>}
*
* \param id Request ID.
* \param method Requested method.
* \param params Optional payload object.
*/
std::string jsonRequest(
RequestId id,
std::string_view method,
std::optional<folly::dynamic> params = std::nullopt);

} // namespace facebook::react::jsinspector_modern::cdp
Loading

0 comments on commit 030be0b

Please sign in to comment.