Subscribe to a remote producer (TypeScript)

client.subscribe(path, handler) writes a SUBSCRIBER into the producer’s :subscribers[], and every later write to the producer is delivered to the handler.

The node on the other end is stand-in-node.mjs, an in-memory stand-in. The TypeScript packages have no node of their own, and the stand-in lets the example run with no C++ build. Against a real node the client code is unchanged.

What to notice

  • Two clients, one node. The consumer subscribes and a second client writes. The deliveries arrive in write order.

  • unsubscribe() is a local detach. It stops the handler firing; it does not clear the remote slot.

  • The handler is registered before the ack. A producer may deliver before its subscribe reply arrives, and the client does not drop that delivery.

Source

 1// SPDX-License-Identifier: Apache-2.0
 2// SPDX-FileCopyrightText: Copyright 2026 avatarsd LLC
 3
 4/**
 5 * @file
 6 * @brief One concept: subscribe to a remote producer. Subscribing is itself a write —
 7 * a SUBSCRIBER into `/sensor/temp:subscribers[]` — and each later write to the producer
 8 * arrives as a delivery to the handler.
 9 *
10 * Run: `node examples/subscribe.mjs` (from `bindings/typescript/`, after `npm run build`).
11 */
12
13import assert from 'node:assert/strict';
14import { LibtracerClient, encodeValue } from '@avatarsd-llc/libtracer-client';
15import { standInNode } from './stand-in-node.mjs';
16
17const node = standInNode();
18const consumer = new LibtracerClient(node.loopback());
19const producer = new LibtracerClient(node.loopback());
20
21// The handler fires inline, once per delivered VALUE.
22const seen = [];
23const unsubscribe = await consumer.subscribe('/sensor/temp', (value) => seen.push(value[0]));
24console.log('subscribed to /sensor/temp');
25
26// Two writes by another client -> two deliveries, in order.
27await producer.write('/sensor/temp', encodeValue(Uint8Array.of(20)));
28await producer.write('/sensor/temp', encodeValue(Uint8Array.of(21)));
29assert.deepEqual(seen, [20, 21]);
30console.log(`delivered: ${seen.join(', ')}`);
31
32// unsubscribe() is a local detach: the handler stops firing.
33unsubscribe();
34await producer.write('/sensor/temp', encodeValue(Uint8Array.of(22)));
35assert.deepEqual(seen, [20, 21]);
36console.log('after unsubscribe: nothing more delivered');

Run it from bindings/typescript/, after npm ci && npm run build:

$ node examples/subscribe.mjs

See also: subscribe to one vertex (C++) · Rust: subscribing is a write.