rclnodejs 0.33.0 → 1.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.
Files changed (66) hide show
  1. package/README.md +3 -3
  2. package/binding.gyp +17 -2
  3. package/lib/client.js +2 -3
  4. package/lib/context.js +8 -0
  5. package/lib/logging.js +26 -9
  6. package/lib/node.js +53 -0
  7. package/lib/publisher.js +8 -0
  8. package/lib/service.js +9 -2
  9. package/lib/subscription.js +8 -0
  10. package/lib/timer.js +32 -0
  11. package/package.json +4 -4
  12. package/scripts/config.js +1 -0
  13. package/scripts/npmjs-readme.md +3 -3
  14. package/src/addon.cpp +54 -53
  15. package/src/executor.cpp +19 -10
  16. package/src/{executor.hpp → executor.h} +7 -5
  17. package/src/handle_manager.cpp +30 -56
  18. package/src/{handle_manager.hpp → handle_manager.h} +8 -7
  19. package/src/{macros.hpp → macros.h} +7 -5
  20. package/src/rcl_action_client_bindings.cpp +231 -0
  21. package/src/{rcl_action_bindings.hpp → rcl_action_client_bindings.h} +6 -11
  22. package/src/rcl_action_goal_bindings.cpp +117 -0
  23. package/src/rcl_action_goal_bindings.h +26 -0
  24. package/src/rcl_action_server_bindings.cpp +470 -0
  25. package/src/rcl_action_server_bindings.h +26 -0
  26. package/src/rcl_bindings.cpp +42 -2010
  27. package/src/{rcl_bindings.hpp → rcl_bindings.h} +5 -25
  28. package/src/rcl_client_bindings.cpp +183 -0
  29. package/src/rcl_client_bindings.h +26 -0
  30. package/src/rcl_context_bindings.cpp +156 -0
  31. package/src/rcl_context_bindings.h +26 -0
  32. package/src/rcl_graph_bindings.cpp +280 -0
  33. package/src/rcl_graph_bindings.h +26 -0
  34. package/src/rcl_guard_condition_bindings.cpp +75 -0
  35. package/src/rcl_guard_condition_bindings.h +26 -0
  36. package/src/rcl_handle.cpp +41 -57
  37. package/src/{rcl_handle.hpp → rcl_handle.h} +18 -17
  38. package/src/rcl_lifecycle_bindings.cpp +135 -114
  39. package/src/{rcl_lifecycle_bindings.hpp → rcl_lifecycle_bindings.h} +5 -7
  40. package/src/rcl_logging_bindings.cpp +96 -0
  41. package/src/rcl_logging_bindings.h +26 -0
  42. package/src/rcl_names_bindings.cpp +255 -0
  43. package/src/rcl_names_bindings.h +26 -0
  44. package/src/rcl_node_bindings.cpp +447 -0
  45. package/src/rcl_node_bindings.h +26 -0
  46. package/src/rcl_publisher_bindings.cpp +141 -0
  47. package/src/rcl_publisher_bindings.h +26 -0
  48. package/src/rcl_service_bindings.cpp +185 -0
  49. package/src/rcl_service_bindings.h +26 -0
  50. package/src/rcl_subscription_bindings.cpp +335 -0
  51. package/src/rcl_subscription_bindings.h +26 -0
  52. package/src/rcl_time_point_bindings.cpp +194 -0
  53. package/src/rcl_time_point_bindings.h +26 -0
  54. package/src/rcl_timer_bindings.cpp +237 -0
  55. package/src/rcl_timer_bindings.h +26 -0
  56. package/src/rcl_utilities.cpp +166 -1
  57. package/src/{rcl_utilities.hpp → rcl_utilities.h} +21 -3
  58. package/src/shadow_node.cpp +56 -75
  59. package/src/{shadow_node.hpp → shadow_node.h} +18 -17
  60. package/types/context.d.ts +6 -0
  61. package/types/node.d.ts +37 -0
  62. package/types/publisher.d.ts +6 -0
  63. package/types/service.d.ts +6 -0
  64. package/types/subscription.d.ts +6 -0
  65. package/types/timer.d.ts +18 -0
  66. package/src/rcl_action_bindings.cpp +0 -826
@@ -12,35 +12,15 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
 
