Helios

API reference

Root module and Node, Redis, HTTP, and testing subpaths.

@helioslx/core is ESM-only. The root entry is runtime-neutral: contracts, scheduling, validation, and memory stores. Integrations live on explicit subpaths.

@helioslx/core

createSacnSource(options) / new SacnSource(options)

Creates an sACN output source. Construction does not start the scheduler.

Required

  • transport: OutputTransport

Optional

OptionDefaultNotes
storeMemoryOutputStoreOutput persistence
clockSystemClockMonotonic clock
loggerno-opStructured logger
activeFps44Rate while dirty/fading
idleFps2Keepalive rate
sendTimeoutMsPer-send timeout
shutdownTimeoutMs2000Owned transport shutdown bound
maxOutputs1024Max universe/priority pairs
ownsTransportfalseClose injected transport
ownsStoretrue / falsetrue for default memory store
createIdUUID factory if needed
onStart / onStop / onCloseHook failures fail the call

Methods

MethodNotes
universe(n, options?)Cached handle for (n, priority). Options: priority (default 100), cid, sourceName, idleFps. First call wins defaults.
start()Restore once, start scheduling. Safe if already running. After stop(), resumes without reloading store.
stop()Pause scheduler; keep targets. Next mutation auto-starts.
listUniverses()Immutable snapshots by universe/priority. Does not auto-start.
getTelemetry()Synchronous immutable snapshot.
subscribe(listener)started, stopped, output-updated, output-cleared, closed. Returns unsubscribe. Listener failures are isolated.
close()Drain, stop, onClose, close owned deps. Idempotent.

Mutations are serialized. Awaiting a mutation means the write is scheduled and persisted — not that a fade finished.

Universe

From source.universe(1, { priority: 100 }):

MethodAuto-startNotes
setChannels(values)yesSnap map { 1: 255, … }
fadeChannels(values, { durationMs })yesShared linear duration
transition([{ channel, value, durationMs }, …])yesPer-channel durations
write(values, { durationMs? })yesExactly 512 values
get()noSnapshot or null
clear({ signal? })yesBlackout + delete store record; false if absent

Mutators accept optional signal for queue-time cancellation.

Addressing

OutputAddress:

  • universe: 1..63999
  • priority: 0..200, default 100

Channel maps: non-empty, keys 1..512, values 0..255. Durations: finite, non-negative milliseconds.

Snapshots and telemetry

OutputSnapshot includes current/target state, last successfully sent frame, identity, scheduler state, sequence, timing, active transition count, and last transport error. Arrays are readonly snapshots.

EngineTelemetry covers scheduler state and aggregate send attempts, successes, failures, retries, and timeouts. Process telemetry is Node-only (getNodeRuntimeTelemetry).

ViewerService

new ViewerService({ receiver, … })

Required: receiver: Receiver

Optional: store, clock, logger, ownsReceiver (default false), ownsStore (owned only for default memory store), streamCapacity (32), maxUniverses (256), maxListeners (256).

MethodNotes
start()Restore selected universes
setSelectedUniverses / addUniverse / removeUniverseMembership + persist
getSelectedUniverses()Ordered selection
subscribe(listener)Sync callback; returns unsubscribe
packets(capacity?)Closeable async iterable
getTelemetry()Packets, drops/coalesces, selections, streams
close()Unsubscribe; close owned deps

Streams keep at most one queued packet per universe. Newer replaces older. At capacity, oldest is dropped.

Stores and contracts

Root exports: MemoryOutputStore, MemoryViewerStore, OutputTransport, OutputStore, Receiver, ViewerStore, Clock, Logger, SystemClock.

Errors

All extend SacnError with a stable string code:

ClassWhen
SacnValidationErrorBad universe, priority, channel, frame, fade, FPS, timeout, CID, name
SacnLifecycleErrorInvalid for current lifecycle or capacity
TransportTimeoutErrorSend exceeded bound
TransportErrorTransport failure
PersistenceErrorStorage failure or invalid stored data
DependencyUnavailableErrorOptional integration cannot be used

Match on class or code, not message text.


@helioslx/core/node

ExportPurpose
NodeSacnTransport(options?)UDP output; port 5568. Options: iface, port, sourceName, unicastDestination, logger, senderFactory.
NodeSacnReceiver(options?)Selected-universe receiver. Options: universes, iface, port, logger, receiverFactory.
createSacnSource(options?)Source + owned transport. Adds name, transportOptions, installProcessHandlers (default true).
getNodeRuntimeTelemetry()CPU, memory, PID, uptime

With process handlers enabled, a module registry installs SIGINT / SIGTERM / beforeExit once and closes registered Node sources. Pass installProcessHandlers: false when the host owns signals.

Multicast destination comes from universe number. Unicast is transport-level, not per-universe.


@helioslx/core/redis

RedisOutputStore and RedisViewerStore accept a Redis client or connection options, plus optional namespace (default helioslx), version, logger, and closeClient. Injected clients are caller-owned by default. Records are validated on load. See Persistence.


@helioslx/core/http

createSacnHttpAdapter(options) → unbound Elysia plugin.

Required: source

Optional: viewer, prefix (/sacn), auth, onViewerPacket, sunset, openapiPath, maxWebSocketClients, webSocketQueueCapacity

Canonical paths use /universes/:universe/priorities/:priority. Deprecated /outputs… aliases remain with deprecation headers. Full route table: HTTP guide.


@helioslx/core/testing

FakeClock, RecordingTransport, FakeReceiver, and createDeferred for deterministic tests without sockets.

On this page