Комментарии 17
Круто. Я прямо глазам своим не верю: изящное внятное решение для повышения user ux, а не developer ux, в npm.
Библиотека, насколько я понял, ваша — мои искренние поздравления и пожелания всяческих благ. Очень верной тропой идете, товарищ :)
Да, библиотека моя, я давно ее веду, с 2018 года в разных реализациях. Спасибо за теплые слова, это мотивирует!)
Ну, «правду говорить легко и приятно», как говорил один перевымышленный персонаж.
Я просто правда в восхищении (и недоумении, как так вышло, что ничего похожего ранее создано не было, а еще — как так получилось, что пока единственный, кто оценил по достоинству — человек, вообще не пересекающийся с фронтендом).
Год назад писал тот же функционал самостоятельно, потому что не подумал найти готовое решение, спасибо, буду иметь ввиду
socket.addEventListener('message',
vs.
tabs.on('stream-update',
Вы наверное думаете, что вы король лаконичности, а те, кто придумал название addEventListener — душные старпёры?
Спасибо за комментарий! Я вовсе не считаю, что авторы addEventListener
— “душные старпёры”, а сам я — “король лаконичности”. Разные стили и названия отражают разные подходы и эпохи в развитии JavaScript и веб-стандартов. addEventListener
в свое время ввел более формальный и универсальный способ подписки на события, а короткие методы вроде on
стали популярны благодаря более “цепочечному” стилю кода в фреймворках и библиотеках. В итоге каждый разработчик выбирает то, что ему удобнее и понятнее в контексте конкретного проекта. Я просто поделился своим взглядом — он, конечно, не единственно верный. Но рад, что статья вызвала интерес и дискуссию!
Крутое решение, но пока читал статью, наткнулся на мысль, ответ на который не нашел, либо его тут нет.
Какой очевидный плюс от этой библиотеки, против использования нативных Broadcast channel с Shared worker?
Например когда нужна библиотека для рендеринга сразу понятно, что могу взять react и получить множество преимуществ, а не писать innerHtml на каждое событие.
А какие преимущества тут?
BroadcastChannel - сам по себе решает задачу лишь обмена сообщениями между вкладками, но не решает проблему гонки и синхронизации между ними. Мое решение делает "главной" лишь одну вкладку и с нее, допустим, общается с бекендом и сервисами, поднимает WebSocket, принимает SSE и т.п., рассказывая другим вкладкам о результатах.
А каким алгоритмом пользуетесь для назначения главной и второстепенных вкладок?
Есть же ссылка на репозиторий. Проблема выбора лидера тут не стоит: открытие и закрытие вкладок — не высококонкурентный процесс, поэтому код просто при закрытии главной вкладки выбирает первую из следующих и назначает ее главной.
Насколько я вижу, ключ primaryTabId
захардкожен. Не будет ли проблем, если на одном сайте есть несколько виджетов/приложений, независимо юзающих это либу?
Скажем, на страницах A, B, и C есть виджет W1, а на страницах B и С еще и виджет W2.
У каждого виджета свой экземпляр TabsBroadcast со своим channelName
.
Страницы открываются в алфавитном порядке в новых вкладках.
Если W2 создаст экземпляр TabsBroadcast с emitByPrimaryOnly: true
, похоже, что он не сможет посылать сообщения, т.к. статус PrimaryTab будет занят первой вкладкой.
P.S. Я не проверял, просто бегло просмотрел код, так что могу ошибаться.
Замечание хорошее, спасибо что изучали код и пытались его понять! Объясняю:
1) Механизм создания нескольких экземпляров TabsBroadcast
нужен для того, чтобы объединять несколько приложений внутри одного веб-сайта. Поэтому можно создавать бесконечное количество инстансов, каждый из которых будет обмениваться сообщениями между собой.
2) А вот primaryTabId
- это сущность, связанная с вкладками браузера (в каждой из которых работает N инстансов). При закрытии или переключении вкладок браузера все N инстансов должны будут изменить режим Primary\Slave. Т.е. переменная относится к общему для всех инстансов механизму переключения режима активности.
Так же замечу, что если на новой фоновой вкладке будет открыта вкладка с новым экземпляром TabsBroadcast
у которой стоит флаг "emitByPrimaryOnly: true", то она ничего отправить никому не сможет. Это вы верно подметили. Но при этом, она не считается Primary, а значит она никакие активности не должна выполнять в принципе (не открываются WebSocket, не получает SSE, ничего не дергает по API).
Я имею в виду, что приложения W1 и W2 могут разрабатываться независимо одно от другого и не знать, что в другом тоже используется эта либа. И, соответственно, не знать, что кто-то другой может застолбить primaryTab
Если это вообще не связанные приложения, то все равно беспокоиться не о чем) Сама переменная в localStorage называется уникально, словарь выглядит так:
dict: {
tab_prefix: 'xploit_tab_id_',
slave : 'xploit_slave',
primary : 'xploit_primary',
primaryTabId : 'xploit_primary_tab_id',
primaryStatusChanged : 'XPLOIT_TAB_STATUS_CHANGED',
}
Вряд ли кто-то сможет их перепутать и позаимствовать)
Но есть о чем задуматься. Вероятно, нужен "механизм фонового взаимодействия" вновь открываемых вкладок, у которых создается новый инстанс TabsBroadcast
. Я подумаю об этом. Спасибо!
tabs-broadcast — библиотека для синхронизации вкладок