Acabo de actualizar mi sistema de ventas para que muestre una ventana emergente indicando que hay una actualización y, en caso de que el usuario lo elija, se pueda actualizar.
En este post te voy a enseñar cómo es que he implementado la actualización de mi sistema offline PWA Sublime POS 4 usando JSON y JavaScript además de Vue 3 que es con lo que está programado el sistema.
El archivo de actualizaciones
Por el momento tengo un archivo JSON que muestra todas las versiones del sistema junto con sus notas de actualización y que está disponible públicamente en mi servidor.
Se ve así:
[
{
"version": "0.3.2",
"notas": ["Probando actualizaciones", "Estas fueron introducidas desde la 0.3.2, así que esto nunca debería mostrarse"]
}
]
Cuando salga una nueva versión simplemente añadiré los detalles al inicio del arreglo JSON junto con sus notas.
Este archivo está, obviamente, en mi servidor. Cuando quiera lanzar una nueva actualización voy a editar ese archivo manualmente pues por el momento no necesito algo más sofisticado.
¿Cómo funciona SPOS4?
Sublime POS 4 es una PWA que guarda todos sus datos localmente usando SQLite3 con WebAssembly. Básicamente es una página web que no necesita nada de internet (excepto la primera vez que la cargas) ya que guarda todo en la caché del navegador.
El problema con la caché es que por más que refresques la página se te seguirá mostrando lo que ya tienes cacheado sin importar si ya hay una nueva versión.
Esto es y no es un problema, ya que la caché me permite a mí como dueño del servidor ahorrar ancho de banda, y al usuario le permite que su sistema cargue sin internet.
Consultando archivo de actualizaciones
Entonces en mi código hago un fetch al archivo JSON y lo decodifico accediendo al primer elemento del arreglo. La versión local está inyectada en mi propia app gracias al archivo .env
const buscarActualizaciones = async () => {
try {
const url = import.meta.env.VITE_UPDATES_URL + "?dia=" + (new Date().setHours(0, 0, 0, 0));
const respuestaHttp = await fetch(url);
if (respuestaHttp.status === 200) {
const informacionVersionesComoJson = await respuestaHttp.json();
if (informacionVersionesComoJson.length > 0) {
const ultimaVersion = informacionVersionesComoJson[0];
if (ultimaVersion.version > version) {
notasActualizacion.value = ultimaVersion.notas;
deberiaMostrarAlertaActualizar.value = true;
}
}
}
} catch (e) {
console.error(e);
}
}
Por cierto, para evitar la caché propia del navegador al consultar el archivo JSON me aseguro de enviar un nombre de archivo distinto cada día, así se podrá consultar si hay actualizaciones a diario mientras que sigo ahorrando ancho de banda.
Actualizando sistema
Como puedes ver en el código anterior, si hay una nueva actualización entonces establezco deberiaMostrarAlertaActualizar
en true
, eso hará que se muestre un cuadro de diálogo y si el usuario acepta la actualización entonces se ejecuta lo siguiente:
const actualizar = async () => {
const clavesCache = await window.caches.keys();
for (const clave of clavesCache) {
if (clave.endsWith("https://parzibyte.me/apps/pos/")) {
const ok = await caches.delete(clave);
if (ok) {
window.location.reload();
}
}
}
}
Simplemente estoy borrando la caché. Eso sí, me debo asegurar que es la caché correcta ya que para el mismo origen
window.caches.keys()
me devuelve las claves de varias aplicaciones que tengo además de SPOS4, por ello es que uso endsWith
.
Y después de eso simplemente actualizo la página con location.reload()
.
Si el usuario no tiene internet, no habrá manera de comprobar actualizaciones y por lo tanto no se va a borrar la caché.
La caché se borra solamente cuando hay internet, y para asegurarnos de que hay internet invocamos a esta función después de consultar el archivo JSON que obviamente necesita internet para consultarse.
Me parece que hay maneras más limpias, elegantes y recomendadas de actualizar una app que tiene un Service worker, pero prefiero hacer esto porque es más simple.
Conclusión
Me gusta mucho este método. Tengo el control de las actualizaciones en el archivo JSON. Cuando yo quiera lanzar una actualización solo debo editar dicho archivo y los usuarios podrán actualizar cuando tengan internet.
De este modo mi sistema PWA tiene revisión de actualizaciones asegurándome de que los usuarios van a disfrutar la última versión libre de errores y con nuevas características.