Skip to content

feat: support bounded Elixir callbacks from JavaScript - #6

Closed
pepicrft wants to merge 1 commit into
mainfrom
feat/elixir-host-callbacks
Closed

pepicrft wants to merge 1 commit into
mainfrom
feat/elixir-host-callbacks

Conversation

@pepicrft

Copy link
Copy Markdown
Contributor

What

Add per-execution Elixir callbacks callable synchronously from JavaScript through Javex.Host.call(name, argument), on both the in-process and isolated backends. HTTP stays in application callbacks; Javex adds no HTTP dependency or guest networking.

Javex.run(mod, input,
  callbacks: %{"http.request" => &MyApp.ScriptHTTP.request/2},
  callback_timeout: 1_000,
  max_callback_calls: 8
)
const response = Javex.Host.call("http.request", {path: "/status"});

Callbacks receive (argument, %{deadline: absolute_monotonic_ms}) and return {:ok, json_value} or {:error, %{"code" => ..., "message" => ...}}. Declared errors are catchable HostErrors; host crashes are sanitized. Call-count, request/result byte limits and callback deadlines terminate execution and cannot be bypassed with JS try/catch. Pending callbacks stop on cancellation, caller death or runtime shutdown, without blocking the runtime GenServer or occupying dirty CPU schedulers while waiting.

Provider compatibility

Bundle a custom Javy provider with its source, locked dependencies and build instructions. It preserves the synchronous Javy environment and adds a private, bounded Wasm hostcall bridge. Persisted dynamic modules compiled against the previous provider must be recompiled. Older static modules must be recompiled to use the new JS API. This is synchronous, not fetch or a Promise event loop.

The README includes an application-owned HTTP example with fixed destination, host-only credentials and bounded response reads. Elixir/HTTP allocations remain outside guest/process memory budgets; external effects cannot be rolled back.

Verification

Verified locally on Linux:

  • JAVEX_BUILD=1 mix test --cover: 55 tests passed; 91.53% coverage.
  • Real HTTP requests on both backends; dynamic/static modules, nested JSON, grant isolation, errors, byte/count boundaries, deadlines and cancellation.
  • cargo test --manifest-path native/javex_nif/Cargo.toml --release --locked: 5 native tests passed.
  • Compilation with warnings as errors, strict Credo, Clippy and Elixir/Rust formatting passed.
  • Hex package contents and the README HTTP response-size boundary were checked.

macOS was not exercised locally. No release or deployment is included.

Expose per-run JSON capabilities through Javex.Host.call on both backends.
Keep HTTP, credentials and authorization in application callbacks while
bounding callback calls, bytes and deadlines and cancelling pending work.

Bundle the custom Javy provider with its source and build instructions,
and cover HTTP, static/dynamic modules, errors, quotas and cancellation.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15077-f2fd-70be-bb87-b78853bd4c2c
Co-authored-by: Pedro Piñera Buendía <pedro@pepicrft.me>
@pepicrft pepicrft closed this Oct 19, 2026
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.

2 participants