rclnodejs 1.5.2 → 1.7.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/index.js +79 -3
- package/lib/action/client.js +55 -9
- package/lib/action/deferred.js +8 -2
- package/lib/action/server.js +10 -1
- package/lib/action/uuid.js +4 -1
- package/lib/client.js +152 -3
- package/lib/clock.js +4 -1
- package/lib/context.js +12 -2
- package/lib/duration.js +37 -12
- package/lib/errors.js +571 -0
- package/lib/event_handler.js +21 -4
- package/lib/interface_loader.js +52 -12
- package/lib/lifecycle.js +8 -2
- package/lib/logging.js +12 -3
- package/lib/message_serialization.js +179 -0
- package/lib/native_loader.js +9 -4
- package/lib/node.js +283 -47
- package/lib/parameter.js +176 -45
- package/lib/parameter_client.js +506 -0
- package/lib/parameter_watcher.js +309 -0
- package/lib/qos.js +22 -5
- package/lib/rate.js +6 -1
- package/lib/serialization.js +7 -2
- package/lib/subscription.js +16 -1
- package/lib/time.js +136 -21
- package/lib/time_source.js +13 -4
- package/lib/utils.js +313 -0
- package/lib/validator.js +11 -12
- package/package.json +2 -7
- package/prebuilds/linux-arm64/humble-jammy-arm64-rclnodejs.node +0 -0
- package/prebuilds/linux-arm64/jazzy-noble-arm64-rclnodejs.node +0 -0
- package/prebuilds/linux-arm64/kilted-noble-arm64-rclnodejs.node +0 -0
- package/prebuilds/linux-x64/humble-jammy-x64-rclnodejs.node +0 -0
- package/prebuilds/linux-x64/jazzy-noble-x64-rclnodejs.node +0 -0
- package/prebuilds/linux-x64/kilted-noble-x64-rclnodejs.node +0 -0
- package/rosidl_convertor/idl_convertor.js +3 -2
- package/rosidl_gen/generate_worker.js +1 -1
- package/rosidl_gen/idl_generator.js +11 -24
- package/rosidl_gen/index.js +1 -1
- package/rosidl_gen/templates/action-template.js +68 -0
- package/rosidl_gen/templates/message-template.js +1113 -0
- package/rosidl_gen/templates/service-event-template.js +31 -0
- package/rosidl_gen/templates/service-template.js +44 -0
- package/rosidl_parser/rosidl_parser.js +2 -2
- package/third_party/ref-napi/lib/ref.js +0 -45
- package/types/base.d.ts +3 -0
- package/types/client.d.ts +36 -0
- package/types/errors.d.ts +447 -0
- package/types/index.d.ts +17 -0
- package/types/interfaces.d.ts +1910 -1
- package/types/node.d.ts +56 -1
- package/types/parameter_client.d.ts +252 -0
- package/types/parameter_watcher.d.ts +104 -0
- package/rosidl_gen/templates/CMakeLists.dot +0 -40
- package/rosidl_gen/templates/action.dot +0 -50
- package/rosidl_gen/templates/message.dot +0 -851
- package/rosidl_gen/templates/package.dot +0 -16
- package/rosidl_gen/templates/service.dot +0 -26
- package/rosidl_gen/templates/service_event.dot +0 -10
package/lib/validator.js
CHANGED
|
@@ -15,16 +15,15 @@
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
17
|
const rclnodejs = require('./native_loader.js');
|
|
18
|
+
const { TypeValidationError, NameValidationError } = require('./errors.js');
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* An object - Representing a validator in ROS.
|
|
21
22
|
* @exports validator
|
|
22
23
|
*/
|
|
23
24
|
let validator = {
|
|
24
|
-
_createErrorFromValidation: function (result) {
|
|
25
|
-
|
|
26
|
-
err.invalidIndex = result[1];
|
|
27
|
-
return err;
|
|
25
|
+
_createErrorFromValidation: function (result, nameValue, nameType) {
|
|
26
|
+
return new NameValidationError(nameValue, nameType, result[0], result[1]);
|
|
28
27
|
},
|
|
29
28
|
|
|
30
29
|
/**
|
|
@@ -34,14 +33,14 @@ let validator = {
|
|
|
34
33
|
*/
|
|
35
34
|
validateFullTopicName(topic) {
|
|
36
35
|
if (typeof topic !== 'string') {
|
|
37
|
-
throw new
|
|
36
|
+
throw new TypeValidationError('topic', topic, 'string');
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
let result = rclnodejs.validateFullTopicName(topic);
|
|
41
40
|
if (result === null) {
|
|
42
41
|
return true;
|
|
43
42
|
}
|
|
44
|
-
throw this._createErrorFromValidation(result);
|
|
43
|
+
throw this._createErrorFromValidation(result, topic, 'topic');
|
|
45
44
|
},
|
|
46
45
|
|
|
47
46
|
/**
|
|
@@ -51,14 +50,14 @@ let validator = {
|
|
|
51
50
|
*/
|
|
52
51
|
validateNodeName(name) {
|
|
53
52
|
if (typeof name !== 'string') {
|
|
54
|
-
throw new
|
|
53
|
+
throw new TypeValidationError('name', name, 'string');
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
let result = rclnodejs.validateNodeName(name);
|
|
58
57
|
if (result === null) {
|
|
59
58
|
return true;
|
|
60
59
|
}
|
|
61
|
-
throw this._createErrorFromValidation(result);
|
|
60
|
+
throw this._createErrorFromValidation(result, name, 'node');
|
|
62
61
|
},
|
|
63
62
|
|
|
64
63
|
/**
|
|
@@ -68,14 +67,14 @@ let validator = {
|
|
|
68
67
|
*/
|
|
69
68
|
validateTopicName(topic) {
|
|
70
69
|
if (typeof topic !== 'string') {
|
|
71
|
-
throw new
|
|
70
|
+
throw new TypeValidationError('topic', topic, 'string');
|
|
72
71
|
}
|
|
73
72
|
|
|
74
73
|
let result = rclnodejs.validateTopicName(topic);
|
|
75
74
|
if (result === null) {
|
|
76
75
|
return true;
|
|
77
76
|
}
|
|
78
|
-
throw this._createErrorFromValidation(result);
|
|
77
|
+
throw this._createErrorFromValidation(result, topic, 'topic');
|
|
79
78
|
},
|
|
80
79
|
|
|
81
80
|
/**
|
|
@@ -85,14 +84,14 @@ let validator = {
|
|
|
85
84
|
*/
|
|
86
85
|
validateNamespace(namespace) {
|
|
87
86
|
if (typeof namespace !== 'string') {
|
|
88
|
-
throw new
|
|
87
|
+
throw new TypeValidationError('namespace', namespace, 'string');
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
let result = rclnodejs.validateNamespace(namespace);
|
|
92
91
|
if (result === null) {
|
|
93
92
|
return true;
|
|
94
93
|
}
|
|
95
|
-
throw this._createErrorFromValidation(result);
|
|
94
|
+
throw this._createErrorFromValidation(result, namespace, 'namespace');
|
|
96
95
|
},
|
|
97
96
|
};
|
|
98
97
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rclnodejs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "ROS2.0 JavaScript client with Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"rebuild:dev": "npm run clean && node-gyp -j 16 rebuild --debug",
|
|
20
20
|
"generate-messages": "node scripts/generate_messages.js",
|
|
21
21
|
"generate-messages-idl": "node scripts/generate_messages.js --idl",
|
|
22
|
-
"generate-messages:dev": "node scripts/generate_messages.js --debug
|
|
22
|
+
"generate-messages:dev": "node scripts/generate_messages.js --debug",
|
|
23
23
|
"generate-tsd-messages": "node scripts/generate_tsd.js",
|
|
24
24
|
"clean": "node-gyp clean && npx rimraf ./generated",
|
|
25
25
|
"install": "node scripts/install.js",
|
|
@@ -76,14 +76,9 @@
|
|
|
76
76
|
"@rclnodejs/ref-array-di": "^1.2.2",
|
|
77
77
|
"@rclnodejs/ref-struct-di": "^1.1.1",
|
|
78
78
|
"bindings": "^1.5.0",
|
|
79
|
-
"compare-versions": "^6.1.1",
|
|
80
79
|
"debug": "^4.4.0",
|
|
81
|
-
"dot": "^1.1.3",
|
|
82
|
-
"fs-extra": "^11.2.0",
|
|
83
|
-
"is-close": "^1.3.3",
|
|
84
80
|
"json-bigint": "^1.0.0",
|
|
85
81
|
"node-addon-api": "^8.3.1",
|
|
86
|
-
"terser": "^5.39.0",
|
|
87
82
|
"walk": "^2.3.15"
|
|
88
83
|
},
|
|
89
84
|
"husky": {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -14,15 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
+
const fs = require('fs');
|
|
17
18
|
const path = require('path');
|
|
18
|
-
const fse = require('
|
|
19
|
+
const fse = require('../lib/utils.js');
|
|
19
20
|
const execFile = require('child_process').execFile;
|
|
20
21
|
const pythonExecutable =
|
|
21
22
|
require('../rosidl_parser/py_utils').getPythonExecutable('python3');
|
|
22
23
|
|
|
23
24
|
async function convertIDLToROS2IDL(pkgName, idlFilePath, outputDir) {
|
|
24
25
|
const packagePath = path.join(outputDir, pkgName);
|
|
25
|
-
if (!
|
|
26
|
+
if (!fs.existsSync(packagePath)) {
|
|
26
27
|
fse.mkdirSync(packagePath);
|
|
27
28
|
}
|
|
28
29
|
return new Promise((resolve, reject) => {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
|
-
const fse = require('
|
|
15
|
+
const fse = require('../lib/utils.js');
|
|
16
16
|
const generateJSStructFromIDL = require('./idl_generator.js');
|
|
17
17
|
const packages = require('./packages.js');
|
|
18
18
|
const path = require('path');
|
|
@@ -14,20 +14,17 @@
|
|
|
14
14
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
const { minify } = require('terser');
|
|
19
|
-
const fse = require('fs-extra');
|
|
17
|
+
const fse = require('../lib/utils.js');
|
|
20
18
|
const path = require('path');
|
|
21
19
|
const parser = require('../rosidl_parser/rosidl_parser.js');
|
|
22
20
|
const actionMsgs = require('./action_msgs.js');
|
|
23
21
|
const DistroUtils = require('../lib/distro.js');
|
|
22
|
+
const generateMessage = require('./templates/message-template.js');
|
|
23
|
+
const generateService = require('./templates/service-template.js');
|
|
24
|
+
const generateAction = require('./templates/action-template.js');
|
|
25
|
+
const generateServiceEvent = require('./templates/service-event-template.js');
|
|
24
26
|
|
|
25
|
-
dot.templateSettings.strip = false;
|
|
26
|
-
dot.log = process.env.RCLNODEJS_LOG_VERBOSE || false;
|
|
27
27
|
const isDebug = !!process.argv.find((arg) => arg === '--debug');
|
|
28
|
-
const dots = dot.process({
|
|
29
|
-
path: path.join(__dirname, '../rosidl_gen/templates'),
|
|
30
|
-
});
|
|
31
28
|
|
|
32
29
|
/**
|
|
33
30
|
* Output generated code to disk. Do not overwrite
|
|
@@ -37,18 +34,8 @@ const dots = dot.process({
|
|
|
37
34
|
* @param {string} code
|
|
38
35
|
*/
|
|
39
36
|
async function writeGeneratedCode(dir, fileName, code) {
|
|
40
|
-
let result = null;
|
|
41
|
-
if (!isDebug && fileName.endsWith('.js')) {
|
|
42
|
-
try {
|
|
43
|
-
result = await minify(code);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
console.error(`Error minifying ${fileName}:`, error);
|
|
46
|
-
result = null;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
37
|
await fse.mkdirs(dir);
|
|
51
|
-
await fse.writeFile(path.join(dir, fileName),
|
|
38
|
+
await fse.writeFile(path.join(dir, fileName), code.replace(/^\s*\n/gm, ''));
|
|
52
39
|
}
|
|
53
40
|
|
|
54
41
|
async function generateServiceJSStruct(
|
|
@@ -64,7 +51,7 @@ async function generateServiceJSStruct(
|
|
|
64
51
|
'__' +
|
|
65
52
|
serviceInfo.interfaceName +
|
|
66
53
|
'.js';
|
|
67
|
-
const generatedSrvCode =
|
|
54
|
+
const generatedSrvCode = generateService({ serviceInfo: serviceInfo });
|
|
68
55
|
|
|
69
56
|
// We are going to only generate the service JavaScript file if it meets one
|
|
70
57
|
// of the followings:
|
|
@@ -85,7 +72,7 @@ async function generateServiceJSStruct(
|
|
|
85
72
|
|
|
86
73
|
async function generateServiceEventMsg(serviceInfo, dir) {
|
|
87
74
|
const fileName = serviceInfo.interfaceName + '.msg';
|
|
88
|
-
const generatedEvent =
|
|
75
|
+
const generatedEvent = generateServiceEvent({ serviceInfo: serviceInfo });
|
|
89
76
|
|
|
90
77
|
return writeGeneratedCode(dir, fileName, generatedEvent).then(() => {
|
|
91
78
|
serviceInfo.interfaceName += '_Event';
|
|
@@ -118,7 +105,7 @@ async function generateServiceEventJSStruct(msgInfo, dir) {
|
|
|
118
105
|
// const AddTwoInts_RequestWrapper = require('../../generated/example_interfaces/example_interfaces__srv__AddTwoInts_Request.js');
|
|
119
106
|
// const AddTwoInts_ResponseWrapper = require('../../generated/example_interfaces/example_interfaces__srv__AddTwoInts_Response.js');
|
|
120
107
|
msgInfo.isServiceEvent = true;
|
|
121
|
-
const generatedCode =
|
|
108
|
+
const generatedCode = generateMessage({
|
|
122
109
|
messageInfo: msgInfo,
|
|
123
110
|
spec: spec,
|
|
124
111
|
json: JSON.stringify(spec, null, ' '),
|
|
@@ -146,7 +133,7 @@ function generateMessageJSStructFromSpec(messageInfo, dir, spec) {
|
|
|
146
133
|
spec.msgName +
|
|
147
134
|
'.js';
|
|
148
135
|
|
|
149
|
-
const generatedCode =
|
|
136
|
+
const generatedCode = generateMessage({
|
|
150
137
|
messageInfo: messageInfo,
|
|
151
138
|
spec: spec,
|
|
152
139
|
json: JSON.stringify(spec, null, ' '),
|
|
@@ -286,7 +273,7 @@ async function generateActionJSStruct(actionInfo, dir) {
|
|
|
286
273
|
'__' +
|
|
287
274
|
actionInfo.interfaceName +
|
|
288
275
|
'.js';
|
|
289
|
-
const generatedCode =
|
|
276
|
+
const generatedCode = generateAction({ actionInfo: actionInfo });
|
|
290
277
|
dir = path.join(dir, actionInfo.pkgName);
|
|
291
278
|
const action = writeGeneratedCode(dir, fileName, generatedCode);
|
|
292
279
|
|
package/rosidl_gen/index.js
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
function generateAction(data) {
|
|
16
|
+
const actionInfo = data.actionInfo;
|
|
17
|
+
const className = `${actionInfo.pkgName}__${actionInfo.subFolder}__${actionInfo.interfaceName}`;
|
|
18
|
+
|
|
19
|
+
return `// This file is automatically generated by rclnodejs
|
|
20
|
+
//
|
|
21
|
+
// *** DO NOT EDIT directly
|
|
22
|
+
//
|
|
23
|
+
|
|
24
|
+
'use strict';
|
|
25
|
+
|
|
26
|
+
class ${className} {
|
|
27
|
+
static get Goal() {
|
|
28
|
+
return require('./${className}_Goal.js');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static get Result() {
|
|
32
|
+
return require('./${className}_Result.js');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static get Feedback() {
|
|
36
|
+
return require('./${className}_Feedback.js');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static get impl() {
|
|
40
|
+
return {
|
|
41
|
+
get SendGoalService() {
|
|
42
|
+
return require('./${className}_SendGoal.js');
|
|
43
|
+
},
|
|
44
|
+
get GetResultService() {
|
|
45
|
+
return require('./${className}_GetResult.js');
|
|
46
|
+
},
|
|
47
|
+
get FeedbackMessage() {
|
|
48
|
+
return require('./${className}_FeedbackMessage.js');
|
|
49
|
+
},
|
|
50
|
+
get CancelGoal() {
|
|
51
|
+
return require('../action_msgs/action_msgs__srv__CancelGoal.js');
|
|
52
|
+
},
|
|
53
|
+
get GoalStatusArray() {
|
|
54
|
+
return require('../action_msgs/action_msgs__msg__GoalStatusArray.js');
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static type() {
|
|
60
|
+
return {pkgName: '${actionInfo.pkgName}', subFolder: '${actionInfo.subFolder}', interfaceName: '${actionInfo.interfaceName}'};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = ${className};
|
|
65
|
+
`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = generateAction;
|