Skip to content

Async sweepers #11372

@shi-gg

Description

@shi-gg

Which application or package is this feature request for?

discord.js

Feature

support for async sweeper functions ala

import { Client, GatewayIntentBits, Options } from "discord.js";

import { db } from "~/db";

const ONE_DAY_MS = 1_000 * 60 * 60 * 24;

const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMembers,
        GatewayIntentBits.GuildMessageReactions,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent
    ],
    sweepers: {
        ...Options.DefaultSweeperSettings,
        messages: {
            interval: 60 * 60,
            filter: async () => { // <- this
                const guilddbs = await db
                    .selectFrom("guilds")
                    .select(["guildId"])
                    .select(() => sql<string>`starboard->>'emoji'`.as("emoji"))
                    .where((eb) => sql<boolean>`(${eb.ref("flags")} & ${GuildFlags.StarboardEnabled}) != 0`)
                    .where(sql<boolean>`starboard->>'emoji' IS NOT NULL`)
                    .execute();

                const cutoffTimestamp = Date.now() - ONE_DAY_MS;

                return (message: Message) => {
                    if (isBotMessage(message)) return false;

                    const guilddb = guilddbs.find((guilddb) => guilddb.guildId === message.guildId!);
                    if (!guilddb?.emoji || !reactionsContainEmoji(message, guilddb.emoji)) return true; // Sweep (No Emoji)

                    return message.createdTimestamp <= cutoffTimestamp; // Sweep if Old
                };
            }
        }
    }
});

Ideal solution or implementation

roughly like that

diff --git a/node_modules/discord.js/.bun-tag-33cb380651d649b2 b/.bun-tag-33cb380651d649b2
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/util/Sweepers.js b/src/util/Sweepers.js
index edc328749f4a12bb77d91a06bbd9a7a9a91c8614..e8e5da8a80276cb6d6bc510dbb6273e9c2c1ede9 100644
diff --git a/src/util/Sweepers.js b/src/util/Sweepers.js
index edc328749f4a12bb77d91a06bbd9a7a9a91c8614..e8e5da8a80276cb6d6bc510dbb6273e9c2c1ede9 100644
--- a/src/util/Sweepers.js
+++ b/src/util/Sweepers.js
@@ -475,8 +475,9 @@ class Sweepers {
    */
   _initInterval(intervalKey, sweepKey, opts) {
     if (opts.interval <= 0 || opts.interval === Infinity) return;
-    this.intervals[intervalKey] = setInterval(() => {
-      const sweepFn = opts.filter();
+    this.intervals[intervalKey] = setInterval(async () => {
+      let sweepFn = opts.filter();
+      if (sweepFn instanceof Promise) sweepFn = await sweepFn;
       if (sweepFn === null) return;
       if (typeof sweepFn !== 'function') throw new DiscordjsTypeError(ErrorCodes.SweepFilterReturn);
       this[sweepKey](sweepFn);
diff --git a/typings/index.d.mts b/typings/index.d.mts
index ab2bc793e12deffc226604121fa444cbc7870382..ca44cc7e28dc1de1dd3ad86824c35f0abfde2a90 100644
--- a/typings/index.d.mts
+++ b/typings/index.d.mts
@@ -6583,6 +6583,7 @@ export interface AttachmentPayload {
 
 export type GlobalSweepFilter<Key, Value> = () =>
   | ((value: Value, key: Key, collection: Collection<Key, Value>) => boolean)
+  | Promise<((value: Value, key: Key, collection: Collection<Key, Value>) => boolean)>
   | null;
 
 interface GuildAuditLogsTypes {
diff --git a/typings/index.d.ts b/typings/index.d.ts
index bc2515e3726a208594d842c5d5b1ece84b66540e..a9104fc51aa95eb41bcb900b8a35c1c344fd1437 100644
--- a/typings/index.d.ts
+++ b/typings/index.d.ts
@@ -6583,6 +6583,7 @@ export interface AttachmentPayload {
 
 export type GlobalSweepFilter<Key, Value> = () =>
   | ((value: Value, key: Key, collection: Collection<Key, Value>) => boolean)
+  | Promise<((value: Value, key: Key, collection: Collection<Key, Value>) => boolean)>
   | null;
 
 interface GuildAuditLogsTypes {

Alternative solutions or implementations

No response

Other context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions