universe level virtual machine
(ulvm.core/defscope :todo-svc
"Todo todo-svc"
{:ulvm.core/runnable-env-ref
{:ulvm.core/builtin-runnable-env-loader-name :ulvm.re-loaders/project-file
:ulvm.core/runnable-env-descriptor {:path "scopes/nodejs.ulvm"}}
:ulvm.core/parent-scope :todo-svc-container
:ulvm.core/modules {:validate-todo {:ulvm.core/tags #{:js-sync}
:ulvm.core/mod-descriptor
{:local-filename "todo-svc/validators/auth"}
:ulvm.core/config {
:ulvm.arg-mappings/positional [[:todo]]}}
...
Users can implement their own scopes
Scopes have modules
(ulvm.core/defflow :create-todo [session todo-list-id todo-text due-date]
{:ulvm.core/home-scope :todo-svc
:ulvm.core/output-descriptor {:err [(:err valid-todo) (:err stored-session)]
:success [todo-response]}
(session-user {:session session} :as session-user)
(todo-validator {:user session-user
:todo-list-id todo-list-id} :as valid-todo)
((:store-session todo-db) {:user session-user
:todo-list-id todo-list-id
:todo-text todo-text
:due-date due-date } :as stored-todo)
(:make-todo-response {:todo stored-todo} :as session-response
:after [stored-session]))
Flow arguments
Possible results
Remote invocation
(ulvm.core/defmodcombinator :js-sync
"Synchronous javascript function"
{:ulvm.core/runnable-env-ref
{:ulvm.core/runnable-env-loader-name :ulvm.re-loaders/project-file
:ulvm.core/runnable-env-descriptor {:path "mod-combinators/js-sync.ulvm"}})
Users can implement their own module combinators
{:org.ulvm.mod-combinators.js-sync/js-sync
{:ulvm.core/artifact-loader
{:ulvm.core/builtin-artifact-loader-name :ulvm.artifact-loaders/docker-hub
:ulvm.core/artifact-descriptor {:image "ulvm-js-sync:latest"}}
:ulvm.core/runner
{:ulvm.core/builtin-runner-name :ulvm.runners/docker-container
:ulvm.core/runner-descriptor
{:image (ulvm.core/from-env :image)
:host-cfg {:network-mode "bridge"}}}}}
Artifacts are loaded from somewhere
Artifacts need to be run
{:org.ulvm.mod-combinators.js-sync/block-with-results
{:ulvm.core/runner
{:ulvm.core/builtin-runner-name :ulvm.runners/http
:ulvm.core/runner-descriptor {:method :post
:url (ulvm.core/eval (str "http://"
(ulvm.core/from-env
:container-ip)
":8080/block"))
:body (ulvm.core/eval (pr-str *params*))
:headers {"content-type" "application/edn"}
:acceptable-statuses #{200}}}
:ulvm.core/ideal-flows #{:org.ulvm.mod-combinator/block-with-results}}
Flows must have some way of being invoked
Flows can declare that they implement some ideal flows