Crear/cargar archivo json en Pilas

¡Saludos, aquí Lukeitor!
Estuve rehaciendo un juego de fútbol que hice hace varios años y encontré engorroso tener que actualizar o cambiar los datos de jugadores y equipos uno a uno en las variables del proyecto.
Así que discutí con la IA sobre cómo implementar algún tipo de sistema de guardado y cargado de archivos.

Después de varias pruebas, llegué a que lo más sencillo es usar archivos JSON. El siguiente proyecto es la demostración mínima.

Al clicar en guardar se abre una nueva pestaña que muestra un archivo JSON previamente creado en el propio actor botón. No pude hacer que se descargue como un archivo propiamente dicho debido a que el iframe de pilas tiene una medida de seguridad aplicada o algo así.

Al clicar en cargar se abre el explorador de archivos para que seleccionemos un archivo JSON.

Abrir este proyecto en el editor de pilas

Si quieren probarlo, se espera que el archivo JSON tenga la siguiente estructura:

{
  "nombre": "Lukeitor",
  "edad": 28,
  "estudia": false
}

Si cargan un JSON con esa estructura, los actores de texto mostrarán el nombre y la edad.

Para implementar este sistema en cualquier otro proyecto debemos:

  1. Guardar: Debajo del código del actor, más allá de la última llave, hay que crear la función para guardar, esta recibe el parámetro datos el cual debe tener la estructura de un archivo JSON y es lo que vamos a guardar como un archivo. Luego llamamos a la función desde el actor, por ejemplo desde cuando_hace_click().
function mostrarJSON_en_nueva_pestaña(datos) {
  const datos_guardar = datos;

  const contenidoTexto = JSON.stringify(datos_guardar, null, 2);

  // 1. Creamos el Blob usando el objeto global window
  const blob = new window.Blob([contenidoTexto], { type: 'application/json' });

  // 2. Generamos la URL temporal para el archivo
  const urlBlob = window.URL.createObjectURL(blob);

  // 3. Le ordenamos al navegador abrir esa URL en una pestaña limpia
  // Esto salta el bloqueo del sandbox porque la pestaña nueva corre de forma independiente
  window.open(urlBlob, '_blank');

  mostrar("JSON enviado a una nueva pestaña de forma segura.");
}
  1. Para cargar: De manera similar, pondremos la siguiente función debajo del código del actor cargar. Con la diferencia que debemos crear una variable con la palabra var en el código del proyecto para que la función guarde allí lo que cargamos del archivo. La función que comparto guarda la información en una variable llamada datos_cargados1, creada como var en el proyecto.
function solicitar_y_cargarJSON() {
  // 1. Usamos 'window.document' para saltarnos la restricción de TypeScript
  const inputArchivo = window.document.createElement('input');
  inputArchivo.type = 'file';
  inputArchivo.accept = '.json';

  inputArchivo.onchange = function (evento: any) {
    const archivo = evento.target.files[0];
    if (!archivo) return;

    // 2. Usamos 'window.FileReader' para que Pilas lo reconozca
    const lector = new window.FileReader();

    lector.onload = function (e: any) {
      try {
        const contenidoTexto = e.target.result;
        const datosCargados = JSON.parse(contenidoTexto);

        console.log("¡Archivo JSON cargado!", datosCargados);
        // Aquí aplicas tus variables...
        datos_cargados1 = datosCargados;//es una variable (var) creada en el proyecto

      } catch (error) {
        console.error("Error al parsear el JSON:", error);
      }
    };

    lector.readAsText(archivo);
  };

  // 3. Ejecutamos el clic
  inputArchivo.click();
}

Este sistema permitiría guardar partidas o, en mi caso, cargar datos que tengo en un excel.

  • Posdata: Sí, este código lo hice con ayuda de la IA. No me avergüenza… bueno tal vez un poquito xd.

Genial @lukeitor !!!, está buena la solución!!!, como dices el iframe de pilas tiene algunas limitaciones, podemos cambiarlas si hace falta, yo inicialmente puse la mayor seguridad posible, pero sin saber muy bien realmente.

Sobre el guardado y recuperación, creo que ese json generado también se puede guardar en localStorage que es una especie de memoria que tiene el navegador; no se si te resulte útil, pero lo comento por las dudas te sirva.

Gracias por compartirlo @lukeitor !!!