Создание TodoMVC с помощью Twilio Sync и JavaScript

Автор: | 07.08.2026

Обмен информацией между различными устройствами в реальном времени — сложная задача, но с Twilio Sync это всего лишь вопрос нескольких строк кода. Чтобы понять, как работает Sync, давайте создадим собственную версию приложения TodoMVC, используя Twilio Sync для хранения данных и их синхронизации между несколькими устройствами.

Мы возьмем за основу копию версии TodoMVC на чистом JavaScript и изменим хранилище с локального на Twilio Sync. Однако вы можете использовать этот же код с вашим любимым фреймворком.

Прежде чем начать, убедитесь, что у вас есть следующие компоненты:

— Установленные Node.js и npm. Инструкции по установке можно найти на их сайте.

— Аккаунт Twilio. Зарегистрируйтесь бесплатно.

Начните с клонирования шаблонной ветки этого репозитория и установите зависимости:

Заполните файл `.env` необходимыми значениями. Если у вас еще нет Twilio API Key / Secret, сгенерируйте их в Twilio Console. Затем создайте Twilio Sync Service в консоли и скопируйте SID в файл `.env`.

Проверьте, запускается ли ваш сервер, выполнив команду:

Перейдите в браузере по адресу http://localhost:3000, и вы должны увидеть базовое приложение TodoMVC.

Twilio Sync SDK требует токен при инициализации клиента. Думайте о токене как о «пропуске» для соответствующего пользователя. Он определяет, кто этот пользователь и какие у него права. Этот токен должен генерироваться на стороне сервера. Мы создадим новый маршрут на нашем сервере, который будет предоставлять такой токен доступа.

Откройте файл `index.js` в корне вашего проекта и добавьте следующие строки перед выражением `app.listen(…)`:

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

Перезапустите сервер и перейдите по адресу http://localhost:3000/token, и вы должны получить JSON, похожий на этот:

Приложение TodoMVC в настоящее время использует LocalStorage для хранения элементов, и мы обновим его для использования Sync. Начнем с изменения в нашем файле `index.html` скрипта, который подключается. Найдите тег скрипта, который включает `»js/local-storage.js»`, и замените его на `»js/sync-storage.js»`.

В том же месте мы также подключаем Twilio Sync SDK из CDN Twilio. Если вы используете инструмент вроде Webpack для вашего проекта, не волнуйтесь — вы также можете использовать SDK из npm.

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

`Store(…)`

⇒ Функция инициализации

`Store.prototype.find()`

⇒ Поиск определенных задач на основе фильтра

`Store.prototype.findAll()`

⇒ Возвращает все задачи

`Store.prototype.save()`

⇒ Создает или обновляет задачу

`Store.prototype.remove()`

⇒ Удаляет определенную задачу

`Store.prototype.drop()`

⇒ Удаляет все задачи

Прежде чем приступить к кодированию, давайте немного поговорим о терминологии Twilio Sync.

В Twilio Sync можно хранить три типа данных: документ, карту и список:

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

— Карта — это неупорядоченная коллекция, где у каждого объекта есть ключи для идентификации.

— Список — это упорядоченная коллекция, где ключи определены как «индекс». Представьте его как массив. Мы будем использовать этот тип данных для нашего списка дел.

Сначала нам нужно инициализировать наше хранилище. Для этого необходимо выполнить следующие шаги:

— Получить токен с помощью `fetch(‘/token’)`

— Создать экземпляр клиента

— Получить список с именем, переданным в функцию

— Извлечь текущий набор элементов в списке

— Вызвать callback с элементами

Поместите следующие строки в функцию Storage:

В рамках этого мы сохраняем экземпляр списка, который создали, как `this._list`. С этим экземпляром мы будем взаимодействовать в последующих функциях.

Кроме того, данные каждого элемента в SyncList обернуты метаданными. Нам нужно извлечь фактические данные. Добавьте следующую функцию `extractData` в конец файла:

Есть два способа поиска элементов задач, которые нам нужно реализовать для этого хранилища. Один — это функция `find`, а другой — `findAll`. Обе возвращают списки элементов в функцию обратного вызова, но `find` позволяет фильтровать эти элементы с помощью объекта запроса. Для реализации `findAll` мы можем использовать метод `getItems()` на экземпляре `this._list` для получения всех задач и применить к ним функцию `extractData`. Обновите функцию `findAll` соответствующим образом:

У `SyncLists` нет собственной функции фильтрации, поэтому для реализации метода `find` мы получим все элементы и отфильтруем их самостоятельно. Для этого добавьте следующую функцию `createFilterFunction` в конец вашего файла:

Теперь используйте тот же метод `getItems()`, который мы использовали в функции `findAll`, и отфильтруйте результаты с помощью `createFilterFunction`. Измените вашу функцию `find` следующим образом:

Далее нам нужно реализовать функцию `save()`, которая создает и обновляет элементы. Если функции передается `id`, достаточно вызвать `.update(id, data)` для списка, чтобы обновить данные. TodoMVC также ожидает, что будет возвращен список текущих задач, поэтому нам нужно снова получить все элементы и вызвать callback с ними.

Добавьте следующий код в функцию `save()`:

Создание нового элемента немного сложнее. Мы узнаем `id`, который будет индексом элемента, только после того, как он будет добавлен в список. Поэтому сначала мы добавим элемент, а затем обновим его, указав `id` как индекс.

Расширьте метод `save()` соответствующим образом:

Давайте протестируем наш код в первый раз! Перейдите по адресу http://localhost:3000 и начните создавать элементы. Если вы обновите страницу, данные все еще будут на месте.

Две функции, которые нам еще предстоит реализовать, — это `remove` и `drop`. Удаление элемента просто: вызовите `remove()` с соответствующим `id`, и элемент исчезнет.

Добавьте следующий код в метод `remove()`:

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

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

До сих пор мы использовали Sync в основном как базу данных для хранения элементов, но мы не слушали изменения. `SyncLists` предоставляют ряд различных событий. Мы будем слушать события `itemAdded`, `itemUpdated` и `itemRemoved` и вызывать функцию `eventHandler()`, переданную в `Store()`.

Добавьте следующий код в конструктор `Store`:

В файле `app.js` мы уже передаем функцию, где на строке 30 вызываем `todo.controller._filter(true);`. Это вызовет перезагрузку контроллера и отобразит обновленный список.

Перезагрузите http://localhost:3000 и откройте два окна рядом. Добавьте несколько элементов, удалите некоторые, отметьте выполненные. Вы увидите, как списки волшебным образом обновляются на обеих сторонах одновременно!

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

Мне бы очень хотелось увидеть, что у вас получится с использованием Twilio Sync! Не стесняйтесь связаться со мной по адресу: