Live Mercury размещает компоненты Mercury на страницах, которые рендерит Phoenix. Сервер создаёт один элемент и указывает LiveView не менять его содержимое; клиентский хук монтирует в него компонент Mercury Hyperscript, передаёт свойства с сервера и обновляет их при изменении assigns в LiveView.
Что такое Live Mercury
Остров — элемент серверной страницы, содержимым которого управляет клиентский компонент. Вокруг него — HEEx, внутри — Mercury Hyperscript. LiveView не применяет патчи внутри острова, поскольку элемент имеет phx-update="ignore". Свойства передаются в атрибутах элемента, а обновления — патчами через уже открытый сокет LiveView.
Поэтому страница читается без JavaScript, сервер сохраняет управление данными, а клиентский код выполняется только там, где нужен.
Две части
| Часть | Где находится | Что предоставляет |
|---|---|---|
| серверная | echo/apps/live_mercury, модуль LiveMercury |
mercury/1 — функциональный компонент, выводящий элемент острова и его свойства |
| браузерная | fiberfx/live-mercury, пакет @fiberfx/live-mercury 4.0.0 |
getHooks и createMercuryHook (жизненный цикл MercuryHook), useLiveMercury, Link и кодеки патчей |
@fiberfx/hyperscript — peer-зависимость браузерной части, поэтому остров использует единую среду Hyperscript страницы.
Доска KAN использует обе части. Её LiveView выводит остров:
def render(assigns) do
~H"""
<EchdOSWeb.KanLayouts.nav active={:board} />
<LiveMercury.mercury
name="KanBoard"
id="kan-board"
socket={@socket}
source={@source}
now={@now}
lanes={@lanes}
rungs={@rungs}
messages={@messages}
/>
"""
end
Бандл регистрирует компонент под тем же именем и открывает сокет:
const liveSocket = new LiveSocket("/live", Socket, {
params: { _csrf_token: csrfToken },
hooks: getHooks({ KanBoard, SeatsExplorer, SquadsExplorer, KanAdmin }) as never,
});
liveSocket.connect();
name="KanBoard" на сервере и ключ KanBoard в карте getHooks связывают обе части.
Два варианта размещения в репозитории
Курс рассматривает двух реальных потребителей с разными способами монтирования островов:
- Представления KAN в echd_os (
kan_board_live.ex,kan_seats_live.ex,kan_squads_live.ex,kan_admin_live.ex) выводят<LiveMercury.mercury>. Один бандл,kan.mjs, регистрирует четыре компонента черезgetHooksи открывает LiveSocket страницы по пути/live. - Острова курсов EDU выводят
EchoEduWeb.Island.island/1с хукомCourseIsland. У каждого острова свой бандл. Загрузчик EDU импортирует его по URL и передаёт обратные вызовы LiveView вhookбандла — жизненный цикл Live Mercury, созданный черезcourseIsland(component).
Оба варианта используют один жизненный цикл, createMercuryHook. Различаются источники свойств и тот, кто импортирует компонент.
Курс
- LM0, Острова: что такое остров, какой элемент выводит каждый вариант размещения и как клиент его монтирует.
- LM1, Остров в LiveView: путь сокета, четыре обратных вызова хука и события в обоих направлениях.
- LM2, Сборка островов через mx:
mx build --lib, пять сборок для островов EDU и этап сборки образа без Node. - LM3, Свойства и потоки:
data-props-diffиdata-streams-diff, компактный формат патчей,upsert,limitи пути$$<id>. - LM4, Серверный рендеринг: флаг
ssr, отключённый по умолчанию,LiveMercury.SSRи причины замены серверной разметки вместо гидратации. - LM5, Тестирование островов:
LiveMercury.Test.get_mercury/2, проверка событий острова, тесты хука иcheck_hosts/3в EDU. - LM6, итоговое задание, запланировано: остров в LiveView, собранный без Node. Оно зависит от H3–H5 эпика 24 и отказа от Vite в бандле представлений KAN:
kan.mjsпока собирается с pnpm и Vite.
Что уже поставляется
Острова EDU собираются через mx внутри образа на этапе, который проверяет отсутствие node в PATH. Бандл представлений KAN, kan.mjs, там не собирается: он хранится в Git в priv/static приложения echd_os и собирается вне образа, как показано в уроке о сборке. Версия @fiberfx/live-mercury в его package.json — 4.0.0.