rclnodejs 1.0.0 → 1.2.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.
@@ -385,40 +385,71 @@ Napi::Value GetNodeNames(const Napi::CallbackInfo& info) {
385
385
 
386
386
  RclHandle* node_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
387
387
  rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
388
+ bool get_enclaves = info[1].As<Napi::Boolean>().Value();
388
389
  rcutils_string_array_t node_names =
389
390
  rcutils_get_zero_initialized_string_array();
390
391
  rcutils_string_array_t node_namespaces =
391
392
  rcutils_get_zero_initialized_string_array();
393
+ rcutils_string_array_t enclaves = rcutils_get_zero_initialized_string_array();
392
394
  rcl_allocator_t allocator = rcl_get_default_allocator();
393
395
 
394
- THROW_ERROR_IF_NOT_EQUAL(
395
- RCL_RET_OK,
396
- rcl_get_node_names(node, allocator, &node_names, &node_namespaces),
397
- "Failed to get_node_names.");
396
+ if (get_enclaves) {
397
+ THROW_ERROR_IF_NOT_EQUAL(
398
+ RCL_RET_OK,
399
+ rcl_get_node_names_with_enclaves(node, allocator, &node_names,
400
+ &node_namespaces, &enclaves),
401
+ "Failed to get_node_names.");
402
+ } else {
403
+ THROW_ERROR_IF_NOT_EQUAL(
404
+ RCL_RET_OK,
405
+ rcl_get_node_names(node, allocator, &node_names, &node_namespaces),
406
+ "Failed to get_node_names.");
407
+ }
398
408
 
399
409
  Napi::Array result_list = Napi::Array::New(env, node_names.size);
400
410
 
401
411
  for (size_t i = 0; i < node_names.size; ++i) {
402
412
  Napi::Object item = Napi::Object::New(env);
403
-
404
413
  item.Set("name", Napi::String::New(env, node_names.data[i]));
405
414
  item.Set("namespace", Napi::String::New(env, node_namespaces.data[i]));
406
-
415
+ if (get_enclaves) {
416
+ item.Set("enclave", Napi::String::New(env, enclaves.data[i]));
417
+ }
407
418
  result_list.Set(i, item);
408
419
  }
409
420
 
410
421
  rcutils_ret_t fini_names_ret = rcutils_string_array_fini(&node_names);
411
422
  rcutils_ret_t fini_namespaces_ret =
412
423
  rcutils_string_array_fini(&node_namespaces);
413
-
424
+ rcutils_ret_t fini_enclaves_ret = rcutils_string_array_fini(&enclaves);
414
425
  THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, fini_names_ret,
415
426
  "Failed to destroy node_names");
416
427
  THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, fini_namespaces_ret,
417
428
  "Failed to destroy node_namespaces");
418
-
429
+ THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, fini_enclaves_ret,
430
+ "Failed to fini enclaves string array");
419
431
  return result_list;
420
432
  }
421
433
 
