Лёгкая система авторинга интерактивных CLM-презентаций. Vite + SCSS + Web Components, без runtime-зависимостей, offline-first, оптимизировано под планшет и WebView.
Авторская среда + библиотека компонентов + сборщик в один офлайн-пакет.
Каждый слайд — отдельный HTML. Добавил файл — он сам появляется в деке (Vite glob + live-reload).
Переиспользуемые Web Components: <stat-card>, <bar-chart>, <hotspot-image>.
В DOM только текущий слайд ± соседи — память WebView не течёт на больших деках.
Просмотры, клики и время на слайде пишутся в живой поток. Экспорт в JSON.
Токены {{viewer.name}} прямо в тексте — движок подставляет значения.
Дизайн-токены в theme.scss, переключение через [data-theme].
Ловит битые переходы, missing-ассеты и кривой JSON ещё до сборки.
Единый self-contained офлайн-HTML, готовый к заливке в CLM-платформу.
Node 18+, npm. Зависимостей в рантайме нет — только dev-тулинг.
git clone https://github.com/Helgechka/pulse-clm.git
cd pulse-clm
npm install
npm run dev # студия с live-reload → http://localhost:5180
npm run validate # проверка деков
npm run build # validate + production-сборка в dist/
npm run package # офлайн self-contained пакет
npm test # unit-тесты движка и валидатора
npm run new:slide cardiolex pricing "Стоимость терапии"
# создаст presentations/cardiolex/slides/NN-pricing.html
# слайд появится в студии автоматически
npm run new:deck onkocet violet # id деки + тема
Чёткое разделение по ответственностям. Контент отделён от кода.
presentations/ ← презентации (каждая — папка)
cardiolex/
deck.json ← конфиг: заголовок, тема, данные зрителя
slides/ ← слайды как отдельные HTML-файлы
assets/ ← ресурсы деки
src/
engine/ Pulse.js ← оркестратор: навигация, проводка слоёв
SlideStore.js ← ленивый монтаж слайдов
analytics.js ← трекер вовлечённости
animate.js ← анимации входа
input.js ← жесты + клавиатура
interpolate.js ← токены {{...}}
constants.js ← имена событий/классов
components/ ← библиотека Web Components
ui/ AnalyticsPanel · PlayerChrome · toast
styles/ theme · base · components · panel
tests/ SlideStore.test · validate.test
scripts/ new-slide · new-deck · validate · build-packages
Библиотека переиспользуемых элементов. Каждый сам анимируется при показе слайда.
| Компонент | Назначение |
|---|---|
<stat-card value unit label> | Число с анимацией счётчика |
<bar-chart bars='[…]'> | Диаграмма с растущими столбцами |
<hotspot-image emoji points='[…]'> | Интерактивная схема с точками-хотспотами |
Добавь класс в src/components/, зарегистрируй в index.js, стили — в components.scss. Реализуй enter() для анимации входа и диспатчи pulse:track для аналитики.
Декларативный API на атрибутах + тонкий JS.
| Что | Как |
|---|---|
| Навигация | data-go="slide-id" на любом элементе |
| Открытие ресурса | data-asset="file.pdf" |
| Аналитика клика | data-track="name" |
| Персонализация | токены {{viewer.name}} |
| Глубина ленивого окна | "preload" в deck.json |
Большой дек (40–80 слайдов с видео) не помещается в память WebView, если держать всё в DOM. SlideStore монтирует только окно: текущий слайд и preload соседей, остальные выгружает — их компоненты получают disconnectedCallback. Проверено тестом: пик 3 слайда из 6 в DOM.
npm run validate прогоняет деки до сборки, ненулевой код при ошибках (встроен в build, годен для CI).
$ npm run validate
cardiolex
✖ 03-moa.html: data-go="efficasy" → нет такого слайда (похоже на "efficacy")
✖ 02-efficacy.html: <bar-cart> — неизвестный компонент
⚠ 04-safety.html: instrukciya.pdf (1.8 МБ) > лимита 500 КБ
1 дек · 2 ошибки · 1 предупреждение
Ошибки (блокируют сборку): битый data-go с подсказкой id, дубли/отсутствие data-id, missing-ассеты, неизвестные компоненты, кривой JSON в пропсах, несуществующая тема.
Предупреждения: тяжёлые ассеты, неизвестные токены, нецелый preload, нет data-title.