Skip to content

Wasm: dispatch lifecycle events when async instantiation completes#143

Closed
JasonGross wants to merge 1 commit into
ocaml-wasm:mainfrom
JasonGross:wasm-loaded-event
Closed

Wasm: dispatch lifecycle events when async instantiation completes#143
JasonGross wants to merge 1 commit into
ocaml-wasm:mainfrom
JasonGross:wasm-loaded-event

Conversation

@JasonGross
Copy link
Copy Markdown
Contributor

Summary

  • Fixes [BUG] wasm is not ready when DOMContentLoaded fires and does not trigger an event when it is loaded #11: surrounding JavaScript has no way to know when the asynchronous Wasm instantiation has finished, so user code that runs from DOMContentLoaded can race against the OCaml exports being defined.
  • The generated launcher invokes the runtime as init_fun(primitives)(runtime_arguments) and discards the returned Promise, so callers can't simply await it. Instead, the runtime now dispatches a wasmoocaml:loaded CustomEvent on globalThis after _initialize() resolves, and a wasmoocaml:error event (with the thrown error in detail.error) if anything in the instantiation pipeline rejects.
  • Both events carry detail.src (the assets directory name passed in args.src) so listeners can disambiguate when multiple Wasm modules are loaded on the same page.
  • Listener example:
    addEventListener("wasmoocaml:loaded", (e) => {
      // OCaml exports are now available; e.detail.src identifies the module.
      synthesize(...);
    });

Test plan

🤖 Generated with Claude Code

Compiling and instantiating the generated WebAssembly is asynchronous,
but the launcher only returns a Promise that callers typically don't
await. Surrounding JavaScript that runs on DOMContentLoaded therefore
has no way to tell when the OCaml exports are actually ready. Dispatch
'wasmoocaml:loaded' (and 'wasmoocaml:error' on failure) CustomEvents
on globalThis so external code can wait for the runtime to be ready.

Fixes ocaml-wasm#11.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
JasonGross added a commit to mit-plv/fiat-crypto that referenced this pull request May 5, 2026
)

The wasm_of_ocaml launcher loads and instantiates the wasm module
asynchronously, then runs the OCaml entry point that calls
`Js.export "synthesize" ...`. The previous fixed 1s setTimeout in
the worker raced against this and produced
`ReferenceError: synthesize is not defined` on the deployed site
(the wasm blob is now ~13.8 MB and routinely takes longer to load
than 1s).

Replace the timeout with a 50ms poll for `self.synthesize`, and
also subscribe to the `wasmoocaml:loaded` / `wasmoocaml:error`
events introduced in
ocaml-wasm/wasm_of_ocaml#143 so we install
the handler immediately on success and surface load failures back
to the page instead of looping forever. The loaded handler logs a
note that the polling fallback can be removed once the deployed
wasm_of_ocaml ships these events.
@hhugo
Copy link
Copy Markdown
Contributor

hhugo commented May 5, 2026

You probably want to open a PR against https://github.com/ocsigen/js_of_ocaml

@JasonGross
Copy link
Copy Markdown
Contributor Author

Thank you, doing that now

@JasonGross
Copy link
Copy Markdown
Contributor Author

Superseded by ocsigen/js_of_ocaml#2232, which ports this change to the merged js_of_ocaml repository. Closing here.

@JasonGross JasonGross closed this May 6, 2026
hhugo pushed a commit to JasonGross/js_of_ocaml that referenced this pull request May 6, 2026
Compiling and instantiating the generated WebAssembly is asynchronous,
but the launcher only returns a Promise that callers typically don't
await. Surrounding JavaScript that runs on DOMContentLoaded therefore
has no way to tell when the OCaml exports are actually ready. Dispatch
'wasmoocaml:loaded' (and 'wasmoocaml:error' on failure) CustomEvents
on globalThis so external code can wait for the runtime to be ready.

Ported from ocaml-wasm/wasm_of_ocaml#143.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] wasm is not ready when DOMContentLoaded fires and does not trigger an event when it is loaded

2 participants