434
+ Napi::Value GetFullyQualifiedName(const Napi::CallbackInfo& info) {
435
+ Napi::Env env = info.Env();
436
+
437
+ RclHandle* node_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
438
+ rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
439
+ const char* fully_qualified_node_name =
440
+ rcl_node_get_fully_qualified_name(node);
441
+ if (!fully_qualified_node_name) {
442
+ Napi::Error::New(env, "Fully qualified name not set")
443
+ .ThrowAsJavaScriptException();
444
+ return env.Undefined();
445
+ }
446
+ return Napi::String::New(env, fully_qualified_node_name);
447
+ }
448
+
449
+ Napi::Value GetRMWImplementationIdentifier(const Napi::CallbackInfo& info) {
450
+ return Napi::String::New(info.Env(), rmw_get_implementation_identifier());
451
+ }
452
+
422
453
  Napi::Object InitNodeBindings(Napi::Env env, Napi::Object exports) {
423
454
  exports.Set("getParameterOverrides",
424
455
  Napi::Function::New(env, GetParameterOverrides));
@@ -439,6 +470,10 @@ Napi::Object InitNodeBindings(Napi::Env env, Napi::Object exports) {
439
470
  exports.Set("countServices", Napi::Function::New(env, CountServices));
440
471
  #endif
441
472
  exports.Set("getNodeNames", Napi::Function::New(env, GetNodeNames));
473
+ exports.Set("getFullyQualifiedName",
474
+ Napi::Function::New(env, GetFullyQualifiedName));
475
+ exports.Set("getRMWImplementationIdentifier",
476
+ Napi::Function::New(env, GetRMWImplementationIdentifier));
442
477
  return exports;
443
478
  }
444
479
 
@@ -128,6 +128,24 @@ Napi::Value GetSubscriptionCount(const Napi::CallbackInfo& info) {
128
128
  return Napi::Number::New(env, count);
129
129
  }
130
130
 
131
+ Napi::Value WaitForAllAcked(const Napi::CallbackInfo& info) {
132
+ Napi::Env env = info.Env();
133
+ rcl_publisher_t* publisher = reinterpret_cast<rcl_publisher_t*>(
134
+ RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
135
+ bool lossless;
136
+ int64_t nanoseconds = info[1].As<Napi::BigInt>().Int64Value(&lossless);
137
+
138
+ rcl_ret_t ret = rcl_publisher_wait_for_all_acked(publisher, nanoseconds);
139
+ if (RCL_RET_OK == ret) {
140
+ return Napi::Boolean::New(env, true);
141
+ } else if (RCL_RET_TIMEOUT == ret) {
142
+ return Napi::Boolean::New(env, false);
143
+ }
144
+ Napi::Error::New(env, "Failed to wait for all acknowledgements")
145
+ .ThrowAsJavaScriptException();
146
+ return env.Undefined();
147
+ }
148
+
131
149
  Napi::Object InitPublisherBindings(Napi::Env env, Napi::Object exports) {
132
150
  exports.Set("createPublisher", Napi::Function::New(env, CreatePublisher));
133
151
  exports.Set("publish", Napi::Function::New(env, Publish));
@@ -135,6 +153,7 @@ Napi::Object InitPublisherBindings(Napi::Env env, Napi::Object exports) {
135
153
  exports.Set("publishRawMessage", Napi::Function::New(env, PublishRawMessage));
136
154
  exports.Set("getSubscriptionCount",
137
155
  Napi::Function::New(env, GetSubscriptionCount));
156
+ exports.Set("waitForAllAcked", Napi::Function::New(env, WaitForAllAcked));
138
157
  return exports;
139
158
  }
140
159
 
@@ -0,0 +1,79 @@
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_type_description_service_bindings.h"
16
+
17
+ #include <napi.h>
18
+ #include <rcl/rcl.h>
19
+ #include <rmw/types.h>
20
+
21
+ #include "rcl_handle.h"
22
+
23
+ namespace rclnodejs {
24
+
25
+ Napi::Value InitTypeDescriptionService(const Napi::CallbackInfo& info) {
26
+ Napi::Env env = info.Env();
27
+ RclHandle* node_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
28
+ rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
29
+ rcl_service_t* service =
30
+ reinterpret_cast<rcl_service_t*>(malloc(sizeof(rcl_service_t)));
31
+ *service = rcl_get_zero_initialized_service();
32
+ rcl_ret_t ret = rcl_node_type_description_service_init(service, node);
33
+ if (RCL_RET_OK != ret) {
34
+ Napi::Error::New(env, "Failed to initialize type description service")
35
+ .ThrowAsJavaScriptException();
36
+ }
37
+
38
+ auto service_handle =
39
+ RclHandle::NewInstance(env, service, node_handle, [node, env](void* ptr) {
40
+ rcl_service_t* service = reinterpret_cast<rcl_service_t*>(ptr);
41
+ rcl_ret_t ret = rcl_service_fini(service, node);
42
+ if (RCL_RET_OK != ret) {
43
+ Napi::Error::New(env, "Failed to destroy type description service")
44
+ .ThrowAsJavaScriptException();
45
+ }
46
+ free(ptr);
47
+ });
48
+ return service_handle;
49
+ }
50
+
51
+ Napi::Value HandleRequest(const Napi::CallbackInfo& info) {
52
+ Napi::Env env = info.Env();
53
+ rcl_node_t* node = reinterpret_cast<rcl_node_t*>(
54
+ RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
55
+ void* request = info[1].As<Napi::Buffer<char>>().Data();
56
+ void* taken_response = info[2].As<Napi::Buffer<char>>().Data();
57
+
58
+ rmw_request_id_t header;
59
+ rcl_node_type_description_service_handle_request(
60
+ node, &header,
61
+ static_cast<
62
+ type_description_interfaces__srv__GetTypeDescription_Request*>(
63
+ request),
64
+ static_cast<
65
+ type_description_interfaces__srv__GetTypeDescription_Response*>(
66
+ taken_response));
67
+ return env.Undefined();
68
+ }
69
+
70
+ Napi::Object InitTypeDescriptionServiceBindings(Napi::Env env,
71
+ Napi::Object exports) {
72
+ exports.Set("handleRequest", Napi::Function::New(env, HandleRequest));
73
+ exports.Set("initTypeDescriptionService",
74
+ Napi::Function::New(env, InitTypeDescriptionService));
75
+
76
+ return exports;
77
+ }
78
+
79
+ } // namespace rclnodejs
@@ -0,0 +1,27 @@
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_TYPE_DESCRIPTION_SERVICE_BINDINGS_H_
16
+ #define SRC_RCL_TYPE_DESCRIPTION_SERVICE_BINDINGS_H_
17
+
18
+ #include <napi.h>
19
+
20
+ namespace rclnodejs {
21
+
22
+ Napi::Object InitTypeDescriptionServiceBindings(Napi::Env env,
23
+ Napi::Object exports);
24
+
25
+ }
26
+
27
+ #endif // SRC_RCL_TYPE_DESCRIPTION_SERVICE_BINDINGS_H_
@@ -173,5 +173,23 @@ declare module 'rclnodejs' {
173
173
  * Destroy the underlying action client handle.
174
174
  */
175
175
  destroy(): void;
176
+
177
+ /**
178
+ * Get the number of wait set entities that make up an action entity.
179
+ * @return - The number of subscriptions, guard_conditions, timers, and clients and services.
180
+ */
181
+ getNumEntities(): object;
182
+
183
+ /**
184
+ * Configure introspection.
185
+ * @param clock - Clock to use for service event timestamps
186
+ * @param QoSProfile - QOS profile for the service event publisher
187
+ * @param introspectionState - The state to set introspection to
188
+ */
189
+ configureIntrospection(
190
+ clock: Clock,
191
+ serviceEventPubQOS: QoS,
192
+ introspectionState: ServiceIntrospectionStates
193
+ ): void;
176
194
  }
177
195
  }
@@ -181,5 +181,17 @@ declare module 'rclnodejs' {
181
181
  * Destroy the action server and all goals.
182
182
  */
183
183
  destroy(): void;
184
+
185
+ /**
186
+ * Configure introspection.
187
+ * @param clock - Clock to use for service event timestamps
188
+ * @param QoSProfile - QOS profile for the service event publisher
189
+ * @param introspectionState - The state to set introspection to
190
+ */
191
+ configureIntrospection(
192
+ clock: Clock,
193
+ serviceEventPubQOS: QoS,
194
+ introspectionState: ServiceIntrospectionStates
195
+ ): void;
184
196
  }
185
197
  }
@@ -326,6 +326,13 @@ declare module 'rclnodejs' {
326
326
  topic: string,
327
327
  options?: Options
328
328
  ): LifecyclePublisher<T>;
329
+
330
+ /**
331
+ * Check if state machine is initialized.
332
+ *
333
+ * @returns {boolean} true if the state machine is initialized; otherwise false.
334
+ */
335
+ get isInitialized(): boolean;
329
336
  }
330
337
  } // lifecycle namespace
