Обзор изменений в WLJS Notebook

Очень коротко из чего состоит приложение

Очень коротко из чего состоит приложение

WLJS Notebook — это приложение, похожее на Jupyter и Mathematica. Пользовательский интерфейс сделан на Electron, а сервер работает на Wolfram Language. Т.е. это не очередная оболочка для Jupyter, а полностью самостоятельное приложение. Более подробно о проекте можно почитать в предыдущих статьях: Wolfram Language JavaScript Frontend и Open-source блокнот Wolfram Language или как воссоздать минимальное ядро Mathematica на Javascript. В этой статье я постараюсь рассказать о том, чего мы достигли за последнее время. Мы добавили новую функциональность, исправили множество ошибок оптимизировали взаимодействие с сервером и ускорили выполнение кода в интерфейсе. И конечно же внесли множество изменений в пользовательский интерфейс и улучшили графику. Обо всем этом подробнее под катом!

Общий стиль приложения

Мы постоянно работаем над стилистикой приложения и добавляем различные новые эффекты и здесь лучше один раз увидеть и сравнить со старой версией чем долго расписывать (все примеры будут для Windows 11):

Было

Было

Стало

Стало

  • Заголовок окна теперь активен. В нем расположены элементы управления слева направо:

    • Главное меню

    • Открыть папку

    • Скрыть/показать область навигации слева

    • Сохранить документ

    • Поделиться ссылкой

    • Меню команд

    • Оставить вычисления

    • Повторно подключить ядро

  • Изменены шрифты по умолчанию и масштаб элементов

  • Меню настроек теперь в левом нижнем углу. Раньше оно находилось в стандартном меню как для любого окна

  • Новые иконки для различных типов файлов

  • Активная область редактора теперь выделена рамкой

  • Изменился стиль выделения текущей ячейки — вместо пунктирной рамки теперь ячейка выделяется цветом

  • Всплывающие кнопки для управления ячейкой теперь расположены более компактно и не отбирают место в окне

  • Добавлены эффекты прозрачности

Наша невнимательность к версии HTML

В ходе разработки мы столкнулись с одной неочевидной для нас проблемой. Мы используем самописный шаблонизатор, который в чем-то подобен JSX, но вместо JS использует WL — то есть мы называем его WLX. И при формировании страниц очень долгое время мы игнорировали правильное использование первой строки HTML-документов:

В итоге из-за того, что мы не использовали указание типа документа наше приложение считало, что нужно рендерить все страницы согласно спецификации HTML v1. Из-за чего мы долго не могли понять почему многие вещи при оформлении CSS-стилей не работали, например тени или разные типы заголовков в разметке Markdown. Но самая большая проблема лично для меня была в масштабе шрифтов. Ниже пример, где я сравнивал отображение одного и того же документа до включения DOCTYPE и после:

Слева

Слева «до», а справа «после». Это не текущая версия, а версия на момент исправления

Как видно на скриншоте выше — межстрочные расстояния стали более удобными, увеличился стандартный масштаб, а заголовки 2-го уровня и далее стали правильно отображаться.

Новые графики

В Mathematica и Wolfram Language — все что видит пользователь является «выражением». А пользовательский интерфейс в зависимости от формы выражения может его отображать. Почти тоже самое что и HTML, только выражения в WL могут еще и вычисляться. Математика славится своим многообразием самых разных графиков. Мы не можем просто взять и отображать их в виде картинки, ведь наша главная цель — воспроизвести принципы работы Mathematica используя веб-стек, а значит за нашими графиками тоже должны прятаться выражения. Постепенно мы добавляем все больше и больше графики, которая уже существует в Mathematica. Например, в первых версиях пользователям были недоступны чарты, а 3D-графики были очень скудными. В текущей версии мы добавили много нового.

3D графики - это все еще выражения WL, которые можно скопировать, вставить, разобрать и т.д.

3D графики — это все еще выражения WL, которые можно скопировать, вставить, разобрать и т.д.

Как видно на примере выше — теперь появилось больше возможностей для стилизации 3D-графиков. А так же мы добавили сетку и подписи осей, о которых нас давно просили. Раньше всего этого не было. Кроме того теперь пользователям доступны чарты и большее количество примитивов, которые можно использовать в Graphics.

d5d405e7b7279c3df3d65991e887c6a8.png

А так же теперь вы можете настроить освещение на графиках (без RTX):

3 источника света освещают шар и куб

3 источника света освещают шар и куб

И с трассировкой лучей конечно же:

Сфера и цилиндр с

Сфера и цилиндр с «правдоподобными» отражениями

Динамика и анимации

Мы добавили несколько собственных функций, которые автоматически импортируются при старте приложения. Первая функция — это ManipulatePlot. Это чуть более простой вариант Manipulate + Plot из Mathmatica, который хорошо работает в WLJS и подходит для простых интерактивных графиков. Например как тут:

Интерактивный график синуса

Интерактивный график синуса

Еще одна подобная функция — это AnimatePlot, которая сразу создает «анимацию» без слайдеров и кнопок:

Зацикленная анимация

Зацикленная анимация

Вся динамика на фронтенде основана на обработке событий. Большинство функций для создания анимированных и динамических графиков представляют собой один из вариантов обработчика событий EventHandler. После выполнения функции на UI создается объект, который может генерировать некоторые события, например, по таймеру. Он отправляет их на сервер и сервер отвечает сообщениями, которые говорят клиенту что и где нужно изменить.

Но в этом обзоре я не буду очень подробно останавливаться конкретно на этом аспекте, так как он заслуживает отдельной большой статьи.

