Skip to content

Архитектура ​

Обзор клиента и worker. Исходники — в каталоге src/ репозитория.

Компоненты ​

КомпонентРасположениеРоль
createDatabasesrc/client/createDatabase.tsПубличное API, обёртка над PortBridge
PortBridgesrc/client/PortBridge.tsRPC + события на MessagePort
SharedWorkerBridgesrc/client/SharedWorkerBridge.tsnew SharedWorker() + connect
MessageRoutersrc/shared-worker/MessageRouter.tsДиспетчеризация запросов
ClientRegistrysrc/shared-worker/ClientRegistry.tsКарта портов, подписки, fan-out
DbEnginesrc/shared-worker/DbEngine.tsCRUD IndexedDB
RemoteSyncsrc/shared-worker/RemoteSync.tsЦикл push/pull

Dedicated worker переиспользует тот же router/engine через внутренний MessageChannel (src/dedicated-worker/entry.ts).

Fan-out между вкладками ​

Tab A ──put──► SharedWorker ──IDB write──► response to Tab A
                    │
                    └── change event ──► Tab B (if subscribed)

ClientRegistry хранит подписки по портам. broadcastChange шлёт { kind: 'change', collection, type, doc, id } только клиентам, подписанным на эту коллекцию.

Раскладка IndexedDB ​

Для схемы { todos: { keyPath: 'id' } }:

StoreНазначение
todosПользовательские коллекции
_metaКлюч-значение курсора sync
sync_queueОтложенные записи PendingOp

Версионирование схемы ​

computeSchemaVersion(schema) хеширует имена коллекций, key path и индексы в целое число — версию IndexedDB. Смена схемы запускает upgrade и создаёт новые индексы/store.

Все вкладки с одним dbName должны использовать одинаковую JSON-форму схемы, иначе connect вернёт SchemaMismatch.

Выбор leader (удалённый sync) ​

При connect с syncCapable: true (ставится, если передан адаптер remote):

  1. Первый способный клиент становится sync leader.
  2. RemoteSync шлёт sync:pull / sync:push только на порт leader.
  3. Если leader отключается, роль переходит к следующему клиенту с syncCapable.

В fetch-режиме HTTP идёт внутри worker; в delegate-режиме HTTP выполняется на leader-вкладке.

MIT License · offline-first IndexedDB и синхронизация через SharedWorker