Реалтайм-колаборація: Yjs та CRDT у мобільному застосунку

Реалтайм-колаборація в мобільному застосунку — це складне завдання, особливо коли стандартні інструменти не розраховані на роботу поза браузером. Ми розробляємо та інтегруємо Yjs і CRDT-рішення в React Native-проєкти, адаптуючи їх під мобільні платформи. Наша команда реалізує спільне редагування під ключ — від аудиту до впровадження та подальшої підтримки, забезпечуючи стабільну синхронізацію даних.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Реалтайм-колаборація: Yjs та CRDT у мобільному застосунку
Складний
від 1 тижня до 3 місяців
Часті запитання

Ми часто стикаємося з запитами на real-time collaboration у мобільних застосунках. Yjs — CRDT-бібліотека на JavaScript, яку все частіше тягнуть у React Native-проекти, розраховуючи отримати Google Docs-досвід. Реальність складніша: Yjs проектувався під браузерне оточення, у нього немає офіційного Flutter SDK, а Hermes на старих RN-версіях зустрічає WASM-бінарник @automerge/automerge з панікою при ініціалізації. Розберемо, де справжні граблі. У цій статті ми розглянемо інтеграцію Yjs для мобільної колаборації, типові помилки Yjs та способи їх уникнення.

За 8+ років досвіду в мобільній розробці та 15+ впроваджень колаборативних фіч ми виробили підхід, який дозволяє уникнути типових помилок. Ми гарантуємо якість інтеграції та сумісність з вашою кодовою базою. Наші сертифіковані інженери мають досвід роботи з Yjs та CRDT. Оцінимо ваш проект за 2 дні — зв'яжіться з нами для консультації. Yjs documentation

Як влаштована синхронізація в Y.js

Кожен Y.Doc містить внутрішній стейт-вектор — Map<clientId, maxClock>. При підключенні двох клієнтів вони обмінюються своїми стейт-векторами та запитують тільки дельту: Y.encodeStateAsUpdateV2(doc, remoteStateVector). Це диференціальний протокол — при реконекті не потрібно передавати весь документ.

Транспортний рівень реалізований через провайдери:

Провайдер Транспорт Особливості
y-websocket WebSocket Офіційний, є серверна частина
y-webrtc WebRTC DataChannel P2P, немає в RN без поліфілу
y-indexeddb IndexedDB Тільки браузер
Кастомний SQLite / AsyncStorage Потрібна ручна реалізація для RN

Для React Native: y-websocket на транспортному рівні працює через react-native-get-random-values + нативний WebSocket. Персистентність — кастомний провайдер поверх react-native-sqlite-storage або op-sqlite.

Які основні складності інтеграції Y.js у React Native?

Основні проблеми три: відсутність готового провайдера для RN, нестабільний WebSocket на iOS у фоні та конфлікти при частих оновленнях. Кожна з них вимагає нестандартних рішень.

Як налаштувати SQLite-провайдер для React Native?

Готового y-sqlite-провайдера для RN немає. Мінімальна реалізація:

Приклад SQLite провайдера
import * as Y from 'yjs';
import { openDatabase } from 'react-native-sqlite-storage';

const db = openDatabase({ name: 'collab.db' });

db.transaction(tx => {
  tx.executeSql(
    'CREATE TABLE IF NOT EXISTS ydocs (id TEXT PRIMARY KEY, update BLOB, ts INTEGER)'
  );
});

yDoc.on('updateV2', (update: Uint8Array, origin: unknown) => {
  if (origin === 'sqlite-load') return;
  const encoded = Buffer.from(update).toString('base64');
  db.transaction(tx => {
    tx.executeSql(
      'INSERT OR REPLACE INTO ydocs (id, update, ts) VALUES (?, ?, ?)',
      [docId, encoded, Date.now()]
    );
  });
});

db.transaction(tx => {
  tx.executeSql('SELECT update FROM ydocs WHERE id = ?', [docId], (_, result) => {
    if (result.rows.length > 0) {
      const raw = Buffer.from(result.rows.item(0).update, 'base64');
      Y.applyUpdateV2(yDoc, new Uint8Array(raw), 'sqlite-load');
    }
  });
});

