Bases de dados
Em que adaptadores de base de dados do Content um site duxt pode ser implementado, quais foram verificados e a única regra que mantém a camada fora do caminho.
O Content v3 guarda as suas páginas em SQL e sabe falar com cinco bases de dados. O duxt não tem opinião sobre nenhuma delas: o adaptador é uma decisão da tua implementação, o Content já é dono dessa superfície, e a única função da camada é não atrapalhar.
Esta página diz até onde isso foi de facto verificado, em vez de o insinuar.
Duas bases de dados, não uma
Quase todas as surpresas nesta área nascem de ler «a base de dados» como uma só coisa. O Content mantém duas, e têm tempos de vida e tipos diferentes.
content._localDatabase | content.database | |
|---|---|---|
| O que guarda | A cache de análise — uma linha por ficheiro, tal como analisado | As coleções que o site consulta |
| Quando existe | Durante uma compilação, em .data/content/ | No servidor implementado |
| Que adaptadores | sqlite ou d1, e mais nada | Qualquer um dos cinco abaixo |
| Quem a lê | duxt report, o validador de compilação, o mapa de redirecionamentos | queryCollection(), num pedido |
A consequência é a parte útil: escolher um adaptador muda a base de dados implementada e mais nada. Um site implementado em PostgreSQL continua a compilar através de uma cache de análise SQLite local, porque o próprio tipo que o Content dá a essa cache não admite outra coisa.
.data/content/contents.sqlite, no diretório onde compilas. É uma cache —
apagá-la custa uma compilação, nunca conteúdo.
Os adaptadores
content.database.type no teu próprio nuxt.config.ts. O duxt não o define para
nenhum site; deixá-lo por definir dá-te o valor por omissão do Content.
| Adaptador | Precisa de instalado | duxt |
|---|---|---|
sqlite (por omissão) | Nada no Node 24 — lido pelo node:sqlite integrado | Verificado em CI em cada commit |
d1 | Nada; um binding da Cloudflare | Verificado — este site corre nele |
libsql | @libsql/client | Verificado em CI |
postgresql | pg | Verificado em CI |
pglite | @electric-sql/pglite | Por testar |
«Verificado em CI» significa uma compilação do próprio site deste repositório
contra esse adaptador, seguida de uma sondagem de todos os pontos de acesso que
leem a base de dados em tempo de execução e de uma execução do duxt report. O
workflow é .github/workflows/adapters.yml; corre em cada pull request, para que
as linhas acima não possam deixar de ser verdadeiras em silêncio.
Não se conhece nada de errado nele. Também não se conhece nada de certo — não teve uma execução dedicada, por isso está marcado como por testar em vez de se dar a entender que funciona. Se o usares numa implementação, a camada gostaria de saber como correu.
Não é instalado nenhum controlador SQLite nativo
O valor por omissão do Content é o better-sqlite3, um addon nativo que compila
através do node-gyp. O duxt define content.experimental.sqliteConnector como
'native', que usa em vez disso o node:sqlite integrado no Node 24 e não
precisa de pacote nenhum — razão pela qual a instalação da camada não arrasta um
compilador e pela qual a compilação quer o Node 24.
Herdas essa definição ao estender a camada e nunca deverias ver um aviso de
descontinuação por causa dela. O que o Content descontinuou foi o antigo
experimental.nativeSqlite; o duxt tem um teste que lê as próprias declarações
do Content e faz falhar as verificações da camada assim que algo que ela define
sob content.experimental traz uma etiqueta @deprecated — a próxima mudança de
nome aterra neste repositório em vez de aterrar no teu registo de compilação.
O que corre durante a compilação, e nunca no servidor
Três partes da camada leem diretamente do sistema de ficheiros. As três correm dentro de uma compilação, que é precisamente o que torna possível um Worker — ou qualquer alvo sem disco.
| O que faz | Quando | |
|---|---|---|
content-cache.ts | Abre a cache de análise com node:sqlite e põe-na em modo WAL | Compilação |
modules/git-meta.ts | Corre git log sobre a cópia de trabalho para «última atualização» e contribuidores | Compilação |
duxt report | Lê essa mesma cache a partir da linha de comandos | Ao lado da compilação |
Nenhuma delas é alcançável a partir de um pedido, e nenhuma é afetada pelo teu
adaptador: leem a cache SQLite local descrita acima, que existe diga o que disser
content.database.
A regra
A camada nunca lê a base de dados do Content em tempo de execução por outra via que não
queryCollection().
É nisto que consiste toda a compatibilidade de adaptadores do duxt. No momento em que uma rota de servidor abrisse a base de dados por si, a camada passaria a pressupor um sistema de ficheiros e um dialeto SQLite — e falharia na tua implementação, não nos testes deste repositório.
É imposta em vez de prometida: tests/content-database.test.ts falha se qualquer
ficheiro sob server/ ou app/ importar um controlador de base de dados, e
mantém fechada a lista de ficheiros de tempo de compilação que podem abrir um,
pelo que um novo tem de ser justificado por escrito antes de entrar.
O que lê a base de dados num pedido
Tudo o resto que um site duxt serve já é um ficheiro quando é servido. Isto não é, e é isto que a matriz de adaptadores sonda:
…/page.md— a fonte Markdown por trás de «Ver como Markdown» e das ligações de entrega./mcp— todas as ferramentas, já que cada uma responde a partir de uma coleção./llms.txte/llms-full.txt— ambos percorrem todas as coleções./rss.xml, assim que o configurares.
Uma página está igualmente nessa lista numa implementação renderizada no servidor, e fora dela numa pré-renderizada. Ver Implementar um site para saber qual das duas tens.