#!/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 local input="$1" local selector="$2" shift 2 echo "$input" | preserves-tool convert --indent=no --select "$selector" "$@" } ds_connect_stdio() { eval "$1" exec 5<&0 6>&1 ds_flush ds_mainloop } ds_connect() { local addr=$1 case $(ds_project "$addr" ".^") in tcp) nc_args="$(ds_project "$addr" ". 0" --output-format=unquoted) $(ds_project "$addr" ". 1")";; unix) nc_args="-U $(ds_project "$addr" ". 0" --output-format=unquoted)";; stdio) ds_connect_stdio "$2"; return;; *) echo "ds_connect: address '$addr' not supported"; return 1;; esac local f=$(mktemp -u /tmp/ds.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) mkfifo $f trap "rm -f $f" 2 EXIT RETURN { eval "$2" ds_flush ds_mainloop } 5< <(nc $nc_args <$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" "" if [ -n "${3:-}" ] then ds_handle_oids[$3]="$1" ds_handles[$3]="$h" fi } ds_retract() { ds_action "${ds_handle_oids[$1]}" "" } ds_message() { ds_action "$1" "" } 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" " {0: >}> $presence>" ds_assert "$ds_ref" "" demo_utterance() { ds_project "$ds_event" '^ message . 0' } ds_object utterance demo_utterance ds_assert "$ds_ref" " {0: > 1: >}> $utterance>" ds_flush ds_mainloop " ds_flush done ' \ 'ds_assert "#![1 0]" " $bootk>"' } demo