147 lines
3.6 KiB
Bash
Executable File
147 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
ds_handle=0
|
|
ds_buf=""
|
|
declare -A ds_handles
|
|
declare -A ds_handle_oids
|
|
declare -A ds_object_map
|
|
declare -A ds_retraction_handlers
|
|
|
|
ds_project() {
|
|
# cargo install preserves-tools
|
|
echo "$1" | preserves-tool convert --indent=no --select "$2"
|
|
}
|
|
|
|
ds_connect() {
|
|
local f=$(mktemp -u /tmp/ds.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)
|
|
mkfifo $f
|
|
|
|
trap "rm -f $f" 2 EXIT RETURN
|
|
{
|
|
eval "$1"
|
|
ds_flush
|
|
ds_mainloop
|
|
} 5< <(nc -U ./sock <$f) 6>$f
|
|
}
|
|
|
|
ds_send() {
|
|
echo "$@" >&6
|
|
# echo "SENDING: $@"
|
|
}
|
|
|
|
ds_mainloop() {
|
|
while read ds_packet
|
|
do
|
|
# echo "RECEIVING: $ds_packet"
|
|
while read ds_turnevent
|
|
do
|
|
ds_dispatch "$(ds_project "$ds_turnevent" '. 0')" "$(ds_project "$ds_turnevent" '. 1')"
|
|
done < <(ds_project "$ds_packet" 'seq /')
|
|
ds_flush
|
|
done <&5
|
|
}
|
|
|
|
ds_dispatch() {
|
|
ds_event="$2"
|
|
eval "${ds_object_map[$1]}"
|
|
}
|
|
|
|
ds_action() {
|
|
case $(ds_project "$1" '.embedded . 0') in
|
|
0) ds_dispatch "$(ds_project "$1" '.embedded . 1')" "$2" ;;
|
|
1) ds_buf="${ds_buf}[$(ds_project "$1" '.embedded . 1') $2]" ;;
|
|
esac
|
|
}
|
|
|
|
ds_flush() {
|
|
if [ -n "$ds_buf" ]
|
|
then
|
|
ds_send "[$ds_buf]"
|
|
ds_buf=""
|
|
fi
|
|
}
|
|
|
|
ds_assert() {
|
|
local h="$ds_handle"
|
|
ds_handle=$(($ds_handle + 1))
|
|
ds_action "$1" "<assert $2 $h>"
|
|
if [ -n "${3:-}" ]
|
|
then
|
|
ds_handle_oids[$3]="$1"
|
|
ds_handles[$3]="$h"
|
|
fi
|
|
}
|
|
|
|
ds_retract() {
|
|
ds_action "${ds_handle_oids[$1]}" "<retract ${ds_handles[$1]}>"
|
|
}
|
|
|
|
ds_message() {
|
|
ds_action "$1" "<message $2>"
|
|
}
|
|
|
|
ds_object() {
|
|
local oid="$ds_handle"
|
|
ds_handle=$(($ds_handle + 1))
|
|
ds_object_map[$oid]="$2"
|
|
printf -v $1 '%s' "#![0,$oid]"
|
|
}
|
|
|
|
demo() {
|
|
demo_ds_resolved() {
|
|
local oid="$(ds_project "$ds_event" '^ assert . 0 .embedded . 1')"
|
|
if [ -n "$oid" ]
|
|
then
|
|
ds_ref="#![1 $oid]"
|
|
echo "Dataspace: $ds_ref"
|
|
|
|
username="user$$"
|
|
|
|
declare -A demo_user_presence
|
|
demo_presence() {
|
|
case $(ds_project "$ds_event" .^) in
|
|
assert)
|
|
local h="$(ds_project "$ds_event" '. 1')"
|
|
local who="$(ds_project "$ds_event" '. 0 . 0')"
|
|
demo_user_presence[$h]="$who"
|
|
echo "JOIN: $who"
|
|
;;
|
|
retract)
|
|
local h="$(ds_project "$ds_event" '. 0')"
|
|
local who="${demo_user_presence[$h]}"
|
|
echo "PART: $who"
|
|
unset 'demo_user_presence[$h]'
|
|
;;
|
|
esac
|
|
}
|
|
ds_object presence demo_presence
|
|
ds_assert "$ds_ref" "<Observe <compound <rec Present 1> {0: <bind <_>>}> $presence>"
|
|
ds_assert "$ds_ref" "<Present \"$username\">"
|
|
|
|
demo_utterance() {
|
|
ds_project "$ds_event" '^ message . 0'
|
|
}
|
|
ds_object utterance demo_utterance
|
|
ds_assert "$ds_ref" "<Observe <compound <rec Says 2> {0: <bind <_>> 1: <bind <_>>}> $utterance>"
|
|
|
|
ds_flush
|
|
ds_mainloop </dev/null &
|
|
mainloop_pid=$!
|
|
while read line
|
|
do
|
|
ds_message "$ds_ref" "<Says \"$username\" \"$line\">"
|
|
ds_flush
|
|
done </dev/tty
|
|
kill $mainloop_pid
|
|
exit 0
|
|
fi
|
|
}
|
|
ds_object bootk demo_ds_resolved
|
|
ds_connect 'ds_assert "#![1 0]" "<resolve <ref \"syndicate\" [] #x\"a6480df5306611ddd0d3882b546e1977\"> $bootk>"'
|
|
}
|
|
|
|
demo
|
|
|