Commit graph

3 commits

Author SHA1 Message Date
11470a5fba
bend: wire bend!-call into the pyodide tier — playground python ⚡
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.
2026-06-14 18:25:46 -04:00
ff2ef382c7
gc diagnostics: per-tier heap pressure surfaced in repl tabbar
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.
2026-06-14 17:32:48 -04:00
d8ffab5ea6
repl: /repl/ page with encrypted multi-tab sessions
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.
2026-06-14 12:50:35 -04:00