Usa SQLite para controlar todas tus necesidades de almacenamiento con alto rendimiento en la Web.
SQLite es un sistema de administración de bases de datos relacionales de código abierto, ligero y empotrable. Muchos desarrolladores lo usan para almacenar datos de forma estructurada y fácil de usar. Debido a su tamaño pequeño y sus requisitos de memoria mínimos, SQLite a menudo se aprovecha como motor de base de datos en dispositivos móviles, aplicaciones para computadoras de escritorio y navegadores web.
Una de las características clave de SQLite es que es una base de datos sin servidor, lo que significa que no requiere un proceso de servidor independiente para funcionar. En cambio, la base de datos se almacena en un solo archivo en el dispositivo del usuario, lo que facilita su integración en las aplicaciones.
SQLite basado en Web Assembly
Existen varias versiones no oficiales de SQLite basadas en Web Assembly (Wasm), que permiten usarla en navegadores web, por ejemplo, sql.js. El subproyecto sqlite3 WASM/JS es el primer esfuerzo que se asocia oficialmente con el proyecto SQLite, lo que hace que las compilaciones de Wasm de la biblioteca sean miembros establecidos de la familia de entregas compatibles de SQLite. Los objetivos concretos de este proyecto incluyen los siguientes:
- Vincula una API de sqlite3 de bajo nivel que sea lo más cercana posible a la de C en términos de uso.
- Una API orientada a objetos de nivel superior, más similar a sql.js y a las implementaciones de estilo de Node.js, que se comunica directamente con la API de bajo nivel. Esta API se debe usar desde el mismo subproceso que la API de bajo nivel.
- Una API basada en trabajadores que se comunica con las APIs anteriores a través de mensajes de trabajadores. Esta está diseñada para usarse en el subproceso principal, con las APIs de nivel inferior instaladas en un subproceso de trabajo y comunicarse con ellas a través de mensajes de trabajador.
- Es una variante de la API de Worker basada en promesas que oculta por completo al usuario los aspectos de comunicación entre subprocesos.
- Compatibilidad con el almacenamiento persistente del cliente con las APIs de JavaScript disponibles, incluido el sistema de archivos privados de origen (OPFS).
Cómo usar SQLite Wasm con el backend de persistencia del sistema de archivos privados de Origin
Cómo instalar la biblioteca desde npm
Instala el paquete @sqlite.org/sqlite-wasm desde npm con el siguiente comando:
npm install @sqlite.org/sqlite-wasm
Origin Private File System
El sistema de archivos privados de Origin (OPFS, parte de la API de acceso al sistema de archivos) se complementa con una plataforma especial que brinda acceso de alto rendimiento a los datos. Esta nueva plataforma difiere de las existentes, ya que ofrece acceso de escritura exclusivo y en el lugar al contenido de un archivo. Este cambio, junto con la capacidad de leer de forma coherente las modificaciones no borradas y la disponibilidad de una variante síncrona en los trabajadores dedicados, mejora significativamente el rendimiento y desbloquea nuevos casos de uso.
Como puedes imaginar, el último punto de los objetivos del proyecto, la compatibilidad con el almacenamiento persistente del cliente mediante las APIs de JavaScript disponibles, tiene requisitos de rendimiento estrictos en cuanto a la persistencia de datos en el archivo de la base de datos.
Aquí es donde entra en juego el sistema de archivos privados de origen y, más específicamente, el método createSyncAccessHandle()
de los objetos FileSystemFileHandle
. Este método muestra una promesa que se resuelve en un objeto FileSystemSyncAccessHandle
que se puede usar para leer y escribir de forma síncrona en un archivo. La naturaleza síncrona de este método brinda ventajas de rendimiento, pero solo se puede usar dentro de trabajadores web dedicados para archivos dentro del sistema de archivos privados de origen, de modo que no se pueda bloquear el subproceso principal.
Cómo configurar los encabezados obligatorios
Entre otros archivos, el archivo SQLite Wasm descargado contiene los archivos sqlite3.js
y sqlite3.wasm
, que conforman la compilación SQLite3 WASM/JS. El directorio jswasm
contiene las entregas principales de sqlite3, y el directorio de nivel superior contiene apps de demostración y prueba. Los navegadores no entregarán archivos Wasm desde URLs file://
, por lo que las apps que compilas con esto requieren un servidor web, y ese servidor debe incluir los siguientes encabezados en su respuesta cuando entregue los archivos:
Cross-Origin-Opener-Policy
configurado en la directivasame-origin
, que aísla el contexto de navegación exclusivamente a documentos del mismo origen. Los documentos de origen cruzado no se cargan en el mismo contexto de navegación.Cross-Origin-Embedder-Policy
configurado en la directivarequire-corp
, por lo que un documento solo puede cargar recursos del mismo origen o recursos marcados de forma explícita como cargables desde otro origen.
El motivo de estos encabezados es que SQLite Wasm depende de SharedArrayBuffer
, y la configuración de estos encabezados forma parte de sus requisitos de seguridad.
Si inspeccionas el tráfico con DevTools, deberías encontrar la siguiente información:
Prueba de velocidad
El equipo de SQLite ejecutó algunas comparativas en su implementación de WebAssembly en comparación con Web SQL, que dejó de estar disponible. Estas comparativas muestran que SQLite Wasm es, en general, tan rápido como Web SQL. A veces es un poco más lento y, a veces, un poco más rápido. Consulta todos los detalles en la página de resultados.
Muestra de código para comenzar
Como se mencionó anteriormente, SQLite Wasm con el backend de persistencia del sistema de archivos privados de Origin debe ejecutarse desde un contexto de trabajador. La buena noticia es que la biblioteca se encarga automáticamente de todo esto por ti y puedes usarla desde el subproceso 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);
}
})();
Demostración
Consulta el código anterior en acción en la demostración. Asegúrate de revisar el código fuente en Glitch. Observa que la versión incorporada que se muestra a continuación no usa el backend de OPFS, pero sí lo hace cuando abres la demostración en una pestaña separada.
Cómo depurar el sistema de archivos privados de origen
Para depurar el resultado del sistema de archivos privados de origen de SQLite Wasm, usa la extensión de Chrome OPFS Explorer.
Después de instalar la extensión, abre las Herramientas para desarrolladores de Chrome, selecciona la pestaña OPFS Explorer y estará todo listo para inspeccionar lo que SQLite Wasm escribe en el sistema de archivos privados de origen.
Si seleccionas cualquiera de los archivos de la ventana del explorador de OPFS en DevTools, puedes guardarlo en el disco local. Luego, puedes usar una app como SQLite Viewer para inspeccionar la base de datos, de modo que puedas asegurarte de que SQLite Wasm realmente funciona según lo prometido.
Cómo obtener ayuda y enviar comentarios
La comunidad de SQLite desarrolla y mantiene SQLite Wasm. Para obtener ayuda y enviar comentarios, busca en el foro de asistencia y publica en él. La documentación completa está disponible en el sitio de SQLite.