npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@r6stats/valkord

v0.0.13

Published

Valkord Micro Framework for discord.js Bots

Downloads

3

Readme

Valkord (valk-discord)

Discord npm (scoped) David David

Valkord is a micro framework for building Discord bots with discordjs and TypeScript. Valkord uses a Modular component loading system, allowing you to develop or use 3rd party modules in your bot. Modules consist of commands, listeners and other classes that can be customized on a case-by-case basis.

Installing

To use Valkord to develop your own bot, you'll need to install it in your project alongside discord.js.

npm install @r6stats/valkord discord.js --save

Creating a Module

In order to create your own module, you'll want to extend the ValkordModule class and define the components that make up your module. You can also optionally add add a custom config for loading variables from the user's .env file. cd

// my.module.ts

import { ClientCommand, Constructor, ValkordModule } from '@r6stats/valkord'
import { MyModuleConfig } from './my.module-config'
import { PingCommand } from './commands'

export class MyModule extends ValkordModule<MyModuleConfig> {
  public getName = (): string => 'MyStuff'

  public getConfig = (): Constructor<MyModuleConfig> | null => MyModuleConfig // or return null

  public getCommands = (): Constructor<ClientCommand>[] => {
    PingCommand,
  }
}
// my.module-config.ts

import { ValkordConfig } from '@r6stats/valkord'

export interface MyModuleConfigOptions {
  my_config_value: string
}

export class MyModuleConfig extends ValkordConfig<MyModuleConfigOptions> {
  public load = (): MyModuleConfigOptions => ({
    my_config_value: env('MY_CONFIG_VALUE')
  })
}
// index.ts

export * from './my.module-config'
export * from './my.module'

The referenced command class makes use of the ValkordCommand class built into Valkord, which is extensible and allows for custom command handling as well as built in support for aliases, help messages and more.

import { ValkordCommand, CommandContext, Injectable } from '@r6stats/valkord'
import { Message } from 'discord.js'

@Injectable()
export class PingCommand extends ValkordCommand {
  public readonly command = 'ping'
  public readonly name = 'Ping'

  public async handle (ctx: CommandContext): Promise<Message | Message[] | void> {
    return ctx.reply('Pong!')
  }
}

Thanks to Valkord's incredibly simple Dependency Injection implementation, you can also create your own service (among others) classes that can auomatically be resolved from Valkord's built in container.

Take for example, the TimeService class:

import R6StatsAPI, { GenericStatsResponse, OperatorStatsResponse } from '@r6stats/node'
import { ConfigService, OnModuleBoot, Injectable } from '@r6stats/valkord'

@Injectable()
export class TimeService {
  public async getTime (): Promise<Date> {
    return new Date()
  }
}

You can now reference the TimeService from any class where the @Injectable() decorator is present, more importantly in the commands.

import { ValkordCommand, CommandContext, Injectable } from '@r6stats/valkord'
import { Message } from 'discord.js'

@Injectable()
export class TimeCommand extends ValkordCommand {
  public readonly command = 'time'
  public readonly name = 'Time'

  private readonly time: TimeService

  public constructor (time: TimeService) {
    this.time = time
  }

  public async handle (ctx: CommandContext): Promise<Message | Message[] | void> {
    return ctx.reply(this.time.getTime())
  }
}

Creating a Deployable Bot

Regardless or whether or not you want to build your own modules, you'll have no problem running the bot in production.

You'll simply need to create a TypeScript or JavaScript file named index.js (or whatever you prefer) and instantiate your bot:

import { ValkordClient, ValkordFactory } from '@r6stats/valkord'

// optionally import your custom module, or any 3rd party modules
import MyModule from 'my-valkord-module'

export class MyClient extends ValkordClient {

}

const run = async () => {
  // instatiate the client from the Container
  const client = await ValkordFactory.create<MyClient>(MyClient)

  // load any modules of your choosing
  const loader = client.getModuleLoader()
  loader.load(MyModule)

  // connect!
  await client.connect()
}

run()

Sharded Bot

Larger Discord bots may require sharding, typically suggested for any bots in more than 2000 guilds. Read more about sharding here. In order to enable sharding in Valkord, a second file is necessary to create shards of the client.

The new index file (TypeScript or JavaScript) will create an instance of the ValkordManager which will handle spawning the bot's shards. No changes to the client class are necessary.

// index.ts

import { ValkordFactory } from '@r6stats/valkord'
import * as path from 'path'

export const run = async (): Promise<void> => {
  // the path should refer to the file containing your ValkordClient instance
  await ValkordFactory.createManaged(path.join(__dirname, './client.ts'))
}

run()

The total number of shards and the range of shards to create can be configured in the .env file.

TOTAL_SHARDS=3 // total number of shards, if running more than one instance of the manager
SHARD_RANGE=0-2 // zero-based range of shards to run on this instance, starting at 0, last shard # should be one less than the total