Contains libs and function necessary for basic server side scripting.
Embedded libraries:
- eli
- eli.fs.extra
- eli.proc.extra
- eli.os.extra
- eli.pipe.extra
- eli.stream.extra
- eli.extra.utils
- hjson
- lustache
- lzip + libzip + zlib
- corehttp
- lua-corehttp
- lua-simple-socket
- lua-simple-ipc
- mbedtls
- lua-mbed-base64 + lua-mbed-bigint + lua-mbed-hash
Predefined variables:
interpreter- path to interpreterAPP_ROOT_SCRIPT- path to executed scriptAPP_ROOT- path to directory containingAPP_ROOT_SCRIPTELI_LIB_VERSION- version of eli library
Linux or MacOS:
wget -q https://raw.githubusercontent.com/alis-is/eli/main/install.sh -O /tmp/install.sh && sudo sh /tmp/install.sh
Windows (PowerShell):
iwr https://raw.githubusercontent.com/alis-is/eli/main/install.ps1 -OutFile $env:TEMP\install-eli.ps1 -UseBasicParsing; if ($?) { & $env:TEMP\install-eli.ps1 }
Build requirements:
- docker or podman
Steps:
git clone https://github.com/alis-is/eli && cd elidocker build -f ./containers/build/Containerfile -t elibuild ./containers/builddocker build -f ./containers/test/Containerfile -t elitest ./containers/testdocker run -w "/root/luabuild" -v $(pwd):"/root/luabuild":Z -v "$(pwd)/toolchains:/opt/cross" -e TOOLCHAINS='zig:x86_64-linux-musl;zig:x86_64-windows-gnu;zig:x86_64-macos-none' -it elibuilddocker run -w "/root/luabuild" -v $(pwd):"/root/luabuild":Z -it elitest- Built binaries
eliandelicwill be created in release directory
Note: You can choose build toolchain you like from https://musl.cc/ and set its name in TOOLCHAINS
Tests:
- Run
./tools/test.sh [platform]on Linux/macOS or./tools/test.ps1 [platform]on Windows- Example:
./tools/test.sh x86_64
- Example:
Native worker regressions: configure with -DELI_BUILD_TESTS=ON, build, then run
ctest --test-dir build -R eli_worker_constructor --output-on-failure.
Tools used for build:
- eli
- luasrcdiet (for minfication)
eli.worker runs each worker on a native thread with its own Lua state. Bundled
native modules synchronize the process-wide state they share (environment
variables, signals, TLS/PSA, socket initialization, subprocess helpers);
environment variables and the working directory are shared between states while
Lua globals and loaded modules are not.
Cross-state Lua code can coordinate through worker.mutex() locks. The native
lock is shared through spawn arguments, channel messages, and worker results,
but each state gets its own box: an acquisition never transfers, a box can only
be unlocked by the thread that acquired through it, and try_lock() never
blocks. A box releases its acquisition at scope exit when to-be-closed
(local lock <close> = m; lock:lock(); ..., including on error), when the
worker state exits, and if the handle is collected while held (keep it
referenced for as long as the lock is needed). A worker that dies while holding
a lock therefore never strands it.
Third-party native extensions are not automatically thread-safe just because
Lua states are independent. Any extension that touches process-global state
(environment, cwd, signals, shared file descriptors, libc helpers such as
getenv/setlocale) must provide the same synchronization or restrict the
operation to the main state. Statics and globals in a native module are shared by
every worker state in the process.
Workers block asynchronous signals so their handlers run only in the main state.
Child processes created with proc.spawn reset that mask in the child and handle
termination signals normally. os.execute and io.popen synchronize environment
inheritance, but their children inherit the worker's blocked mask; use proc.spawn
for subprocesses that must respond to signals such as SIGTERM.