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/parameter.js
CHANGED
|
@@ -19,7 +19,13 @@
|
|
|
19
19
|
|
|
20
20
|
'use strict';
|
|
21
21
|
|
|
22
|
-
const
|
|
22
|
+
const { isClose } = require('./utils.js');
|
|
23
|
+
const {
|
|
24
|
+
TypeValidationError,
|
|
25
|
+
RangeValidationError,
|
|
26
|
+
ParameterError,
|
|
27
|
+
ParameterTypeError,
|
|
28
|
+
} = require('./errors.js');
|
|
23
29
|
|
|
24
30
|
/**
|
|
25
31
|
* The plus/minus tolerance for determining number equivalence.
|
|
@@ -184,17 +190,25 @@ class Parameter {
|
|
|
184
190
|
typeof this.name !== 'string' ||
|
|
185
191
|
this.name.trim().length === 0
|
|
186
192
|
) {
|
|
187
|
-
throw new
|
|
193
|
+
throw new TypeValidationError('name', this.name, 'non-empty string', {
|
|
194
|
+
entityType: 'parameter',
|
|
195
|
+
});
|
|
188
196
|
}
|
|
189
197
|
|
|
190
198
|
// validate type
|
|
191
199
|
if (!validType(this.type)) {
|
|
192
|
-
throw new
|
|
200
|
+
throw new ParameterError('Invalid parameter type', this.name, {
|
|
201
|
+
details: { providedType: this.type },
|
|
202
|
+
});
|
|
193
203
|
}
|
|
194
204
|
|
|
195
205
|
// validate value
|
|
196
206
|
if (!validValue(this.value, this.type)) {
|
|
197
|
-
throw new
|
|
207
|
+
throw new ParameterTypeError(this.name, this.type, typeof this.value, {
|
|
208
|
+
details: {
|
|
209
|
+
providedValue: this.value,
|
|
210
|
+
},
|
|
211
|
+
});
|
|
198
212
|
}
|
|
199
213
|
|
|
200
214
|
this._dirty = false;
|
|
@@ -383,10 +397,23 @@ class ParameterDescriptor {
|
|
|
383
397
|
return;
|
|
384
398
|
}
|
|
385
399
|
if (!(range instanceof Range)) {
|
|
386
|
-
throw
|
|
400
|
+
throw new TypeValidationError('range', range, 'Range', {
|
|
401
|
+
entityType: 'parameter descriptor',
|
|
402
|
+
parameterName: this.name,
|
|
403
|
+
});
|
|
387
404
|
}
|
|
388
405
|
if (!range.isValidType(this.type)) {
|
|
389
|
-
throw
|
|
406
|
+
throw new ParameterError(
|
|
407
|
+
'Incompatible Range for parameter type',
|
|
408
|
+
this.name,
|
|
409
|
+
{
|
|
410
|
+
entityType: 'parameter descriptor',
|
|
411
|
+
details: {
|
|
412
|
+
rangeType: range.constructor.name,
|
|
413
|
+
parameterType: this.type,
|
|
414
|
+
},
|
|
415
|
+
}
|
|
416
|
+
);
|
|
390
417
|
}
|
|
391
418
|
|
|
392
419
|
this._range = range;
|
|
@@ -405,22 +432,40 @@ class ParameterDescriptor {
|
|
|
405
432
|
typeof this.name !== 'string' ||
|
|
406
433
|
this.name.trim().length === 0
|
|
407
434
|
) {
|
|
408
|
-
throw new
|
|
435
|
+
throw new TypeValidationError('name', this.name, 'non-empty string', {
|
|
436
|
+
entityType: 'parameter descriptor',
|
|
437
|
+
});
|
|
409
438
|
}
|
|
410
439
|
|
|
411
440
|
// validate type
|
|
412
441
|
if (!validType(this.type)) {
|
|
413
|
-
throw new
|
|
442
|
+
throw new ParameterError('Invalid parameter type', this.name, {
|
|
443
|
+
entityType: 'parameter descriptor',
|
|
444
|
+
details: { providedType: this.type },
|
|
445
|
+
});
|
|
414
446
|
}
|
|
415
447
|
|
|
416
448
|
// validate description
|
|
417
449
|
if (this.description && typeof this.description !== 'string') {
|
|
418
|
-
throw new
|
|
450
|
+
throw new TypeValidationError('description', this.description, 'string', {
|
|
451
|
+
entityType: 'parameter descriptor',
|
|
452
|
+
parameterName: this.name,
|
|
453
|
+
});
|
|
419
454
|
}
|
|
420
455
|
|
|
421
456
|
// validate rangeConstraint
|
|
422
457
|
if (this.hasRange() && !this.range.isValidType(this.type)) {
|
|
423
|
-
throw new
|
|
458
|
+
throw new ParameterError(
|
|
459
|
+
'Incompatible Range for parameter type',
|
|
460
|
+
this.name,
|
|
461
|
+
{
|
|
462
|
+
entityType: 'parameter descriptor',
|
|
463
|
+
details: {
|
|
464
|
+
rangeType: this.range.constructor.name,
|
|
465
|
+
parameterType: this.type,
|
|
466
|
+
},
|
|
467
|
+
}
|
|
468
|
+
);
|
|
424
469
|
}
|
|
425
470
|
}
|
|
426
471
|
|
|
@@ -433,27 +478,66 @@ class ParameterDescriptor {
|
|
|
433
478
|
*/
|
|
434
479
|
validateParameter(parameter) {
|
|
435
480
|
if (!parameter) {
|
|
436
|
-
throw new
|
|
481
|
+
throw new TypeValidationError('parameter', parameter, 'Parameter', {
|
|
482
|
+
entityType: 'parameter descriptor',
|
|
483
|
+
parameterName: this.name,
|
|
484
|
+
});
|
|
437
485
|
}
|
|
438
486
|
|
|
439
487
|
// ensure parameter is valid
|
|
440
488
|
try {
|
|
441
489
|
parameter.validate();
|
|
442
|
-
} catch {
|
|
443
|
-
throw new
|
|
490
|
+
} catch (err) {
|
|
491
|
+
throw new ParameterError('Parameter is invalid', parameter.name, {
|
|
492
|
+
cause: err,
|
|
493
|
+
details: { validationError: err.message },
|
|
494
|
+
});
|
|
444
495
|
}
|
|
445
496
|
|
|
446
497
|
// ensure this descriptor is valid
|
|
447
498
|
try {
|
|
448
499
|
this.validate();
|
|
449
|
-
} catch {
|
|
450
|
-
throw new
|
|
500
|
+
} catch (err) {
|
|
501
|
+
throw new ParameterError('Descriptor is invalid', this.name, {
|
|
502
|
+
entityType: 'parameter descriptor',
|
|
503
|
+
cause: err,
|
|
504
|
+
details: { validationError: err.message },
|
|
505
|
+
});
|
|
451
506
|
}
|
|
452
507
|
|
|
453
|
-
if (this.name !== parameter.name)
|
|
454
|
-
|
|
508
|
+
if (this.name !== parameter.name) {
|
|
509
|
+
throw new ParameterError('Name mismatch', this.name, {
|
|
510
|
+
details: {
|
|
511
|
+
descriptorName: this.name,
|
|
512
|
+
parameterName: parameter.name,
|
|
513
|
+
},
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
if (this.type !== parameter.type) {
|
|
517
|
+
throw new ParameterTypeError(this.name, this.type, parameter.type, {
|
|
518
|
+
details: {
|
|
519
|
+
expectedType: this.type,
|
|
520
|
+
actualType: parameter.type,
|
|
521
|
+
},
|
|
522
|
+
});
|
|
523
|
+
}
|
|
455
524
|
if (this.hasRange() && !this.range.inRange(parameter.value)) {
|
|
456
|
-
throw new
|
|
525
|
+
throw new RangeValidationError(
|
|
526
|
+
'value',
|
|
527
|
+
parameter.value,
|
|
528
|
+
`${this.range.fromValue} to ${this.range.toValue}`,
|
|
529
|
+
{
|
|
530
|
+
entityType: 'parameter',
|
|
531
|
+
parameterName: parameter.name,
|
|
532
|
+
details: {
|
|
533
|
+
range: {
|
|
534
|
+
from: this.range.fromValue,
|
|
535
|
+
to: this.range.toValue,
|
|
536
|
+
step: this.range.step,
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
}
|
|
540
|
+
);
|
|
457
541
|
}
|
|
458
542
|
}
|
|
459
543
|
|
|
@@ -550,7 +634,9 @@ class Range {
|
|
|
550
634
|
true
|
|
551
635
|
);
|
|
552
636
|
} else if (typeof value !== 'number' && typeof value !== 'bigint') {
|
|
553
|
-
throw new
|
|
637
|
+
throw new TypeValidationError('value', value, 'number or bigint', {
|
|
638
|
+
entityType: 'range',
|
|
639
|
+
});
|
|
554
640
|
}
|
|
555
641
|
|
|
556
642
|
return true;
|
|
@@ -623,8 +709,8 @@ class FloatingPointRange extends Range {
|
|
|
623
709
|
const max = Math.max(this.fromValue, this.toValue);
|
|
624
710
|
|
|
625
711
|
if (
|
|
626
|
-
|
|
627
|
-
|
|
712
|
+
isClose(value, min, this.tolerance) ||
|
|
713
|
+
isClose(value, max, this.tolerance)
|
|
628
714
|
) {
|
|
629
715
|
return true;
|
|
630
716
|
}
|
|
@@ -633,13 +719,7 @@ class FloatingPointRange extends Range {
|
|
|
633
719
|
}
|
|
634
720
|
if (this.step != 0.0) {
|
|
635
721
|
const distanceInSteps = Math.round((value - min) / this.step);
|
|
636
|
-
if (
|
|
637
|
-
!IsClose.isClose(
|
|
638
|
-
min + distanceInSteps * this.step,
|
|
639
|
-
value,
|
|
640
|
-
this.tolerance
|
|
641
|
-
)
|
|
642
|
-
) {
|
|
722
|
+
if (!isClose(min + distanceInSteps * this.step, value, this.tolerance)) {
|
|
643
723
|
return false;
|
|
644
724
|
}
|
|
645
725
|
}
|
|
@@ -699,30 +779,80 @@ class IntegerRange extends Range {
|
|
|
699
779
|
* @param {any} value - The value to infer it's ParameterType
|
|
700
780
|
* @returns {ParameterType} - The ParameterType that best scribes the value.
|
|
701
781
|
*/
|
|
702
|
-
// eslint-disable-next-line no-unused-vars
|
|
703
782
|
function parameterTypeFromValue(value) {
|
|
704
|
-
if (
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
if (
|
|
783
|
+
if (value === null || value === undefined) {
|
|
784
|
+
return ParameterType.PARAMETER_NOT_SET;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
if (typeof value === 'boolean') {
|
|
788
|
+
return ParameterType.PARAMETER_BOOL;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
if (typeof value === 'string') {
|
|
792
|
+
return ParameterType.PARAMETER_STRING;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
if (typeof value === 'bigint') {
|
|
796
|
+
return ParameterType.PARAMETER_INTEGER;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
if (typeof value === 'number') {
|
|
800
|
+
// Distinguish between integer and double
|
|
801
|
+
return Number.isInteger(value)
|
|
802
|
+
? ParameterType.PARAMETER_INTEGER
|
|
803
|
+
: ParameterType.PARAMETER_DOUBLE;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
// Handle TypedArrays
|
|
807
|
+
if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {
|
|
808
|
+
if (value instanceof Uint8Array) {
|
|
809
|
+
return ParameterType.PARAMETER_BYTE_ARRAY;
|
|
810
|
+
}
|
|
811
|
+
// For other typed arrays, infer from first element
|
|
709
812
|
if (value.length > 0) {
|
|
710
|
-
const
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
return ParameterType.PARAMETER_BOOL_ARRAY;
|
|
714
|
-
case ParameterType.PARAMETER_DOUBLE:
|
|
715
|
-
return ParameterType.PARAMETER_DOUBLE_ARRAY;
|
|
716
|
-
case ParameterType.PARAMETER_STRING:
|
|
717
|
-
return ParameterType.PARAMETER_STRING_ARRAY;
|
|
813
|
+
const firstType = parameterTypeFromValue(value[0]);
|
|
814
|
+
if (firstType === ParameterType.PARAMETER_INTEGER) {
|
|
815
|
+
return ParameterType.PARAMETER_INTEGER_ARRAY;
|
|
718
816
|
}
|
|
817
|
+
return ParameterType.PARAMETER_DOUBLE_ARRAY;
|
|
719
818
|
}
|
|
720
|
-
|
|
721
819
|
return ParameterType.PARAMETER_NOT_SET;
|
|
722
820
|
}
|
|
723
821
|
|
|
724
|
-
|
|
725
|
-
|
|
822
|
+
if (Array.isArray(value)) {
|
|
823
|
+
if (value.length === 0) {
|
|
824
|
+
return ParameterType.PARAMETER_NOT_SET;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
const elementType = parameterTypeFromValue(value[0]);
|
|
828
|
+
switch (elementType) {
|
|
829
|
+
case ParameterType.PARAMETER_BOOL:
|
|
830
|
+
return ParameterType.PARAMETER_BOOL_ARRAY;
|
|
831
|
+
case ParameterType.PARAMETER_INTEGER:
|
|
832
|
+
return ParameterType.PARAMETER_INTEGER_ARRAY;
|
|
833
|
+
case ParameterType.PARAMETER_DOUBLE:
|
|
834
|
+
return ParameterType.PARAMETER_DOUBLE_ARRAY;
|
|
835
|
+
case ParameterType.PARAMETER_STRING:
|
|
836
|
+
return ParameterType.PARAMETER_STRING_ARRAY;
|
|
837
|
+
default:
|
|
838
|
+
return ParameterType.PARAMETER_NOT_SET;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
// Unrecognized value type
|
|
843
|
+
throw new TypeValidationError('value', value, 'valid parameter type', {
|
|
844
|
+
entityType: 'parameter',
|
|
845
|
+
details: {
|
|
846
|
+
supportedTypes: [
|
|
847
|
+
'boolean',
|
|
848
|
+
'string',
|
|
849
|
+
'number',
|
|
850
|
+
'boolean[]',
|
|
851
|
+
'number[]',
|
|
852
|
+
'string[]',
|
|
853
|
+
],
|
|
854
|
+
},
|
|
855
|
+
});
|
|
726
856
|
}
|
|
727
857
|
|
|
728
858
|
/**
|
|
@@ -832,4 +962,5 @@ module.exports = {
|
|
|
832
962
|
FloatingPointRange,
|
|
833
963
|
IntegerRange,
|
|
834
964
|
DEFAULT_NUMERIC_RANGE_TOLERANCE,
|
|
965
|
+
parameterTypeFromValue,
|
|
835
966
|
};
|