- ARCHITECTURE.md: high-level view of FakeFs abstraction, sync flow, state - DEVELOPMENT.md: mise setup + npm commands + local install - CONTRIBUTING.md: workflow, English commit conventions, upstream PR cherry-pick
3.1 KiB
3.1 KiB
Arquitetura
Plugin Obsidian (TypeScript) que sincroniza vaults com serviços de armazenamento remoto (WebDAV, S3, Dropbox, OneDrive, etc).
Estrutura
src/ código público (MIT)
├── main.ts entry point, estende Plugin do Obsidian (~2k linhas)
├── settings.ts UI de settings (~3k linhas)
├── fsAll.ts abstração FakeFs — interface comum dos backends
├── fsGetter.ts roteamento backend → instância (switch por tipo)
├── fs<Backend>.ts implementações: S3, WebDAV, Dropbox, OneDrive, Webdis, Local, Encrypt
├── localdb.ts IndexedDB via LocalForage — state local
├── configPersist.ts serialização da config no disco do plugin
├── i18n.ts Mustache + moment, idiomas em src/langs/
└── ...
pro/ código tier pago (PolyForm Strict License)
├── src/
│ ├── sync.ts motor de sincronização (~2k linhas, doActualSync + dispatchDecision)
│ ├── fs<Backend>.ts GoogleDrive, Box, pCloud, YandexDisk, Koofr, Azure, OnedriveFull
│ └── ...
└── tests/
tests/ testes Mocha (estrutura básica, sem cobertura do core)
docs/ documentação
.github/workflows/ CI
Abstração FakeFs
Todo backend implementa a classe abstrata FakeFs (src/fsAll.ts):
abstract class FakeFs {
walk() / walkPartial() / stat() / mkdir() / writeFile()
readFile() / rename() / rm()
checkConnect() / getUserDisplayName() / revokeAuth() / allowEmptyFile()
}
fsGetter.ts faz o roteamento via switch — ao adicionar backend novo, registrar nele.
Fluxo de sincronização
main.tsdispara sync (manual, auto-sync, evento de save)pro/src/sync.ts:doActualSync()carrega árvore local + remota- Diff 3-way usando snapshot anterior (
prevSyncRecordsTblem IndexedDB) dispatchDecision()aplica decisão por entry (copy, merge, delete, skip)- Conflitos: 3-way merge via
node-diff3(apenas Markdown < 1MB, tier pro) - Erros agregados em
AggregateError; falha até 3x antes de abortar
State
LocalForage (IndexedDB) com 8 tabelas em src/localdb.ts:
prevSyncRecordsTbl— snapshot da última syncfileContentHistoryTbl— histórico de conteúdo (smart conflict)syncPlansTbl— log das operações planejadasversionTbl,loggerOutputTbl,profilerResultsTbl— metadados
Config persiste via API do Obsidian em <vault>/.obsidian/plugins/remotely-save/data.json,
com obfuscação base64 reverse (decorativa, não criptográfica).
Pontos de atenção
- mtime no WebDAV: padrão WebDAV não define mtime — Nextcloud expõe via header custom (
OC-LastModified). Inconsistência pode causar falsa detecção de modificação. - OAuth2 duplicado: cada backend implementa fluxo próprio (~100-300 linhas duplicadas). Sem extração comum.
- Sem retry HTTP: 429/503 quebram sync. PR upstream #1034 propõe retry para WebDAV.
- 141
: anyresiduais: concentrados em callbacks de error e payloads OAuth2.