Здравствуйте, меня зовут Дмитрий Карловский и я.. как 30 лет назад вошёл в IT, и всё никак не могу из него выйти. И всё это время я не только работал работу, но и точил свой набор топоров, благодаря которому путь стартапа от идеи до прода сокращается с минимум недели до максимум часа.

Заинтригованы? Тогда следите за руками внимательно, иначе пропустите как мы во мгновение ока нарисуем полноценный фронтенд без чат-ботов, поднимем базу данных без сервера, задеплоим всё на статический сервер без боли, и будем наслаждаться результатом без тормозов.

Evrone Meetup

Это - текстовая версия доклада с Evrone <Frontend> Meetup. Можете глянуть видео запись с живыми запинками, а можете читать далее с более выверенными формулировками.

Дмитрий Карловский

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

Дмитрий Карловский
30 лет в IT, но всё ещё не скуксился

Яндекс, 1C, Газпром
Wrike, SAPRUN, Deutsche Bank

10+ докладов, 70+ статей, 60+ видео
ОРП, ФТ, Tree, MT, HARP
MAM, mol, HyOO, CRUS?DB

Выделенные жирным велосипеды мы и будем далее использовать.

SlowDating

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

И захотел я получить о неё обратную связь. Ведь многие проблемы человечества возникают всего лишь из-за недопонимания.

Сервис сбора обратной связи

Но решить проблему здесь и сейчас - слишком мелкая задача. Так что решил я сделать целый сервис для сбора отзывов, который могли бы применять все в самых разных контекстах.

И тут вы, наверно, спросите меня: "А чего бы просто не создать Гугл Яндекс форму?". Ну, помимо наличия у них фатального недостатка, этими набившими оскомину формами уже никого не впечатлишь. А вот собственным, поднятым в кратчайшие сроки, сервисом - есть шанс. Кроме того..

? Мы же спортсмены

? Сапожник должен есть свои сапоги

? Можно сделать гораздо лучше

Рабочее окружение в один клик

Итак, приступим. Самый простой способ поднять рабочее окружение - это пройти по ссылке на облачную среду разработки.

https://gitpod.io/#https://github.com/hyoo-ru/mam

Там уже есть VSCode со всеми нужными настройками и плагинами, так что можно сразу приступать к написанию кода. Но это не спортивно..

Старт проекта с нуля

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

mkdir mam
cd mam
npm exec mam
start http://localhost:9080/my/survey/app/-/test.html

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

Подробнее про MAM

Я подробно рассказывал про принципы разработки в нашей экосистеме в отдельной статье..

MAM: сборка фронтенда без боли

Так что подробно на этом мы сейчас останавливаться не будем.

Прикладная область

Итак, мы уже готовы писать код, но про что именно мы его будем писать? Давайте опишем нашу предметную область..

Любой пользователь нашего сервиса является персоной (Person). У каждого из них есть список встреч (Meet), у каждой из которых есть список отзывов (Opinion). Вроде бы не сложно, да?

Как это обычно делают

Давайте представим, как это всё выглядело бы с традиционным подходом. Берётся реляционная СУБД. В ней создаётся пяток табличек и десяток индексов. Работать с SQL напрямую не удобно, поэтому обмазываются ORM. Работать напрямую с СУБД не безопасно, поэтому прячут её за API сервером. На клиенте работать напрямую c API не удобно, поэтому придумываются какую-нибудь клиентскую обвязку. А чтобы он с сервером не подрался, то прикручивают какую-нибудь изоморфную схему данных с кодо-генераторами, доко-генеараторами и прочими валидаторо-нормализаторами. И это не говоря о куче инфраструктурных вещей, о которых надо как минимум подумать, а как максимум реализовать, проверить, что они работают как следует, завернуть в кубер-докеры и, наконец, задеплоить в кластере.

? 5+ табличек и 10+ индексов

? Object-Relation Mapping

? API сервер

? Изоморфная схема

? Клиентская обвязка

? Бэкапы и репликация

? Аутентификация и авторизация

? Всё это в контейнеры

Короче, всё это за часок, пока едете домой, вы точно не успеете.

Структура базы данных в CRUS?DB

Мы же будем использовать децентрализованную, безопасную, неубиваемую базу данных CRUS?DB, которая живёт прямо в браузерах на клиентских устройствах, и без конфликтов синхронизируется через любые каналы связи. В ней используется не реляционная алгебра, а графовая модель, поэтому предметная область ложится на неё практически 1-в-1.

