diff --git a/web/request-handler.sx b/web/request-handler.sx index 64ea34e2..0c32ce6e 100644 --- a/web/request-handler.sx +++ b/web/request-handler.sx @@ -1,3 +1,44 @@ +(define + sx-handle-request + (fn + (path headers env) + (let + ((is-ajax (or (has-key? headers "sx-request") (has-key? headers "hx-request"))) + (path-expr (sx-parse-url path)) + (page-ast (sx-eval-page path-expr env))) + (if + (nil? page-ast) + nil + (let + ((nav-path (if (starts-with? path "/sx/") path (str "/sx" path)))) + (if + is-ajax + (sx-render-ajax page-ast nav-path env) + (sx-render-full-page page-ast nav-path env))))))) + +(define + sx-parse-url + (fn + (path) + (let + ((p (cond (or (= path "/") (= path "/sx/") (= path "/sx")) "home" (starts-with? path "/sx/") (substring path 4 (string-length path)) (starts-with? path "/") (substring path 1 (string-length path)) :else path))) + (let ((spaced (join " " (split p ".")))) spaced)))) + +(define + sx-eval-page + (fn + (path-expr env) + (let + ((exprs (sx-parse path-expr))) + (when + (not (empty? exprs)) + (let + ((expr (if (= (len exprs) 1) (first exprs) exprs)) + (quoted (sx-auto-quote expr env))) + (let + ((callable (if (symbol? quoted) (list quoted) quoted))) + (cek-try (fn () (eval-expr callable env)) (fn (err) nil)))))))) + (define sx-auto-quote (fn @@ -10,66 +51,53 @@ :else expr))) (define - sx-expr-to-str + sx-render-ajax (fn - (expr) - (cond - (string? expr) - (str "\"" expr "\"") - (symbol? expr) - (symbol-name expr) - (list? expr) - (str "(" (join " " (map sx-expr-to-str expr)) ")") - :else (str expr)))) + (page-ast nav-path env) + (let + ((wrapped (list (make-symbol "~layouts/doc") :path nav-path page-ast)) + (aser-result (aser (list (make-symbol "quote") wrapped) env))) + (let + ((body-exprs (sx-parse aser-result))) + (let + ((body-expr (if (= (len body-exprs) 1) (first body-exprs) (cons (make-symbol "<>") body-exprs)))) + (render-to-html body-expr env)))))) (define - sx-handle-request + sx-render-full-page (fn - (path headers env) + (page-ast nav-path env) (let - ((is-ajax (or (has-key? headers "sx-request") (has-key? headers "hx-request"))) - (raw-sx - (if - (or (= path "/sx/") (= path "/")) - "(home)" - (slice path 4 (len path)))) - (page-sx-raw (replace raw-sx "." " ")) - (page-exprs (sx-parse page-sx-raw)) - (page-expr (if (empty? page-exprs) nil (first page-exprs))) - (page-sx - (if - (nil? page-expr) - page-sx-raw - (sx-expr-to-str (sx-auto-quote page-expr env)))) - (layout-sx (str "(~layouts/doc :path \"" path "\" " page-sx ")"))) - (if - is-ajax + ((wrapped (list (make-symbol "~layouts/doc") :path nav-path page-ast)) + (full-ast + (list (make-symbol "~shared:layout/app-body") :content wrapped))) + (let + ((aser-result (aser (list (make-symbol "quote") full-ast) env))) (let - ((full-sx (render-to-sx (first (sx-parse layout-sx)) env))) - full-sx) - (let - ((body-html (render-to-html (first (sx-parse layout-sx)) env))) - (render-to-html - (quasiquote + ((body-exprs (sx-parse aser-result))) + (let + ((body-expr (if (= (len body-exprs) 1) (first body-exprs) (cons (make-symbol "<>") body-exprs)))) + (let + ((body-html (render-to-html body-expr env)) + (page-source (serialize full-ast))) (~shared:shell/sx-page-shell - :title "sx" + :title "SX" :csrf "" - :page-sx (unquote layout-sx) - :body-html (unquote body-html) - :component-defs (unquote (env-get env "__shell-component-defs")) - :component-hash (unquote (env-get env "__shell-component-hash")) - :pages-sx (unquote (env-get env "__shell-pages-sx")) - :sx-css (unquote (env-get env "__shell-sx-css")) - :sx-css-classes (unquote (env-get env "__shell-sx-css-classes")) - :asset-url (unquote (env-get env "__shell-asset-url")) - :sx-js-hash (unquote (env-get env "__shell-sx-js-hash")) - :body-js-hash (unquote (env-get env "__shell-body-js-hash")) - :wasm-hash (unquote (env-get env "__shell-wasm-hash")) - :head-scripts nil - :body-scripts nil - :inline-css nil - :inline-head-js nil - :init-sx nil - :use-wasm true - :meta-html "")) - env)))))) + :page-sx page-source + :body-html body-html + :component-defs __shell-component-defs + :component-hash __shell-component-hash + :pages-sx __shell-pages-sx + :sx-css __shell-sx-css + :sx-css-classes __shell-sx-css-classes + :asset-url __shell-asset-url + :sx-js-hash __shell-sx-js-hash + :body-js-hash __shell-body-js-hash + :wasm-hash __shell-wasm-hash + :head-scripts __shell-head-scripts + :body-scripts __shell-body-scripts + :inline-css __shell-inline-css + :inline-head-js __shell-inline-head-js + :init-sx __shell-init-sx + :use-wasm (= (or (env-get env "SX_USE_WASM") "") "1") + :meta-html ""))))))))