@mobrowser/native 2.0.0

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 ADDED
@@ -0,0 +1 @@
1
+ This package contains the configuration files for MōBrowser native integration.
@@ -0,0 +1,80 @@
1
+ message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
2
+
3
+ include(${PROJECT_ROOT_DIR}/node_modules/@mobrowser/native/cmake/Platform.cmake)
4
+
5
+ # Configure project properties.
6
+ set(TARGET_NAME "app")
7
+ set(STATIC_LIB_NAME "mobrowser_lib")
8
+ set(SHARED_LIB_NAME "mobrowser_client")
9
+ set(DIST_DIR ${CMAKE_BINARY_DIR}/bin)
10
+
11
+ # Configure SDK directory.
12
+ if (OS_WIN)
13
+ set(MOBROWSER_SDK_DIR "${PROJECT_ROOT_DIR}/node_modules/@mobrowser/sdk-win-x64")
14
+ elseif (OS_MAC)
15
+ set(MOBROWSER_SDK_DIR "${PROJECT_ROOT_DIR}/node_modules/@mobrowser/sdk-darwin-arm64")
16
+ elseif (OS_LINUX)
17
+ set(MOBROWSER_SDK_DIR "${PROJECT_ROOT_DIR}/node_modules/@mobrowser/sdk-linux-x64")
18
+ endif ()
19
+
20
+ cmake_path(ABSOLUTE_PATH MOBROWSER_SDK_DIR NORMALIZE)
21
+ message(STATUS "MOBROWSER_SDK_DIR: ${MOBROWSER_SDK_DIR}")
22
+ set(MOBROWSER_SDK_NATIVE_DIR "${PROJECT_ROOT_DIR}/node_modules/@mobrowser/native")
23
+ cmake_path(ABSOLUTE_PATH MOBROWSER_SDK_NATIVE_DIR NORMALIZE)
24
+
25
+ if (MSVC)
26
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
27
+ add_compile_options(/MP)
28
+ # Suppress Protobuf warnings
29
+ add_compile_options(
30
+ /wd4065 # switch statement contains 'default' but no 'case' labels
31
+ /wd4047 # 'operator' : 'identifier1' differs in levels of indirection from 'identifier2'
32
+ /wd4146 # unary minus operator applied to unsigned type
33
+ /wd4244 # 'conversion' conversion from 'type1' to 'type2', possible loss of data
34
+ /wd4251 # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
35
+ /wd4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data
36
+ /wd4305 # 'identifier' : truncation from 'type1' to 'type2'
37
+ /wd4307 # 'operator' : integral constant overflow
38
+ /wd4309 # 'conversion' : truncation of constant value
39
+ /wd4334 # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
40
+ /wd4355 # 'this' : used in base member initializer list
41
+ /wd4506 # no definition for inline function 'function'
42
+ /wd4800 # 'type' : forcing value to bool 'true' or 'false' (performance warning)
43
+ /wd4996 # The compiler encountered a deprecated declaration.
44
+ /wd4715 # 'function' : not all control paths return a value
45
+ /wd5287 # operands are different enum types
46
+ )
47
+ else ()
48
+ # Suppress Protobuf warnings for Clang/GCC
49
+ add_compile_options(
50
+ -Wno-deprecated-declarations
51
+ )
52
+ endif ()
53
+
54
+ # Suppress Protobuf linker warnings
55
+ if (APPLE)
56
+ add_link_options("-Wl,-no_warn_duplicate_libraries")
57
+ endif ()
58
+
59
+ if (OS_LINUX)
60
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
61
+ endif ()
62
+
63
+ include(${PROJECT_ROOT_DIR}/node_modules/@mobrowser/native/cmake/Protobuf.cmake)
64
+
65
+ # Create the shared library mobrowser_client with MoBrowser runtime
66
+ add_library(${SHARED_LIB_NAME} SHARED
67
+ ${GENERATED_SOURCES}
68
+ ${MOBROWSER_SDK_NATIVE_DIR}/internal/rpc.cc
69
+ ${MOBROWSER_SDK_NATIVE_DIR}/internal/transport.cc)
70
+
71
+ # Set up include paths for mobrowser_client
72
+ target_include_directories(${SHARED_LIB_NAME} PRIVATE
73
+ ${protobuf_SOURCE_DIR}/src
74
+ ${absl_SOURCE_DIR}
75
+ ${PROJECT_SOURCE_DIR}/native/gen
76
+ ${MOBROWSER_SDK_NATIVE_DIR}/include
77
+ ${MOBROWSER_SDK_DIR}/include)
78
+
79
+ # Link mobrowser_lib into mobrowser_client
80
+ target_link_libraries(${SHARED_LIB_NAME} PRIVATE ${STATIC_LIB_NAME} libprotobuf)
@@ -0,0 +1,13 @@
1
+ if (${CMAKE_SYSTEM_NAME} MATCHES Windows)
2
+ set(OS_WIN TRUE)
3
+ add_definitions(-DOS_WIN)
4
+ elseif (${CMAKE_SYSTEM_NAME} MATCHES Linux)
5
+ set(OS_LINUX TRUE)
6
+ add_definitions(-DOS_LINUX)
7
+ elseif (${CMAKE_SYSTEM_NAME} MATCHES Darwin)
8
+ set(OS_MAC TRUE)
9
+ add_definitions(-DOS_MAC)
10
+ # Set minimum macOS version to 12.0 for broader compatibility
11
+ # Use FORCE to ensure this overrides any cached value
12
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "Minimum macOS deployment version" FORCE)
13
+ endif ()
@@ -0,0 +1,121 @@
1
+ include(FetchContent)
2
+
3
+ set(FETCHCONTENT_QUIET OFF)
4
+ set(BUILD_TESTING OFF)
5
+
6
+ set(PROTOBUF_VERSION 33.2)
7
+
8
+ if (NOT DEFINED PROTO_DIR)
9
+ file(REAL_PATH "${PROJECT_ROOT_DIR}/src/native/proto" PROTO_DIR)
10
+ endif ()
11
+
12
+ # Replace backslashes with forward slashes to fix path issue
13
+ # when parsing the path with backslashes in CMake.
14
+ string(REPLACE "\\" "/" PROTO_DIR "${PROTO_DIR}")
15
+
16
+ message(STATUS "Proto dir: ${PROTO_DIR}")
17
+
18
+ file(GLOB_RECURSE PROTO_FILES CONFIGURE_DEPENDS "${PROTO_DIR}/*.proto")
19
+
20
+ # Ensure protobuf (and everything else) inherits the macOS deployment target
21
+ if (APPLE)
22
+ if (NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
23
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "Minimum macOS deployment version")
24
+ endif ()
25
+ endif ()
26
+
27
+ # Verify C++17 or higher is set (required by Abseil).
28
+ if (NOT DEFINED CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 17)
29
+ message(FATAL_ERROR "CMAKE_CXX_STANDARD must be set to 17 or higher before including MoBrowser.cmake")
30
+ endif ()
31
+
32
+ # ##############################################################################
33
+ # Protobuf (with automatic Abseil fetching)
34
+ # ##############################################################################
35
+ message(CHECK_START "Fetching Protobuf")
36
+ list(APPEND CMAKE_MESSAGE_INDENT " ")
37
+
38
+ # Abseil options
39
+ set(ABSL_USE_SYSTEM_INCLUDES ON CACHE BOOL "Use system includes for Abseil")
40
+ set(ABSL_PROPAGATE_CXX_STD ON CACHE BOOL "Propagate C++ standard from consumers")
41
+ set(ABSL_ENABLE_INSTALL OFF CACHE BOOL "Enable install rules for Abseil")
42
+ set(ABSL_BUILD_TESTING OFF CACHE BOOL "Build Abseil tests")
43
+ set(ABSL_BUILD_TEST_HELPERS OFF CACHE BOOL "Build Abseil test helpers")
44
+ set(ABSL_USE_EXTERNAL_GOOGLETEST ON CACHE BOOL "Use external GTest when needed")
45
+ set(ABSL_FIND_GOOGLETEST OFF CACHE BOOL "Let Abseil find GTest on its own")
46
+ set(ABSL_MSVC_STATIC_RUNTIME ON CACHE BOOL "Use static runtime with MSVC")
47
+
48
+ # Protobuf options
49
+ set(protobuf_BUILD_TESTS OFF CACHE BOOL "Do not build Protobuf tests")
50
+ set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "Build Protobuf as static libs")
51
+ set(protobuf_BUILD_EXPORT OFF CACHE BOOL "Do not export Protobuf CMake targets")
52
+ set(protobuf_INSTALL OFF CACHE BOOL "Disable Protobuf install rules")
53
+ set(protobuf_BUILD_LIBUPB ON CACHE BOOL "Build libupb for Protobuf")
54
+ set(protobuf_MSVC_STATIC_RUNTIME ON CACHE BOOL "Use static runtime with MSVC")
55
+ set(protobuf_FORCE_FETCH_DEPENDENCIES ON CACHE BOOL "Let Protobuf fetch Abseil and utf8_range")
56
+ set(utf8_range_ENABLE_INSTALL OFF CACHE BOOL "Disable utf8_range install rules")
57
+
58
+ FetchContent_Declare(
59
+ Protobuf
60
+ GIT_REPOSITORY "https://github.com/protocolbuffers/protobuf.git"
61
+ GIT_TAG "v${PROTOBUF_VERSION}"
62
+ GIT_SHALLOW TRUE
63
+ )
64
+
65
+ FetchContent_MakeAvailable(Protobuf)
66
+
67
+ list(POP_BACK CMAKE_MESSAGE_INDENT)
68
+ message(CHECK_PASS "fetched")
69
+
70
+ # ##############################################################################
71
+ # Protobuf code generation
72
+ # ##############################################################################
73
+
74
+ # Ensure output directory exists
75
+ file(MAKE_DIRECTORY "${PROJECT_SOURCE_DIR}/src/native/gen")
76
+
77
+ # Set proto paths for protoc command
78
+ set(PROTOBUF_IMPORT_DIRS "${protobuf_SOURCE_DIR}/src" "${PROTO_DIR}")
79
+
80
+ set(GENERATED_SOURCES)
81
+ foreach (f IN LISTS PROTO_FILES)
82
+ # Get file name without extension: foo/bar/baz.proto -> baz
83
+ get_filename_component(proto_name "${f}" NAME_WE)
84
+
85
+ # Map proto path under .../proto/... to .../src/native/gen/...
86
+ # e.g. <root>/proto/foo/bar/baz.proto -> <root>/src/native/gen/foo/bar/baz.pb.cc
87
+ string(REGEX REPLACE ".*/proto/" "${PROJECT_SOURCE_DIR}/src/native/gen/" base_path_with_ext "${f}")
88
+ # Remove the .proto extension from base_path
89
+ string(REGEX REPLACE "\\.proto$" "" base_path "${base_path_with_ext}")
90
+
91
+ set(msg_header "${base_path}.pb.h")
92
+ set(msg_source "${base_path}.pb.cc")
93
+ set(rpc_header "${base_path}.rpc.h")
94
+ set(rpc_source "${base_path}.rpc.cc")
95
+
96
+ list(APPEND GENERATED_SOURCES
97
+ "${msg_header}" "${msg_source}"
98
+ "${rpc_header}" "${rpc_source}")
99
+ endforeach ()
100
+
101
+ # Build protoc command arguments
102
+ set(PROTOC_ARGS)
103
+ foreach(dir ${PROTOBUF_IMPORT_DIRS})
104
+ list(APPEND PROTOC_ARGS --proto_path=${dir})
105
+ endforeach()
106
+
107
+ set(CC_NATIVEGEN_PLUGIN "${MOBROWSER_SDK_DIR}/bin/cc_nativegen${CMAKE_EXECUTABLE_SUFFIX}")
108
+
109
+ add_custom_command(
110
+ OUTPUT ${GENERATED_SOURCES}
111
+ COMMAND $<TARGET_FILE:protoc>
112
+ ${PROTOC_ARGS}
113
+ --cpp_out=${PROJECT_SOURCE_DIR}/src/native/gen
114
+ --plugin=protoc-gen-rpc=${CC_NATIVEGEN_PLUGIN}
115
+ --rpc_out=${PROJECT_SOURCE_DIR}/src/native/gen
116
+ ${PROTO_FILES}
117
+ DEPENDS ${PROTO_FILES} protoc ${CC_NATIVEGEN_PLUGIN}
118
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
119
+ COMMENT "Generating C++ sources from .proto files"
120
+ VERBATIM
121
+ )
@@ -0,0 +1,152 @@
1
+ // Copyright (c) 2000-2026 TeamDev. All rights reserved.
2
+ // TeamDev PROPRIETARY and CONFIDENTIAL.
3
+ // Use is subject to license terms.
4
+
5
+ #ifndef MO_RPC_CALLBACK_H_
6
+ #define MO_RPC_CALLBACK_H_
7
+
8
+ #include <cstddef>
9
+ #include <functional>
10
+ #include <memory>
11
+ #include <mutex>
12
+ #include <string>
13
+ #include <utility>
14
+
15
+ #include "google/protobuf/message.h"
16
+
17
+ namespace mo::rpc {
18
+
19
+ template<class T>
20
+ concept ProtobufMessageType = std::is_base_of<google::protobuf::Message, T>::value;
21
+
22
+ // Type-erased callback handlers for RPC operations.
23
+ // These work with serialized protobuf data and are independent of message type.
24
+ using OnCompleteHandler = std::function<void(uint64_t id, const char* data, size_t size)>;
25
+ using OnRejectHandler = std::function<void(uint64_t id, const char* error)>;
26
+
27
+ // A move-only, one-shot RPC callback for completing or rejecting an
28
+ // asynchronous operation.
29
+ //
30
+ // Thread Safety:
31
+ // - All public methods are thread-safe and may be called from any thread.
32
+ // - Only one of Complete(), Reject(), or auto-cancel will fire; subsequent
33
+ // calls are no-ops.
34
+ //
35
+ // Usage:
36
+ // std::move(callback).Complete(response); // Success path
37
+ // std::move(callback).Reject("error"); // Failure path
38
+ // // Or let it destruct to auto-cancel
39
+ //
40
+ template <ProtobufMessageType T>
41
+ class Callback {
42
+ public:
43
+ // Constructs a callback with the given completion and rejection handlers.
44
+ Callback(uint64_t id, OnCompleteHandler on_complete, OnRejectHandler on_reject)
45
+ : id_(id),
46
+ on_complete_(std::move(on_complete)),
47
+ on_reject_(std::move(on_reject)),
48
+ is_pending_(true),
49
+ mutex_(std::make_unique<std::mutex>()) {}
50
+
51
+ // Non-copyable.
52
+ Callback(const Callback&) = delete;
53
+ Callback& operator=(const Callback&) = delete;
54
+
55
+ // Move constructor. The source callback becomes inert (already handled).
56
+ Callback(Callback&& other) noexcept : mutex_(std::make_unique<std::mutex>()) {
57
+ std::lock_guard<std::mutex> lock(*other.mutex_);
58
+ id_ = other.id_;
59
+ on_complete_ = std::move(other.on_complete_);
60
+ on_reject_ = std::move(other.on_reject_);
61
+ is_pending_ = other.is_pending_;
62
+ other.is_pending_ = false;
63
+ }
64
+
65
+ // Move assignment. Auto-cancels any pending operation on this callback
66
+ // before taking ownership from the source.
67
+ Callback& operator=(Callback&& other) noexcept {
68
+ if (this != &other) {
69
+ AutoCancelIfPending();
70
+ std::lock_guard<std::mutex> lock(*other.mutex_);
71
+ id_ = other.id_;
72
+ on_complete_ = std::move(other.on_complete_);
73
+ on_reject_ = std::move(other.on_reject_);
74
+ is_pending_ = other.is_pending_;
75
+ other.is_pending_ = false;
76
+ }
77
+ return *this;
78
+ }
79
+
80
+ // Destructor. Auto-cancels if still pending.
81
+ ~Callback() { AutoCancelIfPending(); }
82
+
83
+ // Completes the callback successfully with the given response.
84
+ //
85
+ // This is a one-shot operation; if already handled (completed, rejected, or
86
+ // moved-from), this call is a no-op.
87
+ //
88
+ // Note: The `&&` qualifier indicates this consumes the callback. Use with
89
+ // std::move: `std::move(callback).Complete(response);`
90
+ void Complete(T response) && {
91
+ std::unique_lock<std::mutex> lock(*mutex_);
92
+ if (!is_pending_) {
93
+ return;
94
+ }
95
+ is_pending_ = false;
96
+ OnCompleteHandler handler = std::move(on_complete_);
97
+ on_reject_ = nullptr;
98
+ lock.unlock();
99
+ auto buffer = response.SerializeAsString();
100
+ handler(id_, buffer.data(), buffer.size());
101
+ }
102
+
103
+ // Rejects the callback with an error message.
104
+ //
105
+ // This is a one-shot operation; if already handled (completed, rejected, or
106
+ // moved-from), this call is a no-op.
107
+ //
108
+ // Note: The `&&` qualifier indicates this consumes the callback. Use with
109
+ // std::move: `std::move(callback).Reject("error message");`
110
+ void Reject(std::string error) && {
111
+ std::unique_lock<std::mutex> lock(*mutex_);
112
+ if (!is_pending_) {
113
+ return;
114
+ }
115
+ is_pending_ = false;
116
+ OnRejectHandler handler = std::move(on_reject_);
117
+ on_complete_ = nullptr;
118
+ lock.unlock();
119
+ handler(id_, error.c_str());
120
+ }
121
+
122
+ private:
123
+ // Auto-cancels the callback if still pending by invoking the rejection
124
+ // handler with a cancellation message.
125
+ void AutoCancelIfPending() {
126
+ std::unique_lock<std::mutex> lock(*mutex_);
127
+ if (!is_pending_ || !on_reject_) {
128
+ return;
129
+ }
130
+ is_pending_ = false;
131
+ OnRejectHandler handler = std::move(on_reject_);
132
+ on_complete_ = nullptr;
133
+ lock.unlock();
134
+ handler(id_, "RPC canceled: callback destroyed without completion.");
135
+ }
136
+
137
+ uint64_t id_;
138
+ OnCompleteHandler on_complete_;
139
+ OnRejectHandler on_reject_;
140
+
141
+ // True if neither Complete() nor Reject() has been called yet.
142
+ // Protected by mutex_.
143
+ bool is_pending_;
144
+
145
+ // Mutex protecting internal state.
146
+ // Stored as unique_ptr to ensure stable address across moves
147
+ std::unique_ptr<std::mutex> mutex_;
148
+ };
149
+
150
+ } // namespace mo::rpc
151
+
152
+ #endif // MO_RPC_CALLBACK_H_
package/include/rpc.h ADDED
@@ -0,0 +1,14 @@
1
+ // Copyright (c) 2000-2026 TeamDev. All rights reserved.
2
+ // TeamDev PROPRIETARY and CONFIDENTIAL.
3
+ // Use is subject to license terms.
4
+
5
+ #ifndef MO_RPC_H_
6
+ #define MO_RPC_H_
7
+
8
+ #include "service.h"
9
+
10
+ namespace mo::rpc {
11
+ void RegisterService(Service* service);
12
+ }
13
+
14
+ #endif // MO_RPC_H_
@@ -0,0 +1,98 @@
1
+ // Copyright (c) 2000-2026 TeamDev. All rights reserved.
2
+ // TeamDev PROPRIETARY and CONFIDENTIAL.
3
+ // Use is subject to license terms.
4
+
5
+ #ifndef MO_RPC_SERVICE_H_
6
+ #define MO_RPC_SERVICE_H_
7
+
8
+ #include <string>
9
+
10
+ #include "callback.h"
11
+
12
+ namespace google::protobuf {
13
+ class ServiceDescriptor;
14
+ class MethodDescriptor;
15
+ class Message;
16
+ } // namespace google::protobuf
17
+
18
+ namespace mo::rpc {
19
+
20
+ // Abstract base class for all generated RPC services.
21
+ //
22
+ // This class defines the interface that all generated services must implement.
23
+ // It allows for dynamic invocation of service methods through a generic
24
+ // interface.
25
+ class Service {
26
+ public:
27
+ inline Service() {}
28
+
29
+ Service(const Service&) = delete;
30
+ Service& operator=(const Service&) = delete;
31
+ virtual ~Service() = default;
32
+
33
+ // Returns the descriptor for this service.
34
+ //
35
+ // The ServiceDescriptor contains metadata about the service, including its
36
+ // name, the methods it implements, and their signatures. This is used for
37
+ // reflection and dynamic invocation.
38
+ //
39
+ // Returns:
40
+ // A pointer to the ServiceDescriptor for this service. The returned pointer
41
+ // is owned by the service and remains valid for the lifetime of the
42
+ // service.
43
+ virtual const ::google::protobuf::ServiceDescriptor* GetDescriptor() = 0;
44
+
45
+ // Invokes an RPC method on this service.
46
+ //
47
+ // This is the core method for executing RPC calls. The implementation should:
48
+ // 1. Validate that the method belongs to this service
49
+ // 2. Downcast the generic Message to the specific request type
50
+ // 3. Execute the method logic
51
+ // 4. Complete the callback with the response or reject it with an error
52
+ //
53
+ // Parameters:
54
+ // method - Descriptor of the method to invoke. Must be a method of this
55
+ // service (obtained via GetDescriptor()).
56
+ // request - The request message. Must be of the type expected by the method
57
+ // (as specified by GetRequestPrototype()).
58
+ // on_complete - Handler to invoke on successful completion with the
59
+ // serialized response data.
60
+ // on_reject - Handler to invoke on failure with an error message.
61
+ virtual void CallMethod(const ::google::protobuf::MethodDescriptor* method,
62
+ const ::google::protobuf::Message& request,
63
+ uint64_t request_id,
64
+ OnCompleteHandler on_complete,
65
+ OnRejectHandler on_reject) = 0;
66
+
67
+ // Returns the prototype (default instance) for request messages of a method.
68
+ //
69
+ // This is used for message deserialization and reflection. The returned
70
+ // prototype can be cloned to create new request messages of the correct type.
71
+ //
72
+ // Parameters:
73
+ // method - The method descriptor. Must be a method of this service.
74
+ //
75
+ // Returns:
76
+ // A const reference to the prototype request message for this method.
77
+ // The returned reference remains valid for the lifetime of the service.
78
+ virtual const ::google::protobuf::Message& GetRequestPrototype(
79
+ const ::google::protobuf::MethodDescriptor* method) const = 0;
80
+
81
+ // Returns the prototype (default instance) for response messages of a method.
82
+ //
83
+ // This is used for message deserialization and reflection. The returned
84
+ // prototype can be cloned to create new response messages of the correct type.
85
+ //
86
+ // Parameters:
87
+ // method - The method descriptor. Must be a method of this service.
88
+ //
89
+ // Returns:
90
+ // A const reference to the prototype response message for this method.
91
+ // The returned reference remains valid for the lifetime of the service.
92
+ virtual const ::google::protobuf::Message& GetResponsePrototype(
93
+ const ::google::protobuf::MethodDescriptor* method) const = 0;
94
+ };
95
+
96
+ } // namespace mo::rpc
97
+
98
+ #endif // MO_RPC_SERVICE_H_
@@ -0,0 +1,14 @@
1
+ // Copyright (c) 2000-2026 TeamDev. All rights reserved.
2
+ // TeamDev PROPRIETARY and CONFIDENTIAL.
3
+ // Use is subject to license terms.
4
+
5
+ #ifndef MOBROWSER_EXPORT_H
6
+ #define MOBROWSER_EXPORT_H
7
+
8
+ #if defined(OS_WIN)
9
+ #define MOBROWSER_EXPORT __declspec(dllexport)
10
+ #else
11
+ #define MOBROWSER_EXPORT __attribute__((visibility("default")))
12
+ #endif
13
+
14
+ #endif // MOBROWSER_EXPORT_H
@@ -0,0 +1,20 @@
1
+ // Copyright (c) 2000-2026 TeamDev. All rights reserved.
2
+ // TeamDev PROPRIETARY and CONFIDENTIAL.
3
+ // Use is subject to license terms.
4
+
5
+ #include "../include/rpc.h"
6
+ #include "transport.h"
7
+
8
+ void launch();
9
+
10
+ extern "C" {
11
+ MOBROWSER_EXPORT void AppMain() {
12
+ launch();
13
+ }
14
+ }
15
+
16
+ namespace mo::rpc {
17
+ void RegisterService(Service* service) {
18
+ Transport::GetInstance()->RegisterService(service);
19
+ }
20
+ } // namespace mo::rpc
@@ -0,0 +1,66 @@
1
+ // Copyright (c) 2000-2026 TeamDev. All rights reserved.
2
+ // TeamDev PROPRIETARY and CONFIDENTIAL.
3
+ // Use is subject to license terms.
4
+
5
+ #include "transport.h"
6
+
7
+ #include <shared_mutex>
8
+ #include <vector>
9
+
10
+ #include "../include/service.h"
11
+
12
+ #include "google/protobuf/arena.h"
13
+ #include "google/protobuf/descriptor.h"
14
+ #include "google/protobuf/message.h"
15
+
16
+ void invoke(uint64_t id,
17
+ const char* service_name,
18
+ const char* method_name,
19
+ const char* data,
20
+ size_t data_size,
21
+ reply_callback reply,
22
+ reject_callback reject) {
23
+ mo::rpc::Transport::GetInstance()->Invoke(id, service_name, method_name, data, data_size, reply, reject);
24
+ }
25
+
26
+ namespace mo::rpc {
27
+ Transport::Transport() = default;
28
+ Transport::~Transport() = default;
29
+
30
+ Transport* Transport::GetInstance() {
31
+ static auto* instance = new Transport();
32
+ return instance;
33
+ }
34
+
35
+ void Transport::RegisterService(Service* service) {
36
+ std::unique_lock lock(mutex_);
37
+ services_.emplace(service->GetDescriptor()->full_name(), service);
38
+ }
39
+
40
+ void Transport::Invoke(uint64_t id,
41
+ const char* service_name,
42
+ const char* method_name,
43
+ const char* data,
44
+ size_t data_size,
45
+ reply_callback reply,
46
+ reject_callback reject) {
47
+ Service* service;
48
+ {
49
+ std::shared_lock lock(mutex_);
50
+ auto it = services_.find(service_name);
51
+ if (it == services_.end()) {
52
+ reject(id, "Service not found.");
53
+ return;
54
+ }
55
+ service = it->second;
56
+ }
57
+ auto method = service->GetDescriptor()->FindMethodByName(method_name);
58
+ if (!method) {
59
+ reject(id, "Method not found.");
60
+ return;
61
+ }
62
+ auto* request = service->GetRequestPrototype(method).New();
63
+ request->ParseFromArray(data, data_size);
64
+ service->CallMethod(method, *request, id, reply, reject);
65
+ }
66
+ } // namespace mo::rpc
@@ -0,0 +1,52 @@
1
+ // Copyright (c) 2000-2026 TeamDev. All rights reserved.
2
+ // TeamDev PROPRIETARY and CONFIDENTIAL.
3
+ // Use is subject to license terms.
4
+
5
+ #ifndef MOBROWSER_TRANSPORT_H
6
+ #define MOBROWSER_TRANSPORT_H
7
+
8
+ #include <shared_mutex>
9
+ #include <string>
10
+ #include <unordered_map>
11
+ #include "export.h"
12
+
13
+ extern "C" {
14
+ typedef void (*reply_callback)(uint64_t id, const char* data, size_t data_size);
15
+ typedef void (*reject_callback)(uint64_t id, const char* error);
16
+
17
+ MOBROWSER_EXPORT void invoke(uint64_t id,
18
+ const char* service_name,
19
+ const char* method_name,
20
+ const char* data,
21
+ size_t data_size,
22
+ reply_callback reply,
23
+ reject_callback reject);
24
+ }
25
+
26
+ namespace mo::rpc {
27
+ class Service;
28
+
29
+ class Transport {
30
+ public:
31
+ Transport();
32
+ ~Transport();
33
+
34
+ static Transport* GetInstance();
35
+
36
+ void RegisterService(Service* service);
37
+
38
+ void Invoke(uint64_t id,
39
+ const char* service_name,
40
+ const char* method_name,
41
+ const char* data,
42
+ size_t data_size,
43
+ reply_callback reply,
44
+ reject_callback reject);
45
+
46
+ private:
47
+ std::shared_mutex mutex_;
48
+ std::unordered_map<std::string, Service*> services_;
49
+ };
50
+ } // namespace mo::rpc
51
+
52
+ #endif // MOBROWSER_TRANSPORT_H
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@mobrowser/native",
3
+ "version": "2.0.0",
4
+ "description": "Configuration files for MōBrowser native integration",
5
+ "main": "cmake/MoBrowser.cmake",
6
+ "files": [
7
+ "cmake/MoBrowser.cmake",
8
+ "cmake/Platform.cmake",
9
+ "cmake/Protobuf.cmake",
10
+ "include",
11
+ "internal"
12
+ ],
13
+ "keywords": [
14
+ "mobrowser",
15
+ "native"
16
+ ],
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/TeamDev-IP/MoBrowser.git"
20
+ },
21
+ "author": "TeamDev",
22
+ "license": "MŌBROWSER",
23
+ "bugs": {
24
+ "url": "https://github.com/TeamDev-IP/MoBrowser/issues"
25
+ },
26
+ "homepage": "https://teamdev.com/mobrowser"
27
+ }