15
- #ifndef SRC_RCL_BINDINGS_HPP_
16
- #define SRC_RCL_BINDINGS_HPP_
15
+ #ifndef SRC_RCL_BINDINGS_H_
16
+ #define SRC_RCL_BINDINGS_H_
17
17
 
18
- #include <nan.h>
19
- #include <rcl/graph.h>
20
- #include <rcl/rcl.h>
21
-
22
- #include <memory>
23
- #include <string>
24
- #include <vector>
18
+ #include <napi.h>
25
19
 
26
20
  namespace rclnodejs {
27
21
 
28
- typedef void (*JsCFuntcion)(const Nan::FunctionCallbackInfo<v8::Value>&);
29
-
30
- typedef struct {
31
- const char* name;
32
- JsCFuntcion function;
33
- } BindingMethod;
34
-
35
- extern rcl_guard_condition_t* g_sigint_gc;
36
-
37
- void ExtractNamesAndTypes(rcl_names_and_types_t names_and_types,
38
- v8::Local<v8::Array>* result_list);
39
-
40
- std::unique_ptr<rmw_qos_profile_t> GetQoSProfile(v8::Local<v8::Value> qos);
41
-
42
- extern std::vector<BindingMethod> binding_methods;
22
+ Napi::Object InitBindings(Napi::Env env, Napi::Object exports);
43
23
 
44
24
  } // namespace rclnodejs
45
25
 
