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