rclnodejs 0.27.4 → 0.28.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/CONTRIBUTORS.md CHANGED
@@ -1,54 +1,63 @@
1
- rclnodejs contributors (sorted alphabetically)
2
- ==============================================
1
+ # rclnodejs contributors (sorted alphabetically)
2
+
3
+ - **[Alaa El Jawad](https://github.com/ejalaa12), [Ian McElroy](https://github.com/imcelroy)**
3
4
 
4
- * **[Alaa El Jawad](https://github.com/ejalaa12), [Ian McElroy](https://github.com/imcelroy)**
5
5
  - Fix compatibility with ROS2 parameters array types
6
6
  - Unit tests for all parameter types
7
7
  - Handle concurrent ROS2 client calls, with unit tests
8
8
 
9
- * **[Alex Mikhalev](https://github.com/amikhalev)**
10
- * Fix build for AMENT_PREFIX_PATH with multiple entries
11
-
12
- * **[Felix Divo](https://github.com/felixdivo)**
13
- * Code cleanup of index.js, tests cases & message generation
14
- * Improved shutdown behavior
15
- * Fixed compilation warnings
16
-
17
- * **[Hanyia](https://github.com/hanyia)**
18
- * Benchmark test script
19
-
20
- * **[Kenny Yuan](https://github.com/kenny-y)**
21
- * Message features: JS generation, typed arrays, plain JS object, compound msgs, many others...
22
- * npm publish scripts
23
- * Mac support
24
-
25
- * **[Matt Richard](https://github.com/mattrichard)**
26
- * ROS2 Actions
27
- * Guard conditions
28
- * Node utility methods (countPublishers/subscribers...)
29
- * TypeScript improvements
30
- * Node 12 compatibility
31
-
32
- * **[Minggang Wang](https://github.com/minggangw)**
33
- * Author, lead developer, maintainer
34
- * Core, CI
35
-
36
- * **[Martins Mozeiko](https://github.com/martins-mozeiko)**
37
- * QoS new/delete fix
38
-
39
- * **[Qiuzhong](https://github.com/qiuzhong)**
40
- * Test coverage for actions, topics, multi-array messages, cross platform, security
41
- * Converted from setTimeout to ROS2 Timer
42
-
43
- * **[Teo Koon Peng](https://github.com/koonpeng)**
44
- * TypeScript improvements
45
- * Added Client#waitForService
46
- * Code style improvements, e.g., Prettier formatting
47
- * Improved code generation smarts and efficiency
48
-
49
- * **[Wayne Parrott](https://github.com/wayneparrott)**
50
- * TypeScript support with interface generation
51
- * ROS2 parameter support
52
- * ROS2 lifecycle node
53
- * Rate class
54
- * Node class hierarchy
9
+ - **[Alex Mikhalev](https://github.com/amikhalev)**
10
+
11
+ - Fix build for AMENT_PREFIX_PATH with multiple entries
12
+
13
+ - **[Felix Divo](https://github.com/felixdivo)**
14
+
15
+ - Code cleanup of index.js, tests cases & message generation
16
+ - Improved shutdown behavior
17
+ - Fixed compilation warnings
18
+
19
+ - **[Hanyia](https://github.com/hanyia)**
20
+
21
+ - Benchmark test script
22
+
23
+ - **[Kenny Yuan](https://github.com/kenny-y)**
24
+
25
+ - Message features: JS generation, typed arrays, plain JS object, compound msgs, many others...
26
+ - npm publish scripts
27
+ - Mac support
28
+
29
+ - **[Matt Richard](https://github.com/mattrichard)**
30
+
31
+ - ROS2 Actions
32
+ - Guard conditions
33
+ - Node utility methods (countPublishers/subscribers...)
34
+ - TypeScript improvements
35
+ - Node 12 compatibility
36
+
37
+ - **[Minggang Wang](https://github.com/minggangw)**
38
+
39
+ - Author, lead developer, maintainer
40
+ - Core, CI
41
+
42
+ - **[Martins Mozeiko](https://github.com/martins-mozeiko)**
43
+
44
+ - QoS new/delete fix
45
+
46
+ - **[Qiuzhong](https://github.com/qiuzhong)**
47
+
48
+ - Test coverage for actions, topics, multi-array messages, cross platform, security
49
+ - Converted from setTimeout to ROS2 Timer
50
+
51
+ - **[Teo Koon Peng](https://github.com/koonpeng)**
52
+
53
+ - TypeScript improvements
54
+ - Added Client#waitForService
55
+ - Code style improvements, e.g., Prettier formatting
56
+ - Improved code generation smarts and efficiency
57
+
58
+ - **[Wayne Parrott](https://github.com/wayneparrott)**
59
+ - TypeScript support with interface generation
60
+ - ROS2 parameter support
61
+ - ROS2 lifecycle node
62
+ - Rate class
63
+ - Node class hierarchy
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # rclnodejs ![GitHub Workflow Status](https://github.com/RobotWebTools/rclnodejs/actions/workflows/linux-build-and-test.yml/badge.svg?branch=iron-irwini)
1
+ # rclnodejs ![GitHub Workflow Status](https://github.com/RobotWebTools/rclnodejs/actions/workflows/linux-build-and-test.yml/badge.svg?branch=jazzy)
2
2
 
3
3
  `rclnodejs` is a Node.js client for the Robot Operating System (ROS 2). It provides a simple and easy JavaScript API for ROS 2 programming. TypeScript declarations are included to support use of rclnodejs in TypeScript projects.
4
4
 
@@ -43,9 +43,9 @@ npm i rclnodejs@x.y.z
43
43
 
44
44
  #### RCLNODEJS - ROS 2 Version Compatibility
45
45
 
46
- | RCLNODEJS Version | Compatible ROS 2 LTS |
47
- | :------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------: |
48
- | latest version (currently [v0.22.3](https://github.com/RobotWebTools/rclnodejs/tree/0.22.3)) | [Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill)<br>[Iron](https://github.com/RobotWebTools/rclnodejs/tree/iron-irwini) |
46
+ | RCLNODEJS Version | Compatible ROS 2 LTS |
47
+ | :------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------: |
48
+ | latest version (currently [v0.28.0](https://github.com/RobotWebTools/rclnodejs/tree/0.28.0)) | [Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill)<br>[Jazzy](https://github.com/RobotWebTools/rclnodejs/tree/jazzy) |
49
49
 
50
50
  ## Documentation
51
51
 
@@ -0,0 +1,54 @@
1
+ # Rclnodejs Electron demo
2
+
3
+ ## Introduction
4
+
5
+ This is a minimal rclnodejs demo using Electron. More information about Electron, please check with [Electron documentation](https://electronjs.org/docs/latest/tutorial/quick-start).
6
+
7
+ The demo includes the following files:
8
+
9
+ - `package.json` - Points to the app's main file and lists its details and dependencies.
10
+ - `main.js` - Introduces the `rclnodejs` native module, starts the app and creates a browser window to render HTML. This is the app's **main process**.
11
+ - `index.html` - Includes a text editor where you can input the the topic to be published. This is the app's **renderer process**.
12
+ - `renderer.js` - Communicate with main process to publish a topic and get it through a subscription.
13
+
14
+ ## To run the demo
15
+
16
+ Before starting, please ensure you have installed [nodejs](https://nodejs.org/en).
17
+
18
+ 1. Clone this repository.
19
+
20
+ ```bash
21
+ git clone https://github.com/RobotWebTools/rclnodejs.git
22
+ ```
23
+
24
+ 2. Go into the demo.
25
+ ```bash
26
+ cd rclnodejs/electron_demo
27
+ ```
28
+
29
+ 3. [SOURCE THE ROS 2 SETUP FILE](https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.html#source-the-setup-files)
30
+
31
+ 4. Install dependencies
32
+ ```bash
33
+ npm install
34
+ ```
35
+
36
+ 5. Rebuild rclnodejs for Electron
37
+ ```bash
38
+ # Every time you run "npm install", run this:
39
+ ./node_modules/.bin/electron-rebuild
40
+ ```
41
+
42
+ 6. Run the app
43
+ ```
44
+ npm start
45
+ ```
46
+
47
+ If it works, you can see the demo as:
48
+ ![demo screenshot](./electron-demo.gif)
49
+
50
+ ## Resources for Learning Electron
51
+
52
+ - [electronjs.org/docs](https://electronjs.org/docs) - all of Electron's documentation.
53
+ - [Native Node Modules](https://www.electronjs.org/docs/latest/tutorial/using-native-node-modules) - Use a native node module.
54
+
Binary file
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta http-equiv="Content-Security-Policy"
7
+ content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
8
+ <title>RCLNODEJS Electron Demo</title>
9
+ </head>
10
+
11
+ <body>
12
+ <div>
13
+ <div style="height: 20px;"></div>
14
+ <div>
15
+ <input id="topic-input"></input>
16
+ <button id="publish-topic">Publish topic</button>
17
+ </div>
18
+ <div style="height: 20px;"></div>
19
+ <span>Received topic:</span>
20
+ <span id="received-topic"></span>
21
+ </div>
22
+ <script src="./renderer.js"></script>
23
+ </body>
24
+
25
+ </html>
@@ -0,0 +1,66 @@
1
+ // Licensed under the Apache License, Version 2.0 (the "License");
2
+ // you may not use this file except in compliance with the License.
3
+ // You may obtain a copy of the License at
4
+ //
5
+ // http://www.apache.org/licenses/LICENSE-2.0
6
+ //
7
+ // Unless required by applicable law or agreed to in writing, software
8
+ // distributed under the License is distributed on an "AS IS" BASIS,
9
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ // See the License for the specific language governing permissions and
11
+ // limitations under the License.
12
+
13
+ const { app, BrowserWindow } = require('electron')
14
+ let rclnodejs = require("rclnodejs");
15
+ const { ipcMain } = require('electron');
16
+
17
+ function createWindow() {
18
+ // Create the browser window.
19
+ const mainWindow = new BrowserWindow({
20
+ width: 800,
21
+ height: 600,
22
+ webPreferences: {
23
+ // Add the following two lines in order to use require() in renderer, see details
24
+ // https://stackoverflow.com/questions/44391448/electron-require-is-not-defined
25
+ nodeIntegration: true,
26
+ contextIsolation: false,
27
+ }
28
+ });
29
+
30
+ mainWindow.loadFile('index.html');
31
+ }
32
+
33
+ // This method will be called when Electron has finished
34
+ // initialization and is ready to create browser windows.
35
+ // Some APIs can only be used after this event occurs.
36
+ app.whenReady().then(() => {
37
+ createWindow();
38
+ rclnodejs.init().then(() => {
39
+ let sender = null;
40
+ const node = rclnodejs.createNode('publisher_example_node');
41
+ node.createSubscription('std_msgs/msg/String', 'topic', (msg) => {
42
+ if (sender) {
43
+ sender.send('topic-received', msg.data);
44
+ }
45
+ });
46
+ const publisher = node.createPublisher('std_msgs/msg/String', 'topic');
47
+ ipcMain.on('publish-topic', (event, topic) => {
48
+ publisher.publish(topic);
49
+ sender = event.sender;
50
+ });
51
+ rclnodejs.spin(node);
52
+ });
53
+
54
+ app.on('activate', function () {
55
+ // On macOS it's common to re-create a window in the app when the
56
+ // dock icon is clicked and there are no other windows open.
57
+ if (BrowserWindow.getAllWindows().length === 0) createWindow();
58
+ });
59
+ });
60
+
61
+ // Quit when all windows are closed, except on macOS. There, it's common
62
+ // for applications and their menu bar to stay active until the user quits
63
+ // explicitly with Cmd + Q.
64
+ app.on('window-all-closed', function () {
65
+ if (process.platform !== 'darwin') app.quit()
66
+ });
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "rclnodejs-electron-demo",
3
+ "version": "1.0.0",
4
+ "description": "A minimal rclnodejs Electron application",
5
+ "main": "main.js",
6
+ "scripts": {
7
+ "start": "electron ."
8
+ },
9
+ "keywords": [
10
+ "Electron",
11
+ "rclnodejs",
12
+ "demo"
13
+ ],
14
+ "license": "Apache",
15
+ "dependencies": {
16
+ "rclnodejs": "^0.27.4"
17
+ },
18
+ "devDependencies": {
19
+ "@electron/rebuild": "^3.6.0",
20
+ "electron": "^31.0.0"
21
+ }
22
+ }
@@ -0,0 +1,22 @@
1
+ // Licensed under the Apache License, Version 2.0 (the "License");
2
+ // you may not use this file except in compliance with the License.
3
+ // You may obtain a copy of the License at
4
+ //
5
+ // http://www.apache.org/licenses/LICENSE-2.0
6
+ //
7
+ // Unless required by applicable law or agreed to in writing, software
8
+ // distributed under the License is distributed on an "AS IS" BASIS,
9
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ // See the License for the specific language governing permissions and
11
+ // limitations under the License.
12
+
13
+ const { ipcRenderer } = require('electron');
14
+
15
+ ipcRenderer.on('topic-received', function (event, response) {
16
+ document.getElementById('received-topic').innerText = response;
17
+ });
18
+
19
+ document.getElementById('publish-topic').addEventListener('click', () => {
20
+ const topic = document.getElementById('topic-input').value;
21
+ ipcRenderer.send('publish-topic', topic);
22
+ });
package/lib/client.js CHANGED
@@ -58,7 +58,6 @@ class Client extends Entity {
58
58
  request instanceof this._typeClass.Request
59
59
  ? request
60
60
  : new this._typeClass.Request(request);
61
- requestToSend._willCheckConsistency = this._options.willCheckConsistency;
62
61
 
63
62
  let rawRequest = requestToSend.serialize();
64
63
  let sequenceNumber = rclnodejs.sendRequest(this._handle, rawRequest);
@@ -27,7 +27,7 @@ const Publisher = require('./publisher.js');
27
27
  */
28
28
  class LifecyclePublisher extends Publisher {
29
29
  constructor(handle, typeClass, topic, options) {
30
- super(handle, typeClass, /*topic=*/'', options);
30
+ super(handle, typeClass, /*topic=*/ '', options);
31
31
 
32
32
  this._enabled = false;
33
33
  this._loggger = Logging.getLogger('LifecyclePublisher');
package/lib/node.js CHANGED
@@ -116,7 +116,7 @@ class Node extends rclnodejs.ShadowNode {
116
116
  // override cli parameterOverrides with those specified in options
117
117
  if (options.parameterOverrides.length > 0) {
118
118
  for (const parameter of options.parameterOverrides) {
119
- if (!parameter instanceof Parameter) {
119
+ if ((!parameter) instanceof Parameter) {
120
120
  throw new TypeError(
121
121
  'Parameter-override must be an instance of Parameter.'
122
122
  );
@@ -502,10 +502,6 @@ class Node extends rclnodejs.ShadowNode {
502
502
  options = Object.assign(options, { isRaw: false });
503
503
  }
504
504
 
505
- if (options.willCheckConsistency === undefined) {
506
- options = Object.assign(options, { willCheckConsistency: false });
507
- }
508
-
509
505
  return options;
510
506
  }
511
507
 
@@ -592,7 +588,6 @@ class Node extends rclnodejs.ShadowNode {
592
588
  * @param {object} options - The options argument used to parameterize the publisher.
593
589
  * @param {boolean} options.enableTypedArray - The topic will use TypedArray if necessary, default: true.
594
590
  * @param {QoS} options.qos - ROS Middleware "quality of service" settings for the publisher, default: QoS.profileDefault.
595
- * @param {boolean} options.willCheckConsistency - Pulisher will check the consistancy of the message to be sent, default: false.
596
591
  * @return {Publisher} - An instance of Publisher.
597
592
  */
598
593
  createPublisher(typeClass, topic, options) {
@@ -695,7 +690,6 @@ class Node extends rclnodejs.ShadowNode {
695
690
  * @param {object} options - The options argument used to parameterize the client.
696
691
  * @param {boolean} options.enableTypedArray - The response will use TypedArray if necessary, default: true.
697
692
  * @param {QoS} options.qos - ROS Middleware "quality of service" settings for the client, default: QoS.profileDefault.
698
- * @param {boolean} options.willCheckConsistency - Client will check the consistancy of the message to be sent, default: false.
699
693
  * @return {Client} - An instance of Client.
700
694
  */
701
695
  createClient(typeClass, serviceName, options) {
@@ -1696,7 +1690,6 @@ Node.getDefaultOptions = function () {
1696
1690
  isRaw: false,
1697
1691
  qos: QoS.profileDefault,
1698
1692
  contentFilter: undefined,
1699
- willCheckConsistency: false
1700
1693
  };
1701
1694
  };
1702
1695
 
package/lib/publisher.js CHANGED
@@ -53,7 +53,6 @@ class Publisher extends Entity {
53
53
  message instanceof this._typeClass
54
54
  ? message
55
55
  : new this._typeClass(message);
56
- messageToSend._willCheckConsistency = this._options.willCheckConsistency;
57
56
  let rawMessage = messageToSend.serialize();
58
57
  rclnodejs.publish(this._handle, rawMessage);
59
58
  }
package/lib/service.js CHANGED
@@ -75,18 +75,19 @@ class Service extends Entity {
75
75
 
76
76
  const plainObj = request.toPlainObject(this.typedArrayEnabled);
77
77
  const response = new Response(this, headerHandle);
78
- Promise.resolve(this._callback(plainObj, response)).then((responseToReturn) => {
79
-
80
- if (!response.sent && responseToReturn) {
81
- responseToReturn = new this._typeClass.Response(responseToReturn);
82
- const rawResponse = responseToReturn.serialize();
83
- rclnodejs.sendResponse(this._handle, rawResponse, headerHandle);
78
+ Promise.resolve(this._callback(plainObj, response)).then(
79
+ (responseToReturn) => {
80
+ if (!response.sent && responseToReturn) {
81
+ responseToReturn = new this._typeClass.Response(responseToReturn);
82
+ const rawResponse = responseToReturn.serialize();
83
+ rclnodejs.sendResponse(this._handle, rawResponse, headerHandle);
84
+ }
85
+
86
+ debug(
87
+ `Service has processed the ${this._serviceName} request and sent the response.`
88
+ );
84
89
  }
85
-
86
- debug(
87
- `Service has processed the ${this._serviceName} request and sent the response.`
88
- );
89
- });
90
+ );
90
91
  }
91
92
 
92
93
  static createService(nodeHandle, serviceName, typeClass, options, callback) {
@@ -102,7 +102,7 @@ class TimeSource {
102
102
  * @return {undefined}
103
103
  */
104
104
  attachNode(node) {
105
- if (!node instanceof rclnodejs.ShadowNode) {
105
+ if ((!node) instanceof rclnodejs.ShadowNode) {
106
106
  throw new TypeError('Invalid argument, must be type of Node');
107
107
  }
108
108
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rclnodejs",
3
- "version": "0.27.4",
3
+ "version": "0.28.0",
4
4
  "description": "ROS2.0 JavaScript client with Node.js",
5
5
  "main": "index.js",
6
6
  "types": "types/index.d.ts",
@@ -18,6 +18,7 @@
18
18
  "rebuild": "npm run clean && node-gyp -j 16 rebuild",
19
19
  "rebuild:dev": "npm run clean && node-gyp -j 16 rebuild --debug",
20
20
  "generate-messages": "node scripts/generate_messages.js",
21
+ "generate-messages:dev": "node scripts/generate_messages.js --debug",
21
22
  "clean": "node-gyp clean && rimraf ./generated",
22
23
  "install": "npm run rebuild",
23
24
  "postinstall": "npm run generate-messages",
@@ -25,7 +26,8 @@
25
26
  "test": "node --expose-gc ./scripts/run_test.js && npm run dtslint",
26
27
  "dtslint": "node scripts/generate_tsd.js",
27
28
  "lint": "eslint --max-warnings=0 --ext js,ts index.js types scripts lib example rosidl_gen rosidl_parser test benchmark/rclnodejs && node ./scripts/cpplint.js",
28
- "format": "clang-format -i -style=file ./src/*.cpp ./src/*.hpp && prettier --write \"{lib,rosidl_gen,rostsd_gen,rosidl_parser,types,example,test,scripts,benchmark}/**/*.{js,md,ts}\" ./*.{js,md,ts}"
29
+ "format": "clang-format -i -style=file ./src/*.cpp ./src/*.hpp && prettier --write \"{lib,rosidl_gen,rostsd_gen,rosidl_parser,types,example,test,scripts,benchmark}/**/*.{js,md,ts}\" ./*.{js,md,ts}",
30
+ "prepare": "husky"
29
31
  },
30
32
  "bin": {
31
33
  "generate-ros-messages": "./scripts/generate_messages.js"
@@ -41,45 +43,47 @@
41
43
  "type": "git",
42
44
  "url": "git+https://github.com/RobotWebTools/rclnodejs.git"
43
45
  },
46
+ "//": "Pin deep-equal to ^1.1.1",
44
47
  "devDependencies": {
45
- "@babel/eslint-parser": "^7.22.15",
46
- "@typescript-eslint/eslint-plugin": "^6.6.0",
47
- "@typescript-eslint/parser": "^6.6.0",
48
+ "@babel/eslint-parser": "^7.25.9",
49
+ "@typescript-eslint/eslint-plugin": "^8.18.0",
50
+ "@typescript-eslint/parser": "^8.18.0",
48
51
  "babel-eslint": "^10.1.0",
49
52
  "clang-format": "^1.8.0",
50
- "commander": "^11.0.0",
53
+ "commander": "^12.1.0",
51
54
  "deep-equal": "^1.1.1",
52
- "eslint": "^8.49.0",
53
- "eslint-config-prettier": "^9.0.0",
54
- "eslint-plugin-prettier": "^5.0.0",
55
- "husky": "^8.0.3",
56
- "jsdoc": "^4.0.2",
57
- "lint-staged": "^14.0.1",
58
- "mocha": "^10.2.0",
59
- "prettier": "^3.0.3",
60
- "sinon": "^15.2.0",
55
+ "eslint": "^9.16.0",
56
+ "eslint-config-prettier": "^9.1.0",
57
+ "eslint-plugin-prettier": "^5.2.1",
58
+ "husky": "^9.1.7",
59
+ "jsdoc": "^4.0.4",
60
+ "lint-staged": "^15.2.10",
61
+ "mocha": "^11.0.2",
62
+ "sinon": "^19.0.2",
61
63
  "tree-kill": "^1.2.2",
62
- "typescript": "^4.9.3"
64
+ "typescript": "^5.7.2"
63
65
  },
66
+ "//": "Pin int64-napi to ^1.0.2",
64
67
  "dependencies": {
65
68
  "@rclnodejs/ref-array-di": "^1.2.2",
66
69
  "@rclnodejs/ref-napi": "^4.0.0",
67
70
  "@rclnodejs/ref-struct-di": "^1.1.1",
68
71
  "array.prototype.flat": "^1.3.2",
69
72
  "bindings": "^1.5.0",
70
- "compare-versions": "^6.1.0",
71
- "debug": "^4.3.4",
73
+ "compare-versions": "^6.1.1",
74
+ "debug": "^4.4.0",
72
75
  "dot": "^1.1.3",
73
76
  "dtslint": "^4.2.1",
74
- "fs-extra": "^11.1.1",
77
+ "fs-extra": "^11.2.0",
75
78
  "int64-napi": "^1.0.2",
76
79
  "is-close": "^1.3.3",
77
80
  "mkdirp": "^3.0.1",
78
81
  "mz": "^2.7.0",
79
- "nan": "^2.17.0",
80
- "rimraf": "^5.0.1",
81
- "uuid": "^9.0.0",
82
- "walk": "^2.3.15"
82
+ "nan": "^2.22.0",
83
+ "rimraf": "^6.0.1",
84
+ "uuid": "^11.0.3",
85
+ "walk": "^2.3.15",
86
+ "prettier": "^3.4.2"
83
87
  },
84
88
  "husky": {
85
89
  "hooks": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rosidl-generator",
3
- "version": "0.3.9",
3
+ "version": "0.4.0",
4
4
  "description": "Generate JavaScript object from ROS IDL(.msg) files",
5
5
  "main": "index.js",
6
6
  "authors": [
@@ -15,6 +15,7 @@
15
15
  'use strict';
16
16
 
17
17
  const dot = require('dot');
18
+ const prettier = require('prettier');
18
19
  const fse = require('fs-extra');
19
20
  const path = require('path');
20
21
  const parser = require('../rosidl_parser/rosidl_parser.js');
@@ -23,6 +24,7 @@ const DistroUtils = require('../lib/distro.js');
23
24
 
24
25
  dot.templateSettings.strip = false;
25
26
  dot.log = process.env.RCLNODEJS_LOG_VERBOSE || false;
27
+ const isDebug = !!process.argv.find((arg) => arg === '--debug');
26
28
  const dots = dot.process({
27
29
  path: path.join(__dirname, '../rosidl_gen/templates'),
28
30
  });
@@ -39,6 +41,9 @@ function removeEmptyLines(str) {
39
41
  * @param {string} code
40
42
  */
41
43
  async function writeGeneratedCode(dir, fileName, code) {
44
+ if (fileName.endsWith('.js')) {
45
+ code = await prettier.format(code, { parser: 'babel' });
46
+ }
42
47
  await fse.mkdirs(dir);
43
48
  await fse.writeFile(path.join(dir, fileName), code);
44
49
  }
@@ -119,6 +124,7 @@ async function generateServiceEventJSStruct(msgInfo, dir) {
119
124
  messageInfo: msgInfo,
120
125
  spec: spec,
121
126
  json: JSON.stringify(spec, null, ' '),
127
+ isDebug: isDebug,
122
128
  })
123
129
  );
124
130
 
@@ -148,6 +154,7 @@ function generateMessageJSStructFromSpec(messageInfo, dir, spec) {
148
154
  messageInfo: messageInfo,
149
155
  spec: spec,
150
156
  json: JSON.stringify(spec, null, ' '),
157
+ isDebug: isDebug,
151
158
  })
152
159
  );
153
160
  return writeGeneratedCode(dir, fileName, generatedCode);
@@ -149,7 +149,10 @@ function toPlainObject(message, enableTypedArray = true) {
149
149
  // TODO(Kenny): make sure Int64 & Uint64 type can be copied here
150
150
  obj[name] = message[name];
151
151
  }
152
- } else if (def.fields[i].type.isArray && def.fields[i].type.type === 'Constants') {
152
+ } else if (
153
+ def.fields[i].type.isArray &&
154
+ def.fields[i].type.type === 'Constants'
155
+ ) {
153
156
  // For a constants array, because its field is empty we just return an empty array here.
154
157
  obj[name] = [];
155
158
  } else {
@@ -148,10 +148,10 @@ async function generateMsgForSrv(filePath, interfaceInfo, pkgMap) {
148
148
  await fsp.writeFile(path.join(packagePath, responseMsgName), arr[1]);
149
149
  let requestInfo = Object.assign({}, interfaceInfo);
150
150
  requestInfo.filePath = path.join(packagePath, requestMsgName);
151
- requestInfo.interfaceName = requestInfo.interfaceName + "_Request"
151
+ requestInfo.interfaceName = requestInfo.interfaceName + '_Request';
152
152
  let responseInfo = Object.assign({}, interfaceInfo);
153
153
  responseInfo.filePath = path.join(packagePath, responseMsgName);
154
- responseInfo.interfaceName = responseInfo.interfaceName + "_Response"
154
+ responseInfo.interfaceName = responseInfo.interfaceName + '_Response';
155
155
 
156
156
  addInterfaceInfo(requestInfo, 'messages', pkgMap);
157
157
  addInterfaceInfo(responseInfo, 'messages', pkgMap);
@@ -199,7 +199,7 @@ async function findAmentPackagesInDirectory(dir) {
199
199
  const rosFiles = Array.prototype.flat ? files.flat() : flat(files);
200
200
  const pkgMap = new Map();
201
201
  await Promise.all(
202
- rosFiles.map(filePath => addInterfaceInfos(filePath, dir, pkgMap))
202
+ rosFiles.map((filePath) => addInterfaceInfos(filePath, dir, pkgMap))
203
203
  );
204
204
  return pkgMap;
205
205
  }
@@ -28,14 +28,14 @@ const StringRefStruct = StructType({
28
28
 
29
29
  function initString(str, own = false) {
30
30
  if (own) {
31
- if (!str instanceof Buffer) {
31
+ if ((!str) instanceof Buffer) {
32
32
  throw new TypeError(
33
33
  'Invalid argument: should provide a Node Buffer to bindingsStringInit()'
34
34
  );
35
35
  }
36
36
  rclnodejs.initString(str);
37
37
  } else {
38
- if (!str instanceof StringRefStruct) {
38
+ if ((!str) instanceof StringRefStruct) {
39
39
  throw new TypeError(
40
40
  'Invalid argument: should provide a type of StringRefStruct'
41
41
  );