rclnodejs 0.20.0 → 0.21.1

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.
@@ -0,0 +1,15 @@
1
+ {
2
+ "configurations": [
3
+ {
4
+ "name": "Linux",
5
+ "includePath": [
6
+ "${default}"
7
+ ],
8
+ "compilerPath": "/usr/bin/clang-10",
9
+ "cStandard": "c11",
10
+ "cppStandard": "c++14",
11
+ "intelliSenseMode": "linux-clang-x64"
12
+ }
13
+ ],
14
+ "version": 4
15
+ }
package/README.md CHANGED
@@ -18,7 +18,7 @@ rclnodejs.init().then(() => {
18
18
 
19
19
  **Node.js**
20
20
 
21
- - [Node.js](https://nodejs.org/en/) version between 8.12 - 12.x.
21
+ - [Node.js](https://nodejs.org/en/) version between 10.23 - 16.x.
22
22
 
23
23
  **ROS 2 SDK**
24
24
 
@@ -45,7 +45,7 @@ npm i rclnodejs@x.y.z
45
45
 
46
46
  | RCLNODEJS Version | Compatible ROS 2 Release |
47
47
  | :-------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
48
- | [0.20.0 (current)](https://www.npmjs.com/package/rclnodejs/v/0.20.0) ([API](http://robotwebtools.org/rclnodejs/docs/0.20.0/index.html)) | [Galactic Geochelone](https://github.com/ros2/ros2/releases/tag/release-galactic-20210716) / [Foxy Fitzroy](https://github.com/ros2/ros2/releases/tag/release-foxy-20201211) / [Eloquent Elusor](https://github.com/ros2/ros2/releases/tag/release-eloquent-20200124) |
48
+ | [0.21.1 (current)](https://www.npmjs.com/package/rclnodejs/v/0.21.1) ([API](http://robotwebtools.org/rclnodejs/docs/0.21.0/index.html)) | [Galactic Geochelone](https://github.com/ros2/ros2/releases/tag/release-galactic-20210716) / [Foxy Fitzroy](https://github.com/ros2/ros2/releases/tag/release-foxy-20201211) / [Eloquent Elusor](https://github.com/ros2/ros2/releases/tag/release-eloquent-20200124) |
49
49
  | [0.10.3](https://github.com/RobotWebTools/rclnodejs/releases/tag/0.10.3) | [Dashing Diademata - Patch 4](https://github.com/ros2/ros2/releases/tag/release-dashing-20191018) |
50
50
 
51
51
  ## Documentation
@@ -153,7 +153,7 @@ class ActionClient extends Entity {
153
153
  let uuid = ActionUuid.fromBytes(message.goal_id.uuid).toString();
154
154
  if (this._feedbackCallbacks.has(uuid)) {
155
155
  this._feedbackCallbacks.get(uuid)(
156
- message.toPlainObject(this.typedArrayEnabled)
156
+ message.toPlainObject(this.typedArrayEnabled).feedback
157
157
  );
158
158
  }
159
159
  }
@@ -166,10 +166,10 @@ class ActionClient extends Entity {
166
166
  ).toString();
167
167
  let status = statusMessage.status;
168
168
 
169
- if (!this._goalHandles.has(uuid)) {
169
+ if (this._goalHandles.has(uuid)) {
170
170
  let goalHandle = this._goalHandles.get(uuid);
171
171
  if (goalHandle) {
172
- goalHandle._status = status;
172
+ goalHandle.status = status;
173
173
 
174
174
  // Remove done handles from the list
175
175
  // eslint-disable-next-line max-depth
@@ -332,12 +332,16 @@ class ActionClient extends Entity {
332
332
  }
333
333
 
334
334
  let deferred = new Deferred();
335
- this._pendingResultRequests.set(sequenceNumber, deferred);
336
-
335
+ deferred.beforeSetResultCallback((result) => {
336
+ goalHandle.status = result.status;
337
+ return result.result;
338
+ });
337
339
  deferred.setDoneCallback(() =>
338
340
  this._removePendingResultRequest(sequenceNumber)
339
341
  );
340
342
 
343
+ this._pendingResultRequests.set(sequenceNumber, deferred);
344
+
341
345
  return deferred.promise;
342
346
  }
343
347
 
@@ -26,7 +26,9 @@ class ClientGoalHandle {
26
26
  this._actionClient = actionClient;
27
27
  this._goalId = goalId;
28
28
  this._goalResponse = goalResponse;
29
- this._status = ActionInterfaces.GoalStatus.STATUS_UNKNOWN;
29
+ this._status = this.accepted
30
+ ? ActionInterfaces.GoalStatus.STATUS_ACCEPTED
31
+ : ActionInterfaces.GoalStatus.STATUS_UNKNOWN;
30
32
  }
31
33
 
32
34
  /**
@@ -45,11 +47,60 @@ class ClientGoalHandle {
45
47
 
46
48
  /**
47
49
  * Gets if the goal response was accepted.
50
+ * @deprecated use isAccepted()
48
51
  */
49
52
  get accepted() {
53
+ return this.isAccepted();
54
+ }
55
+
56
+ /**
57
+ * Determine if goal is currently executing
58
+ * @returns {bool} - True if goal is executing; otherwise return false.
59
+ */
60
+ isAccepted() {
50
61
  return this._goalResponse.accepted;
51
62
  }
52
63
 
64
+ /**
65
+ * Determine if goal is currently executing
66
+ * @returns {bool} - True if goal is executing; otherwise return false.
67
+ */
68
+ isExecuting() {
69
+ return this.status === ActionInterfaces.GoalStatus.STATUS_EXECUTING;
70
+ }
71
+
72
+ /**
73
+ * Determine if goal is in the process of canceling.
74
+ * @returns {bool} - True if goal is canceling; otherwise return false.
75
+ */
76
+ isCanceling() {
77
+ return this.status === ActionInterfaces.GoalStatus.STATUS_CANCELING;
78
+ }
79
+
80
+ /**
81
+ * Determine if goal completed successfullly.
82
+ * @returns {bool} - True if goal completed successfully; otherwise return false.
83
+ */
84
+ isSucceeded() {
85
+ return this.status === ActionInterfaces.GoalStatus.STATUS_SUCCEEDED;
86
+ }
87
+
88
+ /**
89
+ * Determine if goal has been canceled.
90
+ * @returns {bool} - True if goal has been aborted; otherwise return false.
91
+ */
92
+ isCanceled() {
93
+ return this.status === ActionInterfaces.GoalStatus.STATUS_CANCELED;
94
+ }
95
+
96
+ /**
97
+ * Determine if goal has been aborted.
98
+ * @returns {bool} - True if goal was aborted; otherwise return false.
99
+ */
100
+ isAborted() {
101
+ return this.status === ActionInterfaces.GoalStatus.STATUS_ABORTED;
102
+ }
103
+
53
104
  /**
54
105
  * Gets the goal status.
55
106
  */
@@ -57,6 +108,21 @@ class ClientGoalHandle {
57
108
  return this._status;
58
109
  }
59
110
 
111
+ /**
112
+ * Update status to the latest state of goal computation.
113
+ * When status is in a final state it can not be revered to an
114
+ * earlier state, e.g., can not change from SUCCEEDED to ACCEPTED.
115
+ * @param {number} newStatus - The new status of this goal.
116
+ */
117
+ set status(newStatus) {
118
+ if (
119
+ this._status < ActionInterfaces.GoalStatus.STATUS_SUCCEEDED &&
120
+ newStatus > this._status
121
+ ) {
122
+ this._status = newStatus;
123
+ }
124
+ }
125
+
60
126
  /**
61
127
  * Send a cancel request for the goal.
62
128
  * @returns {Promise} - The cancel response.
@@ -35,6 +35,19 @@ class Deferred {
35
35
  return this._promise;
36
36
  }
37
37
 
38
+ /**
39
+ * Sets a function to be called before result updated
40
+ * @param {function} callback - Function to be called.
41
+ * @returns {undefined}
42
+ */
43
+ beforeSetResultCallback(callback) {
44
+ if (typeof callback !== 'function') {
45
+ throw new TypeError('Invalid parameter');
46
+ }
47
+
48
+ this._beforeSetResultCallback = callback;
49
+ }
50
+
38
51
  /**
39
52
  * Resolves the deferred promise.
40
53
  * @param {*} result - The value to resolve the promise with.
@@ -42,8 +55,10 @@ class Deferred {
42
55
  */
43
56
  setResult(result) {
44
57
  if (this._resolve) {
45
- this._result = result;
46
- this._resolve(result);
58
+ this._result = this._beforeSetResultCallback
59
+ ? this._beforeSetResultCallback(result)
60
+ : result;
61
+ this._resolve(this._result);
47
62
  this._resolve = null;
48
63
  }
49
64
  }
package/lib/node.js CHANGED
@@ -102,7 +102,7 @@ class Node extends rclnodejs.ShadowNode {
102
102
  this._parameterEventPublisher = null;
103
103
  this._setParametersCallbacks = [];
104
104
  this._logger = new Logging(rclnodejs.getNodeLoggerName(this.handle));
105
- this.spinning = false;
105
+ this._spinning = false;
106
106
 
107
107
  this._parameterEventPublisher = this.createPublisher(
108
108
  PARAMETER_EVENT_MSG_TYPE,
@@ -375,6 +375,14 @@ class Node extends rclnodejs.ShadowNode {
375
375
  });
376
376
  }
377
377
 
378
+ /**
379
+ * Determine if this node is spinning.
380
+ * @returns {boolean} - true when spinning; otherwise returns false.
381
+ */
382
+ get spinning() {
383
+ return this._spinning;
384
+ }
385
+
378
386
  /**
379
387
  * Trigger the event loop to continuously check for and route.
380
388
  * incoming events.
@@ -388,7 +396,7 @@ class Node extends rclnodejs.ShadowNode {
388
396
  throw new Error('The node is already spinning.');
389
397
  }
390
398
  this.start(this.context.handle, timeout);
391
- this.spinning = true;
399
+ this._spinning = true;
392
400
  }
393
401
 
394
402
  /**
@@ -401,21 +409,21 @@ class Node extends rclnodejs.ShadowNode {
401
409
 
402
410
  /**
403
411
  * Terminate spinning - no further events will be received.
404
- * @returns {undfined}
412
+ * @returns {undefined}
405
413
  */
406
414
  stop() {
407
415
  super.stop();
408
- this.spinning = false;
416
+ this._spinning = false;
409
417
  }
410
418
 
411
419
  /**
412
420
  * Terminate spinning - no further events will be received.
413
- * @returns {undfined}
421
+ * @returns {undefined}
414
422
  * @deprecated since 0.18.0, Use stop().
415
423
  */
416
424
  stopSpinning() {
417
425
  super.stop();
418
- this.spinning = false;
426
+ this._spinning = false;
419
427
  }
420
428
 
421
429
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rclnodejs",
3
- "version": "0.20.0",
3
+ "version": "0.21.1",
4
4
  "description": "ROS2.0 JavaScript client with Node.js",
5
5
  "main": "index.js",
6
6
  "types": "types/index.d.ts",
@@ -43,35 +43,37 @@
43
43
  "clang-format": "^1.4.0",
44
44
  "commander": "^6.0.0",
45
45
  "deep-equal": "^1.1.1",
46
- "dtslint": "^4.1.0",
46
+ "dtslint": "^4.2.1",
47
47
  "eslint": "^7.5.0",
48
48
  "eslint-config-prettier": "^6.11.0",
49
49
  "eslint-plugin-prettier": "^3.1.4",
50
50
  "husky": "^4.2.5",
51
+ "jsdoc": "^3.6.7",
51
52
  "lint-staged": "^10.2.11",
52
53
  "mocha": "^8.0.1",
53
54
  "prettier": "^2.0.5",
55
+ "rimraf": "^3.0.2",
54
56
  "sinon": "^9.0.2",
55
57
  "tree-kill": "^1.2.2",
56
58
  "typescript": "^4.0.3"
57
59
  },
58
60
  "dependencies": {
61
+ "@rclnodejs/ref-array-di": "^1.2.2",
62
+ "@rclnodejs/ref-napi": "^4.0.0",
63
+ "@rclnodejs/ref-struct-di": "^1.1.1",
64
+ "array.prototype.flat": "^1.2.4",
59
65
  "bindings": "^1.5.0",
60
66
  "compare-versions": "^3.6.0",
61
67
  "debug": "^4.1.1",
62
68
  "dot": "^1.1.3",
63
69
  "fs-extra": "^10.0.0",
70
+ "int64-napi": "^1.0.2",
64
71
  "is-close": "^1.3.3",
65
72
  "mkdirp": "^1.0.4",
66
73
  "mz": "^2.7.0",
67
74
  "nan": "^2.14.2",
68
- "ref-napi": "^3.0.0",
69
- "ref-array-di": "^1.2.2",
70
- "ref-struct-di": "^1.1.1",
71
- "walk": "^2.3.14",
72
75
  "uuid": "^8.2.0",
73
- "int64-napi": "^1.0.1",
74
- "array.prototype.flat": "^1.2.4"
76
+ "walk": "^2.3.14"
75
77
  },
76
78
  "husky": {
77
79
  "hooks": {
@@ -87,6 +89,6 @@
87
89
  ]
88
90
  },
89
91
  "engines": {
90
- "node": ">= 10.23.1 <13.0.0"
92
+ "node": ">= 10.23.1 <18.0.0"
91
93
  }
92
94
  }
@@ -24,7 +24,12 @@ let deallocator = {
24
24
  );
25
25
  },
26
26
  freeStructMember(refObj, type, name) {
27
- rclnodejs.freeMemeoryAtOffset(refObj.ref(), type.fields[name].offset);
27
+ if (refObj.ref().length !== 0) {
28
+ rclnodejs.freeMemeoryAtOffset(
29
+ refObj.ref().hexAddress(),
30
+ type.fields[name].offset
31
+ );
32
+ }
28
33
  },
29
34
  };
30
35
 
@@ -14,8 +14,8 @@
14
14
 
15
15
  'use strict';
16
16
 
17
- const ref = require('ref-napi');
18
- const StructType = require('ref-struct-di')(ref);
17
+ const ref = require('@rclnodejs/ref-napi');
18
+ const StructType = require('@rclnodejs/ref-struct-di')(ref);
19
19
  const rclnodejs = require('bindings')('rclnodejs');
20
20
 
21
21
  /* eslint-disable camelcase */
@@ -219,9 +219,9 @@ function extractMemberNames(fields) {
219
219
  {{? usePlainTypedArray}}
220
220
  const rclnodejs = require('bindings')('rclnodejs');
221
221
  {{?}}
222
- const ref = require('ref-napi');
223
- const StructType = require('ref-struct-di')(ref);
224
- const ArrayType = require('ref-array-di')(ref);
222
+ const ref = require('@rclnodejs/ref-napi');
223
+ const StructType = require('@rclnodejs/ref-struct-di')(ref);
224
+ const ArrayType = require('@rclnodejs/ref-array-di')(ref);
225
225
  const primitiveTypes = require('../../rosidl_gen/primitive_types.js');
226
226
  const deallocator = require('../../rosidl_gen/deallocator.js');
227
227
  const translator = require('../../rosidl_gen/message_translator.js');
@@ -750,7 +750,9 @@ class {{=arrayWrapper}} {
750
750
  {{? usePlainTypedArray}}
751
751
  const byteLen = refObject.size * ref.types.{{=currentTypedArrayElementType}}.size;
752
752
  // An ArrayBuffer object that doesn't hold the ownership of the address
753
- const arrayBuffer = rclnodejs.createArrayBufferFromAddress(refObject.data, byteLen);
753
+ const arrayBuffer = refObject.data.length !== 0 ?
754
+ rclnodejs.createArrayBufferFromAddress(refObject.data.hexAddress(), byteLen) :
755
+ Buffer.alloc(0);
754
756
  this._wrappers = new {{=currentTypedArray}}(arrayBuffer);
755
757
  {{?? true}}
756
758
  let refObjectArray = this._refObject.data;
package/scripts/build.sh CHANGED
@@ -19,5 +19,5 @@ set -e
19
19
  pushd $(dirname $0) > /dev/null
20
20
 
21
21
  git submodule update --init --recursive
22
- npm install --unsafe-perm
22
+ npm install
23
23
  npm run lint
@@ -20,7 +20,7 @@ const cmd = 'wget -nc ';
20
20
  const cpplintUrl =
21
21
  'https://raw.githubusercontent.com/google/styleguide' +
22
22
  '/gh-pages/cpplint/cpplint.py';
23
- const root = `${__dirname}/../src/`;
23
+ const root = `${__dirname}/../src`;
24
24
  const args = `--extensions=cpp,h,hpp,cc ${root}/*`;
25
25
 
26
26
  console.log('Downloading the cpplint...');
@@ -18,7 +18,7 @@ rclnodejs.init().then(() => {
18
18
 
19
19
  **Node.js**
20
20
 
21
- - [Node.js](https://nodejs.org/en/) version between 8.12 - 12.x.
21
+ - [Node.js](https://nodejs.org/en/) version between 10.23 - 16.x.
22
22
 
23
23
  **ROS 2 SDK**
24
24
 
@@ -45,7 +45,7 @@ npm i rclnodejs@x.y.z
45
45
 
46
46
  | RCLNODEJS Version | Compatible ROS 2 Release |
47
47
  | :-------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
48
- | [0.20.0 (current)](https://www.npmjs.com/package/rclnodejs/v/0.20.0) ([API](http://robotwebtools.org/rclnodejs/docs/0.20.0/index.html)) | [Galactic Geochelone](https://github.com/ros2/ros2/releases/tag/release-galactic-20210716) / [Foxy Fitzroy](https://github.com/ros2/ros2/releases/tag/release-foxy-20201211) / [Eloquent Elusor](https://github.com/ros2/ros2/releases/tag/release-eloquent-20200124) |
48
+ | [0.21.1 (current)](https://www.npmjs.com/package/rclnodejs/v/0.21.1) ([API](http://robotwebtools.org/rclnodejs/docs/0.21.0/index.html)) | [Galactic Geochelone](https://github.com/ros2/ros2/releases/tag/release-galactic-20210716) / [Foxy Fitzroy](https://github.com/ros2/ros2/releases/tag/release-foxy-20201211) / [Eloquent Elusor](https://github.com/ros2/ros2/releases/tag/release-eloquent-20200124) |
49
49
  | [0.10.3](https://github.com/RobotWebTools/rclnodejs/releases/tag/0.10.3) | [Dashing Diademata - Patch 4](https://github.com/ros2/ros2/releases/tag/release-dashing-20191018) |
50
50
 
51
51
  ## Documentation
package/src/executor.hpp CHANGED
@@ -24,8 +24,6 @@
24
24
 
25
25
  #include "rcl_handle.hpp"
26
26
 
27
- struct rcl_context_t;
28
-
29
27
  namespace rclnodejs {
30
28
 
31
29
  class HandleManager;
@@ -39,6 +39,9 @@
39
39
  #include <memory>
40
40
  #include <string>
41
41
  #include <vector>
42
+ #if NODE_MAJOR_VERSION > 12
43
+ #include <utility>
44
+ #endif
42
45
 
43
46
  #include "handle_manager.hpp"
44
47
  #include "macros.hpp"
@@ -1292,18 +1295,14 @@ inline char* GetBufAddr(v8::Local<v8::Value> buf) {
1292
1295
  }
1293
1296
 
1294
1297
  NAN_METHOD(FreeMemeoryAtOffset) {
1295
- v8::Local<v8::Value> buf = info[0];
1296
- if (!node::Buffer::HasInstance(buf)) {
1297
- return Nan::ThrowTypeError("Buffer instance expected as first argument");
1298
- }
1299
-
1298
+ v8::Local<v8::Context> currentContent = Nan::GetCurrentContext();
1299
+ std::string addr_str(
1300
+ *Nan::Utf8String(info[0]->ToString(currentContent).ToLocalChecked()));
1301
+ int64_t result = std::stoull(addr_str, 0, 16);
1302
+ char* addr = reinterpret_cast<char*>(result);
1300
1303
  int64_t offset =
1301
1304
  info[1]->IsNumber() ? Nan::To<int64_t>(info[1]).FromJust() : 0;
1302
- auto ptr = GetBufAddr(buf) + offset;
1303
-
1304
- if (ptr == nullptr) {
1305
- return Nan::ThrowError("Cannot read from NULL pointer");
1306
- }
1305
+ auto ptr = addr + offset;
1307
1306
 
1308
1307
  char* val = *reinterpret_cast<char**>(ptr);
1309
1308
  free(val);
@@ -1311,15 +1310,28 @@ NAN_METHOD(FreeMemeoryAtOffset) {
1311
1310
  }
1312
1311
 
1313
1312
  NAN_METHOD(CreateArrayBufferFromAddress) {
1314
- char* addr = GetBufAddr(info[0]);
1313
+ v8::Local<v8::Context> currentContent = Nan::GetCurrentContext();
1314
+ std::string addr_str(
1315
+ *Nan::Utf8String(info[0]->ToString(currentContent).ToLocalChecked()));
1316
+ int64_t result = std::stoull(addr_str, 0, 16);
1317
+ char* addr = reinterpret_cast<char*>(result);
1315
1318
  int32_t length = Nan::To<int32_t>(info[1]).FromJust();
1316
1319
 
1317
1320
  // We will create an ArrayBuffer with mode of
1318
1321
  // ArrayBufferCreationMode::kInternalized and copy data starting from |addr|,
1319
1322
  // thus the memory block will be collected by the garbage collector.
1323
+ #if NODE_MAJOR_VERSION <= 12
1320
1324
  v8::Local<v8::ArrayBuffer> array_buffer =
1321
1325
  v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), addr, length,
1322
1326
  v8::ArrayBufferCreationMode::kInternalized);
1327
+ #else
1328
+ std::unique_ptr<v8::BackingStore> backing =
1329
+ v8::ArrayBuffer::NewBackingStore(v8::Isolate::GetCurrent(), length);
1330
+ memcpy(backing->Data(), addr, length);
1331
+ auto array_buffer =
1332
+ v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), std::move(backing));
1333
+ free(addr);
1334
+ #endif
1323
1335
 
1324
1336
  info.GetReturnValue().Set(array_buffer);
1325
1337
  }
@@ -26,13 +26,50 @@ declare module 'rclnodejs' {
26
26
 
27
27
  /**
28
28
  * Gets if the goal response was accepted.
29
+ * @deprecated Use isAccepted()
29
30
  */
30
31
  get accepted(): boolean;
31
32
 
33
+ /**
34
+ * Determine if goal is currently executing
35
+ * @returns {bool} - True if goal is executing; otherwise return false.
36
+ */
37
+ isAccepted(): boolean;
38
+
39
+ /**
40
+ * Determine if goal is currently executing
41
+ * @returns {bool} - True if goal is executing; otherwise return false.
42
+ */
43
+ isExecuting(): boolean;
44
+
45
+ /**
46
+ * Determine if goal is in the process of canceling.
47
+ * @returns True if goal is canceling; otherwise return false.
48
+ */
49
+ isCanceling(): boolean;
50
+
51
+ /**
52
+ * Determine if goal completed successfullly.
53
+ * @returns True if goal completed successfully; otherwise return false.
54
+ */
55
+ isSucceeded(): boolean;
56
+
57
+ /**
58
+ * Determine if goal has been canceled.
59
+ * @returns True if goal has been aborted; otherwise return false.
60
+ */
61
+ isCanceled(): boolean;
62
+
63
+ /**
64
+ * Determine if goal has been aborted.
65
+ * @returns True if goal was aborted; otherwise return false.
66
+ */
67
+ isAborted(): boolean;
68
+
32
69
  /**
33
70
  * Gets the goal status.
34
71
  */
35
- get status(): string;
72
+ get status(): number;
36
73
 
37
74
  /**
38
75
  * Send a cancel request for the goal.
@@ -77,12 +77,14 @@ declare module 'rclnodejs' {
77
77
 
78
78
  type ExecuteCallback<T extends TypeClass<ActionTypeClassName>> = (
79
79
  goalHandle: ServerGoalHandle<T>
80
- ) => ActionResult<T>;
81
- type GoalCallback = () => GoalResponse;
80
+ ) => Promise<ActionResult<T>> | ActionResult<T>;
81
+ type GoalCallback<T extends TypeClass<ActionTypeClassName>> = (
82
+ goalHandle: ServerGoalHandle<T>
83
+ ) => GoalResponse;
82
84
  type HandleAcceptedCallback<T extends TypeClass<ActionTypeClassName>> = (
83
85
  goalHandle: ServerGoalHandle<T>
84
86
  ) => void;
85
- type CancelCallback = () => CancelResponse;
87
+ type CancelCallback = () => Promise<CancelResponse> | CancelResponse;
86
88
 
87
89
  interface ActionServerOptions extends Options<ActionQoS> {
88
90
  /**
@@ -112,7 +114,7 @@ declare module 'rclnodejs' {
112
114
  typeClass: T,
113
115
  actionName: string,
114
116
  executeCallback: ExecuteCallback<T>,
115
- goalCallback?: GoalCallback,
117
+ goalCallback?: GoalCallback<T>,
116
118
  handleAcceptedCallback?: HandleAcceptedCallback<T>,
117
119
  cancelCallback?: CancelCallback,
118
120
  options?: ActionServerOptions
@@ -144,7 +146,7 @@ declare module 'rclnodejs' {
144
146
  *
145
147
  * @param goalCallback - Callback function, if not provided, then unregisters any previously registered callback.
146
148
  */
147
- registerGoalCallback(goalCallback?: GoalCallback): void;
149
+ registerGoalCallback(goalCallback?: GoalCallback<T>): void;
148
150
 
149
151
  /**
150
152
  * Register a callback for handling cancel requests.
package/types/node.d.ts CHANGED
@@ -182,6 +182,13 @@ declare module 'rclnodejs' {
182
182
  */
183
183
  options(): NodeOptions;
184
184
 
185
+ /**
186
+ * Determine if this node is spinning.
187
+ *
188
+ * @returns true when spinning; otherwise returns false.
189
+ */
190
+ get spinning(): boolean;
191
+
185
192
  /**
186
193
  * Trigger the event loop to continuously check for and route.
187
194
  * incoming events.