@composi/runtime:

POS—Programa de Orden Superior

Envolver un Programa Dentro de Otro

El entorno de ejecución de @composi/core hace muchas cosas interesantes para que funcione. Esto sucede en el closure (clausura) del entorno de ejecución. Ahí es donde se mantiene el estado. Si deseas examinar el estado del programa, no puedes alcanzarlo porque nunca está expuesto fuera de la clausura. Sin embargo, si quieres la habilidad de examinar el estado durante el desarrollo, puedes crear un programa de orden superior para envolver el programa y exponer su estado. Aquí es cómo harías eso:

export function registrarEstado(programa, estadoCambio) {
  return {
    ...programa,
    view (estado, send) {
      estadoCambio(estado)
      return programa.view(estado, send)
    }
  }
}

Puedes usar el POS anterior para acceder al estado del programa envuelto:

import { h, render, run } from '@composi/core'
import { registrarEstado } from './registrarEstado'

// Not a full programa to conserve space:
// El programa no es completo para no toma espacio.
const programa = {
  init() {},
  view() {},
  update() {}
}

// Envolver el programa previo en el programa de orden superior:
const programaEnvuelto = registrarEstado(programa, estado => {
  console.log(estado)
})

// Ejecutar el programa de orden superior:
run(programaEnvuelto)

Ya que el programa está envuelta por el programa de orden superior, el programa registrará su estado cada vez que cambia.

Depuración

Puedes crear un programa de orden superior para depurar a otro programa. Aquí mostramos un ejemplo bastante sencillo de esto. Clara que tendrías que desarollarlo mucho más para que fuera más útil.

export function registarErrores(programa) {
  // Captar el estado y efecto del programa:
  const estadoDelPrograma = program.init()
  const init = () => ({ tieneError: false, error: null, estadoDelPrograma })

  // Gestionar cualquer cosa que devuelva la función update.
  // Si es error, trata con él,
  // si no renderice el view de defecto.
  function view(estado, send) {
    if (estado.tieneError) {
      // Aquí solo registramos el error.
      // Podrías proporcionar una vista alternativa para usar
      // a fin de mostar el error en detalle.
      return console.log(estado.error)
    } else {
      // De otro modo, todo está bien así que renderizamos la vista.
      return programa.view(estado.estadoDelPrograma, send)
    }
  }

  // Interceptar el update del programa para captar los errores:
  function update(estado, mensaje) {
    let actualizarLaVista
    try {
      actualizarLaVista = programa.update(estado.estadoDelPrograma, mensaje)
    } catch (error) {
      return ({ ...estado, tieneError: true, error })
    }

    const [estadoDelPrograma, efectoDelPrograma] = actualizarLaVista
    return ({ ...estado, estadoDelPrograma }, efectoDelPrograma)
  }

  // Deja que el programa termine.
  let done
  if (programa.done) {
    done = function(estado) {
      return programa.done(estado.estadoDelPrograma)
    }
  }

  return { init, update, view, done }
}

Con este programa de orden superior podemos envolver nuestro programa para registrar errores:

run(registarErrores(programa))