У меня постоянно открыто несколько окон Хрома с множеством табов. В одном - десяток табов с медленными запросами в наш BI-сервис, которые я "вот-вот посмотрю". Во втором - исследование нюансов $lookup и $unwind в MongoDB. В третьем, где больше всего вкладок, - санкт-петербургские правила зачисления в школу, потому что жизнь.

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

Tab Saver demo
Tab Saver demo

Результат - Tab Saver. Один клик - все табы сохранены и бэкапятся в Google-аккаунт.

storage.sync

Chrome предоставляет расширениям API chrome.storage.sync - хранилище, которое автоматически синхронизируется между всеми браузерами пользователя, залогиненными в тот же Google-аккаунт.

Использовать его вот так:

// Сохранить
await browser.storage.sync.set({ 
  myData: { tabs: [...], savedAt: new Date().toISOString() } 
});

// Прочитать
const result = await browser.storage.sync.get('myData');
console.log(result.myData);

Как и следует из названия, после browser.storage.sync данные не только бэкапятся, но и волшебным образом появляются на других компьютерах, где залогинен в тот же Google-аккаунт Chrome. Лимиты - так себе, но для синхронизации табов хватит: 100 КБ общего объёма, до 512 ключей, до 8 КБ на элемент.

Всё очень неплохо, однако есть нюанс. Даже несколько.

Нюанс 1: "Синхронизация" не означает "бэкап"

Самый болезненный сюрприз: при удалении расширения Chrome удаляет ВСЕ данные storage.sync.

Если удалить расширение, скажем, для переустановки, то после переустановки - данных нет. Они удалились вместе с расширением. Chrome считает, что данные расширения принадлежат расширению, а не пользователю. Удалил расширение - удалил и данные. Всё, что можно сделать, - разве что предупреждать в UI, что я и делаю. Ну или добавить экспорт-импорт и другие места для бэкапа - это оставим для второй версии.

Нюанс 2: identity API врёт. Ну или предоставляет неточную информацию

Чтобы данные синхронизировались в облако Google, требуется, чтобы пользователь был залогинен и была включена либо синхронизация всего аккаунта, либо синхронизация именно "Apps". Увы, Chrome Identity API позволяет узнать только, включена ли синхронизация всего аккаунта. Ну что ж, можно лишь точно отразить это в UI.

const userInfo = await chrome.identity.getProfileUserInfo({ 
  accountStatus: 'SYNC' 
});
// Так можно получить только подтверждение, что включена синхронизация всего аккаунта
Требуемые для синхронизации данных расширений настройки гуглоэккаунта
Требуемые для синхронизации данных расширений настройки гуглоэккаунта

Нюанс 3: Нужен доступ к email, чтобы просто узнать статус

Чтобы вызвать chrome.identity.getProfileUserInfo(), расширению нужен permission identity.email.

В Chrome Web Store это выглядит как "Read your email address". Это, конечно, неприятно. Для бэкапа табов email-адрес и даром не нужен, но без этого разрешения не узнать статус синхронизации и не получится успокоить меня подтверждением, что табы бэкапятся.

Нюанс 4: Нет подтверждения, что данные синхронизировались

storage.sync.set() возвращает Promise, который резолвится, когда данные записаны локально. Дальше остаётся лишь надеяться, что они таки на самом деле ушли в облако, ну или посмотреть, когда они доедут до Хрома на втором ноутбуке. Конечно, для сохранения адресов ссылок достаточно пары секунд офисного вайфая, но точно - не узнать.

Нет API чтобы узнать:

  • Синхронизировались ли данные

  • Когда синхронизировались

  • Есть ли ошибки синхронизации

Есть и плюсы

  • Никаких серверов - не нужно поднимать бэкенд

  • Никакой авторизации - пользователь уже залогинен в Chrome

  • Бесплатно - Google хостит данные

  • Кроссплатформенно - работает на всех устройствах с Chrome

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

А у вас?

Пробовали storage.sync в своих расширениях? Может быть, знаете способ надёжно определить ушли ли данные в облако на самом деле?

P.S.
Изначально опубликовано на моём agilsoftwaredevelopment.com