SWAGcommands
API reference

Stores

Bring your own storage for prefixes and cooldowns.

Both built-in stores keep data in memory. That is great for a small bot and ephemeral state; persistence or multiple workers call for your own implementations.

PrefixStore

interface PrefixStore {
  getPrefix(guildId: string): string | undefined | Promise<string | undefined>;
  setPrefix(guildId: string, prefix: string): void | Promise<void>;
}

Pass prefixStore to SWAG.create(). The message router asks it for a guild prefix and falls back to defaultPrefix when it returns undefined. DMs use the default. The shipped MemoryPrefixStore is an easy starting point.

CooldownStore

interface CooldownClaim {
  acquired: boolean;
  expiresAt: number;
}

interface CooldownStore {
  getCooldown(id: string): number | undefined | Promise<number | undefined>;
  setCooldown(id: string, expiresAt: number): void | Promise<void>;
  deleteCooldown(id: string): void | Promise<void>;
  claimCooldown(
    id: string,
    expiresAt: number,
    now: number,
  ): CooldownClaim | Promise<CooldownClaim>;
}

The timestamps are Unix time in milliseconds. claimCooldown must atomically acquire a missing or expired bucket and return { acquired: true, expiresAt }, or reject a live bucket with { acquired: false, expiresAt: activeExpiration }. This atomic step prevents concurrent invocations from both entering the callback. MemoryCooldownStore implements this in one process; distributed stores must use their backend's atomic primitive.

const swag = await SWAG.create({
  client,
  prefixStore: new MyPrefixStore(),
  cooldownStore: new MyCooldownStore(),
});

These interfaces accept synchronous or asynchronous methods. Prefixes and Cooldowns show how the stores affect command behavior.

On this page