43 lines
1.5 KiB
TypeScript
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);
|
|
}));
|
|
}
|