feat(extra): collectors (#86)

* feat: collectors

* import type

* fix: collector.once
This commit is contained in:
Drylozu 2022-08-01 14:05:25 -05:00 committed by GitHub
parent c610b183f7
commit 220069a89c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 192 additions and 0 deletions

View File

@ -56,6 +56,10 @@
{
"name": "socram03",
"url": "https://github.com/socram03"
},
{
"name": "Drylozu",
"url": "https://github.com/Drylozu"
}
],
"homepage": "https://biscuitjs.com",

View File

@ -44,6 +44,10 @@
{
"name": "socram03",
"url": "https://github.com/socram03"
},
{
"name": "Drylozu",
"url": "https://github.com/Drylozu"
}
],
"homepage": "https://biscuitjs.com",

View File

@ -48,6 +48,10 @@
{
"name": "socram03",
"url": "https://github.com/socram03"
},
{
"name": "Drylozu",
"url": "https://github.com/Drylozu"
}
],
"homepage": "https://biscuitjs.com",

View File

@ -49,6 +49,10 @@
{
"name": "socram03",
"url": "https://github.com/socram03"
},
{
"name": "Drylozu",
"url": "https://github.com/Drylozu"
}
],
"homepage": "https://biscuitjs.com",

View File

@ -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 <yuzuru@programmer.net>",
"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"
}
}

View File

@ -0,0 +1,71 @@
import type { Session, Events } from '@biscuitland/core';
import { EventEmitter } from 'node:events';
interface CollectorOptions<E extends keyof Events> {
event: E;
filter?(...args: Parameters<Events[E]>): unknown;
max?: number;
time?: number;
idle?: number;
}
export class Collector<E extends keyof Events> extends EventEmitter {
collected = new Set<Parameters<Events[E]>[0]>();
ended = false;
private timeout: NodeJS.Timeout;
constructor(readonly session: Session, public options: CollectorOptions<E>) {
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<Events[E]>));
this.timeout = setTimeout(() => this.stop('time'), this.options.idle ?? this.options.time);
}
private collect(...args: Parameters<Events[E]>) {
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<Events[E]>));
this.session.events.setMaxListeners(this.session.events.getMaxListeners() - 1);
this.ended = true;
this.emit('end', reason, this.collected);
}
on(event: 'collect', listener: (...args: Parameters<Events[E]>) => unknown): this;
on(event: 'end', listener: (reason: string | null | undefined, collected: Set<Parameters<Events[E]>[0]>) => void): this;
on(event: string, listener: unknown): this {
return super.on(event, listener as (() => unknown));
}
once(event: 'collect', listener: (...args: Parameters<Events[E]>) => unknown): this;
once(event: 'end', listener: (reason: string | null | undefined, collected: Set<Parameters<Events[E]>[0]>) => void): this;
once(event: string, listener: unknown): this {
return super.once(event, listener as (() => unknown));
}
}

View File

@ -0,0 +1 @@
export * from './collectors';

View File

@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": ["src/**/*"]
}

View File

@ -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,
});

View File

@ -47,6 +47,10 @@
{
"name": "socram03",
"url": "https://github.com/socram03"
},
{
"name": "Drylozu",
"url": "https://github.com/Drylozu"
}
],
"homepage": "https://biscuitjs.com",

View File

@ -50,6 +50,10 @@
{
"name": "socram03",
"url": "https://github.com/socram03"
},
{
"name": "Drylozu",
"url": "https://github.com/Drylozu"
}
],
"homepage": "https://biscuitjs.com",

View File

@ -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
},