novy-syndicate/src/examples/secure-chat-client.ts

80 lines
2.9 KiB
TypeScript
Raw Permalink Normal View History

2021-10-11 10:55:45 +00:00
import { $joinedUser, $says, $user, fromNickClaim, fromSays, NickClaim, Says, UserId } from "../gen/secureChatProtocol.js";
import { during, observe, P } from "../runtime/dataspace.js";
import { Assertion, Ref, Turn } from "../runtime/actor.js";
import { attachReadline } from './readline.js';
import { Embedded } from "@preserves/core";
export default function (t: Turn, ds_ptr: Embedded<Ref>) {
const ds = ds_ptr.embeddedValue;
2021-10-11 11:06:57 +00:00
observe(t, ds, P.rec($joinedUser, P.bind(), P.bind()),
2021-10-11 10:55:45 +00:00
during(async (t, bindings) => {
let [uid, handle] = bindings as [UserId, Ref];
const facet = t.facet(t => runSession(t, uid, handle));
return t => t.stop(facet);
}));
}
function runSession(t: Turn, uid: UserId, session: Ref) {
let username: string | undefined;
let cleanShutdown = false;
t.activeFacet.onStop(_t => {
if (!cleanShutdown) {
console.log('Moderator retracted room permission.');
}
});
function updateUsername(t: Turn, name: string) {
const q = t.assert(session, fromNickClaim(NickClaim({ uid, name, k: t.ref({
message(t, reply0) {
if (reply0 === true) {
username = name;
console.log(`Nick changed to ${username}`);
} else {
console.log(`Nick conflict: name is still ${username ?? '<not set>'}`);
}
t.retract(q);
}
})})));
}
updateUsername(t, 'user' + process.pid);
const users = new Map<UserId, string>();
2021-10-11 11:06:57 +00:00
observe(t, session, P.rec($user, P.bind(), P.bind()),
2021-10-11 10:55:45 +00:00
during(async (_t, bindings) => {
let [uid, name] = bindings as [UserId, string];
const oldName = users.get(uid);
console.log(oldName === void 0
? `${name} arrived`
: `${oldName} changed name to ${name}`);
users.set(uid, name);
return (_t) => {
if (users.get(uid) === name) {
console.log(`${name} departed`);
users.delete(uid);
}
};
}));
2021-10-11 11:06:57 +00:00
observe(t, session, P.rec($says, P.bind(), P.bind()), {
2021-10-11 10:55:45 +00:00
message(_t: Turn, bindings: Assertion): void {
let [who, what] = bindings as [UserId, string];
console.log(`${users.get(who) ?? `<unknown ${who}>`}: ${what}`);
},
});
attachReadline(t, {
retract(t) {
cleanShutdown = true;
t.stopActor();
},
message(t, line: string) {
if (line.toLowerCase().startsWith('/nick ')) {
updateUsername(t, line.slice(5).trimLeft());
} else {
t.message(session, fromSays(Says({ who: uid, what: line })));
}
},
});
}