Обратите внимание, что на схеме у нас теперь отражены ещё и политики доступа. Данные персоны будут зашифрованы и доступны только самой персоне. Данные встречи читать смогут все, у кого есть на неё ссылка. Содержимое отзыва будет доступно лишь его автору и владельцу встречи. Плюс появилась дополнительная сущность - отзывы (Opinions), куда любой пользователь сможет прилинковать свой отзыв.

Схема базы данных

Чтобы формализовать схему предметной области, переложим её в код на TypeScript, и получим модель, с которой уже можно будет работать.

class $my_survey_person extends Dict.with({
	Meets: List_ref( ()=> $my_survey_meet ),
}) {}

class $my_survey_meet extends Dict.with({
	Title: Str,
	Owner: Ref( ()=> $my_survey_person ),
	Opinions: Ref( ()=> $my_survey_opinions ) ),
}) {}

class $my_survey_opinions extends Dict_to(
	Ref( ()=> $my_survey_opinion )
) {}

class $hyoo_survey_opinion extends Dict.with({
	Descr: Text,
}) {}

Через неё уже можно будет читать и писать в базу данных, она будет синхронизироваться и тд.

Возможно вы обратили внимание, что Title и Descr имеют разные типы, хотя и там, и там хранятся буковки. Str в данном случае - это атомарная строка, которая хранит лишь наиболее свежее значение, стирая все предыдущие. А вот Text - это более хитрый тип данных, который автоматически мёржит изменения.

Когда вы вводите одну букву, другим пирам посылается не весь текст, а маленькая дельта, которая применяется к другому тексту без потерь уже внесённых в него изменений. По научному это называется dCvRDT, и лежит оно в основе всей CRUS?DB.

Создание новой встречи

Давайте немного расширим нашу модель методами, позволяющим сделать работу с нашей предметной областью ещё более удобной. Например, добавим в персону метод для создания новой встречи.

class $my_survey_person extends Dict.with({
	Meets: List_ref( ()=> $my_survey_meet ),
}) {

	@act meet_make() {
		const meet = this.Meets(null)!.remote_make({ '': Rank.get })!
		meet.Owner(null)!.val( this.land().auth().lord() )
		return meet
	}

}

Тут мы берём объявленное нами в схеме свойство `Meets` и просим его добавить в список ссылку на свежесозданную встречу с правами на чтение для всех подряд. А потом устанавливаем в ней ссылку на владельца - текущего пользователя. `null` в аргументах тут означает автоматическое создание записи для свойства, если его ещё нет.

Получение своего мнения

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

export class $my_survey_meet extends Dict.with({ ... }) {
	
	@mem opinion_my() {
		
		const my_auth = this.land().auth()
		const owner_key = this.Owner()?.remote()?.land().key()
		if( !owner_key ) return null
		
		const opinions = this.Opinions(null)?.remote_ensure({ '': Rank.add })
		
		const opinion = opinions?.key( my_auth.peer(), null )?.remote_ensure({
			[ owner_key.toString() ]: Rank.get,
			[ my_auth.public().toString() ]: Rank.law,
		}) ?? null
		
		return opinion
	}

}

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

Получение всех мнений

Для модели встречи нам далее пригодятся ещё пара методов: получение списка идентификаторов респондентов из ключей словаря со ссылками на мнения, и получение модели мнения по идентификатору респондента.

@mem responder_refs() {
	return this.Opinions()?.remote()?.keys()
		.map( $hyoo_crus_vary_cast_ref )
		.filter( $mol_guard_defined ) ?? []
}
	
@mems opinion( responder: $hyoo_crus_ref ) {
	const options = this.Opinions()?.remote()
	return options?.key( responder.description! )?.remote() ?? null
}

Всё, API готово!

Всё, наша умная модель полностью завершена и может использоваться где угодно.

Мы не возились с языками запросов, и не боролись с SQL и HTTP инъекциями. Всё, что нам потребовалось - это строго типизированное API на том же языки, на котором мы пишем и клиент. Причём написали мы исключительно прикладной код, без бойлерплейта связанного с проверками безопасности, обеспечения надёжности и своевременным обновлением и тд.

Нам не пришлось поднимать сервера, базы данных, контейнеры и тп. Более того, мы не написали ни строчки серверного кода - всё исполняется на клиенте. То есть мы получили настоящую бессерверность, а не то, что маркетологи продают нам как serverless, за которым скрываются на самом деле облачные серверные функции.

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

? Не надо поднимать СУБД

? Не надо писать код сервера

? Не надо настраивать бэкапы и репликацию

? Не надо делать аутентификацию и авторизацию

? Не надо изолировать периметр

Да какое API!

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

