;; lib/dream/run.sx — Dream-on-SX entry point. ;; dream-run installs a root handler into the existing SX HTTP server via ;; (perform (:http/listen …)) — it does NOT implement its own socket loop. The ;; host invokes the installed app per request with a raw request dict; the app ;; adapts it to a dream-request, runs the handler, and serialises the response ;; (status/headers/body/set-cookies, or a websocket upgrade). Depends on types.sx ;; + websocket.sx. The listen transport is injectable for testing. ;; ── response serialisation for the host ──────────────────────────── (define dr/serialize-response (fn (resp) (if (dream-websocket? resp) {:websocket (dream-ws-handler resp) :body "" :headers (dream-headers resp) :status 101 :set-cookies (list)} {:body (dream-resp-body resp) :headers (dream-headers resp) :status (dream-status resp) :set-cookies (dream-resp-cookies resp)}))) ;; ── the app: raw host request -> serialised response ─────────────── (define dream-app (fn (handler) (fn (raw) (let ((req (dream-request (or (get raw :method) "GET") (or (get raw :target) (or (get raw :path) "/")) (or (get raw :headers) {}) (or (get raw :body) "")))) (dr/serialize-response (dream-coerce-response (handler req))))))) ;; ── dream-run ────────────────────────────────────────────────────── (define dream-default-port 8080) (define dream-run-with (fn (listen handler opts) (listen {:op "http/listen" :port (or (get opts :port) dream-default-port) :app (dream-app handler) :host (or (get opts :host) "0.0.0.0")}))) (define dream-perform-listen (fn (op) (perform op))) (define dream-run (fn (handler) (dream-run-with dream-perform-listen handler {}))) (define dream-run-port (fn (handler port) (dream-run-with dream-perform-listen handler {:port port}))) (define dream-run-opts (fn (handler opts) (dream-run-with dream-perform-listen handler opts)))