Skip to content

Conversation

@mahmoud-ghalayini
Copy link
Collaborator

@mahmoud-ghalayini mahmoud-ghalayini commented Oct 22, 2025

Public API Changes

New subscription option:

  • serializationMode: 'default' | 'plain' | 'json' for createSubscription()

New utility functions:

  • rclnodejs.toJSONSafe(obj) - makes objects JSON-friendly
  • rclnodejs.toJSONString(obj) - converts directly to JSON string

Fully backward compatible - existing code works unchanged.

Description

This adds message serialization modes to fix a common headache: ROS sensor messages use TypedArrays which don't play nice with JSON.

The Problem:
If you try to JSON.stringify() a LaserScan message, you get {} instead of the actual data. This breaks web APIs, logging, and any workflow that needs JSON.

The Solution:
Three modes to handle messages differently:

  • 'default' Uses native rclnodejs behavior
  • 'plain': Convert TypedArrays to regular arrays - JSON works!
  • 'json': Handle everything (TypedArrays, BigInt, NaN) - fully JSON-safe

#1307

Closes RobotWebTools#1307

- Add SerializationMode type ('typed' | 'plain' | 'json')
- Implement message_serialization.js with conversion utilities
- Add serializationMode option to createSubscription
- Export toJSONSafe and toJSONString utility functions
@coveralls
Copy link

coveralls commented Oct 22, 2025

Coverage Status

coverage: 81.795% (-0.8%) from 82.578%
when pulling e6d7df4 on mahmoudalghalayini:feat-add-json-safe-serialization-modes-1307
into c8f0ae6 on RobotWebTools:develop.

@minggangw
Copy link
Member

@mahmoudalghalayini thanks for submitting the PR with ut and examples, that's great! The overall looks good to me, I will be oof for the rest of the week and will take a closer look early next week. Meanwhile, please feel free to take what we disscussed in #1306, thanks!

this._callback(msg.toPlainObject(this.typedArrayEnabled));
let message = msg.toPlainObject(this.typedArrayEnabled);

if (this._serializationMode !== 'typed') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some concern about the naming typed here, considering when:

  1. this.typedArrayEnabled is false
  2. this._serializationMode is typed

The message may contain plain array even if the array can be typed-array, which may cause confusing.

When typedArrayEnabled is true, rclnodejs won't allocate additional memory from C++ side, instead, the typed array is backed by a Buffer if possible, whose memory was allocated by rcl, but I don't have a proper name in my mind now.

@@ -0,0 +1,41 @@
// Copyright (c) 2024 rclnodejs contributors. All rights reserved.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer unifying the wording here, you can either:

  1. Add your name, like https://github.com/RobotWebTools/rclnodejs/blob/develop/lib/parameter_service.js
  2. Use a general name, like https://github.com/RobotWebTools/rclnodejs/blob/develop/lib/utils.js

It's up to you. nit: it's year of 2025 already :)

Copy link
Member

@minggangw minggangw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks for submitting the PR!

* @param {boolean} options.enableTypedArray - The topic will use TypedArray if necessary, default: true.
* @param {QoS} options.qos - ROS Middleware "quality of service" settings for the subscription, default: QoS.profileDefault.
* @param {boolean} options.isRaw - The topic is serialized when true, default: false.
* @param {string} [options.serializationMode='default'] - Controls message serialization format:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default makes sence to combine with enableTypedArray

@minggangw minggangw merged commit 525fba1 into RobotWebTools:develop Oct 27, 2025
18 checks passed
minggangw pushed a commit that referenced this pull request Oct 30, 2025
## **Public API Changes**

**New subscription option:**
- `serializationMode: 'default' | 'plain' | 'json'` for `createSubscription()`

**New utility functions:**  
- `rclnodejs.toJSONSafe(obj)` - makes objects JSON-friendly
- `rclnodejs.toJSONString(obj)` - converts directly to JSON string

**Fully backward compatible** - existing code works unchanged.

## **Description**

This adds **message serialization modes** to fix a common headache: ROS sensor messages use `TypedArray`s which don't play nice with JSON.

**The Problem:**
If you try to `JSON.stringify()` a LaserScan message, you get `{}` instead of the actual data. This breaks web APIs, logging, and any workflow that needs JSON.

**The Solution:**
Three modes to handle messages differently:

- **`'default'`** Uses native rclnodejs behavior
- **`'plain'`**: Convert TypedArrays to regular arrays - JSON works!  
- **`'json'`**: Handle everything (TypedArrays, BigInt, NaN) - fully JSON-safe


[#1307](#1307)
@minggangw
Copy link
Member

@mahmoud-ghalayini this change has landed onto latest v1.6.0, thanks for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants