@composi/runtime:

Entorno de Ejecución

Gestión de Estado para los Componentes Funcionales

Esta sección asume que ya sabe cómo crear y usar componentes funcionales con @composi/core. Si no es así, visite esta sección.

Es increíble lo que puedes hacer con solo h y render. Sin embargo, más a menudo tu componente necesitará algún tipo de estado local. Los componentes basados en clases pueden lograr esto fácilmente. @composi/core solo proporciona componentes funcionales, que no pueden tener un estado local. @composi/core soluciona esta limitación a través de su entorno de ejecución creado con la función run, que proporciona un ámbito privado para encapsular el estado y un mecanismo para acutalizar la vista cuando cambia el estado. El entorno de ejecución de @composi/core te permite crear un programa en el cuál las preocupaciones se dividen en responsabilidades claramente definidas.

SVU: State-View-Update

El entorno de ejecución de Composi se basa en el concepto de SVU, State, View y Update (Estado, Vista y Actualización). Esto es similar a MVC, pero sutilmente diferente. En el MVC tradicional, el modelo no solo contiene los datos, sino que puede validar los datos y conservarlos en una base de datos. Con SVU, el estado consiste en los datos inertes. No tiene lógica para nada. En SVU, View es una función que toma el estado y devuelve una representación de éste. A la vista no le importa cómo se hace esto. Es tu responsabilidad dar instrucciones a la vista sobre qué hacer con el estado. Esto podría ser simplemente devolver un componente funcional, o usar la función render de @composi/core para renderizar el resultado en el DOM. Al crear una vista, se supone que vas a implementar eventos para la interacción con el usuario. Cuando un usuario interactúa con esos eventos, ese acto envía mensajes al método Update. La función update contiene toda la lógica de negocios del programa. El método update maneja esto internamente a través de funciones de acción. Dependiendo del mensaje enviado, update lo pasa a una acción que modifica el estado. Cuando esto sucede, el entorno de ejecución invoca el método view con ese estado, lo que hace que view devuelva el resultado. En cuanto al desarollo front-end (para el navegador), esto significa una nueva representación de la vista.

SVU Diagram

Si la ilustración anterior es un poco demasiado técnica para ti, aquí hay otra que muestra cómo funciona un programa de retorno de ejecución. Como usuario, interactúas con la vista enviando mensajes. Estos son interceptados por el método de actualización, que luego manipula el estado, causando que la vista cambie.

SVU Diagram

Cada programa de returno de ejecución @composi/core implementa este patrón SVU. Lo hace con tres métodos: init, ver y update. Init es donde se define el estado predeterminado para el programa. En el inicio, el retorno de ejecución toma el valor devuelto por init y lo usa para representar la vista. El siguiente ejemplo muestra las partes centrales de un programa de ejecución.

const programa = {
  init() {
    return estado
  },
  view(estado, enviar) {
  // Renderiza la vista que puede enviar mensajes a update:
  return render(componente, contenedor)
  },
  update(mensaje, estado, enviar) {
    if (mensaje) {
      // Gestionar mensajes para actualizar el estado:
      return estado
    }
  }
}

Init

Init es una función que devuelve una matriz de dos valores: estado y efecto. Al inicio, el programa usa el estado que init proporciona para representar la vista. El efecto es opcional. Si se proporciona, se ejecutará al inicio también. Los efectos son funciones asíncronas para los temporizadores o la obtención de datos. La mayoría de las veces init solo proporcionará el estado. El estado de un programa puede ser cualquier tipo de JavaScript: null, undefined, number, string, array u objecto. Los programas complejos inevitablemente necesitarán algún estado como una matriz u objeto.

View

View es una función que implementa la vista, la cual es la representación del estado del programa. Una vista por lo general tiene eventos para la interacción con el usuario. Una interacción enviará un mensaje a la función de update del programa.

Update

Update es la función donde se arregla toda la lógica de negocios para el programa. Según el mensaje que recibe, update performa acciones sobre el estado y lo devuelve. Esto causa que el programa vuelva a renderizar la vista con el estado nuevo.

Aquí está el program más sencillo que se puede hacer. Este es válido y funcionando, pero no hace nada.

See the Pen @composi/core + runtime Básico by Robert Biggs (@rbiggs) on CodePen.

El Orden no Importa

Al crear un programa, el orden de las funciones no importa. En nuestros ejemplos solemos usar init, view, update. Pero puedes escoger cualquier orden que prefieres.

const programa1 = {
  init() {},
  update() {},
  view() {}
}
const programa2 = {
  init() {},
  view() {},
  update() {}
}
const programa3 = {
  view() {},
  init() {},
  update() {}
}

Si ya tienes un orden que prefieres, quédate con el para preservar la consistencia.

Contador--El Hola Mundo de Programas

Para ilustrar cómo configurar un programa y ejecutarlo, vamos a hacer un contador sencillo. Su estado será un número. La vista manadará un mensaje a la función update, despuś del cual el estado se aumentará por 1.

See the Pen @composi/core + runtime - contador by Robert Biggs (@rbiggs) on CodePen.

Un Objeto es un Objeto

En los ejemplos anteriores se puede notar que hemos creado objetos con el nombre programa los cuales pasamos a la función run. Esto es similar a los componentes de clase. Una instancia de clase es un objeto retornado por una clase. La diferencia es en cómo se usan. Con los componentes de clase es muy común añadir propiedades y métodos nuevos a la clase para que tengan funcionalidad nueva. Al contrario, un programa de entorno de ejecución @composi/core solo tiene tres métodos: init, view y update.

El ejemplo previo del contador es talvez demasiado sencillo, pero muestra el formato básico para un programa del entorno de ejecución: init, view y update. Puedes aprender más de su documentación en el menú arriba.

Part of Core

The runtime is part of @composi/core, so importing and using it does not add anything to the final payload of your project's JavaScript. @composi/core is 2KB gzipped.

When we say the runtime is small, we mean it. Here's all the code for the runtime minified and completely functional:

function run(a){function b(m){if(j)return c(f(i,m,b))}function c(m){m?i=m:d&&(i=d()),g&&k&&('function'==typeof
g&&g(l,b),k=!1),e(i,b)}let d=a.init;const e=a.view,f=a.update,g=a.subscriptions||a.subs,h=a.done;let i,j=!0,k=!0;const
l=()=>i;return a.send=b,c(i),()=>{j&&(j=!1,h&&h(i))}}