Skip to main content
Version: v0.1.0

Transport adapters

The WebSocket, SSE, and ROS adapters share a similar shape: you pass a connection URL, a chunk callback, and optionally an error handler, and get back a stop function. The quantized adapter takes a WebSocket instance and a schema instead. Call the stop function to disconnect.

import {
createWebSocketAdapter,
createSSEAdapter,
createRosbridgeAdapter,
createQuantizedAdapter,
mergeChunkStreams,
withSourceTag,
} from "pointflow";

createWebSocketAdapter​

Connects to a WebSocket and calls onChunk for each message that parses as a valid PointChunk.

const stop = createWebSocketAdapter(
url: string,
onChunk: (chunk: PointChunk) => void,
onError?: (event: Event) => void,
): () => void;

Non-chunk messages (JSON that doesn't match the PointChunk shape, or non-JSON frames) are silently ignored.


createSSEAdapter​

Connects to a Server-Sent Events endpoint. Each data: event should carry a JSON-encoded PointChunk.

const stop = createSSEAdapter(
url: string,
onChunk: (chunk: PointChunk) => void,
onError?: (error: Error) => void,
): () => void;

createRosbridgeAdapter​

Subscribes to a ROS topic via rosbridge v2 WebSocket protocol and translates sensor_msgs/PointCloud2 messages.

const stop = createRosbridgeAdapter(
wsUrl: string,
topic: string,
options: {
fields?: Record<string, string>; // ROS field name → PointFlow attribute key
onChunk: (chunk: PointChunk) => void;
onError?: (event: Event) => void;
},
): () => void;

x, y, z are always extracted. Other fields need to be listed in fields.


createQuantizedAdapter​

Decodes compact binary WebSocket messages. Each point is 6 bytes (3 × uint16 XYZ) vs 12 bytes for float32.

const stop = createQuantizedAdapter(
ws: WebSocket,
schema: {
attributes: Array<{
key: string;
min: number;
max: number;
}>;
},
onChunk: (chunk: PointChunk) => void,
): () => void;

The attributes array must match the server's channel order. Each attribute is dequantized with value = min + (uint16 / 65535) × (max - min).

Calling stop() detaches the listener. It does NOT close the WebSocket — you're responsible for that.


mergeChunkStreams​

Fans in multiple chunk sources into one emit callback:

import { mergeChunkStreams } from "pointflow";

const stop = mergeChunkStreams([sourceA, sourceB], emit);
// call stop() to disconnect all sources

sources is an array of ChunkSourceFactory functions (each takes an emit callback and returns an unsubscribe). emit is the ChunkEmitter you want all sources to feed into. Returns an unsubscribe that stops all sources at once.


withSourceTag​

Wraps an emit callback to stamp a sourceId onto each chunk it receives:

import { withSourceTag } from "pointflow";

const taggedEmit = withSourceTag("lidar-front", emit);
adapter.connect(taggedEmit);

The first argument is the source ID string. The second is the ChunkEmitter to wrap. Returns a new ChunkEmitter that forwards chunks with sourceId set (won't overwrite an existing sourceId).


detectWebGPUSupport​

Asynchronous WebGPU capability check:

import { detectWebGPUSupport } from "pointflow";

const available: boolean = await detectWebGPUSupport();

detectWebGPUSync​

Synchronous check (less accurate — prefer detectWebGPUSupport when you can await):

import { detectWebGPUSync } from "pointflow";

const available = detectWebGPUSync();

detectSabSupport​

Checks SharedArrayBuffer availability (needed for some high-perf transfer paths):

import { detectSabSupport } from "pointflow";

const { available, crossOriginIsolated, message } = detectSabSupport();
// available: boolean
// crossOriginIsolated: boolean — whether COOP/COEP headers are set
// message: string — human-readable explanation