dankgrinder 5.0.2 → 5.0.3
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 +29 -37
- package/package.json +1 -1
package/lib/grinder.js
CHANGED
|
@@ -565,32 +565,20 @@ async function reportEarnings(accountId, accountName, earned, spent, command) {
|
|
|
565
565
|
earningsBatch.push({ account_id: accountId, account_name: accountName, earned, spent, command });
|
|
566
566
|
}
|
|
567
567
|
|
|
568
|
-
|
|
568
|
+
// Command feed sends directly (no batching) for real-time dashboard SSE updates.
|
|
569
|
+
// The dashboard live queue depends on instant delivery via eventBus.emit("sse").
|
|
570
|
+
async function reportCommandFeed(accountId, accountName, data) {
|
|
569
571
|
if (!API_URL) return;
|
|
572
|
+
const normalized = { ...data };
|
|
573
|
+
if (typeof normalized.command === 'string') normalized.command = stripAnsi(normalized.command).replace(/\s+/g, ' ').trim();
|
|
574
|
+
if (typeof normalized.result === 'string') normalized.result = stripAnsi(normalized.result).replace(/\s+/g, ' ').trim();
|
|
570
575
|
try {
|
|
571
|
-
await fetch(`${API_URL}/api/grinder/command-feed
|
|
576
|
+
await fetch(`${API_URL}/api/grinder/command-feed`, {
|
|
572
577
|
method: 'POST',
|
|
573
578
|
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
574
|
-
body: JSON.stringify({
|
|
579
|
+
body: JSON.stringify({ account_id: accountId, account_name: accountName, ...normalized }),
|
|
575
580
|
});
|
|
576
|
-
} catch {
|
|
577
|
-
for (const item of batch) {
|
|
578
|
-
try {
|
|
579
|
-
await fetch(`${API_URL}/api/grinder/command-feed`, {
|
|
580
|
-
method: 'POST',
|
|
581
|
-
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
582
|
-
body: JSON.stringify(item),
|
|
583
|
-
});
|
|
584
|
-
} catch {}
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
}, { maxSize: 100, flushMs: 2000 });
|
|
588
|
-
|
|
589
|
-
async function reportCommandFeed(accountId, accountName, data) {
|
|
590
|
-
const normalized = { ...data };
|
|
591
|
-
if (typeof normalized.command === 'string') normalized.command = stripAnsi(normalized.command).replace(/\s+/g, ' ').trim();
|
|
592
|
-
if (typeof normalized.result === 'string') normalized.result = stripAnsi(normalized.result).replace(/\s+/g, ' ').trim();
|
|
593
|
-
feedBatch.push({ account_id: accountId, account_name: accountName, ...normalized });
|
|
581
|
+
} catch { /* silent — dashboard just won't see this update */ }
|
|
594
582
|
}
|
|
595
583
|
|
|
596
584
|
function randomDelay(min, max) {
|
|
@@ -1886,7 +1874,7 @@ class AccountWorker {
|
|
|
1886
1874
|
this.tickTimeout = setTimeout(() => this.tick(), 5000);
|
|
1887
1875
|
return;
|
|
1888
1876
|
}
|
|
1889
|
-
if (this.busy) {
|
|
1877
|
+
if (this.busy || this._invRunning) {
|
|
1890
1878
|
this.tickTimeout = setTimeout(() => this.tick(), 2000);
|
|
1891
1879
|
return;
|
|
1892
1880
|
}
|
|
@@ -2189,9 +2177,9 @@ class AccountWorker {
|
|
|
2189
2177
|
// Handle pending actions from dashboard
|
|
2190
2178
|
if (Array.isArray(data.pendingActions)) {
|
|
2191
2179
|
for (const action of data.pendingActions) {
|
|
2192
|
-
if (action.action === 'check_inventory' && !this.busy) {
|
|
2180
|
+
if (action.action === 'check_inventory' && !this.busy && !this._invRunning) {
|
|
2193
2181
|
this.log('info', 'Dashboard requested inventory check');
|
|
2194
|
-
this.checkInventory().catch(() => {});
|
|
2182
|
+
await this.checkInventory().catch(() => {});
|
|
2195
2183
|
try {
|
|
2196
2184
|
await fetch(`${API_URL}/api/grinder/actions`, {
|
|
2197
2185
|
method: 'DELETE',
|
|
@@ -2280,6 +2268,8 @@ class AccountWorker {
|
|
|
2280
2268
|
|
|
2281
2269
|
// Let Discord gateway settle before sending first command
|
|
2282
2270
|
await new Promise(r => setTimeout(r, 2500));
|
|
2271
|
+
// Run initial inventory check (awaited) before grind loop starts
|
|
2272
|
+
await this.checkInventory().catch(() => {});
|
|
2283
2273
|
this.grindLoop();
|
|
2284
2274
|
resolve();
|
|
2285
2275
|
});
|
|
@@ -2341,7 +2331,6 @@ async function start(apiKey, apiUrl) {
|
|
|
2341
2331
|
API_URL = apiUrl || process.env.DANKGRINDER_URL || 'http://localhost:3000';
|
|
2342
2332
|
REDIS_URL = process.env.REDIS_URL || '';
|
|
2343
2333
|
WEBHOOK_URL = process.env.WEBHOOK_URL || '';
|
|
2344
|
-
initRedis();
|
|
2345
2334
|
|
|
2346
2335
|
process.stdout.write('\x1b[2J\x1b[H');
|
|
2347
2336
|
const tw = Math.min(process.stdout.columns || 80, 78);
|
|
@@ -2361,16 +2350,6 @@ async function start(apiKey, apiUrl) {
|
|
|
2361
2350
|
);
|
|
2362
2351
|
console.log(bar);
|
|
2363
2352
|
|
|
2364
|
-
const checks = [];
|
|
2365
|
-
checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${c.white}API${c.reset}`);
|
|
2366
|
-
if (REDIS_URL) checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${c.white}Redis${c.reset}`);
|
|
2367
|
-
if (hasZlib) checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${c.white}zlib${c.reset}`);
|
|
2368
|
-
if (WEBHOOK_URL) checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${c.white}Webhook${c.reset}`);
|
|
2369
|
-
if (CLUSTER_ENABLED) {
|
|
2370
|
-
checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${rgb(34, 211, 238)}Cluster${c.reset} ${c.dim}(${NODE_ID.substring(0, 12)})${c.reset}`);
|
|
2371
|
-
}
|
|
2372
|
-
console.log(` ${checks.join(' ')}`);
|
|
2373
|
-
|
|
2374
2353
|
log('info', `${c.dim}Fetching accounts...${c.reset}`);
|
|
2375
2354
|
|
|
2376
2355
|
let data = await fetchConfig(4, 2000);
|
|
@@ -2381,6 +2360,13 @@ async function start(apiKey, apiUrl) {
|
|
|
2381
2360
|
data = await fetchConfig(4, 2000);
|
|
2382
2361
|
}
|
|
2383
2362
|
|
|
2363
|
+
// Pull Redis/Webhook URLs from API config if not in env
|
|
2364
|
+
if (!REDIS_URL && data.redis_url) REDIS_URL = data.redis_url;
|
|
2365
|
+
if (!REDIS_URL && data.redisUrl) REDIS_URL = data.redisUrl;
|
|
2366
|
+
if (!WEBHOOK_URL && data.webhook_url) WEBHOOK_URL = data.webhook_url;
|
|
2367
|
+
if (!WEBHOOK_URL && data.webhookUrl) WEBHOOK_URL = data.webhookUrl;
|
|
2368
|
+
initRedis();
|
|
2369
|
+
|
|
2384
2370
|
let { accounts } = data;
|
|
2385
2371
|
if (!accounts || accounts.length === 0) {
|
|
2386
2372
|
log('error', 'No active accounts. Add them in the dashboard.');
|
|
@@ -2397,9 +2383,15 @@ async function start(apiKey, apiUrl) {
|
|
|
2397
2383
|
}
|
|
2398
2384
|
}
|
|
2399
2385
|
|
|
2386
|
+
const checks = [];
|
|
2387
|
+
checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${c.white}API${c.reset}`);
|
|
2388
|
+
if (REDIS_URL) checks.push(redis ? `${rgb(52, 211, 153)}✓${c.reset} ${c.white}Redis${c.reset}` : `${rgb(251, 191, 36)}○${c.reset} ${c.dim}Redis (connecting...)${c.reset}`);
|
|
2389
|
+
if (hasZlib) checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${c.white}zlib${c.reset}`);
|
|
2390
|
+
if (WEBHOOK_URL) checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${c.white}Webhook${c.reset}`);
|
|
2391
|
+
if (CLUSTER_ENABLED) {
|
|
2392
|
+
checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${rgb(34, 211, 238)}Cluster${c.reset} ${c.dim}(${NODE_ID.substring(0, 12)})${c.reset}`);
|
|
2393
|
+
}
|
|
2400
2394
|
checks.push(`${rgb(52, 211, 153)}✓${c.reset} ${c.white}${accounts.length} Account${accounts.length > 1 ? 's' : ''}${c.reset}`);
|
|
2401
|
-
process.stdout.write(c.cursorUp(1));
|
|
2402
|
-
process.stdout.write(c.clearLine + '\r');
|
|
2403
2395
|
console.log(` ${checks.join(' ')}`);
|
|
2404
2396
|
console.log('');
|
|
2405
2397
|
|