(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 (expr env) (cond (and (symbol? expr) (not (env-has? env (symbol-name expr)))) (symbol-name expr) (list? expr) (map (fn (e) (sx-auto-quote e env)) expr) :else expr))) (define sx-render-ajax (fn (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-render-full-page (fn (page-ast nav-path env) (let ((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 ((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" :csrf "" :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 ""))))))))