Skip to content

Conversation

@minggangw
Copy link
Member

@minggangw minggangw commented Mar 27, 2025

The day when rclnodejs was initialized, nan was the only library designed to simplify the development of native addons, providing a consistent interface for interacting with the V8 JavaScript engine and Node.js APIs across different Node.js versions.

N-API was introduced in Node.js v8.0.0 as an experimental feature to provide a stable Node API for native modules, it's officially supported by Node and allows developing native addons that are independent of the underlying JavaScript engine, and ensures Application Binary Interface (ABI) stability across different Node.js versions and compiler levels. so it is recommended to migrate to N-API for existing projects.

This patch leverages node-addon-api based on Node-API, which provides a C++ object model and exception handling semantics with low overhead, to rewrite the existing C++ bindings, including:

  1. Add node-addon-api into dependencies.
  2. Replace the Nan headers with node-addon-api headers.
  3. Replace nan APIs with node-addon-api equivalents.
  4. Use Napi::Env for environment handling.
  5. Replace Nan::ObjectWrap with Napi::ObjectWrap.
  6. Replace Nan::Persistent with Napi::FunctionReference.
  7. Update error handling and buffer management.

After this patch, we will remove the explicit usage of classes from v8::.

Fix: #1036

@coveralls
Copy link

coveralls commented Mar 27, 2025

Coverage Status

coverage: 85.019% (-0.3%) from 85.325%
when pulling 7db7fa4 on minggangw:fix-1036
into 3d3eb17 on RobotWebTools:develop.

@minggangw minggangw requested a review from Copilot March 28, 2025 07:40
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR updates the logging functionality to improve the extraction of caller information from error stacks and revises the build configuration for native modules.

  • Updated the stack trace parsing logic in lib/logging.js to support both named and anonymous functions.
  • Changed the conversion of line number to an integer and updated the include directive in binding.gyp to use node-addon-api.

Reviewed Changes

Copilot reviewed 4 out of 19 changed files in this pull request and generated 1 comment.

File Description
lib/logging.js Refactored caller info extraction and adjusted line number parsing.
binding.gyp Updated the include_dirs command to reference node-addon-api.
Files not reviewed (15)
  • package.json: Language not supported
  • src/addon.cpp: Language not supported
  • src/executor.cpp: Language not supported
  • src/executor.hpp: Language not supported
  • src/handle_manager.cpp: Language not supported
  • src/handle_manager.hpp: Language not supported
  • src/macros.hpp: Language not supported
  • src/rcl_action_bindings.hpp: Language not supported
  • src/rcl_bindings.hpp: Language not supported
  • src/rcl_handle.cpp: Language not supported
  • src/rcl_handle.hpp: Language not supported
  • src/rcl_lifecycle_bindings.cpp: Language not supported
  • src/rcl_lifecycle_bindings.hpp: Language not supported
  • src/shadow_node.cpp: Language not supported
  • src/shadow_node.hpp: Language not supported
Comments suppressed due to low confidence (1)

binding.gyp:33

  • Ensure that node-addon-api is properly added as a dependency and that the command substitution syntax works across all intended build environments.
<!@(node -p "require('node-addon-api').include")

lib/logging.js Outdated
message,
caller.functionName,
caller.lineNumber,
parseInt(caller.lineNumber),
Copy link

Copilot AI Mar 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider specifying the radix when using parseInt, e.g., parseInt(caller.lineNumber, 10), to avoid unexpected behavior.

Suggested change
parseInt(caller.lineNumber),
parseInt(caller.lineNumber, 10),

Copilot uses AI. Check for mistakes.
@minggangw minggangw changed the title NOT TO MERGE Migrate nan to node-addon-api for implementing the C++ addon Mar 28, 2025
@minggangw minggangw requested a review from Copilot April 2, 2025 06:50
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the addon support from using nan to node-addon-api and updates logging functionality to improve caller information extraction.

  • Replaces nan include with node-addon-api in binding.gyp.
  • Updates the logging module to initialize caller details with default values and uses regex-based parsing for enhanced stack frame extraction.
  • Converts the logged line number from a string to an integer.

Reviewed Changes

Copilot reviewed 4 out of 20 changed files in this pull request and generated 1 comment.

File Description
lib/logging.js Enhances caller data extraction by updating stack parsing and type conversion
binding.gyp Modifies include path to use node-addon-api instead of nan
Files not reviewed (16)
  • package.json: Language not supported
  • src/addon.cpp: Language not supported
  • src/executor.cpp: Language not supported
  • src/executor.hpp: Language not supported
  • src/handle_manager.cpp: Language not supported
  • src/handle_manager.hpp: Language not supported
  • src/macros.hpp: Language not supported
  • src/rcl_action_bindings.hpp: Language not supported
  • src/rcl_bindings.hpp: Language not supported
  • src/rcl_handle.cpp: Language not supported
  • src/rcl_handle.hpp: Language not supported
  • src/rcl_lifecycle_bindings.cpp: Language not supported
  • src/rcl_lifecycle_bindings.hpp: Language not supported
  • src/rcl_utilities.hpp: Language not supported
  • src/shadow_node.cpp: Language not supported
  • src/shadow_node.hpp: Language not supported

