open Versioned.Make(struct con key = [Id = int] con data = [Nam = string, ShoeSize = int] val key = {Id = _} val data = {Nam = {Inj = _, Eq = _}, ShoeSize = {Inj = _, Eq = _}} end) fun retro vr = ks <- keysAt vr; ks <- List.mapM (fn r => fso <- archive vr r; return (r.Id, fso)) ks; return <xml><body> {List.mapX (fn (k, r) => <xml><li> {[k]}: {case r of None => <xml>Whoa!</xml> | Some r => <xml>{[r.Nam]}, {[r.ShoeSize]}</xml>} </li></xml>) ks} </body></xml> fun expandKey k = name <- source ""; shoeSize <- source ""; return {Key = k, Nam = name, ShoeSize = shoeSize} fun main () = ks0 <- keys; ks0 <- List.mapM (fn r => expandKey r.Id) ks0; ks <- source ks0; id <- source ""; name <- source ""; shoeSize <- source ""; times <- updateTimes; return <xml><body> <dyn signal={ks <- signal ks; return (List.mapX (fn kr => <xml><div> {[kr.Key]}: <ctextbox source={kr.Nam}/> <ctextbox size={5} source={kr.ShoeSize}/> <button value="Latest" onclick={ro <- rpc (current {Id = kr.Key}); case ro of None => alert "Can't get it!" | Some r => set kr.Nam r.Nam; set kr.ShoeSize (show r.ShoeSize)}/> <button value="Update" onclick={name <- get kr.Nam; shoeSize <- get kr.ShoeSize; rpc (update {Id = kr.Key, Nam = name, ShoeSize = readError shoeSize}) }/> </div></xml>) ks)}/> <h2>Add one:</h2> <table> <tr><th>Id:</th> <td><ctextbox size={5} source={id}/></td></tr> <tr><th>Name:</th> <td><ctextbox source={name}/></td></tr> <tr><th>Shoe size:</th> <td><ctextbox size={5} source={shoeSize}/></td></tr> <tr><th><button value="Add" onclick={id <- get id; name <- get name; shoeSize <- get shoeSize; rpc (insert {Id = readError id, Nam = name, ShoeSize = readError shoeSize}); cur <- get ks; kr <- expandKey (readError id); set ks (kr :: cur)}/></th></tr> </table> <h2>Archive</h2> {List.mapX (fn (vr, tm) => <xml><li><a link={retro vr}>{[tm]}</a></li></xml>) times} </body></xml>