331
338
  } // rclnodejs namespace
package/types/node.d.ts CHANGED
@@ -142,6 +142,24 @@ declare module 'rclnodejs' {
142
142
  namespace: string;
143
143
  };
144
144
 
145
+ /**
146
+ * Result of Node.getNodeNames() query
147
+ *
148
+ * @example
149
+ * ```
150
+ * [
151
+ * { name: 'gazebo', namespace: '/', enclave: '/'},
152
+ * { name: 'robot_state_publisher', namespace: '/', enclave: '/' },
153
+ * { name: 'cam2image', namespace: '/demo' , enclave: '/'}
154
+ * ]
155
+ * ```
156
+ */
157
+ type NodeNamesQueryResultWithEnclaves = {
158
+ name: string;
159
+ namespace: string;
160
+ enclave: string;
161
+ };
162
+
145
163
  /**
146
164
  * Node is the primary entrypoint in a ROS system for communication.
147
165
  * It can be used to create ROS entities such as publishers, subscribers,
@@ -285,12 +303,14 @@ declare module 'rclnodejs' {
285
303
  * @param typeClass - Type of message that will be published.
286
304
  * @param topic - Name of the topic the publisher will publish to.
287
305
  * @param options - Configuration options, see DEFAULT_OPTIONS
306
+ * @param eventCallbacks - Optional The event callbacks for the publisher.
288
307
  * @returns New instance of Publisher.
289
308
  */
