Simplest chat system
This commit is contained in:
parent
4737a3d070
commit
f35815d62a
|
@ -0,0 +1,5 @@
|
|||
version 1 .
|
||||
pointer Actor.Ref .
|
||||
|
||||
Present = <Present @username string>.
|
||||
Says = <Says @who string @what string>.
|
|
@ -0,0 +1,60 @@
|
|||
import { $Present, $Says, asPresent, asSays, fromPresent, fromSays, Present, Says } from "./gen/chat-protocol.js";
|
||||
import { fromObserve, Observe } from "./gen/dataspace.js";
|
||||
import { Assertion, Handle, Ref, Turn } from "./actor.js";
|
||||
import readline from 'readline';
|
||||
|
||||
export default function (t: Turn, ds: Ref) {
|
||||
let username = '';
|
||||
let usernameHandle: Handle | undefined;
|
||||
|
||||
function updateUsername(t: Turn, u: string) {
|
||||
username = u;
|
||||
usernameHandle = t.replace(ds, usernameHandle, fromPresent(Present(username)));
|
||||
}
|
||||
updateUsername(t, 'user' + process.pid);
|
||||
|
||||
const usermap = new Map<Handle, Present>();
|
||||
t.assert(ds, fromObserve(Observe({
|
||||
label: $Present,
|
||||
observer: t.ref({
|
||||
assert(t: Turn, e0: Assertion, h: Handle): void {
|
||||
const e = asPresent(e0);
|
||||
console.log(`${e.username} arrived`);
|
||||
usermap.set(h, e);
|
||||
},
|
||||
retract(t: Turn, h: Handle): void {
|
||||
const e = usermap.get(h);
|
||||
if (e) {
|
||||
usermap.delete(h);
|
||||
console.log(`${e.username} departed`);
|
||||
}
|
||||
},
|
||||
}),
|
||||
})));
|
||||
|
||||
t.assert(ds, fromObserve(Observe({
|
||||
label: $Says,
|
||||
observer: t.ref({
|
||||
message(t: Turn, u0: Assertion): void {
|
||||
const u = asSays(u0);
|
||||
console.log(`${u.who}: ${u.what}`);
|
||||
},
|
||||
}),
|
||||
})));
|
||||
|
||||
function sendUtterance(what: string) {
|
||||
t.freshen(t => t.message(ds, fromSays(Says({ who: username, what }))));
|
||||
}
|
||||
|
||||
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
||||
|
||||
rl.on('line', (line: string) => {
|
||||
if (line.startsWith('/nick ')) {
|
||||
t.freshen(t => updateUsername(t, line.slice(5).trimLeft()));
|
||||
} else {
|
||||
sendUtterance(line);
|
||||
}
|
||||
});
|
||||
|
||||
rl.on('close', () => t.freshen(t => t.quit()));
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
import * as _ from "@preserves/core";
|
||||
import * as _i_Actor from "../actor";
|
||||
|
||||
export const $Present = Symbol.for("Present");
|
||||
export const $Says = Symbol.for("Says");
|
||||
|
||||
export type _ptr = _i_Actor.Ref;
|
||||
|
||||
export type _val = _.Value<_ptr>;
|
||||
|
||||
export type Present = {"username": string};
|
||||
|
||||
export type Says = {"who": string, "what": string};
|
||||
|
||||
|
||||
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
|
||||
|
||||
export function Present(username: string): Present {return {"username": username};}
|
||||
|
||||
export function Says({who, what}: {who: string, what: string}): Says {return {"who": who, "what": what};}
|
||||
|
||||
export function asPresent(v: _val): Present {
|
||||
let result = toPresent(v);
|
||||
if (result === void 0) throw new TypeError(`Invalid Present: ${_.stringify(v)}`);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function toPresent(v: _val): undefined | Present {
|
||||
let result: undefined | Present;
|
||||
if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) {
|
||||
let _tmp0: (null) | undefined;
|
||||
_tmp0 = _.is(v.label, $Present) ? null : void 0;
|
||||
if (_tmp0 !== void 0) {
|
||||
let _tmp1: (string) | undefined;
|
||||
_tmp1 = typeof v[0] === 'string' ? v[0] : void 0;
|
||||
if (_tmp1 !== void 0) {result = {"username": _tmp1};};
|
||||
};
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
export function fromPresent(_v: Present): _val {return _.Record($Present, [_v["username"]]);}
|
||||
|
||||
export function asSays(v: _val): Says {
|
||||
let result = toSays(v);
|
||||
if (result === void 0) throw new TypeError(`Invalid Says: ${_.stringify(v)}`);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function toSays(v: _val): undefined | Says {
|
||||
let result: undefined | Says;
|
||||
if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) {
|
||||
let _tmp0: (null) | undefined;
|
||||
_tmp0 = _.is(v.label, $Says) ? null : void 0;
|
||||
if (_tmp0 !== void 0) {
|
||||
let _tmp1: (string) | undefined;
|
||||
_tmp1 = typeof v[0] === 'string' ? v[0] : void 0;
|
||||
if (_tmp1 !== void 0) {
|
||||
let _tmp2: (string) | undefined;
|
||||
_tmp2 = typeof v[1] === 'string' ? v[1] : void 0;
|
||||
if (_tmp2 !== void 0) {result = {"who": _tmp1, "what": _tmp2};};
|
||||
};
|
||||
};
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
export function fromSays(_v: Says): _val {return _.Record($Says, [_v["who"], _v["what"]]);}
|
||||
|
Loading…
Reference in New Issue