Local-first заметки и явная синхронизация
Создаём «Блокнот»: изменяемые записи в IndexedDB, атомарную локальную очередь и собственный серверный контракт. Учимся сохранять текст без доступной сети, повторять стабильное намерение, получать журнал по cursor и разрешать конфликт двух редакций вручную. IndexedDB здесь хранит данные; серверная синхронизация реализована приложением. Service worker, кеш оболочки и CRDT остаются темами других серий.
Нужны основы JavaScript и HTTP, Node.js 24 и современный браузер с IndexedDB, Web Locks и BroadcastChannel. Сервер слушает localhost:4174. Два независимых профиля моделируют устройства одного аккаунта; настоящее размещение для разных компьютеров требует отдельного HTTPS сервера и реальной аутентификации. JSON сервер предназначен для одного процесса, без гарантии аварийной durability; journal/ledger/tombstones не очищаются. Учебные токены не являются паролями. Новый офлайн-вход и кеш оболочки не реализованы.
| Урок | Новый результат |
|---|---|
| 1. Локальная запись и границы синхронизации | Разделяем локальную заметку, серверную ревизию и ещё не подтверждённое изменение. |
| 2. Схема IndexedDB для записей и очереди | Открываем три object store и связываем обновление схемы с жизненным циклом вкладок. |
| 3. Атомарное сохранение заметки и outbox | Сохраняем форму и намерение отправки одной транзакцией, сообщая об успехе после complete. |
| 4. Стабильный ID операции и неизменяемый снимок | Отделяем идентификатор заметки от идентификатора отправки и сохраняем снимок до подтверждения. |
| 5. Серверный revision и журнал изменений | Реализуем push/pull контракт с проверкой исходной ревизии и сохранением результата операции. |
| 6. Отправка outbox и подтверждение снимка | Применяем серверный ответ к отправленной операции, не теряя правку во время запроса. |
| 7. Получение изменений и атомарный cursor | Сохраняем страницу серверного журнала и её cursor одной транзакцией. |
| 8. Сравнение версий и ручное объединение | Разрешаем конфликт явным выбором, сохраняя серверную revision и новый ID намерения. |
| 9. Удаление заметки и tombstone | Передаём удаление как версионированное состояние и удерживаем его для отключённых устройств. |
| 10. Повторы, отключение сети и прогресс | Разделяем временный сетевой отказ, завершение сессии и прикладной конфликт, сохраняя очередь. |
| 11. Несколько вкладок и несколько устройств | Координируем отправителей одного origin и защищаем сохранение устаревшей формы. |
| 12. Квоты браузера и экспорт заметок | Обрабатываем ограниченное хранение и экспортируем согласованный диагностический снимок. |
| 13. Аккаунт, локальная база и прекращение сессии | Разделяем записи разных владельцев и прекращаем отправку при отказе авторизации. |
| 14. Передача Блокнота и сценарии восстановления | Собираем регламент локального хранения, синхронизации, конфликта и экспорта с явными границами. |
Скачать полный конечный пример. README указывает порядок самостоятельного прохода, файлы, совместимость и границы. Архив доступен для скачивания; он не содержит готового работающего окружения.
Все материалы опубликованы. Учебные программы, серверы, установки, Git операции лабораторий, сборки образов, Kubernetes, Argo CD, HTTP сценарии и тесты не запускались. Показанные состояния и выводы ожидаемые. Сборка статического сайта, если выполнена отдельно, не подтверждает выполнение учебного примера.