CLM Authoring System

Pulse

Лёгкая система авторинга интерактивных CLM-презентаций. Vite + SCSS + Web Components, без runtime-зависимостей, offline-first, оптимизировано под планшет и WebView.

⚡ Vite + SCSS 🧩 Web Components 📦 Offline-first 🪶 Zero deps ✅ 9 тестов

Возможности

Авторская среда + библиотека компонентов + сборщик в один офлайн-пакет.

📁

Слайды как файлы

Каждый слайд — отдельный 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.

⚠️ Демо-контент про «Кардиолекс®» — вымышленный препарат, данные не являются медицинской информацией.