dankgrinder 8.39.0 → 8.41.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/lib/grinder.js +13 -4
- package/lib/rawLogger.js +10 -6
- package/lib/ui.js +5 -3
- package/package.json +1 -1
package/lib/grinder.js
CHANGED
|
@@ -13,12 +13,21 @@ const ui = require('./ui');
|
|
|
13
13
|
// Global shutdown flag
|
|
14
14
|
let shutdownCalled = false;
|
|
15
15
|
|
|
16
|
-
// Catch silent Discord client errors
|
|
16
|
+
// Catch silent Discord client errors — route through log() once available
|
|
17
17
|
process.on('unhandledRejection', (reason) => {
|
|
18
|
-
|
|
18
|
+
const msg = reason?.message || reason;
|
|
19
|
+
if (typeof log === 'function') {
|
|
20
|
+
log('error', msg);
|
|
21
|
+
} else {
|
|
22
|
+
process.stderr.write(`[UNHANDLED REJECTION] ${msg}\n`);
|
|
23
|
+
}
|
|
19
24
|
});
|
|
20
25
|
process.on('uncaughtException', (err) => {
|
|
21
|
-
|
|
26
|
+
if (typeof log === 'function') {
|
|
27
|
+
log('error', err.message);
|
|
28
|
+
} else {
|
|
29
|
+
process.stderr.write(`[UNCAUGHT] ${err.message}\n`);
|
|
30
|
+
}
|
|
22
31
|
});
|
|
23
32
|
|
|
24
33
|
// ── Memory-Optimized Client Factory ──────────────────────────
|
|
@@ -2768,7 +2777,7 @@ async function start(apiKey, apiUrl, opts = {}) {
|
|
|
2768
2777
|
|
|
2769
2778
|
// Init rawLogger Redis (uses same URL — logs all raw gateway data)
|
|
2770
2779
|
if (REDIS_URL) {
|
|
2771
|
-
rawLogger.init(REDIS_URL).catch(() => {});
|
|
2780
|
+
rawLogger.init(REDIS_URL, { silent: true }).catch(() => {});
|
|
2772
2781
|
// Listen for DM events across all accounts — update worker state + dashboard LIVE
|
|
2773
2782
|
rawLogger.onDmEvent((event, raw) => {
|
|
2774
2783
|
const channelId = raw.channel_id;
|
package/lib/rawLogger.js
CHANGED
|
@@ -28,11 +28,15 @@ const memStore = new Map();
|
|
|
28
28
|
const channelLast = new Map();
|
|
29
29
|
const memRing = [];
|
|
30
30
|
let memIdx = 0;
|
|
31
|
+
let _silent = false;
|
|
32
|
+
function _log(...args) { if (!_silent) console.log(...args); }
|
|
33
|
+
function _err(...args) { if (!_silent) console.error(...args); }
|
|
31
34
|
|
|
32
35
|
// ── Redis init ──
|
|
33
|
-
async function init(redisUrl) {
|
|
36
|
+
async function init(redisUrl, opts = {}) {
|
|
37
|
+
if (opts.silent) _silent = true;
|
|
34
38
|
if (!redisUrl) {
|
|
35
|
-
|
|
39
|
+
_log('[rawLogger] No Redis URL — raw logging disabled');
|
|
36
40
|
return;
|
|
37
41
|
}
|
|
38
42
|
try {
|
|
@@ -44,7 +48,7 @@ async function init(redisUrl) {
|
|
|
44
48
|
});
|
|
45
49
|
// Skip if already connecting or connected
|
|
46
50
|
if (redis.status === 'connecting' || redis.status === 'connect' || redis.status === 'ready') {
|
|
47
|
-
|
|
51
|
+
_log('[rawLogger] Redis already connecting — skipping');
|
|
48
52
|
redisReady = false;
|
|
49
53
|
return;
|
|
50
54
|
}
|
|
@@ -58,12 +62,12 @@ async function init(redisUrl) {
|
|
|
58
62
|
redis.connect().catch(reject);
|
|
59
63
|
});
|
|
60
64
|
redisReady = true;
|
|
61
|
-
|
|
65
|
+
_log('[rawLogger] Redis connected');
|
|
62
66
|
redis.on('error', (e) => {
|
|
63
67
|
// Suppress common transient network errors from spamming stderr
|
|
64
68
|
const msg = e?.message || '';
|
|
65
69
|
if (msg.includes('ETIMEDOUT') || msg.includes('ECONNRESET') || msg.includes('ENOTFOUND') || msg.includes('read') || msg.includes('connect')) return;
|
|
66
|
-
|
|
70
|
+
_err(`[rawLogger] Redis error: ${msg}`);
|
|
67
71
|
redisReady = false;
|
|
68
72
|
});
|
|
69
73
|
redis.on('close', () => {
|
|
@@ -79,7 +83,7 @@ async function init(redisUrl) {
|
|
|
79
83
|
// Suppress "already connecting" errors — happens when Redis reconnects mid-init
|
|
80
84
|
const msg = e?.message || '';
|
|
81
85
|
if (!msg.includes('already connecting') && !msg.includes('already connected')) {
|
|
82
|
-
|
|
86
|
+
_err(`[rawLogger] Redis connect failed: ${msg}`);
|
|
83
87
|
}
|
|
84
88
|
redis = null;
|
|
85
89
|
redisReady = false;
|
package/lib/ui.js
CHANGED
|
@@ -59,7 +59,7 @@ const DIM = c.dim;
|
|
|
59
59
|
|
|
60
60
|
function trunc(s, n) { s = String(s || ''); return s.length <= n ? s : s.slice(0, n - 1) + '…'; }
|
|
61
61
|
function padR(s, n) { return trunc(s, n).padEnd(n); }
|
|
62
|
-
function padL(s, n) { return String(s).padStart(n); }
|
|
62
|
+
function padL(s, n, char) { return String(s).padStart(n, char || ' '); }
|
|
63
63
|
function padC(s, n) {
|
|
64
64
|
s = String(s || '');
|
|
65
65
|
const pad = Math.max(0, n - s.length);
|
|
@@ -120,7 +120,9 @@ function draw() {
|
|
|
120
120
|
const T = '─'.repeat(W - 2); // inner width
|
|
121
121
|
|
|
122
122
|
// ── Top of box ──
|
|
123
|
-
|
|
123
|
+
// Move cursor to top-left of box area and overwrite in place (no full clear)
|
|
124
|
+
process.stdout.write(`\x1b[${1};1H`);
|
|
125
|
+
process.stdout.write(`\x1b[0J`); // clear from cursor to end of screen
|
|
124
126
|
process.stdout.write(`\x1b[38;2;77;212;238m┌─${T}─┐\x1b[0m\n`);
|
|
125
127
|
|
|
126
128
|
// ── Banner inside box ──
|
|
@@ -219,7 +221,7 @@ function draw() {
|
|
|
219
221
|
process.stdout.write(`${c.bold}Σ${c.reset} `);
|
|
220
222
|
process.stdout.write(`${DIM}${padL(_workers.length, 2)} acc${c.reset} `);
|
|
221
223
|
process.stdout.write(`${' '.repeat(col.name)} `);
|
|
222
|
-
process.stdout.write(`${DIM}${
|
|
224
|
+
process.stdout.write(`${DIM}${' '.repeat(col.last)}${c.reset} `);
|
|
223
225
|
process.stdout.write(`${padL(totalCmds, col.cmds)} `);
|
|
224
226
|
process.stdout.write(`${padL(rate, col.ok)}% `);
|
|
225
227
|
process.stdout.write(`${totalCoins > 0 ? c.green + padL('+' + totalCoins.toLocaleString(), col.earned) + c.reset : DIM + padL('—', col.earned) + c.reset} `);
|