OCaml CEK machine compiled to WebAssembly for browser execution
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 23m17s

- wasm_of_ocaml compiles OCaml SX engine to WASM (722/722 spec tests)
- js_of_ocaml fallback also working (722/722 spec tests)
- Thin JS platform layer (sx-platform.js) with ~80 DOM/browser natives
- Lambda callback bridge: SX lambdas callable from JS via handle table
- Side-channel pattern bypasses js_of_ocaml return-value property stripping
- Web adapters (signals, deps, router, adapter-html) load as SX source
- Render mode dispatch: HTML tags + fragments route to OCaml renderer
- Island/component accessors handle both Component and Island types
- Dict-based signal support (signals.sx creates dicts, not native Signal)
- Scope stack implementation (collect!/collected/emit!/emitted/context)
- Bundle script embeds web adapters + WASM loader + platform layer
- SX_USE_WASM env var toggles WASM engine in dev/production
- Bootstrap extended: --web flag transpiles web adapters, :effects stripping

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-16 07:13:49 +00:00
parent 5ab3ecb7e0
commit 0caa965de0
44 changed files with 5167 additions and 171 deletions

View File

@@ -852,6 +852,9 @@ async def sx_page(ctx: dict, page_sx: str, *,
if body_scripts is None:
body_scripts = _shell_cfg.get("body_scripts")
import os as _os
_sx_js_file = "sx-wasm.js" if _os.environ.get("SX_USE_WASM") == "1" else "sx-browser.js"
shell_kwargs: dict[str, Any] = dict(
title=_html_escape(title),
asset_url=asset_url,
@@ -863,7 +866,8 @@ async def sx_page(ctx: dict, page_sx: str, *,
page_sx=page_sx,
sx_css=sx_css,
sx_css_classes=sx_css_classes,
sx_js_hash=_script_hash("sx-browser.js"),
sx_js_file=_sx_js_file,
sx_js_hash=_script_hash(_sx_js_file),
body_js_hash=_script_hash("body.js"),
)
if head_scripts is not None:

View File

@@ -16,6 +16,7 @@
(component-hash :as string?) (component-defs :as string?)
(pages-sx :as string?) (page-sx :as string?)
(asset-url :as string) (sx-js-hash :as string) (body-js-hash :as string?)
(sx-js-file :as string?)
(head-scripts :as list?) (inline-css :as string?) (inline-head-js :as string?)
(init-sx :as string?) (body-scripts :as list?))
(<>
@@ -74,7 +75,7 @@ details.group{overflow:hidden}details.group>summary{list-style:none}details.grou
(raw! (or pages-sx "")))
(script :type "text/sx" :data-mount "body"
(raw! (or page-sx "")))
(script :src (str asset-url "/scripts/sx-browser.js?v=" sx-js-hash))
(script :src (str asset-url "/scripts/" (or sx-js-file "sx-browser.js") "?v=" sx-js-hash))
;; Body scripts — configurable per app
;; Pass a list (even empty) to override defaults; nil = use defaults
(if (not (nil? body-scripts))