adamc@915: con rawMeta = fn t :: Type => adamc@915: {New : transaction t, adamc@915: Inj : sql_injectable t} adamc@915: adamc@915: con colMeta' = fn (row :: {Type}) (t :: Type) => adamc@915: {Header : string, adamc@915: Project : $row -> transaction t, adamc@915: Update : $row -> t -> transaction ($row), adamc@915: Display : t -> xbody, adamc@915: Edit : t -> xbody, adamc@915: Validate : t -> signal bool} adamc@915: adamc@915: con colMeta = fn (row :: {Type}) (global_t :: (Type * Type)) => adamc@915: {Initialize : transaction global_t.1, adamc@915: Handlers : global_t.1 -> colMeta' row global_t.2} adamc@915: adamc@915: structure Direct : sig adamc@915: con meta = fn global_actual_input :: (Type * Type * Type) => adamc@915: {Initialize : transaction global_actual_input.1, adamc@915: Handlers : global_actual_input.1 adamc@915: -> {Display : global_actual_input.3 -> xbody, adamc@915: Edit : global_actual_input.3 -> xbody, adamc@915: Initialize : global_actual_input.2 -> transaction global_actual_input.3, adamc@915: Parse : global_actual_input.3 -> signal (option global_actual_input.2)}} adamc@915: adamc@915: con editableState :: (Type * Type * Type) -> (Type * Type) adamc@915: val editable : ts ::: (Type * Type * Type) -> rest ::: {Type} adamc@915: -> nm :: Name -> [[nm] ~ rest] => string -> meta ts adamc@915: -> colMeta ([nm = ts.2] ++ rest) adamc@915: (editableState ts) adamc@915: adamc@915: con readOnlyState :: (Type * Type * Type) -> (Type * Type) adamc@915: val readOnly : ts ::: (Type * Type * Type) -> rest ::: {Type} adamc@915: -> nm :: Name -> [[nm] ~ rest] => string -> meta ts adamc@915: -> colMeta ([nm = ts.2] ++ rest) adamc@915: (readOnlyState ts) adamc@915: adamc@915: type intGlobal adamc@915: type intInput adamc@915: val int : meta (intGlobal, int, intInput) adamc@915: adamc@915: type stringGlobal adamc@915: type stringInput adamc@915: val string : meta (stringGlobal, string, stringInput) adamc@915: adamc@915: type boolGlobal adamc@915: type boolInput adamc@915: val bool : meta (boolGlobal, bool, boolInput) adamc@915: adamc@915: functor Foreign (M : sig adamc@915: con row :: {Type} adamc@915: con t :: Type adamc@915: val show_t : show t adamc@915: val read_t : read t adamc@915: val eq_t : eq t adamc@915: val inj_t : sql_injectable t adamc@915: con nm :: Name adamc@915: constraint [nm] ~ row adamc@915: table tab : ([nm = t] ++ row) adamc@915: val render : $([nm = t] ++ row) -> string adamc@915: end) : sig adamc@915: con global :: Type adamc@915: con input :: Type adamc@915: val meta : meta (global, M.t, input) adamc@915: end adamc@915: end adamc@915: adamc@915: con computedState :: (Type * Type) adamc@915: val computed : row ::: {Type} -> t ::: Type -> show t adamc@915: -> string -> ($row -> t) -> colMeta row computedState adamc@915: val computedHtml : row ::: {Type} -> string -> ($row -> xbody) -> colMeta row computedState adamc@915: adamc@915: functor Make(M : sig adamc@915: con key :: {Type} adamc@915: con row :: {Type} adamc@915: constraint key ~ row adamc@915: table tab : (key ++ row) adamc@915: adamc@915: val raw : $(map rawMeta (key ++ row)) adamc@915: adamc@915: con cols :: {(Type * Type)} adamc@915: val cols : $(map (colMeta (key ++ row)) cols) adamc@915: adamc@915: val keyFolder : folder key adamc@915: val rowFolder : folder row adamc@915: val colsFolder : folder cols adamc@915: end) : sig adamc@915: type grid adamc@915: adamc@915: val grid : transaction grid adamc@915: val sync : grid -> transaction unit adamc@915: val render : grid -> xbody adamc@915: end