v0.3.0 (2026-05-23)

Added

  • New :startup_timeout option for Tyrex.start/1 and Tyrex.start_link/1 (defaults to 30s); the GenServer init callback now returns {:stop, :nif_startup_timeout} if the NIF does not acknowledge in time.
  • New examples/error_handling.exs demonstrating pattern-matching on Tyrex.Error (:execution_error, :promise_rejection, :conversion_error, :dead_runtime_error) and on Tyrex.eval! raising.
  • New examples/least_loaded.exs implementing the LeastLoaded custom Tyrex.Pool.Strategy from the README as a real runnable script.
  • New examples/ink_tui/ example demonstrating terminal UI rendering.
  • Documented the deny_import permission key (always supported by the Rust side; previously missing from Elixir docs and the README permission table).

Changed

  • Tyrex.eval!/1,2 and Tyrex.Pool.eval!/2,3 now raise Tyrex.Error on failure instead of crashing with MatchError.
  • Tyrex.Pool.Strategy.RoundRobin's first selection now returns index 0 (previously 1). The counter is now seeded at size - 1 so the first update_counter/3 wraps to 0.
  • Tyrex.Pool is now supervised as :rest_for_one with a dedicated internal registry GenServer that owns the :persistent_term entry and the strategy state so they get cleaned up on supervisor shutdown.
  • Tightened the mix.exs package description.

Fixed

  • ~16 panic sites in the Rust NIF and Deno worker event loop (BEAM crash risk) replaced with proper error propagation or best-effort logging.
  • Pending promises now receive a :dead_runtime_error reply when the worker shuts down — callers no longer hang on Tyrex.stop/1.
  • Tyrex.Pool now erases its :persistent_term entry and invokes the strategy's terminate/1 callback (cleaning up ETS tables for RoundRobin) on supervisor shutdown, so create/destroy cycles no longer leak VM state.
  • Recover from mutex poisoning in the Rust runtime registry rather than panicking on lock().unwrap().
  • The Rust→JS apply-reply path now dispatches via a JS bridge function (Tyrex._applyReply) instead of format!-interpolating attacker-influenceable values into a Tyrex._applications[...].fn(...) expression.
  • The ~JS sigil now raises a CompileError for unknown modifiers (previously silently ignored).
  • The Tyrex GenServer now has a configurable startup timeout (default 30s) instead of hanging forever on the inner receive.
  • [allow_all: true, deny_X: true] now actually honors the deny overrides — the Rust permission parser used to short-circuit to allow_all and ignore any sibling deny_* keys, contradicting the README's documented pattern.
  • Removed false "TypeScript main module" claim from the README and dropped the (broken) examples/typescript/. The default FsModuleLoader does not transpile .ts files; first-class TypeScript module loading is tracked for a future release. JavaScript (.js) main modules continue to work.

v0.2.1 (2026-03-15)

Fixed

  • Fixed precompiled NIF archive packaging — files inside tar.gz are now named to match RustlerPrecompiled convention (libtyrex-v{version}-nif-2.16-{target}.so)
  • Fixed CI: V8 source builds now work on all targets (tolerate bindgen failure, use pre-generated bindings from rusty_v8 releases)
  • Replaced philss/rustler-precompiled-action with manual cargo build + tar (action installed cross even with use-cross: false)
  • Fixed macOS runner: macos-13 deprecated, switched to macos-15
  • Fixed LLVM 19 → 20 in docker-build.sh Phase 2

Changed

  • NIF version 2.15 → 2.16 (requires OTP 27+)
  • Removed Windows (x86_64-pc-windows-msvc) target (not building it)
  • Upgraded Deno embedded runtime to v2.7.5 (see v0.2.0 for Deno changelog)

Deno 2.7.5 highlights

  • deno compile improvements with npm/jsr package support
  • deno init --npm vite scaffolding
  • deno task supports dependencies field for task ordering
  • Temporal API support (behind --unstable-temporal)
  • Node.js compatibility improvements (http2, worker_threads, async_hooks)
  • V8 engine upgraded to 14.6

v0.2.0 (2026-03-11)

Changed

  • Upgraded embedded Deno runtime to v2.7.5
    • deno_core 0.330.0 → 0.391.0
    • deno_runtime 0.194.0 → 0.246.0
    • deno_fs 0.96.0 → 0.148.0
    • deno_resolver 0.17.0 → 0.69.0
    • serde_v8 0.239.0 → 0.300.0
    • sys_traits 0.1.7 → 0.1.24
  • Relaxed serde version pin

v0.1.0 (2026-03-08)

Initial release.

Features

  • Embedded Deno runtime — Full Deno JS/TS runtime embedded in Elixir via Rustler NIFs
  • JavaScript & TypeScript evaluationTyrex.eval/1,2 with automatic promise awaiting
  • Blocking & async modes — Choose NIF-blocking (fast, <1ms) or async eval
  • Bidirectional calls — Call Elixir functions from JavaScript via Tyrex.apply()
  • Module loading — Import ES modules with import/export, load main modules at startup
  • ~JS sigil — Write JavaScript inline in Elixir code with Tyrex.Sigil
  • Tyrex.Inline — Process-local runtime binding with set_runtime/1 and with_runtime/2
  • Granular permissions — Control network, filesystem, env, subprocess, FFI, and system access per runtime
  • Runtime poolTyrex.Pool supervisor with pluggable dispatch strategies:
    • RoundRobin (default) — Lock-free ETS atomic counter
    • Random — Random runtime selection
    • Hash — Key-based sticky sessions
  • Named runtimes — Add Tyrex to supervision trees with start_link/1
  • Deno APIsfetch, Deno.readTextFile, setTimeout, Node.js compatibility, and more

Precompiled binaries

  • aarch64-apple-darwin
  • aarch64-unknown-linux-gnu
  • x86_64-apple-darwin
  • x86_64-pc-windows-msvc
  • x86_64-unknown-linux-gnu