Helios

Viewing packets

Receive and observe sACN with ViewerService.

ViewerService sits on top of a Receiver, filters selected universes, normalizes every packet to 512 slots, and delivers updates to callbacks or bounded async streams.

Minimal setup

import { ViewerService } from "@helioslx/core";
import { NodeSacnReceiver } from "@helioslx/core/node";

const viewer = new ViewerService({
  receiver: new NodeSacnReceiver({ iface: "192.168.10.20" }),
  ownsReceiver: true,
});

await viewer.start();
await viewer.setSelectedUniverses([1, 2]);

const unsubscribe = viewer.subscribe((packet) => {
  console.info(
    `universe ${packet.universe} ch1=${packet.values[0]} ` +
      `from ${packet.source.sourceName ?? packet.source.cid}`,
  );
});

// later
unsubscribe();
await viewer.close();

Callbacks vs streams

Callbacks (subscribe) run synchronously on the receive path. Keep them fast. Exceptions are isolated and logged; they do not stop delivery.

Streams (packets(capacity?)) are async iterables. They keep at most one queued packet per universe (newer replaces older). At capacity, the oldest queued packet is dropped. Slow consumers cannot block reception or grow memory without bound — check telemetry for drops and coalescing.

const stream = viewer.packets(8);

for await (const packet of stream) {
  console.info(packet.universe, packet.values[0]);
}

stream.close();

Selection and limits

MethodPurpose
setSelectedUniverses(universes)Replace membership + persist
addUniverse / removeUniverseIncremental updates
getSelectedUniverses()Current ordered selection

Defaults: streamCapacity 32, maxUniverses 256, maxListeners 256. Raise or lower them for the installation.

Ownership

Injected receivers and stores are caller-owned by default. The default memory viewer store is owned. Set ownsReceiver: true when the viewer should close the receiver.

Pair with Redis via RedisViewerStore when selection must survive restarts — see Persistence.

HTTP and TUI

On this page