Sova Profile picture
I'm a podcast publisher focusing on frontend development and writing Rust in my spare time.

Oct 7, 2020, 42 tweets

Тред про effector devtools!

Лайкайте, ретвитайте, отвечайте, а я постараюсь за вами поспевать!

Для начала давайте определимся с проблемой, зачем нам девтулзы и что они пытаются решить. У нас есть приложение любого размера, и нам хочется одним взглядом на некую схему понять его структуру, кто от кого зависит и какие части приложения изменять опасно, в общем архитектура

Пример бенефита при достижении предыдущей цели: граф можно строить при создании PullRequest, и показывать визуальный дифф изменений, какие связи были удалены, какие созданы. То есть начать ревью ещё до просмотра кода. О тулзах вроде dependency-cruiser, для валидации связей умолчу

Казалось, бы возьми madge или тот же dependecy-cruiser и будь счастлив. Но то, что генерируют эти ребята, вряд-ли можно назвать читабельной схемой. Здесь только около десятка файлов, и уже связи между файлами без взаимодействия не воспринимаются. Увы, выбрасываем такое

Вот так можно отобразить оператор sample, у него три связи: source, clock, target. Каждый unit может находиться в своём файле, так ещё и сам sample может лежать отдельно ото всех. Получаем связь из 4 файлов. Существующие инструменты уже отваливаются.

Здесь: круг — событие, квадрат — стор, суффикс FX — эффект, круг с фигурой внутри — sample. Пример взят с anode.effector.dev

И это только один sample, коих в проекте может быть несколько сотен. В моей обычной модели имеется как минимум 3-4 подобных оператора и около десятка сущностей. Для каждой страницы своя модель, а ещё по несколько моделей в каждой фиче. В итоге общее количество связей около тысячи

На самом деле индустрия биологов имеет опыт построения огромных сложнейших схем. Например: метаболические пути в организме

Посмотреть полностью можно по ссылке. roche.com/sustainability…

Разница в том, что эта схема нарисована вручную, а нужен какой-то автоматический способ располагать сущности так, чтобы человеку рассматривающему это, процесс приносил пользу, а не страдания

А вот ещё один небольшой пример ручного расположения. Оправданные циклические зависимости, которые должны быть легко идентифицируемы на общем виде схемы приложения.

Примерно год назад был разработан алгоритм прокладки связей между нодами. Связи не должны сливаться, всегда должна быть возможность четко идентифицировать связанные ноды. Да, хотелось бы избежать пересечений, но граф связей не может быть планарным, но может быть наглядным

Разделение соседних линий сделано по принципам дорожного движения: каждый путь это шести-полосное шоссе, в каждой полосе может находиться лишь одна связь, если кто-то не успел занять нужную ему полосу, то он встаёт в соседнюю и делает перестроение позже

Для нахождения путей вокруг нод используется алгоритм A* на сетке: en.wikipedia.org/wiki/A*_search…

Потыкать можно тут: qiao.github.io/PathFinding.js…

Ещё была попытка использовать CSS Grids для отображения вложенности и выравнивания, но без сабгридов это идея умерла.

Судя по предыдущим картинкам можно провести некие параллели с электроникой. Но опять же, это всё ручная прокладка. Даже на материнских платах всё ещё много ручной работы.

Текущие способы отображения графов нестабильны — при зуме вглубь и обратно, ноды не сходятся на прежние места, а встают заново в случайном порядке. Поэтому точно нужен способ зумить граф от отдельных моделей к общей структуре связей изменяя масштаб без перестройки положений.

Не так давно @zero__bias показал единственный пейпер показывающий возможное решение проблемы, как сжимать направленный граф. Повторять его не буду, лишь дам ссылки и покажу скриншоты pubmed.ncbi.nlm.nih.gov/24051826/

И вот с этого момента визуализация связей в приложении существенно продвинулась. Но начинается всё, конечно же с ручных зарисовок

1) упаковка связей файлов и директории в одну сущность.
2) увеличение точки связей при подведении множества соединений
3) выведение соединений юнитов на границу файла, чтобы не пересекать границу лишний раз

Итак, способ ужатия найден, алгоритм прокладки связей тоже есть. Осталось всё соединить! Ииии… как такое количество связей вообще можно красиво проложить, даже имея вышеописанные алгоритмы?

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

Эта задача даже звучит не так просто. А теперь ещё один живой пример: слева вверху квадрат с россыпью связей это слой апи, где пачка эффектов создана на основе базового, через attach. Нужно понять как такое отобразить, не оставлять же этот веер.

Прошу заметить, что в этом масштабе нет подписей. Ведь это application structure overview. Да и добавлять подписи сейчас, это значительно усложнить себе задачу, сначала нужно научиться вменяемо прокладывать связи, а уж потом их красиво подписывать

Все эти схемы генерируются из JSON. А вот этот самый JSON можно сгенерировать из любого приложения на эффекторе. Для этого есть пакет trail npmjs.com/package/trail. Можно не переживать, данные продакшена он не утянет, он лишь сгенерирует JSON структуру связей и распечатает её

Если хочется попробовать поиграться с визуализацией связей самостоятельно, то просто используйте этот пакет и вуаля, нерешенные проблемы computer science падают к вашим ногам. А ещё можно помочь с визуализацией #effector.

Самая сложная часть будущих девтулзов это визуализация схемы. Тот же effector-inspector, может спокойно отображать содержимое сторов и триггеры ивентов. Если вернуться к началу треда, то очевидно, что в сложных приложениях схема связей является основной целью использования девтул

Ну и как бонус, из схемы связей, можно обратно сгенерировать код на javascript, ровно также разложить его по файлам и директориям. Потеряются разве что хендлеры эффектов, вотчеров и комментарии.

Потыкать борд с текущим отображением связей можно по ссылке diagrams-stats-ngs57r4aa.vercel.app

Всем спасибо за чтение треда! Я буду продолжать его, как только появятся новости про devtools.

Есть апдейт! Картиночки before/after.

dense dir layout (before/after) — если после добавления блока-папки в строке остаётся место, то расположить следующую папку на пустующем месте, а не справа. это позволило уместить на экране на одну папку больше

unwrap dirs with single index files (before/after) — если в папке есть только index-файл, то вынести его содержимое в папку на уровень выше.

Благодаря этому существенно уменьшилось число связей в самых нагруженных папках вроде верхней левой, потому что от одной папки чертится одна связь, а папок стало меньше.

в сумме, эти две возможности позволили отобразить всю схему на одном экране, иначе схема больше на четверть

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

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

проблема в том, что на схеме сейчас по техническим причинам нет небольшой части вызовов split. Из 442 не видно 388. Если с окрестностями точки варианты есть разные, то как прокладывать путь через всю папку до этого самого места соединения — не понятно.

Ещё один пример обнаруженных конвенций: слева входящий связи из других папок, справа исходящие, то есть по сути это импорты и экспорты.

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

Изначально планировалось просто сближать линии визуально, по прежнему отображая каждую из них, но кажется с определённого количества связей в шине их всё равно придётся скрывать и расчищать место для шины от других юнитов тоже придётся, тут тоже непонятно как это должно выглядеть

Намедни popuguy предложил рассмотреть способ застройки в Финляндии, там сначала прокладывают дороги, а лишь потом начинают строительство зданий. И это весьма интересная мысль, ведь дороги уже есть, двухполосное движение упрощает прокладку линий

Как мы помним алгоритм A* уже прокладывает пути. Можно легко показать связи, кликнув по ноде

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

Share this Scrolly Tale with your friends.

A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.

Keep scrolling