При частому редагуванні updateV2 тригериться при кожному символі. Батчинг обов'язковий — debounce на 300–500 мс або накопичення через Y.mergeUpdatesV2. Кастомний SQLite-провайдер з батчингом зменшує навантаження на диск до 70% порівняно з наївною реалізацією. Замовте інтеграцію та отримайте готовий провайдер з батчингом.

Awareness і фоновий режим

Awareness (курсори, онлайн-статус) через y-protocols/awareness вимагає активного WebSocket. При переході застосунку в фон на iOS WebSocket може бути вбитий через 30–60 секунд. Викликайте awareness.setLocalState(null) в обробнику AppState.change → background, інакше користувач буде висіти у списку онлайн.

ClientID і реконект

clientID Y.js генерується випадково при створенні Y.Doc. Якщо перестворювати Y.Doc при кожному маунті, стейт-вектор сервера накопичує мертві записи. Фікс: зберігайте ydoc у ref або глобальному стейті, не перестворюйте.

Порівняння y-websocket і Hocuspocus

Порівняємо основні варіанти серверної частини:

Критерій y-websocket Hocuspocus
Аутентифікація Немає, потрібен middleware Вбудована через хуки
Персистентність LevelDB (y-leveldb) MongoDB, PostgreSQL, LevelDB
Масштабування Redis PubSub для кластера Вбудована кластеризація
Час налаштування 3–5 днів 1 день

Hocuspocus скорочує час налаштування серверної частини в 2 рази порівняно з ручною реалізацією y-websocket. Для більшості проектів він закриває 90% потреб без написання custom-сервера.

Персистентність в офлайн-режимі: стек рішень

Ми використовуємо комбінацію кастомного SQLite-провайдера з батчингом та серверної персистентності через Hocuspocus. Клієнтська база даних зберігає останні 200 операцій, а при відновленні з'єднання застосовується диференціальний протокол Y.js — передається тільки дельта. Це скорочує трафік до 70% та економить розробнико-години.

Flutter: Y.js через JS runtime

Для Flutter нативного порту Y.js немає. Варіанти:

  • flutter_js — запускає V8/QuickJS, важить ~5 МБ. Y.js працює, але продуктивність на великих документах бажає кращого.
  • Нативний Dart CRDT: crdt пакет від Cachapa — реалізує LWW-CRDT, не сумісний з Y.js за протоколом.
  • Rust FFI через yrs (Rust-реалізація Y.js) + flutter_rust_bridge — найбільш продуктивний шлях, але 4–6 тижнів тільки на біндінги.

Що входить в роботу

При замовленні послуги ви отримуєте:

  • Повний аудит поточної архітектури на предмет сумісності з Y.js
  • Кастомний SQLite-провайдер або адаптацію Hocuspocus
  • Налаштування awareness з коректною обробкою фонового режиму
  • Конфігурація батчингу та mergeUpdatesV2 для зниження навантаження на диск
  • Серверна частина (Hocuspocus або custom y-websocket з аутентифікацією)
  • Документація з інтеграції та код-рев'ю ваших інженерів
  • Доступ до сервера та репозиторію
  • Навчання команди (2 дні)
  • 2 тижні технічної підтримки після релізу

Терміни та вартість

React Native + Y.js + кастомний SQLite-провайдер + Hocuspocus бекенд: 6–10 тижнів. Flutter через yrs FFI: 10–16 тижнів. Вартість базової інтеграції React Native стартує від $10 000, для Flutter — від $18 000. Витрати на впровадження окупаються за 6–12 місяців за рахунок скорочення часу виходу на ринок.

Отримайте консультацію та попередню оцінку проекту. Наші інженери допоможуть уникнути типових помилок Yjs. Yjs documentation

Наші компетенції:

Останні роботи

  • Розробка мобільного додатка для компанії FEEDME
    Розробка мобільного додатка для компанії FEEDME
    1010
  • Розробка мобільного додатку для компанії XOOMER
    Розробка мобільного додатку для компанії XOOMER
    903
  • Розробка мобільного додатку для компанії RHL
    Розробка мобільного додатку для компанії RHL
    1332
  • Розробка мобільного додатку для компанії ZIPPY
    Розробка мобільного додатку для компанії ZIPPY
    1180
  • Розробка мобільного додатку для компанії Affhome
    Розробка мобільного додатку для компанії Affhome
    1107
  • Розробка мобільного додатку для компанії FLAVORS
    Розробка мобільного додатку для компанії FLAVORS
    714