Или независимость от сети - мы можем как читать, так и писать данные в базу даже в не ограниченно долгом офлайне. А при появлении сети изменения разных пиров сливаются без конфликтов благодаря авторским CRDT алгоритмам. Причём делают они это в реальном времени благодаря синхронизации маленькими дельтами.

Наконец, положенные в основу базы данных E2E-шифрованиие и цифровые подписи для всех изменений дают беспрецедентную безопасность. Это не как в Телеграм, где по умолчанию все ваши переписки доступны и на чтение, и на запись одному Дурову известно какому кругу лиц, а для включения e2e-шифрования надо создавать отдельный неудобный секретный чат. В CRUS?DB всё по взрослому - вы сами контролируете кто и какой доступ имеет к вашим приватным данным.

✨ Строгая типизация

✨ Работа офлайн

✨ Синхронизация в реальном времени

✨ Слияние без конфликтов

✨ End-to-End шифрование

Форма сбора отзывов

Ну что ж, приступим, наконец, к написанию интерфейса. Сделать это быстрее и проще, конечно же, на $mol.

Используя язык view.tree опишем основную страницу нашего приложения - форму сбора обратной связи.

$my_survey_meet_form $mol_page
	meet $my_survey_meet
	-
	Title $mol_string_button
		value? <=> title? \
		hint @ \Meet title
	-
	body /
		<= Bid $mol_text
		<= Opinion_my $mol_textarea
		<= Opinions $mol_section

Стандартный Title, выводящийся в шапке $mol_page, нас не устроил, поэтому мы заменили его на поле строкового ввода, которое связали со свойством title, которое уже через TS свяжем с соответствующим свойством модели встречи, которую мы будем получать из вне.

@mem title( next?: string ) {
	return this.meet()
		.Title( next )?.val( next ) ?? ''
}

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

Побуждение к действию

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

Bid $mol_text text @ \
	\//Constructive feedback makes the world a better!// Tell:
	\? What did you **like**?
	\? What could be done **better**?
	\? More ideas and **suggestions** for the future?

Редактирование отзыва

Следующий блок - умная $mol_textarea для ввода своего мнения, которую мы связываем с соответствующим полем модели мнения.

Opinion_my $mol_textarea
	value? <=> opinion_my? \
@mem opinion_my( next?: string ) {
	return this.meet().opinion_my()
		?.Descr( next )?.text( next ) ?? ''
}

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

Список отзывов

Ну и в третьем блоке для владельца встречи нам нужно вывести все отзывы по ней. Для этого мы воспользуемся секцией $mol_section, под заголовком которой выведем вертикальный список мнений, каждое из которых визуализируем опять же через $mol_text, то есть в отзывах тоже можно будет пользоваться легковесной разметкой текста.

Opinions $mol_section
	title @ \Opinions
	content <= opinions /
		<= Opinion*0 $mol_text
			text <= opinion* \
@mem opinions() {
	return this.meet().responder_refs()
		.map( person => this.Opinion( person ) ) ?? []
}
	
@mems opinion( responder: $hyoo_crus_ref ) {
	return this.meet().opinion( responder )
		?.Descr()?.text() ?? ''
}

Если вы обратили внимание, то порой перед строками во view.tree можно встретит собачку - это значит, что данная строка не просто константа, а локализуемая строка. А это значит, что сборщик, увидев это, вырезает текст в отдельный JSON файл с английскими текстами, оставляя в коде лишь обращение к локализации по человеко-понятному глобально-уникальному идентификатору.

Локализация

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

my/survey/form/form.locale=ru.json

{ "$hyoo_survey_meet_form_Title_hint": "Название встречи", "$hyoo_survey_meet_form_Bid_text": "//Конструктивная обратная связь делает мир лучше!// ...", "$hyoo_survey_meet_form_Opinions_title": "Отзывы" }

Общая обвязка

Осталось дело за малым - сделать обвязку, чтобы у нас было меню со своими встречами и прочее. Для этого проще всего воспользоваться компонентом $mol_book2_catalog, который рисует типовую книжку из двух страниц: меню и развёртка для выбранного пункта.

$my_survey_app $mol_book2_catalog
	realm $hyoo_crus_realm
	param \meet
	Spread* <= Meet* $my_survey_meet_form
		meet <= meet* $my_survey_meet
	Placeholder $mol_page
		title @ \? Graceful Feedback

Объявленный в начале realm - это, собственно, вся база данных. param задаёт имя параметра в урле, в котором будет храниться идентификатор текущей развёртки. В Spread мы указываем, что в качестве развёртки надо использовать описанную нами ранее страницу встречи, которой передаём модель встречи. А в Placeholder, заполняющий оставшееся свободное место на экране, отобразим страничку с дополнительной информацией.

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