46
- #endif // SRC_RCL_BINDINGS_HPP_
26
+ #endif // SRC_RCL_BINDINGS_H_
@@ -0,0 +1,183 @@
1
+ // Copyright (c) 2025, The Robot Web Tools Contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "rcl_client_bindings.h"
16
+
17
+ #include <rcl/error_handling.h>
18
+ #include <rcl/rcl.h>
19
+
20
+ #include <string>
21
+
22
+ #include "macros.h"
23
+ #include "rcl_handle.h"
24
+ #include "rcl_utilities.h"
25
+
26
+ namespace rclnodejs {
27
+
28
+ Napi::Value CreateClient(const Napi::CallbackInfo& info) {
29
+ Napi::Env env = info.Env();
30
+
31
+ RclHandle* node_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
32
+ rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
33
+
34
+ std::string service_name = info[1].As<Napi::String>().Utf8Value();
35
+ std::string interface_name = info[2].As<Napi::String>().Utf8Value();
36
+ std::string package_name = info[3].As<Napi::String>().Utf8Value();
37
+
38
+ const rosidl_service_type_support_t* ts =
39
+ GetServiceTypeSupport(package_name, interface_name);
40
+
41
+ if (ts) {
42
+ rcl_client_t* client =
43
+ reinterpret_cast<rcl_client_t*>(malloc(sizeof(rcl_client_t)));
44
+ *client = rcl_get_zero_initialized_client();
45
+ rcl_client_options_t client_ops = rcl_client_get_default_options();
46
+ auto qos_profile = GetQoSProfile(info[4]);
47
+
48
+ if (qos_profile) {
49
+ client_ops.qos = *qos_profile;
50
+ }
51
+
52
+ THROW_ERROR_IF_NOT_EQUAL(
53
+ rcl_client_init(client, node, ts, service_name.c_str(), &client_ops),
54
+ RCL_RET_OK, rcl_get_error_string().str);
55
+
56
+ auto js_obj =
57
+ RclHandle::NewInstance(env, client, node_handle, [node](void* ptr) {
58
+ rcl_client_t* client = reinterpret_cast<rcl_client_t*>(ptr);
59
+ rcl_ret_t ret = rcl_client_fini(client, node);
60
+ free(ptr);
61
+ THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, ret, rcl_get_error_string().str);
62
+ });
63
+
64
+ return js_obj;
65
+ } else {
66
+ Napi::Error::New(env, GetErrorMessageAndClear())
67
+ .ThrowAsJavaScriptException();
68
+ return env.Undefined();
69
+ }
70
+ }
71
+
72
+ Napi::Value SendRequest(const Napi::CallbackInfo& info) {
73
+ Napi::Env env = info.Env();
74
+
75
+ rcl_client_t* client = reinterpret_cast<rcl_client_t*>(
76
+ RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
77
+ char* buffer = info[1].As<Napi::Buffer<char>>().Data();
78
+ int64_t sequence_number;
79
+ THROW_ERROR_IF_NOT_EQUAL(rcl_send_request(client, buffer, &sequence_number),
80
+ RCL_RET_OK, rcl_get_error_string().str);
81
+
82
+ return Napi::Number::New(env, static_cast<uint32_t>(sequence_number));
83
+ }
84
+
85
+ Napi::Value RclTakeResponse(const Napi::CallbackInfo& info) {
86
+ Napi::Env env = info.Env();
87
+
88
+ rcl_client_t* client = reinterpret_cast<rcl_client_t*>(
89
+ RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
90
+
91
+ rmw_service_info_t header;
92
+
93
+ void* taken_response = info[1].As<Napi::Buffer<char>>().Data();
94
+ rcl_ret_t ret = rcl_take_response_with_info(client, &header, taken_response);
95
+ int64_t sequence_number = header.request_id.sequence_number;
96
+
97
+ if (ret == RCL_RET_OK) {
98
+ return Napi::Number::New(env, static_cast<uint32_t>(sequence_number));
99
+ }
100
+
101
+ rcl_reset_error();
102
+ return env.Undefined();
103
+ }
104
+
105
+ Napi::Value GetClientServiceName(const Napi::CallbackInfo& info) {
106
+ Napi::Env env = info.Env();
107
+
108
+ rcl_client_t* client = reinterpret_cast<rcl_client_t*>(
109
+ RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
110
+
111
+ const char* service_name = rcl_client_get_service_name(client);
112
+ return Napi::String::New(env, service_name);
113
+ }
114
+
115
+ Napi::Value ServiceServerIsAvailable(const Napi::CallbackInfo& info) {
116
+ Napi::Env env = info.Env();
117
+
118
+ RclHandle* node_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
119
+ rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
120
+ RclHandle* client_handle = RclHandle::Unwrap(info[1].As<Napi::Object>());
121
+ rcl_client_t* client = reinterpret_cast<rcl_client_t*>(client_handle->ptr());
122
+
123
+ bool is_available;
124
+ THROW_ERROR_IF_NOT_EQUAL(
125
+ RCL_RET_OK, rcl_service_server_is_available(node, client, &is_available),
126
+ "Failed to get service state.");
127
+
128
+ return Napi::Boolean::New(env, is_available);
129
+ }
130
+
131
+ #if ROS_VERSION > 2205 // 2205 == Humble
132
+ Napi::Value ConfigureClientIntrospection(const Napi::CallbackInfo& info) {
133
+ Napi::Env env = info.Env();
134
+
135
+ RclHandle* client_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
136
+ rcl_client_t* client = reinterpret_cast<rcl_client_t*>(client_handle->ptr());
137
+ RclHandle* node_handle = RclHandle::Unwrap(info[1].As<Napi::Object>());
138
+ rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
139
+ rcl_clock_t* clock = reinterpret_cast<rcl_clock_t*>(
140
+ RclHandle::Unwrap(info[2].As<Napi::Object>())->ptr());
141
+
142
+ std::string interface_name = info[3].As<Napi::String>().Utf8Value();
143
+ std::string package_name = info[4].As<Napi::String>().Utf8Value();
144
+ const rosidl_service_type_support_t* ts =
145
+ GetServiceTypeSupport(package_name, interface_name);
146
+
147
+ if (ts) {
148
+ rcl_publisher_options_t publisher_ops = rcl_publisher_get_default_options();
149
+ auto qos_profile = GetQoSProfile(info[5]);
150
+ if (qos_profile) {
151
+ publisher_ops.qos = *qos_profile;
152
+ }
153
+ rcl_service_introspection_state_t state =
154
+ static_cast<rcl_service_introspection_state_t>(
155
+ info[6].As<Napi::Number>().Uint32Value());
156
+
157
+ THROW_ERROR_IF_NOT_EQUAL(rcl_client_configure_service_introspection(
158
+ client, node, clock, ts, publisher_ops, state),
159
+ RCL_RET_OK, rcl_get_error_string().str);
160
+ } else {
161
+ Napi::Error::New(env, GetErrorMessageAndClear())
162
+ .ThrowAsJavaScriptException();
163
+ }
164
+ return env.Undefined();
165
+ }
166
+ #endif
167
+
168
+ Napi::Object InitClientBindings(Napi::Env env, Napi::Object exports) {
169
+ exports.Set("createClient", Napi::Function::New(env, CreateClient));
170
+ exports.Set("sendRequest", Napi::Function::New(env, SendRequest));
171
+ exports.Set("rclTakeResponse", Napi::Function::New(env, RclTakeResponse));
172
+ exports.Set("getClientServiceName",
173
+ Napi::Function::New(env, GetClientServiceName));
174
+ exports.Set("serviceServerIsAvailable",
175
+ Napi::Function::New(env, ServiceServerIsAvailable));
176
+ #if ROS_VERSION > 2205 // 2205 == Humble
177
+ exports.Set("configureClientIntrospection",
178
+ Napi::Function::New(env, ConfigureClientIntrospection));
179
+ #endif
180
+ return exports;
181
+ }
182
+
183
+ } // namespace rclnodejs
@@ -0,0 +1,26 @@
1
+ // Copyright (c) 2025, The Robot Web Tools Contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef SRC_RCL_CLIENT_BINDINGS_H_
16
+ #define SRC_RCL_CLIENT_BINDINGS_H_
17
+
18
+ #include <napi.h>
19
+
20
+ namespace rclnodejs {
21
+
22
+ Napi::Object InitClientBindings(Napi::Env env, Napi::Object exports);
23
+
24
+ }
25
+
26
+ #endif // SRC_RCL_CLIENT_BINDINGS_H_
@@ -0,0 +1,156 @@
1
+ // Copyright (c) 2025, The Robot Web Tools Contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ #include "rcl_context_bindings.h"
15
+
16
+ #include <rcl/error_handling.h>
17
+ #include <rcl/logging.h>
18
+ #include <rcl/rcl.h>
19
+
20
+ #include <cstdio>
21
+ #include <string>
22
+
23
+ #include "macros.h"
24
+ #include "rcl_handle.h"
25
+ #include "rcl_utilities.h"
26
+
27
+ namespace rclnodejs {
28
+
29
+ Napi::Value Init(const Napi::CallbackInfo& info) {
30
+ Napi::Env env = info.Env();
31
+
32
+ rcl_allocator_t allocator = rcl_get_default_allocator();
33
+ rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
34
+ THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
35
+ rcl_init_options_init(&init_options, allocator),
36
+ rcl_get_error_string().str);
37
+
38
+ // Preprocess Context
39
+ RclHandle* context_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
40
+ rcl_context_t* context =
41
+ reinterpret_cast<rcl_context_t*>(context_handle->ptr());
42
+
43
+ // Preprocess argc & argv
44
+ Napi::Array jsArgv = info[1].As<Napi::Array>();
45
+ int argc = jsArgv.Length();
46
+ char** argv = nullptr;
47
+
48
+ if (argc > 0) {
49
+ argv = reinterpret_cast<char**>(malloc(argc * sizeof(char*)));
50
+ for (int i = 0; i < argc; i++) {
51
+ std::string arg = jsArgv.Get(i).As<Napi::String>().Utf8Value();
52
+ int len = arg.length() + 1;
53
+ argv[i] = reinterpret_cast<char*>(malloc(len * sizeof(char)));
54
+ snprintf(argv[i], len, "%s", arg.c_str());
55
+ }
56
+ }
57
+
58
+ THROW_ERROR_IF_NOT_EQUAL(
59
+ RCL_RET_OK,
60
+ rcl_init(argc, argc > 0 ? argv : nullptr, &init_options, context),
61
+ rcl_get_error_string().str);
62
+
63
+ THROW_ERROR_IF_NOT_EQUAL(
64
+ RCL_RET_OK, rcl_logging_configure(&context->global_arguments, &allocator),
65
+ rcl_get_error_string().str);
66
+
67
+ for (int i = 0; i < argc; i++) {
68
+ free(argv[i]);
69
+ }
70
+ free(argv);
71
+
72
+ return env.Undefined();
73
+ }
74
+
75
+ Napi::Value Shutdown(const Napi::CallbackInfo& info) {
76
+ Napi::Env env = info.Env();
77
+
78
+ RclHandle* context_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
79
+ rcl_context_t* context =
80
+ reinterpret_cast<rcl_context_t*>(context_handle->ptr());
81
+ THROW_ERROR_IF_NOT_EQUAL(rcl_shutdown(context), RCL_RET_OK,
82
+ rcl_get_error_string().str);
83
+ THROW_ERROR_IF_NOT_EQUAL(rcl_logging_fini(), RCL_RET_OK,
84
+ rcl_get_error_string().str);
85
+
86
+ return env.Undefined();
87
+ }
88
+
89
+ int DestroyContext(Napi::Env env, rcl_context_t* context) {
90
+ rcl_ret_t ret = RCL_RET_OK;
91
+ if (context->impl) {
92
+ if (rcl_context_is_valid(context)) {
93
+ if (RCL_RET_OK != rcl_shutdown(context)) {
94
+ Napi::Error::New(env, rcl_get_error_string().str)
95
+ .ThrowAsJavaScriptException();
96
+ }
97
+ ret = rcl_context_fini(context);
98
+ }
99
+ }
100
+ return ret;
101
+ }
102
+
103
+ Napi::Value CreateContext(const Napi::CallbackInfo& info) {
104
+ Napi::Env env = info.Env();
105
+
106
+ rcl_context_t* context =
107
+ reinterpret_cast<rcl_context_t*>(malloc(sizeof(rcl_context_t)));
108
+ *context = rcl_get_zero_initialized_context();
109
+ auto js_obj =
110
+ RclHandle::NewInstance(env, context, nullptr, [&env](void* ptr) {
111
+ rcl_context_t* context = reinterpret_cast<rcl_context_t*>(ptr);
112
+ rcl_ret_t ret = DestroyContext(env, context);
113
+ free(ptr);
114
+ THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, ret, rcl_get_error_string().str);
115
+ });
116
+
117
+ return js_obj;
118
+ }
119
+
120
+ Napi::Value IsContextValid(const Napi::CallbackInfo& info) {
121
+ Napi::Env env = info.Env();
122
+
123
+ RclHandle* context_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
124
+ rcl_context_t* context =
125
+ reinterpret_cast<rcl_context_t*>(context_handle->ptr());
126
+ bool is_valid = rcl_context_is_valid(context);
127
+ return Napi::Boolean::New(env, is_valid);
128
+ }
129
+
130
+ Napi::Value GetDomainId(const Napi::CallbackInfo& info) {
131
+ Napi::Env env = info.Env();
132
+
133
+ RclHandle* context_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
134
+ rcl_context_t* context =
135
+ reinterpret_cast<rcl_context_t*>(context_handle->ptr());
136
+ size_t domain_id;
137
+ rcl_ret_t ret = rcl_context_get_domain_id(context, &domain_id);
138
+ if (RCL_RET_OK != ret) {
139
+ Napi::Error::New(env, rcl_get_error_string().str)
140
+ .ThrowAsJavaScriptException();
141
+ return env.Undefined();
142
+ }
143
+
144
+ return Napi::Number::New(env, domain_id);
145
+ }
146
+
147
+ Napi::Object InitContextBindings(Napi::Env env, Napi::Object exports) {
148
+ exports.Set("init", Napi::Function::New(env, Init));
149
+ exports.Set("shutdown", Napi::Function::New(env, Shutdown));
150
+ exports.Set("createContext", Napi::Function::New(env, CreateContext));
151
+ exports.Set("isContextValid", Napi::Function::New(env, IsContextValid));
152
+ exports.Set("getDomainId", Napi::Function::New(env, GetDomainId));
153
+ return exports;
154
+ }
155
+
156
+ } // namespace rclnodejs
@@ -0,0 +1,26 @@
1
+ // Copyright (c) 2025, The Robot Web Tools Contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef SRC_RCL_CONTEXT_BINDINGS_H_
16
+ #define SRC_RCL_CONTEXT_BINDINGS_H_
17
+
18
+ #include <napi.h>
19
+
20
+ namespace rclnodejs {
21
+
22
+ Napi::Object InitContextBindings(Napi::Env env, Napi::Object exports);
23
+
24
+ } // namespace rclnodejs
25
+
26
+ #endif // SRC_RCL_CONTEXT_BINDINGS_H_