diff --git a/hosts/ocaml/bin/sx_server.ml b/hosts/ocaml/bin/sx_server.ml index 43620c16..b38d7a6b 100644 --- a/hosts/ocaml/bin/sx_server.ml +++ b/hosts/ocaml/bin/sx_server.ml @@ -280,10 +280,44 @@ let flush_batched_io result_str = !final end +(** Resolve a library spec to a file path. + (sx render) → spec/render.sx, (sx bytecode) → lib/bytecode.sx, etc. + Returns Some path or None if unknown. *) +let _lib_base = ref "lib" +let _spec_base = ref "spec" +let _web_base = ref "web" + +let resolve_library_path lib_spec = + let parts = match lib_spec with List l | ListRef { contents = l } -> l | _ -> [] in + match List.map (fun v -> match v with Symbol s -> s | String s -> s | _ -> "") parts with + | ["sx"; name] -> + (* Check spec/ first, then lib/ *) + let spec_path = Filename.concat !_spec_base (name ^ ".sx") in + let lib_path = Filename.concat !_lib_base (name ^ ".sx") in + if Sys.file_exists spec_path then Some spec_path + else if Sys.file_exists lib_path then Some lib_path + else None + | ["web"; name] -> + let path = Filename.concat !_web_base (name ^ ".sx") in + if Sys.file_exists path then Some path else None + | [prefix; name] -> + (* Generic: try prefix/name.sx *) + let path = Filename.concat prefix (name ^ ".sx") in + if Sys.file_exists path then Some path else None + | _ -> None + +(** Load a library file — parse and evaluate all expressions in the global env. + The file should contain a define-library form that registers itself. *) +let _import_env : env option ref = ref None + +let load_library_file path = + let env = match !_import_env with Some e -> e | None -> Sx_types.make_env () in + let exprs = Sx_parser.parse_file path in + List.iter (fun expr -> ignore (Sx_ref.eval_expr expr (Env env))) exprs + (** IO-aware CEK run — handles suspension by dispatching IO requests. - When the CEK machine suspends with a perform, this function sends - the IO request to the Python bridge, resumes with the response, - and repeats until evaluation completes. *) + Import requests are handled locally (load .sx file). + Other IO requests are sent to the Python bridge. *) let cek_run_with_io state = let s = ref state in let is_terminal s = match Sx_ref.cek_terminal_p s with Bool true -> true | _ -> false in @@ -295,16 +329,27 @@ let cek_run_with_io state = if is_suspended !s then begin let request = Sx_runtime.get_val !s (String "request") in let op = match Sx_runtime.get_val request (String "op") with String s -> s | _ -> "" in - (* Extract args based on operation type *) - let args = match op with + let response = match op with | "import" -> - let lib = Sx_runtime.get_val request (String "library") in - [String "import"; lib] + (* Resolve library locally — load the .sx file *) + let lib_spec = Sx_runtime.get_val request (String "library") in + let key = Sx_ref.library_name_key lib_spec in + if Sx_types.sx_truthy (Sx_ref.library_loaded_p key) then + (* Already loaded — just resume *) + Nil + else begin + (match resolve_library_path lib_spec with + | Some path -> load_library_file path + | None -> + Printf.eprintf "[import] WARNING: no file for library %s\n%!" + (Sx_runtime.value_to_str lib_spec)); + Nil + end | _ -> - let a = Sx_runtime.get_val request (String "args") in - (match a with List l -> l | _ -> [a]) + let args = let a = Sx_runtime.get_val request (String "args") in + (match a with List l -> l | _ -> [a]) in + io_request op args in - let response = io_request op args in s := Sx_ref.cek_resume !s response; loop () end else diff --git a/hosts/ocaml/lib/sx_ref.ml b/hosts/ocaml/lib/sx_ref.ml index befc1de6..ed8d5d41 100644 --- a/hosts/ocaml/lib/sx_ref.ml +++ b/hosts/ocaml/lib/sx_ref.ml @@ -503,7 +503,7 @@ and step_eval_list expr env kont = (* step-sf-define-library *) and step_sf_define_library args env kont = - (let lib_spec = (first (args)) in let decls = (rest (args)) in (let lib_env = (env_extend ((make_env ()))) in let exports = ref ((List [])) in let body_forms = ref ((List [])) in (let () = ignore ((List.iter (fun decl -> ignore ((if sx_truthy ((let _and = (list_p (decl)) in if not (sx_truthy _and) then _and else (let _and = (Bool (not (sx_truthy ((empty_p (decl)))))) in if not (sx_truthy _and) then _and else (symbol_p ((first (decl))))))) then (let kind = (symbol_name ((first (decl)))) in (if sx_truthy ((prim_call "=" [kind; (String "export")])) then (exports := (prim_call "append" [!exports; (List (List.map (fun s -> (if sx_truthy ((symbol_p (s))) then (symbol_name (s)) else (String (sx_str [s])))) (sx_to_list (rest (decl)))))]); Nil) else (if sx_truthy ((prim_call "=" [kind; (String "begin")])) then (body_forms := (prim_call "append" [!body_forms; (rest (decl))]); Nil) else Nil))) else Nil))) (sx_to_list decls); Nil)) in (let () = ignore ((List.iter (fun form -> ignore ((eval_expr (form) (lib_env)))) (sx_to_list !body_forms); Nil)) in (let export_dict = (Dict (Hashtbl.create 0)) in (let () = ignore ((List.iter (fun name -> ignore ((if sx_truthy ((env_has (lib_env) (name))) then (sx_dict_set_b export_dict name (env_get (lib_env) (name))) else Nil))) (sx_to_list !exports); Nil)) in (let () = ignore ((register_library (lib_spec) (export_dict))) in (make_cek_value (Nil) (env) (kont))))))))) + (let lib_spec = (first (args)) in let decls = (rest (args)) in (let lib_env = (env_extend (env)) in let exports = ref ((List [])) in let body_forms = ref ((List [])) in (let () = ignore ((List.iter (fun decl -> ignore ((if sx_truthy ((let _and = (list_p (decl)) in if not (sx_truthy _and) then _and else (let _and = (Bool (not (sx_truthy ((empty_p (decl)))))) in if not (sx_truthy _and) then _and else (symbol_p ((first (decl))))))) then (let kind = (symbol_name ((first (decl)))) in (if sx_truthy ((prim_call "=" [kind; (String "export")])) then (exports := (prim_call "append" [!exports; (List (List.map (fun s -> (if sx_truthy ((symbol_p (s))) then (symbol_name (s)) else (String (sx_str [s])))) (sx_to_list (rest (decl)))))]); Nil) else (if sx_truthy ((prim_call "=" [kind; (String "begin")])) then (body_forms := (prim_call "append" [!body_forms; (rest (decl))]); Nil) else Nil))) else Nil))) (sx_to_list decls); Nil)) in (let () = ignore ((List.iter (fun form -> ignore ((eval_expr (form) (lib_env)))) (sx_to_list !body_forms); Nil)) in (let export_dict = (Dict (Hashtbl.create 0)) in (let () = ignore ((List.iter (fun name -> ignore ((if sx_truthy ((env_has (lib_env) (name))) then (sx_dict_set_b export_dict name (env_get (lib_env) (name))) else Nil))) (sx_to_list !exports); Nil)) in (let () = ignore ((register_library (lib_spec) (export_dict))) in (make_cek_value (Nil) (env) (kont))))))))) (* bind-import-set *) and bind_import_set import_set env = diff --git a/lib/bytecode.sx b/lib/bytecode.sx index 8e70b146..5bc9510f 100644 --- a/lib/bytecode.sx +++ b/lib/bytecode.sx @@ -19,6 +19,94 @@ ;; -------------------------------------------------------------------------- ;; Stack / Constants + +(define-library (sx bytecode) + (export + OP_CONST + OP_NIL + OP_TRUE + OP_FALSE + OP_POP + OP_DUP + OP_LOCAL_GET + OP_LOCAL_SET + OP_UPVALUE_GET + OP_UPVALUE_SET + OP_GLOBAL_GET + OP_GLOBAL_SET + OP_JUMP + OP_JUMP_IF_FALSE + OP_JUMP_IF_TRUE + OP_CALL + OP_TAIL_CALL + OP_RETURN + OP_CLOSURE + OP_CALL_PRIM + OP_APPLY + OP_LIST + OP_DICT + OP_APPEND_BANG + OP_ITER_INIT + OP_ITER_NEXT + OP_MAP_OPEN + OP_MAP_APPEND + OP_MAP_CLOSE + OP_FILTER_TEST + OP_HO_MAP + OP_HO_FILTER + OP_HO_REDUCE + OP_HO_FOR_EACH + OP_HO_SOME + OP_HO_EVERY + OP_SCOPE_PUSH + OP_SCOPE_POP + OP_PROVIDE_PUSH + OP_PROVIDE_POP + OP_CONTEXT + OP_EMIT + OP_EMITTED + OP_RESET + OP_SHIFT + OP_DEFINE + OP_DEFCOMP + OP_DEFISLAND + OP_DEFMACRO + OP_EXPAND_MACRO + OP_STR_CONCAT + OP_STR_JOIN + OP_SERIALIZE + OP_ADD + OP_SUB + OP_MUL + OP_DIV + OP_EQ + OP_LT + OP_GT + OP_NOT + OP_LEN + OP_FIRST + OP_REST + OP_NTH + OP_CONS + OP_NEG + OP_INC + OP_DEC + OP_ASER_TAG + OP_ASER_FRAG + BYTECODE_MAGIC + BYTECODE_VERSION + CONST_NUMBER + CONST_STRING + CONST_BOOL + CONST_NIL + CONST_SYMBOL + CONST_KEYWORD + CONST_LIST + CONST_DICT + CONST_CODE + opcode-name) + (begin + (define OP_CONST 1) ;; u16 pool_idx — push constant (define OP_NIL 2) ;; push nil (define OP_TRUE 3) ;; push true @@ -161,3 +249,9 @@ (= op 50) "RETURN" (= op 52) "CALL_PRIM" (= op 128) "DEFINE" (= op 144) "STR_CONCAT" :else (str "OP_" op)))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx bytecode)) diff --git a/lib/callcc.sx b/lib/callcc.sx index 6fe67166..b59e91f3 100644 --- a/lib/callcc.sx +++ b/lib/callcc.sx @@ -77,6 +77,12 @@ ;; 2. call/cc — call with current continuation ;; -------------------------------------------------------------------------- + +(define-library (sx callcc) + (export + sf-callcc) + (begin + (define sf-callcc (fn (args env) ;; Single argument: a function to call with the current continuation. @@ -243,3 +249,9 @@ ;; dispatch in eval-list (same path as lambda calls). ;; ;; -------------------------------------------------------------------------- + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx callcc)) diff --git a/lib/compiler.sx b/lib/compiler.sx index 180f1a40..2f876bf5 100644 --- a/lib/compiler.sx +++ b/lib/compiler.sx @@ -14,6 +14,53 @@ ;; -------------------------------------------------------------------------- ;; Constant pool builder ;; -------------------------------------------------------------------------- + +(define-library (sx compiler) + (export + make-pool + pool-add + make-scope + scope-define-local + scope-resolve + make-emitter + emit-byte + emit-u16 + emit-i16 + emit-op + emit-const + current-offset + patch-i16 + compile-expr + compile-symbol + compile-dict + compile-list + compile-if + compile-when + compile-and + compile-or + compile-begin + compile-let + compile-letrec + compile-lambda + compile-define + compile-set + compile-quote + compile-cond + compile-case + compile-case-clauses + compile-match + compile-thread + compile-thread-step + compile-defcomp + compile-defmacro + compile-quasiquote + compile-qq-expr + compile-qq-list + compile-call + compile + compile-module) + (begin + (define make-pool (fn () {:entries (if (primitive? "mutable-list") (mutable-list) (list)) :index {:_count 0}})) (define @@ -871,3 +918,9 @@ (compile-expr em (last exprs) scope false) (emit-op em 50) {:constants (get (get em "pool") "entries") :bytecode (get em "bytecode")}))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx compiler)) diff --git a/lib/content.sx b/lib/content.sx index 69370ed1..f2cd2c31 100644 --- a/lib/content.sx +++ b/lib/content.sx @@ -11,6 +11,17 @@ ;; localStorage or IPFS by providing their own store backend. ;; ========================================================================== + +(define-library (sx content) + (export + content-store + content-hash + content-put + content-get + freeze-to-cid + thaw-from-cid) + (begin + (define content-store (dict)) (define content-hash :effects [] @@ -46,3 +57,9 @@ (when sx-text (thaw-from-sx sx-text) true)))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx content)) diff --git a/lib/freeze.sx b/lib/freeze.sx index f3c2e972..561e11f2 100644 --- a/lib/freeze.sx +++ b/lib/freeze.sx @@ -20,6 +20,20 @@ ;; ========================================================================== ;; Registry of freeze scopes: name → list of {name signal} entries + +(define-library (sx freeze) + (export + freeze-registry + freeze-signal + freeze-scope + cek-freeze-scope + cek-freeze-all + cek-thaw-scope + cek-thaw-all + freeze-to-sx + thaw-from-sx) + (begin + (define freeze-registry (dict)) ;; Register a signal in the current freeze scope @@ -92,3 +106,9 @@ (when (not (empty? parsed)) (let ((frozen (first parsed))) (cek-thaw-scope (get frozen "name") frozen)))))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx freeze)) diff --git a/lib/highlight.sx b/lib/highlight.sx index 46a455bb..d0289e01 100644 --- a/lib/highlight.sx +++ b/lib/highlight.sx @@ -1,3 +1,22 @@ + + +(define-library (sx highlight) + (export + sx-specials + sx-special? + hl-digit? + hl-alpha? + hl-sym-char? + hl-ws? + hl-escape + hl-span + tokenize-sx + sx-token-classes + render-sx-tokens + highlight-sx + highlight) + (begin + (define sx-specials (list @@ -298,3 +317,9 @@ (or (= lang "lisp") (= lang "sx") (= lang "sexp") (= lang "scheme")) (highlight-sx code) (list (quote code) code)))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx highlight)) diff --git a/lib/r7rs.sx b/lib/r7rs.sx index 2bf0d5af..9e157f53 100644 --- a/lib/r7rs.sx +++ b/lib/r7rs.sx @@ -1,3 +1,30 @@ + + +(define-library (sx r7rs) + (export + make-error-object + error-object? + error-message + error-object-irritants + with-exception-handler + car + cdr + cadr + cddr + caar + cdar + caddr + cadddr + null? + pair? + procedure? + boolean=? + symbol->string + string->symbol + number->string + string->number) + (begin + (define make-error-object (fn (message irritants) {:irritants irritants :type "error-object" :message message})) (define @@ -51,3 +78,9 @@ (define string->number (fn (s) (if (string-contains? s ".") (parse-float s) (parse-int s)))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx r7rs)) diff --git a/lib/render-trace.sx b/lib/render-trace.sx index 08d4dc11..0743a289 100644 --- a/lib/render-trace.sx +++ b/lib/render-trace.sx @@ -1,3 +1,17 @@ + + +(define-library (sx render-trace) + (export + *render-trace* + *render-trace-log* + *render-trace-depth* + render-trace-reset! + render-trace-push! + render-trace-enter! + render-trace-exit! + format-render-trace) + (begin + (define *render-trace* false) (define *render-trace-log* (list)) @@ -49,3 +63,9 @@ (result (get entry :result))) (str indent kind " " detail " → " result))) *render-trace-log*)))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx render-trace)) diff --git a/lib/stdlib.sx b/lib/stdlib.sx index bba11c49..ea741746 100644 --- a/lib/stdlib.sx +++ b/lib/stdlib.sx @@ -13,6 +13,58 @@ ;; Replacing them with SX lambdas changes behavior inside shift/reset ;; because the transpiled evaluator code uses them directly. + +(define-library (sx stdlib) + (export + eq? + eqv? + equal? + boolean? + number? + string? + list? + dict? + continuation? + zero? + odd? + even? + empty? + abs + ceil + round + min + max + clamp + first + last + rest + nth + cons + append + reverse + flatten + range + chunk-every + zip-pairs + vals + has-key? + assoc + dissoc + into + upcase + downcase + string-length + substring + string-contains? + starts-with? + ends-with? + contains? + pluralize + escape + parse-datetime + assert) + (begin + (define eq? (fn (a b) (= a b))) (define eqv? (fn (a b) (= a b))) (define equal? (fn (a b) (= a b))) @@ -273,3 +325,9 @@ (when (not condition) (error (or message "Assertion failed"))) true)) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx stdlib)) diff --git a/lib/sx-swap.sx b/lib/sx-swap.sx index c1709b46..3090f62c 100644 --- a/lib/sx-swap.sx +++ b/lib/sx-swap.sx @@ -1,3 +1,22 @@ + + +(define-library (sx swap) + (export + _skip-string + _find-close + _skip-ws + _skip-token + _skip-value + _find-children-start + _scan-back + find-element-by-id + sx-swap + _extract-attr-value + find-oob-elements + strip-oob + apply-response) + (begin + (define _skip-string (fn @@ -298,3 +317,9 @@ (get oob "content")) (rest items)))))) (_apply-oobs result oobs))))))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx swap)) diff --git a/lib/vm.sx b/lib/vm.sx index af314ad2..38dc1a3c 100644 --- a/lib/vm.sx +++ b/lib/vm.sx @@ -1,3 +1,41 @@ + + +(define-library (sx vm) + (export + make-upvalue-cell + uv-get + uv-set! + make-vm-code + make-vm-closure + make-vm-frame + make-vm + vm-push + vm-pop + vm-peek + frame-read-u8 + frame-read-u16 + frame-read-i16 + vm-push-frame + code-from-value + vm-closure? + vm-call + frame-local-get + frame-local-set + frame-upvalue-get + frame-upvalue-set + vm-global-get + vm-resolve-ho-form + vm-call-external + vm-global-set + env-walk + env-walk-set! + vm-create-closure + vm-run + vm-step + vm-call-closure + vm-execute-module) + (begin + (define make-upvalue-cell (fn (value) {:uv-value value})) (define uv-get (fn (cell) (get cell "uv-value"))) @@ -556,3 +594,9 @@ (dict-set! vm "frames" (list frame)) (vm-run vm) (vm-pop vm))))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx vm)) diff --git a/spec/canonical.sx b/spec/canonical.sx index de581c76..0f546168 100644 --- a/spec/canonical.sx +++ b/spec/canonical.sx @@ -1,4 +1,21 @@ ;; Deterministic serialization for content addressing + +(define-library (sx canonical) + (export + canonical-serialize + canonical-number + canonical-dict + content-id + content-id-short + make-bytecode-module + bytecode-module? + bytecode-module-version + bytecode-module-source-hash + bytecode-module-code + make-code-object + make-provenance) + (begin + (define canonical-serialize :effects () @@ -127,3 +144,9 @@ :bytecode-cid bytecode-cid :compiler-cid compiler-cid :timestamp timestamp))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx canonical)) diff --git a/spec/evaluator.sx b/spec/evaluator.sx index 008668e8..56e4121e 100644 --- a/spec/evaluator.sx +++ b/spec/evaluator.sx @@ -1469,9 +1469,7 @@ (let ((lib-spec (first args)) (decls (rest args))) (let - ((lib-env (env-extend (make-env))) - (exports (list)) - (body-forms (list))) + ((lib-env (env-extend env)) (exports (list)) (body-forms (list))) (for-each (fn (decl) diff --git a/spec/harness.sx b/spec/harness.sx index 13cb1683..1f1ae91d 100644 --- a/spec/harness.sx +++ b/spec/harness.sx @@ -1,4 +1,30 @@ ;; Assert condition is truthy, error with message + +(define-library (sx harness) + (export + assert + assert= + default-platform + make-harness + harness-reset! + harness-log + harness-get + harness-set! + make-interceptor + install-interceptors + io-calls + io-call-count + io-call-nth + io-call-args + io-call-result + assert-io-called + assert-no-io + assert-io-count + assert-io-args + assert-io-result + assert-state) + (begin + (define assert (fn (condition msg) (when (not condition) (error (or msg "Assertion failed"))))) ;; Assert two values are equal @@ -60,3 +86,9 @@ ;; Assert a state key has the expected value (define assert-state :effects () (fn (session key expected) (let ((actual (harness-get session key))) (assert (equal? actual expected) (str "Expected state " key " to be " (str expected) " but got " (str actual)))))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx harness)) diff --git a/spec/render.sx b/spec/render.sx index 50d66e7f..0def04e8 100644 --- a/spec/render.sx +++ b/spec/render.sx @@ -1,4 +1,24 @@ ;; Registry of all valid HTML tag names + +(define-library (sx render) + (export + HTML_TAGS + VOID_ELEMENTS + BOOLEAN_ATTRS + *definition-form-extensions* + definition-form? + parse-element-args + render-attrs + eval-cond + eval-cond-scheme + eval-cond-clojure + process-bindings + is-render-expr? + merge-spread-attrs + escape-html + escape-attr) + (begin + (define HTML_TAGS (list @@ -413,3 +433,9 @@ ;; Escape special chars for HTML attribute values (define escape-attr (fn (s) (escape-html s))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx render)) diff --git a/spec/signals.sx b/spec/signals.sx index 8d2e4325..da8f8885 100644 --- a/spec/signals.sx +++ b/spec/signals.sx @@ -1,3 +1,32 @@ + + +(define-library (sx signals) + (export + make-signal + signal? + signal-value + signal-set-value! + signal-subscribers + signal-add-sub! + signal-remove-sub! + signal-deps + signal-set-deps! + signal + deref + reset! + swap! + computed + effect + *batch-depth* + *batch-queue* + batch + notify-subscribers + flush-subscribers + dispose-computed + with-island-scope + register-in-scope) + (begin + (define make-signal (fn @@ -193,3 +222,9 @@ (let ((collector (scope-peek "sx-island-scope"))) (when collector (cek-call collector (list disposable)))))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (sx signals)) diff --git a/web/adapter-html.sx b/web/adapter-html.sx index e87c2d27..46a232c6 100644 --- a/web/adapter-html.sx +++ b/web/adapter-html.sx @@ -1,3 +1,22 @@ + + +(define-library (web adapter-html) + (export + render-to-html + render-value-to-html + RENDER_HTML_FORMS + render-html-form? + render-list-to-html + dispatch-html-form + render-lambda-html + render-html-component + render-html-element + render-html-lake + render-html-marsh + render-html-island + serialize-island-state) + (begin + (define render-to-html :effects (render) @@ -589,3 +608,9 @@ (fn ((kwargs :as dict)) (if (empty-dict? kwargs) nil (sx-serialize kwargs)))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (web adapter-html)) diff --git a/web/adapter-sx.sx b/web/adapter-sx.sx index 9e4aece1..0a7f69a9 100644 --- a/web/adapter-sx.sx +++ b/web/adapter-sx.sx @@ -1,3 +1,22 @@ + + +(define-library (web adapter-sx) + (export + render-to-sx + aser + aser-list + aser-reserialize + aser-fragment + aser-call + aser-expand-component + SPECIAL_FORM_NAMES + HO_FORM_NAMES + special-form? + ho-form? + aser-special + eval-case-aser) + (begin + (define render-to-sx :effects (render) @@ -570,3 +589,9 @@ (= match-val (trampoline (eval-expr test env))) (aser body env) (eval-case-aser match-val (slice clauses 2) env))))))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (web adapter-sx)) diff --git a/web/deps.sx b/web/deps.sx index 8f7a3c44..fca9ff79 100644 --- a/web/deps.sx +++ b/web/deps.sx @@ -1,3 +1,28 @@ + + +(define-library (web deps) + (export + scan-refs + scan-refs-walk + transitive-deps-walk + transitive-deps + compute-all-deps + scan-components-from-source + components-needed + page-component-bundle + page-css-classes + scan-io-refs-walk + scan-io-refs + transitive-io-refs-walk + transitive-io-refs + compute-all-io-refs + component-io-refs-cached + component-pure? + render-target + page-render-plan + env-components) + (begin + (define scan-refs :effects () @@ -335,3 +360,9 @@ ((k :as string)) (let ((v (env-get env k))) (or (component? v) (macro? v)))) (keys env)))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (web deps)) diff --git a/web/engine.sx b/web/engine.sx index 8ba70565..1b584909 100644 --- a/web/engine.sx +++ b/web/engine.sx @@ -1,3 +1,42 @@ + + +(define-library (web engine) + (export + ENGINE_VERBS + DEFAULT_SWAP + parse-time + parse-trigger-spec + default-trigger + get-verb-info + build-request-headers + process-response-headers + parse-swap-spec + parse-retry-spec + next-retry-ms + filter-params + resolve-target + apply-optimistic + revert-optimistic + find-oob-swaps + morph-node + sync-attrs + morph-children + morph-island-children + morph-marsh + process-signal-updates + swap-dom-nodes + insert-remaining-siblings + swap-html-string + handle-history + PRELOAD_TTL + preload-cache-get + preload-cache-set + classify-trigger + should-boost-link? + should-boost-form? + parse-sse-swap) + (begin + (define ENGINE_VERBS (list "get" "post" "put" "delete" "patch")) (define DEFAULT_SWAP "outerHTML") @@ -806,3 +845,9 @@ parse-sse-swap :effects (io) (fn (el) (or (dom-get-attr el "sx-sse-swap") "message"))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (web engine)) diff --git a/web/orchestration.sx b/web/orchestration.sx index d718892e..b683cbe1 100644 --- a/web/orchestration.sx +++ b/web/orchestration.sx @@ -1,3 +1,68 @@ + + +(define-library (web orchestration) + (export + _preload-cache + dispatch-trigger-events + execute-request + do-fetch + handle-fetch-success + flush-collected-styles + handle-sx-response + handle-html-response + handle-retry + bind-triggers + bind-event + post-swap + process-settle-hooks + activate-scripts + process-oob-swaps + hoist-head-elements + process-boosted + boost-descendants + _page-data-cache + _page-data-cache-ttl + page-data-cache-key + page-data-cache-get + page-data-cache-set + invalidate-page-cache + invalidate-all-page-cache + update-page-cache + process-cache-directives + _optimistic-snapshots + optimistic-cache-update + optimistic-cache-revert + optimistic-cache-confirm + submit-mutation + _is-online + _offline-queue + offline-is-online? + offline-set-online! + offline-queue-mutation + offline-sync + offline-pending-count + offline-aware-mutation + current-page-layout + swap-rendered-content + resolve-route-target + deps-satisfied? + try-client-route + bind-client-route-link + process-sse + bind-sse + bind-sse-swap + bind-inline-handlers + bind-preload-for + do-preload + VERB_SELECTOR + process-elements + process-one + process-emit-elements + save-scroll-position + handle-popstate + engine-init) + (begin + (define _preload-cache (dict)) (define @@ -1566,3 +1631,9 @@ (fn () (do (sx-process-scripts nil) (sx-hydrate nil) (process-elements nil)))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (web orchestration)) diff --git a/web/page-helpers.sx b/web/page-helpers.sx index e538cb91..b2a90255 100644 --- a/web/page-helpers.sx +++ b/web/page-helpers.sx @@ -1,3 +1,21 @@ + + +(define-library (web page-helpers) + (export + special-form-category-map + extract-define-kwargs + categorize-special-forms + build-ref-items-with-href + build-reference-data + build-attr-detail + build-header-detail + build-event-detail + build-component-source + build-bundle-analysis + build-routing-analysis + build-affinity-analysis) + (begin + (define special-form-category-map {:defmacro "Functions & Components" :for-each "Higher-Order Forms" :defpage "Domain Definitions" :let "Binding" :filter "Higher-Order Forms" :shift "Continuations" :and "Control Flow" :set! "Binding" :map-indexed "Higher-Order Forms" :dynamic-wind "Guards" :reduce "Higher-Order Forms" :cond "Control Flow" :defquery "Domain Definitions" :-> "Sequencing & Threading" :let* "Binding" :define "Binding" :reset "Continuations" :case "Control Flow" :do "Sequencing & Threading" :map "Higher-Order Forms" :some "Higher-Order Forms" :letrec "Binding" :if "Control Flow" :quote "Quoting" :every? "Higher-Order Forms" :defhandler "Domain Definitions" :fn "Functions & Components" :defstyle "Domain Definitions" :lambda "Functions & Components" :defaction "Domain Definitions" :or "Control Flow" :defcomp "Functions & Components" :quasiquote "Quoting" :when "Control Flow" :begin "Sequencing & Threading"}) (define @@ -230,3 +248,9 @@ (define build-affinity-analysis (fn ((demo-components :as list) (page-plans :as list)) {:components demo-components :page-plans page-plans})) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (web page-helpers)) diff --git a/web/request-handler.sx b/web/request-handler.sx index 88e35b13..d8d4141f 100644 --- a/web/request-handler.sx +++ b/web/request-handler.sx @@ -1,3 +1,13 @@ + + +(define-library (web request-handler) + (export + sx-url-to-expr + sx-auto-quote + sx-eval-page + sx-handle-request) + (begin + (define sx-url-to-expr (fn @@ -66,3 +76,9 @@ path (str (slice prefix 0 (- prefix-len 1)) path)))) {:page-ast page-ast :nav-path nav-path :is-ajax is-ajax}))))) + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (web request-handler)) diff --git a/web/router.sx b/web/router.sx index 862c18a1..2b8311d6 100644 --- a/web/router.sx +++ b/web/router.sx @@ -17,6 +17,47 @@ ;; "/" → () ;; "/docs/" → ("docs") + +(define-library (web router) + (export + split-path-segments + make-route-segment + parse-route-pattern + match-route-segments + match-route + find-matching-route + _fn-to-segment + sx-url-to-path + _count-leading-dots + _strip-trailing-close + _index-of-safe + _last-index-of + _pop-sx-url-level + _pop-sx-url-levels + _split-pos-kw + _parse-relative-body + _extract-innermost + _find-kw-in-tokens + _find-keyword-value + _replace-kw-in-tokens + _set-keyword-in-content + _is-delta-value? + _apply-delta + _apply-kw-pairs + _apply-keywords-to-url + _normalize-relative + resolve-relative-url + relative-sx-url? + _url-special-forms + url-special-form? + parse-sx-url + url-special-form-name + url-special-form-inner + url-to-expr + auto-quote-unknowns + prepare-url-expr) + (begin + (define split-path-segments :effects [] (fn ((path :as string)) (let ((trimmed (if (starts-with? path "/") (slice path 1) path))) @@ -678,3 +719,9 @@ ;; ;; From parser.sx: sx-parse, sx-serialize ;; -------------------------------------------------------------------------- + + +)) ;; end define-library + +;; Re-export to global namespace for backward compatibility +(import (web router))