Apps web progresivas: IndexedDB

1. Te damos la bienvenida

En este lab, crearás copias de seguridad de los datos del cliente y los recuperarás en IndexedDB. Este es el tercero de una serie de codelabs complementarios para el taller de apps web progresivas. El codelab anterior fue Trabaja con Workbox. Hay cinco codelabs más en esta serie.

Qué aprenderás

  • Crea una base de datos y un almacén de objetos de IndexedDB con idb
  • Cómo agregar y recuperar elementos en un almacén de objetos

Lo que debe saber

  • JavaScript y promesas

Lo que necesitarás

2. Prepárate

Para comenzar, clona o descarga el código de partida necesario para completar este codelab:

Si clonas el repositorio, asegúrate de estar en la rama pwa03--indexeddb. El archivo ZIP también contiene el código de esa rama.

Este código base requiere Node.js 14 o una versión posterior. Una vez que tengas el código disponible, ejecuta npm ci desde la línea de comandos en la carpeta del código para instalar todas las dependencias que necesitarás. Luego, ejecuta npm start para iniciar el servidor de desarrollo del codelab.

El archivo README.md del código fuente proporciona una explicación de todos los archivos distribuidos. Además, los siguientes son los archivos existentes clave con los que trabajarás a lo largo de este codelab:

Archivos de claves

  • js/main.js: Archivo JavaScript principal de la aplicación

3. Configurar base de datos

Antes de poder usar una base de datos de IndexedDB, se debe abrir y configurar. Si bien puedes hacerlo directamente, dado que IndexedDB se estandarizó antes de que las promesas fueran prominentes, su interfaz basada en devoluciones de llamada puede ser difícil de usar. En su lugar, usaremos idb, un wrapper de Promise muy pequeño para IndexedDB. Para comenzar, primero impórtalo a js/main.js:

import { openDB } from 'idb';

Luego, agrega el siguiente código de configuración en la parte superior del objeto de escucha de eventos DOMContentLoaded:

// Set up the database
const db = await openDB('settings-store', 1, {
  upgrade(db) {
    db.createObjectStore('settings');
  },
});

Explicación

Aquí, se crea una base de datos IndexedDB llamada settings-store. Su versión se inicializa en 1 y se inicializa con un almacén de objetos llamado settings. Este es el tipo más básico de almacén de objetos, con pares clave-valor simples, pero se pueden crear almacenes de objetos más complejos según sea necesario. Sin esta inicialización de un almacén de objetos, no habrá dónde colocar los datos, por lo que omitir esto sería como crear una base de datos sin tablas.

4. Cómo guardar el estado del editor en la actualización

Una vez que se inicializa la base de datos, es hora de guardar contenido en ella. El editor expone un método onUpdate que te permite pasar una función para que se llame cada vez que se actualice el contenido en el editor. Es el lugar perfecto para ingresar y agregar los cambios a la base de datos. Para ello, agrega el siguiente código justo antes de la declaración de defaultText en js/main.js:

// Save content to database on edit
editor.onUpdate(async (content) => {
  await db.put('settings', content, 'content');
});

Explicación

db es la base de datos IndexedDB que se abrió anteriormente. El método put permite crear o actualizar entradas en un almacén de objetos de esa base de datos. El primer argumento es el almacén de objetos de la base de datos que se usará, el segundo es el valor que se almacenará y el tercero es la clave en la que se guardará el valor si no está claro a partir del valor (en este caso, no lo está, ya que nuestra base de datos no incluye claves especificadas). Como es asíncrono, se incluye en async/await.

5. Recuperar el estado al cargar

Por último, para recuperar el trabajo en curso del usuario, se debe cargar cuando se cargue el editor. El editor proporciona un método setContent para hacer precisamente eso: establecer su contenido. Actualmente, se usa para establecerlo en el valor de defaultText. Actualízalo con lo siguiente para cargar el trabajo anterior del usuario:

editor.setContent((await db.get('settings', 'content')) || defaultText);

Explicación

En lugar de simplemente configurar el editor en el valor de defaultText, ahora intenta obtener la clave content del almacén de objetos settings en la base de datos settings-store de IndexedDB. Si existe ese valor, se usa. De lo contrario, se usará el texto predeterminado.

6. Cómo establecer y recuperar el estado del modo nocturno

Ahora que te sientes cómodo con IndexedDB, agrega el siguiente código a la parte inferior de js/main.js y actualízalo para guardar la preferencia del usuario sobre el modo nocturno cuando cambie y cargar esa preferencia cuando se inicialice el modo nocturno.

// Set up night mode toggle
const { NightMode } = await import('./app/night-mode.js');
new NightMode(
  document.querySelector('#mode'),
  async (mode) => {
    editor.setTheme(mode);
    // Save the night mode setting when changed
  },
  // Retrieve the night mode setting on initialization
);

7. ¡Felicitaciones!

Aprendiste a guardar y cargar datos desde un almacén de objetos en IndexedDB.

El siguiente codelab de la serie es De la pestaña a la barra de tareas.