@mem profile() {
	return this.realm().home()
		.hall_by( $my_survey_person, {} )
}
	
@mem spread_ids() {
	return this.profile()
		?.Meets()?.remote_list()
		.map( meet => meet.ref().description! ) ?? []
}
	
@mems meet( id: string ) {
	const ref = $hyoo_crus_ref( id )
	return this.realm()
		.Node( ref, $my_survey_meet )
}

Тут мы получаем профиль текущего пользователя как экземпляр модели персоны. Если его ещё нет, то он будет создан автоматически с правами доступа никому, кроме автора. А это значит, что он будет автоматически зашифрован.

Потом мы формируем список идентификаторов развёрток для меню. И потом уточняем, как по этим идентификаторам получать из базы экземпляры встреч.

Первый результат

Наконец, запустив своё приложение, мы с удивлением обнаруживаем, что оно.. работает. Можно создавать встречи, делиться ссылками, оставлять отзывы и видеть как они прилетают в реально времени.

Но показывать его кому-то ещё немного стыдно. Тут не выровнено, там поехало.

Наведение красоты

Давайте отполируем визуал, используя статически типизированные каскадные стили - фичу, которая есть только в $mol..

$mol_style_define( $my_survey_meet_form, {
	
	flex: {
		basis: `40rem`,
	},
	margin: [ 0, 'auto' ],
	
	Opinion: {
		margin: $mol_gap.block, 
		background: {
			color: $mol_theme.card,
		},
	},
	
} )

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

Аналогичным образом мы поправим стили и для всего приложения..

$mol_style_define( $hyoo_survey_app, {
	
	Menu: {
		flex: {
			basis: `20rem`,
		},
	},
	
		Placeholder: {
		flex: {
			basis: `20rem`,
		},
	},
	
} )

Статически типизированные каскадные стили

Подробно я рассказывал про нашу систему стилизации в докладе Продвинутый CSS-in-TS на PiterJS #46.

Результат

Ну что ж, вот и финальный результат.

Вид респондента на мобилке, вводящего отзыв.
Вид респондента на мобилке, вводящего отзыв.
Вид владельца встречи, смотрящего отзывы на десктопе.
Вид владельца встречи, смотрящего отзывы на десктопе.

Добавляем офлайн

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

my/survey/app/app.meta.tree

include \/mol/offline/install

Деплой на сервер

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

# my/survey/.github/workflows/my_survey_app.yml
steps:

- uses: hyoo-ru/mam_build@master2
  with:
    package: 'my/survey'
    modules: 'app'

- uses: hyoo-ru/gh-deploy@v4.4.1
  if: github.ref == 'refs/heads/master'
  with:
    folder: 'my/survey/app/-'

Тут у нас два экшена: собственно сборка проекта под ключ, и выкладка его нас CDN гитхаба. Далее самое долгое - ожидание когда же раскатится DNS и сгенерируется HTTPS сертификат. Об этом, конечно, стоило позаботиться до начала разработки, но нам уж очень не терпелось поскорее взяться за код.

Статистика

Ну что ж, пришло время оценить, что у нас получилось.

10 Files

300 SLOC

100 KB bundle

Мы написали 300 строк кода - по 30 на файл в среднем. Всё это с зависимостями весит сотню килобайт. Казалось бы много, пока не вспомнишь, что там внутри собственная база данных, системы реактивности и виртуального рендеринга, визуализатор легковесной разметки, умная текстария и много других, на первый взгляд не заметных, но необходимых вещей. И при этом даже на мобилке полностью запускается всего за 2 секунды, что быстрее чем 99% используемых вами приложений, которые хорошо если хоть шапку покажут за это время.

Финальный твист

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

Эпилог

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

survey.hyoo.ru - отзыв на этот доклад

mol.hyoo.ru, mam_mol - про фреймворк и веб

crus.hyoo.ru - про БД и платформу

h_y_o_o - обсуждение децентрализации

mol_news - новости о проектах

jin.hyoo.ru - обо мне и от меня

boosty.to/hyoo - поддержка рублём

На портале мола вы найдёте целый кладезь информации о веб разработке. И, в частности, про $mol. Та же картинка и с ютуб каналом, где я разбираю разные веб-технологии, и рассказываю, почему они нашим в подмётки не годятся.

На странице CRUS?DB вы найдёте подробности о базе данных - она уже почти готова к продакшену, но нужно ещё немного потерпеть. А вот пробовать своими руками и давать обратную связь уже можно и нужно.

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

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

