lib/client: generalize pendingWHOIS, store list in ENDOF* messages

This allows processing a list of replies atomically and receiving
the ENDOF* marker.
This commit is contained in:
Simon Ser 2021-10-23 20:03:57 +02:00
parent b059e034e2
commit 92043ded2c

View File

@ -79,7 +79,7 @@ export default class Client extends EventTarget {
pendingHistory = Promise.resolve(null);
cm = irc.CaseMapping.RFC1459;
monitored = new irc.CaseMapMap(null, irc.CaseMapping.RFC1459);
pendingWHOIS = new irc.CaseMapMap(null, irc.CaseMapping.RFC1459);
pendingLists = new irc.CaseMapMap(null, irc.CaseMapping.RFC1459);
whoxQueries = new Map();
constructor(params) {
@ -186,6 +186,20 @@ export default class Client extends EventTarget {
});
}
pushPendingList(k, msg) {
let l = this.pendingLists.get(k);
if (!l) {
l = [];
this.pendingLists.set(k, l);
}
l.push(msg);
}
endPendingList(k, msg) {
msg.list = this.pendingLists.get(k) || [];
this.pendingLists.delete(k);
}
handleMessage(event) {
if (typeof event.data !== "string") {
console.error("Received unsupported data type:", event.data);
@ -211,6 +225,7 @@ export default class Client extends EventTarget {
}
let deleteBatch = null;
let k;
switch (msg.command) {
case irc.RPL_WELCOME:
if (this.params.saslPlain && this.availableCaps["sasl"] === undefined) {
@ -266,23 +281,21 @@ export default class Client extends EventTarget {
this.send({ command: "CAP", params: ["END"] });
}
break;
case irc.RPL_NAMREPLY:
this.pushPendingList("NAMES " + msg.params[2], msg);
break;
case irc.RPL_ENDOFNAMES:
this.endPendingList("NAMES " + msg.params[1], msg);
break;
case irc.RPL_WHOISUSER:
case irc.RPL_WHOISSERVER:
case irc.RPL_WHOISOPERATOR:
case irc.RPL_WHOISIDLE:
case irc.RPL_WHOISCHANNELS:
this.pushPendingList("WHOIS " + msg.params[1], msg);
break;
case irc.RPL_ENDOFWHOIS:
let nick = msg.params[1];
let whois = this.pendingWHOIS.get(nick);
if (!whois) {
whois = {};
this.pendingWHOIS.set(nick, whois);
}
whois[msg.command] = msg;
if (msg.command == irc.RPL_ENDOFWHOIS) {
this.pendingWHOIS.delete(nick);
msg.whois = whois;
}
this.endPendingList("WHOIS " + msg.params[1], msg);
break;
case irc.ERR_NICKLOCKED:
case irc.ERR_SASLFAIL:
@ -446,7 +459,11 @@ export default class Client extends EventTarget {
case irc.RPL_ENDOFWHOIS:
nick = msg.params[1];
if (this.cm(nick) === targetCM) {
return msg.whois;
let whois = {};
msg.list.forEach((reply) => {
whois[reply.command] = reply;
});
return whois;
}
break;
case irc.ERR_NOSUCHNICK:
@ -593,7 +610,7 @@ export default class Client extends EventTarget {
this.cm = irc.CaseMapping.RFC1459;
}
this.pendingWHOIS = new irc.CaseMapMap(this.pendingWHOIS, this.cm);
this.pendingLists = new irc.CaseMapMap(this.pendingLists, this.cm);
this.monitored = new irc.CaseMapMap(this.monitored, this.cm);
}