Use o SQLite para lidar com todas as suas necessidades de armazenamento com desempenho na Web.
O SQLite é um sistema de gerenciamento de banco de dados relacional leve, incorporado e de código aberto conhecido. Muitos desenvolvedores usam esse recurso para armazenar dados de maneira estruturada e fácil de usar. Devido ao tamanho pequeno e aos baixos requisitos de memória, o SQLite é frequentemente usado como um mecanismo de banco de dados em dispositivos móveis, aplicativos para computador e navegadores da Web.
Um dos principais recursos do SQLite é que ele é um banco de dados sem servidor, o que significa que não requer um processo de servidor separado para operar. Em vez disso, o banco de dados é armazenado em um único arquivo no dispositivo do usuário, facilitando a integração com os aplicativos.
SQLite baseado na Web Assembly
Há várias versões não oficiais do SQLite baseadas em Web Assembly (Wasm), permitindo que ele seja usado em navegadores da Web, por exemplo, sql.js. O subprojeto sqlite3 WASM/JS é o primeiro esforço oficialmente associado ao projeto SQLite, fazendo com que os builds do Wasm da biblioteca sejam membros estabelecidos da família de itens de SQLite com suporte. Os objetivos concretos deste projeto incluem:
- Vinculação de uma API sqlite3 de baixo nível, que seja o mais próxima possível da C em termos de uso.
- uma API orientada a objetos de nível superior, semelhante a sql.js e implementações no estilo Node.js, que se comunica diretamente com a API de nível inferior; Essa API precisa ser usada na mesma linha de execução da API de baixo nível.
- Uma API baseada em worker que se comunica com as APIs anteriores por mensagens de worker. Essa é destinada ao uso na linha de execução principal, com as APIs de nível inferior instaladas em uma linha de execução de worker e se comunicando com elas por mensagens de worker.
- Uma variante baseada em promessas da API Worker que oculta completamente os aspectos de comunicação entre linhas de execução do usuário.
- Suporte para armazenamento persistente do lado do cliente usando APIs JavaScript disponíveis, incluindo o Origin Private File System (OPFS).
Como usar o SQLite Wasm com o back-end de persistência do sistema de arquivos particular da origem
Como instalar a biblioteca do npm
Instale o pacote @sqlite.org/sqlite-wasm do npm com o seguinte comando:
npm install @sqlite.org/sqlite-wasm
O sistema de arquivos particular da origem
O Origin Private File System (OPFS, parte da API File System Access) é aprimorado com uma superfície especial que oferece acesso de alto desempenho aos dados. Essa nova plataforma difere das atuais por oferecer acesso de gravação exclusivo e no local ao conteúdo de um arquivo. Essa mudança, além da capacidade de ler modificações não limpas de forma consistente e a disponibilidade de uma variante síncrona em workers dedicados, melhora significativamente o desempenho e desbloqueia novos casos de uso.
Como você pode imaginar, o último ponto das metas do projeto, o suporte ao
armazenamento permanente do lado do cliente usando APIs JavaScript disponíveis, vem com
requisitos rigorosos de desempenho relacionados à persistência de dados no arquivo do banco de dados.
É aqui que o Origin Private File System e, mais especificamente, o método
createSyncAccessHandle()
dos objetos
FileSystemFileHandle
entram em ação. Esse método retorna uma promessa que é resolvida para um objeto
FileSystemSyncAccessHandle
que pode ser usado para ler e gravar um arquivo de forma síncrona. A
natureza síncrona desse método traz vantagens de desempenho, mas, portanto,
ele só pode ser usado em
Web Workers dedicados para
arquivos no sistema de arquivos particular da origem para que a linha de execução principal não seja bloqueada.
Como definir os cabeçalhos necessários
Entre outros arquivos, o SQLite Wasm transferido por download contém os arquivos sqlite3.js
e sqlite3.wasm
, que compõem o build sqlite3 WASM/JS. O diretório jswasm
contém as principais entregas do sqlite3, e o diretório de nível superior
contém apps de demonstração e teste. Os navegadores não vão oferecer arquivos Wasm de
URLs file://
. Portanto, todos os apps criados com isso exigem um servidor da Web, e esse
servidor precisa incluir os seguintes cabeçalhos na resposta ao fornecer os
arquivos:
Cross-Origin-Opener-Policy
definido como a diretivasame-origin
, que isola o contexto de navegação exclusivamente para documentos de mesma origem. Os documentos de origem cruzada não são carregados no mesmo contexto de navegação.Cross-Origin-Embedder-Policy
definido como a diretivarequire-corp
, para que um documento só possa carregar recursos da mesma origem ou recursos explicitamente marcados como carregáveis de outra origem.
O motivo desses cabeçalhos é que o SQLite Wasm depende de
SharedArrayBuffer
,
e a configuração desses cabeçalhos faz parte dos
requisitos de segurança.
Se você inspecionar o tráfego com as DevTools, vai encontrar as seguintes informações:
Teste de velocidade
A equipe do SQLite realizou alguns comparativos de mercado na implementação do WebAssembly em comparação com o SQL da Web descontinuado. Esses comparativos de mercado mostram que o SQLite Wasm é geralmente tão rápido quanto o Web SQL. Às vezes é um pouco mais lento, às vezes é um pouco mais rápido. Confira todos os detalhes na página de resultados.
Exemplo de código para iniciantes
Como mencionado anteriormente, o SQLite Wasm com o back-end de persistência do sistema de arquivos particular da origem precisa ser executado em um contexto de worker. A boa notícia é que a biblioteca cuida automaticamente de tudo isso para você, e você pode usá-la diretamente na linha de execução principal.
import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';
(async () => {
try {
console.log('Loading and initializing SQLite3 module...');
const promiser = await new Promise((resolve) => {
const _promiser = sqlite3Worker1Promiser({
onready: () => {
resolve(_promiser);
},
});
});
console.log('Done initializing. Running demo...');
let response;
response = await promiser('config-get', {});
console.log('Running SQLite3 version', response.result.version.libVersion);
response = await promiser('open', {
filename: 'file:worker-promiser.sqlite3?vfs=opfs',
});
const { dbId } = response;
console.log(
'OPFS is available, created persisted database at',
response.result.filename.replace(/^file:(.*?)\?vfs=opfs$/, '$1'),
);
await promiser('exec', { dbId, sql: 'CREATE TABLE IF NOT EXISTS t(a,b)' });
console.log('Creating a table...');
console.log('Insert some data using exec()...');
for (let i = 20; i <= 25; ++i) {
await promiser('exec', {
dbId,
sql: 'INSERT INTO t(a,b) VALUES (?,?)',
bind: [i, i * 2],
});
}
console.log('Query data with exec()');
await promiser('exec', {
dbId,
sql: 'SELECT a FROM t ORDER BY a LIMIT 3',
callback: (result) => {
if (!result.row) {
return;
}
console.log(result.row);
},
});
await promiser('close', { dbId });
} catch (err) {
if (!(err instanceof Error)) {
err = new Error(err.result.message);
}
console.error(err.name, err.message);
}
})();
Demonstração
Confira o código acima em ação na demonstração. Confira o código-fonte no Glitch. Observe como a versão incorporada abaixo não usa o back-end do OPFS, mas quando você abre a demonstração em uma guia separada, ele é usado.
Depurar o sistema de arquivos particular da origem
Para depurar a saída do sistema de arquivos particular de origem do SQLite Wasm, use a extensão OPFS Explorer do Chrome.
Depois de instalar a extensão, abra o Chrome DevTools, selecione a guia OPFS Explorer e você estará pronto para inspecionar o que o SQLite Wasm grava no Origin Private File System.
Se você selecionar qualquer um dos arquivos na janela do OPFS Explorer no DevTools, poderá salvá-lo no disco local. Em seguida, use um app como o SQLite Viewer para inspecionar o banco de dados e garantir que o SQLite Wasm funciona conforme o esperado.
Receber ajuda e enviar feedback
O SQLite Wasm é desenvolvido e mantido pela comunidade SQLite. Receba ajuda e envie feedback pesquisando e postando no fórum de suporte. A documentação completa está disponível no site do SQLite.