API Reference

GlyriaBus

A typed event bus with middleware support.

Overview

GlyriaBus is a typed pub/sub event bus with middleware support. It lets you communicate between different parts of your bot without coupling them together.

// src/utils/useBus.ts
type BotEvents = {
  userBanned: [guildId: string, userId: string, reason: string]
  levelUp: [userId: string, level: number]
}

export const useBus = new GlyriaBus<BotEvents>()
GlyriaBus is available globally — no import needed. Define your bus in src/utils/ and it's auto-imported everywhere.

Constructor

new GlyriaBus<Events>()

Type parameter

Events is a record mapping event names to their payload types (as tuples):

type Events = {
  userBanned: [guildId: string, userId: string]
  levelUp: [userId: string, level: number]
}

Methods

.on(event, listener)

Register a listener for an event. Returns an unregister function.

const stop = useBus.on("userBanned", (guildId, userId) => {
  console.log(`${userId} banned from ${guildId}`)
})

// later
stop()
ParameterTypeDescription
eventkeyof EventsEvent name
listenerListener<Events[K]>Handler receiving the event payload

Returns () => void — call it to remove the listener.


.use(event, middleware)

Register a middleware for an event. Middlewares run before listeners and must call next() to continue the chain.

useBus.use("userBanned", async (guildId, userId, next) => {
  console.log(`[middleware] ban received`)
  await next()
})
ParameterTypeDescription
eventkeyof EventsEvent name
middlewareMiddleware<Events[K]>Handler with next as last argument

.emit(event, ...args)

Emit an event with typed arguments. Runs all middlewares and listeners in order.

await useBus.emit("userBanned", guildId, userId, reason)
ParameterTypeDescription
eventkeyof EventsEvent name
...argsEvents[K]Typed event payload

Returns Promise<void>


.off(event, middleware)

Remove a specific middleware from an event.

useBus.off("userBanned", myMiddleware)

.clear(event)

Remove all listeners and middlewares for an event.

useBus.clear("userBanned")

Types

Middleware<T>

type Middleware<T extends any[]> = (
  ...args: [...ctx: T, next: NextFunction]
) => any | Promise<any>

Listener<T>

type Listener<T extends any[]> = (...ctx: T) => any | Promise<any>

NextFunction

type NextFunction = () => void | Promise<void>

Middleware chain

Middlewares and listeners run in registration order. Not calling next() stops the chain — subsequent middlewares and listeners won't run.

useBus.use("levelUp", async (userId, level, next) => {
  if (level < 5) return // stops here, listener never runs
  await next()
})

useBus.on("levelUp", (userId, level) => {
  console.log(`${userId} reached level ${level}`)
})

globalBus

globalBus is a ready-made GlyriaBus singleton shipped with glyria.js. Unlike a bus you create yourself, it's shared across your whole project and every loaded module — making it the canonical place for framework-level lifecycle events.

globalBus.on("botReady", (client) => {
  console.log(`Logged in as ${client.user?.tag}`)
})
globalBus is available globally — no import needed.

Events

EventPayloadDescription
botReady[GlyriaClient]Emitted once, when the client is logged in and fully ready

botReady is the recommended entry point for initialization logic — especially inside modules, where it replaces a ready event listener.

// inside a module's index.ts
globalBus.on("botReady", async (client) => {
  // safe to access client.user, guilds, etc.
  client.bus.on(Events.MessageCreate, (message) => {
    // ...
  })
})
Use globalBus only for framework lifecycle events like botReady. For your own app events, create a dedicated typed GlyriaBus so its event names and payloads stay isolated and fully typed.
Copyright © 2026