Наконец, на моей личной страничке вы найдёте информацию обо мне и различные материалы от меня: от хардкорных статей о разработке, до фоточек и стихов. Кстати, создана она в сервисе для ведения баз знаний, вот уже больше года крутящемся на прототипе CRUS?DB, так что скоро нам предстоит увлекательный переезд.

А на этом пока что всё, следите за новостями.


Актуальный оригинал на $hyoo_page.

Комментарии (15)


  1. igrishaev
    11.06.2024 08:20
    +9

    Как-то мало ссылок на личный сайт, телеграм-канал, "обо мне", форму обратной связи и ютуб-канал. Может, еще добавить?


    1. nin-jin Автор
      11.06.2024 08:20

      Не вопрос. Могу порекомендовать ещё эти каналы:

      • Core Dump про фундаментальные вещи в компьютерной науке.

      • PiterJS про ежемесячные митапы жабаскриптизёров.

      • Твой тайный принц про жизнь и отношения.


  1. Aniro
    11.06.2024 08:20
    +3

    Давайте представим, как это всё выглядело бы с традиционным подходом. Берётся реляционная СУБД. В ней создаётся пяток табличек и десяток индексов. Работать с SQL напрямую не удобно, поэтому обмазываются ORM. Работать напрямую с СУБД не безопасно, поэтому прячут её за API сервером. На клиенте работать напрямую c API не удобно, поэтому придумываются какую-нибудь клиентскую обвязку.

    Но если мы хотим заговнокодить прототип, мы херакнем json в localstorage и пусть он там лежит... (ну или решим гулять на все деньги и возьмем SQLite)
    А если серьезно, бд выглядит интересно, можно чуть подробностей? Как ваши одноранговые пиры друг-друга находят? Как вы защищаетесь от подделки контента вместе с ключами, клиенты же одноранговые?


    1. nin-jin Автор
      11.06.2024 08:20

      Зачем говнокодить, если можно писать и быстро, и качественно?

      Сейчас для коммуникации используется наиболее надёжный канал - по WebSocket через сервера синхронизации, поддерживаемые энтузиастами. В дальнейшем прикрутим WebRTC, чтобы снизить нагрузку на сервера.

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


      1. Aniro
        11.06.2024 08:20

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

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


        1. nin-jin Автор
          11.06.2024 08:20

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


          1. Aniro
            11.06.2024 08:20
            +4

            Вы не хотите выпустить этот самый круздб отдельным пакетом, без <s>брайнфака</s> мола внутри, чтобы им люди могли пользоваться, а не только сектанты?
            Выглядит интересно, и как минимум какие-то применения для него вероятно найдутся, я бы пощупал но без нагрузки.


            1. nin-jin Автор
              11.06.2024 08:20

              А вы не хотите принести мне чашечку чаю? Я бы мог и сам заварить, конечно, но так лень.


              1. Aniro
                11.06.2024 08:20
                +3

                Будете в Белграде, заходите, заварю.

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


      1. savostin
        11.06.2024 08:20

        То есть мы получили настоящую бессерверность, а не то, что маркетологи продают нам как serverless, за которым скрываются на самом деле облачные серверные функции.

        Сейчас для коммуникации используется наиболее надёжный канал - по WebSocket через сервера синхронизации, поддерживаемые энтузиастами.

        Ну как-то...


        1. nin-jin Автор
          11.06.2024 08:20

          Весь прикладной код исполняется на клиенте.


      1. michael_v89
        11.06.2024 08:20

        через сервера синхронизации, поддерживаемые энтузиастами

        То есть я сохранил данные, они записались на сервер энтузиаста, потом перед синхронизацией у него пропал интернет, и ничего не синхронизировалось, потом пока не было интернета он решил "да ну нафиг вашу CRUS DB" и удалил все файлы. Получается, я потерял данные, и они зависят от воли какого-то энтузиаста? Ненадежно.

        Другой вопрос. Я сохранил 100 Гб данных. Получается, у всех энтузиастов забьется канал, пока эти данные будут синхронизироваться? Что если у кого-то нет столько свободного места на диске, а библиотека в следующий раз меня подключит к нему, чтобы эти данные прочитать?


        1. nin-jin Автор
          11.06.2024 08:20
          +1

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

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


  1. sumdy-c
    11.06.2024 08:20
    +2

    Можно долго кидать минусы г-ну Карловскому, но его почему-то всегда интересно читать))

    indexedDB на стеройдах порадовал, но я лучше пока по старинке. Nestиком да Prismочкой...


  1. MasterMentor
    11.06.2024 08:20

    Хоп, Хлоп, и MVP готов

    Нашёл на просторах Хабра картинку в тему.