From 220069a89c63f7e05eebb2e17114d9ca9eadd50d Mon Sep 17 00:00:00 2001 From: Drylozu <35281350+Drylozu@users.noreply.github.com> Date: Mon, 1 Aug 2022 14:05:25 -0500 Subject: [PATCH] feat(extra): collectors (#86) * feat: collectors * import type * fix: collector.once --- package.json | 4 ++ packages/api-types/package.json | 4 ++ packages/cache/package.json | 4 ++ packages/core/package.json | 4 ++ packages/extra/package.json | 74 ++++++++++++++++++++++++++++++++ packages/extra/src/collectors.ts | 71 ++++++++++++++++++++++++++++++ packages/extra/src/index.ts | 1 + packages/extra/tsconfig.json | 7 +++ packages/extra/tsup.config.ts | 12 ++++++ packages/rest/package.json | 4 ++ packages/ws/package.json | 4 ++ turbo.json | 3 ++ 12 files changed, 192 insertions(+) create mode 100644 packages/extra/package.json create mode 100644 packages/extra/src/collectors.ts create mode 100644 packages/extra/src/index.ts create mode 100644 packages/extra/tsconfig.json create mode 100644 packages/extra/tsup.config.ts diff --git a/package.json b/package.json index b7573a3..d083b24 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,10 @@ { "name": "socram03", "url": "https://github.com/socram03" + }, + { + "name": "Drylozu", + "url": "https://github.com/Drylozu" } ], "homepage": "https://biscuitjs.com", diff --git a/packages/api-types/package.json b/packages/api-types/package.json index db620dc..c38fed4 100644 --- a/packages/api-types/package.json +++ b/packages/api-types/package.json @@ -44,6 +44,10 @@ { "name": "socram03", "url": "https://github.com/socram03" + }, + { + "name": "Drylozu", + "url": "https://github.com/Drylozu" } ], "homepage": "https://biscuitjs.com", diff --git a/packages/cache/package.json b/packages/cache/package.json index bc59b59..c013044 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -48,6 +48,10 @@ { "name": "socram03", "url": "https://github.com/socram03" + }, + { + "name": "Drylozu", + "url": "https://github.com/Drylozu" } ], "homepage": "https://biscuitjs.com", diff --git a/packages/core/package.json b/packages/core/package.json index 617c088..c0a40be 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -49,6 +49,10 @@ { "name": "socram03", "url": "https://github.com/socram03" + }, + { + "name": "Drylozu", + "url": "https://github.com/Drylozu" } ], "homepage": "https://biscuitjs.com", diff --git a/packages/extra/package.json b/packages/extra/package.json new file mode 100644 index 0000000..75476c9 --- /dev/null +++ b/packages/extra/package.json @@ -0,0 +1,74 @@ +{ + "name": "@biscuitland/extra", + "version": "1.1.0", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist/**" + ], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist && rm -rf .turbo", + "dev": "tsup --watch" + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + }, + "require": "./dist/index.js" + } + }, + "peerDependencies": { + "@biscuitland/core": "^1.1.0" + }, + "devDependencies": { + "tsup": "^6.1.3" + }, + "license": "Apache-2.0", + "author": "Yuzuru ", + "contributors": [ + { + "name": "Yuzuru", + "url": "https://github.com/yuzudev", + "author": true + }, + { + "name": "miia", + "url": "https://github.com/dragurimu" + }, + { + "name": "n128", + "url": "https://github.com/nicolito128" + }, + { + "name": "socram03", + "url": "https://github.com/socram03" + }, + { + "name": "Drylozu", + "url": "https://github.com/Drylozu" + } + ], + "homepage": "https://biscuitjs.com", + "repository": { + "type": "git", + "url": "git+https://github.com/oasisjs/biscuit.git" + }, + "bugs": { + "url": "https://github.com/oasisjs/biscuit" + }, + "keywords": [ + "api", + "discord", + "bots", + "typescript", + "botdev" + ], + "publishConfig": { + "access": "public" + } +} diff --git a/packages/extra/src/collectors.ts b/packages/extra/src/collectors.ts new file mode 100644 index 0000000..415a16f --- /dev/null +++ b/packages/extra/src/collectors.ts @@ -0,0 +1,71 @@ +import type { Session, Events } from '@biscuitland/core'; +import { EventEmitter } from 'node:events'; + +interface CollectorOptions { + event: E; + filter?(...args: Parameters): unknown; + max?: number; + time?: number; + idle?: number; +} + +export class Collector extends EventEmitter { + collected = new Set[0]>(); + ended = false; + private timeout: NodeJS.Timeout; + + constructor(readonly session: Session, public options: CollectorOptions) { + super(); + + if (!('filter' in this.options)) + this.options.filter = (() => true); + + if (!('max' in this.options)) + this.options.max = -1; + + this.session.events.setMaxListeners(this.session.events.getMaxListeners() + 1); + + this.session.events.on(this.options.event, (...args: unknown[]) => this.collect(...args as Parameters)); + + this.timeout = setTimeout(() => this.stop('time'), this.options.idle ?? this.options.time); + } + + private collect(...args: Parameters) { + if (this.options.filter?.(...args)) { + this.collected.add(args[0]); + this.emit('collect', ...args); + } + + if (this.options.idle) { + clearTimeout(this.timeout); + this.timeout = setTimeout(() => this.stop('time'), this.options.idle); + } + + if (this.collected.size >= this.options.max!) + this.stop('max'); + } + + stop(reason?: string) { + if (this.ended) return; + + clearTimeout(this.timeout); + + this.session.events.removeListener(this.options.event, (...args: unknown[]) => this.collect(...args as Parameters)); + this.session.events.setMaxListeners(this.session.events.getMaxListeners() - 1); + + this.ended = true; + this.emit('end', reason, this.collected); + } + + on(event: 'collect', listener: (...args: Parameters) => unknown): this; + on(event: 'end', listener: (reason: string | null | undefined, collected: Set[0]>) => void): this; + on(event: string, listener: unknown): this { + return super.on(event, listener as (() => unknown)); + } + + once(event: 'collect', listener: (...args: Parameters) => unknown): this; + once(event: 'end', listener: (reason: string | null | undefined, collected: Set[0]>) => void): this; + once(event: string, listener: unknown): this { + return super.once(event, listener as (() => unknown)); + } +} \ No newline at end of file diff --git a/packages/extra/src/index.ts b/packages/extra/src/index.ts new file mode 100644 index 0000000..ca84f07 --- /dev/null +++ b/packages/extra/src/index.ts @@ -0,0 +1 @@ +export * from './collectors'; \ No newline at end of file diff --git a/packages/extra/tsconfig.json b/packages/extra/tsconfig.json new file mode 100644 index 0000000..9b4f197 --- /dev/null +++ b/packages/extra/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist" + }, + "include": ["src/**/*"] +} diff --git a/packages/extra/tsup.config.ts b/packages/extra/tsup.config.ts new file mode 100644 index 0000000..6eebbb4 --- /dev/null +++ b/packages/extra/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'tsup'; + +const isProduction = process.env.NODE_ENV === 'production'; + +export default defineConfig({ + clean: true, + dts: true, + entry: ['src/index.ts'], + format: ['cjs', 'esm'], + minify: isProduction, + sourcemap: true, +}); diff --git a/packages/rest/package.json b/packages/rest/package.json index bb523c7..63c48a7 100644 --- a/packages/rest/package.json +++ b/packages/rest/package.json @@ -47,6 +47,10 @@ { "name": "socram03", "url": "https://github.com/socram03" + }, + { + "name": "Drylozu", + "url": "https://github.com/Drylozu" } ], "homepage": "https://biscuitjs.com", diff --git a/packages/ws/package.json b/packages/ws/package.json index e88fb5f..ebd32f2 100644 --- a/packages/ws/package.json +++ b/packages/ws/package.json @@ -50,6 +50,10 @@ { "name": "socram03", "url": "https://github.com/socram03" + }, + { + "name": "Drylozu", + "url": "https://github.com/Drylozu" } ], "homepage": "https://biscuitjs.com", diff --git a/turbo.json b/turbo.json index f088b24..cfe7b36 100644 --- a/turbo.json +++ b/turbo.json @@ -17,6 +17,9 @@ "@biscuitland/core#build": { "dependsOn": ["@biscuitland/api-types#build", "@biscuitland/rest#build", "@biscuitland/ws#build"] }, + "@biscuitland/extra#build": { + "dependsOn": ["@biscuitland/core#build"] + }, "clean": { "cache": false },