import { $claimNick, $joinedUser, $says, $user, Join, NickConflict, UserId, UserInfo, fromJoin, fromNickConflict, fromUserInfo, } from "../gen/secureChatProtocol.js"; import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js"; import { observe, during, $Observe, Dataspace, P, $rec, $compound } from "../runtime/dataspace.js"; import { attenuate, rfilter, pRec, pEmbedded, pString, pLit, pDiscard } from "../runtime/rewrite.js"; import { attenuate as sturdyAttenuate, KEY_LENGTH, sturdyEncode, fromSturdyRef, mint } from "../transport/sturdy.js"; import { Bind, fromBind } from "../gen/gatekeeper.js"; import { Bytes, Embedded } from "@preserves/core"; export default function (t: Turn, gatekeeperDs_ptr: Embedded) { const gatekeeperDs = gatekeeperDs_ptr.embeddedValue; const ds = t.ref(new Dataspace()); const chatOid = 'chat'; const chatKey = new Bytes(KEY_LENGTH); t.assert(gatekeeperDs, fromBind(Bind({ oid: chatOid, key: chatKey, target: ds }))); mint(chatOid, chatKey).then(async r => { r = await sturdyAttenuate(r, rfilter(pRec($Observe, pRec($compound, pRec($rec, pLit($joinedUser), pLit(2)), pDiscard()), pEmbedded()))); console.log(fromSturdyRef(r).asPreservesText()); console.log(sturdyEncode(fromSturdyRef(r)).toHex()); }); const nicks = new Map(); let nextUserId: UserId = 0; observe(t, ds, P.rec($Observe, P.rec($compound, P.rec($rec, P.lit($joinedUser), P.lit(2)), P.discard()), P.bind('observer', P.discard())), during(async (t, bindings) => { const [embeddedObserver] = bindings as [Embedded]; const observer = embeddedObserver.embeddedValue; const uid: UserId = nextUserId++; const f = t.facet(t => { t.assert(observer, fromJoin(Join({ uid, handle: attenuate(ds, rfilter( pRec($Observe, pLit($user), pEmbedded()), pRec($Observe, pLit($says), pEmbedded()), pRec($claimNick, pLit(uid), pString(), pEmbedded()), pRec($says, pLit(uid), pString()))), }))); let infoHandle: Handle | undefined; let nick: string | undefined; observe(t, ds, P.rec($claimNick, P.lit(uid), P.bind('name'), P.bind('k')), { assert(t: Turn, bindings: Assertion): void { const [name, embeddedK] = bindings as [string, Embedded]; const k = embeddedK.embeddedValue; if (nicks.has(name)) { t.message(k, fromNickConflict(NickConflict())); } else { t.message(k, true); if (nick !== void 0) nicks.delete(nick); infoHandle = t.replace(ds, infoHandle, fromUserInfo(UserInfo({ uid, name }))); nick = name; nicks.set(nick, uid); } } }); }); return t => t.stop(f); })); }