novy-syndicate/src/secure-chat-moderator.ts

43 lines
1.5 KiB
TypeScript

import { $claimNick, $joinedUser, asNickClaim, fromJoin, fromNickConflict, fromUserInfo, Join, NickConflict, UserId, UserInfo } from "./gen/secure-chat-protocol.js";
import { Assertion, Handle, Ref, Turn } from "./actor.js";
import { observe, during, $Observe, asObserve } from "./dataspace.js";
export default function (t: Turn, ds: Ref) {
let nextUserId: UserId = 0;
const nicks = new Map<string, UserId>();
const users = new Map<UserId, { infoHandle: Handle | undefined, nick: string | undefined }>();
observe(t, ds, $claimNick, {
assert(t: Turn, c0: Assertion): void {
const c = asNickClaim(c0);
if (nicks.has(c.name)) {
t.message(c.k, fromNickConflict(NickConflict()));
} else {
t.message(c.k, true);
let u = users.get(c.uid);
if (!u) {
u = { infoHandle: void 0, nick: void 0 };
users.set(c.uid, u);
}
if (u.nick !== void 0) nicks.delete(u.nick);
u.infoHandle = t.replace(ds, u.infoHandle, fromUserInfo(UserInfo(c)));
u.nick = c.name;
nicks.set(c.name, c.uid);
}
}
});
observe(t, ds, $Observe, during((t, o0) => {
const o = asObserve(o0);
if (o.label !== $joinedUser) return null;
const uid: UserId = nextUserId++;
const h = t.assert(o.observer, fromJoin(Join({
uid,
handle: ds,
})));
return t => t.retract(h);
}));
}