lumbda-py.js (and the three deployed mirrors) now expose setBendUrl
and register a bend!-call primitive in the pyodide-hosted lumbda
environment.
Implementation:
- JS loader stashes a `globalThis._lumbdaPyBendCall` function that
does sync XHR POST to the configured bend URL (legal in Web
Workers, where the pyodide tier runs in this playground)
- Python bootstrap imports `_lumbdaPyBendCall` from `js` and binds
it as a builtin under the symbol `bend!-call`, accepting any
value and stringifying via lumbda.show before sending
- setBendUrl(url) on the tier object updates the JS closure; the
runner.js plumbing already calls it on every tier when the user
saves a bend URL in the ⚡ bar
This brings the pyodide tier to parity with the asm (WAT) tier for
HTTP-mode bend. The emcc C tier still lacks the bind — wiring it
needs a new wasm primitive built via emcc; lands in the next commit.
Tested: bend!-call "(ping)" against the same gpu-worker endpoint
returns the same (ok pong) S-expression the asm tier sees.
Step 1 of the GC effort. Each tier loader now exposes heapStats():
- asm-wasm — lumbda_heap_used / lumbda_heap_total wat exports
- c-wasm — emscripten linear memory size (no free path right now,
so used = total; documented in the loader)
- python — pyodide module linear memory size; CPython GC cycles
this naturally
Worker handles a "heap" message kind that round-trips the active tab's
loaded tiers; repl tabbar shows a compact "py 12M · c 32M · asm 4M"
strip next to the buttons. Polls every 2s.
Doesn't solve the leak — just makes pressure visible so the user knows
when to use "reboot tier". Real GC (Cheney over the WAT bump allocator,
Boehm-em or custom mark-sweep for c-wasm) coming next.
Interactive REPL at lumbda.com/repl with:
- multi-tab sessions (click + to add, × to close, double-click to rename)
- per-tab tier selector (python/c/asm/all-three race)
- persistent transcripts encrypted in localStorage via Web Crypto
(PBKDF2 + AES-GCM, vault id = SHA-256(password || device-salt) —
same pattern as unsandbox's vault-encryption-design.md, native
crypto.subtle API instead of CryptoJS)
- ephemeral mode (skip vault, transcripts vanish on reload)
- one worker per (tab × tier) — state persists across evals in a tab
- reboot tier button (terminate this tab's worker, fresh state next eval)
- cancel button (kills the running worker in active tab)
Home page now links to both /playground/ and /repl/.
Tier state itself does NOT persist across reloads — the transcript does,
but defines/set!/hash-tables vanish with the worker. Portal save/resume
in WAT (deferred) will let a tier session survive close+reopen.