mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-29 17:01:55 +00:00
Refactored `src/cmd-list.mjs` to use a `Set` for roster lookups, reducing complexity from O(M*N) to O(M+N). Added dependency injection to `cmdList` to enable unit testing. Added `test/cmd-list.test.mjs` to verify functionality. Co-authored-by: PR0M3TH3AN <[email protected]>
75 lines
2.5 KiB
JavaScript
75 lines
2.5 KiB
JavaScript
import {
|
|
getRelays as _getRelays,
|
|
getNamespace as _getNamespace,
|
|
} from './torch-config.mjs';
|
|
import { getRoster as _getRoster } from './roster.mjs';
|
|
import { queryLocks as _queryLocks } from './lock-ops.mjs';
|
|
import { todayDateStr as _todayDateStr, nowUnix as _nowUnix } from './utils.mjs';
|
|
|
|
export async function cmdList(cadence, deps = {}) {
|
|
const {
|
|
getRelays = _getRelays,
|
|
getNamespace = _getNamespace,
|
|
getRoster = _getRoster,
|
|
queryLocks = _queryLocks,
|
|
todayDateStr = _todayDateStr,
|
|
nowUnix = _nowUnix,
|
|
log = console.log,
|
|
error = console.error,
|
|
} = deps;
|
|
|
|
const relays = await getRelays();
|
|
const namespace = await getNamespace();
|
|
const dateStr = todayDateStr();
|
|
const cadences = cadence ? [cadence] : ['daily', 'weekly'];
|
|
|
|
error(`Listing active locks: namespace=${namespace}, cadences=${cadences.join(', ')}`);
|
|
|
|
const results = await Promise.all(
|
|
cadences.map(async (c) => {
|
|
const locks = await queryLocks(relays, c, dateStr, namespace);
|
|
return { c, locks };
|
|
}),
|
|
);
|
|
|
|
for (const { c, locks } of results) {
|
|
log(`\n${'='.repeat(72)}`);
|
|
log(`Active ${namespace} ${c} locks (${dateStr})`);
|
|
log('='.repeat(72));
|
|
|
|
if (locks.length === 0) {
|
|
log(' (no active locks)');
|
|
continue;
|
|
}
|
|
|
|
const sorted = locks.sort((a, b) => a.createdAt - b.createdAt);
|
|
for (const lock of sorted) {
|
|
const age = nowUnix() - lock.createdAt;
|
|
const ageMin = Math.round(age / 60);
|
|
const remaining = lock.expiresAt ? lock.expiresAt - nowUnix() : null;
|
|
const remainMin = remaining ? Math.round(remaining / 60) : '?';
|
|
|
|
log(
|
|
` ${(lock.agent ?? 'unknown').padEnd(30)} ` +
|
|
`age: ${String(ageMin).padStart(4)}m ` +
|
|
`ttl: ${String(remainMin).padStart(4)}m ` +
|
|
`platform: ${lock.platform ?? '?'} ` +
|
|
`event: ${lock.eventId?.slice(0, 12)}...`,
|
|
);
|
|
}
|
|
|
|
const roster = await getRoster(c);
|
|
const rosterSet = new Set(roster);
|
|
const lockedAgents = new Set(locks.map((l) => l.agent).filter(Boolean));
|
|
const unknownLockedAgents = [...lockedAgents].filter((agent) => !rosterSet.has(agent));
|
|
const available = roster.filter((a) => !lockedAgents.has(a));
|
|
|
|
if (unknownLockedAgents.length > 0) {
|
|
log(` Warning: lock events found with non-roster agent names: ${unknownLockedAgents.join(', ')}`);
|
|
}
|
|
|
|
log(`\n Locked: ${lockedAgents.size}/${roster.length}`);
|
|
log(` Available: ${available.join(', ') || '(none)'}`);
|
|
}
|
|
}
|