290
309
  createPublisher<T extends TypeClass<MessageTypeClassName>>(
291
310
  typeClass: T,
292
311
  topic: string,
293
- options?: Options
312
+ options?: Options,
313
+ eventCallbacks?: (event: object) => void
294
314
  ): Publisher<T>;
295
315
 
296
316
  /**
@@ -315,6 +335,7 @@ declare module 'rclnodejs' {
315
335
  * @param topic - Name of the topic the subcription will subscribe to.
316
336
  * @param options - Configuration options, see DEFAULT_OPTIONS
317
337
  * @param callback - Called when a new message is received. The serialized message will be null-terminated.
338
+ * @param eventCallbacks - Optional The event callbacks for the subscription.
318
339
  * @returns New instance of Subscription.
319
340
  * @throws Error - May throw an RMW error if options.content-filter is malformed.
320
341
  * @see {@link https://www.omg.org/spec/DDS/1.4/PDF|Content-filter details at DDS 1.4 specification, Annex B}
@@ -323,7 +344,8 @@ declare module 'rclnodejs' {
323
344
  typeClass: T,
324
345
  topic: string,
325
346
  options: Options,
326
- callback: SubscriptionCallback<T> | SubscriptionWithRawMessageCallback
347
+ callback: SubscriptionCallback<T> | SubscriptionWithRawMessageCallback,
348
+ eventCallbacks?: (event: object) => void
327
349
  ): Subscription;
328
350
 
329
351
  /**
@@ -769,6 +791,13 @@ declare module 'rclnodejs' {
769
791
  */
770
792
  getNodeNamesAndNamespaces(): Array<NodeNamesQueryResult>;
771
793
 
794
+ /**
795
+ * Get the list of nodes and their namespaces with enclaves discovered by the provided node.
796
+ *
797
+ * @returns An array of the names, namespaces and enclaves.
798
+ */
799
+ getNodeNamesAndNamespacesWithEnclaves(): Array<NodeNamesQueryResultWithEnclaves>;
800
+
772
801
  /**
773
802
  * Return the number of publishers on a given topic.
774
803
  * @param topic - The name of the topic.
@@ -796,5 +825,18 @@ declare module 'rclnodejs' {
796
825
  * @returns Number of services.
797
826
  */
798
827
  countServices(serviceName: string): number;
828
+
829
+ /**
830
+ * Get the fully qualified name of the node.
831
+ *
832
+ * @returns String containing the fully qualified name of the node.
833
+ */
834
+ getFullyQualifiedName(): string;
835
+
836
+ /**
837
+ * Get the RMW implementation identifier
838
+ * @returns - The RMW implementation identifier.
839
+ */
840
+ getRMWImplementationIdentifier(): string;
799
841
  }
800
842
  }
@@ -20,5 +20,22 @@ declare module 'rclnodejs' {
20
20
  * @returns The number of subscriptions
21
21
  */
22
22
  subscriptionCount(): number;
23
+
24
+ /**
25
+ * Wait until all published message data is acknowledged or until the specified timeout elapses
26
+ *
27
+ * If the timeout is negative then this function will block indefinitely until all published
28
+ * message data is acknowledged.
29
+ * If the timeout is 0 then it will check if all published message has been acknowledged without
30
+ * waiting.
31
+ * If the timeout is greater than 0 then it will return after that period of time has elapsed or
32
+ * all published message data is acknowledged.
33
+ *
34
+ * Raises an error if failed, such as the middleware not supporting this feature.
35
+ *
36
+ * @param {timeout} timeout - The duration to wait for all published message data to be acknowledged in nanoseconds.
37
+ * @return {boolean} `true` if all published message data is acknowledged before the timeout, otherwise `false`.
38
+ */
39
+ waitForAllAcked(timeout: bigint): boolean;
23
40
  }
24
41
  }