Поле ввода команд

В заголовке окна приложения теперь есть отдельно поле ввода для заранее подготовленных команд. Принцип работы этого поля ввода следующий — пользователь выбирает мышкой или при помощи клавиатуры нужную команду, а приложение в текущее положение курсора вставляет специальный объект, который реализует то, что хочет пользователь. Затем «активировав» этот объект в ячейку с кодом вставляется выражение. Лучше всего это показать на каком-то конкретном примере. Например в списке команд есть захват изображения с камеры:

Получение изображение с камеры и превращение в объект Image языка Wolfram

Получение изображение с камеры и превращение в объект Image языка Wolfram

Еще один полезный пример — таблица опций функции. Нужно сначала написать функцию, затем выполнить команду «show option». Тогда в блоке под текущей ячейкой вставится таблица опций со значениями по умолчанию. Вы можете выбрать любые опции из таблицы:

Таблица опций

Таблица опций

После того как пользователь нажмет галочку в правом верхнем углу таблицы — все выбранные опции вставятся в аргументы функции:

Выбранные опции подсвечены зеленым

Выбранные опции подсвечены зеленым

Какие команды доступны в данный момент:

  • Создать/переименовать блокнот

  • Показать опции

  • Вставить в график «гизмо» для навигации

  • Форматировать текст/код

  • Вставить матрицу/файл с данными/изображение с камеры/спец-символ

  • Открыть терминал

Чат с LLM

Но если вдруг пользователь написал в поле ввода команд что-то такое, чего нет в подготовленном списке команд, то приложение создает чат с большой языковой моделью. По умолчанию это GPT текущей общедоступной версии, но всегда можно сконфигурировать любую другую модель, которая поддерживает OpenAI API. Да вам понадобится VPN, если для текущего IP нет доступа к openai.com и конечно же ключ. Сконфигурировать параметры запросов к языковой модели можно в меню настроек в секции AI Assistant:

В настройках можно сменить базовый адрес, название модели, температуру, размер контекста и конечно же изменить ключ для доступа

В настройках можно сменить базовый адрес, название модели, температуру, размер контекста и конечно же изменить ключ для доступа

Ну и вот как это выглядит в действии:

Ассистент может менять структуру документа и выполнять код

Ассистент может менять структуру документа и выполнять код

Смешивание кода и Markdown

Теперь при оформлении ячеек формата .md в них можно использовать не только стандартный синтаксис, но и выражения языка Wolfram с использованием синтаксиса WLX. То есть если я создам вот такую ячейку:

.md
# Current date is 

То получу следующий результат:

Текущая дата в заголовке

Текущая дата в заголовке

Подробно о WLX можно почитать в документации, но если совсем коротко, то стандартный HTML превращается в разметку, а все теги с прописной буквы в выражения:

// обычный HTML <$MyVariable /> // Одиночнй тег превращается в вызов переменной arg1 arg2 // парный тег превращается в вызов функции // MyFunction["arg1", "arg2"]

Рисование в MD

Теперь можно прямо на месте нарисовать какую-нибудь блок схему (кстати я сделал это для КДПВ). Для этого нужно в .md-ячейке ввести !![], выполнить ячейку и дальше можно рисовать в отдельном блоке Excalidraw:

Блок для рисования на основе Excalidraw

Блок для рисования на основе Excalidraw

После того как пользователь закончит процесс рисования, то можно снова поставить курсор в текстовую часть ячейки, нажать сочетание клавиш Shift+Enter и итоговая картинка вставить в выходную ячейку вот так:

Выходная ячейка с полученной картинкой

Выходная ячейка с полученной картинкой

Документация

Теперь у всех встроенных функций во всплывающей подсказке есть дополнительная кнопка в углу, которая открывает страницу документации к функции прямо с сайта Wolfram Research:

Новое окно Electron со страницей официальной документации

Новое окно Electron со страницей официальной документации

Терминал

Теперь при помощи команд можно запустить отдельное окно терминала, которое позволит выполнять команды на основном ядре сервера. Так, например, можно получить прямой доступ к серверам, которые обрабатывают события:

Терминал с доступом к master kernel

Терминал с доступом к master kernel

Оптимизация

Одним из узких мест во взаимодействии между клиентом и сервером является сериализация и маскирование данных при передаче выражений по протоколу WebSocket. Мы в том числе пытаемся уменьшить задержку ответа сервера и увеличить скорость передачи больших объемов данных. Нам удалось оптимизировать маскирование и размаскирование данных для WebSocket, о чем я писал в предыдущей своей статье. А так же сериализацию в JSON. Благодаря этим оптимизациям сервер может стримить данные с довольно высоким фреймрейтом. Например, ниже демонстрация вычислений в реальном времени:

Анимация весила больше 8 Мб, поэтому тут можно выдать медаль за сжатие джипег

Анимация весила больше 8 Мб, поэтому тут можно выдать медаль за сжатие джипег

Таблицы и датасеты

Теперь для объектов TabView и Dataset есть специальные способы отображения на фронтенде:

Отображение таблиц

Отображение таблиц

Заключение

На самом деле это далеко не все изменения, которые произошли с проектом WLJS Notebook. Их намного больше, но мы в этой статье постарались рассказать про самые заметные и полезные. Подробнее всегда можно почитать в списке релизов, документации, в блоге проекта, а так же в папке с примерами (на всех скриншотах она слева). Всем спасибо за внимание, увидимся в следующих статья!

«Атом» с подсветкой

© Habrahabr.ru