ircbridge

package
v1.5.1-0...-475df33 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package ircbridge wraps the external irc.Connection with multi-subscriber fan-out for the bouncer's per-network event stream.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CleanInput

func CleanInput(text string) string

CleanInput preserves the IRC library's wire-safety normalization used by its convenience send methods. IRC values placed on one wire line must not contain embedded line terminators: LF becomes a visible separator and CR is removed.

func SendRaw

func SendRaw(c *irc.Connection, format string, args ...any)

SendRaw sends an IRC line with a unique labeled-response label when the server negotiated both capabilities required by the specification. The label is generated inside Relay rather than exposed to the browser protocol: Relay has one upstream IRC connection per network and already broadcasts resulting IRC events to all attached sessions.

Commands sent before capability negotiation, or to servers without labeled-response support, retain the existing untagged wire format.

func SendRawTags

func SendRawTags(c *irc.Connection, tags map[string]string, format string, args ...any)

SendRawTags sends an IRC line with caller-supplied tags and adds a unique labeled-response label when the negotiated capabilities allow it. The caller's map is never mutated, so shared message-tag maps remain safe to reuse across chunked sends and local self-echo events.

Types

type Bridge

type Bridge struct {
	Conn *irc.Connection
	// contains filtered or unexported fields
}

Bridge wraps a single *irc.Connection, becoming the sole holder of each of its per-type callbacks and re-publishing every event to any number of subscribers. irc.Connection supports exactly one callback per event type; a bouncer needs "one IRC event -> N attached browser sessions", which is what Bridge adds on top without changing the underlying library's contract (see the migration plan's rationale for keeping this fan-out app-side rather than pushing pub/sub upstream into the library itself).

A Bridge intentionally runs no goroutine of its own beyond the one the caller starts via Run: irc.Connection.Run's read loop already invokes every callback synchronously, one message at a time, so simply becoming that loop's sole callback holder and dispatching to subscribers inline preserves the same single-threaded ordering guarantee Node's event loop gives for free - no extra channel/goroutine layer is needed to get it.

func NewBridge

func NewBridge(conn *irc.Connection) *Bridge

NewBridge wraps conn, installing itself as the sole holder of every callback conn exposes. conn must not have any of its callbacks set already - Bridge overwrites all of them.

func (*Bridge) Connected

func (b *Bridge) Connected() bool

Connected reports whether Run's read loop is still active. False before Run is ever called would be indistinguishable from false after it ends; callers only call this once they know Run has started (e.g. after launching `go bridge.Run()`).

func (*Bridge) Publish

func (b *Bridge) Publish(ev Event)

Publish fans out a synthetic Event to every subscriber, exactly as if the underlying connection had produced it. This is the Go analogue of Node's `irc.emit("privmsg", {...})` self-echo simulation (msg.ts, notice.ts, action.ts all fabricate a local echo when the server hasn't ACKed echo-message) - routing the fabricated event through the same dispatch path real events take, rather than duplicating irchandlers' message- building logic in internal/incommands.

func (*Bridge) Run

func (b *Bridge) Run()

Run blocks, reading from the underlying connection and dispatching events to subscribers, until the connection closes or errors. Callers should invoke this in its own goroutine (one per Bridge, per the package's ordering guarantee) and use Connected to check liveness afterward.

func (*Bridge) Subscribe

func (b *Bridge) Subscribe(l Listener) int

Subscribe registers l to receive every subsequent Event and returns an id for Unsubscribe. Safe to call concurrently with Run.

func (*Bridge) SubscriberCount

func (b *Bridge) SubscriberCount() int

SubscriberCount reports how many listeners are currently registered.

func (*Bridge) Unsubscribe

func (b *Bridge) Unsubscribe(id int)

Unsubscribe removes a listener previously returned by Subscribe. A no-op if id is unknown (e.g. already unsubscribed).

type Event

type Event struct {
	Type EventType

	Privmsg *irc.PrivmsgEvent
	Message *irc.MessageEvent
	Direct  *irc.DirectEvent
	Join    *irc.JoinEvent
	Part    *irc.PartEvent
	Quit    *irc.QuitEvent
	Nick    *irc.NickEvent
	Account *irc.AccountEvent
	Kick    *irc.KickEvent
	Notice  *irc.NoticeEvent
	Numeric *irc.NumericEvent
	Topic   *irc.TopicEvent
	Mode    *irc.ModeEvent
	Chghost *irc.ChghostEvent
	SetName *irc.SetNameEvent
	TagMsg  *irc.TagMsgEvent
	CTCP    *irc.CTCPEvent
	Whois   *irc.WhoisReply
	Error   *irc.ErrorEvent
}

Event is the single fan-out envelope for every callback the irc library exposes on *irc.Connection. Exactly one field matching Type is non-nil; callers switch on Type rather than nil-checking every field.

type EventType

type EventType int

EventType identifies which field of Event is populated.

const (
	EventPrivmsg EventType = iota
	EventMessage
	EventDirect
	EventJoin
	EventPart
	EventQuit
	EventNick
	EventAccount
	EventKick
	EventNotice
	EventNumeric
	EventTopic
	EventMode
	EventChghost
	EventSetName
	EventTagMsg
	EventCTCP
	EventWhois
	EventError
)

type Listener

type Listener func(Event)

Listener receives every Event a Bridge dispatches, in the order the underlying connection produced them. It is invoked synchronously from the Bridge's single dispatching goroutine (see Run) and must not block for long - a slow listener delays delivery to every other listener on the same bridge, and (since irc.Connection's Run loop is itself synchronous) delays the bridge from reading its next line off the wire.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL