v0.3.0 (2026-05-23)
Added
- New
:startup_timeoutoption forTyrex.start/1andTyrex.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.exsdemonstrating pattern-matching onTyrex.Error(:execution_error,:promise_rejection,:conversion_error,:dead_runtime_error) and onTyrex.eval!raising. - New
examples/least_loaded.exsimplementing the LeastLoaded customTyrex.Pool.Strategyfrom the README as a real runnable script. - New
examples/ink_tui/example demonstrating terminal UI rendering. - Documented the
deny_importpermission key (always supported by the Rust side; previously missing from Elixir docs and the README permission table).
Changed
Tyrex.eval!/1,2andTyrex.Pool.eval!/2,3now raiseTyrex.Erroron failure instead of crashing withMatchError.Tyrex.Pool.Strategy.RoundRobin's first selection now returns index0(previously1). The counter is now seeded atsize - 1so the firstupdate_counter/3wraps to0.Tyrex.Poolis now supervised as:rest_for_onewith a dedicated internal registry GenServer that owns the:persistent_termentry and the strategy state so they get cleaned up on supervisor shutdown.- Tightened the
mix.exspackage 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_errorreply when the worker shuts down — callers no longer hang onTyrex.stop/1. Tyrex.Poolnow erases its:persistent_termentry and invokes the strategy'sterminate/1callback (cleaning up ETS tables forRoundRobin) 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 offormat!-interpolating attacker-influenceable values into aTyrex._applications[...].fn(...)expression. - The
~JSsigil now raises aCompileErrorfor unknown modifiers (previously silently ignored). - The
TyrexGenServer now has a configurable startup timeout (default 30s) instead of hanging forever on the innerreceive. [allow_all: true, deny_X: true]now actually honors the deny overrides — the Rust permission parser used to short-circuit toallow_alland ignore any siblingdeny_*keys, contradicting the README's documented pattern.- Removed false "TypeScript main module" claim from the README and dropped
the (broken)
examples/typescript/. The defaultFsModuleLoaderdoes not transpile.tsfiles; 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-actionwith manual cargo build + tar (action installed cross even withuse-cross: false) - Fixed macOS runner:
macos-13deprecated, switched tomacos-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 compileimprovements with npm/jsr package supportdeno init --npm vitescaffoldingdeno tasksupportsdependenciesfield for task orderingTemporalAPI 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 evaluation —
Tyrex.eval/1,2with 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 ~JSsigil — Write JavaScript inline in Elixir code withTyrex.SigilTyrex.Inline— Process-local runtime binding withset_runtime/1andwith_runtime/2- Granular permissions — Control network, filesystem, env, subprocess, FFI, and system access per runtime
- Runtime pool —
Tyrex.Poolsupervisor with pluggable dispatch strategies:RoundRobin(default) — Lock-free ETS atomic counterRandom— Random runtime selectionHash— Key-based sticky sessions
- Named runtimes — Add Tyrex to supervision trees with
start_link/1 - Deno APIs —
fetch,Deno.readTextFile,setTimeout, Node.js compatibility, and more
Precompiled binaries
aarch64-apple-darwinaarch64-unknown-linux-gnux86_64-apple-darwinx86_64-pc-windows-msvcx86_64-unknown-linux-gnu