Add Server-Sent Events support to the El runtime. El v2 handlers can now
hold HTTP connections open and push events in real time.
New builtins in el_seed.c:
__http_conn_fd() — retrieve raw fd from thread-local set by worker
__http_sse_open(fd) — send SSE headers (text/event-stream), keep-alive
__http_sse_send(fd, data) — write "data: <data>\n\n" frame
__http_sse_close(fd) — close the connection fd
http_worker_v2 in legacy/el_runtime.c now:
- stashes the fd via el_seed_set_http_conn_fd() before calling the handler
- detects the "__sse__" sentinel return value to skip http_send_response
and skip close(fd) — SSE handler took ownership of the fd
- clears the thread-local after the handler returns
El wrappers added to runtime/http.el:
http_conn_fd() http_sse_open(fd) http_sse_send(fd, data)
http_sse_close(fd) http_sse_sentinel()
- runtime/stdlib.el: master import file for the full El standard library
in correct dependency order (string→math→time→env→fs→exec→json→http→
state→thread→channel→engram→manifest); test.el excluded (dev-only)
- tools/install.sh: installs El to a prefix (default /usr/local/el);
copies elc binary, runtime .el files, headers, compiles libel.a from
el_seed.c + el_runtime.c, generates an installed stdlib.el with absolute
paths
- tools/new-project.sh: scaffolds a new El project with src/main.el,
build.sh (auto-discovers local elc/runtime), README.md, .gitignore;
verified working end-to-end
- AGENTS.md: fix elc rebuild docs — elc writes to stdout, not to its second
argument; correct usage is ./dist/platform/elc elc-cli.el > elc-new.c
Introduces Go-style channels as El's mid-flight communication primitive,
completing the threading model: threads can now not only spawn/join but
also communicate while running.
Part 1 — seed layer (el_runtime.c / el_runtime.h):
- Add __thread_create/__thread_join/__mutex_new/__mutex_lock/__mutex_unlock
as C seed primitives (dlsym-based thread dispatch, pthread mutex table)
- Add __channel_new/__channel_send/__channel_recv/__channel_try_recv/__channel_close
as MPMC channel seed primitives backed by mutex + condvar + circular buffer
- Bounded channels (cap > 0): circular buffer, sender blocks when full
- Unbounded channels (cap == 0): dynamic array, grows on demand, never blocks
- channel_close wakes all blocked recvers/senders; recv drains then returns ""
Part 2 — El API (runtime/channel.el):
- channel_new/send/recv/try_recv/close — thin wrappers over seed layer
- channel_pipeline — spawn N worker threads reading from in_ch, applying
fn_name, writing to out_ch; workers exit on "" sentinel from close
- channel_drain — collect all messages from a closed channel into [String]
- channel_fan_out — send a [String] list into a channel then close it
Part 3 — codegen.el:
- Register all 10 seed builtins (__thread_* + __channel_*) in builtin_arity
so the arity checker validates call sites at compile time
Provides assert_true/false, assert_eq, assert_int_eq, assert_neq,
assert_contains, assert_starts_with, assert_ends_with, and fail.
Test cases are registered by name+fn_name, executed sequentially via
the thread/dlsym dispatch mechanism, with results tracked in state_.
Includes tests/runtime/string_test.el covering all 23 string.el exports.
All string, I/O, math, classification, splitting, joining, counting, padding,
and URL encoding functions from el_runtime.c implemented in El using seed
primitives. No C required; compiles via the normal El pipeline.
- runtime/engram.el: thin El wrappers over all __engram_* and __generate
seed primitives (16 functions), matching the el_seed.c API exactly
- runtime/manifest.el: build manifest documenting module load order and
the cat+compile+cc command for runtime builds
- el-compiler/src/codegen.el: add 77 __-prefix seed primitive entries to
builtin_arity, covering str, fs, http, thread, exec, env, time, uuid,
math, state, html, json, and engram seeds
Migrates fs_read/write/exists/mkdir/write_bytes/list, exec/exec_bg/exec_command/exec_capture,
env/args/exit_program, state_set/get/del/keys, uuid_new/v4, and list helpers get/len from
el_runtime.c into El source as thin wrappers over seed primitives.
Introduces El's first-class threading primitives built on the seed layer's
__thread_create/__thread_join/mutex ops. parallel_map is the key deliverable:
spawns one thread per item, joins in order — replaces bash fan-out for room
dispatch and any other concurrent HTTP workload.
Thin El wrappers over seed JSON primitives (json_get, json_get_raw,
json_parse, json_stringify, json_set, json_array_len, json_array_get,
json_array_get_string) plus typed extractors (json_get_string/int/float/bool)
and pure-El builders (json_build_object, json_build_array,
json_escape_string) that require no seed call.
Thin El wrappers over seed primitives that form the public HTTP API for
El programs. Covers GET/POST/DELETE, header-map variants, binary streaming
to file, form-auth, v1/v2 server dispatch, and http_response envelope
construction. Documents two new seed primitives needed: __http_do_map and
__http_do_map_to_file (ElMap-accepting variants to avoid needing map
iteration in El).