Current section
Files
Jump to
Current section
Files
src/plushie@runtime_web.erl
-module(plushie@runtime_web).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/plushie/runtime_web.gleam").
-export_type([js_runtime_target/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" JavaScript runtime: callback-driven Elm update loop.\n"
"\n"
" This is the JS-target equivalent of `runtime.gleam` (which uses\n"
" OTP actors). It manages the app model, executes the update/view\n"
" cycle, diffs trees, sends patches to the WASM bridge, and handles\n"
" command execution and subscription lifecycle.\n"
"\n"
" State is stored in a mutable JS object via FFI. The update cycle\n"
" is synchronous (no process boundaries). Event coalescing uses\n"
" `queueMicrotask` to batch high-frequency events.\n"
"\n"
" ## Architecture\n"
"\n"
" The JS runtime reuses the same pure functions as the BEAM runtime:\n"
" - `app.get_update(app)(model, msg)` for the update step\n"
" - `tree.normalize_view(raw_tree, registry, memo_cache)` for scoped\n"
" IDs, widget registry accumulation, and explicit-window validation\n"
" - `tree.diff(old, new)` for incremental patching\n"
" - `protocol/encode` (JSON path) for wire serialization\n"
"\n"
" What differs is the concurrency model: instead of OTP actors and\n"
" process messages, the JS runtime uses callbacks, Promises, and\n"
" setTimeout/setInterval for async work. Those callbacks enter\n"
" through the JS handle's dispatch queue, so a callback that fires\n"
" while an update is running is processed after the current\n"
" update/render cycle finishes.\n"
).
-type js_runtime_target() :: js_runtime_target.