Creates a local shared-instance client interface.
Without options.socket it is the initiator and reconnects after drops.
With an adopted options.socket (server-spawned) it never reconnects.
Protected_Whether a terminal closed event has already been dispatched for the
current connection episode (dedupe guard).
Protected_AbortController for the current reconnect wait, so disconnect() can
cancel an in-flight backoff immediately.
Protected_Reconnect attempt counter for the current drop episode. Reset to 0 at the start of each Interface._runReconnectLoop run.
Protected_Single-flight guard: only one reconnect loop runs at a time.
Whether automatic reconnection is enabled for this initiator interface.
Nominal physical bitrate of this interface in bits per second
(self.bitrate on RNS.Interfaces.Interface in the Python reference,
default 62500). Each interface overrides this with its medium's rate.
Used by TransportCore.prioritizeInterfaces() to order the interface set
highest-bitrate-first (mirrors the Python reference's
Transport.prioritize_interfaces); the per-bitrate link-timeout and
announce-rate-limit behaviours that also build on it are tracked as
Phase 2 of work doc #20. Configured bitrates below
Reticulum.MINIMUM_BITRATE are ignored (matching Python).
Per-dial connect timeout in seconds.
Permanent stop signal read by the reconnect loop. Set by disconnect().
true when this interface is the initiator that connected out to a shared
instance (i.e. this program is using a daemon, not being one). Mirrors
the Python reference LocalClientInterface.is_connected_to_shared_instance.
true when this interface was spawned by a import("./local_server.js").LocalServerInterface to wrap an accepted
connection (i.e. this program is the daemon). Set by the server.
Maximum reconnection attempts per drop. Infinity retries forever.
Seconds to wait between reconnection attempts.
The underlying socket (if any).
Protected_Protected
Applies socket tuning the Python reference applies to the shared-instance
socket: TCP_NODELAY and SO_KEEPALIVE so a dead daemon is detected and
reconnect can trigger. No-op for UDS (these options are TCP-only).
Protected_Protected
Signals the reconnect loop to stop and cancels any in-flight backoff.
Client subclasses call this at the top of their disconnect().
Protected_Protected
Dispatches a terminal closed event exactly once per connection episode.
Protected_Protected
Dials the shared instance (TCP or UDS, with the configured connect
timeout), applies keepalive tuning, sets up the RNS streams, and dispatches
connected. Used both for the initial connection and each reconnect.
Resolves once connected; rejects on failure.
Protected_Protected
Called when the underlying connection drops (the inbound stream ends or
errors). For an initiator with auto-reconnect enabled and not deliberately
detached, dispatches disconnected and kicks off the reconnect loop;
otherwise dispatches a terminal closed event.
Matches the Python reference read_loop, which reconnects the initiator
on any termination and tears down (non-reconnecting) everyone else.
Protected_Protected
Initializes shared reconnect state from constructor options. Called by client interface subclasses (TCP, WebSocket) that support reconnection.
Subclasses must also set Interface.initiator: true for an
outbound dialer, false for an adopted/server-spawned socket.
Protected_Protected
Runs the single-flight reconnect loop. Repeatedly waits reconnectWait
seconds then attempts to re-establish the connection via the subclass
_establishConnection() hook, until it succeeds, the interface is
detached, or maxReconnectTries is exceeded (terminal closed).
Each attempt fires a reconnecting event with the upcoming attempt
number, the wait, and the cap, for observability. A successful reconnect
fires connected (via _establishConnection).
Protected_Protected
Resolves after ms, or immediately if signal aborts. Used so
disconnect() can cancel an in-flight reconnect backoff at once.
The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.
Optionaloptions: boolean | AddEventListenerOptionsOptional hook invoked by import("../transport/transport.js").TransportCore#addInterface with the transport that owns this interface, right after the interface is attached.
The base implementation is a no-op. Interfaces that spawn sub-interfaces
dynamically — notably AutoInterface, which discovers peers and
spawns one per peer — override it to remember the transport so the spawned
peers can be auto-registered without a separate Reticulum global (the
Python reference uses the global RNS.Transport.add_interface for this).
Overriders should also register any peers spawned before the transport was
attached, so the addInterface/connect call order doesn't matter.
Establishes the loopback connection (or adopts the provided socket) and starts the inbound loop.
For an initiator whose first dial fails with auto-reconnect enabled, the
promise rejects (so the caller knows) but the reconnect loop keeps retrying
in the background — matching the Python reference LocalClientInterface
behaviour.
Tears down the socket, cancels any pending reconnect, and marks the interface offline.
The dispatchEvent() method of the EventTarget sends an Event to the object, (synchronously) invoking the affected event listeners in the appropriate order. The normal event processing rules (including the capturing and optional bubbling phase) also apply to events dispatched manually with dispatchEvent().
The removeEventListener() method of the EventTarget interface removes an event listener previously registered with EventTarget.addEventListener() from the target. The event listener to be removed is identified using a combination of the event type, the event listener function itself, and various optional options that may affect the matching process; see Matching event listeners for removal.
Optionaloptions: boolean | EventListenerOptionsStaticconnectStatic async factory: discovers the local shared-instance endpoint (from
the Python ~/.reticulum/config unless pinned by options), connects a
LocalClientInterface to it, and returns the connected interface —
or null if share_instance is disabled in the config or the endpoint is
not currently reachable.
Mirrors the client side of the Python reference
Reticulum.__start_local_interface. This is a factory only: it discovers
and connects, but does not attach the interface to any transport —
the caller wires it, e.g. rns.addInterface(iface, true).
On a first-dial failure the background reconnect loop is cancelled (via
disconnect()) so nothing leaks and the caller can cleanly fall back to
a standalone interface.
Optionaloptions: {OptionalautoReconnect?: booleanReconnect after drops.
OptionalconfigDir?: stringConfig directory to discover from.
OptionalconnectTimeout?: numberPer-dial timeout in seconds.
Optionalhost?: stringOverride the discovered TCP host
(defaults to 127.0.0.1).
OptionalifacSize?: numberOptional IFAC size in bytes.
OptionalmaxReconnectTries?: number | nullAttempt cap, or null
for unlimited.
Optionalname?: stringInterface name.
Optionalport?: numberOverride the discovered TCP port.
OptionalreconnectWait?: numberSeconds between attempts.
OptionalsocketPath?: stringConnect over a Unix domain socket / named pipe instead of TCP.
StaticgetReturns the JSON Schema describing the options accepted by the
LocalClientInterface constructor (excluding the internal socket
adoption option). Drives dynamically-generated setup UIs.
A JSON Schema object.
Client interface for a local shared Reticulum instance.
When constructed without a
socketit is the initiator (an outbound dialer to the shared instance): it sets LocalClientInterface#isConnectedToSharedInstance and auto-reconnects after drops. When constructed with an adoptedsocket(a server-spawned connection on the daemon side) it never reconnects and is flagged as a local client of the owning server.