Fix WASM kernel deploy: 3.6MB js_of_ocaml → 68KB wasm_of_ocaml
The deployed sx_browser.bc.wasm.js was actually the js_of_ocaml output (pure JS), not the wasm_of_ocaml loader. Nothing synced the correct build output from _build/ to shared/static/wasm/. - sx_build target=ocaml now auto-syncs WASM kernel + JS fallback + assets - sx-build-all.sh syncs after dune build - Correct 68KB WASM loader replaces 3.6MB JS imposter Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -581,7 +581,8 @@ let rec handle_tool name args =
|
||||
in
|
||||
let cmd = match target with
|
||||
| "ocaml" ->
|
||||
Printf.sprintf "cd %s/hosts/ocaml && eval $(opam env 2>/dev/null) && dune build 2>&1" project_dir
|
||||
let abs_project = if Filename.is_relative project_dir then Sys.getcwd () ^ "/" ^ project_dir else project_dir in
|
||||
Printf.sprintf "cd %s/hosts/ocaml && eval $(opam env 2>/dev/null) && dune build 2>&1 && cp _build/default/browser/sx_browser.bc.wasm.js %s/shared/static/wasm/sx_browser.bc.wasm.js && cp _build/default/browser/sx_browser.bc.js %s/shared/static/wasm/sx_browser.bc.js && cp -r _build/default/browser/sx_browser.bc.wasm.assets %s/shared/static/wasm/" abs_project abs_project abs_project abs_project
|
||||
| "js" | _ ->
|
||||
let extra = if full then " --extensions continuations --spec-modules types" else "" in
|
||||
Printf.sprintf "cd %s && python3 hosts/javascript/cli.py%s --output shared/static/scripts/sx-browser.js 2>&1" project_dir extra
|
||||
|
||||
@@ -6,6 +6,15 @@ cd "$(dirname "$0")/.."
|
||||
|
||||
echo "=== OCaml build ==="
|
||||
(cd hosts/ocaml && eval $(opam env 2>/dev/null) && dune build) || { echo "FAIL: OCaml build"; exit 1; }
|
||||
|
||||
echo "=== Sync WASM kernel to shared/static/wasm/ ==="
|
||||
OCAML_BUILD=hosts/ocaml/_build/default/browser
|
||||
cp "$OCAML_BUILD/sx_browser.bc.wasm.js" shared/static/wasm/sx_browser.bc.wasm.js
|
||||
cp "$OCAML_BUILD/sx_browser.bc.js" shared/static/wasm/sx_browser.bc.js
|
||||
cp -r "$OCAML_BUILD/sx_browser.bc.wasm.assets" shared/static/wasm/
|
||||
echo " WASM loader: $(du -sh shared/static/wasm/sx_browser.bc.wasm.js | cut -f1)"
|
||||
echo " JS fallback: $(du -sh shared/static/wasm/sx_browser.bc.js | cut -f1)"
|
||||
|
||||
echo "=== JS browser build ==="
|
||||
python3 hosts/javascript/cli.py --output shared/static/scripts/sx-browser.js || { echo "FAIL: JS build"; exit 1; }
|
||||
echo "=== JS test build ==="
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -149,6 +149,53 @@ test.describe('Page Navigation', () => {
|
||||
expect(afterNav).toBe(advanced);
|
||||
});
|
||||
|
||||
test('sx-get link fetches SX not HTML and preserves layout', async ({ page }) => {
|
||||
await loadPage(page, '');
|
||||
|
||||
// Track requests to detect what format the fetch uses
|
||||
const fetches = [];
|
||||
page.on('request', req => {
|
||||
if (req.url().includes('/sx/') && req.resourceType() === 'xhr')
|
||||
fetches.push({ url: req.url(), accept: req.headers()['accept'] || '' });
|
||||
});
|
||||
|
||||
// Mark page so we can detect full reload vs SPA nav
|
||||
await page.evaluate(() => window.__spa_marker = true);
|
||||
|
||||
// Click a nav link (Geography)
|
||||
await page.click('a[sx-get*="(geography)"]');
|
||||
await expect(page).toHaveURL(/geography/, { timeout: 5000 });
|
||||
|
||||
// Must be SPA navigation — marker survives
|
||||
const marker = await page.evaluate(() => window.__spa_marker);
|
||||
expect(marker).toBe(true);
|
||||
|
||||
// The fetch should have been XHR, not a document navigation
|
||||
expect(fetches.length).toBeGreaterThan(0);
|
||||
|
||||
// After navigation, #sx-nav and #main-content should still be
|
||||
// vertically stacked (not side-by-side). Check that nav is above content.
|
||||
const layout = await page.evaluate(() => {
|
||||
const nav = document.querySelector('#sx-nav');
|
||||
const main = document.querySelector('#main-content, #main-panel');
|
||||
if (!nav || !main) return { error: 'missing elements', nav: !!nav, main: !!main };
|
||||
const navRect = nav.getBoundingClientRect();
|
||||
const mainRect = main.getBoundingClientRect();
|
||||
return {
|
||||
navBottom: navRect.bottom,
|
||||
mainTop: mainRect.top,
|
||||
navRight: navRect.right,
|
||||
mainLeft: mainRect.left,
|
||||
// Nav should end before main starts (vertically stacked)
|
||||
verticallyStacked: navRect.bottom <= mainRect.top + 5,
|
||||
// Nav and main should overlap horizontally (not side-by-side)
|
||||
horizontalOverlap: navRect.left < mainRect.right && mainRect.left < navRect.right
|
||||
};
|
||||
});
|
||||
expect(layout.verticallyStacked).toBe(true);
|
||||
expect(layout.horizontalOverlap).toBe(true);
|
||||
});
|
||||
|
||||
test('header island renders with SSR', async ({ page }) => {
|
||||
await loadPage(page, '(geography)');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user