message,
caller.functionName,
caller.lineNumber,
parseInt(caller.lineNumber, 10),
Copy link

Copilot AI Apr 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If caller.lineNumber remains the default 'unknown', parseInt will return NaN. Consider implementing a fallback for non-numeric values to prevent propagation of NaN.

Suggested change
parseInt(caller.lineNumber, 10),
isNaN(parseInt(caller.lineNumber, 10)) ? -1 : parseInt(caller.lineNumber, 10),

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 19 out of 20 changed files in this pull request and generated no comments.

Files not reviewed (1)
  • package.json: Language not supported
Comments suppressed due to low confidence (2)

src/rcl_utilities.hpp:42

  • Storing the Napi::Env in a thread-local variable may lead to unexpected behavior if it is accessed outside the initializing thread. Ensure that rclnodejs::StoreEnv is reliably called in all entry points before any usage of GetEnv().
static thread_local Napi::Env env = nullptr;

src/macros.hpp:26

  • The CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE macro relies on GetEnv() to provide a valid Napi::Env. Ensure that rclnodejs::StoreEnv is invoked before using this macro to avoid null-pointer issues.
Napi::Error::New(rclnodejs::GetEnv(), message).ThrowAsJavaScriptException();

@minggangw minggangw requested a review from Copilot April 15, 2025 02:12
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 21 out of 22 changed files in this pull request and generated no comments.

Files not reviewed (1)
  • package.json: Language not supported
Comments suppressed due to low confidence (2)

src/rcl_utilities.h:40

  • Storing a global reference to Napi::Env may lead to issues if used outside its valid lifecycle. Consider reviewing the design to ensure the environment remains valid when accessed from different threads or later in the execution.
inline Napi::Env& GetEnv() { static thread_local Napi::Env env = nullptr; return env; }

lib/logging.js:57

  • The usage of 'path.basename' suggests that the 'path' module should be imported, but no import statement is present in the diff. Please ensure the module is imported (e.g., const path = require('path');).
this._info.fileName = path.basename(match[2]);

@minggangw minggangw requested a review from Copilot April 21, 2025 06:28
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the C++ addon from using the deprecated NAN API to Node-API via node-addon-api, ensuring ABI stability and modern error handling. Key changes include updating include directives and conversion of NAN constructs (e.g. ObjectWrap, Persistent) to their Napi equivalents; revising error handling patterns and improving include guard naming consistency.

Reviewed Changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/shadow_node.{h,cpp} Updated class inheritance, method signatures, and error handling from NAN to Napi
src/rcl_utilities.{h,cpp} Switched include guards and added API for environment storage
src/rcl_lifecycle_bindings.{h,cpp} Migrated lifecycle binding functions from NAN to Napi and updated header names
src/rcl_handle.{h,cpp} Replaced NAN ObjectWrap and Persistent usage with Napi::ObjectWrap and FunctionReference
src/executor.{h,cpp} Updated constructor parameters and error handling routines using Napi
src/addon.cpp Shifted from NAN to node-addon-api in module initialization and binding functions
Other files (macros, handle_manager, binding.gyp, etc.) Converted syntax and build configurations to work with Node-API rather than NAN
Files not reviewed (1)
  • package.json: Language not supported
Comments suppressed due to low confidence (1)

src/rcl_lifecycle_bindings.cpp:104

  • The lambda capture includes 'node_options', which is not defined; it appears that 'options' defined earlier was intended instead.
auto js_obj = RclHandle::NewInstance(env, state_machine, node_handle, [node, node_options](void* ptr) {

@minggangw minggangw merged commit c21bdcd into RobotWebTools:develop Apr 21, 2025
5 of 12 checks passed
minggangw added a commit that referenced this pull request Apr 21, 2025
The day when `rclnodejs` was initialized, [nan](https://github.com/nodejs/nan) was the only library designed to simplify the development of native addons, providing a consistent interface for interacting with the V8 JavaScript engine and Node.js APIs across different Node.js versions.

[N-API](https://nodejs.org/api/n-api.html#node-api) was introduced in Node.js v8.0.0 as an experimental feature to provide a stable Node API for native modules, it's officially supported by Node and allows developing native addons that are independent of the underlying JavaScript engine, and ensures Application Binary Interface (ABI) stability across different Node.js versions and compiler levels. so it is recommended to migrate to N-API for existing projects.

This patch leverages [node-addon-api](https://github.com/nodejs/node-addon-api) based on [Node-API](https://nodejs.org/api/n-api.html), which provides a C++ object model and exception handling semantics with low overhead, to rewrite the existing C++ bindings, including:

1. Add `node-addon-api` into dependencies.
2. Replace the `Nan` headers with `node-addon-api` headers.
3. Replace `nan` APIs with `node-addon-api` equivalents.
4. Use `Napi::Env` for environment handling.
5. Replace `Nan::ObjectWrap` with `Napi::ObjectWrap`.
6. Replace `Nan::Persistent` with `Napi::FunctionReference`.
7. Update error handling and buffer management.

After this patch, we will remove the explicit usage of classes from `v8::`.
 
Fix: #1036
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider to migrate to Node-API

2 participants