puppywebhook 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "puppywebhook",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Queued, rate safe Discord webhook logger with automatic chunking",
5
5
  "type": "module",
6
+ "types": "./index.d.ts",
6
7
  "main": "./src/index.js",
7
8
  "exports": {
8
9
  ".": "./src/index.js"
package/src/index.d.ts ADDED
@@ -0,0 +1,57 @@
1
+ export interface PuppyWebhookOptions {
2
+ webhookUrl: string;
3
+ username?: string;
4
+ avatar?: string | null;
5
+ maxMessageLength?: number;
6
+ minDelay?: number;
7
+ maxDelay?: number;
8
+ logSends?: boolean;
9
+ logErrors?: boolean;
10
+ }
11
+
12
+ /**
13
+ * A rate-limited Discord webhook sender that queues and splits messages automatically.
14
+ */
15
+ export declare class PuppyWebhook {
16
+ webhookUrl: string;
17
+ username: string;
18
+ avatar: string | null;
19
+ maxMessageLength: number;
20
+ minDelay: number;
21
+ maxDelay: number;
22
+ logSends: boolean;
23
+ logErrors: boolean;
24
+ logQueue: string[];
25
+ queuedChunks: string[];
26
+ messagesSent: number;
27
+ interval: NodeJS.Timer | null;
28
+
29
+ constructor(options: PuppyWebhookOptions);
30
+
31
+ /** Queues a message to be sent to the webhook */
32
+ send(message: string | any): void;
33
+
34
+ /** Starts the sending loop */
35
+ start(): void;
36
+
37
+ /** Stops the sending loop */
38
+ stop(): void;
39
+
40
+ /** Immediately processes all queued messages */
41
+ flush(): Promise<void>;
42
+
43
+ /** @private */
44
+ private _process(force?: boolean): Promise<void>;
45
+
46
+ /** @private */
47
+ private _split(str: string): string[];
48
+
49
+ /** @private */
50
+ private _nextDelay(): number;
51
+
52
+ /** @private */
53
+ private _reschedule(): void;
54
+ }
55
+
56
+ declare const _default: typeof PuppyWebhook;
57
+ export default _default;
package/src/index.js CHANGED
@@ -1,6 +1,20 @@
1
1
  import fetch from 'node:fetch';
2
2
 
3
+ /**
4
+ * A simple rate-limited Discord webhook sender.
5
+ */
3
6
  export class PuppyWebhook {
7
+ /**
8
+ * @param {Object} options
9
+ * @param {string} options.webhookUrl - The webhook URL to send messages to.
10
+ * @param {string} [options.username='puppywebhook'] - The username to display for messages.
11
+ * @param {string|null} [options.avatar=null] - The avatar URL to use for messages.
12
+ * @param {number} [options.maxMessageLength=1900] - Maximum message length before splitting.
13
+ * @param {number} [options.minDelay=5000] - Minimum delay between messages in ms.
14
+ * @param {number} [options.maxDelay=15000] - Maximum delay between messages in ms.
15
+ * @param {boolean} [options.logSends=false] - Whether to log sent messages.
16
+ * @param {boolean} [options.logErrors=true] - Whether to log errors when sending.
17
+ */
4
18
  constructor(options = {}) {
5
19
  this.webhookUrl = options.webhookUrl;
6
20
  this.username = options.username ?? 'puppywebhook';
@@ -25,6 +39,10 @@ export class PuppyWebhook {
25
39
  this.start();
26
40
  }
27
41
 
42
+ /**
43
+ * Queues a message to be sent to the webhook.
44
+ * @param {string} message
45
+ */
28
46
  send(message) {
29
47
  if (typeof message !== 'string') {
30
48
  message = String(message);
@@ -33,21 +51,32 @@ export class PuppyWebhook {
33
51
  this.logQueue.push(message);
34
52
  }
35
53
 
54
+ /** Starts the sending loop. */
36
55
  start() {
37
56
  if (this.interval) return;
38
57
  this.interval = setInterval(() => this._process(), this._nextDelay());
39
58
  }
40
59
 
60
+ /** Stops the sending loop. */
41
61
  stop() {
42
62
  if (!this.interval) return;
43
63
  clearInterval(this.interval);
44
64
  this.interval = null;
45
65
  }
46
66
 
67
+ /**
68
+ * Immediately processes all queued messages.
69
+ * @returns {Promise<void>}
70
+ */
47
71
  flush() {
48
72
  return this._process(true);
49
73
  }
50
74
 
75
+ /**
76
+ * Processes the message queue and sends chunks to the webhook.
77
+ * @param {boolean} [force=false] - Whether to force sending even if queue is empty.
78
+ * @private
79
+ */
51
80
  async _process(force = false) {
52
81
  while (this.logQueue.length > 0) {
53
82
  const msg = this.logQueue.shift();
@@ -102,6 +131,12 @@ export class PuppyWebhook {
102
131
  this._reschedule();
103
132
  }
104
133
 
134
+ /**
135
+ * Splits a string into chunks no longer than maxMessageLength.
136
+ * @param {string} str
137
+ * @returns {string[]}
138
+ * @private
139
+ */
105
140
  _split(str) {
106
141
  const chunks = [];
107
142
  for (let i = 0; i < str.length; i += this.maxMessageLength) {
@@ -110,12 +145,18 @@ export class PuppyWebhook {
110
145
  return chunks;
111
146
  }
112
147
 
148
+ /**
149
+ * Calculates the next delay before sending a chunk.
150
+ * @returns {number} Delay in milliseconds.
151
+ * @private
152
+ */
113
153
  _nextDelay() {
114
154
  const base = this.maxDelay - Math.min(this.queuedChunks.length, 7) * 1000;
115
155
  const jitter = (Math.floor(Math.random() * 8) - 4) * 1000;
116
156
  return Math.max(this.minDelay, base + jitter);
117
157
  }
118
158
 
159
+ /** Reschedules the sending loop with a new delay. @private */
119
160
  _reschedule() {
120
161
  if (!this.interval) return;
121
162
  clearInterval(this.interval);