Add docs/ARCHITECTURE, CONTRIBUTING and DEVELOPMENT
- 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
This commit is contained in:
parent
9dde1bcdc8
commit
48b4f7e19c
71
docs/ARCHITECTURE.md
Normal file
71
docs/ARCHITECTURE.md
Normal file
@ -0,0 +1,71 @@
|
||||
# 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`):
|
||||
|
||||
```typescript
|
||||
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
|
||||
|
||||
1. `main.ts` dispara sync (manual, auto-sync, evento de save)
|
||||
2. `pro/src/sync.ts:doActualSync()` carrega árvore local + remota
|
||||
3. Diff 3-way usando snapshot anterior (`prevSyncRecordsTbl` em IndexedDB)
|
||||
4. `dispatchDecision()` aplica decisão por entry (copy, merge, delete, skip)
|
||||
5. Conflitos: 3-way merge via `node-diff3` (apenas Markdown < 1MB, tier pro)
|
||||
6. Erros agregados em `AggregateError`; falha até 3x antes de abortar
|
||||
|
||||
## State
|
||||
|
||||
LocalForage (IndexedDB) com 8 tabelas em `src/localdb.ts`:
|
||||
|
||||
- `prevSyncRecordsTbl` — snapshot da última sync
|
||||
- `fileContentHistoryTbl` — histórico de conteúdo (smart conflict)
|
||||
- `syncPlansTbl` — log das operações planejadas
|
||||
- `versionTbl`, `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 `: any` residuais**: concentrados em callbacks de error e payloads OAuth2.
|
||||
56
docs/CONTRIBUTING.md
Normal file
56
docs/CONTRIBUTING.md
Normal file
@ -0,0 +1,56 @@
|
||||
# Contribuindo
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Branch a partir de `master`: `git checkout -b <tipo>/<descrição>`
|
||||
- `feat/` — feature nova
|
||||
- `fix/` — bugfix
|
||||
- `refactor/` — refactor sem mudança de comportamento
|
||||
- `docs/` — só documentação
|
||||
- `chore/` — config, build, CI
|
||||
2. Commits pequenos, foco único
|
||||
3. Antes de abrir PR: `npm run format && npm test && npm run build`
|
||||
4. Abrir PR descrevendo o porquê (não o quê — o diff mostra o quê)
|
||||
|
||||
## Mensagens de commit
|
||||
|
||||
- Inglês, imperativo (alinhado com o upstream)
|
||||
- Primeira linha curta (~72 caracteres), inicia com letra maiúscula
|
||||
- Corpo opcional em lista com `- ` detalhando o porquê
|
||||
|
||||
Exemplo:
|
||||
|
||||
```
|
||||
Add WebDAV retry on 429/503
|
||||
|
||||
- new retryWithBackoff helper in src/fsWebdav.ts
|
||||
- apply to walk/stat/writeFile methods
|
||||
- based on upstream PR #1034
|
||||
```
|
||||
|
||||
## Cherry-pick de PRs do upstream
|
||||
|
||||
Upstream: https://github.com/remotely-save/remotely-save
|
||||
|
||||
```bash
|
||||
git remote add upstream https://github.com/remotely-save/remotely-save.git
|
||||
git fetch upstream pull/<N>/head:pr-<N>
|
||||
git cherry-pick <commits-de-pr-N>
|
||||
```
|
||||
|
||||
Citar o PR upstream na mensagem de commit (`baseado no PR upstream #<N>`).
|
||||
|
||||
## Estilo de código
|
||||
|
||||
- Biome formata e linta (`npm run format`)
|
||||
- TypeScript strict — evitar `any`
|
||||
- Funções idealmente 4–20 linhas; refatorar se passar
|
||||
- Nomes específicos, não `data`/`handler`/`Manager`
|
||||
- Sem comentários óbvios — explicar só o porquê quando não-trivial
|
||||
- Early returns (no máximo 2 níveis de aninhamento)
|
||||
|
||||
## Testes
|
||||
|
||||
- Toda feature ou bugfix inclui teste
|
||||
- Cobertura mínima do core: a definir (atualmente sem threshold)
|
||||
- Localização: `tests/` para src/, `pro/tests/` para pro/
|
||||
64
docs/DEVELOPMENT.md
Normal file
64
docs/DEVELOPMENT.md
Normal file
@ -0,0 +1,64 @@
|
||||
# Desenvolvimento
|
||||
|
||||
## Setup
|
||||
|
||||
Pré-requisito: [mise](https://mise.jdx.dev/) instalado.
|
||||
|
||||
```bash
|
||||
mise install # instala Node conforme mise.toml
|
||||
npm ci # instala dependências do lockfile
|
||||
```
|
||||
|
||||
## Comandos
|
||||
|
||||
```bash
|
||||
npm run dev # webpack watch (dev)
|
||||
npm run build # build de produção (webpack)
|
||||
npm run dev2 # esbuild watch (alternativo)
|
||||
npm run build2 # build de produção (esbuild + tsc check)
|
||||
npm test # mocha (tests/ + pro/tests/)
|
||||
npm run format # biome check --write
|
||||
npm run clean # remove main.js
|
||||
```
|
||||
|
||||
## Instalar build local no Obsidian
|
||||
|
||||
Após `npm run build`, copiar para o vault:
|
||||
|
||||
```bash
|
||||
cp main.js manifest.json styles.css \
|
||||
/path/to/vault/.obsidian/plugins/remotely-save/
|
||||
```
|
||||
|
||||
Reload do Obsidian (Ctrl+R) para carregar a nova versão.
|
||||
|
||||
## Testes
|
||||
|
||||
Framework: Mocha + chai-as-promised + tsx (sem transpile separado).
|
||||
|
||||
Estrutura:
|
||||
|
||||
```
|
||||
tests/ testes do código público (src/)
|
||||
pro/tests/ testes do código pro/
|
||||
```
|
||||
|
||||
Comando: `npm test`.
|
||||
|
||||
## Lint/format
|
||||
|
||||
Biome (`biome.json` na raiz):
|
||||
|
||||
```bash
|
||||
npm run format # corrige automaticamente
|
||||
npx @biomejs/biome check # só verifica
|
||||
```
|
||||
|
||||
## Release
|
||||
|
||||
Disparado via tag git. Workflow `.github/workflows/release.yml` constrói e publica artefatos:
|
||||
|
||||
```bash
|
||||
git tag x.y.z
|
||||
git push origin x.y.z
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user